root/usr/src/uts/common/sys/fibre-channel/fc_appif.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _FC_APPIF_H
#define _FC_APPIF_H

#include <sys/note.h>

#ifdef  __cplusplus
extern "C" {
#endif

#if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
#error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif  /* _BIT_FIELDS_LTOH */

/*
 * Local port topology definitions
 *
 * fp/fctl use these a lot with the fp_topology field in the fc_port_t struct,
 * but use is not limited to fp_topology. These are also understood by ULPs.
 */
#define FC_TOP_UNKNOWN          0
#define FC_TOP_PRIVATE_LOOP     1
#define FC_TOP_PUBLIC_LOOP      2
#define FC_TOP_FABRIC           3
#define FC_TOP_PT_PT            4
#define FC_TOP_NO_NS            5

/*
 * Macros used with the preceeding topology #defines.
 * fp/fctl use these a lot with the fp_topology field in the fc_port_t struct,
 * but use is not limited to fp_topology. These are also understood by ULPs.
 */
#define FC_TOP_EXTERNAL(t)      FC_IS_TOP_SWITCH(t)
#define FC_IS_TOP_SWITCH(t)     (((t) == FC_TOP_FABRIC) ||\
                                ((t) == FC_TOP_PUBLIC_LOOP))

/*
 * fc_remote_port state (map_state) definitions.
 *
 * Used with the pd_state field in the fc_remote_port_t struct.
 */
#define PORT_DEVICE_INVALID     0       /* State when created or login failed */
#define PORT_DEVICE_VALID       1       /* Logged out */
#define PORT_DEVICE_LOGGED_IN   2       /* Logged in */


/*
 * Firmware, FCode revision field lengths
 */
#define FC_FCODE_REV_SIZE       25
#define FC_FW_REV_SIZE          25

typedef struct ct_header {
#if defined(_BIT_FIELDS_LTOH)
        uint32_t        ct_inid : 24,           /* Initial Node ID */
                        ct_rev  : 8;            /* Revision */

        uint32_t        ct_reserved1 : 8,
                        ct_options : 8,
                        ct_fcssubtype : 8,
                        ct_fcstype : 8;

        uint32_t        ct_aiusize : 16,
                        ct_cmdrsp : 16;

        uint32_t        ct_vendor : 8,
                        ct_expln : 8,
                        ct_reason : 8,
                        ct_reserved2 : 8;

#else
        uint32_t        ct_rev : 8,             /* revision */
                        ct_inid : 24;           /* initial node ID */
        uint32_t        ct_fcstype : 8,         /* type of service */
                        ct_fcssubtype : 8,      /* subtype of service */
                        ct_options : 8,         /* options */
                        ct_reserved1 : 8;       /* reserved */

        uint32_t        ct_cmdrsp : 16,         /* command/response code */
                        ct_aiusize : 16;        /* AIU/residual size */

        uint32_t        ct_reserved2 : 8,       /* reserved */
                        ct_reason : 8,          /* reason code */
                        ct_expln : 8,           /* reason explanation */
                        ct_vendor : 8;          /* vendor unique */

#endif  /* _BIT_FIELDS_LTOH */
} fc_ct_header_t;

/* World Wide Name format */
typedef union la_wwn {
        uchar_t                 raw_wwn[8];
        uint32_t                i_wwn[2];

#if defined(_BIT_FIELDS_LTOH)
        struct {
                uint32_t        wwn_hi : 16,
                                nport_id : 12,
                                naa_id : 4;
                uint32_t        wwn_lo;
        }w;

#else
        struct {
                uint32_t        naa_id : 4,
                                nport_id : 12,
                                wwn_hi : 16;
                uint32_t        wwn_lo;
        }w;
#endif  /* _BIT_FIELDS_LTOH */
} la_wwn_t;

/*
 * Values for naa_id
 */
#define NAA_ID_IEEE             1
#define NAA_ID_IEEE_EXTENDED    2

#ifndef FC_WWN_SIZE
#define FC_WWN_SIZE             (sizeof (la_wwn_t))
#endif /* FC_WWN_SIZE */

typedef struct service_param {
        uint16_t        class_opt;
        uint16_t        initiator_ctl;
        uint16_t        recipient_ctl;
        uint16_t        rcv_size;
        uint16_t        conc_sequences;
        uint16_t        n_port_e_to_e_credit;
        uint16_t        open_seq_per_xchng;
        uint16_t        rsvd;
} svc_param_t;

typedef struct common_service {
        uint16_t    fcph_version;
        uint16_t    btob_credit;
        uint16_t    cmn_features;
        uint16_t    rx_bufsize;
        uint16_t    conc_sequences;
        uint16_t    relative_offset;
        uint32_t    e_d_tov;
} com_svc_t;

typedef struct ls_code {
#if defined(_BIT_FIELDS_LTOH)
        uint32_t        mbz : 24,
                        ls_code : 8;

#else
        uint32_t        ls_code : 8,
                        mbz : 24;
#endif  /* _BIT_FIELDS_LTOH */
} ls_code_t;


/* Login Payload. */
typedef struct la_els_logi {
        ls_code_t       ls_code;
        com_svc_t       common_service;

        la_wwn_t        nport_ww_name;
        la_wwn_t        node_ww_name;

        svc_param_t     class_1;
        svc_param_t     class_2;
        svc_param_t     class_3;

        uchar_t         reserved[16];
        uchar_t         vendor_version[16];
} la_els_logi_t;

