The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ocs_fc/ocs_hw.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2017 Broadcom. All rights reserved.
    3  * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions are met:
    7  *
    8  * 1. Redistributions of source code must retain the above copyright notice,
    9  *    this list of conditions and the following disclaimer.
   10  *
   11  * 2. Redistributions in binary form must reproduce the above copyright notice,
   12  *    this list of conditions and the following disclaimer in the documentation
   13  *    and/or other materials provided with the distribution.
   14  *
   15  * 3. Neither the name of the copyright holder nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  *
   31  * $FreeBSD$
   32  */
   33 
   34 /**
   35  * @file
   36  * Defines the Hardware Abstraction Layer (HW) interface functions.
   37  */
   38 
   39 #ifndef _OCS_HW_H
   40 #define _OCS_HW_H
   41 
   42 #include "sli4.h"
   43 #include "ocs_hw.h"
   44 #include "ocs_stats.h"
   45 #include "ocs_utils.h"
   46 
   47 typedef struct ocs_hw_io_s ocs_hw_io_t;
   48 
   49 #if defined(OCS_INCLUDE_DEBUG)
   50 #else
   51 #define ocs_queue_history_wq(...)
   52 #define ocs_queue_history_cqe(...)
   53 #define ocs_queue_history_init(...)
   54 #define ocs_queue_history_free(...)
   55 #endif
   56 
   57 /**
   58  * @brief HW queue forward declarations
   59  */
   60 typedef struct hw_eq_s hw_eq_t;
   61 typedef struct hw_cq_s hw_cq_t;
   62 typedef struct hw_mq_s hw_mq_t;
   63 typedef struct hw_wq_s hw_wq_t;
   64 typedef struct hw_rq_s hw_rq_t;
   65 typedef struct hw_rq_grp_s hw_rq_grp_t;
   66 
   67 /* HW asserts/verify
   68  *
   69  */
   70 
   71 extern void _ocs_hw_assert(const char *cond, const char *filename, int linenum);
   72 extern void _ocs_hw_verify(const char *cond, const char *filename, int linenum);
   73 
   74 #if defined(HW_NDEBUG)
   75 #define ocs_hw_assert(cond)
   76 #define ocs_hw_verify(cond, ...)
   77 #else
   78 #define ocs_hw_assert(cond) \
   79         do { \
   80                 if ((!(cond))) { \
   81                         _ocs_hw_assert(#cond, __FILE__, __LINE__); \
   82                 } \
   83         } while (0)
   84 
   85 #define ocs_hw_verify(cond, ...) \
   86         do { \
   87                 if ((!(cond))) { \
   88                         _ocs_hw_verify(#cond, __FILE__, __LINE__); \
   89                         return __VA_ARGS__; \
   90                 } \
   91         } while (0)
   92 #endif
   93 #define ocs_hw_verify_arg(cond) ocs_hw_verify(cond, OCS_HW_RTN_INVALID_ARG)
   94 
   95 /*
   96  * HW completion loop control parameters.
   97  *
   98  * The HW completion loop must terminate periodically to keep the OS happy.  The
   99  * loop terminates when a predefined time has elapsed, but to keep the overhead of
  100  * computing time down, the time is only checked after a number of loop iterations
  101  * has completed.
  102  *
  103  * OCS_HW_TIMECHECK_ITERATIONS          number of loop iterations between time checks
  104  *
  105  */
  106 
  107 #define OCS_HW_TIMECHECK_ITERATIONS     100
  108 #define OCS_HW_MAX_NUM_MQ 1
  109 #define OCS_HW_MAX_NUM_RQ 32
  110 #define OCS_HW_MAX_NUM_EQ 16
  111 #define OCS_HW_MAX_NUM_WQ 32
  112 
  113 #define OCE_HW_MAX_NUM_MRQ_PAIRS 16
  114 
  115 #define OCS_HW_MAX_WQ_CLASS     4
  116 #define OCS_HW_MAX_WQ_CPU       128
  117 
  118 /*
  119  * A CQ will be assinged to each WQ (CQ must have 2X entries of the WQ for abort
  120  * processing), plus a separate one for each RQ PAIR and one for MQ
  121  */
  122 #define OCS_HW_MAX_NUM_CQ ((OCS_HW_MAX_NUM_WQ*2) + 1 + (OCE_HW_MAX_NUM_MRQ_PAIRS * 2))
  123 
  124 /*
  125  * Q hash - size is the maximum of all the queue sizes, rounded up to the next
  126  * power of 2
  127  */
  128 #define OCS_HW_Q_HASH_SIZE      B32_NEXT_POWER_OF_2(OCS_MAX(OCS_HW_MAX_NUM_MQ, OCS_MAX(OCS_HW_MAX_NUM_RQ, \
  129                                 OCS_MAX(OCS_HW_MAX_NUM_EQ, OCS_MAX(OCS_HW_MAX_NUM_WQ, \
  130                                 OCS_HW_MAX_NUM_CQ)))))
  131 
  132 #define OCS_HW_RQ_HEADER_SIZE   128
  133 #define OCS_HW_RQ_HEADER_INDEX  0
  134 
  135 /**
  136  * @brief Options for ocs_hw_command().
  137  */
  138 enum {
  139         OCS_CMD_POLL,   /**< command executes synchronously and busy-waits for completion */
  140         OCS_CMD_NOWAIT, /**< command executes asynchronously. Uses callback */
  141 };
  142 
  143 typedef enum {
  144         OCS_HW_RTN_SUCCESS = 0,
  145         OCS_HW_RTN_SUCCESS_SYNC = 1,
  146         OCS_HW_RTN_ERROR = -1,
  147         OCS_HW_RTN_NO_RESOURCES = -2,
  148         OCS_HW_RTN_NO_MEMORY = -3,
  149         OCS_HW_RTN_IO_NOT_ACTIVE = -4,
  150         OCS_HW_RTN_IO_ABORT_IN_PROGRESS = -5,
  151         OCS_HW_RTN_IO_PORT_OWNED_ALREADY_ABORTED = -6,
  152         OCS_HW_RTN_INVALID_ARG = -7,
  153 } ocs_hw_rtn_e;
  154 #define OCS_HW_RTN_IS_ERROR(e)  ((e) < 0)
  155 
  156 typedef enum {
  157         OCS_HW_RESET_FUNCTION,
  158         OCS_HW_RESET_FIRMWARE,
  159         OCS_HW_RESET_MAX
  160 } ocs_hw_reset_e;
  161 
  162 typedef enum {
  163         OCS_HW_N_IO,
  164         OCS_HW_N_SGL,
  165         OCS_HW_MAX_IO,
  166         OCS_HW_MAX_SGE,
  167         OCS_HW_MAX_SGL,
  168         OCS_HW_MAX_NODES,
  169         OCS_HW_MAX_RQ_ENTRIES,
  170         OCS_HW_TOPOLOGY,        /**< auto, nport, loop */
  171         OCS_HW_WWN_NODE,
  172         OCS_HW_WWN_PORT,
  173         OCS_HW_FW_REV,
  174         OCS_HW_FW_REV2,
  175         OCS_HW_IPL,
  176         OCS_HW_VPD,
  177         OCS_HW_VPD_LEN,
  178         OCS_HW_MODE,            /**< initiator, target, both */
  179         OCS_HW_LINK_SPEED,
  180         OCS_HW_IF_TYPE,
  181         OCS_HW_SLI_REV,
  182         OCS_HW_SLI_FAMILY,
  183         OCS_HW_RQ_PROCESS_LIMIT,
  184         OCS_HW_RQ_DEFAULT_BUFFER_SIZE,
  185         OCS_HW_AUTO_XFER_RDY_CAPABLE,
  186         OCS_HW_AUTO_XFER_RDY_XRI_CNT,
  187         OCS_HW_AUTO_XFER_RDY_SIZE,
  188         OCS_HW_AUTO_XFER_RDY_BLK_SIZE,
  189         OCS_HW_AUTO_XFER_RDY_T10_ENABLE,
  190         OCS_HW_AUTO_XFER_RDY_P_TYPE,
  191         OCS_HW_AUTO_XFER_RDY_REF_TAG_IS_LBA,
  192         OCS_HW_AUTO_XFER_RDY_APP_TAG_VALID,
  193         OCS_HW_AUTO_XFER_RDY_APP_TAG_VALUE,
  194         OCS_HW_DIF_CAPABLE,
  195         OCS_HW_DIF_SEED,
  196         OCS_HW_DIF_MODE,
  197         OCS_HW_DIF_MULTI_SEPARATE,
  198         OCS_HW_DUMP_MAX_SIZE,
  199         OCS_HW_DUMP_READY,
  200         OCS_HW_DUMP_PRESENT,
  201         OCS_HW_RESET_REQUIRED,
  202         OCS_HW_FW_ERROR,
  203         OCS_HW_FW_READY,
  204         OCS_HW_HIGH_LOGIN_MODE,
  205         OCS_HW_PREREGISTER_SGL,
  206         OCS_HW_HW_REV1,
  207         OCS_HW_HW_REV2,
  208         OCS_HW_HW_REV3,
  209         OCS_HW_LINKCFG,
  210         OCS_HW_ETH_LICENSE,
  211         OCS_HW_LINK_MODULE_TYPE,
  212         OCS_HW_NUM_CHUTES,
  213         OCS_HW_WAR_VERSION,
  214         OCS_HW_DISABLE_AR_TGT_DIF,
  215         OCS_HW_EMULATE_I_ONLY_AAB, /**< emulate IAAB=0 for initiator-commands only */
  216         OCS_HW_EMULATE_TARGET_WQE_TIMEOUT, /**< enable driver timeouts for target WQEs */
  217         OCS_HW_LINK_CONFIG_SPEED,
  218         OCS_HW_CONFIG_TOPOLOGY,
  219         OCS_HW_BOUNCE,
  220         OCS_HW_PORTNUM,
  221         OCS_HW_BIOS_VERSION_STRING,
  222         OCS_HW_RQ_SELECT_POLICY,
  223         OCS_HW_SGL_CHAINING_CAPABLE,
  224         OCS_HW_SGL_CHAINING_ALLOWED,
  225         OCS_HW_SGL_CHAINING_HOST_ALLOCATED,
  226         OCS_HW_SEND_FRAME_CAPABLE,
  227         OCS_HW_RQ_SELECTION_POLICY,
  228         OCS_HW_RR_QUANTA,
  229         OCS_HW_FILTER_DEF,
  230         OCS_HW_MAX_VPORTS,
  231         OCS_ESOC,
  232         OCS_HW_FW_TIMED_OUT,
  233 } ocs_hw_property_e;
  234 
  235 enum {
  236         OCS_HW_TOPOLOGY_AUTO,
  237         OCS_HW_TOPOLOGY_NPORT,
  238         OCS_HW_TOPOLOGY_LOOP,
  239         OCS_HW_TOPOLOGY_NONE,
  240         OCS_HW_TOPOLOGY_MAX
  241 };
  242 
  243 enum {
  244         OCS_HW_MODE_INITIATOR,
  245         OCS_HW_MODE_TARGET,
  246         OCS_HW_MODE_BOTH,
  247         OCS_HW_MODE_MAX
  248 };
  249 
  250 /**
  251  * @brief Port protocols
  252  */
  253 
  254 typedef enum {
  255         OCS_HW_PORT_PROTOCOL_ISCSI,
  256         OCS_HW_PORT_PROTOCOL_FCOE,
  257         OCS_HW_PORT_PROTOCOL_FC,
  258         OCS_HW_PORT_PROTOCOL_OTHER,
  259 } ocs_hw_port_protocol_e;
  260 
  261 #define OCS_HW_MAX_PROFILES     40
  262 /**
  263  * @brief A Profile Descriptor
  264  */
  265 typedef struct {
  266         uint32_t        profile_index;
  267         uint32_t        profile_id;
  268         char            profile_description[512];
  269 } ocs_hw_profile_descriptor_t;
  270 
  271 /**
  272  * @brief A Profile List
  273  */
  274 typedef struct {
  275         uint32_t                        num_descriptors;
  276         ocs_hw_profile_descriptor_t     descriptors[OCS_HW_MAX_PROFILES];
  277 } ocs_hw_profile_list_t;
  278 
  279 /**
  280  * @brief Defines DIF operation modes
  281  */
  282 enum {
  283         OCS_HW_DIF_MODE_INLINE,
  284         OCS_HW_DIF_MODE_SEPARATE,
  285 };
  286 
  287 /**
  288  * @brief Defines the type of RQ buffer
  289  */
  290 typedef enum {
  291         OCS_HW_RQ_BUFFER_TYPE_HDR,
  292         OCS_HW_RQ_BUFFER_TYPE_PAYLOAD,
  293         OCS_HW_RQ_BUFFER_TYPE_MAX,
  294 } ocs_hw_rq_buffer_type_e;
  295 
  296 /**
  297  * @brief Defines a wrapper for the RQ payload buffers so that we can place it
  298  *        back on the proper queue.
  299  */
  300 typedef struct {
  301         uint16_t rqindex;
  302         ocs_dma_t dma;
  303 } ocs_hw_rq_buffer_t;
  304 
  305 /**
  306  * @brief T10 DIF operations.
  307  */
  308 typedef enum {
  309         OCS_HW_DIF_OPER_DISABLED,
  310         OCS_HW_SGE_DIF_OP_IN_NODIF_OUT_CRC,
  311         OCS_HW_SGE_DIF_OP_IN_CRC_OUT_NODIF,
  312         OCS_HW_SGE_DIF_OP_IN_NODIF_OUT_CHKSUM,
  313         OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_NODIF,
  314         OCS_HW_SGE_DIF_OP_IN_CRC_OUT_CRC,
  315         OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_CHKSUM,
  316         OCS_HW_SGE_DIF_OP_IN_CRC_OUT_CHKSUM,
  317         OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_CRC,
  318         OCS_HW_SGE_DIF_OP_IN_RAW_OUT_RAW,
  319 } ocs_hw_dif_oper_e;
  320 
  321 #define OCS_HW_DIF_OPER_PASS_THRU       OCS_HW_SGE_DIF_OP_IN_CRC_OUT_CRC
  322 #define OCS_HW_DIF_OPER_STRIP           OCS_HW_SGE_DIF_OP_IN_CRC_OUT_NODIF
  323 #define OCS_HW_DIF_OPER_INSERT          OCS_HW_SGE_DIF_OP_IN_NODIF_OUT_CRC
  324 
  325 /**
  326  * @brief T10 DIF block sizes.
  327  */
  328 typedef enum {
  329         OCS_HW_DIF_BK_SIZE_512,
  330         OCS_HW_DIF_BK_SIZE_1024,
  331         OCS_HW_DIF_BK_SIZE_2048,
  332         OCS_HW_DIF_BK_SIZE_4096,
  333         OCS_HW_DIF_BK_SIZE_520,
  334         OCS_HW_DIF_BK_SIZE_4104,
  335         OCS_HW_DIF_BK_SIZE_NA = 0
  336 } ocs_hw_dif_blk_size_e;
  337 
  338 /**
  339  * @brief Link configurations.
  340  */
  341 typedef enum {
  342         OCS_HW_LINKCFG_4X10G = 0,
  343         OCS_HW_LINKCFG_1X40G,
  344         OCS_HW_LINKCFG_2X16G,
  345         OCS_HW_LINKCFG_4X8G,
  346         OCS_HW_LINKCFG_4X1G,
  347         OCS_HW_LINKCFG_2X10G,
  348         OCS_HW_LINKCFG_2X10G_2X8G,
  349 
  350         /* must be last */
  351         OCS_HW_LINKCFG_NA,
  352 } ocs_hw_linkcfg_e;
  353 
  354 /**
  355  * @brief link module types
  356  *
  357  * (note: these just happen to match SLI4 values)
  358  */
  359 
  360 enum {
  361         OCS_HW_LINK_MODULE_TYPE_1GB = 0x0004,
  362         OCS_HW_LINK_MODULE_TYPE_2GB = 0x0008,
  363         OCS_HW_LINK_MODULE_TYPE_4GB = 0x0040,
  364         OCS_HW_LINK_MODULE_TYPE_8GB = 0x0080,
  365         OCS_HW_LINK_MODULE_TYPE_10GB = 0x0100,
  366         OCS_HW_LINK_MODULE_TYPE_16GB = 0x0200,
  367         OCS_HW_LINK_MODULE_TYPE_32GB = 0x0400,
  368 };
  369 
  370 /**
  371  * @brief T10 DIF information passed to the transport.
  372  */
  373 typedef struct ocs_hw_dif_info_s {
  374         ocs_hw_dif_oper_e dif_oper;
  375         ocs_hw_dif_blk_size_e blk_size;
  376         uint32_t ref_tag_cmp;
  377         uint32_t ref_tag_repl;
  378         uint32_t app_tag_cmp:16,
  379                 app_tag_repl:16;
  380         uint32_t check_ref_tag:1,
  381                 check_app_tag:1,
  382                 check_guard:1,
  383                 auto_incr_ref_tag:1,
  384                 repl_app_tag:1,
  385                 repl_ref_tag:1,
  386                 dif:2,
  387                 dif_separate:1,
  388 
  389                 /* If the APP TAG is 0xFFFF, disable checking the REF TAG and CRC fields */
  390                 disable_app_ffff:1,
  391 
  392                 /* if the APP TAG is 0xFFFF and REF TAG is 0xFFFF_FFFF, disable checking the received CRC field. */
  393                 disable_app_ref_ffff:1,
  394 
  395                 :21;
  396         uint16_t dif_seed;
  397 } ocs_hw_dif_info_t;
  398 typedef enum {
  399         OCS_HW_ELS_REQ, /**< ELS request */
  400         OCS_HW_ELS_RSP, /**< ELS response */
  401         OCS_HW_ELS_RSP_SID,     /**< ELS response, override the S_ID */
  402         OCS_HW_FC_CT,           /**< FC Common Transport */
  403         OCS_HW_FC_CT_RSP,       /**< FC Common Transport Response */
  404         OCS_HW_BLS_ACC, /**< BLS accept (BA_ACC) */
  405         OCS_HW_BLS_ACC_SID,     /**< BLS accept (BA_ACC), override the S_ID */
  406         OCS_HW_BLS_RJT, /**< BLS reject (BA_RJT) */
  407         OCS_HW_BCAST,           /**< Class 3 broadcast sequence */
  408         OCS_HW_IO_TARGET_READ,
  409         OCS_HW_IO_TARGET_WRITE,
  410         OCS_HW_IO_TARGET_RSP,
  411         OCS_HW_IO_INITIATOR_READ,
  412         OCS_HW_IO_INITIATOR_WRITE,
  413         OCS_HW_IO_INITIATOR_NODATA,
  414         OCS_HW_IO_DNRX_REQUEUE,
  415         OCS_HW_IO_MAX,
  416 } ocs_hw_io_type_e;
  417 
  418 typedef enum {
  419         OCS_HW_IO_STATE_FREE,
  420         OCS_HW_IO_STATE_INUSE,
  421         OCS_HW_IO_STATE_WAIT_FREE,
  422         OCS_HW_IO_STATE_WAIT_SEC_HIO,
  423 } ocs_hw_io_state_e;
  424 
  425 /* Descriptive strings for the HW IO request types (note: these must always
  426  * match up with the ocs_hw_io_type_e declaration) */
  427 #define OCS_HW_IO_TYPE_STRINGS \
  428         "ELS request", \
  429         "ELS response", \
  430         "ELS response(set SID)", \
  431         "FC CT request", \
  432         "BLS accept", \
  433         "BLS accept(set SID)", \
  434         "BLS reject", \
  435         "target read", \
  436         "target write", \
  437         "target response", \
  438         "initiator read", \
  439         "initiator write", \
  440         "initiator nodata",
  441 
  442 /**
  443  * @brief HW command context.
  444  *
  445  * Stores the state for the asynchronous commands sent to the hardware.
  446  */
  447 typedef struct ocs_command_ctx_s {
  448         ocs_list_t      link;
  449         /**< Callback function */
  450         int32_t         (*cb)(struct ocs_hw_s *, int32_t, uint8_t *, void *);
  451         void            *arg;   /**< Argument for callback */
  452         uint8_t         *buf;   /**< buffer holding command / results */
  453         void            *ctx;   /**< upper layer context */
  454 } ocs_command_ctx_t;
  455 
  456 typedef struct ocs_hw_sgl_s {
  457         uintptr_t       addr;
  458         size_t          len;
  459 } ocs_hw_sgl_t;
  460 
  461 /**
  462  * @brief HW callback type
  463  *
  464  * Typedef for HW "done" callback.
  465  */
  466 typedef int32_t (*ocs_hw_done_t)(struct ocs_hw_io_s *, ocs_remote_node_t *, uint32_t len, int32_t status, uint32_t ext, void *ul_arg);
  467 
  468 typedef union ocs_hw_io_param_u {
  469         struct {
  470                 uint16_t ox_id;
  471                 uint16_t rx_id;
  472                 uint8_t  payload[12];   /**< big enough for ABTS BA_ACC */
  473         } bls;
  474         struct {
  475                 uint32_t s_id;
  476                 uint16_t ox_id;
  477                 uint16_t rx_id;
  478                 uint8_t  payload[12];   /**< big enough for ABTS BA_ACC */
  479         } bls_sid;
  480         struct {
  481                 uint8_t r_ctl;
  482                 uint8_t type;
  483                 uint8_t df_ctl;
  484                 uint8_t timeout;
  485         } bcast;
  486         struct {
  487                 uint16_t ox_id;
  488                 uint8_t timeout;
  489         } els;
  490         struct {
  491                 uint32_t s_id;
  492                 uint16_t ox_id;
  493                 uint8_t timeout;
  494         } els_sid;
  495         struct {
  496                 uint8_t r_ctl;
  497                 uint8_t type;
  498                 uint8_t df_ctl;
  499                 uint8_t timeout;
  500         } fc_ct;
  501         struct {
  502                 uint8_t r_ctl;
  503                 uint8_t type;
  504                 uint8_t df_ctl;
  505                 uint8_t timeout;
  506                 uint16_t ox_id;
  507         } fc_ct_rsp;
  508         struct {
  509                 uint32_t offset;
  510                 uint16_t ox_id;
  511                 uint16_t flags;
  512                 uint8_t cs_ctl;
  513                 ocs_hw_dif_oper_e dif_oper;
  514                 ocs_hw_dif_blk_size_e blk_size;
  515                 uint8_t timeout;
  516                 uint32_t app_id;
  517         } fcp_tgt;
  518         struct {
  519                 ocs_dma_t       *cmnd;
  520                 ocs_dma_t       *rsp;
  521                 ocs_hw_dif_oper_e dif_oper;
  522                 ocs_hw_dif_blk_size_e blk_size;
  523                 uint32_t        cmnd_size;
  524                 uint16_t        flags;
  525                 uint8_t         timeout;
  526                 uint32_t        first_burst;
  527         } fcp_ini;
  528 } ocs_hw_io_param_t;
  529 
  530 /**
  531  * @brief WQ steering mode
  532  */
  533 typedef enum {
  534         OCS_HW_WQ_STEERING_CLASS,
  535         OCS_HW_WQ_STEERING_REQUEST,
  536         OCS_HW_WQ_STEERING_CPU,
  537 } ocs_hw_wq_steering_e;
  538 
  539 /**
  540  * @brief HW wqe object
  541  */
  542 typedef struct {
  543         uint32_t        abort_wqe_submit_needed:1,      /**< set if abort wqe needs to be submitted */
  544                         send_abts:1,                    /**< set to 1 to have hardware to automatically send ABTS */
  545                         auto_xfer_rdy_dnrx:1,           /**< TRUE if DNRX was set on this IO */
  546                         :29;
  547         uint32_t        id;
  548         uint32_t        abort_reqtag;
  549         ocs_list_link_t link;
  550         uint8_t         *wqebuf;                        /**< work queue entry buffer */
  551 } ocs_hw_wqe_t;
  552 
  553 /**
  554  * @brief HW IO object.
  555  *
  556  * Stores the per-IO information necessary for both the lower (SLI) and upper
  557  * layers (ocs).
  558  */
  559 struct ocs_hw_io_s {
  560         /* Owned by HW */
  561         ocs_list_link_t link;           /**< used for busy, wait_free, free lists */
  562         ocs_list_link_t wqe_link;       /**< used for timed_wqe list */
  563         ocs_list_link_t dnrx_link;      /**< used for io posted dnrx list */
  564         ocs_hw_io_state_e state;        /**< state of IO: free, busy, wait_free */
  565         ocs_hw_wqe_t    wqe;            /**< Work queue object, with link for pending */
  566         ocs_lock_t      axr_lock;       /**< Lock to synchronize TRSP and AXT Data/Cmd Cqes */
  567         ocs_hw_t        *hw;            /**< pointer back to hardware context */
  568         ocs_remote_node_t       *rnode;
  569         struct ocs_hw_auto_xfer_rdy_buffer_s *axr_buf;
  570         ocs_dma_t       xfer_rdy;
  571         uint16_t        type;
  572         uint32_t        port_owned_abort_count; /**< IO abort count */
  573         hw_wq_t *wq;            /**< WQ assigned to the exchange */
  574         uint32_t        xbusy;          /**< Exchange is active in FW */
  575         ocs_hw_done_t  done;            /**< Function called on IO completion */
  576         void            *arg;           /**< argument passed to "IO done" callback */
  577         ocs_hw_done_t  abort_done;      /**< Function called on abort completion */
  578         void            *abort_arg;     /**< argument passed to "abort done" callback */
  579         ocs_ref_t       ref;            /**< refcount object */
  580         size_t          length;         /**< needed for bug O127585: length of IO */
  581         uint8_t         tgt_wqe_timeout; /**< timeout value for target WQEs */
  582         uint64_t        submit_ticks;   /**< timestamp when current WQE was submitted */
  583 
  584         uint32_t        status_saved:1, /**< if TRUE, latched status should be returned */
  585                         abort_in_progress:1, /**< if TRUE, abort is in progress */
  586                         quarantine:1,   /**< set if IO to be quarantined */
  587                         quarantine_first_phase:1,       /**< set if first phase of IO */
  588                         is_port_owned:1,        /**< set if POST_XRI was used to send XRI to th chip */
  589                         auto_xfer_rdy_dnrx:1,   /**< TRUE if DNRX was set on this IO */
  590                         :26;
  591         uint32_t        saved_status;   /**< latched status */
  592         uint32_t        saved_len;      /**< latched length */
  593         uint32_t        saved_ext;      /**< latched extended status */
  594 
  595         hw_eq_t *eq;            /**< EQ that this HIO came up on */
  596         ocs_hw_wq_steering_e    wq_steering;    /**< WQ steering mode request */
  597         uint8_t         wq_class;       /**< WQ class if steering mode is Class */
  598 
  599         /* Owned by SLI layer */
  600         uint16_t        reqtag;         /**< request tag for this HW IO */
  601         uint32_t        abort_reqtag;   /**< request tag for an abort of this HW IO (note: this is a 32 bit value
  602                                              to allow us to use UINT32_MAX as an uninitialized value) */
  603         uint32_t        indicator;      /**< XRI */
  604         ocs_dma_t       def_sgl;        /**< default scatter gather list */
  605         uint32_t        def_sgl_count;  /**< count of SGEs in default SGL */
  606         ocs_dma_t       *sgl;           /**< pointer to current active SGL */
  607         uint32_t        sgl_count;      /**< count of SGEs in io->sgl */
  608         uint32_t        first_data_sge; /**< index of first data SGE */
  609         ocs_dma_t       *ovfl_sgl;      /**< overflow SGL */
  610         uint32_t        ovfl_sgl_count; /**< count of SGEs in default SGL */
  611         sli4_lsp_sge_t  *ovfl_lsp;      /**< pointer to overflow segment length */
  612         ocs_hw_io_t     *ovfl_io;       /**< Used for SGL chaining on skyhawk */
  613         uint32_t        n_sge;          /**< number of active SGEs */
  614         uint32_t        sge_offset;
  615 
  616         /* BZ 161832 Workaround: */
  617         struct ocs_hw_io_s      *sec_hio; /**< Secondary HW IO context */
  618         ocs_hw_io_param_t sec_iparam;   /**< Secondary HW IO context saved iparam */
  619         uint32_t        sec_len;        /**< Secondary HW IO context saved len */
  620 
  621         /* Owned by upper layer */
  622         void            *ul_io;         /**< where upper layer can store reference to its IO */
  623 };
  624 
  625 typedef enum {
  626         OCS_HW_PORT_INIT,
  627         OCS_HW_PORT_SHUTDOWN,
  628         OCS_HW_PORT_SET_LINK_CONFIG,
  629 } ocs_hw_port_e;
  630 
  631 /**
  632  * @brief Fabric/Domain events
  633  */
  634 typedef enum {
  635         OCS_HW_DOMAIN_ALLOC_OK, /**< domain successfully allocated */
  636         OCS_HW_DOMAIN_ALLOC_FAIL,       /**< domain allocation failed */
  637         OCS_HW_DOMAIN_ATTACH_OK,        /**< successfully attached to domain */
  638         OCS_HW_DOMAIN_ATTACH_FAIL,      /**< domain attach failed */
  639         OCS_HW_DOMAIN_FREE_OK,          /**< successfully freed domain */
  640         OCS_HW_DOMAIN_FREE_FAIL,        /**< domain free failed */
  641         OCS_HW_DOMAIN_LOST,             /**< previously discovered domain no longer available */
  642         OCS_HW_DOMAIN_FOUND,            /**< new domain discovered */
  643         OCS_HW_DOMAIN_CHANGED,          /**< previously discovered domain properties have changed */
  644 } ocs_hw_domain_event_e;
  645 
  646 typedef enum {
  647         OCS_HW_PORT_ALLOC_OK,           /**< port successfully allocated */
  648         OCS_HW_PORT_ALLOC_FAIL, /**< port allocation failed */
  649         OCS_HW_PORT_ATTACH_OK,          /**< successfully attached to port */
  650         OCS_HW_PORT_ATTACH_FAIL,        /**< port attach failed */
  651         OCS_HW_PORT_FREE_OK,            /**< successfully freed port */
  652         OCS_HW_PORT_FREE_FAIL,          /**< port free failed */
  653 } ocs_hw_port_event_e;
  654 
  655 typedef enum {
  656         OCS_HW_NODE_ATTACH_OK,
  657         OCS_HW_NODE_ATTACH_FAIL,
  658         OCS_HW_NODE_FREE_OK,
  659         OCS_HW_NODE_FREE_FAIL,
  660         OCS_HW_NODE_FREE_ALL_OK,
  661         OCS_HW_NODE_FREE_ALL_FAIL,
  662 } ocs_hw_remote_node_event_e;
  663 
  664 typedef enum {
  665         OCS_HW_CB_DOMAIN,
  666         OCS_HW_CB_PORT,
  667         OCS_HW_CB_REMOTE_NODE,
  668         OCS_HW_CB_UNSOLICITED,
  669         OCS_HW_CB_BOUNCE,
  670         OCS_HW_CB_MAX,                  /**< must be last */
  671 } ocs_hw_callback_e;
  672 
  673 /**
  674  * @brief HW unsolicited callback status
  675  */
  676 typedef enum {
  677         OCS_HW_UNSOL_SUCCESS,
  678         OCS_HW_UNSOL_ERROR,
  679         OCS_HW_UNSOL_ABTS_RCVD,
  680         OCS_HW_UNSOL_MAX,               /**< must be last */
  681 } ocs_hw_unsol_status_e;
  682 
  683 /**
  684  * @brief Node group rpi reference
  685  */
  686 typedef struct {
  687         ocs_atomic_t rpi_count;
  688         ocs_atomic_t rpi_attached;
  689 } ocs_hw_rpi_ref_t;
  690 
  691 /**
  692  * @brief HW link stat types
  693  */
  694 typedef enum {
  695         OCS_HW_LINK_STAT_LINK_FAILURE_COUNT,
  696         OCS_HW_LINK_STAT_LOSS_OF_SYNC_COUNT,
  697         OCS_HW_LINK_STAT_LOSS_OF_SIGNAL_COUNT,
  698         OCS_HW_LINK_STAT_PRIMITIVE_SEQ_COUNT,
  699         OCS_HW_LINK_STAT_INVALID_XMIT_WORD_COUNT,
  700         OCS_HW_LINK_STAT_CRC_COUNT,
  701         OCS_HW_LINK_STAT_PRIMITIVE_SEQ_TIMEOUT_COUNT,
  702         OCS_HW_LINK_STAT_ELASTIC_BUFFER_OVERRUN_COUNT,
  703         OCS_HW_LINK_STAT_ARB_TIMEOUT_COUNT,
  704         OCS_HW_LINK_STAT_ADVERTISED_RCV_B2B_CREDIT,
  705         OCS_HW_LINK_STAT_CURR_RCV_B2B_CREDIT,
  706         OCS_HW_LINK_STAT_ADVERTISED_XMIT_B2B_CREDIT,
  707         OCS_HW_LINK_STAT_CURR_XMIT_B2B_CREDIT,
  708         OCS_HW_LINK_STAT_RCV_EOFA_COUNT,
  709         OCS_HW_LINK_STAT_RCV_EOFDTI_COUNT,
  710         OCS_HW_LINK_STAT_RCV_EOFNI_COUNT,
  711         OCS_HW_LINK_STAT_RCV_SOFF_COUNT,
  712         OCS_HW_LINK_STAT_RCV_DROPPED_NO_AER_COUNT,
  713         OCS_HW_LINK_STAT_RCV_DROPPED_NO_RPI_COUNT,
  714         OCS_HW_LINK_STAT_RCV_DROPPED_NO_XRI_COUNT,
  715         OCS_HW_LINK_STAT_MAX,           /**< must be last */
  716 } ocs_hw_link_stat_e;
  717 
  718 typedef enum {
  719         OCS_HW_HOST_STAT_TX_KBYTE_COUNT,
  720         OCS_HW_HOST_STAT_RX_KBYTE_COUNT,
  721         OCS_HW_HOST_STAT_TX_FRAME_COUNT,
  722         OCS_HW_HOST_STAT_RX_FRAME_COUNT,
  723         OCS_HW_HOST_STAT_TX_SEQ_COUNT,
  724         OCS_HW_HOST_STAT_RX_SEQ_COUNT,
  725         OCS_HW_HOST_STAT_TOTAL_EXCH_ORIG,
  726         OCS_HW_HOST_STAT_TOTAL_EXCH_RESP,
  727         OCS_HW_HOSY_STAT_RX_P_BSY_COUNT,
  728         OCS_HW_HOST_STAT_RX_F_BSY_COUNT,
  729         OCS_HW_HOST_STAT_DROP_FRM_DUE_TO_NO_RQ_BUF_COUNT,
  730         OCS_HW_HOST_STAT_EMPTY_RQ_TIMEOUT_COUNT,
  731         OCS_HW_HOST_STAT_DROP_FRM_DUE_TO_NO_XRI_COUNT,
  732         OCS_HW_HOST_STAT_EMPTY_XRI_POOL_COUNT,
  733         OCS_HW_HOST_STAT_MAX /* MUST BE LAST */
  734 } ocs_hw_host_stat_e;
  735 
  736 typedef enum {
  737         OCS_HW_STATE_UNINITIALIZED,             /* power-on, no allocations, no initializations */
  738         OCS_HW_STATE_QUEUES_ALLOCATED,          /* chip is reset, allocations are complete (queues not registered) */
  739         OCS_HW_STATE_ACTIVE,                    /* chip is up an running */
  740         OCS_HW_STATE_RESET_IN_PROGRESS, /* chip is being reset */
  741         OCS_HW_STATE_TEARDOWN_IN_PROGRESS,      /* teardown has been started */
  742 } ocs_hw_state_e;
  743 
  744 /**
  745  * @brief Defines a general FC sequence object, consisting of a header, payload buffers
  746  *        and a HW IO in the case of port owned XRI
  747  */
  748 typedef struct {
  749         ocs_hw_t *hw;                   /**< HW that owns this sequence */
  750         /* sequence information */
  751         uint8_t fcfi;           /**< FCFI associated with sequence */
  752         uint8_t auto_xrdy;      /**< If auto XFER_RDY was generated */
  753         uint8_t out_of_xris;    /**< If IO would have been assisted if XRIs were available */
  754         ocs_hw_rq_buffer_t *header;
  755         ocs_hw_rq_buffer_t *payload;    /**< received frame payload buffer */
  756 
  757         /* other "state" information from the SRB (sequence coalescing) */
  758         ocs_hw_unsol_status_e status;
  759         uint32_t xri;           /**< XRI associated with sequence; sequence coalescing only */
  760         ocs_hw_io_t *hio;       /**< HW IO */
  761 
  762         ocs_list_link_t link;
  763         void *hw_priv;          /**< HW private context */
  764 } ocs_hw_sequence_t;
  765 
  766 /**
  767  * @brief Structure to track optimized write buffers posted to chip owned XRIs.
  768  *
  769  * Note: The rqindex will be set the following "fake" indexes. This will be used
  770  *       when the buffer is returned via ocs_seq_free() to make the buffer available
  771  *       for re-use on another XRI.
  772  *
  773  *       The dma->alloc pointer on the dummy header will be used to get back to this structure when the buffer is freed.
  774  *
  775  *       More of these object may be allocated on the fly if more XRIs are pushed to the chip.
  776  */
  777 #define OCS_HW_RQ_INDEX_DUMMY_HDR       0xFF00
  778 #define OCS_HW_RQ_INDEX_DUMMY_DATA      0xFF01
  779 typedef struct ocs_hw_auto_xfer_rdy_buffer_s {
  780         fc_header_t hdr;                /**< used to build a dummy data header for unsolicited processing */
  781         ocs_hw_rq_buffer_t header;      /**< Points to the dummy data header */
  782         ocs_hw_rq_buffer_t payload;     /**< received frame payload buffer */
  783         ocs_hw_sequence_t seq;         /**< sequence for passing the buffers */
  784         uint8_t data_cqe;
  785         uint8_t cmd_cqe;
  786 
  787         /* fields saved from the command header that are needed when the data arrives */
  788         uint8_t fcfi;
  789 
  790         /* To handle outof order completions save AXR cmd and data cqes */
  791         uint8_t call_axr_cmd;
  792         uint8_t call_axr_data;
  793         ocs_hw_sequence_t *cmd_seq;
  794 } ocs_hw_auto_xfer_rdy_buffer_t;
  795 
  796 /**
  797  * @brief Node group rpi reference
  798  */
  799 typedef struct {
  800         uint8_t overflow;
  801         uint32_t counter;
  802 } ocs_hw_link_stat_counts_t;
  803 
  804 /**
  805  * @brief HW object describing fc host stats
  806  */
  807 typedef struct {
  808         uint32_t counter;
  809 } ocs_hw_host_stat_counts_t;
  810 
  811 #define TID_HASH_BITS   8
  812 #define TID_HASH_LEN    (1U << TID_HASH_BITS)
  813 
  814 typedef struct ocs_hw_iopt_s {
  815         char            name[32];
  816         uint32_t        instance_index;
  817         ocs_thread_t    iopt_thread;
  818         ocs_cbuf_t      *iopt_free_queue;       /* multiple reader, multiple writer */
  819         ocs_cbuf_t      *iopt_work_queue;
  820         ocs_array_t     *iopt_cmd_array;
  821 } ocs_hw_iopt_t;
  822 
  823 typedef enum {
  824         HW_CQ_HANDLER_LOCAL,
  825         HW_CQ_HANDLER_THREAD,
  826 } hw_cq_handler_e;
  827 
  828 #include "ocs_hw_queues.h"
  829 
  830 /**
  831  * @brief Stucture used for the hash lookup of queue IDs
  832  */
  833 typedef struct {
  834         uint32_t id:16,
  835                 in_use:1,
  836                 index:15;
  837 } ocs_queue_hash_t;
  838 
  839 /**
  840  * @brief Define the fields required to implement the skyhawk DIF quarantine.
  841  */
  842 #define OCS_HW_QUARANTINE_QUEUE_DEPTH   4
  843 
  844 typedef struct {
  845         uint32_t        quarantine_index;
  846         ocs_hw_io_t     *quarantine_ios[OCS_HW_QUARANTINE_QUEUE_DEPTH];
  847 } ocs_quarantine_info_t;
  848 
  849 /**
  850  * @brief Define the WQ callback object
  851  */
  852 typedef struct {
  853         uint16_t instance_index;        /**< use for request tag */
  854         void (*callback)(void *arg, uint8_t *cqe, int32_t status);
  855         void *arg;
  856 } hw_wq_callback_t;
  857 
  858 typedef struct {
  859         uint64_t fwrev;
  860 
  861         /* Control Declarations here ...*/
  862 
  863         uint8_t retain_tsend_io_length;
  864 
  865         /* Use unregistered RPI */
  866         uint8_t use_unregistered_rpi;
  867         uint32_t unregistered_rid;
  868         uint32_t unregistered_index;
  869 
  870         uint8_t disable_ar_tgt_dif;     /* Disable auto response if target DIF */
  871         uint8_t disable_dump_loc;
  872         uint8_t use_dif_quarantine;
  873         uint8_t use_dif_sec_xri;
  874 
  875         uint8_t override_fcfi;
  876 
  877         uint8_t fw_version_too_low;
  878 
  879         uint8_t sglc_misreported;
  880 
  881         uint8_t ignore_send_frame;
  882 
  883 } ocs_hw_workaround_t;
  884 
  885 /**
  886  * @brief HW object
  887  */
  888 struct ocs_hw_s {
  889         ocs_os_handle_t os;
  890         sli4_t          sli;
  891         uint16_t        ulp_start;
  892         uint16_t        ulp_max;
  893         uint32_t        dump_size;
  894         ocs_hw_state_e state;
  895         uint8_t         hw_setup_called;
  896         uint8_t         sliport_healthcheck;
  897         uint16_t        watchdog_timeout;
  898         ocs_lock_t      watchdog_lock;
  899 
  900         /** HW configuration, subject to ocs_hw_set()  */
  901         struct {
  902                 uint32_t        n_eq; /**< number of event queues */
  903                 uint32_t        n_cq; /**< number of completion queues */
  904                 uint32_t        n_mq; /**< number of mailbox queues */
  905                 uint32_t        n_rq; /**< number of receive queues */
  906                 uint32_t        n_wq; /**< number of work queues */
  907                 uint32_t        n_io; /**< total number of IO objects */
  908                 uint32_t        n_sgl;/**< length of SGL */
  909                 uint32_t        speed;  /** requested link speed in Mbps */
  910                 uint32_t        topology;  /** requested link topology */
  911                 uint32_t        rq_default_buffer_size; /** size of the buffers for first burst */
  912                 uint32_t        auto_xfer_rdy_xri_cnt;  /** Initial XRIs to post to chip at initialization */
  913                 uint32_t        auto_xfer_rdy_size;     /** max size IO to use with this feature */
  914                 uint8_t         auto_xfer_rdy_blk_size_chip;    /** block size to use with this feature */
  915                 uint8_t         esoc;
  916                 uint16_t        dif_seed; /** The seed for the DIF CRC calculation */
  917                 uint16_t        auto_xfer_rdy_app_tag_value;
  918                 uint8_t         dif_mode; /**< DIF mode to use */
  919                 uint8_t         i_only_aab; /** Enable initiator-only auto-abort */
  920                 uint8_t         emulate_tgt_wqe_timeout; /** Enable driver target wqe timeouts */
  921                 uint32_t        bounce:1;
  922                 const char      *queue_topology;                /**< Queue topology string */
  923                 uint8_t         auto_xfer_rdy_t10_enable;       /** Enable t10 PI for auto xfer ready */
  924                 uint8_t         auto_xfer_rdy_p_type;   /** p_type for auto xfer ready */
  925                 uint8_t         auto_xfer_rdy_ref_tag_is_lba;
  926                 uint8_t         auto_xfer_rdy_app_tag_valid;
  927                 uint8_t         rq_selection_policy;            /** MRQ RQ selection policy */
  928                 uint8_t         rr_quanta;                      /** RQ quanta if rq_selection_policy == 2 */
  929                 uint32_t        filter_def[SLI4_CMD_REG_FCFI_NUM_RQ_CFG];
  930         } config;
  931 
  932         /* calculated queue sizes for each type */
  933         uint32_t        num_qentries[SLI_QTYPE_MAX];
  934 
  935         /* Storage for SLI queue objects */
  936         sli4_queue_t    wq[OCS_HW_MAX_NUM_WQ];
  937         sli4_queue_t    rq[OCS_HW_MAX_NUM_RQ];
  938         uint16_t        hw_rq_lookup[OCS_HW_MAX_NUM_RQ];
  939         sli4_queue_t    mq[OCS_HW_MAX_NUM_MQ];
  940         sli4_queue_t    cq[OCS_HW_MAX_NUM_CQ];
  941         sli4_queue_t    eq[OCS_HW_MAX_NUM_EQ];
  942 
  943         /* HW queue */
  944         uint32_t        eq_count;
  945         uint32_t        cq_count;
  946         uint32_t        mq_count;
  947         uint32_t        wq_count;
  948         uint32_t        rq_count;                       /**< count of SLI RQs */
  949         ocs_list_t      eq_list;
  950 
  951         ocs_queue_hash_t cq_hash[OCS_HW_Q_HASH_SIZE];
  952         ocs_queue_hash_t rq_hash[OCS_HW_Q_HASH_SIZE];
  953         ocs_queue_hash_t wq_hash[OCS_HW_Q_HASH_SIZE];
  954 
  955         /* Storage for HW queue objects */
  956         hw_wq_t *hw_wq[OCS_HW_MAX_NUM_WQ];
  957         hw_rq_t *hw_rq[OCS_HW_MAX_NUM_RQ];
  958         hw_mq_t *hw_mq[OCS_HW_MAX_NUM_MQ];
  959         hw_cq_t *hw_cq[OCS_HW_MAX_NUM_CQ];
  960         hw_eq_t *hw_eq[OCS_HW_MAX_NUM_EQ];
  961         uint32_t        hw_rq_count;                    /**< count of hw_rq[] entries */
  962         uint32_t        hw_mrq_count;                   /**< count of multirq RQs */
  963 
  964         ocs_varray_t    *wq_class_array[OCS_HW_MAX_WQ_CLASS];   /**< pool per class WQs */
  965         ocs_varray_t    *wq_cpu_array[OCS_HW_MAX_WQ_CPU];       /**< pool per CPU WQs */
  966 
  967         /* Sequence objects used in incoming frame processing */
  968         ocs_array_t     *seq_pool;
  969 
  970         /* Auto XFER RDY Buffers - protect with io_lock */
  971         uint32_t        auto_xfer_rdy_enabled:1,        /**< TRUE if auto xfer rdy is enabled */
  972                         :31;
  973         ocs_pool_t      *auto_xfer_rdy_buf_pool;        /**< pool of ocs_hw_auto_xfer_rdy_buffer_t objects */
  974 
  975         /** Maintain an ordered, linked list of outstanding HW commands. */
  976         ocs_lock_t      cmd_lock;
  977         ocs_list_t      cmd_head;
  978         ocs_list_t      cmd_pending;
  979         uint32_t        cmd_head_count;
  980 
  981         sli4_link_event_t link;
  982         ocs_hw_linkcfg_e linkcfg; /**< link configuration setting */
  983         uint32_t eth_license;      /**< Ethernet license; to enable FCoE on Lancer */
  984 
  985         struct {
  986                 /**
  987                  * Function + argument used to notify upper layer of domain events.
  988                  *
  989                  * The final argument to the callback is a generic data pointer:
  990                  *  - ocs_domain_record_t on OCS_HW_DOMAIN_FOUND
  991                  *  - ocs_domain_t on OCS_HW_DOMAIN_ALLOC_FAIL, OCS_HW_DOMAIN_ALLOC_OK,
  992                  * OCS_HW_DOMAIN_FREE_FAIL, OCS_HW_DOMAIN_FREE_OK,
  993                  * OCS_HW_DOMAIN_ATTACH_FAIL, OCS_HW_DOMAIN_ATTACH_OK, and
  994                  * OCS_HW_DOMAIN_LOST.
  995                  */
  996                 int32_t (*domain)(void *, ocs_hw_domain_event_e, void *);
  997                 /**
  998                  * Function + argument used to notify upper layers of port events.
  999                  *
 1000                  * The final argument to the callback is a pointer to the effected
 1001                  * SLI port for all events.
 1002                  */
 1003                 int32_t (*port)(void *, ocs_hw_port_event_e, void *);
 1004                 /** Function + argument used to announce arrival of unsolicited frames */
 1005                 int32_t (*unsolicited)(void *, ocs_hw_sequence_t *);
 1006                 int32_t (*rnode)(void *, ocs_hw_remote_node_event_e, void *);
 1007                 int32_t (*bounce)(void (*)(void *arg), void *arg, uint32_t s_id, uint32_t d_id, uint32_t ox_id);
 1008         } callback;
 1009         struct {
 1010                 void *domain;
 1011                 void *port;
 1012                 void *unsolicited;
 1013                 void *rnode;
 1014                 void *bounce;
 1015         } args;
 1016 
 1017         /* OCS domain objects index by FCFI */
 1018         int32_t         first_domain_idx;               /* Workaround for srb->fcfi == 0 */
 1019         ocs_domain_t    *domains[SLI4_MAX_FCFI];
 1020 
 1021         /* Table of FCFI values index by FCF_index */
 1022         uint16_t        fcf_index_fcfi[SLI4_MAX_FCF_INDEX];
 1023 
 1024         uint16_t        fcf_indicator;
 1025 
 1026         ocs_hw_io_t     **io;           /**< pointer array of IO objects */
 1027         uint8_t         *wqe_buffs;     /**< array of WQE buffs mapped to IO objects */ 
 1028 
 1029         ocs_lock_t      io_lock;                /**< IO lock to synchronize list access */
 1030         ocs_lock_t      io_abort_lock;          /**< IO lock to synchronize IO aborting */
 1031         ocs_list_t      io_inuse;               /**< List of IO objects in use */
 1032         ocs_list_t      io_timed_wqe;           /**< List of IO objects with a timed target WQE */
 1033         ocs_list_t      io_wait_free;           /**< List of IO objects waiting to be freed */
 1034         ocs_list_t      io_free;                /**< List of IO objects available for allocation */
 1035         ocs_list_t      io_port_owned;          /**< List of IO objects posted for chip use */
 1036         ocs_list_t      io_port_dnrx;           /**< List of IO objects needing auto xfer rdy buffers */
 1037 
 1038         ocs_dma_t       loop_map;
 1039 
 1040         ocs_dma_t       xfer_rdy;
 1041 
 1042         ocs_dma_t       dump_sges;
 1043 
 1044         ocs_dma_t       rnode_mem;
 1045 
 1046         ocs_dma_t       domain_dmem;    /*domain dma mem for service params */
 1047         ocs_dma_t       fcf_dmem;       /*dma men for fcf */
 1048 
 1049         ocs_hw_rpi_ref_t *rpi_ref;
 1050 
 1051         char            *hw_war_version;
 1052         ocs_hw_workaround_t workaround;
 1053 
 1054         ocs_atomic_t io_alloc_failed_count;
 1055 
 1056 #if defined(OCS_DEBUG_QUEUE_HISTORY)
 1057         ocs_hw_q_hist_t q_hist;
 1058 #endif
 1059 
 1060         ocs_list_t      sec_hio_wait_list;      /**< BZ 161832 Workaround: Secondary HW IO context wait list */
 1061         uint32_t        sec_hio_wait_count;     /**< BZ 161832 Workaround: Count of IOs that were put on the
 1062                                                  * Secondary HW IO wait list
 1063                                                  */
 1064 
 1065 #define HW_MAX_TCMD_THREADS             16
 1066         ocs_hw_qtop_t   *qtop;                                  /**< pointer to queue topology */
 1067 
 1068         uint32_t        tcmd_wq_submit[OCS_HW_MAX_NUM_WQ];      /**< stat: wq sumbit count */
 1069         uint32_t        tcmd_wq_complete[OCS_HW_MAX_NUM_WQ];    /**< stat: wq complete count */
 1070 
 1071         ocs_timer_t     wqe_timer;              /**< Timer to periodically check for WQE timeouts */
 1072         ocs_timer_t     watchdog_timer;         /**< Timer for heartbeat */
 1073         bool            expiration_logged;
 1074         uint32_t        in_active_wqe_timer:1,  /**< TRUE if currently in active wqe timer handler */
 1075                         active_wqe_timer_shutdown:1, /** TRUE if wqe timer is to be shutdown */
 1076                         :30;
 1077 
 1078         ocs_list_t      iopc_list;              /**< list of IO processing contexts */
 1079         ocs_lock_t      iopc_list_lock;         /**< lock for iopc_list */
 1080 
 1081         ocs_pool_t      *wq_reqtag_pool;        /**< pool of hw_wq_callback_t objects */
 1082 
 1083         ocs_atomic_t    send_frame_seq_id;      /**< send frame sequence ID */
 1084 };
 1085 
 1086 typedef enum {
 1087         OCS_HW_IO_INUSE_COUNT,
 1088         OCS_HW_IO_FREE_COUNT,
 1089         OCS_HW_IO_WAIT_FREE_COUNT,
 1090         OCS_HW_IO_PORT_OWNED_COUNT,
 1091         OCS_HW_IO_N_TOTAL_IO_COUNT,
 1092 } ocs_hw_io_count_type_e;
 1093 
 1094 typedef void (*tcmd_cq_handler)(ocs_hw_t *hw, uint32_t cq_idx, void *cq_handler_arg);
 1095 
 1096 /*
 1097  * HW queue data structures
 1098  */
 1099 
 1100 struct hw_eq_s {
 1101         ocs_list_link_t link;           /**< must be first */
 1102         sli4_qtype_e type;              /**< must be second */
 1103         uint32_t instance;
 1104         uint32_t entry_count;
 1105         uint32_t entry_size;
 1106         ocs_hw_t *hw;
 1107         sli4_queue_t *queue;
 1108         ocs_list_t cq_list;
 1109 #if OCS_STAT_ENABLE
 1110         uint32_t use_count;
 1111 #endif
 1112         ocs_varray_t *wq_array;         /*<< array of WQs */
 1113 };
 1114 
 1115 struct hw_cq_s {
 1116         ocs_list_link_t link;           /*<< must be first */
 1117         sli4_qtype_e type;              /**< must be second */
 1118         uint32_t instance;              /*<< CQ instance (cq_idx) */
 1119         uint32_t entry_count;           /*<< Number of entries */
 1120         uint32_t entry_size;            /*<< entry size */
 1121         hw_eq_t *eq;                    /*<< parent EQ */
 1122         sli4_queue_t *queue;            /**< pointer to SLI4 queue */
 1123         ocs_list_t q_list;              /**< list of children queues */
 1124 
 1125 #if OCS_STAT_ENABLE
 1126         uint32_t use_count;
 1127 #endif
 1128 };
 1129 
 1130 typedef struct {
 1131         ocs_list_link_t link;           /*<< must be first */
 1132         sli4_qtype_e type;              /*<< must be second */
 1133 } hw_q_t;
 1134 
 1135 struct hw_mq_s {
 1136         ocs_list_link_t link;           /*<< must be first */
 1137         sli4_qtype_e type;              /*<< must be second */
 1138         uint32_t instance;
 1139 
 1140         uint32_t entry_count;
 1141         uint32_t entry_size;
 1142         hw_cq_t *cq;
 1143         sli4_queue_t *queue;
 1144 
 1145 #if OCS_STAT_ENABLE
 1146         uint32_t use_count;
 1147 #endif
 1148 };
 1149 
 1150 struct hw_wq_s {
 1151         ocs_list_link_t link;           /*<< must be first */
 1152         sli4_qtype_e type;              /*<< must be second */
 1153         uint32_t instance;
 1154         ocs_hw_t *hw;
 1155 
 1156         uint32_t entry_count;
 1157         uint32_t entry_size;
 1158         hw_cq_t *cq;
 1159         sli4_queue_t *queue;
 1160         uint32_t class;
 1161         uint8_t ulp;
 1162 
 1163         /* WQ consumed */
 1164         uint32_t wqec_set_count;                /*<< how often IOs are submitted with wqce set */
 1165         uint32_t wqec_count;                    /*<< current wqce counter */
 1166         uint32_t free_count;                    /*<< free count */
 1167         uint32_t total_submit_count;            /*<< total submit count */
 1168         ocs_list_t pending_list;                /*<< list of IOs pending for this WQ */
 1169 
 1170         /*
 1171          * ---Skyhawk only ---
 1172          * BZ 160124 - Driver must quarantine XRIs for target writes and
 1173          * initiator read when using DIF separates. Throw them on a
 1174          * queue until another 4 similar requests are completed to ensure they
 1175          * are flushed from the internal chip cache before being re-used.
 1176          * The must be a separate queue per CQ because the actual chip completion
 1177          * order cannot be determined. Since each WQ has a separate CQ, use the wq
 1178          * associated with the IO.
 1179          *
 1180          * Note: Protected by queue->lock
 1181          */
 1182         ocs_quarantine_info_t quarantine_info;
 1183 
 1184         /*
 1185          * HW IO allocated for use with Send Frame
 1186          */
 1187         ocs_hw_io_t *send_frame_io;
 1188 
 1189         /* Stats */
 1190 #if OCS_STAT_ENABLE
 1191         uint32_t use_count;                     /*<< use count */
 1192         uint32_t wq_pending_count;              /*<< count of HW IOs that were queued on the WQ pending list */
 1193 #endif
 1194 };
 1195 
 1196 struct hw_rq_s {
 1197         ocs_list_link_t link;                   /*<< must be first */
 1198         sli4_qtype_e type;                      /*<< must be second */
 1199         uint32_t instance;
 1200 
 1201         uint32_t entry_count;
 1202         uint32_t hdr_entry_size;
 1203         uint32_t first_burst_entry_size;
 1204         uint32_t data_entry_size;
 1205         uint8_t ulp;
 1206         bool is_mrq;
 1207         uint32_t base_mrq_id;
 1208 
 1209         hw_cq_t *cq;
 1210 
 1211         uint8_t filter_mask;                    /* Filter mask value */
 1212         sli4_queue_t *hdr;
 1213         sli4_queue_t *first_burst;
 1214         sli4_queue_t *data;
 1215 
 1216         ocs_hw_rq_buffer_t *hdr_buf;
 1217         ocs_hw_rq_buffer_t *fb_buf;
 1218         ocs_hw_rq_buffer_t *payload_buf;
 1219 
 1220         ocs_hw_sequence_t **rq_tracker; /* RQ tracker for this RQ */
 1221 #if OCS_STAT_ENABLE
 1222         uint32_t use_count;
 1223         uint32_t hdr_use_count;
 1224         uint32_t fb_use_count;
 1225         uint32_t payload_use_count;
 1226 #endif
 1227 };
 1228 
 1229 typedef struct ocs_hw_global_s {
 1230         const char      *queue_topology_string;                 /**< queue topology string */
 1231 } ocs_hw_global_t;
 1232 extern ocs_hw_global_t hw_global;
 1233 
 1234 extern hw_eq_t *hw_new_eq(ocs_hw_t *hw, uint32_t entry_count);
 1235 extern hw_cq_t *hw_new_cq(hw_eq_t *eq, uint32_t entry_count);
 1236 extern uint32_t hw_new_cq_set(hw_eq_t *eqs[], hw_cq_t *cqs[], uint32_t num_cqs, uint32_t entry_count);
 1237 extern hw_mq_t *hw_new_mq(hw_cq_t *cq, uint32_t entry_count);
 1238 extern hw_wq_t *hw_new_wq(hw_cq_t *cq, uint32_t entry_count, uint32_t class, uint32_t ulp);
 1239 extern hw_rq_t *hw_new_rq(hw_cq_t *cq, uint32_t entry_count, uint32_t ulp);
 1240 extern uint32_t hw_new_rq_set(hw_cq_t *cqs[], hw_rq_t *rqs[], uint32_t num_rq_pairs, uint32_t entry_count, uint32_t ulp);
 1241 extern void hw_del_eq(hw_eq_t *eq);
 1242 extern void hw_del_cq(hw_cq_t *cq);
 1243 extern void hw_del_mq(hw_mq_t *mq);
 1244 extern void hw_del_wq(hw_wq_t *wq);
 1245 extern void hw_del_rq(hw_rq_t *rq);
 1246 extern void hw_queue_dump(ocs_hw_t *hw);
 1247 extern void hw_queue_teardown(ocs_hw_t *hw);
 1248 extern int32_t hw_route_rqe(ocs_hw_t *hw, ocs_hw_sequence_t *seq);
 1249 extern int32_t ocs_hw_queue_hash_find(ocs_queue_hash_t *, uint16_t);
 1250 extern ocs_hw_rtn_e ocs_hw_setup(ocs_hw_t *, ocs_os_handle_t, sli4_port_type_e);
 1251 extern ocs_hw_rtn_e ocs_hw_init(ocs_hw_t *);
 1252 extern ocs_hw_rtn_e ocs_hw_teardown(ocs_hw_t *);
 1253 extern ocs_hw_rtn_e ocs_hw_reset(ocs_hw_t *, ocs_hw_reset_e);
 1254 extern int32_t ocs_hw_get_num_eq(ocs_hw_t *);
 1255 extern ocs_hw_rtn_e ocs_hw_get(ocs_hw_t *, ocs_hw_property_e, uint32_t *);
 1256 extern void *ocs_hw_get_ptr(ocs_hw_t *, ocs_hw_property_e);
 1257 extern ocs_hw_rtn_e ocs_hw_set(ocs_hw_t *, ocs_hw_property_e, uint32_t);
 1258 extern ocs_hw_rtn_e ocs_hw_set_ptr(ocs_hw_t *, ocs_hw_property_e, void*);
 1259 extern int32_t ocs_hw_event_check(ocs_hw_t *, uint32_t);
 1260 extern int32_t ocs_hw_process(ocs_hw_t *, uint32_t, uint32_t);
 1261 extern ocs_hw_rtn_e ocs_hw_command(ocs_hw_t *, uint8_t *, uint32_t, void *, void *);
 1262 extern ocs_hw_rtn_e ocs_hw_callback(ocs_hw_t *, ocs_hw_callback_e, void *, void *);
 1263 extern ocs_hw_rtn_e ocs_hw_port_alloc(ocs_hw_t *, ocs_sli_port_t *, ocs_domain_t *, uint8_t *);
 1264 extern ocs_hw_rtn_e ocs_hw_port_attach(ocs_hw_t *, ocs_sli_port_t *, uint32_t);
 1265 typedef void (*ocs_hw_port_control_cb_t)(int32_t status, uintptr_t value, void *arg);
 1266 extern ocs_hw_rtn_e ocs_hw_port_control(ocs_hw_t *, ocs_hw_port_e, uintptr_t, ocs_hw_port_control_cb_t, void *);
 1267 extern ocs_hw_rtn_e ocs_hw_port_free(ocs_hw_t *, ocs_sli_port_t *);
 1268 extern ocs_hw_rtn_e ocs_hw_domain_alloc(ocs_hw_t *, ocs_domain_t *, uint32_t, uint32_t);
 1269 extern ocs_hw_rtn_e ocs_hw_domain_attach(ocs_hw_t *, ocs_domain_t *, uint32_t);
 1270 extern ocs_hw_rtn_e ocs_hw_domain_free(ocs_hw_t *, ocs_domain_t *);
 1271 extern ocs_hw_rtn_e ocs_hw_domain_force_free(ocs_hw_t *, ocs_domain_t *);
 1272 extern ocs_domain_t * ocs_hw_domain_get(ocs_hw_t *, uint16_t);
 1273 extern ocs_hw_rtn_e ocs_hw_node_alloc(ocs_hw_t *, ocs_remote_node_t *, uint32_t, ocs_sli_port_t *);
 1274 extern ocs_hw_rtn_e ocs_hw_node_free_all(ocs_hw_t *);
 1275 extern ocs_hw_rtn_e ocs_hw_node_attach(ocs_hw_t *, ocs_remote_node_t *, ocs_dma_t *);
 1276 extern ocs_hw_rtn_e ocs_hw_node_detach(ocs_hw_t *, ocs_remote_node_t *);
 1277 extern ocs_hw_rtn_e ocs_hw_node_free_resources(ocs_hw_t *, ocs_remote_node_t *);
 1278 extern ocs_hw_rtn_e ocs_hw_node_group_alloc(ocs_hw_t *, ocs_remote_node_group_t *);
 1279 extern ocs_hw_rtn_e ocs_hw_node_group_attach(ocs_hw_t *, ocs_remote_node_group_t *, ocs_remote_node_t *);
 1280 extern ocs_hw_rtn_e ocs_hw_node_group_free(ocs_hw_t *, ocs_remote_node_group_t *);
 1281 extern ocs_hw_io_t *ocs_hw_io_alloc(ocs_hw_t *);
 1282 extern ocs_hw_io_t *ocs_hw_io_activate_port_owned(ocs_hw_t *, ocs_hw_io_t *);
 1283 extern int32_t ocs_hw_io_free(ocs_hw_t *, ocs_hw_io_t *);
 1284 extern uint8_t ocs_hw_io_inuse(ocs_hw_t *hw, ocs_hw_io_t *io);
 1285 typedef int32_t (*ocs_hw_srrs_cb_t)(ocs_hw_io_t *io, ocs_remote_node_t *rnode, uint32_t length, int32_t status, uint32_t ext_status, void *arg);
 1286 extern ocs_hw_rtn_e ocs_hw_srrs_send(ocs_hw_t *, ocs_hw_io_type_e, ocs_hw_io_t *, ocs_dma_t *, uint32_t, ocs_dma_t *, ocs_remote_node_t *, ocs_hw_io_param_t *, ocs_hw_srrs_cb_t, void *);
 1287 extern ocs_hw_rtn_e ocs_hw_io_send(ocs_hw_t *, ocs_hw_io_type_e, ocs_hw_io_t *, uint32_t, ocs_hw_io_param_t *, ocs_remote_node_t *, void *, void *);
 1288 extern ocs_hw_rtn_e _ocs_hw_io_send(ocs_hw_t *hw, ocs_hw_io_type_e type, ocs_hw_io_t *io,
 1289                                       uint32_t len, ocs_hw_io_param_t *iparam, ocs_remote_node_t *rnode,
 1290                                       void *cb, void *arg);
 1291 extern ocs_hw_rtn_e ocs_hw_io_register_sgl(ocs_hw_t *, ocs_hw_io_t *, ocs_dma_t *, uint32_t);
 1292 extern ocs_hw_rtn_e ocs_hw_io_init_sges(ocs_hw_t *hw, ocs_hw_io_t *io, ocs_hw_io_type_e type);
 1293 extern ocs_hw_rtn_e ocs_hw_io_add_seed_sge(ocs_hw_t *hw, ocs_hw_io_t *io, ocs_hw_dif_info_t *dif_info);
 1294 extern ocs_hw_rtn_e ocs_hw_io_add_sge(ocs_hw_t *, ocs_hw_io_t *, uintptr_t, uint32_t);
 1295 extern ocs_hw_rtn_e ocs_hw_io_add_dif_sge(ocs_hw_t *hw, ocs_hw_io_t *io, uintptr_t addr);
 1296 extern ocs_hw_rtn_e ocs_hw_io_abort(ocs_hw_t *, ocs_hw_io_t *, uint32_t, void *, void *);
 1297 extern int32_t ocs_hw_io_get_xid(ocs_hw_t *, ocs_hw_io_t *);
 1298 extern uint32_t ocs_hw_io_get_count(ocs_hw_t *, ocs_hw_io_count_type_e);
 1299 extern uint32_t ocs_hw_get_rqes_produced_count(ocs_hw_t *hw);
 1300 
 1301 typedef void (*ocs_hw_fw_cb_t)(int32_t status, uint32_t bytes_written, uint32_t change_status, void *arg);
 1302 extern ocs_hw_rtn_e ocs_hw_firmware_write(ocs_hw_t *, ocs_dma_t *, uint32_t, uint32_t, int, ocs_hw_fw_cb_t, void*);
 1303 
 1304 /* Function for retrieving SFP data */
 1305 typedef void (*ocs_hw_sfp_cb_t)(void *, int32_t, uint32_t, uint32_t *, void *);
 1306 extern ocs_hw_rtn_e ocs_hw_get_sfp(ocs_hw_t *, uint16_t, ocs_hw_sfp_cb_t, void *);
 1307 
 1308 /* Function for retrieving temperature data */
 1309 typedef void (*ocs_hw_temp_cb_t)(int32_t status,
 1310                                   uint32_t curr_temp,
 1311                                   uint32_t crit_temp_thrshld,
 1312                                   uint32_t warn_temp_thrshld,
 1313                                   uint32_t norm_temp_thrshld,
 1314                                   uint32_t fan_off_thrshld,
 1315                                   uint32_t fan_on_thrshld,
 1316                                   void *arg);
 1317 extern ocs_hw_rtn_e ocs_hw_get_temperature(ocs_hw_t *, ocs_hw_temp_cb_t, void*);
 1318 
 1319 /* Function for retrieving link statistics */
 1320 typedef void (*ocs_hw_link_stat_cb_t)(int32_t status,
 1321                                        uint32_t num_counters,
 1322                                        ocs_hw_link_stat_counts_t *counters,
 1323                                        void *arg);
 1324 extern ocs_hw_rtn_e ocs_hw_get_link_stats(ocs_hw_t *,
 1325                                             uint8_t req_ext_counters,
 1326                                             uint8_t clear_overflow_flags,
 1327                                             uint8_t clear_all_counters,
 1328                                             ocs_hw_link_stat_cb_t, void*);
 1329 /* Function for retrieving host statistics */
 1330 typedef void (*ocs_hw_host_stat_cb_t)(int32_t status,
 1331                                        uint32_t num_counters,
 1332                                        ocs_hw_host_stat_counts_t *counters,
 1333                                        void *arg);
 1334 extern ocs_hw_rtn_e ocs_hw_get_host_stats(ocs_hw_t *hw, uint8_t cc, ocs_hw_host_stat_cb_t, void *arg);
 1335 
 1336 extern ocs_hw_rtn_e ocs_hw_raise_ue(ocs_hw_t *, uint8_t);
 1337 typedef void (*ocs_hw_dump_get_cb_t)(int32_t status, uint32_t bytes_read, uint8_t eof, void *arg);
 1338 extern ocs_hw_rtn_e ocs_hw_dump_get(ocs_hw_t *, ocs_dma_t *, uint32_t, uint32_t, ocs_hw_dump_get_cb_t, void *);
 1339 extern ocs_hw_rtn_e ocs_hw_set_dump_location(ocs_hw_t *, uint32_t, ocs_dma_t *, uint8_t);
 1340 
 1341 typedef void (*ocs_get_port_protocol_cb_t)(int32_t status, ocs_hw_port_protocol_e port_protocol, void *arg);
 1342 extern ocs_hw_rtn_e ocs_hw_get_port_protocol(ocs_hw_t *hw, uint32_t pci_func, ocs_get_port_protocol_cb_t mgmt_cb, void* ul_arg);
 1343 typedef void (*ocs_set_port_protocol_cb_t)(int32_t status,  void *arg);
 1344 extern ocs_hw_rtn_e ocs_hw_set_port_protocol(ocs_hw_t *hw, ocs_hw_port_protocol_e profile,
 1345                                                uint32_t pci_func, ocs_set_port_protocol_cb_t mgmt_cb,
 1346                                                void* ul_arg);
 1347 
 1348 typedef void (*ocs_get_profile_list_cb_t)(int32_t status,  ocs_hw_profile_list_t*, void *arg);
 1349 extern ocs_hw_rtn_e ocs_hw_get_profile_list(ocs_hw_t *hw, ocs_get_profile_list_cb_t mgmt_cb, void *arg);
 1350 typedef void (*ocs_get_active_profile_cb_t)(int32_t status,  uint32_t active_profile, void *arg);
 1351 extern ocs_hw_rtn_e ocs_hw_get_active_profile(ocs_hw_t *hw, ocs_get_active_profile_cb_t mgmt_cb, void *arg);
 1352 typedef void (*ocs_set_active_profile_cb_t)(int32_t status, void *arg);
 1353 extern ocs_hw_rtn_e ocs_hw_set_active_profile(ocs_hw_t *hw, ocs_set_active_profile_cb_t mgmt_cb,
 1354                 uint32_t profile_id, void *arg);
 1355 typedef void (*ocs_get_nvparms_cb_t)(int32_t status, uint8_t *wwpn, uint8_t *wwnn, uint8_t hard_alpa,
 1356                 uint32_t preferred_d_id, void *arg);
 1357 extern ocs_hw_rtn_e ocs_hw_get_nvparms(ocs_hw_t *hw, ocs_get_nvparms_cb_t mgmt_cb, void *arg);
 1358 typedef void (*ocs_set_nvparms_cb_t)(int32_t status, void *arg);
 1359 extern ocs_hw_rtn_e ocs_hw_set_nvparms(ocs_hw_t *hw, ocs_set_nvparms_cb_t mgmt_cb, uint8_t *wwpn,
 1360                 uint8_t *wwnn, uint8_t hard_alpa, uint32_t preferred_d_id, void *arg);
 1361 extern int32_t ocs_hw_eq_process(ocs_hw_t *hw, hw_eq_t *eq, uint32_t max_isr_time_msec);
 1362 extern void ocs_hw_cq_process(ocs_hw_t *hw, hw_cq_t *cq);
 1363 extern void ocs_hw_wq_process(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe, int32_t status, uint16_t rid);
 1364 extern void ocs_hw_xabt_process(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe, uint16_t rid);
 1365 extern int32_t hw_wq_write(hw_wq_t *wq, ocs_hw_wqe_t *wqe);
 1366 
 1367 typedef void (*ocs_hw_dump_clear_cb_t)(int32_t status, void *arg);
 1368 extern ocs_hw_rtn_e ocs_hw_dump_clear(ocs_hw_t *, ocs_hw_dump_clear_cb_t, void *);
 1369 
 1370 extern uint8_t ocs_hw_is_io_port_owned(ocs_hw_t *hw, ocs_hw_io_t *io);
 1371 
 1372 extern uint8_t ocs_hw_is_xri_port_owned(ocs_hw_t *hw, uint32_t xri);
 1373 extern ocs_hw_io_t * ocs_hw_io_lookup(ocs_hw_t *hw, uint32_t indicator);
 1374 extern uint32_t ocs_hw_xri_move_to_port_owned(ocs_hw_t *hw, uint32_t num_xri);
 1375 extern ocs_hw_rtn_e ocs_hw_xri_move_to_host_owned(ocs_hw_t *hw, uint8_t num_xri);
 1376 extern int32_t ocs_hw_reque_xri(ocs_hw_t *hw, ocs_hw_io_t *io);
 1377 
 1378 typedef struct {
 1379         /* structure elements used by HW */
 1380         ocs_hw_t *hw;                   /**> pointer to HW */
 1381         hw_wq_callback_t *wqcb; /**> WQ callback object, request tag */
 1382         ocs_hw_wqe_t wqe;               /**> WQE buffer object (may be queued on WQ pending list) */
 1383         void (*callback)(int32_t status, void *arg);    /**> final callback function */
 1384         void *arg;                      /**> final callback argument */
 1385 
 1386         /* General purpose elements */
 1387         ocs_hw_sequence_t *seq;
 1388         ocs_dma_t payload;              /**> a payload DMA buffer */
 1389 } ocs_hw_send_frame_context_t;
 1390 
 1391 #define OCS_HW_OBJECT_G5              0xfeaa0001
 1392 #define OCS_HW_OBJECT_G6              0xfeaa0003
 1393 #define OCS_FILE_TYPE_GROUP            0xf7
 1394 #define OCS_FILE_ID_GROUP              0xa2
 1395 struct ocs_hw_grp_hdr {
 1396         uint32_t size;          
 1397         uint32_t magic_number;  
 1398         uint32_t word2;         
 1399         uint8_t rev_name[128];
 1400         uint8_t date[12];
 1401         uint8_t revision[32];
 1402 };                              
 1403 
 1404 ocs_hw_rtn_e
 1405 ocs_hw_send_frame(ocs_hw_t *hw, fc_header_le_t *hdr, uint8_t sof, uint8_t eof, ocs_dma_t *payload,
 1406                    ocs_hw_send_frame_context_t *ctx,
 1407                    void (*callback)(void *arg, uint8_t *cqe, int32_t status), void *arg);
 1408 
 1409 /* RQ completion handlers for RQ pair mode */
 1410 extern int32_t ocs_hw_rqpair_process_rq(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe);
 1411 extern ocs_hw_rtn_e ocs_hw_rqpair_sequence_free(ocs_hw_t *hw, ocs_hw_sequence_t *seq);
 1412 extern int32_t ocs_hw_rqpair_process_auto_xfr_rdy_cmd(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe);
 1413 extern int32_t ocs_hw_rqpair_process_auto_xfr_rdy_data(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe);
 1414 extern ocs_hw_rtn_e ocs_hw_rqpair_init(ocs_hw_t *hw);
 1415 extern ocs_hw_rtn_e ocs_hw_rqpair_auto_xfer_rdy_buffer_alloc(ocs_hw_t *hw, uint32_t num_buffers);
 1416 extern uint8_t ocs_hw_rqpair_auto_xfer_rdy_buffer_post(ocs_hw_t *hw, ocs_hw_io_t *io, int reuse_buf);
 1417 extern ocs_hw_rtn_e ocs_hw_rqpair_auto_xfer_rdy_move_to_port(ocs_hw_t *hw, ocs_hw_io_t *io);
 1418 extern void ocs_hw_rqpair_auto_xfer_rdy_move_to_host(ocs_hw_t *hw, ocs_hw_io_t *io);
 1419 extern void ocs_hw_rqpair_teardown(ocs_hw_t *hw);
 1420 
 1421 extern ocs_hw_rtn_e ocs_hw_rx_allocate(ocs_hw_t *hw);
 1422 extern ocs_hw_rtn_e ocs_hw_rx_post(ocs_hw_t *hw);
 1423 extern void ocs_hw_rx_free(ocs_hw_t *hw);
 1424 
 1425 extern void ocs_hw_unsol_process_bounce(void *arg);
 1426 
 1427 typedef int32_t (*ocs_hw_async_cb_t)(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg);
 1428 extern int32_t ocs_hw_async_call(ocs_hw_t *hw, ocs_hw_async_cb_t callback, void *arg);
 1429 
 1430 static inline void
 1431 ocs_hw_sequence_copy(ocs_hw_sequence_t *dst, ocs_hw_sequence_t *src)
 1432 {
 1433         /* Copy the src to dst, then zero out the linked list link */
 1434         *dst = *src;
 1435         ocs_memset(&dst->link, 0, sizeof(dst->link));
 1436 }
 1437 
 1438 static inline ocs_hw_rtn_e
 1439 ocs_hw_sequence_free(ocs_hw_t *hw, ocs_hw_sequence_t *seq)
 1440 {
 1441         /* Only RQ pair mode is supported */
 1442         return ocs_hw_rqpair_sequence_free(hw, seq);
 1443 }
 1444 
 1445 /* HW WQ request tag API */
 1446 extern ocs_hw_rtn_e ocs_hw_reqtag_init(ocs_hw_t *hw);
 1447 extern hw_wq_callback_t *ocs_hw_reqtag_alloc(ocs_hw_t *hw,
 1448                                                void (*callback)(void *arg, uint8_t *cqe, int32_t status), void *arg);
 1449 extern void ocs_hw_reqtag_free(ocs_hw_t *hw, hw_wq_callback_t *wqcb);
 1450 extern hw_wq_callback_t *ocs_hw_reqtag_get_instance(ocs_hw_t *hw, uint32_t instance_index);
 1451 extern void ocs_hw_reqtag_reset(ocs_hw_t *hw);
 1452 
 1453 extern uint32_t ocs_hw_dif_blocksize(ocs_hw_dif_info_t *dif_info);
 1454 extern int32_t ocs_hw_dif_mem_blocksize(ocs_hw_dif_info_t *dif_info, int wiretomem);
 1455 extern int32_t ocs_hw_dif_wire_blocksize(ocs_hw_dif_info_t *dif_info, int wiretomem);
 1456 extern uint32_t ocs_hw_get_def_wwn(ocs_t *ocs, uint32_t chan, uint64_t *wwpn, uint64_t *wwnn);
 1457 
 1458 /* Uncomment to enable CPUTRACE */
 1459 //#define ENABLE_CPUTRACE
 1460 #ifdef ENABLE_CPUTRACE
 1461 #define CPUTRACE(t) ocs_printf("trace: %-20s %2s %-16s cpu %2d\n", __func__, t, \
 1462         ({ocs_thread_t *self = ocs_thread_self(); self != NULL ? self->name : "unknown";}), ocs_thread_getcpu());
 1463 #else
 1464 #define CPUTRACE(...)
 1465 #endif
 1466 
 1467 /* Two levels of macro needed due to expansion */
 1468 #define HW_FWREV(a,b,c,d) (((uint64_t)(a) << 48) | ((uint64_t)(b) << 32) | ((uint64_t)(c) << 16) | ((uint64_t)(d)))
 1469 #define HW_FWREV_1(x) HW_FWREV(x)
 1470 
 1471 #define OCS_FW_VER_STR2(a,b,c,d) #a "." #b "." #c "." #d
 1472 #define OCS_FW_VER_STR(x) OCS_FW_VER_STR2(x)
 1473 
 1474 #define OCS_MIN_FW_VER_LANCER 10,4,255,0
 1475 #define OCS_MIN_FW_VER_SKYHAWK 10,4,255,0
 1476 
 1477 extern void ocs_hw_workaround_setup(struct ocs_hw_s *hw);
 1478 
 1479 /**
 1480  * @brief Defines the number of the RQ buffers for each RQ
 1481  */
 1482 
 1483 #ifndef OCS_HW_RQ_NUM_HDR
 1484 #define OCS_HW_RQ_NUM_HDR               1024
 1485 #endif
 1486 
 1487 #ifndef OCS_HW_RQ_NUM_PAYLOAD
 1488 #define OCS_HW_RQ_NUM_PAYLOAD                   1024
 1489 #endif
 1490 
 1491 /**
 1492  * @brief Defines the size of the RQ buffers used for each RQ
 1493  */
 1494 #ifndef OCS_HW_RQ_SIZE_HDR
 1495 #define OCS_HW_RQ_SIZE_HDR              128
 1496 #endif
 1497 
 1498 #ifndef OCS_HW_RQ_SIZE_PAYLOAD
 1499 #define OCS_HW_RQ_SIZE_PAYLOAD          1024
 1500 #endif
 1501 
 1502 /*
 1503  * @brief Define the maximum number of multi-receive queues
 1504  */
 1505 #ifndef OCS_HW_MAX_MRQS
 1506 #define OCS_HW_MAX_MRQS                 8
 1507 #endif
 1508 
 1509 /*
 1510  * @brief Define count of when to set the WQEC bit in a submitted
 1511  * WQE, causing a consummed/released completion to be posted.
 1512  */
 1513 #ifndef OCS_HW_WQEC_SET_COUNT
 1514 #define OCS_HW_WQEC_SET_COUNT                   32
 1515 #endif
 1516 
 1517 /*
 1518  * @brief Send frame timeout in seconds
 1519  */
 1520 #ifndef OCS_HW_SEND_FRAME_TIMEOUT
 1521 #define OCS_HW_SEND_FRAME_TIMEOUT               10
 1522 #endif
 1523 
 1524 /*
 1525  * @brief FDT Transfer Hint value, reads greater than this value
 1526  * will be segmented to implement fairness.   A value of zero disables
 1527  * the feature.
 1528  */
 1529 #ifndef OCS_HW_FDT_XFER_HINT
 1530 #define OCS_HW_FDT_XFER_HINT                    8192
 1531 #endif
 1532 
 1533 #endif /* !_OCS_HW_H */

Cache object: 87a3ffbff90883ba2bcec426fc261e12


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.