1331766Sken/*- 2331766Sken * Copyright (c) 2017 Broadcom. All rights reserved. 3331766Sken * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries. 4331766Sken * 5331766Sken * Redistribution and use in source and binary forms, with or without 6331766Sken * modification, are permitted provided that the following conditions are met: 7331766Sken * 8331766Sken * 1. Redistributions of source code must retain the above copyright notice, 9331766Sken * this list of conditions and the following disclaimer. 10331766Sken * 11331766Sken * 2. Redistributions in binary form must reproduce the above copyright notice, 12331766Sken * this list of conditions and the following disclaimer in the documentation 13331766Sken * and/or other materials provided with the distribution. 14331766Sken * 15331766Sken * 3. Neither the name of the copyright holder nor the names of its contributors 16331766Sken * may be used to endorse or promote products derived from this software 17331766Sken * without specific prior written permission. 18331766Sken * 19331766Sken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20331766Sken * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21331766Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22331766Sken * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23331766Sken * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24331766Sken * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25331766Sken * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26331766Sken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27331766Sken * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28331766Sken * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29331766Sken * POSSIBILITY OF SUCH DAMAGE. 30331766Sken * 31331766Sken * $FreeBSD: stable/11/sys/dev/ocs_fc/ocs_hw.h 331766 2018-03-30 15:28:25Z ken $ 32331766Sken */ 33331766Sken 34331766Sken/** 35331766Sken * @file 36331766Sken * Defines the Hardware Abstraction Layer (HW) interface functions. 37331766Sken */ 38331766Sken 39331766Sken#ifndef _OCS_HW_H 40331766Sken#define _OCS_HW_H 41331766Sken 42331766Sken#include "sli4.h" 43331766Sken#include "ocs_hw.h" 44331766Sken#include "ocs_stats.h" 45331766Sken#include "ocs_utils.h" 46331766Sken 47331766Skentypedef struct ocs_hw_io_s ocs_hw_io_t; 48331766Sken 49331766Sken 50331766Sken#if defined(OCS_INCLUDE_DEBUG) 51331766Sken#else 52331766Sken#define ocs_queue_history_wq(...) 53331766Sken#define ocs_queue_history_cqe(...) 54331766Sken#define ocs_queue_history_init(...) 55331766Sken#define ocs_queue_history_free(...) 56331766Sken#endif 57331766Sken 58331766Sken/** 59331766Sken * @brief HW queue forward declarations 60331766Sken */ 61331766Skentypedef struct hw_eq_s hw_eq_t; 62331766Skentypedef struct hw_cq_s hw_cq_t; 63331766Skentypedef struct hw_mq_s hw_mq_t; 64331766Skentypedef struct hw_wq_s hw_wq_t; 65331766Skentypedef struct hw_rq_s hw_rq_t; 66331766Skentypedef struct hw_rq_grp_s hw_rq_grp_t; 67331766Sken 68331766Sken/* HW asserts/verify 69331766Sken * 70331766Sken */ 71331766Sken 72331766Skenextern void _ocs_hw_assert(const char *cond, const char *filename, int linenum); 73331766Skenextern void _ocs_hw_verify(const char *cond, const char *filename, int linenum); 74331766Sken 75331766Sken#if defined(HW_NDEBUG) 76331766Sken#define ocs_hw_assert(cond) 77331766Sken#define ocs_hw_verify(cond, ...) 78331766Sken#else 79331766Sken#define ocs_hw_assert(cond) \ 80331766Sken do { \ 81331766Sken if ((!(cond))) { \ 82331766Sken _ocs_hw_assert(#cond, __FILE__, __LINE__); \ 83331766Sken } \ 84331766Sken } while (0) 85331766Sken 86331766Sken#define ocs_hw_verify(cond, ...) \ 87331766Sken do { \ 88331766Sken if ((!(cond))) { \ 89331766Sken _ocs_hw_verify(#cond, __FILE__, __LINE__); \ 90331766Sken return __VA_ARGS__; \ 91331766Sken } \ 92331766Sken } while (0) 93331766Sken#endif 94331766Sken#define ocs_hw_verify_arg(cond) ocs_hw_verify(cond, OCS_HW_RTN_INVALID_ARG) 95331766Sken 96331766Sken/* 97331766Sken * HW completion loop control parameters. 98331766Sken * 99331766Sken * The HW completion loop must terminate periodically to keep the OS happy. The 100331766Sken * loop terminates when a predefined time has elapsed, but to keep the overhead of 101331766Sken * computing time down, the time is only checked after a number of loop iterations 102331766Sken * has completed. 103331766Sken * 104331766Sken * OCS_HW_TIMECHECK_ITERATIONS number of loop iterations between time checks 105331766Sken * 106331766Sken */ 107331766Sken 108331766Sken#define OCS_HW_TIMECHECK_ITERATIONS 100 109331766Sken#define OCS_HW_MAX_NUM_MQ 1 110331766Sken#define OCS_HW_MAX_NUM_RQ 32 111331766Sken#define OCS_HW_MAX_NUM_EQ 16 112331766Sken#define OCS_HW_MAX_NUM_WQ 32 113331766Sken 114331766Sken#define OCE_HW_MAX_NUM_MRQ_PAIRS 16 115331766Sken 116331766Sken#define OCS_HW_MAX_WQ_CLASS 4 117331766Sken#define OCS_HW_MAX_WQ_CPU 128 118331766Sken 119331766Sken/* 120331766Sken * A CQ will be assinged to each WQ (CQ must have 2X entries of the WQ for abort 121331766Sken * processing), plus a separate one for each RQ PAIR and one for MQ 122331766Sken */ 123331766Sken#define OCS_HW_MAX_NUM_CQ ((OCS_HW_MAX_NUM_WQ*2) + 1 + (OCE_HW_MAX_NUM_MRQ_PAIRS * 2)) 124331766Sken 125331766Sken/* 126331766Sken * Q hash - size is the maximum of all the queue sizes, rounded up to the next 127331766Sken * power of 2 128331766Sken */ 129331766Sken#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, \ 130331766Sken OCS_MAX(OCS_HW_MAX_NUM_EQ, OCS_MAX(OCS_HW_MAX_NUM_WQ, \ 131331766Sken OCS_HW_MAX_NUM_CQ))))) 132331766Sken 133331766Sken#define OCS_HW_RQ_HEADER_SIZE 128 134331766Sken#define OCS_HW_RQ_HEADER_INDEX 0 135331766Sken 136331766Sken/** 137331766Sken * @brief Options for ocs_hw_command(). 138331766Sken */ 139331766Skenenum { 140331766Sken OCS_CMD_POLL, /**< command executes synchronously and busy-waits for completion */ 141331766Sken OCS_CMD_NOWAIT, /**< command executes asynchronously. Uses callback */ 142331766Sken}; 143331766Sken 144331766Skentypedef enum { 145331766Sken OCS_HW_RTN_SUCCESS = 0, 146331766Sken OCS_HW_RTN_SUCCESS_SYNC = 1, 147331766Sken OCS_HW_RTN_ERROR = -1, 148331766Sken OCS_HW_RTN_NO_RESOURCES = -2, 149331766Sken OCS_HW_RTN_NO_MEMORY = -3, 150331766Sken OCS_HW_RTN_IO_NOT_ACTIVE = -4, 151331766Sken OCS_HW_RTN_IO_ABORT_IN_PROGRESS = -5, 152331766Sken OCS_HW_RTN_IO_PORT_OWNED_ALREADY_ABORTED = -6, 153331766Sken OCS_HW_RTN_INVALID_ARG = -7, 154331766Sken} ocs_hw_rtn_e; 155331766Sken#define OCS_HW_RTN_IS_ERROR(e) ((e) < 0) 156331766Sken 157331766Skentypedef enum { 158331766Sken OCS_HW_RESET_FUNCTION, 159331766Sken OCS_HW_RESET_FIRMWARE, 160331766Sken OCS_HW_RESET_MAX 161331766Sken} ocs_hw_reset_e; 162331766Sken 163331766Skentypedef enum { 164331766Sken OCS_HW_N_IO, 165331766Sken OCS_HW_N_SGL, 166331766Sken OCS_HW_MAX_IO, 167331766Sken OCS_HW_MAX_SGE, 168331766Sken OCS_HW_MAX_SGL, 169331766Sken OCS_HW_MAX_NODES, 170331766Sken OCS_HW_MAX_RQ_ENTRIES, 171331766Sken OCS_HW_TOPOLOGY, /**< auto, nport, loop */ 172331766Sken OCS_HW_WWN_NODE, 173331766Sken OCS_HW_WWN_PORT, 174331766Sken OCS_HW_FW_REV, 175331766Sken OCS_HW_FW_REV2, 176331766Sken OCS_HW_IPL, 177331766Sken OCS_HW_VPD, 178331766Sken OCS_HW_VPD_LEN, 179331766Sken OCS_HW_MODE, /**< initiator, target, both */ 180331766Sken OCS_HW_LINK_SPEED, 181331766Sken OCS_HW_IF_TYPE, 182331766Sken OCS_HW_SLI_REV, 183331766Sken OCS_HW_SLI_FAMILY, 184331766Sken OCS_HW_RQ_PROCESS_LIMIT, 185331766Sken OCS_HW_RQ_DEFAULT_BUFFER_SIZE, 186331766Sken OCS_HW_AUTO_XFER_RDY_CAPABLE, 187331766Sken OCS_HW_AUTO_XFER_RDY_XRI_CNT, 188331766Sken OCS_HW_AUTO_XFER_RDY_SIZE, 189331766Sken OCS_HW_AUTO_XFER_RDY_BLK_SIZE, 190331766Sken OCS_HW_AUTO_XFER_RDY_T10_ENABLE, 191331766Sken OCS_HW_AUTO_XFER_RDY_P_TYPE, 192331766Sken OCS_HW_AUTO_XFER_RDY_REF_TAG_IS_LBA, 193331766Sken OCS_HW_AUTO_XFER_RDY_APP_TAG_VALID, 194331766Sken OCS_HW_AUTO_XFER_RDY_APP_TAG_VALUE, 195331766Sken OCS_HW_DIF_CAPABLE, 196331766Sken OCS_HW_DIF_SEED, 197331766Sken OCS_HW_DIF_MODE, 198331766Sken OCS_HW_DIF_MULTI_SEPARATE, 199331766Sken OCS_HW_DUMP_MAX_SIZE, 200331766Sken OCS_HW_DUMP_READY, 201331766Sken OCS_HW_DUMP_PRESENT, 202331766Sken OCS_HW_RESET_REQUIRED, 203331766Sken OCS_HW_FW_ERROR, 204331766Sken OCS_HW_FW_READY, 205331766Sken OCS_HW_HIGH_LOGIN_MODE, 206331766Sken OCS_HW_PREREGISTER_SGL, 207331766Sken OCS_HW_HW_REV1, 208331766Sken OCS_HW_HW_REV2, 209331766Sken OCS_HW_HW_REV3, 210331766Sken OCS_HW_LINKCFG, 211331766Sken OCS_HW_ETH_LICENSE, 212331766Sken OCS_HW_LINK_MODULE_TYPE, 213331766Sken OCS_HW_NUM_CHUTES, 214331766Sken OCS_HW_WAR_VERSION, 215331766Sken OCS_HW_DISABLE_AR_TGT_DIF, 216331766Sken OCS_HW_EMULATE_I_ONLY_AAB, /**< emulate IAAB=0 for initiator-commands only */ 217331766Sken OCS_HW_EMULATE_TARGET_WQE_TIMEOUT, /**< enable driver timeouts for target WQEs */ 218331766Sken OCS_HW_LINK_CONFIG_SPEED, 219331766Sken OCS_HW_CONFIG_TOPOLOGY, 220331766Sken OCS_HW_BOUNCE, 221331766Sken OCS_HW_PORTNUM, 222331766Sken OCS_HW_BIOS_VERSION_STRING, 223331766Sken OCS_HW_RQ_SELECT_POLICY, 224331766Sken OCS_HW_SGL_CHAINING_CAPABLE, 225331766Sken OCS_HW_SGL_CHAINING_ALLOWED, 226331766Sken OCS_HW_SGL_CHAINING_HOST_ALLOCATED, 227331766Sken OCS_HW_SEND_FRAME_CAPABLE, 228331766Sken OCS_HW_RQ_SELECTION_POLICY, 229331766Sken OCS_HW_RR_QUANTA, 230331766Sken OCS_HW_FILTER_DEF, 231331766Sken OCS_HW_MAX_VPORTS, 232331766Sken OCS_ESOC, 233331766Sken OCS_HW_FW_TIMED_OUT, 234331766Sken} ocs_hw_property_e; 235331766Sken 236331766Skenenum { 237331766Sken OCS_HW_TOPOLOGY_AUTO, 238331766Sken OCS_HW_TOPOLOGY_NPORT, 239331766Sken OCS_HW_TOPOLOGY_LOOP, 240331766Sken OCS_HW_TOPOLOGY_NONE, 241331766Sken OCS_HW_TOPOLOGY_MAX 242331766Sken}; 243331766Sken 244331766Skenenum { 245331766Sken OCS_HW_MODE_INITIATOR, 246331766Sken OCS_HW_MODE_TARGET, 247331766Sken OCS_HW_MODE_BOTH, 248331766Sken OCS_HW_MODE_MAX 249331766Sken}; 250331766Sken 251331766Sken/** 252331766Sken * @brief Port protocols 253331766Sken */ 254331766Sken 255331766Skentypedef enum { 256331766Sken OCS_HW_PORT_PROTOCOL_ISCSI, 257331766Sken OCS_HW_PORT_PROTOCOL_FCOE, 258331766Sken OCS_HW_PORT_PROTOCOL_FC, 259331766Sken OCS_HW_PORT_PROTOCOL_OTHER, 260331766Sken} ocs_hw_port_protocol_e; 261331766Sken 262331766Sken#define OCS_HW_MAX_PROFILES 40 263331766Sken/** 264331766Sken * @brief A Profile Descriptor 265331766Sken */ 266331766Skentypedef struct { 267331766Sken uint32_t profile_index; 268331766Sken uint32_t profile_id; 269331766Sken char profile_description[512]; 270331766Sken} ocs_hw_profile_descriptor_t; 271331766Sken 272331766Sken/** 273331766Sken * @brief A Profile List 274331766Sken */ 275331766Skentypedef struct { 276331766Sken uint32_t num_descriptors; 277331766Sken ocs_hw_profile_descriptor_t descriptors[OCS_HW_MAX_PROFILES]; 278331766Sken} ocs_hw_profile_list_t; 279331766Sken 280331766Sken 281331766Sken/** 282331766Sken * @brief Defines DIF operation modes 283331766Sken */ 284331766Skenenum { 285331766Sken OCS_HW_DIF_MODE_INLINE, 286331766Sken OCS_HW_DIF_MODE_SEPARATE, 287331766Sken}; 288331766Sken 289331766Sken/** 290331766Sken * @brief Defines the type of RQ buffer 291331766Sken */ 292331766Skentypedef enum { 293331766Sken OCS_HW_RQ_BUFFER_TYPE_HDR, 294331766Sken OCS_HW_RQ_BUFFER_TYPE_PAYLOAD, 295331766Sken OCS_HW_RQ_BUFFER_TYPE_MAX, 296331766Sken} ocs_hw_rq_buffer_type_e; 297331766Sken 298331766Sken/** 299331766Sken * @brief Defines a wrapper for the RQ payload buffers so that we can place it 300331766Sken * back on the proper queue. 301331766Sken */ 302331766Skentypedef struct { 303331766Sken uint16_t rqindex; 304331766Sken ocs_dma_t dma; 305331766Sken} ocs_hw_rq_buffer_t; 306331766Sken 307331766Sken/** 308331766Sken * @brief T10 DIF operations. 309331766Sken */ 310331766Skentypedef enum { 311331766Sken OCS_HW_DIF_OPER_DISABLED, 312331766Sken OCS_HW_SGE_DIF_OP_IN_NODIF_OUT_CRC, 313331766Sken OCS_HW_SGE_DIF_OP_IN_CRC_OUT_NODIF, 314331766Sken OCS_HW_SGE_DIF_OP_IN_NODIF_OUT_CHKSUM, 315331766Sken OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_NODIF, 316331766Sken OCS_HW_SGE_DIF_OP_IN_CRC_OUT_CRC, 317331766Sken OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_CHKSUM, 318331766Sken OCS_HW_SGE_DIF_OP_IN_CRC_OUT_CHKSUM, 319331766Sken OCS_HW_SGE_DIF_OP_IN_CHKSUM_OUT_CRC, 320331766Sken OCS_HW_SGE_DIF_OP_IN_RAW_OUT_RAW, 321331766Sken} ocs_hw_dif_oper_e; 322331766Sken 323331766Sken#define OCS_HW_DIF_OPER_PASS_THRU OCS_HW_SGE_DIF_OP_IN_CRC_OUT_CRC 324331766Sken#define OCS_HW_DIF_OPER_STRIP OCS_HW_SGE_DIF_OP_IN_CRC_OUT_NODIF 325331766Sken#define OCS_HW_DIF_OPER_INSERT OCS_HW_SGE_DIF_OP_IN_NODIF_OUT_CRC 326331766Sken 327331766Sken/** 328331766Sken * @brief T10 DIF block sizes. 329331766Sken */ 330331766Skentypedef enum { 331331766Sken OCS_HW_DIF_BK_SIZE_512, 332331766Sken OCS_HW_DIF_BK_SIZE_1024, 333331766Sken OCS_HW_DIF_BK_SIZE_2048, 334331766Sken OCS_HW_DIF_BK_SIZE_4096, 335331766Sken OCS_HW_DIF_BK_SIZE_520, 336331766Sken OCS_HW_DIF_BK_SIZE_4104, 337331766Sken OCS_HW_DIF_BK_SIZE_NA = 0 338331766Sken} ocs_hw_dif_blk_size_e; 339331766Sken 340331766Sken/** 341331766Sken * @brief Link configurations. 342331766Sken */ 343331766Skentypedef enum { 344331766Sken OCS_HW_LINKCFG_4X10G = 0, 345331766Sken OCS_HW_LINKCFG_1X40G, 346331766Sken OCS_HW_LINKCFG_2X16G, 347331766Sken OCS_HW_LINKCFG_4X8G, 348331766Sken OCS_HW_LINKCFG_4X1G, 349331766Sken OCS_HW_LINKCFG_2X10G, 350331766Sken OCS_HW_LINKCFG_2X10G_2X8G, 351331766Sken 352331766Sken /* must be last */ 353331766Sken OCS_HW_LINKCFG_NA, 354331766Sken} ocs_hw_linkcfg_e; 355331766Sken 356331766Sken/** 357331766Sken * @brief link module types 358331766Sken * 359331766Sken * (note: these just happen to match SLI4 values) 360331766Sken */ 361331766Sken 362331766Skenenum { 363331766Sken OCS_HW_LINK_MODULE_TYPE_1GB = 0x0004, 364331766Sken OCS_HW_LINK_MODULE_TYPE_2GB = 0x0008, 365331766Sken OCS_HW_LINK_MODULE_TYPE_4GB = 0x0040, 366331766Sken OCS_HW_LINK_MODULE_TYPE_8GB = 0x0080, 367331766Sken OCS_HW_LINK_MODULE_TYPE_10GB = 0x0100, 368331766Sken OCS_HW_LINK_MODULE_TYPE_16GB = 0x0200, 369331766Sken OCS_HW_LINK_MODULE_TYPE_32GB = 0x0400, 370331766Sken}; 371331766Sken 372331766Sken/** 373331766Sken * @brief T10 DIF information passed to the transport. 374331766Sken */ 375331766Skentypedef struct ocs_hw_dif_info_s { 376331766Sken ocs_hw_dif_oper_e dif_oper; 377331766Sken ocs_hw_dif_blk_size_e blk_size; 378331766Sken uint32_t ref_tag_cmp; 379331766Sken uint32_t ref_tag_repl; 380331766Sken uint32_t app_tag_cmp:16, 381331766Sken app_tag_repl:16; 382331766Sken uint32_t check_ref_tag:1, 383331766Sken check_app_tag:1, 384331766Sken check_guard:1, 385331766Sken auto_incr_ref_tag:1, 386331766Sken repl_app_tag:1, 387331766Sken repl_ref_tag:1, 388331766Sken dif:2, 389331766Sken dif_separate:1, 390331766Sken 391331766Sken /* If the APP TAG is 0xFFFF, disable checking the REF TAG and CRC fields */ 392331766Sken disable_app_ffff:1, 393331766Sken 394331766Sken /* if the APP TAG is 0xFFFF and REF TAG is 0xFFFF_FFFF, disable checking the received CRC field. */ 395331766Sken disable_app_ref_ffff:1, 396331766Sken 397331766Sken :21; 398331766Sken uint16_t dif_seed; 399331766Sken} ocs_hw_dif_info_t; 400331766Skentypedef enum { 401331766Sken OCS_HW_ELS_REQ, /**< ELS request */ 402331766Sken OCS_HW_ELS_RSP, /**< ELS response */ 403331766Sken OCS_HW_ELS_RSP_SID, /**< ELS response, override the S_ID */ 404331766Sken OCS_HW_FC_CT, /**< FC Common Transport */ 405331766Sken OCS_HW_FC_CT_RSP, /**< FC Common Transport Response */ 406331766Sken OCS_HW_BLS_ACC, /**< BLS accept (BA_ACC) */ 407331766Sken OCS_HW_BLS_ACC_SID, /**< BLS accept (BA_ACC), override the S_ID */ 408331766Sken OCS_HW_BLS_RJT, /**< BLS reject (BA_RJT) */ 409331766Sken OCS_HW_BCAST, /**< Class 3 broadcast sequence */ 410331766Sken OCS_HW_IO_TARGET_READ, 411331766Sken OCS_HW_IO_TARGET_WRITE, 412331766Sken OCS_HW_IO_TARGET_RSP, 413331766Sken OCS_HW_IO_INITIATOR_READ, 414331766Sken OCS_HW_IO_INITIATOR_WRITE, 415331766Sken OCS_HW_IO_INITIATOR_NODATA, 416331766Sken OCS_HW_IO_DNRX_REQUEUE, 417331766Sken OCS_HW_IO_MAX, 418331766Sken} ocs_hw_io_type_e; 419331766Sken 420331766Skentypedef enum { 421331766Sken OCS_HW_IO_STATE_FREE, 422331766Sken OCS_HW_IO_STATE_INUSE, 423331766Sken OCS_HW_IO_STATE_WAIT_FREE, 424331766Sken OCS_HW_IO_STATE_WAIT_SEC_HIO, 425331766Sken} ocs_hw_io_state_e; 426331766Sken 427331766Sken/* Descriptive strings for the HW IO request types (note: these must always 428331766Sken * match up with the ocs_hw_io_type_e declaration) */ 429331766Sken#define OCS_HW_IO_TYPE_STRINGS \ 430331766Sken "ELS request", \ 431331766Sken "ELS response", \ 432331766Sken "ELS response(set SID)", \ 433331766Sken "FC CT request", \ 434331766Sken "BLS accept", \ 435331766Sken "BLS accept(set SID)", \ 436331766Sken "BLS reject", \ 437331766Sken "target read", \ 438331766Sken "target write", \ 439331766Sken "target response", \ 440331766Sken "initiator read", \ 441331766Sken "initiator write", \ 442331766Sken "initiator nodata", 443331766Sken 444331766Sken/** 445331766Sken * @brief HW command context. 446331766Sken * 447331766Sken * Stores the state for the asynchronous commands sent to the hardware. 448331766Sken */ 449331766Skentypedef struct ocs_command_ctx_s { 450331766Sken ocs_list_t link; 451331766Sken /**< Callback function */ 452331766Sken int32_t (*cb)(struct ocs_hw_s *, int32_t, uint8_t *, void *); 453331766Sken void *arg; /**< Argument for callback */ 454331766Sken uint8_t *buf; /**< buffer holding command / results */ 455331766Sken void *ctx; /**< upper layer context */ 456331766Sken} ocs_command_ctx_t; 457331766Sken 458331766Skentypedef struct ocs_hw_sgl_s { 459331766Sken uintptr_t addr; 460331766Sken size_t len; 461331766Sken} ocs_hw_sgl_t; 462331766Sken 463331766Sken/** 464331766Sken * @brief HW callback type 465331766Sken * 466331766Sken * Typedef for HW "done" callback. 467331766Sken */ 468331766Skentypedef 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); 469331766Sken 470331766Sken 471331766Skentypedef union ocs_hw_io_param_u { 472331766Sken struct { 473331766Sken uint16_t ox_id; 474331766Sken uint16_t rx_id; 475331766Sken uint8_t payload[12]; /**< big enough for ABTS BA_ACC */ 476331766Sken } bls; 477331766Sken struct { 478331766Sken uint32_t s_id; 479331766Sken uint16_t ox_id; 480331766Sken uint16_t rx_id; 481331766Sken uint8_t payload[12]; /**< big enough for ABTS BA_ACC */ 482331766Sken } bls_sid; 483331766Sken struct { 484331766Sken uint8_t r_ctl; 485331766Sken uint8_t type; 486331766Sken uint8_t df_ctl; 487331766Sken uint8_t timeout; 488331766Sken } bcast; 489331766Sken struct { 490331766Sken uint16_t ox_id; 491331766Sken uint8_t timeout; 492331766Sken } els; 493331766Sken struct { 494331766Sken uint32_t s_id; 495331766Sken uint16_t ox_id; 496331766Sken uint8_t timeout; 497331766Sken } els_sid; 498331766Sken struct { 499331766Sken uint8_t r_ctl; 500331766Sken uint8_t type; 501331766Sken uint8_t df_ctl; 502331766Sken uint8_t timeout; 503331766Sken } fc_ct; 504331766Sken struct { 505331766Sken uint8_t r_ctl; 506331766Sken uint8_t type; 507331766Sken uint8_t df_ctl; 508331766Sken uint8_t timeout; 509331766Sken uint16_t ox_id; 510331766Sken } fc_ct_rsp; 511331766Sken struct { 512331766Sken uint32_t offset; 513331766Sken uint16_t ox_id; 514331766Sken uint16_t flags; 515331766Sken uint8_t cs_ctl; 516331766Sken ocs_hw_dif_oper_e dif_oper; 517331766Sken ocs_hw_dif_blk_size_e blk_size; 518331766Sken uint8_t timeout; 519331766Sken uint32_t app_id; 520331766Sken } fcp_tgt; 521331766Sken struct { 522331766Sken ocs_dma_t *cmnd; 523331766Sken ocs_dma_t *rsp; 524331766Sken ocs_hw_dif_oper_e dif_oper; 525331766Sken ocs_hw_dif_blk_size_e blk_size; 526331766Sken uint32_t cmnd_size; 527331766Sken uint16_t flags; 528331766Sken uint8_t timeout; 529331766Sken uint32_t first_burst; 530331766Sken } fcp_ini; 531331766Sken} ocs_hw_io_param_t; 532331766Sken 533331766Sken/** 534331766Sken * @brief WQ steering mode 535331766Sken */ 536331766Skentypedef enum { 537331766Sken OCS_HW_WQ_STEERING_CLASS, 538331766Sken OCS_HW_WQ_STEERING_REQUEST, 539331766Sken OCS_HW_WQ_STEERING_CPU, 540331766Sken} ocs_hw_wq_steering_e; 541331766Sken 542331766Sken/** 543331766Sken * @brief HW wqe object 544331766Sken */ 545331766Skentypedef struct { 546331766Sken uint32_t abort_wqe_submit_needed:1, /**< set if abort wqe needs to be submitted */ 547331766Sken send_abts:1, /**< set to 1 to have hardware to automatically send ABTS */ 548331766Sken auto_xfer_rdy_dnrx:1, /**< TRUE if DNRX was set on this IO */ 549331766Sken :29; 550331766Sken uint32_t id; 551331766Sken uint32_t abort_reqtag; 552331766Sken ocs_list_link_t link; 553331766Sken uint8_t *wqebuf; /**< work queue entry buffer */ 554331766Sken} ocs_hw_wqe_t; 555331766Sken 556331766Sken/** 557331766Sken * @brief HW IO object. 558331766Sken * 559331766Sken * Stores the per-IO information necessary for both the lower (SLI) and upper 560331766Sken * layers (ocs). 561331766Sken */ 562331766Skenstruct ocs_hw_io_s { 563331766Sken /* Owned by HW */ 564331766Sken ocs_list_link_t link; /**< used for busy, wait_free, free lists */ 565331766Sken ocs_list_link_t wqe_link; /**< used for timed_wqe list */ 566331766Sken ocs_list_link_t dnrx_link; /**< used for io posted dnrx list */ 567331766Sken ocs_hw_io_state_e state; /**< state of IO: free, busy, wait_free */ 568331766Sken ocs_hw_wqe_t wqe; /**< Work queue object, with link for pending */ 569331766Sken ocs_lock_t axr_lock; /**< Lock to synchronize TRSP and AXT Data/Cmd Cqes */ 570331766Sken ocs_hw_t *hw; /**< pointer back to hardware context */ 571331766Sken ocs_remote_node_t *rnode; 572331766Sken struct ocs_hw_auto_xfer_rdy_buffer_s *axr_buf; 573331766Sken ocs_dma_t xfer_rdy; 574331766Sken uint16_t type; 575331766Sken uint32_t port_owned_abort_count; /**< IO abort count */ 576331766Sken hw_wq_t *wq; /**< WQ assigned to the exchange */ 577331766Sken uint32_t xbusy; /**< Exchange is active in FW */ 578331766Sken ocs_hw_done_t done; /**< Function called on IO completion */ 579331766Sken void *arg; /**< argument passed to "IO done" callback */ 580331766Sken ocs_hw_done_t abort_done; /**< Function called on abort completion */ 581331766Sken void *abort_arg; /**< argument passed to "abort done" callback */ 582331766Sken ocs_ref_t ref; /**< refcount object */ 583331766Sken size_t length; /**< needed for bug O127585: length of IO */ 584331766Sken uint8_t tgt_wqe_timeout; /**< timeout value for target WQEs */ 585331766Sken uint64_t submit_ticks; /**< timestamp when current WQE was submitted */ 586331766Sken 587331766Sken uint32_t status_saved:1, /**< if TRUE, latched status should be returned */ 588331766Sken abort_in_progress:1, /**< if TRUE, abort is in progress */ 589331766Sken quarantine:1, /**< set if IO to be quarantined */ 590331766Sken quarantine_first_phase:1, /**< set if first phase of IO */ 591331766Sken is_port_owned:1, /**< set if POST_XRI was used to send XRI to th chip */ 592331766Sken auto_xfer_rdy_dnrx:1, /**< TRUE if DNRX was set on this IO */ 593331766Sken :26; 594331766Sken uint32_t saved_status; /**< latched status */ 595331766Sken uint32_t saved_len; /**< latched length */ 596331766Sken uint32_t saved_ext; /**< latched extended status */ 597331766Sken 598331766Sken hw_eq_t *eq; /**< EQ that this HIO came up on */ 599331766Sken ocs_hw_wq_steering_e wq_steering; /**< WQ steering mode request */ 600331766Sken uint8_t wq_class; /**< WQ class if steering mode is Class */ 601331766Sken 602331766Sken /* Owned by SLI layer */ 603331766Sken uint16_t reqtag; /**< request tag for this HW IO */ 604331766Sken uint32_t abort_reqtag; /**< request tag for an abort of this HW IO (note: this is a 32 bit value 605331766Sken to allow us to use UINT32_MAX as an uninitialized value) */ 606331766Sken uint32_t indicator; /**< XRI */ 607331766Sken ocs_dma_t def_sgl; /**< default scatter gather list */ 608331766Sken uint32_t def_sgl_count; /**< count of SGEs in default SGL */ 609331766Sken ocs_dma_t *sgl; /**< pointer to current active SGL */ 610331766Sken uint32_t sgl_count; /**< count of SGEs in io->sgl */ 611331766Sken uint32_t first_data_sge; /**< index of first data SGE */ 612331766Sken ocs_dma_t *ovfl_sgl; /**< overflow SGL */ 613331766Sken uint32_t ovfl_sgl_count; /**< count of SGEs in default SGL */ 614331766Sken sli4_lsp_sge_t *ovfl_lsp; /**< pointer to overflow segment length */ 615331766Sken ocs_hw_io_t *ovfl_io; /**< Used for SGL chaining on skyhawk */ 616331766Sken uint32_t n_sge; /**< number of active SGEs */ 617331766Sken uint32_t sge_offset; 618331766Sken 619331766Sken /* BZ 161832 Workaround: */ 620331766Sken struct ocs_hw_io_s *sec_hio; /**< Secondary HW IO context */ 621331766Sken ocs_hw_io_param_t sec_iparam; /**< Secondary HW IO context saved iparam */ 622331766Sken uint32_t sec_len; /**< Secondary HW IO context saved len */ 623331766Sken 624331766Sken /* Owned by upper layer */ 625331766Sken void *ul_io; /**< where upper layer can store reference to its IO */ 626331766Sken}; 627331766Sken 628331766Skentypedef enum { 629331766Sken OCS_HW_PORT_INIT, 630331766Sken OCS_HW_PORT_SHUTDOWN, 631331766Sken OCS_HW_PORT_SET_LINK_CONFIG, 632331766Sken} ocs_hw_port_e; 633331766Sken 634331766Sken/** 635331766Sken * @brief Fabric/Domain events 636331766Sken */ 637331766Skentypedef enum { 638331766Sken OCS_HW_DOMAIN_ALLOC_OK, /**< domain successfully allocated */ 639331766Sken OCS_HW_DOMAIN_ALLOC_FAIL, /**< domain allocation failed */ 640331766Sken OCS_HW_DOMAIN_ATTACH_OK, /**< successfully attached to domain */ 641331766Sken OCS_HW_DOMAIN_ATTACH_FAIL, /**< domain attach failed */ 642331766Sken OCS_HW_DOMAIN_FREE_OK, /**< successfully freed domain */ 643331766Sken OCS_HW_DOMAIN_FREE_FAIL, /**< domain free failed */ 644331766Sken OCS_HW_DOMAIN_LOST, /**< previously discovered domain no longer available */ 645331766Sken OCS_HW_DOMAIN_FOUND, /**< new domain discovered */ 646331766Sken OCS_HW_DOMAIN_CHANGED, /**< previously discovered domain properties have changed */ 647331766Sken} ocs_hw_domain_event_e; 648331766Sken 649331766Skentypedef enum { 650331766Sken OCS_HW_PORT_ALLOC_OK, /**< port successfully allocated */ 651331766Sken OCS_HW_PORT_ALLOC_FAIL, /**< port allocation failed */ 652331766Sken OCS_HW_PORT_ATTACH_OK, /**< successfully attached to port */ 653331766Sken OCS_HW_PORT_ATTACH_FAIL, /**< port attach failed */ 654331766Sken OCS_HW_PORT_FREE_OK, /**< successfully freed port */ 655331766Sken OCS_HW_PORT_FREE_FAIL, /**< port free failed */ 656331766Sken} ocs_hw_port_event_e; 657331766Sken 658331766Skentypedef enum { 659331766Sken OCS_HW_NODE_ATTACH_OK, 660331766Sken OCS_HW_NODE_ATTACH_FAIL, 661331766Sken OCS_HW_NODE_FREE_OK, 662331766Sken OCS_HW_NODE_FREE_FAIL, 663331766Sken OCS_HW_NODE_FREE_ALL_OK, 664331766Sken OCS_HW_NODE_FREE_ALL_FAIL, 665331766Sken} ocs_hw_remote_node_event_e; 666331766Sken 667331766Skentypedef enum { 668331766Sken OCS_HW_CB_DOMAIN, 669331766Sken OCS_HW_CB_PORT, 670331766Sken OCS_HW_CB_REMOTE_NODE, 671331766Sken OCS_HW_CB_UNSOLICITED, 672331766Sken OCS_HW_CB_BOUNCE, 673331766Sken OCS_HW_CB_MAX, /**< must be last */ 674331766Sken} ocs_hw_callback_e; 675331766Sken 676331766Sken/** 677331766Sken * @brief HW unsolicited callback status 678331766Sken */ 679331766Skentypedef enum { 680331766Sken OCS_HW_UNSOL_SUCCESS, 681331766Sken OCS_HW_UNSOL_ERROR, 682331766Sken OCS_HW_UNSOL_ABTS_RCVD, 683331766Sken OCS_HW_UNSOL_MAX, /**< must be last */ 684331766Sken} ocs_hw_unsol_status_e; 685331766Sken 686331766Sken/** 687331766Sken * @brief Node group rpi reference 688331766Sken */ 689331766Skentypedef struct { 690331766Sken ocs_atomic_t rpi_count; 691331766Sken ocs_atomic_t rpi_attached; 692331766Sken} ocs_hw_rpi_ref_t; 693331766Sken 694331766Sken/** 695331766Sken * @brief HW link stat types 696331766Sken */ 697331766Skentypedef enum { 698331766Sken OCS_HW_LINK_STAT_LINK_FAILURE_COUNT, 699331766Sken OCS_HW_LINK_STAT_LOSS_OF_SYNC_COUNT, 700331766Sken OCS_HW_LINK_STAT_LOSS_OF_SIGNAL_COUNT, 701331766Sken OCS_HW_LINK_STAT_PRIMITIVE_SEQ_COUNT, 702331766Sken OCS_HW_LINK_STAT_INVALID_XMIT_WORD_COUNT, 703331766Sken OCS_HW_LINK_STAT_CRC_COUNT, 704331766Sken OCS_HW_LINK_STAT_PRIMITIVE_SEQ_TIMEOUT_COUNT, 705331766Sken OCS_HW_LINK_STAT_ELASTIC_BUFFER_OVERRUN_COUNT, 706331766Sken OCS_HW_LINK_STAT_ARB_TIMEOUT_COUNT, 707331766Sken OCS_HW_LINK_STAT_ADVERTISED_RCV_B2B_CREDIT, 708331766Sken OCS_HW_LINK_STAT_CURR_RCV_B2B_CREDIT, 709331766Sken OCS_HW_LINK_STAT_ADVERTISED_XMIT_B2B_CREDIT, 710331766Sken OCS_HW_LINK_STAT_CURR_XMIT_B2B_CREDIT, 711331766Sken OCS_HW_LINK_STAT_RCV_EOFA_COUNT, 712331766Sken OCS_HW_LINK_STAT_RCV_EOFDTI_COUNT, 713331766Sken OCS_HW_LINK_STAT_RCV_EOFNI_COUNT, 714331766Sken OCS_HW_LINK_STAT_RCV_SOFF_COUNT, 715331766Sken OCS_HW_LINK_STAT_RCV_DROPPED_NO_AER_COUNT, 716331766Sken OCS_HW_LINK_STAT_RCV_DROPPED_NO_RPI_COUNT, 717331766Sken OCS_HW_LINK_STAT_RCV_DROPPED_NO_XRI_COUNT, 718331766Sken OCS_HW_LINK_STAT_MAX, /**< must be last */ 719331766Sken} ocs_hw_link_stat_e; 720331766Sken 721331766Skentypedef enum { 722331766Sken OCS_HW_HOST_STAT_TX_KBYTE_COUNT, 723331766Sken OCS_HW_HOST_STAT_RX_KBYTE_COUNT, 724331766Sken OCS_HW_HOST_STAT_TX_FRAME_COUNT, 725331766Sken OCS_HW_HOST_STAT_RX_FRAME_COUNT, 726331766Sken OCS_HW_HOST_STAT_TX_SEQ_COUNT, 727331766Sken OCS_HW_HOST_STAT_RX_SEQ_COUNT, 728331766Sken OCS_HW_HOST_STAT_TOTAL_EXCH_ORIG, 729331766Sken OCS_HW_HOST_STAT_TOTAL_EXCH_RESP, 730331766Sken OCS_HW_HOSY_STAT_RX_P_BSY_COUNT, 731331766Sken OCS_HW_HOST_STAT_RX_F_BSY_COUNT, 732331766Sken OCS_HW_HOST_STAT_DROP_FRM_DUE_TO_NO_RQ_BUF_COUNT, 733331766Sken OCS_HW_HOST_STAT_EMPTY_RQ_TIMEOUT_COUNT, 734331766Sken OCS_HW_HOST_STAT_DROP_FRM_DUE_TO_NO_XRI_COUNT, 735331766Sken OCS_HW_HOST_STAT_EMPTY_XRI_POOL_COUNT, 736331766Sken OCS_HW_HOST_STAT_MAX /* MUST BE LAST */ 737331766Sken} ocs_hw_host_stat_e; 738331766Sken 739331766Skentypedef enum { 740331766Sken OCS_HW_STATE_UNINITIALIZED, /* power-on, no allocations, no initializations */ 741331766Sken OCS_HW_STATE_QUEUES_ALLOCATED, /* chip is reset, allocations are complete (queues not registered) */ 742331766Sken OCS_HW_STATE_ACTIVE, /* chip is up an running */ 743331766Sken OCS_HW_STATE_RESET_IN_PROGRESS, /* chip is being reset */ 744331766Sken OCS_HW_STATE_TEARDOWN_IN_PROGRESS, /* teardown has been started */ 745331766Sken} ocs_hw_state_e; 746331766Sken 747331766Sken/** 748331766Sken * @brief Defines a general FC sequence object, consisting of a header, payload buffers 749331766Sken * and a HW IO in the case of port owned XRI 750331766Sken */ 751331766Skentypedef struct { 752331766Sken ocs_hw_t *hw; /**< HW that owns this sequence */ 753331766Sken /* sequence information */ 754331766Sken uint8_t fcfi; /**< FCFI associated with sequence */ 755331766Sken uint8_t auto_xrdy; /**< If auto XFER_RDY was generated */ 756331766Sken uint8_t out_of_xris; /**< If IO would have been assisted if XRIs were available */ 757331766Sken ocs_hw_rq_buffer_t *header; 758331766Sken ocs_hw_rq_buffer_t *payload; /**< received frame payload buffer */ 759331766Sken 760331766Sken /* other "state" information from the SRB (sequence coalescing) */ 761331766Sken ocs_hw_unsol_status_e status; 762331766Sken uint32_t xri; /**< XRI associated with sequence; sequence coalescing only */ 763331766Sken ocs_hw_io_t *hio; /**< HW IO */ 764331766Sken 765331766Sken ocs_list_link_t link; 766331766Sken void *hw_priv; /**< HW private context */ 767331766Sken} ocs_hw_sequence_t; 768331766Sken 769331766Sken/** 770331766Sken * @brief Structure to track optimized write buffers posted to chip owned XRIs. 771331766Sken * 772331766Sken * Note: The rqindex will be set the following "fake" indexes. This will be used 773331766Sken * when the buffer is returned via ocs_seq_free() to make the buffer available 774331766Sken * for re-use on another XRI. 775331766Sken * 776331766Sken * The dma->alloc pointer on the dummy header will be used to get back to this structure when the buffer is freed. 777331766Sken * 778331766Sken * More of these object may be allocated on the fly if more XRIs are pushed to the chip. 779331766Sken */ 780331766Sken#define OCS_HW_RQ_INDEX_DUMMY_HDR 0xFF00 781331766Sken#define OCS_HW_RQ_INDEX_DUMMY_DATA 0xFF01 782331766Skentypedef struct ocs_hw_auto_xfer_rdy_buffer_s { 783331766Sken fc_header_t hdr; /**< used to build a dummy data header for unsolicited processing */ 784331766Sken ocs_hw_rq_buffer_t header; /**< Points to the dummy data header */ 785331766Sken ocs_hw_rq_buffer_t payload; /**< received frame payload buffer */ 786331766Sken ocs_hw_sequence_t seq; /**< sequence for passing the buffers */ 787331766Sken uint8_t data_cqe; 788331766Sken uint8_t cmd_cqe; 789331766Sken 790331766Sken /* fields saved from the command header that are needed when the data arrives */ 791331766Sken uint8_t fcfi; 792331766Sken 793331766Sken /* To handle outof order completions save AXR cmd and data cqes */ 794331766Sken uint8_t call_axr_cmd; 795331766Sken uint8_t call_axr_data; 796331766Sken ocs_hw_sequence_t *cmd_seq; 797331766Sken} ocs_hw_auto_xfer_rdy_buffer_t; 798331766Sken 799331766Sken/** 800331766Sken * @brief Node group rpi reference 801331766Sken */ 802331766Skentypedef struct { 803331766Sken uint8_t overflow; 804331766Sken uint32_t counter; 805331766Sken} ocs_hw_link_stat_counts_t; 806331766Sken 807331766Sken/** 808331766Sken * @brief HW object describing fc host stats 809331766Sken */ 810331766Skentypedef struct { 811331766Sken uint32_t counter; 812331766Sken} ocs_hw_host_stat_counts_t; 813331766Sken 814331766Sken#define TID_HASH_BITS 8 815331766Sken#define TID_HASH_LEN (1U << TID_HASH_BITS) 816331766Sken 817331766Skentypedef struct ocs_hw_iopt_s { 818331766Sken char name[32]; 819331766Sken uint32_t instance_index; 820331766Sken ocs_thread_t iopt_thread; 821331766Sken ocs_cbuf_t *iopt_free_queue; /* multiple reader, multiple writer */ 822331766Sken ocs_cbuf_t *iopt_work_queue; 823331766Sken ocs_array_t *iopt_cmd_array; 824331766Sken} ocs_hw_iopt_t; 825331766Sken 826331766Skentypedef enum { 827331766Sken HW_CQ_HANDLER_LOCAL, 828331766Sken HW_CQ_HANDLER_THREAD, 829331766Sken} hw_cq_handler_e; 830331766Sken 831331766Sken#include "ocs_hw_queues.h" 832331766Sken 833331766Sken/** 834331766Sken * @brief Stucture used for the hash lookup of queue IDs 835331766Sken */ 836331766Skentypedef struct { 837331766Sken uint32_t id:16, 838331766Sken in_use:1, 839331766Sken index:15; 840331766Sken} ocs_queue_hash_t; 841331766Sken 842331766Sken/** 843331766Sken * @brief Define the fields required to implement the skyhawk DIF quarantine. 844331766Sken */ 845331766Sken#define OCS_HW_QUARANTINE_QUEUE_DEPTH 4 846331766Sken 847331766Skentypedef struct { 848331766Sken uint32_t quarantine_index; 849331766Sken ocs_hw_io_t *quarantine_ios[OCS_HW_QUARANTINE_QUEUE_DEPTH]; 850331766Sken} ocs_quarantine_info_t; 851331766Sken 852331766Sken/** 853331766Sken * @brief Define the WQ callback object 854331766Sken */ 855331766Skentypedef struct { 856331766Sken uint16_t instance_index; /**< use for request tag */ 857331766Sken void (*callback)(void *arg, uint8_t *cqe, int32_t status); 858331766Sken void *arg; 859331766Sken} hw_wq_callback_t; 860331766Sken 861331766Skentypedef struct { 862331766Sken uint64_t fwrev; 863331766Sken 864331766Sken /* Control Declarations here ...*/ 865331766Sken 866331766Sken uint8_t retain_tsend_io_length; 867331766Sken 868331766Sken /* Use unregistered RPI */ 869331766Sken uint8_t use_unregistered_rpi; 870331766Sken uint32_t unregistered_rid; 871331766Sken uint32_t unregistered_index; 872331766Sken 873331766Sken uint8_t disable_ar_tgt_dif; /* Disable auto response if target DIF */ 874331766Sken uint8_t disable_dump_loc; 875331766Sken uint8_t use_dif_quarantine; 876331766Sken uint8_t use_dif_sec_xri; 877331766Sken 878331766Sken uint8_t override_fcfi; 879331766Sken 880331766Sken uint8_t fw_version_too_low; 881331766Sken 882331766Sken uint8_t sglc_misreported; 883331766Sken 884331766Sken uint8_t ignore_send_frame; 885331766Sken 886331766Sken} ocs_hw_workaround_t; 887331766Sken 888331766Sken 889331766Sken 890331766Sken/** 891331766Sken * @brief HW object 892331766Sken */ 893331766Skenstruct ocs_hw_s { 894331766Sken ocs_os_handle_t os; 895331766Sken sli4_t sli; 896331766Sken uint16_t ulp_start; 897331766Sken uint16_t ulp_max; 898331766Sken uint32_t dump_size; 899331766Sken ocs_hw_state_e state; 900331766Sken uint8_t hw_setup_called; 901331766Sken uint8_t sliport_healthcheck; 902331766Sken uint16_t watchdog_timeout; 903331766Sken ocs_lock_t watchdog_lock; 904331766Sken 905331766Sken /** HW configuration, subject to ocs_hw_set() */ 906331766Sken struct { 907331766Sken uint32_t n_eq; /**< number of event queues */ 908331766Sken uint32_t n_cq; /**< number of completion queues */ 909331766Sken uint32_t n_mq; /**< number of mailbox queues */ 910331766Sken uint32_t n_rq; /**< number of receive queues */ 911331766Sken uint32_t n_wq; /**< number of work queues */ 912331766Sken uint32_t n_io; /**< total number of IO objects */ 913331766Sken uint32_t n_sgl;/**< length of SGL */ 914331766Sken uint32_t speed; /** requested link speed in Mbps */ 915331766Sken uint32_t topology; /** requested link topology */ 916331766Sken uint32_t rq_default_buffer_size; /** size of the buffers for first burst */ 917331766Sken uint32_t auto_xfer_rdy_xri_cnt; /** Initial XRIs to post to chip at initialization */ 918331766Sken uint32_t auto_xfer_rdy_size; /** max size IO to use with this feature */ 919331766Sken uint8_t auto_xfer_rdy_blk_size_chip; /** block size to use with this feature */ 920331766Sken uint8_t esoc; 921331766Sken uint16_t dif_seed; /** The seed for the DIF CRC calculation */ 922331766Sken uint16_t auto_xfer_rdy_app_tag_value; 923331766Sken uint8_t dif_mode; /**< DIF mode to use */ 924331766Sken uint8_t i_only_aab; /** Enable initiator-only auto-abort */ 925331766Sken uint8_t emulate_tgt_wqe_timeout; /** Enable driver target wqe timeouts */ 926331766Sken uint32_t bounce:1; 927331766Sken const char *queue_topology; /**< Queue topology string */ 928331766Sken uint8_t auto_xfer_rdy_t10_enable; /** Enable t10 PI for auto xfer ready */ 929331766Sken uint8_t auto_xfer_rdy_p_type; /** p_type for auto xfer ready */ 930331766Sken uint8_t auto_xfer_rdy_ref_tag_is_lba; 931331766Sken uint8_t auto_xfer_rdy_app_tag_valid; 932331766Sken uint8_t rq_selection_policy; /** MRQ RQ selection policy */ 933331766Sken uint8_t rr_quanta; /** RQ quanta if rq_selection_policy == 2 */ 934331766Sken uint32_t filter_def[SLI4_CMD_REG_FCFI_NUM_RQ_CFG]; 935331766Sken } config; 936331766Sken 937331766Sken /* calculated queue sizes for each type */ 938331766Sken uint32_t num_qentries[SLI_QTYPE_MAX]; 939331766Sken 940331766Sken /* Storage for SLI queue objects */ 941331766Sken sli4_queue_t wq[OCS_HW_MAX_NUM_WQ]; 942331766Sken sli4_queue_t rq[OCS_HW_MAX_NUM_RQ]; 943331766Sken uint16_t hw_rq_lookup[OCS_HW_MAX_NUM_RQ]; 944331766Sken sli4_queue_t mq[OCS_HW_MAX_NUM_MQ]; 945331766Sken sli4_queue_t cq[OCS_HW_MAX_NUM_CQ]; 946331766Sken sli4_queue_t eq[OCS_HW_MAX_NUM_EQ]; 947331766Sken 948331766Sken /* HW queue */ 949331766Sken uint32_t eq_count; 950331766Sken uint32_t cq_count; 951331766Sken uint32_t mq_count; 952331766Sken uint32_t wq_count; 953331766Sken uint32_t rq_count; /**< count of SLI RQs */ 954331766Sken ocs_list_t eq_list; 955331766Sken 956331766Sken ocs_queue_hash_t cq_hash[OCS_HW_Q_HASH_SIZE]; 957331766Sken ocs_queue_hash_t rq_hash[OCS_HW_Q_HASH_SIZE]; 958331766Sken ocs_queue_hash_t wq_hash[OCS_HW_Q_HASH_SIZE]; 959331766Sken 960331766Sken /* Storage for HW queue objects */ 961331766Sken hw_wq_t *hw_wq[OCS_HW_MAX_NUM_WQ]; 962331766Sken hw_rq_t *hw_rq[OCS_HW_MAX_NUM_RQ]; 963331766Sken hw_mq_t *hw_mq[OCS_HW_MAX_NUM_MQ]; 964331766Sken hw_cq_t *hw_cq[OCS_HW_MAX_NUM_CQ]; 965331766Sken hw_eq_t *hw_eq[OCS_HW_MAX_NUM_EQ]; 966331766Sken uint32_t hw_rq_count; /**< count of hw_rq[] entries */ 967331766Sken uint32_t hw_mrq_count; /**< count of multirq RQs */ 968331766Sken 969331766Sken ocs_varray_t *wq_class_array[OCS_HW_MAX_WQ_CLASS]; /**< pool per class WQs */ 970331766Sken ocs_varray_t *wq_cpu_array[OCS_HW_MAX_WQ_CPU]; /**< pool per CPU WQs */ 971331766Sken 972331766Sken /* Sequence objects used in incoming frame processing */ 973331766Sken ocs_array_t *seq_pool; 974331766Sken 975331766Sken /* Auto XFER RDY Buffers - protect with io_lock */ 976331766Sken uint32_t auto_xfer_rdy_enabled:1, /**< TRUE if auto xfer rdy is enabled */ 977331766Sken :31; 978331766Sken ocs_pool_t *auto_xfer_rdy_buf_pool; /**< pool of ocs_hw_auto_xfer_rdy_buffer_t objects */ 979331766Sken 980331766Sken /** Maintain an ordered, linked list of outstanding HW commands. */ 981331766Sken ocs_lock_t cmd_lock; 982331766Sken ocs_list_t cmd_head; 983331766Sken ocs_list_t cmd_pending; 984331766Sken uint32_t cmd_head_count; 985331766Sken 986331766Sken 987331766Sken sli4_link_event_t link; 988331766Sken ocs_hw_linkcfg_e linkcfg; /**< link configuration setting */ 989331766Sken uint32_t eth_license; /**< Ethernet license; to enable FCoE on Lancer */ 990331766Sken 991331766Sken struct { 992331766Sken /** 993331766Sken * Function + argument used to notify upper layer of domain events. 994331766Sken * 995331766Sken * The final argument to the callback is a generic data pointer: 996331766Sken * - ocs_domain_record_t on OCS_HW_DOMAIN_FOUND 997331766Sken * - ocs_domain_t on OCS_HW_DOMAIN_ALLOC_FAIL, OCS_HW_DOMAIN_ALLOC_OK, 998331766Sken * OCS_HW_DOMAIN_FREE_FAIL, OCS_HW_DOMAIN_FREE_OK, 999331766Sken * OCS_HW_DOMAIN_ATTACH_FAIL, OCS_HW_DOMAIN_ATTACH_OK, and 1000331766Sken * OCS_HW_DOMAIN_LOST. 1001331766Sken */ 1002331766Sken int32_t (*domain)(void *, ocs_hw_domain_event_e, void *); 1003331766Sken /** 1004331766Sken * Function + argument used to notify upper layers of port events. 1005331766Sken * 1006331766Sken * The final argument to the callback is a pointer to the effected 1007331766Sken * SLI port for all events. 1008331766Sken */ 1009331766Sken int32_t (*port)(void *, ocs_hw_port_event_e, void *); 1010331766Sken /** Function + argument used to announce arrival of unsolicited frames */ 1011331766Sken int32_t (*unsolicited)(void *, ocs_hw_sequence_t *); 1012331766Sken int32_t (*rnode)(void *, ocs_hw_remote_node_event_e, void *); 1013331766Sken int32_t (*bounce)(void (*)(void *arg), void *arg, uint32_t s_id, uint32_t d_id, uint32_t ox_id); 1014331766Sken } callback; 1015331766Sken struct { 1016331766Sken void *domain; 1017331766Sken void *port; 1018331766Sken void *unsolicited; 1019331766Sken void *rnode; 1020331766Sken void *bounce; 1021331766Sken } args; 1022331766Sken 1023331766Sken /* OCS domain objects index by FCFI */ 1024331766Sken int32_t first_domain_idx; /* Workaround for srb->fcfi == 0 */ 1025331766Sken ocs_domain_t *domains[SLI4_MAX_FCFI]; 1026331766Sken 1027331766Sken /* Table of FCFI values index by FCF_index */ 1028331766Sken uint16_t fcf_index_fcfi[SLI4_MAX_FCF_INDEX]; 1029331766Sken 1030331766Sken uint16_t fcf_indicator; 1031331766Sken 1032331766Sken ocs_hw_io_t **io; /**< pointer array of IO objects */ 1033331766Sken uint8_t *wqe_buffs; /**< array of WQE buffs mapped to IO objects */ 1034331766Sken 1035331766Sken ocs_lock_t io_lock; /**< IO lock to synchronize list access */ 1036331766Sken ocs_lock_t io_abort_lock; /**< IO lock to synchronize IO aborting */ 1037331766Sken ocs_list_t io_inuse; /**< List of IO objects in use */ 1038331766Sken ocs_list_t io_timed_wqe; /**< List of IO objects with a timed target WQE */ 1039331766Sken ocs_list_t io_wait_free; /**< List of IO objects waiting to be freed */ 1040331766Sken ocs_list_t io_free; /**< List of IO objects available for allocation */ 1041331766Sken ocs_list_t io_port_owned; /**< List of IO objects posted for chip use */ 1042331766Sken ocs_list_t io_port_dnrx; /**< List of IO objects needing auto xfer rdy buffers */ 1043331766Sken 1044331766Sken ocs_dma_t loop_map; 1045331766Sken 1046331766Sken ocs_dma_t xfer_rdy; 1047331766Sken 1048331766Sken ocs_dma_t dump_sges; 1049331766Sken 1050331766Sken ocs_dma_t rnode_mem; 1051331766Sken 1052331766Sken ocs_dma_t domain_dmem; /*domain dma mem for service params */ 1053331766Sken ocs_dma_t fcf_dmem; /*dma men for fcf */ 1054331766Sken 1055331766Sken ocs_hw_rpi_ref_t *rpi_ref; 1056331766Sken 1057331766Sken char *hw_war_version; 1058331766Sken ocs_hw_workaround_t workaround; 1059331766Sken 1060331766Sken ocs_atomic_t io_alloc_failed_count; 1061331766Sken 1062331766Sken#if defined(OCS_DEBUG_QUEUE_HISTORY) 1063331766Sken ocs_hw_q_hist_t q_hist; 1064331766Sken#endif 1065331766Sken 1066331766Sken ocs_list_t sec_hio_wait_list; /**< BZ 161832 Workaround: Secondary HW IO context wait list */ 1067331766Sken uint32_t sec_hio_wait_count; /**< BZ 161832 Workaround: Count of IOs that were put on the 1068331766Sken * Secondary HW IO wait list 1069331766Sken */ 1070331766Sken 1071331766Sken#define HW_MAX_TCMD_THREADS 16 1072331766Sken ocs_hw_qtop_t *qtop; /**< pointer to queue topology */ 1073331766Sken 1074331766Sken uint32_t tcmd_wq_submit[OCS_HW_MAX_NUM_WQ]; /**< stat: wq sumbit count */ 1075331766Sken uint32_t tcmd_wq_complete[OCS_HW_MAX_NUM_WQ]; /**< stat: wq complete count */ 1076331766Sken 1077331766Sken ocs_timer_t wqe_timer; /**< Timer to periodically check for WQE timeouts */ 1078331766Sken ocs_timer_t watchdog_timer; /**< Timer for heartbeat */ 1079331766Sken bool expiration_logged; 1080331766Sken uint32_t in_active_wqe_timer:1, /**< TRUE if currently in active wqe timer handler */ 1081331766Sken active_wqe_timer_shutdown:1, /** TRUE if wqe timer is to be shutdown */ 1082331766Sken :30; 1083331766Sken 1084331766Sken ocs_list_t iopc_list; /**< list of IO processing contexts */ 1085331766Sken ocs_lock_t iopc_list_lock; /**< lock for iopc_list */ 1086331766Sken 1087331766Sken ocs_pool_t *wq_reqtag_pool; /**< pool of hw_wq_callback_t objects */ 1088331766Sken 1089331766Sken ocs_atomic_t send_frame_seq_id; /**< send frame sequence ID */ 1090331766Sken}; 1091331766Sken 1092331766Sken 1093331766Skentypedef enum { 1094331766Sken OCS_HW_IO_INUSE_COUNT, 1095331766Sken OCS_HW_IO_FREE_COUNT, 1096331766Sken OCS_HW_IO_WAIT_FREE_COUNT, 1097331766Sken OCS_HW_IO_PORT_OWNED_COUNT, 1098331766Sken OCS_HW_IO_N_TOTAL_IO_COUNT, 1099331766Sken} ocs_hw_io_count_type_e; 1100331766Sken 1101331766Skentypedef void (*tcmd_cq_handler)(ocs_hw_t *hw, uint32_t cq_idx, void *cq_handler_arg); 1102331766Sken 1103331766Sken/* 1104331766Sken * HW queue data structures 1105331766Sken */ 1106331766Sken 1107331766Skenstruct hw_eq_s { 1108331766Sken ocs_list_link_t link; /**< must be first */ 1109331766Sken sli4_qtype_e type; /**< must be second */ 1110331766Sken uint32_t instance; 1111331766Sken uint32_t entry_count; 1112331766Sken uint32_t entry_size; 1113331766Sken ocs_hw_t *hw; 1114331766Sken sli4_queue_t *queue; 1115331766Sken ocs_list_t cq_list; 1116331766Sken#if OCS_STAT_ENABLE 1117331766Sken uint32_t use_count; 1118331766Sken#endif 1119331766Sken ocs_varray_t *wq_array; /*<< array of WQs */ 1120331766Sken}; 1121331766Sken 1122331766Skenstruct hw_cq_s { 1123331766Sken ocs_list_link_t link; /*<< must be first */ 1124331766Sken sli4_qtype_e type; /**< must be second */ 1125331766Sken uint32_t instance; /*<< CQ instance (cq_idx) */ 1126331766Sken uint32_t entry_count; /*<< Number of entries */ 1127331766Sken uint32_t entry_size; /*<< entry size */ 1128331766Sken hw_eq_t *eq; /*<< parent EQ */ 1129331766Sken sli4_queue_t *queue; /**< pointer to SLI4 queue */ 1130331766Sken ocs_list_t q_list; /**< list of children queues */ 1131331766Sken 1132331766Sken#if OCS_STAT_ENABLE 1133331766Sken uint32_t use_count; 1134331766Sken#endif 1135331766Sken}; 1136331766Sken 1137331766Skentypedef struct { 1138331766Sken ocs_list_link_t link; /*<< must be first */ 1139331766Sken sli4_qtype_e type; /*<< must be second */ 1140331766Sken} hw_q_t; 1141331766Sken 1142331766Skenstruct hw_mq_s { 1143331766Sken ocs_list_link_t link; /*<< must be first */ 1144331766Sken sli4_qtype_e type; /*<< must be second */ 1145331766Sken uint32_t instance; 1146331766Sken 1147331766Sken uint32_t entry_count; 1148331766Sken uint32_t entry_size; 1149331766Sken hw_cq_t *cq; 1150331766Sken sli4_queue_t *queue; 1151331766Sken 1152331766Sken#if OCS_STAT_ENABLE 1153331766Sken uint32_t use_count; 1154331766Sken#endif 1155331766Sken}; 1156331766Sken 1157331766Skenstruct hw_wq_s { 1158331766Sken ocs_list_link_t link; /*<< must be first */ 1159331766Sken sli4_qtype_e type; /*<< must be second */ 1160331766Sken uint32_t instance; 1161331766Sken ocs_hw_t *hw; 1162331766Sken 1163331766Sken uint32_t entry_count; 1164331766Sken uint32_t entry_size; 1165331766Sken hw_cq_t *cq; 1166331766Sken sli4_queue_t *queue; 1167331766Sken uint32_t class; 1168331766Sken uint8_t ulp; 1169331766Sken 1170331766Sken /* WQ consumed */ 1171331766Sken uint32_t wqec_set_count; /*<< how often IOs are submitted with wqce set */ 1172331766Sken uint32_t wqec_count; /*<< current wqce counter */ 1173331766Sken uint32_t free_count; /*<< free count */ 1174331766Sken uint32_t total_submit_count; /*<< total submit count */ 1175331766Sken ocs_list_t pending_list; /*<< list of IOs pending for this WQ */ 1176331766Sken 1177331766Sken /* 1178331766Sken * ---Skyhawk only --- 1179331766Sken * BZ 160124 - Driver must quarantine XRIs for target writes and 1180331766Sken * initiator read when using DIF separates. Throw them on a 1181331766Sken * queue until another 4 similar requests are completed to ensure they 1182331766Sken * are flushed from the internal chip cache before being re-used. 1183331766Sken * The must be a separate queue per CQ because the actual chip completion 1184331766Sken * order cannot be determined. Since each WQ has a separate CQ, use the wq 1185331766Sken * associated with the IO. 1186331766Sken * 1187331766Sken * Note: Protected by queue->lock 1188331766Sken */ 1189331766Sken ocs_quarantine_info_t quarantine_info; 1190331766Sken 1191331766Sken /* 1192331766Sken * HW IO allocated for use with Send Frame 1193331766Sken */ 1194331766Sken ocs_hw_io_t *send_frame_io; 1195331766Sken 1196331766Sken /* Stats */ 1197331766Sken#if OCS_STAT_ENABLE 1198331766Sken uint32_t use_count; /*<< use count */ 1199331766Sken uint32_t wq_pending_count; /*<< count of HW IOs that were queued on the WQ pending list */ 1200331766Sken#endif 1201331766Sken}; 1202331766Sken 1203331766Skenstruct hw_rq_s { 1204331766Sken ocs_list_link_t link; /*<< must be first */ 1205331766Sken sli4_qtype_e type; /*<< must be second */ 1206331766Sken uint32_t instance; 1207331766Sken 1208331766Sken uint32_t entry_count; 1209331766Sken uint32_t hdr_entry_size; 1210331766Sken uint32_t first_burst_entry_size; 1211331766Sken uint32_t data_entry_size; 1212331766Sken uint8_t ulp; 1213331766Sken bool is_mrq; 1214331766Sken uint32_t base_mrq_id; 1215331766Sken 1216331766Sken hw_cq_t *cq; 1217331766Sken 1218331766Sken uint8_t filter_mask; /* Filter mask value */ 1219331766Sken sli4_queue_t *hdr; 1220331766Sken sli4_queue_t *first_burst; 1221331766Sken sli4_queue_t *data; 1222331766Sken 1223331766Sken ocs_hw_rq_buffer_t *hdr_buf; 1224331766Sken ocs_hw_rq_buffer_t *fb_buf; 1225331766Sken ocs_hw_rq_buffer_t *payload_buf; 1226331766Sken 1227331766Sken ocs_hw_sequence_t **rq_tracker; /* RQ tracker for this RQ */ 1228331766Sken#if OCS_STAT_ENABLE 1229331766Sken uint32_t use_count; 1230331766Sken uint32_t hdr_use_count; 1231331766Sken uint32_t fb_use_count; 1232331766Sken uint32_t payload_use_count; 1233331766Sken#endif 1234331766Sken}; 1235331766Sken 1236331766Skentypedef struct ocs_hw_global_s { 1237331766Sken const char *queue_topology_string; /**< queue topology string */ 1238331766Sken} ocs_hw_global_t; 1239331766Skenextern ocs_hw_global_t hw_global; 1240331766Sken 1241331766Skenextern hw_eq_t *hw_new_eq(ocs_hw_t *hw, uint32_t entry_count); 1242331766Skenextern hw_cq_t *hw_new_cq(hw_eq_t *eq, uint32_t entry_count); 1243331766Skenextern uint32_t hw_new_cq_set(hw_eq_t *eqs[], hw_cq_t *cqs[], uint32_t num_cqs, uint32_t entry_count); 1244331766Skenextern hw_mq_t *hw_new_mq(hw_cq_t *cq, uint32_t entry_count); 1245331766Skenextern hw_wq_t *hw_new_wq(hw_cq_t *cq, uint32_t entry_count, uint32_t class, uint32_t ulp); 1246331766Skenextern hw_rq_t *hw_new_rq(hw_cq_t *cq, uint32_t entry_count, uint32_t ulp); 1247331766Skenextern 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); 1248331766Skenextern void hw_del_eq(hw_eq_t *eq); 1249331766Skenextern void hw_del_cq(hw_cq_t *cq); 1250331766Skenextern void hw_del_mq(hw_mq_t *mq); 1251331766Skenextern void hw_del_wq(hw_wq_t *wq); 1252331766Skenextern void hw_del_rq(hw_rq_t *rq); 1253331766Skenextern void hw_queue_dump(ocs_hw_t *hw); 1254331766Skenextern void hw_queue_teardown(ocs_hw_t *hw); 1255331766Skenextern int32_t hw_route_rqe(ocs_hw_t *hw, ocs_hw_sequence_t *seq); 1256331766Skenextern int32_t ocs_hw_queue_hash_find(ocs_queue_hash_t *, uint16_t); 1257331766Skenextern ocs_hw_rtn_e ocs_hw_setup(ocs_hw_t *, ocs_os_handle_t, sli4_port_type_e); 1258331766Skenextern ocs_hw_rtn_e ocs_hw_init(ocs_hw_t *); 1259331766Skenextern ocs_hw_rtn_e ocs_hw_teardown(ocs_hw_t *); 1260331766Skenextern ocs_hw_rtn_e ocs_hw_reset(ocs_hw_t *, ocs_hw_reset_e); 1261331766Skenextern int32_t ocs_hw_get_num_eq(ocs_hw_t *); 1262331766Skenextern ocs_hw_rtn_e ocs_hw_get(ocs_hw_t *, ocs_hw_property_e, uint32_t *); 1263331766Skenextern void *ocs_hw_get_ptr(ocs_hw_t *, ocs_hw_property_e); 1264331766Skenextern ocs_hw_rtn_e ocs_hw_set(ocs_hw_t *, ocs_hw_property_e, uint32_t); 1265331766Skenextern ocs_hw_rtn_e ocs_hw_set_ptr(ocs_hw_t *, ocs_hw_property_e, void*); 1266331766Skenextern int32_t ocs_hw_event_check(ocs_hw_t *, uint32_t); 1267331766Skenextern int32_t ocs_hw_process(ocs_hw_t *, uint32_t, uint32_t); 1268331766Skenextern ocs_hw_rtn_e ocs_hw_command(ocs_hw_t *, uint8_t *, uint32_t, void *, void *); 1269331766Skenextern ocs_hw_rtn_e ocs_hw_callback(ocs_hw_t *, ocs_hw_callback_e, void *, void *); 1270331766Skenextern ocs_hw_rtn_e ocs_hw_port_alloc(ocs_hw_t *, ocs_sli_port_t *, ocs_domain_t *, uint8_t *); 1271331766Skenextern ocs_hw_rtn_e ocs_hw_port_attach(ocs_hw_t *, ocs_sli_port_t *, uint32_t); 1272331766Skentypedef void (*ocs_hw_port_control_cb_t)(int32_t status, uintptr_t value, void *arg); 1273331766Skenextern ocs_hw_rtn_e ocs_hw_port_control(ocs_hw_t *, ocs_hw_port_e, uintptr_t, ocs_hw_port_control_cb_t, void *); 1274331766Skenextern ocs_hw_rtn_e ocs_hw_port_free(ocs_hw_t *, ocs_sli_port_t *); 1275331766Skenextern ocs_hw_rtn_e ocs_hw_domain_alloc(ocs_hw_t *, ocs_domain_t *, uint32_t, uint32_t); 1276331766Skenextern ocs_hw_rtn_e ocs_hw_domain_attach(ocs_hw_t *, ocs_domain_t *, uint32_t); 1277331766Skenextern ocs_hw_rtn_e ocs_hw_domain_free(ocs_hw_t *, ocs_domain_t *); 1278331766Skenextern ocs_hw_rtn_e ocs_hw_domain_force_free(ocs_hw_t *, ocs_domain_t *); 1279331766Skenextern ocs_domain_t * ocs_hw_domain_get(ocs_hw_t *, uint16_t); 1280331766Skenextern ocs_hw_rtn_e ocs_hw_node_alloc(ocs_hw_t *, ocs_remote_node_t *, uint32_t, ocs_sli_port_t *); 1281331766Skenextern ocs_hw_rtn_e ocs_hw_node_free_all(ocs_hw_t *); 1282331766Skenextern ocs_hw_rtn_e ocs_hw_node_attach(ocs_hw_t *, ocs_remote_node_t *, ocs_dma_t *); 1283331766Skenextern ocs_hw_rtn_e ocs_hw_node_detach(ocs_hw_t *, ocs_remote_node_t *); 1284331766Skenextern ocs_hw_rtn_e ocs_hw_node_free_resources(ocs_hw_t *, ocs_remote_node_t *); 1285331766Skenextern ocs_hw_rtn_e ocs_hw_node_group_alloc(ocs_hw_t *, ocs_remote_node_group_t *); 1286331766Skenextern ocs_hw_rtn_e ocs_hw_node_group_attach(ocs_hw_t *, ocs_remote_node_group_t *, ocs_remote_node_t *); 1287331766Skenextern ocs_hw_rtn_e ocs_hw_node_group_free(ocs_hw_t *, ocs_remote_node_group_t *); 1288331766Skenextern ocs_hw_io_t *ocs_hw_io_alloc(ocs_hw_t *); 1289331766Skenextern ocs_hw_io_t *ocs_hw_io_activate_port_owned(ocs_hw_t *, ocs_hw_io_t *); 1290331766Skenextern int32_t ocs_hw_io_free(ocs_hw_t *, ocs_hw_io_t *); 1291331766Skenextern uint8_t ocs_hw_io_inuse(ocs_hw_t *hw, ocs_hw_io_t *io); 1292331766Skentypedef 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); 1293331766Skenextern 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 *); 1294331766Skenextern 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 *); 1295331766Skenextern ocs_hw_rtn_e _ocs_hw_io_send(ocs_hw_t *hw, ocs_hw_io_type_e type, ocs_hw_io_t *io, 1296331766Sken uint32_t len, ocs_hw_io_param_t *iparam, ocs_remote_node_t *rnode, 1297331766Sken void *cb, void *arg); 1298331766Skenextern ocs_hw_rtn_e ocs_hw_io_register_sgl(ocs_hw_t *, ocs_hw_io_t *, ocs_dma_t *, uint32_t); 1299331766Skenextern ocs_hw_rtn_e ocs_hw_io_init_sges(ocs_hw_t *hw, ocs_hw_io_t *io, ocs_hw_io_type_e type); 1300331766Skenextern 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); 1301331766Skenextern ocs_hw_rtn_e ocs_hw_io_add_sge(ocs_hw_t *, ocs_hw_io_t *, uintptr_t, uint32_t); 1302331766Skenextern ocs_hw_rtn_e ocs_hw_io_add_dif_sge(ocs_hw_t *hw, ocs_hw_io_t *io, uintptr_t addr); 1303331766Skenextern ocs_hw_rtn_e ocs_hw_io_abort(ocs_hw_t *, ocs_hw_io_t *, uint32_t, void *, void *); 1304331766Skenextern int32_t ocs_hw_io_get_xid(ocs_hw_t *, ocs_hw_io_t *); 1305331766Skenextern uint32_t ocs_hw_io_get_count(ocs_hw_t *, ocs_hw_io_count_type_e); 1306331766Skenextern uint32_t ocs_hw_get_rqes_produced_count(ocs_hw_t *hw); 1307331766Sken 1308331766Skentypedef void (*ocs_hw_fw_cb_t)(int32_t status, uint32_t bytes_written, uint32_t change_status, void *arg); 1309331766Skenextern 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*); 1310331766Sken 1311331766Sken/* Function for retrieving SFP data */ 1312331766Skentypedef void (*ocs_hw_sfp_cb_t)(void *, int32_t, uint32_t, uint32_t *, void *); 1313331766Skenextern ocs_hw_rtn_e ocs_hw_get_sfp(ocs_hw_t *, uint16_t, ocs_hw_sfp_cb_t, void *); 1314331766Sken 1315331766Sken/* Function for retrieving temperature data */ 1316331766Skentypedef void (*ocs_hw_temp_cb_t)(int32_t status, 1317331766Sken uint32_t curr_temp, 1318331766Sken uint32_t crit_temp_thrshld, 1319331766Sken uint32_t warn_temp_thrshld, 1320331766Sken uint32_t norm_temp_thrshld, 1321331766Sken uint32_t fan_off_thrshld, 1322331766Sken uint32_t fan_on_thrshld, 1323331766Sken void *arg); 1324331766Skenextern ocs_hw_rtn_e ocs_hw_get_temperature(ocs_hw_t *, ocs_hw_temp_cb_t, void*); 1325331766Sken 1326331766Sken/* Function for retrieving link statistics */ 1327331766Skentypedef void (*ocs_hw_link_stat_cb_t)(int32_t status, 1328331766Sken uint32_t num_counters, 1329331766Sken ocs_hw_link_stat_counts_t *counters, 1330331766Sken void *arg); 1331331766Skenextern ocs_hw_rtn_e ocs_hw_get_link_stats(ocs_hw_t *, 1332331766Sken uint8_t req_ext_counters, 1333331766Sken uint8_t clear_overflow_flags, 1334331766Sken uint8_t clear_all_counters, 1335331766Sken ocs_hw_link_stat_cb_t, void*); 1336331766Sken/* Function for retrieving host statistics */ 1337331766Skentypedef void (*ocs_hw_host_stat_cb_t)(int32_t status, 1338331766Sken uint32_t num_counters, 1339331766Sken ocs_hw_host_stat_counts_t *counters, 1340331766Sken void *arg); 1341331766Skenextern ocs_hw_rtn_e ocs_hw_get_host_stats(ocs_hw_t *hw, uint8_t cc, ocs_hw_host_stat_cb_t, void *arg); 1342331766Sken 1343331766Skenextern ocs_hw_rtn_e ocs_hw_raise_ue(ocs_hw_t *, uint8_t); 1344331766Skentypedef void (*ocs_hw_dump_get_cb_t)(int32_t status, uint32_t bytes_read, uint8_t eof, void *arg); 1345331766Skenextern 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 *); 1346331766Skenextern ocs_hw_rtn_e ocs_hw_set_dump_location(ocs_hw_t *, uint32_t, ocs_dma_t *, uint8_t); 1347331766Sken 1348331766Skentypedef void (*ocs_get_port_protocol_cb_t)(int32_t status, ocs_hw_port_protocol_e port_protocol, void *arg); 1349331766Skenextern 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); 1350331766Skentypedef void (*ocs_set_port_protocol_cb_t)(int32_t status, void *arg); 1351331766Skenextern ocs_hw_rtn_e ocs_hw_set_port_protocol(ocs_hw_t *hw, ocs_hw_port_protocol_e profile, 1352331766Sken uint32_t pci_func, ocs_set_port_protocol_cb_t mgmt_cb, 1353331766Sken void* ul_arg); 1354331766Sken 1355331766Skentypedef void (*ocs_get_profile_list_cb_t)(int32_t status, ocs_hw_profile_list_t*, void *arg); 1356331766Skenextern ocs_hw_rtn_e ocs_hw_get_profile_list(ocs_hw_t *hw, ocs_get_profile_list_cb_t mgmt_cb, void *arg); 1357331766Skentypedef void (*ocs_get_active_profile_cb_t)(int32_t status, uint32_t active_profile, void *arg); 1358331766Skenextern ocs_hw_rtn_e ocs_hw_get_active_profile(ocs_hw_t *hw, ocs_get_active_profile_cb_t mgmt_cb, void *arg); 1359331766Skentypedef void (*ocs_set_active_profile_cb_t)(int32_t status, void *arg); 1360331766Skenextern ocs_hw_rtn_e ocs_hw_set_active_profile(ocs_hw_t *hw, ocs_set_active_profile_cb_t mgmt_cb, 1361331766Sken uint32_t profile_id, void *arg); 1362331766Skentypedef void (*ocs_get_nvparms_cb_t)(int32_t status, uint8_t *wwpn, uint8_t *wwnn, uint8_t hard_alpa, 1363331766Sken uint32_t preferred_d_id, void *arg); 1364331766Skenextern ocs_hw_rtn_e ocs_hw_get_nvparms(ocs_hw_t *hw, ocs_get_nvparms_cb_t mgmt_cb, void *arg); 1365331766Skentypedef void (*ocs_set_nvparms_cb_t)(int32_t status, void *arg); 1366331766Skenextern ocs_hw_rtn_e ocs_hw_set_nvparms(ocs_hw_t *hw, ocs_set_nvparms_cb_t mgmt_cb, uint8_t *wwpn, 1367331766Sken uint8_t *wwnn, uint8_t hard_alpa, uint32_t preferred_d_id, void *arg); 1368331766Skenextern int32_t ocs_hw_eq_process(ocs_hw_t *hw, hw_eq_t *eq, uint32_t max_isr_time_msec); 1369331766Skenextern void ocs_hw_cq_process(ocs_hw_t *hw, hw_cq_t *cq); 1370331766Skenextern void ocs_hw_wq_process(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe, int32_t status, uint16_t rid); 1371331766Skenextern void ocs_hw_xabt_process(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe, uint16_t rid); 1372331766Skenextern int32_t hw_wq_write(hw_wq_t *wq, ocs_hw_wqe_t *wqe); 1373331766Sken 1374331766Skentypedef void (*ocs_hw_dump_clear_cb_t)(int32_t status, void *arg); 1375331766Skenextern ocs_hw_rtn_e ocs_hw_dump_clear(ocs_hw_t *, ocs_hw_dump_clear_cb_t, void *); 1376331766Sken 1377331766Skenextern uint8_t ocs_hw_is_io_port_owned(ocs_hw_t *hw, ocs_hw_io_t *io); 1378331766Sken 1379331766Sken 1380331766Skenextern uint8_t ocs_hw_is_xri_port_owned(ocs_hw_t *hw, uint32_t xri); 1381331766Skenextern ocs_hw_io_t * ocs_hw_io_lookup(ocs_hw_t *hw, uint32_t indicator); 1382331766Skenextern uint32_t ocs_hw_xri_move_to_port_owned(ocs_hw_t *hw, uint32_t num_xri); 1383331766Skenextern ocs_hw_rtn_e ocs_hw_xri_move_to_host_owned(ocs_hw_t *hw, uint8_t num_xri); 1384331766Skenextern int32_t ocs_hw_reque_xri(ocs_hw_t *hw, ocs_hw_io_t *io); 1385331766Sken 1386331766Sken 1387331766Skentypedef struct { 1388331766Sken /* structure elements used by HW */ 1389331766Sken ocs_hw_t *hw; /**> pointer to HW */ 1390331766Sken hw_wq_callback_t *wqcb; /**> WQ callback object, request tag */ 1391331766Sken ocs_hw_wqe_t wqe; /**> WQE buffer object (may be queued on WQ pending list) */ 1392331766Sken void (*callback)(int32_t status, void *arg); /**> final callback function */ 1393331766Sken void *arg; /**> final callback argument */ 1394331766Sken 1395331766Sken /* General purpose elements */ 1396331766Sken ocs_hw_sequence_t *seq; 1397331766Sken ocs_dma_t payload; /**> a payload DMA buffer */ 1398331766Sken} ocs_hw_send_frame_context_t; 1399331766Sken 1400331766Sken 1401331766Sken#define OCS_HW_OBJECT_G5 0xfeaa0001 1402331766Sken#define OCS_HW_OBJECT_G6 0xfeaa0003 1403331766Sken#define OCS_FILE_TYPE_GROUP 0xf7 1404331766Sken#define OCS_FILE_ID_GROUP 0xa2 1405331766Skenstruct ocs_hw_grp_hdr { 1406331766Sken uint32_t size; 1407331766Sken uint32_t magic_number; 1408331766Sken uint32_t word2; 1409331766Sken uint8_t rev_name[128]; 1410331766Sken uint8_t date[12]; 1411331766Sken uint8_t revision[32]; 1412331766Sken}; 1413331766Sken 1414331766Sken 1415331766Skenocs_hw_rtn_e 1416331766Skenocs_hw_send_frame(ocs_hw_t *hw, fc_header_le_t *hdr, uint8_t sof, uint8_t eof, ocs_dma_t *payload, 1417331766Sken ocs_hw_send_frame_context_t *ctx, 1418331766Sken void (*callback)(void *arg, uint8_t *cqe, int32_t status), void *arg); 1419331766Sken 1420331766Sken/* RQ completion handlers for RQ pair mode */ 1421331766Skenextern int32_t ocs_hw_rqpair_process_rq(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe); 1422331766Skenextern ocs_hw_rtn_e ocs_hw_rqpair_sequence_free(ocs_hw_t *hw, ocs_hw_sequence_t *seq); 1423331766Skenextern int32_t ocs_hw_rqpair_process_auto_xfr_rdy_cmd(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe); 1424331766Skenextern int32_t ocs_hw_rqpair_process_auto_xfr_rdy_data(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe); 1425331766Skenextern ocs_hw_rtn_e ocs_hw_rqpair_init(ocs_hw_t *hw); 1426331766Skenextern ocs_hw_rtn_e ocs_hw_rqpair_auto_xfer_rdy_buffer_alloc(ocs_hw_t *hw, uint32_t num_buffers); 1427331766Skenextern uint8_t ocs_hw_rqpair_auto_xfer_rdy_buffer_post(ocs_hw_t *hw, ocs_hw_io_t *io, int reuse_buf); 1428331766Skenextern ocs_hw_rtn_e ocs_hw_rqpair_auto_xfer_rdy_move_to_port(ocs_hw_t *hw, ocs_hw_io_t *io); 1429331766Skenextern void ocs_hw_rqpair_auto_xfer_rdy_move_to_host(ocs_hw_t *hw, ocs_hw_io_t *io); 1430331766Skenextern void ocs_hw_rqpair_teardown(ocs_hw_t *hw); 1431331766Sken 1432331766Skenextern ocs_hw_rtn_e ocs_hw_rx_allocate(ocs_hw_t *hw); 1433331766Skenextern ocs_hw_rtn_e ocs_hw_rx_post(ocs_hw_t *hw); 1434331766Skenextern void ocs_hw_rx_free(ocs_hw_t *hw); 1435331766Sken 1436331766Skenextern void ocs_hw_unsol_process_bounce(void *arg); 1437331766Sken 1438331766Skentypedef int32_t (*ocs_hw_async_cb_t)(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg); 1439331766Skenextern int32_t ocs_hw_async_call(ocs_hw_t *hw, ocs_hw_async_cb_t callback, void *arg); 1440331766Sken 1441331766Skenstatic inline void 1442331766Skenocs_hw_sequence_copy(ocs_hw_sequence_t *dst, ocs_hw_sequence_t *src) 1443331766Sken{ 1444331766Sken /* Copy the src to dst, then zero out the linked list link */ 1445331766Sken *dst = *src; 1446331766Sken ocs_memset(&dst->link, 0, sizeof(dst->link)); 1447331766Sken} 1448331766Sken 1449331766Skenstatic inline ocs_hw_rtn_e 1450331766Skenocs_hw_sequence_free(ocs_hw_t *hw, ocs_hw_sequence_t *seq) 1451331766Sken{ 1452331766Sken /* Only RQ pair mode is supported */ 1453331766Sken return ocs_hw_rqpair_sequence_free(hw, seq); 1454331766Sken} 1455331766Sken 1456331766Sken/* HW WQ request tag API */ 1457331766Skenextern ocs_hw_rtn_e ocs_hw_reqtag_init(ocs_hw_t *hw); 1458331766Skenextern hw_wq_callback_t *ocs_hw_reqtag_alloc(ocs_hw_t *hw, 1459331766Sken void (*callback)(void *arg, uint8_t *cqe, int32_t status), void *arg); 1460331766Skenextern void ocs_hw_reqtag_free(ocs_hw_t *hw, hw_wq_callback_t *wqcb); 1461331766Skenextern hw_wq_callback_t *ocs_hw_reqtag_get_instance(ocs_hw_t *hw, uint32_t instance_index); 1462331766Skenextern void ocs_hw_reqtag_reset(ocs_hw_t *hw); 1463331766Sken 1464331766Sken 1465331766Skenextern uint32_t ocs_hw_dif_blocksize(ocs_hw_dif_info_t *dif_info); 1466331766Skenextern int32_t ocs_hw_dif_mem_blocksize(ocs_hw_dif_info_t *dif_info, int wiretomem); 1467331766Skenextern int32_t ocs_hw_dif_wire_blocksize(ocs_hw_dif_info_t *dif_info, int wiretomem); 1468331766Skenextern uint32_t ocs_hw_get_def_wwn(ocs_t *ocs, uint32_t chan, uint64_t *wwpn, uint64_t *wwnn); 1469331766Sken 1470331766Sken/* Uncomment to enable CPUTRACE */ 1471331766Sken//#define ENABLE_CPUTRACE 1472331766Sken#ifdef ENABLE_CPUTRACE 1473331766Sken#define CPUTRACE(t) ocs_printf("trace: %-20s %2s %-16s cpu %2d\n", __func__, t, \ 1474331766Sken ({ocs_thread_t *self = ocs_thread_self(); self != NULL ? self->name : "unknown";}), ocs_thread_getcpu()); 1475331766Sken#else 1476331766Sken#define CPUTRACE(...) 1477331766Sken#endif 1478331766Sken 1479331766Sken 1480331766Sken/* Two levels of macro needed due to expansion */ 1481331766Sken#define HW_FWREV(a,b,c,d) (((uint64_t)(a) << 48) | ((uint64_t)(b) << 32) | ((uint64_t)(c) << 16) | ((uint64_t)(d))) 1482331766Sken#define HW_FWREV_1(x) HW_FWREV(x) 1483331766Sken 1484331766Sken#define OCS_FW_VER_STR2(a,b,c,d) #a "." #b "." #c "." #d 1485331766Sken#define OCS_FW_VER_STR(x) OCS_FW_VER_STR2(x) 1486331766Sken 1487331766Sken#define OCS_MIN_FW_VER_LANCER 10,4,255,0 1488331766Sken#define OCS_MIN_FW_VER_SKYHAWK 10,4,255,0 1489331766Sken 1490331766Skenextern void ocs_hw_workaround_setup(struct ocs_hw_s *hw); 1491331766Sken 1492331766Sken 1493331766Sken/** 1494331766Sken * @brief Defines the number of the RQ buffers for each RQ 1495331766Sken */ 1496331766Sken 1497331766Sken#ifndef OCS_HW_RQ_NUM_HDR 1498331766Sken#define OCS_HW_RQ_NUM_HDR 1024 1499331766Sken#endif 1500331766Sken 1501331766Sken#ifndef OCS_HW_RQ_NUM_PAYLOAD 1502331766Sken#define OCS_HW_RQ_NUM_PAYLOAD 1024 1503331766Sken#endif 1504331766Sken 1505331766Sken/** 1506331766Sken * @brief Defines the size of the RQ buffers used for each RQ 1507331766Sken */ 1508331766Sken#ifndef OCS_HW_RQ_SIZE_HDR 1509331766Sken#define OCS_HW_RQ_SIZE_HDR 128 1510331766Sken#endif 1511331766Sken 1512331766Sken#ifndef OCS_HW_RQ_SIZE_PAYLOAD 1513331766Sken#define OCS_HW_RQ_SIZE_PAYLOAD 1024 1514331766Sken#endif 1515331766Sken 1516331766Sken/* 1517331766Sken * @brief Define the maximum number of multi-receive queues 1518331766Sken */ 1519331766Sken#ifndef OCS_HW_MAX_MRQS 1520331766Sken#define OCS_HW_MAX_MRQS 8 1521331766Sken#endif 1522331766Sken 1523331766Sken/* 1524331766Sken * @brief Define count of when to set the WQEC bit in a submitted 1525331766Sken * WQE, causing a consummed/released completion to be posted. 1526331766Sken */ 1527331766Sken#ifndef OCS_HW_WQEC_SET_COUNT 1528331766Sken#define OCS_HW_WQEC_SET_COUNT 32 1529331766Sken#endif 1530331766Sken 1531331766Sken/* 1532331766Sken * @brief Send frame timeout in seconds 1533331766Sken */ 1534331766Sken#ifndef OCS_HW_SEND_FRAME_TIMEOUT 1535331766Sken#define OCS_HW_SEND_FRAME_TIMEOUT 10 1536331766Sken#endif 1537331766Sken 1538331766Sken/* 1539331766Sken * @brief FDT Transfer Hint value, reads greater than this value 1540331766Sken * will be segmented to implement fairness. A value of zero disables 1541331766Sken * the feature. 1542331766Sken */ 1543331766Sken#ifndef OCS_HW_FDT_XFER_HINT 1544331766Sken#define OCS_HW_FDT_XFER_HINT 8192 1545331766Sken#endif 1546331766Sken 1547331766Sken#endif /* !_OCS_HW_H */ 1548