fcip.h revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
/*
* 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 _SYS_FIBRE_CHANNEL_ULP_FCIP_H
#define _SYS_FIBRE_CHANNEL_ULP_FCIP_H
/*
* Header file for FCIP: IP/ARP ULP over FibreChannel
*/
#include <sys/kstat.h>
#include <sys/socket.h>
#include <netinet/arp.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Definitions for module_info.
*/
#define FCIPIDNUM (77) /* module ID number */
#define FCIPNAME "fcip" /* module name */
#define FCIPMINPSZ (0) /* min packet size */
#define FCIPMAXPSZ 1514 /* max packet size */
#define FCIPHIWAT (32 * 1024) /* hi-water mark */
#define FCIPLOWAT (1) /* lo-water mark */
#define FCIPMTU 65280 /* Max permissible MTU */
#define FCIPMIN (ETHERMIN + sizeof (llc_snap_hdr_t) + \
sizeof (fcph_network_hdr_t))
/*
* Per-Stream instance state information.
*
* Each instance is dynamically allocated at open() and free'd
* at close(). Each per-Stream instance points to at most one
* per-device structure using the sl_fcip field. All instances
* are threaded together into one list of active instances
* ordered on minor device number.
*/
#define NMCHASH 64 /* no. of multicast hash buckets */
#define INIT_BUCKET_SIZE 16 /* Initial hash bucket size */
struct fcipstr {
struct fcipstr *sl_nextp; /* next in list */
queue_t *sl_rq; /* pointer to our rq */
struct fcip *sl_fcip; /* attached device */
t_uscalar_t sl_state; /* current DL state */
t_uscalar_t sl_sap; /* bound sap */
uint32_t sl_flags; /* misc. flags */
uint32_t sl_minor; /* minor device number */
la_wwn_t *sl_mctab[NMCHASH]; /* multicast addr table */
uint_t sl_mccount[NMCHASH]; /* # valid addr in mctab[i] */
uint_t sl_mcsize[NMCHASH]; /* size of mctab[i] */
ushort_t sl_ladrf[4]; /* Multicast filter bits */
ushort_t sl_ladrf_refcnt[64]; /* ref. count for filter bits */
kmutex_t sl_lock; /* protect this structure */
};
/* per-stream flags */
#define FCIP_SLFAST 0x01 /* "M_DATA fastpath" mode */
#define FCIP_SLRAW 0x02 /* M_DATA plain raw mode */
#define FCIP_SLALLPHYS 0x04 /* "promiscuous mode" */
#define FCIP_SLALLMULTI 0x08 /* enable all multicast addresses */
#define FCIP_SLALLSAP 0x10 /* enable all ether type values */
/*
* Maximum # of multicast addresses per Stream.
*/
#define FCIPMAXMC 64
#define FCIPMCALLOC (FCIPMAXMC * sizeof (la_wwn_t))
/*
* Full DLSAP address length (in struct dladdr format).
*/
#define FCIPADDRL (sizeof (ushort_t) + sizeof (struct ether_addr))
typedef struct fcip_port_info {
struct fcip_port_info *fcipp_next; /* next port in list */
opaque_t *fcipp_handle;
struct modlinkage fcipp_linkage;
dev_info_t *fcipp_dip;
uint32_t fcipp_topology;
uint32_t fcipp_pstate;
la_wwn_t fcipp_pwwn;
la_wwn_t fcipp_nwwn;
uchar_t fcipp_naa; /* This port's NAA */
int fcipp_fca_pkt_size;
ddi_dma_attr_t fcipp_cmd_dma_attr;
ddi_dma_attr_t fcipp_resp_dma_attr;
ddi_device_acc_attr_t fcipp_fca_acc_attr;
fc_portid_t fcipp_sid; /* this port's S_ID */
struct fcip *fcipp_fcip; /* this port's fcip struct */
} fcip_port_info_t;
#define FCIP_SUCCESS (0)
#define FCIP_FAILURE (1)
#define FCIP_FARP_TIMEOUT 10 /* seconds */
#define FCIP_WAIT_CMDS 5 /* 5 retries at 1 sec between retries */
/*
* Num ports supported for soft_state_init
*/
#define FCIP_NUM_INSTANCES 5
#define FCIP_UB_NBUFS 60
#define FCIP_UB_SIZE 65535
#define FCIP_UB_DECREMENT 4
#define FCIP_UB_MINBUFS 8
#define FCIP_INIT_DELAY 10000000 /* 10 seconds */
#define FCIP_PKT_TTL 120 /* 120 secs */
#define FCIP_TIMEOUT_INTERVAL 10 /* 10 seconds */
#define FCIP_OFFLINE_TIMEOUT 60 /* 60 seconds */
#define FCIP_MAX_PORTS 127 /* for private loop/pt_pt */
#define FCIP_RTE_TIMEOUT 60 /* 60 seconds */
#define ETHERSTRL ((2 * ETHERADDRL) + 1)
/*
* Hash lists
*/
#define FCIP_RT_HASH_ELEMS 32
#define FCIP_DEST_HASH_ELEMS 16
#define FCIP_RT_HASH(x) ((x[2] + x[3] + x[4] + x[5] + x[6] + x[7]) \
& (FCIP_RT_HASH_ELEMS - 1))
#define FCIP_DEST_HASH(x) ((x[2] + x[3] + x[4] + x[5] + x[6] + x[7]) \
& (FCIP_DEST_HASH_ELEMS - 1))
#define FCIP_HDR_SIZE 8
#define FCIP_RT_INVALID (-1)
#define FCIP_RT_RETIRED (-2)
#define FCIP_RT_SUSPENDED (-3)
#define FCIP_RT_LOGIN_PROGRESS (-4)
#define FCIP_RTE_UNAVAIL(state) (((state) == FCIP_RT_INVALID) || \
((state) == FCIP_RT_RETIRED) || \
((state) == FCIP_RT_SUSPENDED)) ? 1 : 0
/*
* Taskq related
*/
#define FCIP_NUM_THREADS 4
#define FCIP_MIN_TASKS 12
#define FCIP_MAX_TASKS 32
/*
* Per-Device instance state information.
*
* Each instance is dynamically allocated on first attach.
*/
struct fcip {
dev_info_t *fcip_dip; /* parent's dev_info */
int fcip_instance; /* parent's instance */
struct fcip *fcip_sibling; /* The other FCA port */
uint32_t fcip_flags; /* misc. flags */
uint32_t fcip_port_state; /* Link State */
fcip_port_info_t *fcip_port_info; /* info about port */
struct fcip *fcip_next;
kcondvar_t fcip_farp_cv; /* For perport serialization */
int fcip_farp_rsp_flag; /* FARP response flag */
kmutex_t fcip_mutex; /* protect this structure */
kmutex_t fcip_ub_mutex; /* protect the unsol bufs */
uint32_t fcip_ub_nbufs; /* no. of Unsol. Buffers */
uint32_t fcip_ub_upstream; /* no ubufs in use */
kcondvar_t fcip_ub_cv;
timeout_id_t fcip_timeout_id; /* for timeout routine */
uint32_t fcip_timeout_ticks;
uint32_t fcip_mark_offline;
uint64_t *fcip_ub_tokens; /* unsol buf tokens */
kmutex_t fcip_dest_mutex; /* dest table lock */
struct fcip_dest *fcip_dest[FCIP_DEST_HASH_ELEMS];
/* hash table of remote dest. ports */
kmutex_t fcip_rt_mutex; /* routing table lock */
struct fcip_routing_table *fcip_rtable[FCIP_RT_HASH_ELEMS];
/* hash table of WWN to D_ID maps */
int fcip_intr_flag; /* init. flag for fcipintr() */
uint32_t fcip_addrflags; /* type of MAC address */
struct ether_addr fcip_factmacaddr; /* local mac address */
struct ether_addr fcip_macaddr; /* MAC addr */
la_wwn_t fcip_ouraddr; /* individual address */
uchar_t fcip_ouripaddr[16]; /* Our IP address */
struct kmem_cache *fcip_xmit_cache; /* cache of xmit pkts */
uint32_t fcip_wantw; /* out of xmit resources */
queue_t *fcip_ipq; /* ip read queue */
taskq_t *fcip_tq; /* Taskq pointer */
int fcip_sendup_thr_initted; /* sendup tq thread */
kmutex_t fcip_sendup_mutex; /* for upstream data */
kcondvar_t fcip_sendup_cv; /* for upstream unsol data */
struct fcip_sendup_elem *fcip_sendup_head; /* head of mblk elems */
struct fcip_sendup_elem *fcip_sendup_tail; /* tail of elem list */
struct kmem_cache *fcip_sendup_cache; /* for sendup elems */
uint32_t fcip_sendup_cnt; /* Num msgs queued */
uint32_t fcip_broadcast_did; /* broadcast D_ID */
kstat_t *fcip_intrstats; /* interrupt statistics */
kstat_t *fcip_kstatp; /* kstat pointer */
callb_cpr_t fcip_cpr_info; /* for the sendup thread */
ulong_t fcip_ipackets; /* # packets received */
ulong_t fcip_ierrors; /* # total input errors */
ulong_t fcip_opackets; /* # packets sent */
ulong_t fcip_oerrors; /* # total output errors */
ulong_t fcip_collisions; /* # collisions */
ulong_t fcip_defer; /* # defers */
ulong_t fcip_fram; /* # receive framing errors */
ulong_t fcip_crc; /* # receive crc errors */
ulong_t fcip_oflo; /* # receiver overflows */
ulong_t fcip_uflo; /* # transmit underflows */
ulong_t fcip_missed; /* # receive missed */
ulong_t fcip_tlcol; /* # xmit late collisions */
ulong_t fcip_trtry; /* # transmit retry failures */
ulong_t fcip_tnocar; /* # loss of carrier errors */
ulong_t fcip_inits; /* # driver inits */
ulong_t fcip_notbufs; /* # out of pkts for xmit */
ulong_t fcip_norbufs; /* # out of buffers for rcv */
ulong_t fcip_nocanput; /* # input canputret.false */
ulong_t fcip_allocbfail; /* # allocb failed */
int fcip_tx_lbolt; /* time of last tx interrupt */
int fcip_rx_lbolt; /* time of last rx interrupt */
/*
* MIB II variables
*/
ulong_t fcip_rcvbytes; /* # bytes received */
ulong_t fcip_xmtbytes; /* # bytes transmitted */
ulong_t fcip_multircv; /* # multicast pkts received */
ulong_t fcip_multixmt; /* # multicast pkts for xmit */
ulong_t fcip_brdcstrcv; /* # broadcast pkts received */
ulong_t fcip_brdcstxmt; /* # broadcast pkts for xmit */
ulong_t fcip_norcvbuf; /* # rcv pkts discarded */
ulong_t fcip_noxmtbuf; /* # xmit pkts discarded */
ulong_t fcip_num_ipkts_pending;
/* #ipkts pending call back */
};
#define FCIP_FACTADDR_PRESENT 0x01
#define FCIP_FACTADDR_USE 0x02
/* flags */
#define FCIP_RUNNING 0x01
#define FCIP_INITED 0x02
#define FCIP_PROMISC 0x04
#define FCIP_SUSPENDED 0x08
#define FCIP_NOTIMEOUTS 0x10
#define FCIP_DETACHING 0x20
#define FCIP_DETACHED 0x40
#define FCIP_ATTACHING 0x80
#define FCIP_LINK_DOWN 0x100
#define FCIP_IN_SC_CB 0x200
#define FCIP_IN_DATA_CB 0x400
#define FCIP_IN_ELS_CB 0x800
#define FCIP_IN_TIMEOUT 0x1000
#define FCIP_POWER_DOWN 0x2000
#define FCIP_RTE_REMOVING 0x4000
#define FCIP_REG_INPROGRESS 0x8000
/* macro for checking any callback */
#define FCIP_IN_CALLBACK (FCIP_IN_SC_CB | FCIP_IN_DATA_CB | \
FCIP_IN_ELS_CB)
/* macro for checking if a port is busy */
#define FCIP_PORT_BUSY (FCIP_ATTACHING | \
FCIP_REG_INPROGRESS | FCIP_DETACHING)
/*
* FCIP routing table maintains the FC Layer and the ARP layer
* mapping for a destination port.
*/
struct fcip_routing_table {
struct fcip_routing_table *fcipr_next; /* next elem */
la_wwn_t fcipr_pwwn; /* Destination Port's Port WWN */
la_wwn_t fcipr_nwwn; /* Destination Port's Node WWN */
fc_portid_t fcipr_d_id; /* Destination Port's D_ID */
void *fcipr_pd; /* pointer to port device struct */
uchar_t fcipr_ipaddr[16]; /* Port's IP address */
int fcipr_state; /* login state etc */
clock_t fcipr_invalid_timeout; /* wait after marked inval */
opaque_t fcipr_fca_dev; /* FCA device pointer */
};
#define FCIP_COMPARE_NWWN 0x001
#define FCIP_COMPARE_PWWN 0x010
#define FCIP_COMPARE_BROADCAST 0x100
#define IS_BROADCAST_ADDR(wwn) (((wwn)->raw_wwn[2] == 0xff) && \
((wwn)->raw_wwn[3] == 0xff) && \
((wwn)->w.wwn_lo == 0xffffffff))
/*
* Define a fcip_pkt structure. We can stuff information about
* the message block and queue for which the packet was built. We can
* then free up the message once the transport layer has confirmed
* that the packet has been successfully transported.
*/
typedef struct fcip_pkt {
mblk_t *fcip_pkt_mp; /* message blk pointer */
queue_t *fcip_pkt_wq; /* queue pointer if needed */
uint32_t fcip_pkt_ttl; /* time to live */
uint32_t fcip_pkt_retries; /* retries if needed */
fc_packet_t *fcip_pkt_fcpktp; /* the actual fc packet */
struct fcip_dest *fcip_pkt_dest; /* destination of pkt */
struct fcip *fcip_pkt_fptr; /* fcip structure */
struct fcip_pkt *fcip_pkt_next; /* next pkt */
struct fcip_pkt *fcip_pkt_prev; /* prev pkt */
uint32_t fcip_pkt_state; /* pkt state */
uint32_t fcip_pkt_reason; /* pkt reason */
uint32_t fcip_pkt_flags; /* pkt flags */
uint32_t fcip_pkt_dma_flags; /* DMA flags */
fc_packet_t fcip_pkt_fcpkt; /* the actual fc packet */
struct fcip_routing_table *fcip_pkt_frp; /* routing table */
} fcip_pkt_t;
/* fcipp_dma_flags */
#define FCIP_CMD_DMA_MEM 0x01
#define FCIP_CMD_DMA_BOUND 0x02
#define FCIP_RESP_DMA_MEM 0x04
#define FCIP_RESP_DMA_BOUND 0x08
/* fcipp_flags */
#define FCIP_PKT_INTERNAL 0x01
#define FCIP_PKT_IN_TIMEOUT 0x02
#define FCIP_PKT_RETURNED 0x04
#define FCIP_PKT_IN_LIST 0x08
#define FCIP_PKT_IN_ABORT 0x10
#define FCIP_PKT_TO_FC_PKT(fcip_pkt) &(fcip_pkt)->fcip_pkt_fcpkt
/*
* For each remote port we have a active session with (logged in and
* having active exchanges) setup a Destination Port structure. Maintain
* a Hash list of destination structures in the fcip structure. Before
* starting a new session with the destination port, lookup the hash
* table to see if we are already having active exchanges with a remote
* port and if yes bump the reference count and continue use the same
* destination port. Hash on Port WWNs.
*/
struct fcip_dest {
struct fcip_dest *fcipd_next; /* next element of hashtable */
fcip_pkt_t *fcipd_head; /* packet head for this port */
kmutex_t fcipd_mutex; /* packet list mutex */
uint32_t fcipd_refcnt; /* no.of active sessions */
struct fcip_routing_table *fcipd_rtable;
#define fcipd_nwwn fcipd_rtable->fcipr_nwwn
#define fcipd_pwwn fcipd_rtable->fcipr_pwwn
#define fcipd_did fcipd_rtable->fcipr_d_id
#define fcipd_pd fcipd_rtable->fcipr_pd
#define fcipd_state fcipd_rtable->fcipr_state
#define fcipd_fca_dev fcipd_rtable->fcipr_fca_dev;
uint32_t fcipd_retries; /* retries if needed ?? */
uint32_t fcipd_flags; /* flags ?? */
ulong_t fcipd_ncmds; /* no. of transport cmds */
};
#define FCIP_PORT_OFFLINE 0
#define FCIP_PORT_ONLINE 1
#define FCIP_PORT_NOTLOGGED 2
#define FCIP_INVALID_WWN -1
#define SLFAST 0x01 /* MDATA fastpath mode */
#define SLRAW 0x02 /* M_DATA plain raw mode */
#define SLALLPHYS 0x04 /* promiscuous mode */
#define SLALLMULTI 0x05 /* enable all multicast addr */
#define SLALLSAP 0x10 /* enable all ethertype values */
/*
* Private DLPI full dlsap address format.
*/
struct fcipdladdr {
struct ether_addr dl_phys;
uint16_t dl_sap;
};
typedef struct llc_snap_hdr {
uchar_t dsap;
uchar_t ssap;
uchar_t ctrl;
uchar_t oui[3];
ushort_t pid;
} llc_snap_hdr_t;
/*
* "Export" a few of the error counters via the kstats mechanism.
*/
struct fcipstat {
struct kstat_named fcips_ipackets;
struct kstat_named fcips_ierrors;
struct kstat_named fcips_opackets;
struct kstat_named fcips_oerrors;
struct kstat_named fcips_collisions;
struct kstat_named fcips_defer;
struct kstat_named fcips_fram;
struct kstat_named fcips_crc;
struct kstat_named fcips_oflo;
struct kstat_named fcips_uflo;
struct kstat_named fcips_missed;
struct kstat_named fcips_tlcol;
struct kstat_named fcips_trtry;
struct kstat_named fcips_tnocar;
struct kstat_named fcips_inits;
struct kstat_named fcips_notmds;
struct kstat_named fcips_notbufs;
struct kstat_named fcips_norbufs;
struct kstat_named fcips_nocanput;
struct kstat_named fcips_allocbfail;
/*
* required by kstat for MIB II objects(RFC 1213)
*/
struct kstat_named fcips_rcvbytes; /* # octets received */
/* MIB - ifInOctets */
struct kstat_named fcips_xmtbytes; /* # octets xmitted */
/* MIB - ifOutOctets */
struct kstat_named fcips_multircv; /* # multicast packets */
/* delivered to upper layer */
/* MIB - ifInNUcastPkts */
struct kstat_named fcips_multixmt; /* # multicast packets */
/* requested to be sent */
/* MIB - ifOutNUcastPkts */
struct kstat_named fcips_brdcstrcv; /* # broadcast packets */
/* delivered to upper layer */
/* MIB - ifInNUcastPkts */
struct kstat_named fcips_brdcstxmt; /* # broadcast packets */
/* requested to be sent */
/* MIB - ifOutNUcastPkts */
struct kstat_named fcips_norcvbuf; /* # rcv packets discarded */
/* MIB - ifInDiscards */
struct kstat_named fcips_noxmtbuf; /* # xmt packets discarded */
/* MIB - ifOutDiscards */
};
#define FC_OFF 0x00
#define DA_OFF 0x01
#define SA_OFF 0x07
#define DLSAP_OFF 0x0D
#define SLSAP_OFF 0x0E
#define ORG_OFF 0x0F
#define TYPE_OFF 0x13
#define FCIP_IPV4_LEN 0x04;
#define FCIP_CP_IN(s, d, handle, len) (ddi_rep_get8((handle), \
(uint8_t *)(d), (uint8_t *)(s), \
(len), DDI_DEV_AUTOINCR))
#define FCIP_CP_OUT(s, d, handle, len) (ddi_rep_put8((handle), \
(uint8_t *)(s), (uint8_t *)(d), \
(len), DDI_DEV_AUTOINCR))
#define LA_ELS_FARP_REQ 0x54
#define LA_ELS_FARP_REPLY 0x55
/* Match address code points */
#define FARP_MATCH_RSVD 0x00
#define FARP_MATCH_WW_PN 0x01
#define FARP_MATCH_WW_NN 0x02
#define FARP_MATCH_WW_PN_NN 0x03
#define FARP_MATCH_IPv4 0x04
#define FARP_MATCH_WW_PN_IPv4 0x05
#define FARP_MATCH_WW_NN_IPv4 0x06
#define FARP_MATCH_WW_PN_NN_IPv4 0x07
/* Responder flags */
#define FARP_INIT_P_LOGI 0x0
#define FARP_INIT_REPLY 0x1
/*
* Structure for FARP ELS request and Response
*/
typedef struct la_els_farp {
ls_code_t ls_code; /* FARP ELS code - 0x54/0x55 */
uchar_t match_addr; /* match addr. code points */
fc_portid_t req_id; /* Requester Port_ID */
uchar_t resp_flags; /* Responder flags */
fc_portid_t dest_id; /* Responder Port_ID */
la_wwn_t req_pwwn; /* Port WWN of Requester */
la_wwn_t req_nwwn; /* Node WWN of Requester */
la_wwn_t resp_pwwn; /* Port WWN of Responder */
la_wwn_t resp_nwwn; /* Node WWN of Responder */
uchar_t req_ip[16]; /* IP address or Requester */
uchar_t resp_ip[16]; /* IP address or Responder */
} la_els_farp_t;
/*
* Linked list of farp responses
*/
struct farp_resp_list {
struct farp_resp_list *farpl_next;
struct farp_resp_list *farpl_prev;
la_els_farp_t *farpl_resp;
};
/*
* FCPH Optional network Header
*/
typedef struct network_header {
la_wwn_t net_dest_addr;
la_wwn_t net_src_addr;
} fcph_network_hdr_t;
/*
* InArp request structure
*/
typedef struct fcip_inarp {
fcph_network_hdr_t fcip_inarp_nh;
llc_snap_hdr_t fcip_inarp_snap;
struct ether_arp fcip_inarp_data;
} fcip_inarp_t;
/*
* InArp Response list
*/
struct inarp_resp_list {
struct inarp_resp_list *inarpl_next;
struct inarp_resp_list *inarpl_prev;
fcip_inarp_t *inarpl_resp;
};
/*
* Structure to define args for esballoc frtn function
*/
struct fcip_esballoc_arg {
fc_unsol_buf_t *buf;
opaque_t phandle;
frtn_t *frtnp;
};
struct fcip_sendup_elem {
struct fcip_sendup_elem *fcipsu_next;
mblk_t *fcipsu_mp;
struct fcipstr *(*fcipsu_func)();
};
/*
* Having TNF probe points can be lethal during reconfiguration boot. Enable
* TNF using a compile time define.
*/
#ifdef __lint
#define FCIP_TNF_ENABLED
#else
#undef FCIP_TNF_ENABLED
#endif
#ifdef FCIP_TNF_ENABLED
extern int tnf_mod_load(void);
extern int tnf_mod_unload(struct modlinkage *e);
#define FCIP_TNF_LOAD() (void) tnf_mod_load()
#define FCIP_TNF_UNLOAD(x) (void) tnf_mod_unload(x)
#define FCIP_TNF_PROBE_0(x) TNF_PROBE_0 x
#define FCIP_TNF_PROBE_1(x) TNF_PROBE_1 x
#define FCIP_TNF_PROBE_2(x) TNF_PROBE_2 x
#define FCIP_TNF_PROBE_3(x) TNF_PROBE_3 x
#define FCIP_TNF_PROBE_4(x) TNF_PROBE_4 x
#define FCIP_TNF_PROBE_5(x) TNF_PROBE_5 x
#else
#define FCIP_TNF_LOAD()
#define FCIP_TNF_UNLOAD(x)
#define FCIP_TNF_PROBE_0(x)
#define FCIP_TNF_PROBE_1(x)
#define FCIP_TNF_PROBE_2(x)
#define FCIP_TNF_PROBE_3(x)
#define FCIP_TNF_PROBE_4(x)
#define FCIP_TNF_PROBE_5(x)
#endif /* FCIP_TNF_ENABLED */
/*
* Macros to help with complex TNF output
*/
#ifdef FCIP_TNF_ENABLED
#define FCIP_TNF_BYTE_ARRAY(name, keys, detail, mesg, barray_name, \
barray, len) \
{ \
TNF_PROBE_1(name, keys, detail, tnf_string, msg, mesg); \
{ \
int i = 0; \
char str[65] = ""; \
char *strp = str; \
while (i < 32 && i < len) { \
(void) sprintf(strp, "%02x", \
((char *)(barray))[i++] & 0xff); \
strp += 2; \
} \
TNF_PROBE_1(name, keys, "", \
tnf_string, barray_name, str); \
} \
}
#else
#define FCIP_TNF_BYTE_ARRAY(name, keys, detail, mesg, barray_name, barray, len)
#endif /* FCIP_TNF_ENABLED */
/*
* FC4 type setttings for Name Server registration.
*/
#define FC4_TYPE_WORD_POS(x) ((uchar_t)(x) >> 5)
#define FC4_TYPE_BIT_POS(x) ((uchar_t)(x) & 0x1F)
#ifdef __cplusplus
}
#endif
#endif /* !_SYS_FIBRE_CHANNEL_ULP_FCIP_H */