typedef struct fc_ns_cmd {
        uint32_t        ns_flags;               /* for future use */
        uint16_t        ns_cmd;                 /* NS command type */
        uint16_t        ns_req_len;
        caddr_t         ns_req_payload;         /* No CT header */
        uint16_t        ns_resp_len;
        caddr_t         ns_resp_payload;        /* no CT header */
        void            *ns_fctl_private;       /* Transport private */
        fc_ct_header_t  ns_resp_hdr;            /* for the curious */
} fc_ns_cmd_t;

#if defined(_SYSCALL32)

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack(4)
#endif

typedef struct la_els_logi32 {
        ls_code_t       ls_code;
        com_svc_t       common_service;
        la_wwn_t        nport_ww_name;
        la_wwn_t        node_ww_name;
        svc_param_t     class_1;
        svc_param_t     class_2;
        svc_param_t     class_3;
        uchar_t         reserved[16];
        uchar_t         vendor_version[16];
} la_els_logi32_t;

typedef struct fc_ns_cmd32 {
        uint32_t        ns_flags;               /* for future use */
        uint16_t        ns_cmd;                 /* NS command type */
        uint16_t        ns_req_len;
        caddr_t         ns_req_payload;         /* No CT header */
        uint16_t        ns_resp_len;
        caddr_t         ns_resp_payload;        /* no CT header */
        void            *ns_fctl_private;       /* Transport private */
        fc_ct_header_t  ns_resp_hdr;            /* for the curious */
} fc_ns_cmd32_t;

#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif

#endif  /* _SYSCALL32 */

/* Link Error Parameters in the RLS Accept payload */
typedef struct fc_rls_acc_params {
        uint32_t        rls_link_fail;          /* link failure count */
        uint32_t        rls_sync_loss;          /* loss of sync count */
        uint32_t        rls_sig_loss;           /* loss of signal count */
        uint32_t        rls_prim_seq_err;       /* primitive seq error */
        uint32_t        rls_invalid_word;       /* invalid tx word */
        uint32_t        rls_invalid_crc;        /* invalid CRC count */
} fc_rls_acc_t;

/* RLS Payload. */
typedef struct la_els_rls {
        ls_code_t       ls_code;
        fc_portid_t     rls_portid;             /* port identifier */
} la_els_rls_t;

/* RLS accept payload */
typedef struct la_els_rls_acc {
        ls_code_t       ls_code;
        fc_rls_acc_t    rls_link_params;        /* link error status block */
} la_els_rls_acc_t;

/* Node Id Parameters in the RNID Get/Set Accept/Request payload */
typedef struct fc_rnid_params {
        uchar_t         global_id[16];          /* global name */
        uint32_t        unit_type;              /* unit type */
        uint32_t        port_id;                /* port id */
        uint32_t        num_attached;           /* number of attached nodes */
        uint16_t        ip_version;             /* ip version */
        uint16_t        udp_port;               /* udp port number */
        uchar_t         ip_addr[16];            /* ip address */
        uint16_t        specific_id_resv;       /* reserved */
        uint16_t        topo_flags;             /* topology discovery flags */
} fc_rnid_t;

/* RNID get data format flag */
#define FCIO_CFLAGS_RNID_GET_GENERAL_TOPOLOGY   0xDF
#define FCIO_CFLAGS_RNID_GET_VENDOR_SPECIFIC    0xE0

/* RNID maximum data length - common data(16) + specific data(252) */
#define FCIO_RNID_MAX_DATA_LEN  268

/* RNID Payload. */
typedef struct la_els_rnid {
        ls_code_t       ls_code;
        uchar_t         data_format;            /* data format returned */
        uchar_t         resv[3];
} la_els_rnid_t;

/*
 * ELS RNID header
 * - cmn_len can be 0 or 16 - if it is 0 then specific data starts at
 *   offset 8 else specific data starts at offset 24 in the RNID els response
 */
typedef struct fc_rnid_hdr {
        uchar_t         data_format;
        uchar_t         cmn_len;
        uchar_t         resv;
        uchar_t         specific_len;
}fc_rnid_hdr_t;

typedef struct la_els_rnid_acc {
        ls_code_t       ls_code;
        fc_rnid_hdr_t   hdr;
        uchar_t         data[FCIO_RNID_MAX_DATA_LEN];
} la_els_rnid_acc_t;

typedef struct la_npiv_create_entry {
        la_wwn_t        VNodeWWN;
        la_wwn_t        VPortWWN;
        uint32_t        vindex;
} la_npiv_create_entry_t;

#if     !defined(__lint)
_NOTE(SCHEME_PROTECTS_DATA("unique per request", fc_ns_cmd))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", ct_header))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", la_els_logi))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", la_wwn))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", fc_rls_acc_params))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", la_els_rls))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", la_els_rls_acc))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", fc_rnid_params))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", la_els_rnid))
_NOTE(SCHEME_PROTECTS_DATA("unique per request", la_els_rnid_acc))
#endif /* __lint */

#ifdef  __cplusplus
}
#endif

#endif  /* _FC_APPIF_H */