1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2010 Emulex.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #ifndef _EMLXS_FC_H
  28 #define _EMLXS_FC_H
  29 
  30 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 typedef struct emlxs_buf
  35 {
  36         fc_packet_t             *pkt;           /* scsi_pkt reference */
  37         struct emlxs_port       *port;          /* pointer to port */
  38         void                    *bmp;           /* Save the buffer pointer */
  39                                                 /* list for later use. */
  40         struct emlxs_buf        *fc_fwd;        /* Use it by chip_Q */
  41         struct emlxs_buf        *fc_bkwd;       /* Use it by chip_Q */
  42         struct emlxs_buf        *next;          /* Use it when the iodone */
  43         struct emlxs_node       *node;
  44         void                    *channel;       /* Save channel and used by */
  45                                                 /* abort */
  46         struct emlxs_buf        *fpkt;          /* Flush pkt pointer */
  47         struct XRIobj           *xrip;          /* Exchange resource */
  48         IOCBQ                   iocbq;
  49         kmutex_t                mtx;
  50         uint32_t                pkt_flags;
  51         uint32_t                iotag;          /* iotag for this cmd */
  52         uint32_t                ticks;          /* save the timeout ticks */
  53                                                 /* for the fc_packet_t */
  54         uint32_t                abort_attempts;
  55         uint32_t                lun;
  56 #define EMLXS_LUN_NONE          0xFFFFFFFF
  57 
  58         uint32_t                class;          /* Save class and used by */
  59                                                 /* abort */
  60         uint32_t                ucmd;           /* Unsolicted command that */
  61                                                 /* this packet is responding */
  62                                                 /* to, if any */
  63         int32_t                 flush_count;    /* Valid only in flush pkts */
  64         uint32_t                did;
  65 
  66 #ifdef SFCT_SUPPORT
  67         kmutex_t                fct_mtx;
  68         fc_packet_t             *fct_pkt;
  69         fct_cmd_t               *fct_cmd;
  70 
  71         uint8_t                 fct_type;
  72 
  73 #define EMLXS_FCT_ELS_CMD               0x01    /* Unsolicted */
  74 #define EMLXS_FCT_ELS_REQ               0x02    /* Solicited */
  75 #define EMLXS_FCT_ELS_RSP               0x04
  76 #define EMLXS_FCT_CT_REQ                0x08    /* Solicited */
  77 #define EMLXS_FCT_FCP_CMD               0x10    /* Unsolicted */
  78 #define EMLXS_FCT_FCP_DATA              0x20
  79 #define EMLXS_FCT_FCP_STATUS            0x40
  80 
  81 
  82         uint8_t                 fct_flags;
  83 
  84 #define EMLXS_FCT_SEND_STATUS           0x01
  85 #define EMLXS_FCT_ABORT_INP             0x02
  86 #define EMLXS_FCT_IO_INP                0x04
  87 #define EMLXS_FCT_PLOGI_RECEIVED        0x10
  88 #define EMLXS_FCT_REGISTERED            0x20
  89 
  90         uint16_t                fct_state;
  91 
  92 #define EMLXS_FCT_FCP_CMD_RECEIVED      1
  93 #define EMLXS_FCT_ELS_CMD_RECEIVED      2
  94 #define EMLXS_FCT_CMD_POSTED            3
  95 #define EMLXS_FCT_CMD_WAITQ             4
  96 #define EMLXS_FCT_SEND_CMD_RSP          5
  97 #define EMLXS_FCT_SEND_ELS_RSP          6
  98 #define EMLXS_FCT_SEND_ELS_REQ          7
  99 #define EMLXS_FCT_SEND_CT_REQ           8
 100 #define EMLXS_FCT_RSP_PENDING           9
 101 #define EMLXS_FCT_REQ_PENDING           10
 102 #define EMLXS_FCT_REG_PENDING           11
 103 #define EMLXS_FCT_REG_COMPLETE          12
 104 #define EMLXS_FCT_OWNED                 13
 105 #define EMLXS_FCT_SEND_FCP_DATA         14
 106 #define EMLXS_FCT_SEND_FCP_STATUS       15
 107 #define EMLXS_FCT_DATA_PENDING          16
 108 #define EMLXS_FCT_STATUS_PENDING        17
 109 #define EMLXS_FCT_PKT_COMPLETE          18
 110 #define EMLXS_FCT_PKT_FCPRSP_COMPLETE   19
 111 #define EMLXS_FCT_PKT_ELSRSP_COMPLETE   20
 112 #define EMLXS_FCT_PKT_ELSCMD_COMPLETE   21
 113 #define EMLXS_FCT_PKT_CTCMD_COMPLETE    22
 114 #define EMLXS_FCT_REQ_COMPLETE          23
 115 #define EMLXS_FCT_CLOSE_PENDING         24
 116 #define EMLXS_FCT_ABORT_PENDING         25
 117 #define EMLXS_FCT_ABORT_DONE            26
 118 #define EMLXS_FCT_IO_DONE               27
 119 
 120 #define EMLXS_FCT_IOCB_ISSUED           256 /* For tracing only */
 121 #define EMLXS_FCT_IOCB_COMPLETE         257 /* For tracing only */
 122 
 123         stmf_data_buf_t         *fct_buf;
 124 
 125 #endif /* SFCT_SUPPORT */
 126 
 127 #ifdef SAN_DIAG_SUPPORT
 128         hrtime_t                sd_start_time;
 129 #endif
 130 } emlxs_buf_t;
 131 
 132 
 133 
 134 #ifdef FCT_IO_TRACE
 135 #define EMLXS_FCT_STATE_CHG(_fct_cmd, _cmd_sbp, _state) \
 136         (_cmd_sbp)->fct_state = _state;                      \
 137         emlxs_fct_io_trace((_cmd_sbp)->port, _fct_cmd, _state)
 138 #else
 139 /* define to set fct_state */
 140 #define EMLXS_FCT_STATE_CHG(_fct_cmd, _cmd_sbp, _state) \
 141         (_cmd_sbp)->fct_state = _state
 142 #endif /* FCT_IO_TRACE */
 143 
 144 
 145 /* pkt_flags */
 146 #define PACKET_IN_COMPLETION    0x00000001
 147 #define PACKET_IN_TXQ           0x00000002
 148 #define PACKET_IN_CHIPQ         0x00000004
 149 #define PACKET_IN_DONEQ         0x00000008
 150 
 151 #define PACKET_FCP_RESET        0x00000030
 152 #define PACKET_FCP_TGT_RESET    0x00000010
 153 #define PACKET_FCP_LUN_RESET    0x00000020
 154 #define PACKET_POLLED           0x00000040
 155 
 156 #ifdef EMLXS_I386
 157 #define PACKET_FCP_SWAPPED      0x00000100
 158 #define PACKET_ELS_SWAPPED      0x00000200
 159 #define PACKET_CT_SWAPPED       0x00000400
 160 #define PACKET_CSP_SWAPPED      0x00000800
 161 #endif  /* EMLXS_I386 */
 162 
 163 #define PACKET_STALE            0x00001000
 164 
 165 #define PACKET_IN_TIMEOUT       0x00010000
 166 #define PACKET_IN_FLUSH         0x00020000
 167 #define PACKET_IN_ABORT         0x00040000
 168 #define PACKET_XRI_CLOSED       0x00080000 /* An XRI abort/close was issued */
 169 
 170 #define PACKET_CHIP_COMP        0x00100000
 171 #define PACKET_COMPLETED        0x00200000
 172 #define PACKET_ULP_OWNED        0x00400000
 173 
 174 #define PACKET_STATE_VALID      0x01000000
 175 #define PACKET_FCP_RSP_VALID    0x02000000
 176 #define PACKET_ELS_RSP_VALID    0x04000000
 177 #define PACKET_CT_RSP_VALID     0x08000000
 178 
 179 #define PACKET_DELAY_REQUIRED   0x10000000
 180 #define PACKET_ALLOCATED        0x40000000
 181 #define PACKET_VALID            0x80000000
 182 
 183 
 184 #define STALE_PACKET            ((emlxs_buf_t *)0xFFFFFFFF)
 185 
 186 
 187 /*
 188  * From fc_error.h pkt_reason (except for state = NPORT_RJT, FABRIC_RJT,
 189  * NPORT_BSY, FABRIC_BSY, LS_RJT, BA_RJT, FS_RJT)
 190  *
 191  * FCA unique error codes can begin after FC_REASON_FCA_UNIQUE.
 192  * Each FCA defines its own set with values greater >= 0x7F
 193  */
 194 #define FC_REASON_FCA_DEFINED   0x100
 195 
 196 
 197 /*
 198  * Device VPD save area
 199  */
 200 
 201 typedef struct emlxs_vpd
 202 {
 203         uint32_t        biuRev;
 204         uint32_t        smRev;
 205         uint32_t        smFwRev;
 206         uint32_t        endecRev;
 207         uint16_t        rBit;
 208         uint8_t         fcphHigh;
 209         uint8_t         fcphLow;
 210         uint8_t         feaLevelHigh;
 211         uint8_t         feaLevelLow;
 212 
 213         uint32_t        postKernRev;
 214         char            postKernName[32];
 215 
 216         uint32_t        opFwRev;
 217         char            opFwName[32];
 218         char            opFwLabel[32];
 219 
 220         uint32_t        sli1FwRev;
 221         char            sli1FwName[32];
 222         char            sli1FwLabel[32];
 223 
 224         uint32_t        sli2FwRev;
 225         char            sli2FwName[32];
 226         char            sli2FwLabel[32];
 227 
 228         uint32_t        sli3FwRev;
 229         char            sli3FwName[32];
 230         char            sli3FwLabel[32];
 231 
 232         uint32_t        sli4FwRev;
 233         char            sli4FwName[32];
 234         char            sli4FwLabel[32];
 235 
 236         char            fw_version[32];
 237         char            fw_label[32];
 238 
 239         char            fcode_version[32];
 240         char            boot_version[32];
 241 
 242         char            serial_num[32];
 243         char            part_num[32];
 244         char            port_num[20];
 245         char            eng_change[32];
 246         char            manufacturer[80];
 247         char            model[80];
 248         char            model_desc[256];
 249         char            prog_types[256];
 250         char            id[80];
 251 
 252         uint32_t        port_index;
 253         uint16_t        link_speed;
 254 } emlxs_vpd_t;
 255 
 256 
 257 typedef struct emlxs_queue
 258 {
 259         void            *q_first;       /* queue first element */
 260         void            *q_last;        /* queue last element */
 261         uint16_t        q_cnt;  /* current length of queue */
 262         uint16_t        q_max;  /* max length queue can get */
 263 } emlxs_queue_t;
 264 typedef emlxs_queue_t Q;
 265 
 266 
 267 
 268 /*
 269  * This structure is used when allocating a buffer pool.
 270  * Note: this should be identical to gasket buf_info (fldl.h).
 271  */
 272 typedef struct emlxs_buf_info
 273 {
 274         int32_t         size;   /* Specifies the number of bytes to allocate. */
 275         int32_t         align;  /* The desired address boundary. */
 276 
 277         int32_t         flags;
 278 
 279 #define FC_MBUF_DMA             0x01    /* blocks are for DMA */
 280 #define FC_MBUF_PHYSONLY        0x02    /* For malloc - map a given virtual */
 281                                         /* address to physical address (skip */
 282                                         /* the malloc). */
 283                                         /* For free - just unmap the given */
 284                                         /* physical address (skip the free). */
 285 #define FC_MBUF_IOCTL           0x04    /* called from dfc_ioctl */
 286 #define FC_MBUF_UNLOCK          0x08    /* called with driver unlocked */
 287 #define FC_MBUF_SNGLSG          0x10    /* allocate a single contiguous */
 288                                         /* physical memory */
 289 #define FC_MBUF_DMA32           0x20
 290 
 291         uint64_t        phys;           /* specifies physical buffer pointer */
 292         void            *virt;          /* specifies virtual buffer pointer */
 293         void            *data_handle;
 294         void            *dma_handle;
 295 } emlxs_buf_info_t;
 296 typedef emlxs_buf_info_t MBUF_INFO;
 297 
 298 
 299 #define EMLXS_MAX_HBQ           16      /* Max HBQs handled by firmware */
 300 #define EMLXS_ELS_HBQ_ID        0
 301 #define EMLXS_IP_HBQ_ID         1
 302 #define EMLXS_CT_HBQ_ID         2
 303 #define EMLXS_FCT_HBQ_ID        3
 304 
 305 #ifdef SFCT_SUPPORT
 306 #define EMLXS_NUM_HBQ           4       /* Number of HBQs supported by driver */
 307 #else
 308 #define EMLXS_NUM_HBQ           3       /* Number of HBQs supported by driver */
 309 #endif /* SFCT_SUPPORT */
 310 
 311 
 312 /*
 313  * An IO Channel is a object that comprises a xmit/cmpl
 314  * path for IOs.
 315  * For SLI3, an IO path maps to a ring (cmd/rsp)
 316  * For SLI4, an IO path map to a queue pair (WQ/CQ)
 317  */
 318 typedef struct emlxs_channel
 319 {
 320         struct emlxs_hba *hba;                  /* ptr to hba for channel */
 321         void            *iopath;                /* ptr to SLI3/4 io path */
 322 
 323         kmutex_t        rsp_lock;
 324         IOCBQ           *rsp_head;      /* deferred completion head */
 325         IOCBQ           *rsp_tail;      /* deferred completion tail */
 326         emlxs_thread_t  intr_thread;
 327 
 328 
 329         uint16_t        channelno;
 330         uint16_t        chan_flag;
 331 
 332 #define EMLXS_NEEDS_TRIGGER 1
 333 
 334         /* Protected by EMLXS_TX_CHANNEL_LOCK */
 335         emlxs_queue_t   nodeq;                  /* Node service queue */
 336 
 337         kmutex_t        channel_cmd_lock;
 338         uint32_t        timeout;
 339 
 340         /* Channel command counters */
 341         uint32_t        ulpSendCmd;
 342         uint32_t        ulpCmplCmd;
 343         uint32_t        hbaSendCmd;
 344         uint32_t        hbaCmplCmd;
 345         uint32_t        hbaSendCmd_sbp;
 346         uint32_t        hbaCmplCmd_sbp;
 347 
 348 } emlxs_channel_t;
 349 typedef emlxs_channel_t CHANNEL;
 350 
 351 /*
 352  * Should be able to handle max number of io paths for a
 353  * SLI4 HBA (EMLXS_MAX_WQS) or for a SLI3 HBA (MAX_RINGS)
 354  */
 355 #define MAX_CHANNEL EMLXS_MSI_MAX_INTRS
 356 
 357 
 358 /* Structure used to access adapter rings */
 359 typedef struct emlxs_ring
 360 {
 361         void            *fc_cmdringaddr;        /* virtual offset for cmd */
 362                                                 /* rings */
 363         void            *fc_rspringaddr;        /* virtual offset for rsp */
 364                                                 /* rings */
 365 
 366         void            *fc_mpon;               /* index ptr for match */
 367                                                 /* structure */
 368         void            *fc_mpoff;              /* index ptr for match */
 369                                                 /* structure */
 370         struct emlxs_hba *hba;                  /* ptr to hba for ring */
 371 
 372         uint8_t         fc_numCiocb;            /* number of command iocb's */
 373                                                 /* per ring */
 374         uint8_t         fc_numRiocb;            /* number of response iocb's */
 375                                                 /* per ring */
 376         uint8_t         fc_rspidx;              /* current index in response */
 377                                                 /* ring */
 378         uint8_t         fc_cmdidx;              /* current index in command */
 379                                                 /* ring */
 380         uint8_t         fc_port_rspidx;
 381         uint8_t         fc_port_cmdidx;
 382         uint8_t         ringno;
 383 
 384         uint16_t        fc_missbufcnt;          /* buf cnt we need to repost */
 385         CHANNEL         *channelp;
 386 
 387 
 388 } emlxs_ring_t;
 389 typedef emlxs_ring_t RING;
 390 
 391 
 392 #ifdef SAN_DIAG_SUPPORT
 393 /*
 394  * Although right now it's just 1 field, SAN Diag anticipates that this
 395  * structure will grow in the future.
 396  */
 397 typedef struct sd_timestat_level0 {
 398         int             count;
 399 } sd_timestat_level0_t;
 400 #endif
 401 
 402 typedef struct emlxs_node
 403 {
 404         struct emlxs_node       *nlp_list_next;
 405         struct emlxs_node       *nlp_list_prev;
 406 
 407         NAME_TYPE               nlp_portname;   /* port name */
 408         NAME_TYPE               nlp_nodename;   /* node name */
 409 
 410         uint32_t                nlp_DID;        /* fibre channel D_ID */
 411         uint32_t                nlp_oldDID;
 412 
 413         uint16_t                nlp_Rpi;        /* login id returned by */
 414                                                 /* REG_LOGIN */
 415         uint16_t                nlp_Xri;        /* login id returned by */
 416                                                 /* REG_LOGIN */
 417 
 418         uint8_t                 nlp_fcp_info;   /* Remote class info */
 419 
 420         /* nlp_fcp_info */
 421 #define NLP_FCP_TGT_DEVICE      0x10    /* FCP TGT device */
 422 #define NLP_FCP_INI_DEVICE      0x20    /* FCP Initiator device */
 423 #define NLP_FCP_2_DEVICE        0x40    /* FCP-2 TGT device */
 424 #define NLP_EMLX_VPORT          0x80    /* Virtual port */
 425 
 426         uint32_t                nlp_force_rscn;
 427         uint32_t                nlp_tag;        /* Tag used by port_offline */
 428         uint32_t                flag;
 429 
 430 #define NODE_POOL_ALLOCATED     0x00000001
 431 
 432         SERV_PARM               sparm;
 433 
 434         /* Protected by EMLXS_TX_CHANNEL_LOCK */
 435         uint32_t                nlp_active;     /* Node active flag */
 436         uint32_t                nlp_base;
 437         uint32_t                nlp_flag[MAX_CHANNEL];  /* Node level channel */
 438                                                         /* flags */
 439 
 440         /* nlp_flag */
 441 #define NLP_CLOSED              0x1
 442 #define NLP_OFFLINE             0x2
 443 #define NLP_RPI_XRI             0x4
 444 
 445         uint32_t                nlp_tics[MAX_CHANNEL];  /* gate timeout */
 446         emlxs_queue_t           nlp_tx[MAX_CHANNEL];    /* Transmit Q head */
 447         emlxs_queue_t           nlp_ptx[MAX_CHANNEL];   /* Priority transmit */
 448                                                         /* Queue head */
 449         void                    *nlp_next[MAX_CHANNEL]; /* Service Request */
 450                                                         /* Queue pointer used */
 451                                                         /* when node needs */
 452                                                         /* servicing */
 453 #ifdef DHCHAP_SUPPORT
 454         emlxs_node_dhc_t        node_dhc;
 455 #endif  /* DHCHAP_SUPPORT */
 456 
 457 #ifdef SAN_DIAG_SUPPORT
 458         sd_timestat_level0_t    sd_dev_bucket[SD_IO_LATENCY_MAX_BUCKETS];
 459 #endif
 460 
 461         struct RPIobj           *rpip;  /* SLI4 only */
 462 #define EMLXS_NODE_TO_RPI(_p, _n)       \
 463         ((_n)?((_n->rpip)?_n->rpip:emlxs_rpi_find(_p, _n->nlp_Rpi)):NULL)
 464 
 465 } emlxs_node_t;
 466 typedef emlxs_node_t NODELIST;
 467 
 468 
 469 
 470 #define NADDR_LEN       6       /* MAC network address length */
 471 typedef struct emlxs_fcip_nethdr
 472 {
 473         NAME_TYPE       fc_destname;    /* destination port name */
 474         NAME_TYPE       fc_srcname;     /* source port name */
 475 } emlxs_fcip_nethdr_t;
 476 typedef emlxs_fcip_nethdr_t NETHDR;
 477 
 478 
 479 #define MEM_NLP         0       /* memory segment to hold node list entries */
 480 #define MEM_IOCB        1       /* memory segment to hold iocb commands */
 481 #define MEM_MBOX        2       /* memory segment to hold mailbox cmds  */
 482 #define MEM_BPL         3       /* and to hold buffer ptr lists - SLI2   */
 483 #define MEM_BUF         4       /* memory segment to hold buffer data   */
 484 #define MEM_ELSBUF      4       /* memory segment to hold buffer data   */
 485 #define MEM_IPBUF       5       /* memory segment to hold IP buffer data */
 486 #define MEM_CTBUF       6       /* memory segment to hold CT buffer data */
 487 #define MEM_FCTBUF      7       /* memory segment to hold FCT buffer data */
 488 
 489 #ifdef SFCT_SUPPORT
 490 #define FC_MAX_SEG      8
 491 #else
 492 #define FC_MAX_SEG      7
 493 #endif /* SFCT_SUPPORT */
 494 
 495 
 496 /* A BPL entry is 12 bytes. Subtract 2 for command and response buffers */
 497 #define BPL_TO_SGLLEN(_bpl)   ((_bpl/12)-2)
 498 #define MEM_BPL_SIZE            1024  /* Default size */
 499 
 500 /* A SGL entry is 16 bytes. Subtract 2 for command and response buffers */
 501 #define SGL_TO_SGLLEN(_sgl)   ((_sgl/16)-2)
 502 #define MEM_SGL_SIZE            4096  /* Default size */
 503 
 504 #ifdef EMLXS_I386
 505 #define EMLXS_SGLLEN            BPL_TO_SGLLEN(MEM_BPL_SIZE)
 506 #else   /* EMLXS_SPARC */
 507 #define EMLXS_SGLLEN            1
 508 #endif  /* EMLXS_I386 */
 509 
 510 #define MEM_BUF_SIZE            1024
 511 #define MEM_BUF_COUNT           64
 512 
 513 #define MEM_ELSBUF_SIZE         MEM_BUF_SIZE
 514 #define MEM_ELSBUF_COUNT        hba->max_nodes
 515 #define MEM_IPBUF_SIZE          65535
 516 #define MEM_IPBUF_COUNT         60
 517 #define MEM_CTBUF_SIZE          MAX_CT_PAYLOAD  /* (1024*320) */
 518 #define MEM_CTBUF_COUNT         8
 519 #define MEM_FCTBUF_SIZE         65535
 520 #define MEM_FCTBUF_COUNT        128
 521 
 522 typedef struct emlxs_memseg
 523 {
 524         void                    *fc_memget_ptr;
 525         void                    *fc_memget_end;
 526         void                    *fc_memput_ptr;
 527         void                    *fc_memput_end;
 528 
 529         void                    *fc_memstart_virt;      /* beginning address */
 530                                                         /* of memory block */
 531         uint64_t                fc_memstart_phys;       /* beginning address */
 532                                                         /* of memory block */
 533         ddi_dma_handle_t        fc_mem_dma_handle;
 534         ddi_acc_handle_t        fc_mem_dat_handle;
 535         uint32_t                fc_total_memsize;
 536         uint32_t                fc_memsize;             /* size of mem blks */
 537         uint32_t                fc_numblks;             /* no of mem blks */
 538         uint32_t                fc_memget_cnt;          /* no of mem get blks */
 539         uint32_t                fc_memput_cnt;          /* no of mem put blks */
 540         uint32_t                fc_memflag;  /* emlxs_buf_info_t FLAGS */
 541         uint32_t                fc_reserved; /* used with priority flag */
 542         uint32_t                fc_memalign;
 543         uint32_t                fc_memtag;
 544         char                    fc_label[32];
 545 
 546 } emlxs_memseg_t;
 547 typedef emlxs_memseg_t MEMSEG;
 548 
 549 
 550 /* Board stat counters */
 551 typedef struct emlxs_stats
 552 {
 553         uint32_t        LinkUp;
 554         uint32_t        LinkDown;
 555         uint32_t        LinkEvent;
 556         uint32_t        LinkMultiEvent;
 557 
 558         uint32_t        MboxIssued;
 559         uint32_t        MboxCompleted;  /* MboxError + MbxGood */
 560         uint32_t        MboxGood;
 561         uint32_t        MboxError;
 562         uint32_t        MboxBusy;
 563         uint32_t        MboxInvalid;
 564 
 565         uint32_t        IocbIssued[MAX_CHANNEL];
 566         uint32_t        IocbReceived[MAX_CHANNEL];
 567         uint32_t        IocbTxPut[MAX_CHANNEL];
 568         uint32_t        IocbTxGet[MAX_CHANNEL];
 569         uint32_t        IocbRingFull[MAX_CHANNEL];
 570         uint32_t        IocbThrottled;
 571 
 572         uint32_t        IntrEvent[8];
 573 
 574         uint32_t        FcpIssued;
 575         uint32_t        FcpCompleted;   /* FcpGood + FcpError */
 576         uint32_t        FcpGood;
 577         uint32_t        FcpError;
 578 
 579         uint32_t        FcpEvent;       /* FcpStray + FcpCompleted */
 580         uint32_t        FcpStray;
 581 #ifdef SFCT_SUPPORT
 582         uint32_t        FctRingEvent;
 583         uint32_t        FctRingError;
 584         uint32_t        FctRingDropped;
 585 #endif /* SFCT_SUPPORT */
 586 
 587         uint32_t        ElsEvent;       /* ElsStray + ElsCmplt (cmd + rsp) */
 588         uint32_t        ElsStray;
 589 
 590         uint32_t        ElsCmdIssued;
 591         uint32_t        ElsCmdCompleted;        /* ElsCmdGood + ElsCmdError */
 592         uint32_t        ElsCmdGood;
 593         uint32_t        ElsCmdError;
 594 
 595         uint32_t        ElsRspIssued;
 596         uint32_t        ElsRspCompleted;
 597 
 598         uint32_t        ElsRcvEvent;    /* ElsRcvErr + ElsRcvDrop + ElsCmdRcv */
 599         uint32_t        ElsRcvError;
 600         uint32_t        ElsRcvDropped;
 601         uint32_t        ElsCmdReceived; /* ElsRscnRcv + ElsPlogiRcv + ... */
 602         uint32_t        ElsRscnReceived;
 603         uint32_t        ElsFlogiReceived;
 604         uint32_t        ElsPlogiReceived;
 605         uint32_t        ElsPrliReceived;
 606         uint32_t        ElsPrloReceived;
 607         uint32_t        ElsLogoReceived;
 608         uint32_t        ElsAdiscReceived;
 609         uint32_t        ElsAuthReceived;
 610         uint32_t        ElsGenReceived;
 611 
 612         uint32_t        CtEvent;        /* CtStray + CtCompleted (cmd + rsp) */
 613         uint32_t        CtStray;
 614 
 615         uint32_t        CtCmdIssued;
 616         uint32_t        CtCmdCompleted; /* CtCmdGood + CtCmdError */
 617         uint32_t        CtCmdGood;
 618         uint32_t        CtCmdError;
 619 
 620         uint32_t        CtRspIssued;
 621         uint32_t        CtRspCompleted;
 622 
 623         uint32_t        CtRcvEvent;     /* CtRcvError + CtRcvDrop + CtCmdRcvd */
 624         uint32_t        CtRcvError;
 625         uint32_t        CtRcvDropped;
 626         uint32_t        CtCmdReceived;
 627 
 628         uint32_t        IpEvent;        /* IpStray + IpSeqCmpl + IpBcastCmpl */
 629         uint32_t        IpStray;
 630 
 631         uint32_t        IpSeqIssued;
 632         uint32_t        IpSeqCompleted; /* IpSeqGood + IpSeqError */
 633         uint32_t        IpSeqGood;
 634         uint32_t        IpSeqError;
 635 
 636         uint32_t        IpBcastIssued;
 637         uint32_t        IpBcastCompleted;       /* IpBcastGood + IpBcastError */
 638         uint32_t        IpBcastGood;
 639         uint32_t        IpBcastError;
 640 
 641         uint32_t        IpRcvEvent;     /* IpDrop + IpSeqRcv + IpBcastRcv */
 642         uint32_t        IpDropped;
 643         uint32_t        IpSeqReceived;
 644         uint32_t        IpBcastReceived;
 645 
 646         uint32_t        IpUbPosted;
 647         uint32_t        ElsUbPosted;
 648         uint32_t        CtUbPosted;
 649 #ifdef SFCT_SUPPORT
 650         uint32_t        FctUbPosted;
 651 #endif /* SFCT_SUPPORT */
 652 
 653         uint32_t        ResetTime;      /* Time of last reset */
 654 
 655         uint32_t        ElsTestReceived;
 656         uint32_t        ElsEstcReceived;
 657         uint32_t        ElsFarprReceived;
 658         uint32_t        ElsEchoReceived;
 659         uint32_t        ElsRlsReceived;
 660         uint32_t        ElsRtvReceived;
 661 
 662 } emlxs_stats_t;
 663 
 664 
 665 #define FC_MAX_ADPTMSG   (8*28) /* max size of a msg from adapter */
 666 
 667 #define EMLXS_NUM_THREADS       8
 668 #define EMLXS_MIN_TASKS         8
 669 #define EMLXS_MAX_TASKS         8
 670 
 671 #define EMLXS_NUM_HASH_QUES     32
 672 #define EMLXS_DID_HASH(x)       ((x) & (EMLXS_NUM_HASH_QUES - 1))
 673 
 674 
 675 /* pkt_tran_flag */
 676 #define FC_TRAN_COMPLETED       0x8000
 677 
 678 
 679 typedef struct emlxs_dfc_event
 680 {
 681         uint32_t        pid;
 682         uint32_t        event;
 683         uint32_t        last_id;
 684 
 685         void            *dataout;
 686         uint32_t        size;
 687         uint32_t        mode;
 688 } emlxs_dfc_event_t;
 689 
 690 
 691 typedef struct emlxs_hba_event
 692 {
 693         uint32_t        last_id;
 694         uint32_t        new;
 695         uint32_t        missed;
 696 } emlxs_hba_event_t;
 697 
 698 
 699 #ifdef SFCT_SUPPORT
 700 
 701 #define TGTPORTSTAT                     port->fct_stat
 702 
 703 /*
 704  * FctP2IOXcnt will count IOs by their fcpDL. Counters
 705  * are for buckets of various power of 2 sizes.
 706  * Bucket 0  <  512  > 0
 707  * Bucket 1  >= 512  < 1024
 708  * Bucket 2  >= 1024 < 2048
 709  * Bucket 3  >= 2048 < 4096
 710  * Bucket 4  >= 4096 < 8192
 711  * Bucket 5  >= 8192 < 16K
 712  * Bucket 6  >= 16K  < 32K
 713  * Bucket 7  >= 32K  < 64K
 714  * Bucket 8  >= 64K  < 128K
 715  * Bucket 9  >= 128K < 256K
 716  * Bucket 10 >= 256K < 512K
 717  * Bucket 11 >= 512K < 1MB
 718  * Bucket 12 >= 1MB  < 2MB
 719  * Bucket 13 >= 2MB  < 4MB
 720  * Bucket 14 >= 4MB  < 8MB
 721  * Bucket 15 >= 8MB
 722  */
 723 #define MAX_TGTPORT_IOCNT  16
 724 
 725 
 726 /*
 727  * These routines will bump the right counter, based on
 728  * the size of the IO inputed, with the least number of
 729  * comparisions.  A max of 5 comparisions is only needed
 730  * to classify the IO in one of 16 ranges. A binary search
 731  * to locate the high bit in the size is used.
 732  */
 733 #define EMLXS_BUMP_RDIOCTR(port, cnt) \
 734 { \
 735         /* Use binary search to find the first high bit */ \
 736         if (cnt & 0xffff0000) { \
 737                 if (cnt & 0xff800000) { \
 738                         TGTPORTSTAT.FctP2IORcnt[15]++; \
 739                 } \
 740                 else { \
 741                         /* It must be 0x007f0000 */ \
 742                         if (cnt & 0x00700000) { \
 743                                 if (cnt & 0x00400000) { \
 744                                         TGTPORTSTAT.FctP2IORcnt[14]++; \
 745                                 } \
 746                                 else { \
 747                                         /* it must be 0x00300000 */ \
 748                                         if (cnt & 0x00200000) { \
 749                                                 TGTPORTSTAT.FctP2IORcnt[13]++; \
 750                                         } \
 751                                         else { \
 752                                                 /* It must be 0x00100000 */ \
 753                                                 TGTPORTSTAT.FctP2IORcnt[12]++; \
 754                                         } \
 755                                 } \
 756                         } \
 757                         else { \
 758                                 /* It must be 0x000f0000 */ \
 759                                 if (cnt & 0x000c0000) {     \
 760                                         if (cnt & 0x00080000) {     \
 761                                                 TGTPORTSTAT.FctP2IORcnt[11]++; \
 762                                         } \
 763                                         else { \
 764                                                 /* It must be 0x00040000 */ \
 765                                                 TGTPORTSTAT.FctP2IORcnt[10]++; \
 766                                         } \
 767                                 } \
 768                                 else { \
 769                                         /* It must be 0x00030000 */ \
 770                                         if (cnt & 0x00020000) {     \
 771                                                 TGTPORTSTAT.FctP2IORcnt[9]++; \
 772                                         } \
 773                                         else { \
 774                                                 /* It must be 0x00010000 */ \
 775                                                 TGTPORTSTAT.FctP2IORcnt[8]++; \
 776                                         } \
 777                                 } \
 778                         } \
 779                 } \
 780         } \
 781         else { \
 782                 if (cnt & 0x0000fe00) { \
 783                         if (cnt & 0x0000f000) { \
 784                                 if (cnt & 0x0000c000) { \
 785                                         if (cnt & 0x00008000) { \
 786                                                 TGTPORTSTAT.FctP2IORcnt[7]++; \
 787                                         } \
 788                                         else { \
 789                                                 /* It must be 0x00004000 */ \
 790                                                 TGTPORTSTAT.FctP2IORcnt[6]++; \
 791                                         } \
 792                                 } \
 793                                 else { \
 794                                         /* It must be 0x00000300 */ \
 795                                         if (cnt & 0x00000200) { \
 796                                                 TGTPORTSTAT.FctP2IORcnt[5]++; \
 797                                         } \
 798                                         else { \
 799                                                 /* It must be 0x00000100 */ \
 800                                                 TGTPORTSTAT.FctP2IORcnt[4]++; \
 801                                         } \
 802                                 } \
 803                         } \
 804                         else { \
 805                                 /* It must be 0x00000e00 */ \
 806                                 if (cnt & 0x00000800) { \
 807                                         TGTPORTSTAT.FctP2IORcnt[3]++; \
 808                                 } \
 809                                 else { \
 810                                         /* It must be 0x00000600 */ \
 811                                         if (cnt & 0x00000400) { \
 812                                                 TGTPORTSTAT.FctP2IORcnt[2]++; \
 813                                         } \
 814                                         else { \
 815                                                 /* It must be 0x00000200 */ \
 816                                                 TGTPORTSTAT.FctP2IORcnt[1]++; \
 817                                         } \
 818                                 } \
 819                         } \
 820                 } \
 821                 else { \
 822                         /* It must be 0x000001ff */ \
 823                         TGTPORTSTAT.FctP2IORcnt[0]++; \
 824                 } \
 825         } \
 826 }
 827 
 828 
 829 #define EMLXS_BUMP_WRIOCTR(port, cnt) \
 830 { \
 831 /* Use binary search to find the first high bit */ \
 832         if (cnt & 0xffff0000) { \
 833                 if (cnt & 0xff800000) { \
 834                         TGTPORTSTAT.FctP2IOWcnt[15]++; \
 835                 } \
 836                 else { \
 837                         /* It must be 0x007f0000 */ \
 838                         if (cnt & 0x00700000) { \
 839                                 if (cnt & 0x00400000) { \
 840                                         TGTPORTSTAT.FctP2IOWcnt[14]++; \
 841                                 } \
 842                                 else { \
 843                                         /* It must be 0x00300000 */ \
 844                                         if (cnt & 0x00200000) { \
 845                                                 TGTPORTSTAT.FctP2IOWcnt[13]++; \
 846                                         } \
 847                                         else { \
 848                                                 /* It must be 0x00100000 */ \
 849                                                 TGTPORTSTAT.FctP2IOWcnt[12]++; \
 850                                         } \
 851                                 } \
 852                         } \
 853                         else { \
 854                                 /* It must be 0x000f0000 */ \
 855                                 if (cnt & 0x000c0000) { \
 856                                         if (cnt & 0x00080000) { \
 857                                                 TGTPORTSTAT.FctP2IOWcnt[11]++; \
 858                                         } \
 859                                         else { \
 860                                                 /* it must be 0x00040000 */ \
 861                                                 TGTPORTSTAT.FctP2IOWcnt[10]++; \
 862                                         } \
 863                                 } \
 864                                 else { \
 865                                         /* It must be 0x00030000 */ \
 866                                         if (cnt & 0x00020000) { \
 867                                                 TGTPORTSTAT.FctP2IOWcnt[9]++; \
 868                                         } \
 869                                         else { \
 870                                                 /* It must be 0x00010000 */ \
 871                                                 TGTPORTSTAT.FctP2IOWcnt[8]++; \
 872                                         } \
 873                                 } \
 874                         } \
 875                 } \
 876         } \
 877         else { \
 878                 if (cnt & 0x0000fe00) { \
 879                         if (cnt & 0x0000f000) { \
 880                                 if (cnt & 0x0000c000) { \
 881                                         if (cnt & 0x00008000) { \
 882                                                 TGTPORTSTAT.FctP2IOWcnt[7]++; \
 883                                         } \
 884                                         else { \
 885                                                 /* It must be 0x00004000 */ \
 886                                                 TGTPORTSTAT.FctP2IOWcnt[6]++; \
 887                                         } \
 888                                 } \
 889                                 else { \
 890                                         /* It must be 0x00000300 */ \
 891                                         if (cnt & 0x00000200) { \
 892                                                 TGTPORTSTAT.FctP2IOWcnt[5]++; \
 893                                         } \
 894                                         else { \
 895                                                 /* It must be 0x00000100 */ \
 896                                                 TGTPORTSTAT.FctP2IOWcnt[4]++; \
 897                                         } \
 898                                 } \
 899                         } \
 900                         else { \
 901                                 /* It must be 0x00000e00 */ \
 902                                 if (cnt & 0x00000800) { \
 903                                         TGTPORTSTAT.FctP2IOWcnt[3]++; \
 904                                 } \
 905                                 else { \
 906                                         /* It must be 0x00000600 */ \
 907                                         if (cnt & 0x00000400) { \
 908                                                 TGTPORTSTAT.FctP2IOWcnt[2]++; \
 909                                         } \
 910                                         else { \
 911                                                 /* It must be 0x00000200 */ \
 912                                                 TGTPORTSTAT.FctP2IOWcnt[1]++; \
 913                                         } \
 914                                 } \
 915                         } \
 916                 } \
 917                 else { \
 918                         /* It must be 0x000001ff */ \
 919                         TGTPORTSTAT.FctP2IOWcnt[0]++; \
 920                 } \
 921         } \
 922 }
 923 
 924 typedef struct emlxs_tgtport_stat
 925 {
 926         /* IO counters */
 927         uint64_t        FctP2IOWcnt[MAX_TGTPORT_IOCNT]; /* Writes */
 928         uint64_t        FctP2IORcnt[MAX_TGTPORT_IOCNT]; /* Reads  */
 929         uint64_t        FctIOCmdCnt;                    /* Other, ie TUR */
 930         uint64_t        FctCmdReceived;                 /* total IOs */
 931         uint64_t        FctReadBytes;                   /* total read bytes */
 932         uint64_t        FctWriteBytes;                  /* total write bytes */
 933 
 934         /* IOCB handling counters */
 935         uint64_t        FctEvent;       /* FctStray + FctCompleted */
 936         uint64_t        FctCompleted;   /* FctCmplGood + FctCmplError */
 937         uint64_t        FctCmplGood;
 938 
 939         uint32_t        FctCmplError;
 940         uint32_t        FctStray;
 941 
 942         /* Fct event counters */
 943         uint32_t        FctRcvDropped;
 944         uint32_t        FctOverQDepth;
 945         uint32_t        FctOutstandingIO;
 946         uint32_t        FctFailedPortRegister;
 947         uint32_t        FctPortRegister;
 948         uint32_t        FctPortDeregister;
 949 
 950         uint32_t        FctAbortSent;
 951         uint32_t        FctNoBuffer;
 952         uint32_t        FctScsiStatusErr;
 953         uint32_t        FctScsiQfullErr;
 954         uint32_t        FctScsiResidOver;
 955         uint32_t        FctScsiResidUnder;
 956         uint32_t        FctScsiSenseErr;
 957 
 958         uint32_t        FctFiller1;
 959 } emlxs_tgtport_stat_t;
 960 
 961 #ifdef FCT_IO_TRACE
 962 #define MAX_IO_TRACE    67
 963 typedef struct emlxs_iotrace
 964 {
 965         fct_cmd_t       *fct_cmd;
 966         uint32_t        xri;
 967         uint8_t         marker;  /* 0xff */
 968         uint8_t         trc[MAX_IO_TRACE]; /* trc[0] = index */
 969 } emlxs_iotrace_t;
 970 #endif /* FCT_IO_TRACE */
 971 #endif /* SFCT_SUPPORT */
 972 
 973 
 974 #include <emlxs_fcf.h>
 975 
 976 /*
 977  *     Port Information Data Structure
 978  */
 979 
 980 typedef struct emlxs_port
 981 {
 982         struct emlxs_hba        *hba;
 983 
 984         /* Virtual port management */
 985         struct VPIobj           VPIobj;
 986         uint32_t                vpi;
 987 
 988         uint32_t                flag;
 989 #define EMLXS_PORT_ENABLE               0x00000001
 990 #define EMLXS_PORT_BOUND                0x00000002
 991 
 992 #define EMLXS_PORT_REG_VPI              0x00010000 /* SLI3 */
 993 #define EMLXS_PORT_REG_VPI_CMPL         0x00020000 /* SLI3 */
 994 
 995 #define EMLXS_PORT_IP_UP                0x00000010
 996 #define EMLXS_PORT_CONFIG               0x00000020
 997 #define EMLXS_PORT_RESTRICTED           0x00000040 /* Restrict logins */
 998 #define EMLXS_PORT_FLOGI_CMPL           0x00000080
 999 
1000 #define EMLXS_PORT_RESET_MASK           0x0000FFFF /* Flags to keep */
1001                                                 /* across hard reset */
1002 #define EMLXS_PORT_LINKDOWN_MASK        0xFFFFFF7F /* Flags to keep */
1003                                                 /* across link reset */
1004 
1005         uint32_t                options;
1006 #define EMLXS_OPT_RESTRICT              0x00000001 /* Force restricted */
1007                                                 /* logins */
1008 #define EMLXS_OPT_UNRESTRICT            0x00000002 /* Force Unrestricted */
1009                                                 /* logins */
1010 #define EMLXS_OPT_RESTRICT_MASK         0x00000003
1011 
1012 
1013         /* FC world wide names */
1014         NAME_TYPE               wwnn;
1015         NAME_TYPE               wwpn;
1016         char                    snn[256];
1017         char                    spn[256];
1018 
1019         /* Common service paramters */
1020         SERV_PARM               sparam;
1021         SERV_PARM               fabric_sparam;
1022         SERV_PARM               prev_fabric_sparam;
1023 
1024         /* fc_id management */
1025         uint32_t                did;
1026         uint32_t                prev_did;
1027 
1028         /* support FC_PORT_GET_P2P_INFO only */
1029         uint32_t                rdid;
1030 
1031         /* FC_AL management */
1032         uint8_t                 lip_type;
1033         uint8_t                 alpa_map[128];
1034 
1035         /* Node management */
1036         emlxs_node_t            node_base;
1037         uint32_t                node_count;
1038         krwlock_t               node_rwlock;
1039         emlxs_node_t            *node_table[EMLXS_NUM_HASH_QUES];
1040 
1041         /* Polled packet management */
1042         kcondvar_t              pkt_lock_cv;    /* pkt polling */
1043         kmutex_t                pkt_lock;       /* pkt polling */
1044 
1045         /* ULP */
1046         uint32_t                ulp_statec;
1047         void                    (*ulp_statec_cb) ();    /* Port state change */
1048                                                         /* callback routine */
1049         void                    (*ulp_unsol_cb) ();     /* unsolicited event */
1050                                                         /* callback routine */
1051         opaque_t                ulp_handle;
1052 
1053         /* ULP unsolicited buffers */
1054         kmutex_t                ub_lock;
1055         uint32_t                ub_count;
1056         emlxs_unsol_buf_t       *ub_pool;
1057         uint32_t                ub_post[MAX_CHANNEL];
1058         uint32_t                ub_timer;
1059 
1060         emlxs_ub_priv_t         *ub_wait_head;  /* Unsolicited IO received */
1061                                                 /* before link up */
1062         emlxs_ub_priv_t         *ub_wait_tail;  /* Unsolicited IO received */
1063                                                 /* before link up */
1064 
1065 
1066 #ifdef DHCHAP_SUPPORT
1067         emlxs_port_dhc_t        port_dhc;
1068 #endif  /* DHCHAP_SUPPORT */
1069 
1070         uint16_t                ini_mode;
1071         uint16_t                tgt_mode;
1072 
1073 #ifdef SFCT_SUPPORT
1074 
1075 #define FCT_BUF_COUNT_512               256
1076 #define FCT_BUF_COUNT_8K                128
1077 #define FCT_BUF_COUNT_64K               64
1078 #define FCT_BUF_COUNT_128K              64
1079 #define FCT_MAX_BUCKETS                 16
1080 #define FCT_DMEM_MAX_BUF_SIZE           131072   /* 128K */
1081 #define FCT_DMEM_MAX_BUF_SEGMENT        8388608  /* 8M */
1082 
1083         struct emlxs_fct_dmem_bucket dmem_bucket[FCT_MAX_BUCKETS];
1084 
1085         char                    cfd_name[24];
1086         stmf_port_provider_t    *port_provider;
1087         fct_local_port_t        *fct_port;
1088         uint32_t                fct_flags;
1089 
1090 #define FCT_STATE_PORT_ONLINE           0x00000001
1091 #define FCT_STATE_NOT_ACKED             0x00000002
1092 #define FCT_STATE_LINK_UP               0x00000010
1093 #define FCT_STATE_LINK_UP_ACKED         0x00000020
1094 
1095         emlxs_tgtport_stat_t    fct_stat;
1096 
1097         /* Used to save fct_cmd for deferred unsol ELS commands, except FLOGI */
1098         emlxs_buf_t             *fct_wait_head;
1099         emlxs_buf_t             *fct_wait_tail;
1100 
1101         /* Used to save context for deferred unsol FLOGIs */
1102         fct_flogi_xchg_t        fx;
1103 
1104 #ifdef FCT_IO_TRACE
1105         emlxs_iotrace_t         *iotrace;
1106         uint16_t                iotrace_cnt;
1107         uint16_t                iotrace_index;
1108         kmutex_t                iotrace_mtx;
1109 #endif /* FCT_IO_TRACE */
1110 
1111 #endif /* SFCT_SUPPORT */
1112 
1113 #ifdef SAN_DIAG_SUPPORT
1114         uint8_t                 sd_io_latency_state;
1115 #define SD_INVALID      0x00
1116 #define SD_COLLECTING   0x01
1117 #define SD_STOPPED      0x02
1118 
1119         /* SD event management list */
1120         uint32_t                sd_event_mask;   /* bit-mask */
1121         emlxs_dfc_event_t       sd_events[MAX_DFC_EVENTS];
1122 #endif
1123 
1124 } emlxs_port_t;
1125 
1126 
1127 /* Host Attn reg */
1128 #define FC_HA_REG(_hba)         ((volatile uint32_t *) \
1129                                     ((_hba)->sli.sli3.ha_reg_addr))
1130 
1131 /* Chip Attn reg */
1132 #define FC_CA_REG(_hba)         ((volatile uint32_t *) \
1133                                     ((_hba)->sli.sli3.ca_reg_addr))
1134 
1135 /* Host Status reg */
1136 #define FC_HS_REG(_hba)         ((volatile uint32_t *) \
1137                                     ((_hba)->sli.sli3.hs_reg_addr))
1138 
1139 /* Host Cntl reg */
1140 #define FC_HC_REG(_hba)         ((volatile uint32_t *) \
1141                                     ((_hba)->sli.sli3.hc_reg_addr))
1142 
1143 /* BIU Configuration reg */
1144 #define FC_BC_REG(_hba)         ((volatile uint32_t *) \
1145                                     ((_hba)->sli.sli3.bc_reg_addr))
1146 
1147 /* Used by SBUS adapter */
1148 /* TITAN Cntl reg */
1149 #define FC_SHC_REG(_hba)        ((volatile uint32_t *) \
1150                                     ((_hba)->sli.sli3.shc_reg_addr))
1151 
1152 /* TITAN Status reg */
1153 #define FC_SHS_REG(_hba)        ((volatile uint32_t *) \
1154                                     ((_hba)->sli.sli3.shs_reg_addr))
1155 
1156 /* TITAN Update reg */
1157 #define FC_SHU_REG(_hba)        ((volatile uint32_t *) \
1158                                     ((_hba)->sli.sli3.shu_reg_addr))
1159 
1160 /* MPU Semaphore reg */
1161 #define FC_SEMA_REG(_hba)       ((volatile uint32_t *)\
1162                                     ((_hba)->sli.sli4.MPUEPSemaphore_reg_addr))
1163 
1164 /* Bootstrap Mailbox Doorbell reg */
1165 #define FC_MBDB_REG(_hba)       ((volatile uint32_t *) \
1166                                     ((_hba)->sli.sli4.MBDB_reg_addr))
1167 
1168 /* MQ Doorbell reg */
1169 #define FC_MQDB_REG(_hba)       ((volatile uint32_t *) \
1170                                     ((_hba)->sli.sli4.MQDB_reg_addr))
1171 
1172 /* CQ Doorbell reg */
1173 #define FC_CQDB_REG(_hba)       ((volatile uint32_t *) \
1174                                     ((_hba)->sli.sli4.CQDB_reg_addr))
1175 
1176 /* WQ Doorbell reg */
1177 #define FC_WQDB_REG(_hba)       ((volatile uint32_t *) \
1178                                     ((_hba)->sli.sli4.WQDB_reg_addr))
1179 
1180 /* RQ Doorbell reg */
1181 #define FC_RQDB_REG(_hba)       ((volatile uint32_t *) \
1182                                     ((_hba)->sli.sli4.RQDB_reg_addr))
1183 
1184 
1185 #define FC_SLIM2_MAILBOX(_hba)  ((MAILBOX *)(_hba)->sli.sli3.slim2.virt)
1186 
1187 #define FC_SLIM1_MAILBOX(_hba)  ((MAILBOX *)(_hba)->sli.sli3.slim_addr)
1188 
1189 #define FC_MAILBOX(_hba)        (((_hba)->flag & FC_SLIM2_MODE) ? \
1190         FC_SLIM2_MAILBOX(_hba) : FC_SLIM1_MAILBOX(_hba))
1191 
1192 #define WRITE_CSR_REG(_hba, _regp, _value) ddi_put32(\
1193         (_hba)->sli.sli3.csr_acc_handle, (uint32_t *)(_regp), \
1194         (uint32_t)(_value))
1195 
1196 #define READ_CSR_REG(_hba, _regp) ddi_get32(\
1197         (_hba)->sli.sli3.csr_acc_handle, (uint32_t *)(_regp))
1198 
1199 #define WRITE_SLIM_ADDR(_hba, _regp, _value) ddi_put32(\
1200         (_hba)->sli.sli3.slim_acc_handle, (uint32_t *)(_regp), \
1201         (uint32_t)(_value))
1202 
1203 #define READ_SLIM_ADDR(_hba, _regp) ddi_get32(\
1204         (_hba)->sli.sli3.slim_acc_handle, (uint32_t *)(_regp))
1205 
1206 #define WRITE_SLIM_COPY(_hba, _bufp, _slimp, _wcnt) ddi_rep_put32(\
1207         (_hba)->sli.sli3.slim_acc_handle, (uint32_t *)(_bufp), \
1208         (uint32_t *)(_slimp), (_wcnt), DDI_DEV_AUTOINCR)
1209 
1210 #define READ_SLIM_COPY(_hba, _bufp, _slimp, _wcnt) ddi_rep_get32(\
1211         (_hba)->sli.sli3.slim_acc_handle, (uint32_t *)(_bufp), \
1212         (uint32_t *)(_slimp), (_wcnt), DDI_DEV_AUTOINCR)
1213 
1214 /* Used by SBUS adapter */
1215 #define WRITE_SBUS_CSR_REG(_hba, _regp, _value) ddi_put32(\
1216         (_hba)->sli.sli3.sbus_csr_handle, (uint32_t *)(_regp), \
1217         (uint32_t)(_value))
1218 
1219 #define READ_SBUS_CSR_REG(_hba, _regp) ddi_get32(\
1220         (_hba)->sli.sli3.sbus_csr_handle, (uint32_t *)(_regp))
1221 
1222 #define SBUS_WRITE_FLASH_COPY(_hba, _offset, _value) ddi_put8(\
1223         (_hba)->sli.sli3.sbus_flash_acc_handle, \
1224         (uint8_t *)((volatile uint8_t *)(_hba)->sli.sli3.sbus_flash_addr + \
1225         (_offset)), (uint8_t)(_value))
1226 
1227 #define SBUS_READ_FLASH_COPY(_hba, _offset) ddi_get8(\
1228         (_hba)->sli.sli3.sbus_flash_acc_handle, \
1229         (uint8_t *)((volatile uint8_t *)(_hba)->sli.sli3.sbus_flash_addr + \
1230         (_offset)))
1231 
1232 /* SLI4 registers */
1233 #define WRITE_BAR1_REG(_hba, _regp, _value) ddi_put32(\
1234         (_hba)->sli.sli4.bar1_acc_handle, (uint32_t *)(_regp), \
1235         (uint32_t)(_value))
1236 
1237 #define READ_BAR1_REG(_hba, _regp) ddi_get32(\
1238         (_hba)->sli.sli4.bar1_acc_handle, (uint32_t *)(_regp))
1239 
1240 #define WRITE_BAR2_REG(_hba, _regp, _value) ddi_put32(\
1241         (_hba)->sli.sli4.bar2_acc_handle, (uint32_t *)(_regp), \
1242         (uint32_t)(_value))
1243 
1244 #define READ_BAR2_REG(_hba, _regp) ddi_get32(\
1245         (_hba)->sli.sli4.bar2_acc_handle, (uint32_t *)(_regp))
1246 
1247 
1248 #define EMLXS_STATE_CHANGE(_hba, _state)\
1249 {                                                                       \
1250         mutex_enter(&EMLXS_PORT_LOCK);                                      \
1251         EMLXS_STATE_CHANGE_LOCKED((_hba), (_state));                    \
1252         mutex_exit(&EMLXS_PORT_LOCK);                                       \
1253 }
1254 
1255 /* Used when EMLXS_PORT_LOCK is already held */
1256 #define EMLXS_STATE_CHANGE_LOCKED(_hba, _state)                 \
1257 {                                                                       \
1258         if ((_hba)->state != (_state))                                       \
1259         {                                                               \
1260                 uint32_t _st = _state;                                  \
1261                 EMLXS_MSGF(EMLXS_CONTEXT,                               \
1262                         &emlxs_state_msg, "%s --> %s",                   \
1263                         emlxs_ffstate_xlate((_hba)->state),          \
1264                         emlxs_ffstate_xlate(_state));                   \
1265                         (_hba)->state = (_state);                    \
1266                 if ((_st) == FC_ERROR)                                  \
1267                 {                                                       \
1268                         (_hba)->flag |= FC_HARDWARE_ERROR;           \
1269                 }                                                       \
1270         }                                                               \
1271 }
1272 
1273 #ifdef FMA_SUPPORT
1274 #define EMLXS_CHK_ACC_HANDLE(_hba, _acc) \
1275         if (emlxs_fm_check_acc_handle(_hba, _acc) != DDI_FM_OK) { \
1276                 EMLXS_MSGF(EMLXS_CONTEXT, \
1277                     &emlxs_invalid_access_handle_msg, NULL); \
1278         }
1279 #endif  /* FMA_SUPPORT */
1280 
1281 /*
1282  * This is the HBA control area for the adapter
1283  */
1284 
1285 #ifdef MODSYM_SUPPORT
1286 
1287 typedef struct emlxs_modsym
1288 {
1289         ddi_modhandle_t  mod_fctl;      /* For Leadville */
1290 
1291         /* Leadville (fctl) */
1292         int             (*fc_fca_attach)(dev_info_t *, fc_fca_tran_t *);
1293         int             (*fc_fca_detach)(dev_info_t *);
1294         int             (*fc_fca_init)(struct dev_ops *);
1295 
1296 #ifdef SFCT_SUPPORT
1297         uint32_t        fct_modopen;
1298         uint32_t        reserved;  /* Padding for alignment */
1299 
1300         ddi_modhandle_t  mod_fct;       /* For Comstar */
1301         ddi_modhandle_t  mod_stmf;      /* For Comstar */
1302 
1303         /* Comstar (fct) */
1304         void*   (*fct_alloc)(fct_struct_id_t, int, int);
1305         void    (*fct_free)(void *);
1306         void*   (*fct_scsi_task_alloc)(void *, uint16_t, uint32_t, uint8_t *,
1307                         uint16_t, uint16_t);
1308         int     (*fct_register_local_port)(fct_local_port_t *);
1309         void    (*fct_deregister_local_port)(fct_local_port_t *);
1310         void    (*fct_handle_event)(fct_local_port_t *, int, uint32_t, caddr_t);
1311         void    (*fct_post_rcvd_cmd)(fct_cmd_t *, stmf_data_buf_t *);
1312         void    (*fct_ctl)(void *, int, void *);
1313         void    (*fct_queue_cmd_for_termination)(fct_cmd_t *, fct_status_t);
1314         void    (*fct_send_response_done)(fct_cmd_t *, fct_status_t, uint32_t);
1315         void    (*fct_send_cmd_done)(fct_cmd_t *, fct_status_t, uint32_t);
1316         void    (*fct_scsi_data_xfer_done)(fct_cmd_t *, stmf_data_buf_t *,
1317                         uint32_t);
1318         fct_status_t    (*fct_port_shutdown)
1319                                 (fct_local_port_t *, uint32_t, char *);
1320         fct_status_t    (*fct_port_initialize)
1321                                 (fct_local_port_t *, uint32_t, char *);
1322         void            (*fct_cmd_fca_aborted)
1323                                 (fct_cmd_t *, fct_status_t, int);
1324         fct_status_t    (*fct_handle_rcvd_flogi)
1325                                 (fct_local_port_t *, fct_flogi_xchg_t *);
1326 
1327         /* Comstar (stmf) */
1328         void*  (*stmf_alloc)(stmf_struct_id_t, int, int);
1329         void   (*stmf_free)(void *);
1330         void    (*stmf_deregister_port_provider) (stmf_port_provider_t *);
1331         int     (*stmf_register_port_provider) (stmf_port_provider_t *);
1332 #endif /* SFCT_SUPPORT */
1333 } emlxs_modsym_t;
1334 extern emlxs_modsym_t emlxs_modsym;
1335 
1336 #define MODSYM(_f)      emlxs_modsym._f
1337 
1338 #else
1339 
1340 #define MODSYM(_f)      _f
1341 
1342 #endif /* MODSYM_SUPPORT */
1343 
1344 
1345 
1346 typedef struct RPIHdrTmplate
1347 {
1348         uint32_t        Word[16];  /* 64 bytes */
1349 } RPIHdrTmplate_t;
1350 
1351 
1352 typedef struct EQ_DESC
1353 {
1354         uint16_t        host_index;
1355         uint16_t        max_index;
1356         uint16_t        qid;
1357         uint16_t        msix_vector;
1358         kmutex_t        lastwq_lock;
1359         uint16_t        lastwq;
1360         MBUF_INFO       addr;
1361 } EQ_DESC_t;
1362 
1363 
1364 typedef struct CQ_DESC
1365 {
1366         uint16_t        host_index;
1367         uint16_t        max_index;
1368         uint16_t        qid;
1369         uint16_t        eqid;
1370         uint16_t        type;
1371 #define EMLXS_CQ_TYPE_GROUP1    1  /* associated with a MQ and async events */
1372 #define EMLXS_CQ_TYPE_GROUP2    2  /* associated with a WQ and RQ */
1373         uint16_t        rsvd;
1374 
1375         MBUF_INFO       addr;
1376         CHANNEL         *channelp; /* ptr to CHANNEL associated with CQ */
1377 
1378 } CQ_DESC_t;
1379 
1380 
1381 typedef struct WQ_DESC
1382 {
1383         uint16_t        host_index;
1384         uint16_t        max_index;
1385         uint16_t        port_index;
1386         uint16_t        release_depth;
1387 #define WQE_RELEASE_DEPTH       (8 * EMLXS_NUM_WQ_PAGES)
1388         uint16_t        qid;
1389         uint16_t        cqid;
1390         MBUF_INFO       addr;
1391 } WQ_DESC_t;
1392 
1393 
1394 typedef struct RQ_DESC
1395 {
1396         uint16_t        host_index;
1397         uint16_t        max_index;
1398         uint16_t        qid;
1399         uint16_t        cqid;
1400 
1401         MBUF_INFO       addr;
1402         MBUF_INFO       rqb[RQ_DEPTH];
1403 
1404         kmutex_t        lock;
1405 
1406 } RQ_DESC_t;
1407 
1408 
1409 typedef struct RXQ_DESC
1410 {
1411         kmutex_t        lock;
1412         emlxs_queue_t   active;
1413 
1414 } RXQ_DESC_t;
1415 
1416 
1417 typedef struct MQ_DESC
1418 {
1419         uint16_t        host_index;
1420         uint16_t        max_index;
1421         uint16_t        qid;
1422         uint16_t        cqid;
1423         MBUF_INFO       addr;
1424 } MQ_DESC_t;
1425 
1426 
1427 /* Define the number of queues the driver will be using */
1428 #define EMLXS_MAX_EQS   EMLXS_MSI_MAX_INTRS
1429 #define EMLXS_MAX_WQS   EMLXS_MSI_MAX_INTRS
1430 #define EMLXS_MAX_RQS   2       /* ONLY 1 pair is allowed */
1431 #define EMLXS_MAX_MQS   1
1432 
1433 /* One CQ for each WQ & (RQ pair) plus one for the MQ */
1434 #define EMLXS_MAX_CQS   (EMLXS_MAX_WQS + (EMLXS_MAX_RQS/2) + 1)
1435 
1436 /* The First CQ created is ALWAYS for mbox / event handling */
1437 #define EMLXS_CQ_MBOX           0
1438 
1439 /* The Second CQ created is ALWAYS for unsol rcv handling */
1440 /* At this time we are allowing ONLY 1 pair of RQs */
1441 #define EMLXS_CQ_RCV            1
1442 
1443 /* The remaining CQs are for WQ completions */
1444 #define EMLXS_CQ_OFFSET_WQ      2
1445 
1446 
1447 /* FCFI RQ Configuration */
1448 #define EMLXS_FCFI_RQ0_INDEX    0
1449 #define EMLXS_FCFI_RQ0_RMASK    0 /* match all */
1450 #define EMLXS_FCFI_RQ0_RCTL     0 /* match all */
1451 #define EMLXS_FCFI_RQ0_TMASK    0 /* match all */
1452 #define EMLXS_FCFI_RQ0_TYPE     0 /* match all */
1453 
1454 /* Define the maximum value for a Queue Id */
1455 #define EMLXS_MAX_EQ_IDS        256
1456 #define EMLXS_MAX_CQ_IDS        1024
1457 #define EMLXS_MAX_WQ_IDS        1024
1458 #define EMLXS_MAX_RQ_IDS        4
1459 
1460 #define EMLXS_RXQ_ELS           0
1461 #define EMLXS_RXQ_CT            1
1462 #define EMLXS_MAX_RXQS          2
1463 
1464 #define PCI_CONFIG_SIZE   0x80
1465 
1466 typedef struct emlxs_sli3
1467 {
1468         /* SLIM management */
1469         MATCHMAP        slim2;
1470 
1471         /* HBQ management */
1472         uint32_t        hbq_count;      /* Total number of HBQs */
1473                                         /* configured */
1474         HBQ_INIT_t      hbq_table[EMLXS_NUM_HBQ];
1475 
1476         /* Adapter memory management */
1477         caddr_t         csr_addr;
1478         caddr_t         slim_addr;
1479         ddi_acc_handle_t csr_acc_handle;
1480         ddi_acc_handle_t slim_acc_handle;
1481 
1482         /* SBUS adapter management */
1483         caddr_t         sbus_flash_addr;        /* Virt addr of R/W */
1484                                                 /* Flash */
1485         caddr_t         sbus_core_addr;         /* Virt addr of TITAN */
1486                                                 /* CORE */
1487         caddr_t         sbus_csr_addr;          /* Virt addr of TITAN */
1488                                                 /* CSR */
1489         ddi_acc_handle_t sbus_flash_acc_handle;
1490         ddi_acc_handle_t sbus_core_acc_handle;
1491         ddi_acc_handle_t sbus_csr_handle;
1492 
1493         /* SLI 2/3 Adapter register management */
1494         uint32_t        *bc_reg_addr;   /* virtual offset for BIU */
1495                                         /* config reg */
1496         uint32_t        *ha_reg_addr;   /* virtual offset for host */
1497                                         /* attn reg */
1498         uint32_t        *hc_reg_addr;   /* virtual offset for host */
1499                                         /* ctl reg */
1500         uint32_t        *ca_reg_addr;   /* virtual offset for FF */
1501                                         /* attn reg */
1502         uint32_t        *hs_reg_addr;   /* virtual offset for */
1503                                         /* status reg */
1504         uint32_t        *shc_reg_addr;  /* virtual offset for SBUS */
1505                                         /* Ctrl reg */
1506         uint32_t        *shs_reg_addr;  /* virtual offset for SBUS */
1507                                         /* Status reg */
1508         uint32_t        *shu_reg_addr;  /* virtual offset for SBUS */
1509                                         /* Update reg */
1510         uint16_t        hgp_ring_offset;
1511         uint16_t        hgp_hbq_offset;
1512         uint16_t        iocb_cmd_size;
1513         uint16_t        iocb_rsp_size;
1514         uint32_t        hc_copy;        /* local copy of HC register */
1515 
1516         /* Ring management */
1517         uint32_t        ring_count;
1518         emlxs_ring_t    ring[MAX_RINGS];
1519         kmutex_t        ring_cmd_lock[MAX_RINGS];
1520         uint8_t         ring_masks[4];  /* number of masks/rings used */
1521         uint8_t         ring_rval[6];
1522         uint8_t         ring_rmask[6];
1523         uint8_t         ring_tval[6];
1524         uint8_t         ring_tmask[6];
1525 
1526         /* Protected by EMLXS_FCTAB_LOCK */
1527 #ifdef EMLXS_SPARC
1528         MEMSEG          fcp_bpl_seg;
1529         MATCHMAP        **fcp_bpl_table; /* iotag table for */
1530                                         /* bpl buffers */
1531 #endif  /* EMLXS_SPARC */
1532         uint32_t        mem_bpl_size;
1533 } emlxs_sli3_t;
1534 
1535 typedef struct emlxs_sli4
1536 {
1537         MATCHMAP        bootstrapmb;
1538         caddr_t         bar1_addr;
1539         caddr_t         bar2_addr;
1540         ddi_acc_handle_t bar1_acc_handle;
1541         ddi_acc_handle_t bar2_acc_handle;
1542 
1543         /* SLI4 Adapter register management */
1544         uint32_t        *MPUEPSemaphore_reg_addr;
1545         uint32_t        *MBDB_reg_addr;
1546 
1547         uint32_t        *CQDB_reg_addr;
1548         uint32_t        *MQDB_reg_addr;
1549         uint32_t        *WQDB_reg_addr;
1550         uint32_t        *RQDB_reg_addr;
1551 
1552         uint32_t        flag;
1553 #define EMLXS_SLI4_INTR_ENABLED         0x00000001
1554 #define EMLXS_SLI4_HW_ERROR             0x00000002
1555 #define EMLXS_SLI4_DOWN_LINK            0x00000004
1556 
1557         uint16_t        XRICount;
1558         uint16_t        XRIBase;
1559         uint16_t        RPICount;
1560         uint16_t        RPIBase;
1561         uint16_t        VPICount;
1562         uint16_t        VPIBase;
1563         uint16_t        VFICount;
1564         uint16_t        VFIBase;
1565         uint16_t        FCFICount;
1566 
1567         kmutex_t        fcf_lock;
1568         FCFTable_t      fcftab;
1569         VFIobj_t        *VFI_table;
1570 
1571         /* Save Config Region 23 info */
1572         tlv_fcoe_t      cfgFCOE;
1573         tlv_fcfconnectlist_t    cfgFCF;
1574 
1575         MBUF_INFO       slim2;
1576         MBUF_INFO       dump_region;
1577 #define EMLXS_DUMP_REGION_SIZE  1024
1578 
1579         RPIobj_t        *RPIp;
1580         MBUF_INFO       HeaderTmplate;
1581         XRIobj_t        *XRIp;
1582 
1583         /* Double linked list for available XRIs */
1584         XRIobj_t        *XRIfree_f;
1585         XRIobj_t        *XRIfree_b;
1586         uint32_t        xrif_count;
1587         uint32_t        mem_sgl_size;
1588 
1589         /* Double linked list for XRIs in use */
1590         XRIobj_t        *XRIinuse_f;
1591         XRIobj_t        *XRIinuse_b;
1592         uint32_t        xria_count;
1593 
1594         kmutex_t        que_lock[EMLXS_MAX_WQS];
1595         EQ_DESC_t       eq[EMLXS_MAX_EQS];
1596         CQ_DESC_t       cq[EMLXS_MAX_CQS];
1597         WQ_DESC_t       wq[EMLXS_MAX_WQS];
1598         RQ_DESC_t       rq[EMLXS_MAX_RQS];
1599         MQ_DESC_t       mq;
1600 
1601         /* Used to map a queue ID to a queue DESC_t */
1602         uint16_t        eq_map[EMLXS_MAX_EQ_IDS];
1603         uint16_t        cq_map[EMLXS_MAX_CQ_IDS];
1604         uint16_t        wq_map[EMLXS_MAX_WQ_IDS];
1605         uint16_t        rq_map[EMLXS_MAX_RQ_IDS];
1606 
1607         RXQ_DESC_t      rxq[EMLXS_MAX_RXQS];
1608 
1609         uint32_t        ue_mask_lo;
1610         uint32_t        ue_mask_hi;
1611 
1612 } emlxs_sli4_t;
1613 
1614 
1615 typedef struct emlxs_sli_api
1616 {
1617         int             (*sli_map_hdw)();
1618         void            (*sli_unmap_hdw)();
1619         int32_t         (*sli_online)();
1620         void            (*sli_offline)();
1621         uint32_t        (*sli_hba_reset)();
1622         void            (*sli_hba_kill)();
1623         void            (*sli_issue_iocb_cmd)();
1624         uint32_t        (*sli_issue_mbox_cmd)();
1625         uint32_t        (*sli_prep_fct_iocb)();
1626         uint32_t        (*sli_prep_fcp_iocb)();
1627         uint32_t        (*sli_prep_ip_iocb)();
1628         uint32_t        (*sli_prep_els_iocb)();
1629         uint32_t        (*sli_prep_ct_iocb)();
1630         void            (*sli_poll_intr)();
1631         int32_t         (*sli_intx_intr)();
1632         uint32_t        (*sli_msi_intr)();
1633         void            (*sli_disable_intr)();
1634         void            (*sli_timer)();
1635         void            (*sli_poll_erratt)();
1636 
1637 } emlxs_sli_api_t;
1638 
1639 
1640 typedef struct emlxs_hba
1641 {
1642         dev_info_t      *dip;
1643         int32_t         emlxinst;
1644         int32_t         ddiinst;
1645         uint8_t         pci_function_number;
1646         uint8_t         pci_device_number;
1647         uint8_t         pci_bus_number;
1648         uint8_t         pci_cap_offset[PCI_CAP_MAX_PTR];
1649 
1650 #ifdef FMA_SUPPORT
1651         int32_t         fm_caps;        /* FMA capabilities */
1652 #endif  /* FMA_SUPPORT */
1653         fc_fca_tran_t   *fca_tran;
1654 
1655         /* DMA attributes */
1656         ddi_dma_attr_t  dma_attr;
1657         ddi_dma_attr_t  dma_attr_ro;
1658         ddi_dma_attr_t  dma_attr_1sg;
1659         ddi_dma_attr_t  dma_attr_fcip_rsp;
1660 
1661         /* HBA Info */
1662         emlxs_model_t   model_info;
1663         emlxs_vpd_t     vpd;    /* vital product data */
1664         NAME_TYPE       wwnn;
1665         NAME_TYPE       wwpn;
1666         char            snn[256];
1667         char            spn[256];
1668         PROG_ID         load_list[MAX_LOAD_ENTRY];
1669         WAKE_UP_PARMS   wakeup_parms;
1670         uint32_t        max_nodes;
1671         uint32_t        io_throttle;
1672         uint32_t        io_active;
1673         uint32_t        bus_type;
1674 #define PCI_FC          0
1675 #define SBUS_FC         1
1676 
1677         /* Link management */
1678         uint32_t        link_event_tag;
1679         uint8_t         topology;
1680         uint8_t         linkspeed;
1681         uint16_t        qos_linkspeed;
1682         uint32_t        linkup_wait_flag;
1683         kcondvar_t      linkup_lock_cv;
1684         kmutex_t        linkup_lock;
1685 
1686         /* Memory Pool management */
1687         emlxs_memseg_t  memseg[FC_MAX_SEG];     /* memory for buffer */
1688                                                         /* structures */
1689         kmutex_t        memget_lock;    /* locks all memory pools get */
1690         kmutex_t        memput_lock;    /* locks all memory pools put */
1691 
1692         /* Fibre Channel Service Parameters */
1693         SERV_PARM       sparam;
1694         uint32_t        fc_edtov;       /* E_D_TOV timer value */
1695         uint32_t        fc_arbtov;      /* ARB_TOV timer value */
1696         uint32_t        fc_ratov;       /* R_A_TOV timer value */
1697         uint32_t        fc_rttov;       /* R_T_TOV timer value */
1698         uint32_t        fc_altov;       /* AL_TOV timer value */
1699         uint32_t        fc_crtov;       /* C_R_TOV timer value */
1700         uint32_t        fc_citov;       /* C_I_TOV timer value */
1701 
1702         /* Adapter State management */
1703         int32_t         state;
1704 #define FC_ERROR                0x01    /* Adapter shutdown */
1705 #define FC_KILLED               0x02    /* Adapter interlocked/killed */
1706 #define FC_WARM_START           0x03    /* Adapter reset, but not restarted */
1707 #define FC_INIT_START           0x10    /* Adapter restarted */
1708 #define FC_INIT_NVPARAMS        0x11
1709 #define FC_INIT_REV             0x12
1710 #define FC_INIT_CFGPORT         0x13
1711 #define FC_INIT_CFGRING         0x14
1712 #define FC_INIT_INITLINK        0x15
1713 #define FC_LINK_DOWN            0x20
1714 #define FC_LINK_DOWN_PERSIST    0x21
1715 #define FC_LINK_UP              0x30
1716 #define FC_CLEAR_LA             0x31
1717 #define FC_READY                0x40
1718 
1719         uint32_t        flag;
1720 #define FC_ONLINING_MODE        0x00000001
1721 #define FC_ONLINE_MODE          0x00000002
1722 #define FC_OFFLINING_MODE       0x00000004
1723 #define FC_OFFLINE_MODE         0x00000008
1724 
1725 #define FC_NPIV_ENABLED         0x00000010      /* NPIV enabled on adapter    */
1726 #define FC_NPIV_SUPPORTED       0x00000020      /* NPIV supported on fabric   */
1727 #define FC_NPIV_UNSUPPORTED     0x00000040      /* NPIV unsupported on fabric */
1728 #define FC_NPIV_LINKUP          0x00000100      /* NPIV enabled, supported, */
1729                                                 /* and link is ready */
1730 #define FC_NPIV_DELAY_REQUIRED  0x00000200      /* Delay issuing FLOGI/FDISC */
1731                                                 /* and NameServer cmds */
1732 
1733 #define FC_BOOTSTRAPMB_INIT     0x00000400
1734 #define FC_FIP_SUPPORTED        0x00000800      /* FIP supported */
1735 
1736 #define FC_FABRIC_ATTACHED      0x00001000
1737 #define FC_PT_TO_PT             0x00002000
1738 #define FC_BYPASSED_MODE        0x00004000
1739 #define FC_MENLO_MODE           0x00008000      /* Menlo maintenance mode */
1740 
1741 #define FC_DUMP_SAFE            0x00010000      /* Safe to DUMP */
1742 #define FC_DUMP_ACTIVE          0x00020000      /* DUMP in progress */
1743 #define FC_NEW_FABRIC           0x00040000
1744 
1745 #define FC_SLIM2_MODE           0x00100000      /* SLIM in host memory */
1746 #define FC_INTERLOCKED          0x00200000
1747 #define FC_HBQ_ENABLED          0x00400000
1748 #define FC_ASYNC_EVENTS         0x00800000
1749 
1750 #define FC_ILB_MODE             0x01000000
1751 #define FC_ELB_MODE             0x02000000
1752 #define FC_LOOPBACK_MODE        0x03000000      /* Loopback Mode Mask */
1753 #define FC_DUMP                 0x04000000      /* DUMP in progress */
1754 #define FC_SHUTDOWN             0x08000000      /* SHUTDOWN in progress */
1755 
1756 #define FC_OVERTEMP_EVENT       0x10000000      /* FC_ERROR reason: */
1757                                                 /* over temperature event */
1758 #define FC_MBOX_TIMEOUT         0x20000000      /* FC_ERROR reason: */
1759                                                 /* mailbox timeout event */
1760 #define FC_DMA_CHECK_ERROR      0x40000000      /* Shared memory (slim,..) */
1761                                                 /* DMA handle went bad */
1762 #define FC_HARDWARE_ERROR       0x80000000      /* FC_ERROR state triggered */
1763 
1764 #define FC_RESET_MASK           0x00030C1F      /* Bits to protect during */
1765                                                 /* a hard reset */
1766 #define FC_LINKDOWN_MASK        0xFFF30C1F      /* Bits to protect during */
1767                                                 /* a linkdown */
1768 
1769         uint32_t fw_timer;
1770         uint32_t fw_flag;
1771 #define FW_UPDATE_NEEDED        0x00000001
1772 #define FW_UPDATE_KERNEL        0x00000002
1773 
1774         uint32_t temperature;                   /* Last reported temperature */
1775 
1776         /* SBUS adapter management */
1777         caddr_t         sbus_pci_addr;          /* Virt addr of TITAN */
1778                                                 /* pci config */
1779         ddi_acc_handle_t sbus_pci_handle;
1780 
1781         /* PCI BUS adapter management */
1782         caddr_t         pci_addr;
1783         ddi_acc_handle_t pci_acc_handle;
1784 
1785         uint32_t        sli_mode;
1786 #define EMLXS_HBA_SLI1_MODE     1
1787 #define EMLXS_HBA_SLI2_MODE     2
1788 #define EMLXS_HBA_SLI3_MODE     3
1789 #define EMLXS_HBA_SLI4_MODE     4
1790 
1791         /* SLI private data */
1792         union {
1793                 emlxs_sli3_t sli3;
1794                 emlxs_sli4_t sli4;
1795         } sli;
1796 
1797         /* SLI API entry point routines */
1798         emlxs_sli_api_t sli_api;
1799 
1800         uint32_t        io_poll_count;  /* Number of poll commands */
1801                                         /* in progress */
1802 
1803         /* IO Completion management */
1804         uint32_t        iodone_count;   /* Number of IO's on done Q */
1805         /* Protected by EMLXS_PORT_LOCK  */
1806         emlxs_buf_t     *iodone_list;   /* fc_packet being deferred */
1807         emlxs_buf_t     *iodone_tail;   /* fc_packet being deferred */
1808         emlxs_thread_t  iodone_thread;
1809         emlxs_thread_t  *spawn_thread_head;
1810         emlxs_thread_t  *spawn_thread_tail;
1811         kmutex_t        spawn_lock;
1812         uint32_t        spawn_open;
1813 
1814         /* IO Channel management */
1815         int32_t         chan_count;
1816         emlxs_channel_t chan[MAX_CHANNEL];
1817         kmutex_t        channel_tx_lock;
1818         uint8_t         channel_fcp;    /* Default channel to use for FCP IO */
1819 #define CHANNEL_FCT channel_fcp
1820         uint8_t         channel_ip;     /* Default channel to use for IP IO */
1821         uint8_t         channel_els;    /* Default channel to use for ELS IO */
1822         uint8_t         channel_ct;     /* Default channel to use for CT IO */
1823 
1824         /* IOTag management */
1825         emlxs_buf_t     **fc_table;     /* sc_buf pointers indexed by */
1826                                         /* iotag */
1827         uint16_t        fc_iotag;       /* used to identify I/Os */
1828         uint16_t        fc_oor_iotag;   /* OutOfRange (fc_table) iotags */
1829                                         /* typically used for Abort/close */
1830 #define EMLXS_MAX_ABORT_TAG     0x7fff
1831         uint16_t        max_iotag;      /* ALL IOCBs except aborts */
1832         kmutex_t        iotag_lock;
1833         uint32_t        io_count;               /* No of IO holding */
1834                                                 /* regular iotag */
1835         uint32_t        channel_tx_count;       /* No of IO on tx Q */
1836 
1837         /* Mailbox Management */
1838         uint32_t        mbox_queue_flag;
1839         emlxs_queue_t   mbox_queue;
1840         void            *mbox_mqe;      /* active mbox mqe */
1841         void            *mbox_mbq;      /* active MAILBOXQ */
1842         kcondvar_t      mbox_lock_cv;   /* MBX_SLEEP */
1843         kmutex_t        mbox_lock;      /* MBX_SLEEP */
1844         uint32_t        mbox_timer;
1845 
1846         /* Interrupt management */
1847         void            *intr_arg;
1848         uint32_t        intr_unclaimed;
1849         uint32_t        intr_autoClear;
1850         uint32_t        intr_flags;
1851 #define EMLXS_INTX_INITED       0x0001
1852 #define EMLXS_INTX_ADDED        0x0002
1853 #define EMLXS_MSI_ENABLED       0x0010
1854 #define EMLXS_MSI_INITED        0x0020
1855 #define EMLXS_MSI_ADDED         0x0040
1856 #define EMLXS_INTR_INITED       (EMLXS_INTX_INITED|EMLXS_MSI_INITED)
1857 #define EMLXS_INTR_ADDED        (EMLXS_INTX_ADDED|EMLXS_MSI_ADDED)
1858 
1859 #ifdef MSI_SUPPORT
1860         ddi_intr_handle_t *intr_htable;
1861         uint32_t        *intr_pri;
1862         int32_t         *intr_cap;
1863         uint32_t        intr_count;
1864         uint32_t        intr_type;
1865         uint32_t        intr_cond;
1866         uint32_t        intr_map[EMLXS_MSI_MAX_INTRS];
1867         uint32_t        intr_mask;
1868 
1869         kmutex_t        msiid_lock; /* for last_msiid */
1870         int             last_msiid;
1871 
1872         kmutex_t        intr_lock[EMLXS_MSI_MAX_INTRS];
1873         int                     chan2msi[MAX_CHANNEL];
1874                                         /* Index is the channel id */
1875         int                     msi2chan[EMLXS_MSI_MAX_INTRS];
1876                                         /* Index is the MSX-X msg id */
1877 #endif  /* MSI_SUPPORT */
1878 
1879         uint32_t        heartbeat_timer;
1880         uint32_t        heartbeat_flag;
1881         uint32_t        heartbeat_active;
1882 
1883         /* IOCTL management */
1884         kmutex_t        ioctl_lock;
1885         uint32_t        ioctl_flags;
1886 #define EMLXS_OPEN              0x00000001
1887 #define EMLXS_OPEN_EXCLUSIVE    0x00000002
1888 
1889         /* Timer management */
1890         kcondvar_t      timer_lock_cv;
1891         kmutex_t        timer_lock;
1892         timeout_id_t    timer_id;
1893         uint32_t        timer_tics;
1894         uint32_t        timer_flags;
1895 #define EMLXS_TIMER_STARTED     0x0000001
1896 #define EMLXS_TIMER_BUSY        0x0000002
1897 #define EMLXS_TIMER_KILL        0x0000004
1898 #define EMLXS_TIMER_ENDED       0x0000008
1899 
1900         /* Misc Timers */
1901         uint32_t        linkup_timer;
1902         uint32_t        discovery_timer;
1903         uint32_t        pkt_timer;
1904 
1905         /* Power Management */
1906         uint32_t        pm_state;
1907         /* pm_state */
1908 #define EMLXS_PM_IN_ATTACH      0x00000001
1909 #define EMLXS_PM_IN_DETACH      0x00000002
1910 #define EMLXS_PM_IN_SOL_CB      0x00000010
1911 #define EMLXS_PM_IN_UNSOL_CB    0x00000020
1912 #define EMLXS_PM_IN_LINK_RESET  0x00000100
1913 #define EMLXS_PM_IN_HARD_RESET  0x00000200
1914 #define EMLXS_PM_SUSPENDED      0x01000000
1915 
1916         uint32_t        pm_level;
1917         /* pm_level */
1918 #define EMLXS_PM_ADAPTER_DOWN   0
1919 #define EMLXS_PM_ADAPTER_UP     1
1920 
1921         uint32_t        pm_busy;
1922         kmutex_t        pm_lock;
1923         uint8_t         pm_config[PCI_CONFIG_SIZE];
1924 #ifdef IDLE_TIMER
1925         uint32_t        pm_idle_timer;
1926         uint32_t        pm_active;      /* Only used by timer */
1927 #endif  /* IDLE_TIMER */
1928 
1929         /* Loopback management */
1930         uint32_t        loopback_tics;
1931         void            *loopback_pkt;
1932 
1933         /* Event management */
1934         emlxs_event_queue_t event_queue;
1935         uint32_t        event_mask;
1936         uint32_t        event_timer;
1937         emlxs_dfc_event_t dfc_event[MAX_DFC_EVENTS];
1938         emlxs_hba_event_t hba_event;
1939 
1940         /* Parameter management */
1941         emlxs_config_t  config[NUM_CFG_PARAM];
1942 
1943         /* Driver stat management */
1944         kstat_t         *kstat;
1945         emlxs_stats_t   stats;
1946 
1947         /* Log management */
1948         emlxs_msg_log_t log;
1949 
1950         /* Port managment */
1951         uint32_t        vpi_base;
1952         uint32_t        vpi_max;
1953         uint32_t        vpi_high;
1954         uint32_t        num_of_ports;
1955 
1956         kmutex_t        port_lock;      /* locks port, nodes, rings */
1957         emlxs_port_t    port[MAX_VPORTS + 1];   /* port specific info */
1958                                                 /* Last one is for */
1959                                                 /* NPIV ready test */
1960 
1961 #ifdef DHCHAP_SUPPORT
1962         kmutex_t        dhc_lock;
1963         kmutex_t        auth_lock;
1964         emlxs_auth_cfg_t        auth_cfg;       /* Default auth_cfg. */
1965                                                 /* Points to list of entries. */
1966                                                 /* Protected by auth_lock */
1967         uint32_t        auth_cfg_count;
1968         emlxs_auth_key_t        auth_key;       /* Default auth_key. */
1969                                                 /* Points to list of entries. */
1970                                                 /* Protected by auth_lock */
1971         uint32_t        auth_key_count;
1972         uint32_t        rdn_flag;
1973 #endif  /* DHCHAP_SUPPORT */
1974 
1975         uint16_t        ini_mode;
1976         uint16_t        tgt_mode;
1977 
1978 #ifdef TEST_SUPPORT
1979         uint32_t        underrun_counter;
1980 #endif /* TEST_SUPPORT */
1981 
1982 #ifdef MODFW_SUPPORT
1983         ddi_modhandle_t fw_modhandle;
1984 #endif /* MODFW_SUPPORT */
1985 
1986 #ifdef DUMP_SUPPORT
1987         emlxs_file_t    dump_txtfile;
1988         emlxs_file_t    dump_dmpfile;
1989         emlxs_file_t    dump_ceefile;
1990         kmutex_t        dump_lock;
1991 #define EMLXS_DUMP_LOCK         hba->dump_lock
1992 #define EMLXS_TXT_FILE          1
1993 #define EMLXS_DMP_FILE          2
1994 #define EMLXS_CEE_FILE          3
1995 
1996 #define EMLXS_DRV_DUMP          0
1997 #define EMLXS_TEMP_DUMP         1
1998 #define EMLXS_USER_DUMP         2
1999 
2000 #endif /* DUMP_SUPPORT */
2001 
2002 } emlxs_hba_t;
2003 
2004 #define EMLXS_SLI_MAP_HDW               (hba->sli_api.sli_map_hdw)
2005 #define EMLXS_SLI_UNMAP_HDW             (hba->sli_api.sli_unmap_hdw)
2006 #define EMLXS_SLI_ONLINE                (hba->sli_api.sli_online)
2007 #define EMLXS_SLI_OFFLINE               (hba->sli_api.sli_offline)
2008 #define EMLXS_SLI_HBA_RESET             (hba->sli_api.sli_hba_reset)
2009 #define EMLXS_SLI_HBA_KILL              (hba->sli_api.sli_hba_kill)
2010 #define EMLXS_SLI_ISSUE_IOCB_CMD        (hba->sli_api.sli_issue_iocb_cmd)
2011 #define EMLXS_SLI_ISSUE_MBOX_CMD        (hba->sli_api.sli_issue_mbox_cmd)
2012 #define EMLXS_SLI_PREP_FCT_IOCB         (hba->sli_api.sli_prep_fct_iocb)
2013 #define EMLXS_SLI_PREP_FCP_IOCB         (hba->sli_api.sli_prep_fcp_iocb)
2014 #define EMLXS_SLI_PREP_IP_IOCB          (hba->sli_api.sli_prep_ip_iocb)
2015 #define EMLXS_SLI_PREP_ELS_IOCB         (hba->sli_api.sli_prep_els_iocb)
2016 #define EMLXS_SLI_PREP_CT_IOCB          (hba->sli_api.sli_prep_ct_iocb)
2017 #define EMLXS_SLI_POLL_INTR             (hba->sli_api.sli_poll_intr)
2018 #define EMLXS_SLI_INTX_INTR             (hba->sli_api.sli_intx_intr)
2019 #define EMLXS_SLI_MSI_INTR              (hba->sli_api.sli_msi_intr)
2020 #define EMLXS_SLI_DISABLE_INTR          (hba->sli_api.sli_disable_intr)
2021 #define EMLXS_SLI_TIMER                 (hba->sli_api.sli_timer)
2022 #define EMLXS_SLI_POLL_ERRATT           (hba->sli_api.sli_poll_erratt)
2023 
2024 #define EMLXS_HBA_T  1  /* flag emlxs_hba_t is already typedefed */
2025 
2026 #ifdef MSI_SUPPORT
2027 #define EMLXS_INTR_INIT(_hba, _m)               emlxs_msi_init(_hba, _m)
2028 #define EMLXS_INTR_UNINIT(_hba)                 emlxs_msi_uninit(_hba)
2029 #define EMLXS_INTR_ADD(_hba)                    emlxs_msi_add(_hba)
2030 #define EMLXS_INTR_REMOVE(_hba)                 emlxs_msi_remove(_hba)
2031 #else
2032 #define EMLXS_INTR_INIT(_hba, _m)               emlxs_intx_init(_hba, _m)
2033 #define EMLXS_INTR_UNINIT(_hba)                 emlxs_intx_uninit(_hba)
2034 #define EMLXS_INTR_ADD(_hba)                    emlxs_intx_add(_hba)
2035 #define EMLXS_INTR_REMOVE(_hba)                 emlxs_intx_remove(_hba)
2036 #endif  /* MSI_SUPPORT */
2037 
2038 
2039 /* Power Management Component */
2040 #define EMLXS_PM_ADAPTER        0
2041 
2042 
2043 #define DRV_TIME        (uint32_t)(ddi_get_time() - emlxs_device.drv_timestamp)
2044 
2045 #define HBA                     port->hba
2046 #define PPORT                   hba->port[0]
2047 #define VPORT(x)                hba->port[x]
2048 #define EMLXS_TIMER_LOCK        hba->timer_lock
2049 #define VPD                     hba->vpd
2050 #define CFG                     hba->config[0]
2051 #define LOG                     hba->log
2052 #define EVENTQ                  hba->event_queue
2053 #define EMLXS_MBOX_LOCK         hba->mbox_lock
2054 #define EMLXS_MBOX_CV           hba->mbox_lock_cv
2055 #define EMLXS_LINKUP_LOCK       hba->linkup_lock
2056 #define EMLXS_LINKUP_CV         hba->linkup_lock_cv
2057 #define EMLXS_TX_CHANNEL_LOCK   hba->channel_tx_lock /* ring txq lock */
2058 #define EMLXS_MEMGET_LOCK       hba->memget_lock     /* mempool get lock */
2059 #define EMLXS_MEMPUT_LOCK       hba->memput_lock     /* mempool put lock */
2060 #define EMLXS_IOCTL_LOCK        hba->ioctl_lock              /* ioctl lock */
2061 #define EMLXS_SPAWN_LOCK        hba->spawn_lock              /* spawn lock */
2062 #define EMLXS_PM_LOCK           hba->pm_lock         /* pm lock */
2063 #define HBASTATS                hba->stats
2064 #define EMLXS_CMD_RING_LOCK(n)  hba->sli.sli3.ring_cmd_lock[n]
2065 
2066 #define EMLXS_QUE_LOCK(n)       hba->sli.sli4.que_lock[n]
2067 #define EMLXS_MSIID_LOCK        hba->msiid_lock
2068 
2069 #define EMLXS_FCTAB_LOCK        hba->iotag_lock
2070 
2071 #define EMLXS_FCF_LOCK          hba->sli.sli4.fcf_lock
2072 
2073 #define EMLXS_PORT_LOCK         hba->port_lock               /* locks ports, */
2074                                                         /* nodes, rings */
2075 #define EMLXS_INTR_LOCK(_id)    hba->intr_lock[_id]  /* locks intr threads */
2076 
2077 #define EMLXS_PKT_LOCK          port->pkt_lock               /* used for pkt */
2078                                                         /* polling */
2079 #define EMLXS_PKT_CV            port->pkt_lock_cv    /* Used for pkt */
2080                                                         /* polling */
2081 #define EMLXS_UB_LOCK           port->ub_lock                /* locks unsolicited */
2082                                                         /* buffer pool */
2083 
2084 /* These SWAPs will swap on any platform */
2085 #define SWAP32_BUFFER(_b, _c)           emlxs_swap32_buffer(_b, _c)
2086 #define SWAP32_BCOPY(_s, _d, _c)        emlxs_swap32_bcopy(_s, _d, _c)
2087 
2088 #define SWAP64(_x)      ((((uint64_t)(_x) & 0xFF)<<56) | \
2089                             (((uint64_t)(_x) & 0xFF00)<<40) | \
2090                             (((uint64_t)(_x) & 0xFF0000)<<24) | \
2091                             (((uint64_t)(_x) & 0xFF000000)<<8) | \
2092                             (((uint64_t)(_x) & 0xFF00000000)>>8) | \
2093                             (((uint64_t)(_x) & 0xFF0000000000)>>24) | \
2094                             (((uint64_t)(_x) & 0xFF000000000000)>>40) | \
2095                             (((uint64_t)(_x) & 0xFF00000000000000)>>56))
2096 
2097 #define SWAP32(_x)      ((((uint32_t)(_x) & 0xFF)<<24) | \
2098                             (((uint32_t)(_x) & 0xFF00)<<8) | \
2099                             (((uint32_t)(_x) & 0xFF0000)>>8) | \
2100                             (((uint32_t)(_x) & 0xFF000000)>>24))
2101 
2102 #define SWAP16(_x)      ((((uint16_t)(_x) & 0xFF)<<8) | \
2103                             (((uint16_t)(_x) & 0xFF00)>>8))
2104 
2105 #define SWAP24_LO(_x)   ((((uint32_t)(_x) & 0xFF)<<16) | \
2106                             ((uint32_t)(_x) & 0xFF00FF00) | \
2107                             (((uint32_t)(_x) & 0x00FF0000)>>16))
2108 
2109 #define SWAP24_HI(_x)   (((uint32_t)(_x) & 0x00FF00FF) | \
2110                             (((uint32_t)(_x) & 0x0000FF00)<<16) | \
2111                             (((uint32_t)(_x) & 0xFF000000)>>16))
2112 
2113 /* These LE_SWAPs will only swap on a LE platform */
2114 #ifdef EMLXS_LITTLE_ENDIAN
2115 #define LE_SWAP32_BUFFER(_b, _c)        SWAP32_BUFFER(_b, _c)
2116 #define LE_SWAP32_BCOPY(_s, _d, _c)     SWAP32_BCOPY(_s, _d, _c)
2117 #define LE_SWAP64(_x)                   SWAP64(_x)
2118 #define LE_SWAP32(_x)                   SWAP32(_x)
2119 #define LE_SWAP16(_x)                   SWAP16(_x)
2120 #define LE_SWAP24_LO(_x)                SWAP24_LO(X)
2121 #define LE_SWAP24_HI(_x)                SWAP24_HI(X)
2122 
2123 #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2124 #undef  LE_SWAP24_LO
2125 #define LE_SWAP24_LO(_x)                (_x)
2126 #undef  LE_SWAP24_HI
2127 #define LE_SWAP24_HI(_x)                (_x)
2128 #endif  /* EMLXS_MODREV2X */
2129 
2130 #else /* BIG ENDIAN */
2131 #define LE_SWAP32_BUFFER(_b, _c)
2132 #define LE_SWAP32_BCOPY(_s, _d, _c)     bcopy(_s, _d, _c)
2133 #define LE_SWAP64(_x)                   (_x)
2134 #define LE_SWAP32(_x)                   (_x)
2135 #define LE_SWAP16(_x)                   (_x)
2136 #define LE_SWAP24_LO(_x)                (_x)
2137 #define LE_SWAP24_HI(_x)                (_x)
2138 #endif /* EMLXS_LITTLE_ENDIAN */
2139 
2140 /* These BE_SWAPs will only swap on a BE platform */
2141 #ifdef EMLXS_BIG_ENDIAN
2142 #define BE_SWAP32_BUFFER(_b, _c)        SWAP32_BUFFER(_b, _c)
2143 #define BE_SWAP32_BCOPY(_s, _d, _c)     SWAP32_BCOPY(_s, _d, _c)
2144 #define BE_SWAP64(_x)                   SWAP64(_x)
2145 #define BE_SWAP32(_x)                   SWAP32(_x)
2146 #define BE_SWAP16(_x)                   SWAP16(_x)
2147 #else /* LITTLE ENDIAN */
2148 #define BE_SWAP32_BUFFER(_b, _c)
2149 #define BE_SWAP32_BCOPY(_s, _d, _c)     bcopy(_s, _d, _c)
2150 #define BE_SWAP64(_x)                   (_x)
2151 #define BE_SWAP32(_x)                   (_x)
2152 #define BE_SWAP16(_x)                   (_x)
2153 #endif /* EMLXS_BIG_ENDIAN */
2154 
2155 #ifdef  __cplusplus
2156 }
2157 #endif
2158 
2159 #endif  /* _EMLXS_FC_H */