summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/fibre-channel/ulp/fcip.h
blob: 7546e9ca286afc0a7821aab8b2d2a09f775a72c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
/*
 * 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)();
};

/*
 * 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 */