root/usr/src/uts/common/io/qede/qede.h
/*
* CDDL HEADER START
*
* 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 usr/src/OPENSOLARIS.LICENSE
* or http://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

/*
* 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.
*/

/*
 * Copyright 2023 Oxide Computer Company
 */

#ifndef _QEDE_H
#define _QEDE_H

#include <sys/stream.h>

#include <sys/ddi.h>
#include <sys/ddifm.h>
#include <sys/dditypes.h>
#include <sys/sunddi.h>
#include <sys/fm/io/ddi.h>
#include <sys/mac_provider.h>
#include <sys/mac_ether.h>
#include <sys/kobj.h>
#include <sys/mac.h>
#include <sys/mac_ether.h>
#include <sys/dlpi.h>
#include <sys/pattr.h>
#include <sys/gld.h>
#include <inet/ip.h>
#include <inet/tcp.h>
#include <netinet/udp.h>
#include <sys/ethernet.h>
#include <sys/pci.h>
#include <sys/netlb.h>
#include <sys/strsun.h>
#include <sys/strsubr.h>
#include <sys/policy.h>

#include "qede_version.h"
#include "bcm_osal.h"
#include "qede_fp.h"

#if 1
#include "ecore.h"
#include "ecore_status.h"
#include "ecore_utils.h"
#include "ecore_chain.h"
#include "ecore_hsi_common.h"
#include "ecore_hsi_eth.h"
#include "ecore_proto_if.h"
#include "ecore_iov_api.h"
#include "ecore_int_api.h"
#include "ecore_dev_api.h"
#include "ecore_l2_api.h"
#include "ecore_hw.h"
#include "nvm_cfg.h"
#include "ecore_mcp.h"
#include "ecore_dbg_fw_funcs.h"
#include <sys/pcie.h>
#include <sys/time.h>
#else
#include <ecore.h>
#include <ecore_status.h>
#include <ecore_utils.h>
#include <ecore_hsi_common.h>
#include <ecore_hsi_eth.h>
#include <ecore_proto_if.h>
#include <ecore_chain.h>
#include <ecore_iov_api.h>
#include <ecore_int_api.h>
#include <ecore_dev_api.h>
#include <ecore_ll2_api.h>
#include <ecore_l2_api.h>
#include <ecore_mcp.h>
#endif



#ifndef STRINGIFY
#define XSTRINGIFY(x)   #x
#define STRINGIFY(x)    XSTRINGIFY(x)
#endif
#define QEDE_STR_SIZE   32
/* Product Identification Banner */
#define QEDE_PRODUCT_INFO\
        "QLogic FastLinQ QL45xxx " STRINGIFY(MAJVERSION) \
        "." STRINGIFY(MINVERSION) "." STRINGIFY(REVVERSION)

/*
 * Debug Infrastructure
 */
#define DEBUG_NONE      0x0
#define DEBUG_ATTACH    0x1

#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL     DEBUG_NONE
#endif

#define qede_dbg(MASK, ptr, fmt, ...) \
do { \
        if (DEBUG_LEVEL & (MASK)) { \
                qede_print("!%s(%d) STRINGIFY(MASK):" fmt, __func__, \
                    (ptr)->instance, \
##__VA_ARGS__);\
        } \
} while (0);

#define qede_info(ptr, fmt, ...) \
do { \
        qede_print("!%s(%d):" fmt, __func__, (ptr)->instance, \
##__VA_ARGS__); \
} while (0);

#define qede_warn(ptr, fmt, ...) \
do { \
        qede_print_err("!%s(%d):" fmt, __func__, (ptr)->instance, \
##__VA_ARGS__); \
} while (0);

#ifdef __sparc
#define QEDE_PAGE_ALIGNMENT     0x0000000000002000ull
#define QEDE_PAGE_SIZE  0x0000000000002000ull
#else
#define QEDE_PAGE_ALIGNMENT     0x0000000000001000ull
#define QEDE_PAGE_SIZE  0x0000000000001000ull
#endif

#define LE_TO_HOST_64                   LE_64
#define HOST_TO_LE_64                   LE_64
#define HOST_TO_LE_32                   LE_32
#define LE_TO_HOST_32                   LE_32
#define HOST_TO_LE_16                   LE_16
#define LE_TO_HOST_16                   LE_16



#define QEDE_LSO_MAXLEN                 65535

#define BUF_2K_SIZE                     2048
#define BUF_2K_ALIGNMENT                BUF_2K_SIZE

#define MIN_TX_RING_COUNT               1
#define MAX_TX_RING_COUNT               1
#define DEFAULT_TX_RING_COUNT           1
#define MAX_TC_COUNT                    1
#define DEFAULT_TRFK_CLASS_COUNT        1

#define MIN_TX_RING_SIZE                1024
#define DEFAULT_TX_RING_SIZE            8192

#define DEFAULT_TX_COPY_THRESHOLD       256
#define DEFAULT_TX_RECYCLE_THRESHOLD    128

#define TX_RING_MASK                    (tx_ring->tx_ring_size - 1)

#define IP_ALIGNMENT_BYTES              2
#define QEDE_MAX_ETHER_HDR              18 

#define MIN_FASTPATH_COUNT              1
#define MAX_FASTPATH_COUNT              6
#define DEFAULT_FASTPATH_COUNT          4

#define MIN_RX_RING_SIZE                1024
#define DEFAULT_RX_RING_SIZE            8192
#define MAX_RX_RING_SIZE                DEFAULT_RX_RING_SIZE

#define MIN_RX_BUF_SIZE                 2048
#define MAX_RX_BUF_SIZE                 2048
#define DEFAULT_RX_BUF_SIZE             2048

#define DEFAULT_RX_COPY_THRESHOLD       128
#define RX_RING_MASK                    (rx_ring->rx_buf_count - 1)
#define MIN_RX_BUF_COUNT                MIN_RX_RING_SIZE        
#define MAX_RX_BUF_COUNT                MAX_RX_RING_SIZE        
#define DEFAULT_RX_BUF_COUNT            DEFAULT_RX_RING_SIZE    
#define RX_LOW_BUFFER_THRESHOLD 128

#define USER_OPTION_CKSUM_NONE     0x0
#define USER_OPTION_CKSUM_L3       0x1
#define USER_OPTION_CKSUM_L3_L4    0x2
#define DEFAULT_CKSUM_OFFLOAD      USER_OPTION_CKSUM_L3_L4

#define QEDE_OFFLOAD_NONE          0x00000000
#define QEDE_OFFLOAD_TX_IP_CKSUM   0x00000001
#define QEDE_OFFLOAD_RX_IP_CKSUM   0x00000002
#define QEDE_OFFLOAD_TX_TCP_CKSUM  0x00000004
#define QEDE_OFFLOAD_RX_TCP_CKSUM  0x00000008
#define QEDE_OFFLOAD_TX_UDP_CKSUM  0x00000010
#define QEDE_OFFLOAD_RX_UDP_CKSUM  0x00000020

#define DEFAULT_JUMBO_MTU       9000
#define MIN_MTU                 ETHERMTU
#define MAX_MTU                 DEFAULT_JUMBO_MTU       
#define DEFAULT_MTU             ETHERMTU

#define DEFAULT_ECORE_DEBUG_LEVEL       ECORE_LEVEL_VERBOSE 


#define DEFAULT_ECORE_DEBUG_MODULE      ECORE_MSG_DRV 

#define VLAN_TAGSZ              0x4

#define MAX_TC  1

#define DUPLEX_HALF     0 
#define DUPLEX_FULL     1

#define ETH_ALLEN       6

#define MAC_STRING              "%2x:%2x:%2x:%2x:%2x:%2x"
#define MACTOSTR(a)             a[0], a[1], a[2], a[3], a[4], a[5]

#define MAX_MC_SOFT_LIMIT 1024

#define qede_delay(_msecs_)   delay(drv_usectohz(_msecs_ * 1000))

#define QEDE_CMD 73


typedef struct _KstatRingMap
{
    uint32_t  idx;      /* ring index */
    void * qede;        /* reference back to qede_t */
} KstatRingMap;

#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];


union db_prod {
        struct eth_db_data data;
        uint32_t raw;
};

struct qede;
struct qede_fastpath;
struct qede_rx_ring;
struct qede_tx_pktinfo_s;

typedef struct qede_tx_ring {
        struct qede_fastpath    *fp;
        struct qede *qede;
        uint32_t tx_queue_index;
        uint16_t *hw_cons_ptr;

        /* pointer to driver ring control */
        struct ecore_chain      tx_bd_ring;
        u16                     sw_tx_cons;
        u16                     sw_tx_prod;
        u16                     bd_ring_size;

        /* From ecore_sp_tx_queue_start() */
        void __iomem *doorbell_addr;
        ddi_acc_handle_t        doorbell_handle;

        /* Saved copy of doorbell data for this tx queue */
        union db_prod           tx_db;

        uint32_t                fp_idx;
        kmutex_t                tx_lock;
        int                     tx_buf_size;
        uint32_t                tx_ring_size;
        bool                    queue_started;
        mac_ring_handle_t       mac_ring_handle;

        /* pre-allocated bcopy packets */
        qede_tx_bcopy_list_t    bcopy_list;
        /* pre-allocated dma handles */
        qede_dma_handles_list_t dmah_list;
        /* List of recycle entires for tx packets */
        qede_tx_recycle_list_t *tx_recycle_list;

#ifdef  DBLK_DMA_PREMAP 
        pm_handle_t             pm_handle;
#endif
        /* dma_handle for tx bd ring */
        ddi_dma_handle_t        tx_bd_dmah;
        ddi_dma_handle_t        tx_pbl_dmah;

        bool                    tx_q_sleeping;

        uint64_t                tx_pkt_count;
        uint64_t                tx_byte_count;
        uint64_t                tx_pkt_dropped;
        uint64_t                tx_copy_count;
        uint64_t                tx_bind_count;
        uint64_t                tx_bind_fail;
        uint64_t                tx_premap_count;
        uint64_t                tx_premap_fail;
        uint64_t                tx_pullup_count;
        uint64_t                tx_too_many_cookies;
        uint64_t                tx_lso_pkt_count;
        uint64_t                tx_ring_pause;
        uint64_t                tx_too_many_mblks;
        uint64_t                tx_mapped_pkts;
        uint64_t                tx_jumbo_pkt_count;
        struct ecore_queue_cid *p_cid;
} qede_tx_ring_t;


typedef struct qede_vector_info {
        /* 
         * Pointer to a fastpath structure,
         * or to a hwfnc.
         */ 
        void *fp;
        struct qede *qede;
        uint32_t vect_index;
        bool handler_added;
        /* set and cleared by ISR, checked by stop path
         * when waiting for quiesce
         */
        bool in_isr;
} qede_vector_info_t; 


typedef struct qede_fastpath {
        qede_vector_info_t *vect_info;

        /* Status block associated with this fp */
        ddi_dma_handle_t        sb_dma_handle; 
        ddi_acc_handle_t        sb_acc_handle;
        struct status_block *sb_virt;
        uint64_t                sb_phys;

        struct ecore_sb_info *sb_info;
        struct qede_rx_ring *rx_ring;
        qede_tx_ring_t  *tx_ring[MAX_TC];
        struct qede *qede;

        uint32_t        fp_index;
        uint32_t        fp_hw_eng_index;
        uint32_t        vport_id;       /* */   
        uint32_t        stats_id;       /* vport id to hold stats */    
        uint32_t        rx_queue_index; 
        uint32_t        rss_id;
        kmutex_t        fp_lock;
        uint32_t        disabled_by_poll;
} qede_fastpath_t;

enum qede_agg_state {
        QEDE_AGG_STATE_NONE  = 0,
        QEDE_AGG_STATE_START = 1,
        QEDE_AGG_STATE_ERROR = 2
};

#define QEDE_MAX_BD_PER_AGG 16
struct qede_rx_buffer_s;
typedef struct qede_lro_info {
        uint16_t pars_flags;
        uint16_t pad;
        uint16_t vlan_tag;
        uint16_t bd_count;
        uint32_t rss_hash;
        uint32_t header_len;
        uint32_t free_buffer_count;
        struct qede_rx_buffer_s *rx_buffer[QEDE_MAX_BD_PER_AGG];
        enum qede_agg_state agg_state;
} qede_lro_info_t;

typedef struct qede_dma_info_s {
        ddi_acc_handle_t        acc_handle;
        ddi_dma_handle_t        dma_handle;
        u32     ncookies;
        u32     offset;
        u64     phys_addr;
        void *virt_addr;
        u32     pad;
} qede_dma_info_t;

enum rx_buf_state {
        RX_BUF_STATE_FREE,
        RX_BUF_STATE_WITH_FW,
        RX_BUF_STATE_WITH_OS,
        RX_BUF_STATE_WITH_DRV,
};

struct qede_rx_buf_area;

typedef struct qede_rx_buffer_s {
        qede_dma_info_t dma_info;
        mblk_t *mp;
        u32             index;
        struct qede_rx_ring *rx_ring;

        /* Recycle function */
        frtn_t          recycle;
        u32             ref_cnt;
        enum rx_buf_state       buf_state;
        struct qede_rx_buf_area *rx_buf_area;
} qede_rx_buffer_t;

typedef struct qede_rx_buf_list_s {
        kmutex_t                lock;
        u16                     head, tail;
        u32                     num_entries;
        qede_rx_buffer_t *buf_list[DEFAULT_RX_RING_SIZE];
} qede_rx_buf_list_t;

typedef struct qede_rx_buf_area {
        //kmutex_t              rx_buf_area_lock;
        qede_rx_buffer_t        rx_buf_pool[DEFAULT_RX_RING_SIZE];

        qede_rx_buf_list_t      active_buf_list;
        qede_rx_buf_list_t      passive_buf_list;
                
        u32                     bufs_per_page;
        struct qede_rx_ring *rx_ring;
        u32                     inactive;
        u32                     buf_upstream;
} qede_rx_buf_area_t;

typedef struct qede_rx_ring {
        uint32_t                rx_buf_count;
        uint32_t                rx_buf_size;
        /*
         * Pointer to an array of producer indicies. 
         * Returned in call to ecore_sp_eth_rx_queue_start()
         * during qede_start(). Driver uses address
         * to update producer indicies for
         * CQE and RX buffer chains.
         */
        void __iomem *hw_rxq_prod_addr;

        /* Pointer to hw cqe consumer index.
         * Taken from sb_virt->pi_array after
         * rx_ring has been started by calling
         * ecore_sp_eth_rx_queue_start().
         * This value is little endian and requires
         * swapping on big endian platforms.
         * It is updated by ecore and read by
         * the driver while processing rings.
         */
        uint16_t *hw_cons_ptr;

        u16     sw_rx_cons;
        u16 sw_rx_prod;
        u16                     last_cqe_consumer;

        /*
         * Driver buffer descriptor ring defining
         * buffers on a one-to-one releationship
         * to ecore_chain rx_bd_ring.
         */
        qede_rx_buffer_t *rx_buffers;
        qede_rx_buf_area_t *rx_buf_area;
        /*
         * Descriptor rings returned from
         * ecore_chain_alloc()
         */
        struct ecore_chain      rx_bd_ring;
        struct ecore_chain      rx_cqe_ring;

        uint32_t        rss_id;
        bool    queue_started;
        bool    mac_ring_started;
        kmutex_t        rx_lock;                        
        kmutex_t        rx_replen_lock;
        mac_ring_handle_t       mac_ring_handle;
        u64                     mr_gen_num; /* Mac rings generation number */
        uint32_t                group_index;
        qede_fastpath_t *fp;
        struct qede *qede;

        /* dma_handles for rx dma mem */
        ddi_dma_handle_t        rx_bd_dmah;
        ddi_dma_handle_t        rx_cqe_dmah;
        ddi_dma_handle_t        rx_cqe_pbl_dmah;
        uint32_t        rx_copy_threshold;
        uint32_t        rx_low_buffer_threshold;
        struct qede_lro_info lro_info[ETH_TPA_MAX_AGGS_NUM];
        uint32_t lro_active_count;

        uint64_t rx_copy_cnt;
        uint64_t rx_drop_cnt;
        uint64_t rx_low_water_cnt;
        uint64_t rx_poll_cnt;
        uint64_t rx_reg_pkt_cnt;
        uint64_t rx_jumbo_pkt_cnt;
        uint64_t rx_lro_pkt_cnt;
        uint64_t rx_byte_cnt;
        uint64_t rx_pkt_cnt;
        uint8_t intrEnableCnt;
        uint8_t intrDisableCnt;
        struct ecore_queue_cid *p_cid;
} qede_rx_ring_t;

typedef uint32_t qede_offload_t;
typedef struct qede_params {
        qede_offload_t  enabled_offloads;
        boolean_t multi_promisc_fl;
        boolean_t promisc_fl;
        uint32_t link_state;
        u32     loopback_mode;
} qede_params_t;

typedef struct qede_intr_context {
    /* bit field indicating     enable/disable state of vector */
    volatile uint32_t   intr_state;
        qede_vector_info_t *intr_vect_info;
        int intr_vect_info_array_size;                  /* based on hw max vectors */
        ddi_intr_handle_t       *intr_hdl_array;                /* handle array from ddi_intr_alloc() */
        int intr_hdl_array_size;                        /* based on hw max vectors */
        int intr_types_available;                       /* from ddi_intr_get_supported_types */
        int intr_type_forced;                           /* from qede.conf */
        int intr_type_in_use;                           /* interrupt type currently used */
        int     intr_vect_supported;            /* from ddi_intr_get_nintrs */
        int     intr_vect_available;                            /* from ddi_intr_get_navail */
        int intr_vect_to_request;                       /* intr count requested */
        int intr_vect_allocated;                        /* intr count taken */
        uint32_t        intr_pri;
        int intr_cap;
        uint32_t        intr_fp_vector_count;
    enum ecore_int_mode intr_mode;
} qede_intr_context_t;

#define QEDE_LINK_PAUSE_AUTONEG_ENABLE           (1 << 0)
#define QEDE_LINK_PAUSE_RX_ENABLE                (1 << 1)
#define QEDE_LINK_PAUSE_TX_ENABLE                (1 << 2)

typedef struct qede_props {
        uint32_t link_speed;
        boolean_t link_duplex;
        boolean_t tx_pause;
        boolean_t rx_pause;
        time_t    uptime;
} qede_props_t; 

typedef struct qede_link_props {
        uint8_t port_type;
        boolean_t autoneg;
        boolean_t asym_pause;
        boolean_t pause;
        boolean_t param_100000fdx;
        boolean_t param_50000fdx;
        boolean_t param_40000fdx;
        boolean_t param_25000fdx;
        boolean_t param_10000fdx;
        boolean_t param_1000fdx;
        boolean_t param_1000hdx;
} qede_link_props_t;

typedef struct qede_link_cfg {
        boolean_t link_up;
        uint32_t speed;
        uint8_t duplex;
        boolean_t autoneg;
        uint32_t pause_cfg;
        qede_link_props_t supp_capab;
        qede_link_props_t adv_capab;
        qede_link_props_t rem_capab;
        uint32_t media;
        uint32_t txr_data;
} qede_link_cfg_t;

enum qede_filter_type {
        QEDE_FILTER_UCAST,
        QEDE_FILTER_MCAST,
        QEDE_FILTER_RX_MODE,
        QEDE_MAX_FILTER_TYPES,

};

enum qede_filter_rx_mode_type {
        QEDE_FILTER_RX_MODE_REGULAR,
        QEDE_FILTER_RX_MODE_MULTI_PROMISC,
        QEDE_FILTER_RX_MODE_PROMISC,
};



struct qede_mcast_filter_params {
        enum qede_filter_rx_mode_type acc_flg;
        struct ecore_filter_mcast mcast;
};

#define QEDE_MAX_UCST_CNT       8
typedef struct qede_mac_addr {
         struct ether_addr mac_addr;
          boolean_t         set;
} qede_mac_addr_t;


        
enum qede_state {
        QEDE_STATE_UNKNOWN,     
        QEDE_STATE_ATTACHED,    
        QEDE_STATE_STARTING,    /* Transitioning State */       
        QEDE_STATE_STARTED,     
        QEDE_STATE_STOPPING,    /* Transitioning State */       
        QEDE_STATE_STOPPED,     
        QEDE_STATE_SUSPENDING,  /* Transitioning State */       
        QEDE_STATE_SUSPENDED,   
        QEDE_STATE_RESUMING,    /* Transitioning State */       
        QEDE_STATE_FAILED,      
};

enum qede_attach_resources {
        QEDE_STRUCT_ALLOC = (1 << 0),
        QEDE_FM =                       (1 << 1),
        QEDE_PCI =      (1 << 2),
        QEDE_ECORE_HW_PREP = (1 << 3),
        QEDE_SET_PARAMS = (1 << 4),
        QEDE_CALLBACK = (1 << 5),
        QEDE_IO_STRUCT_ALLOC = (1 << 6),
        QEDE_INIT_LOCKS = (1 << 7),
        QEDE_INTR_ALLOC = (1 << 8),
        QEDE_INTR_CONFIG = (1 << 9),
        QEDE_EDEV_CONFIG = (1 << 10),
        QEDE_KSTAT_INIT = (1 << 11),
        QEDE_GLD_INIT = (1 << 12),
        QEDE_SP_INTR_ENBL = (1 << 13),
        QEDE_ECORE_HW_INIT = (1 << 14),
/*
         = (1 << 15),
         = (1 << 16),
         = (1 << 17),
         = (1 << 18),
         = (1 << 19),
         = (1 << 20),
*/
};

enum qede_vport_state {
        QEDE_VPORT_UNKNOWN,
        QEDE_VPORT_STARTED,
        QEDE_VPORT_ON,
        QEDE_VPORT_OFF,
        QEDE_VPORT_STOPPED
};

#define QEDE_MAX_GROUPS         1
typedef struct qede_mac_group {
        int                             group_index;
        mac_group_handle_t              group_handle;
        struct qede *qede;
} qede_mac_group_t;

typedef struct qede_link_input_params {
        struct ecore_mcp_link_params    default_link_params;
        u32                             loopback_mode;
}qede_link_input_params_t;

typedef struct qede {
        struct ecore_dev                edev; /* keep this at the beginning of the structure */
        dev_info_t *dip;
        int                             instance;
        enum qede_state                 qede_state;
#define MAX_QEDE_NAME_LEN               8
        char                            name[MAX_QEDE_NAME_LEN];

        /* PCI access handle */
        ddi_acc_handle_t                pci_cfg_handle;

        /* BAR 0 - registers */
        ddi_acc_handle_t                regs_handle;
        off_t                           regview_size;
        caddr_t                         regview;
        uint64_t                        pci_bar0_base;

        /* BAR 2 - doorbell */
        ddi_acc_handle_t                doorbell_handle;
        off_t                           doorbell_size;
        caddr_t                         doorbell;
        uint64_t                        pci_bar2_base;

        /* Vport params */
        struct ecore_sp_vport_update_params     vport_params[MAX_HWFNS_PER_DEVICE];
        struct ecore_rss_params         rss_params[MAX_HWFNS_PER_DEVICE];
        enum qede_vport_state           vport_state[MAX_HWFNS_PER_DEVICE];

        /* mac Layer related vars */
        mac_handle_t                    mac_handle;
        qede_mac_group_t                rx_groups[QEDE_MAX_GROUPS];
        qede_mac_group_t                tx_groups[QEDE_MAX_GROUPS];

        u8 *sp_dpc;
        /* 
         * pre-mapped buffer cache handle for TX 
         * used for getting sglist for mbkls
         * that were already mapped in mac layer
         */
#ifdef  DBLK_DMA_PREMAP 
        pm_handle_t                     pm_handle;
#endif

        /* current operating paramters */
        uint32_t                        mtu;
        uint32_t                        num_fp;
        uint32_t                        mc_cnt;

        uint32_t                        tx_ring_size;
        uint32_t                        tx_buf_size;
        uint16_t                        tx_recycle_threshold;
        u16                             pad; // remove later

        int                             checksum;
        qede_offload_t                  enabled_offloads;
        uint32_t                        rx_ring_size;
        uint32_t                        rx_buf_count;
        uint32_t                        rx_buf_size;
        uint32_t                        rx_copy_threshold;
        uint32_t                        rx_low_buffer_threshold;
        boolean_t                       lso_enable;
        boolean_t                       lro_enable;
        boolean_t                       jumbo_enable;
        boolean_t                       log_enable;
        uint32_t                        ecore_debug_level;
        uint32_t                        ecore_debug_module;
        boolean_t                       intr_coalesce;
        uint32_t                        intr_rx_coal_usec;
        uint32_t                        intr_tx_coal_usec;

        /* From ecore_hw_init */
        uint32_t                        num_hwfns;
        unsigned char                   ether_addr[ETHERADDRL];
        uint32_t                        num_tc;

        qede_mac_addr_t                 ucst_mac[QEDE_MAX_UCST_CNT];
        uint32_t                        ucst_total;
        uint32_t                        ucst_avail;
        qede_mac_addr_t                 suspnd_mac_list[QEDE_MAX_UCST_CNT];


        /* software data structures for tx/rx */
        qede_intr_context_t             intr_ctx;
        qede_fastpath_t                 fp_array[MAX_FASTPATH_COUNT];
        struct ecore_sb_info            sb_array[MAX_FASTPATH_COUNT];
        qede_rx_ring_t                  rx_array[MAX_FASTPATH_COUNT];
        qede_tx_ring_t    tx_array[MAX_TC_COUNT][MAX_FASTPATH_COUNT];

        uint16_t                        tx_bcopy_threshold;
        uint16_t                        pad1; /* remove later */

        /* status_block phys mem */
        bool                            sb_phy_mem_alloc;

        kmutex_t                        drv_lock;
        kmutex_t                        watch_lock;
        uint32_t                        callback_flags;
        enum qede_attach_resources      attach_resources;

        /*
         * qede osal mem management queues
         */
        qede_phys_mem_list_t            phys_mem_list;
        qede_mem_list_t                 mem_list;

        qede_props_t                    props;
        qede_link_cfg_t                 hwinit;
        qede_link_cfg_t                 curcfg;
        qede_params_t                   params;
        volatile uint32_t               plumbed;
        qede_mcast_list_t               mclist;

        uint32_t                        mfw_ver;

        char                            devName[QEDE_STR_SIZE];
        char                            version[QEDE_STR_SIZE];
        char                            versionFW[QEDE_STR_SIZE];
        char                            versionMFW[QEDE_STR_SIZE];
        char                            chip_name[QEDE_STR_SIZE];
        char                            chipID[QEDE_STR_SIZE];
        char                            intrAlloc[QEDE_STR_SIZE];
        char                            bus_dev_func[QEDE_STR_SIZE];
        char                            vendor_device[QEDE_STR_SIZE];

        uint64_t                        txTotalPkts;
        uint64_t                        txTotalBytes;
        uint64_t                        txTotalDiscards;
        uint64_t                        rxTotalPkts;
        uint64_t                        rxTotalBytes;
        uint64_t                        rxTotalDiscards;

        uint64_t                        intrFired;
        kmutex_t                        kstat_lock;
        kmutex_t                        gld_lock;
        uint64_t                        intrSbCnt[MAX_FASTPATH_COUNT + 1];
        uint64_t     intrSbNoChangeCnt[MAX_FASTPATH_COUNT + 1];
        uint64_t                        intrSbPollCnt[MAX_FASTPATH_COUNT + 1];
        uint64_t                        intrSbPollNoChangeCnt[MAX_FASTPATH_COUNT + 1];
    
        kstat_t *kstats;
        kstat_t *kstats_link;
        kstat_t *kstats_intr;
        kstat_t *kstats_vport;
        kstat_t *kstats_rxq[MAX_FASTPATH_COUNT];
        KstatRingMap                    kstats_rxq_map[MAX_FASTPATH_COUNT];
        kstat_t *kstats_txq[MAX_FASTPATH_COUNT];
        KstatRingMap                    kstats_txq_map[MAX_FASTPATH_COUNT];
        struct ecore_eth_stats          save_stats;

        mblk_t  *stored_mp;
        int                             mp_index;
        qede_link_input_params_t        link_input_params;  /*(test) */
        uint32_t                        loop_back_mode;     /*(test) */
        bool                            lb_linkup;          /*(test) */
        uint32_t                        forced_speed_10G;
        uint8_t                         pci_func;    
        void *nvm_buf;
        void *nvm_buf_start;
        uint32_t                        nvm_buf_size;
        uint32_t                        copy_len;
        uint8_t                         *reserved_buf;  
        int                             fm_cap;
        uint64_t                        allocbFailures;
        volatile uint32_t               detach_unsafe;

} qede_t;

/*
 * ioctl commands
 */

typedef enum {
        QEDE_DRV_INFO = 2,
        QEDE_RD_PCICFG,
        QEDE_WR_PCICFG,
        QEDE_RW_REG,
        QEDE_RW_NVRAM,
        QEDE_FUNC_INFO,
        QEDE_MAC_ADDR
} qede_ioctl_cmd_t;



/*
 * ioctl message structure for FW update utility
 */

/* regiser read/write commands */ 
#define QEDE_REG_READ 0
#define QEDE_REG_WRITE 1

/* nvram read/write commands */
#define QEDE_NVRAM_CMD_READ 0
#define QEDE_NVRAM_CMD_WRITE 1
#define QEDE_NVRAM_CMD_PUT_FILE_DATA 2
#define QEDE_NVRAM_CMD_SET_SECURE_MODE 3
#define QEDE_NVRAM_CMD_DEL_FILE 4
#define QEDE_NVRAM_CMD_PUT_FILE_BEGIN 5
#define QEDE_NVRAM_CMD_GET_NVRAM_RESP 6

typedef struct {
        uint32_t cmd;
        uint32_t unused1;
        uint64_t off;
        uint32_t size;
        uint32_t rv;
        char uabc[2048];
        uint64_t address;
        void *ptr;      
} qede_ioctl_data_t;

typedef struct {
        uint32_t cmd;
        uint32_t unused1;
        uint64_t off;
        uint32_t size;
        uint32_t buf_size;
        char uabc[2048];
        uint64_t cmd2;
#define START_NVM_WRITE 1
#define ACCUMULATE_NVM_BUF 2
#define STOP_NVM_WRITE 3
#define READ_BUF 4
        void *ptr;
}qede_nvram_data_t;

typedef struct {
        char drv_name[MAX_QEDE_NAME_LEN];
        char drv_version[QEDE_STR_SIZE];
        char mfw_version[QEDE_STR_SIZE];
        char stormfw_version[QEDE_STR_SIZE];
        uint32_t eeprom_dump_len; /* in bytes */
        uint32_t reg_dump_len; /* in bytes */
        char bus_info[QEDE_STR_SIZE];
} qede_driver_info_t;   

typedef struct {
        uint32_t        supported;      /* Features this interface supports */
        uint32_t        advertising;    /* Features this interface advertises */
        uint32_t        speed;          /* The forced speed, 10Mb, 100Mb, gigabit */
        uint32_t        duplex;         /* Duplex, half or full */
        uint32_t        port;           /* Which connector port */
        uint32_t        phy_address;    /* port number*/
        uint32_t        autoneg;        /* Enable or disable autonegotiation */
} qede_func_info_t;


typedef struct {
        bool    link_up;                                   
        u32     supported_caps; /* In SUPPORTED defs */    
        u32     advertised_caps; /* In ADVERTISED defs */  
        u32     lp_caps; /* In ADVERTISED defs */          
        u32     speed; /* In Mb/s */                       
        u8      duplex; /* In DUPLEX defs */               
        u8      port; /* In PORT defs */                   
        bool    autoneg;                                   
} qede_link_output_t;

#define PORT_FIBRE                      (1)
#define SUPPORTED_FIBRE                 (1 << 15)
#define SUPPORTED_Autoneg               (1 << 16)
#define SUPPORTED_Pause                 (1 << 17)
#define SUPPORTED_Asym_Pause            (1 << 18)
#define SUPPORTED_1000baseT_Half        (1 << 19)
#define SUPPORTED_1000baseT_Full        (1 << 20)
#define SUPPORTED_10000baseKR_Full      (1 << 21)
#define SUPPORTED_20000baseKR2_Full     (1 << 22)
#define SUPPORTED_40000baseKR4_Full     (1 << 23)
#define SUPPORTED_40000baseCR4_Full     (1 << 24)
#define SUPPORTED_40000baseSR4_Full     (1 << 25)
#define SUPPORTED_40000baseLR4_Full     (1 << 26)



typedef struct {
        uint32_t cmd;
#define QEDE_PCICFG_READ 0x01
#define QEDE_PCICFG_WRITE 0x02
        uint32_t reg;
        uint32_t val;
        uint32_t width;
} qede_pcicfg_rdw_t;
/*
 * (Internal) return values from ioctl subroutines
 *
 */
enum ioc_reply {
        IOC_INVAL = -1, /* bad, NAK with EINVAL */
        IOC_DONE, /* OK, reply sent  */
        IOC_ACK, /* OK, just send ACK  */
        IOC_REPLY, /* OK, just send reply */
        IOC_RESTART_ACK, /* OK, restart & ACK */
        IOC_RESTART_REPLY /* OK, restart & reply */
};

/*
 * Loop Back Modes
 */
enum {  
        QEDE_LOOP_NONE,
        QEDE_LOOP_INTERNAL,
        QEDE_LOOP_EXTERNAL,
};

/* Loopback test return values */
enum {  
        QEDE_LB_TEST_OK,
        QEDE_LB_SEND_WAIT_QUEUE_ERR,
        QEDE_LB_NORCV_ERR,
        QEDE_LB_NOMEM_ERR,
        QEDE_LB_TX_QUEUE_ERR,
        QEDE_LB_SHORT_DATA_ERR,
        QEDE_LB_SEQUENCE_ERR,
        QEDE_LB_DATA_ERR,
        QEDE_LB_ERRCNT,
        QEDE_LB_NOT_SUPPORTED,
        QEDE_LB_TEST_CHECK_CABLE,
        QEDE_LB_TEST_IN_PROGRESS
};

extern qede_link_props_t qede_def_link_props;
/* Functions exported by qede_cfg.c */
void qede_cfg_reset(qede_t *qede);
void qede_cfg_init(qede_t *qede);

/* Functions exported by qede_gld.c */
boolean_t qede_gld_init(qede_t *qede);
int qede_multicast(qede_t * qede, boolean_t flag, const uint8_t *ptr_mcaddr);
int qede_set_filter_rx_mode(qede_t *qede, enum qede_filter_rx_mode_type type);
int qede_set_rx_mac_mcast(qede_t *qede, enum ecore_filter_opcode opcode,
    uint8_t *mac, int mc_cnt);
int qede_ucst_find(qede_t *qede, const uint8_t *mac_addr);
int qede_clear_filters(qede_t *qede);
/* Functions exported by qede_main.c */
int
qede_stop(qede_t *);
int
qede_start(qede_t *);

#define QEDE_DOORBELL_WR        qede_bar2_write32_tx_doorbell
void
qede_bar2_write32_tx_doorbell(qede_tx_ring_t *tx_ring, u32 val);
void
qede_enable_hw_intr(qede_fastpath_t *);
void
qede_disable_hw_intr(qede_fastpath_t *);

/* Functions exported by qede_dbg.c */
extern void
qede_stacktrace(qede_t *);
extern void
qede_print_vport_params(qede_t *,
    struct ecore_sp_vport_update_params *);
void
qede_dump_single_mblk(qede_t *qede, mblk_t *mp);
void
qede_dump_mblk_chain_bnext_ptr(qede_t *qede, mblk_t *mp);
void
qede_dump_mblk_chain_bcont_ptr(qede_t *qede, mblk_t *mp);
void
qede_dump_bytes(char *, int);
void qede_dump_reg_cqe(struct eth_fast_path_rx_reg_cqe *cqe);
void qede_dump_start_lro_cqe(struct eth_fast_path_rx_tpa_start_cqe *);
void qede_dump_cont_lro_cqe(struct eth_fast_path_rx_tpa_cont_cqe *);
void qede_dump_end_lro_cqe(struct eth_fast_path_rx_tpa_end_cqe *);
void qede_dump_mblk_chain_bcont_ptr(qede_t *, mblk_t *);

/* Functions exported by qede_fp.c */
mblk_t *qede_fp_poll(void *arg, int poll_bytes, int poll_pkts);
int qede_fp_stat(mac_ring_driver_t rh, uint_t stat, u64 *val);
mblk_t *
qede_process_fastpath(qede_fastpath_t *fp,
    int nbytes, int npkts, int *work_done);
void
qede_desc_dma_mem_sync(ddi_dma_handle_t *dma_handle,
    uint_t start, uint_t count, uint_t range,
    uint_t unit_size, uint_t direction);

/* Functions exported by qede_osal.c */
u32 qede_osal_cleanup(qede_t *qede);
int
qede_osal_find_dma_handle_for_block(qede_t *qede, void *addr,
    ddi_dma_handle_t *dma_handle);

/* Functions exported by qede_main.c */
int 
qede_get_mag_elem(qede_rx_ring_t *, qede_rx_buffer_t *);
void
qede_update_rx_q_producer(qede_rx_ring_t *rx_ring);
void qede_get_link_info(struct ecore_hwfn *hwfn,struct qede_link_cfg *lnkcfg);
int
qede_put_to_passive_list(qede_rx_ring_t *rx_ring, qede_rx_buffer_t *rx_buffer);
qede_rx_buffer_t *
qede_get_from_active_list(qede_rx_ring_t *, uint32_t *);
void
qede_replenish_rx_buffers(qede_rx_ring_t *);
void
qede_recycle_copied_rx_buffer(qede_rx_buffer_t *rx_buffer);
boolean_t qede_kstat_init(qede_t *qede);
void qede_kstat_fini(qede_t *qede);

/* Functions exported by qede_main.c */
void qede_update_media_info(struct ecore_dev *, qede_link_cfg_t *);
mac_ether_media_t qede_link_to_media(qede_link_cfg_t *, uint32_t);
#endif /* _QEDE_H */