aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/scsi/fc/fc_els.h816
-rw-r--r--include/scsi/fc/fc_encaps.h138
-rw-r--r--include/scsi/fc/fc_fc2.h124
-rw-r--r--include/scsi/fc/fc_fcoe.h114
-rw-r--r--include/scsi/fc/fc_fcp.h199
-rw-r--r--include/scsi/fc/fc_fs.h340
-rw-r--r--include/scsi/fc/fc_gs.h93
-rw-r--r--include/scsi/fc/fc_ns.h159
-rw-r--r--include/scsi/fc_encode.h309
-rw-r--r--include/scsi/fc_frame.h242
-rw-r--r--include/scsi/fc_transport_fcoe.h54
-rw-r--r--include/scsi/iscsi_if.h7
-rw-r--r--include/scsi/libfc.h938
-rw-r--r--include/scsi/libfcoe.h176
-rw-r--r--include/scsi/libiscsi.h39
-rw-r--r--include/scsi/libiscsi_tcp.h132
-rw-r--r--include/scsi/scsi_device.h7
-rw-r--r--include/scsi/scsi_transport_iscsi.h12
18 files changed, 3882 insertions, 17 deletions
diff --git a/include/scsi/fc/fc_els.h b/include/scsi/fc/fc_els.h
new file mode 100644
index 000000000000..195ca014d3ce
--- /dev/null
+++ b/include/scsi/fc/fc_els.h
@@ -0,0 +1,816 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_ELS_H_
21#define _FC_ELS_H_
22
23/*
24 * Fibre Channel Switch - Enhanced Link Services definitions.
25 * From T11 FC-LS Rev 1.2 June 7, 2005.
26 */
27
28/*
29 * ELS Command codes - byte 0 of the frame payload
30 */
31enum fc_els_cmd {
32 ELS_LS_RJT = 0x01, /* ESL reject */
33 ELS_LS_ACC = 0x02, /* ESL Accept */
34 ELS_PLOGI = 0x03, /* N_Port login */
35 ELS_FLOGI = 0x04, /* F_Port login */
36 ELS_LOGO = 0x05, /* Logout */
37 ELS_ABTX = 0x06, /* Abort exchange - obsolete */
38 ELS_RCS = 0x07, /* read connection status */
39 ELS_RES = 0x08, /* read exchange status block */
40 ELS_RSS = 0x09, /* read sequence status block */
41 ELS_RSI = 0x0a, /* read sequence initiative */
42 ELS_ESTS = 0x0b, /* establish streaming */
43 ELS_ESTC = 0x0c, /* estimate credit */
44 ELS_ADVC = 0x0d, /* advise credit */
45 ELS_RTV = 0x0e, /* read timeout value */
46 ELS_RLS = 0x0f, /* read link error status block */
47 ELS_ECHO = 0x10, /* echo */
48 ELS_TEST = 0x11, /* test */
49 ELS_RRQ = 0x12, /* reinstate recovery qualifier */
50 ELS_REC = 0x13, /* read exchange concise */
51 ELS_SRR = 0x14, /* sequence retransmission request */
52 ELS_PRLI = 0x20, /* process login */
53 ELS_PRLO = 0x21, /* process logout */
54 ELS_SCN = 0x22, /* state change notification */
55 ELS_TPLS = 0x23, /* test process login state */
56 ELS_TPRLO = 0x24, /* third party process logout */
57 ELS_LCLM = 0x25, /* login control list mgmt (obs) */
58 ELS_GAID = 0x30, /* get alias_ID */
59 ELS_FACT = 0x31, /* fabric activate alias_id */
60 ELS_FDACDT = 0x32, /* fabric deactivate alias_id */
61 ELS_NACT = 0x33, /* N-port activate alias_id */
62 ELS_NDACT = 0x34, /* N-port deactivate alias_id */
63 ELS_QOSR = 0x40, /* quality of service request */
64 ELS_RVCS = 0x41, /* read virtual circuit status */
65 ELS_PDISC = 0x50, /* discover N_port service params */
66 ELS_FDISC = 0x51, /* discover F_port service params */
67 ELS_ADISC = 0x52, /* discover address */
68 ELS_RNC = 0x53, /* report node cap (obs) */
69 ELS_FARP_REQ = 0x54, /* FC ARP request */
70 ELS_FARP_REPL = 0x55, /* FC ARP reply */
71 ELS_RPS = 0x56, /* read port status block */
72 ELS_RPL = 0x57, /* read port list */
73 ELS_RPBC = 0x58, /* read port buffer condition */
74 ELS_FAN = 0x60, /* fabric address notification */
75 ELS_RSCN = 0x61, /* registered state change notification */
76 ELS_SCR = 0x62, /* state change registration */
77 ELS_RNFT = 0x63, /* report node FC-4 types */
78 ELS_CSR = 0x68, /* clock synch. request */
79 ELS_CSU = 0x69, /* clock synch. update */
80 ELS_LINIT = 0x70, /* loop initialize */
81 ELS_LSTS = 0x72, /* loop status */
82 ELS_RNID = 0x78, /* request node ID data */
83 ELS_RLIR = 0x79, /* registered link incident report */
84 ELS_LIRR = 0x7a, /* link incident record registration */
85 ELS_SRL = 0x7b, /* scan remote loop */
86 ELS_SBRP = 0x7c, /* set bit-error reporting params */
87 ELS_RPSC = 0x7d, /* report speed capabilities */
88 ELS_QSA = 0x7e, /* query security attributes */
89 ELS_EVFP = 0x7f, /* exchange virt. fabrics params */
90 ELS_LKA = 0x80, /* link keep-alive */
91 ELS_AUTH_ELS = 0x90, /* authentication ELS */
92};
93
94/*
95 * Initializer useful for decoding table.
96 * Please keep this in sync with the above definitions.
97 */
98#define FC_ELS_CMDS_INIT { \
99 [ELS_LS_RJT] = "LS_RJT", \
100 [ELS_LS_ACC] = "LS_ACC", \
101 [ELS_PLOGI] = "PLOGI", \
102 [ELS_FLOGI] = "FLOGI", \
103 [ELS_LOGO] = "LOGO", \
104 [ELS_ABTX] = "ABTX", \
105 [ELS_RCS] = "RCS", \
106 [ELS_RES] = "RES", \
107 [ELS_RSS] = "RSS", \
108 [ELS_RSI] = "RSI", \
109 [ELS_ESTS] = "ESTS", \
110 [ELS_ESTC] = "ESTC", \
111 [ELS_ADVC] = "ADVC", \
112 [ELS_RTV] = "RTV", \
113 [ELS_RLS] = "RLS", \
114 [ELS_ECHO] = "ECHO", \
115 [ELS_TEST] = "TEST", \
116 [ELS_RRQ] = "RRQ", \
117 [ELS_REC] = "REC", \
118 [ELS_SRR] = "SRR", \
119 [ELS_PRLI] = "PRLI", \
120 [ELS_PRLO] = "PRLO", \
121 [ELS_SCN] = "SCN", \
122 [ELS_TPLS] = "TPLS", \
123 [ELS_TPRLO] = "TPRLO", \
124 [ELS_LCLM] = "LCLM", \
125 [ELS_GAID] = "GAID", \
126 [ELS_FACT] = "FACT", \
127 [ELS_FDACDT] = "FDACDT", \
128 [ELS_NACT] = "NACT", \
129 [ELS_NDACT] = "NDACT", \
130 [ELS_QOSR] = "QOSR", \
131 [ELS_RVCS] = "RVCS", \
132 [ELS_PDISC] = "PDISC", \
133 [ELS_FDISC] = "FDISC", \
134 [ELS_ADISC] = "ADISC", \
135 [ELS_RNC] = "RNC", \
136 [ELS_FARP_REQ] = "FARP_REQ", \
137 [ELS_FARP_REPL] = "FARP_REPL", \
138 [ELS_RPS] = "RPS", \
139 [ELS_RPL] = "RPL", \
140 [ELS_RPBC] = "RPBC", \
141 [ELS_FAN] = "FAN", \
142 [ELS_RSCN] = "RSCN", \
143 [ELS_SCR] = "SCR", \
144 [ELS_RNFT] = "RNFT", \
145 [ELS_CSR] = "CSR", \
146 [ELS_CSU] = "CSU", \
147 [ELS_LINIT] = "LINIT", \
148 [ELS_LSTS] = "LSTS", \
149 [ELS_RNID] = "RNID", \
150 [ELS_RLIR] = "RLIR", \
151 [ELS_LIRR] = "LIRR", \
152 [ELS_SRL] = "SRL", \
153 [ELS_SBRP] = "SBRP", \
154 [ELS_RPSC] = "RPSC", \
155 [ELS_QSA] = "QSA", \
156 [ELS_EVFP] = "EVFP", \
157 [ELS_LKA] = "LKA", \
158 [ELS_AUTH_ELS] = "AUTH_ELS", \
159}
160
161/*
162 * LS_ACC payload.
163 */
164struct fc_els_ls_acc {
165 __u8 la_cmd; /* command code ELS_LS_ACC */
166 __u8 la_resv[3]; /* reserved */
167};
168
169/*
170 * ELS reject payload.
171 */
172struct fc_els_ls_rjt {
173 __u8 er_cmd; /* command code ELS_LS_RJT */
174 __u8 er_resv[4]; /* reserved must be zero */
175 __u8 er_reason; /* reason (enum fc_els_rjt_reason below) */
176 __u8 er_explan; /* explanation (enum fc_els_rjt_explan below) */
177 __u8 er_vendor; /* vendor specific code */
178};
179
180/*
181 * ELS reject reason codes (er_reason).
182 */
183enum fc_els_rjt_reason {
184 ELS_RJT_NONE = 0, /* no reject - not to be sent */
185 ELS_RJT_INVAL = 0x01, /* invalid ELS command code */
186 ELS_RJT_LOGIC = 0x03, /* logical error */
187 ELS_RJT_BUSY = 0x05, /* logical busy */
188 ELS_RJT_PROT = 0x07, /* protocol error */
189 ELS_RJT_UNAB = 0x09, /* unable to perform command request */
190 ELS_RJT_UNSUP = 0x0b, /* command not supported */
191 ELS_RJT_INPROG = 0x0e, /* command already in progress */
192 ELS_RJT_VENDOR = 0xff, /* vendor specific error */
193};
194
195
196/*
197 * reason code explanation (er_explan).
198 */
199enum fc_els_rjt_explan {
200 ELS_EXPL_NONE = 0x00, /* No additional explanation */
201 ELS_EXPL_SPP_OPT_ERR = 0x01, /* service parameter error - options */
202 ELS_EXPL_SPP_ICTL_ERR = 0x03, /* service parm error - initiator ctl */
203 ELS_EXPL_AH = 0x11, /* invalid association header */
204 ELS_EXPL_AH_REQ = 0x13, /* association_header required */
205 ELS_EXPL_SID = 0x15, /* invalid originator S_ID */
206 ELS_EXPL_OXID_RXID = 0x17, /* invalid OX_ID-RX_ID combination */
207 ELS_EXPL_INPROG = 0x19, /* Request already in progress */
208 ELS_EXPL_PLOGI_REQD = 0x1e, /* N_Port login required */
209 ELS_EXPL_INSUF_RES = 0x29, /* insufficient resources */
210 ELS_EXPL_UNAB_DATA = 0x2a, /* unable to supply requested data */
211 ELS_EXPL_UNSUPR = 0x2c, /* Request not supported */
212 ELS_EXPL_INV_LEN = 0x2d, /* Invalid payload length */
213 /* TBD - above definitions incomplete */
214};
215
216/*
217 * Common service parameters (N ports).
218 */
219struct fc_els_csp {
220 __u8 sp_hi_ver; /* highest version supported (obs.) */
221 __u8 sp_lo_ver; /* highest version supported (obs.) */
222 __be16 sp_bb_cred; /* buffer-to-buffer credits */
223 __be16 sp_features; /* common feature flags */
224 __be16 sp_bb_data; /* b-b state number and data field sz */
225 union {
226 struct {
227 __be16 _sp_tot_seq; /* total concurrent sequences */
228 __be16 _sp_rel_off; /* rel. offset by info cat */
229 } sp_plogi;
230 struct {
231 __be32 _sp_r_a_tov; /* resource alloc. timeout msec */
232 } sp_flogi_acc;
233 } sp_u;
234 __be32 sp_e_d_tov; /* error detect timeout value */
235};
236#define sp_tot_seq sp_u.sp_plogi._sp_tot_seq
237#define sp_rel_off sp_u.sp_plogi._sp_rel_off
238#define sp_r_a_tov sp_u.sp_flogi_acc._sp_r_a_tov
239
240#define FC_SP_BB_DATA_MASK 0xfff /* mask for data field size in sp_bb_data */
241
242/*
243 * Minimum and maximum values for max data field size in service parameters.
244 */
245#define FC_SP_MIN_MAX_PAYLOAD FC_MIN_MAX_PAYLOAD
246#define FC_SP_MAX_MAX_PAYLOAD FC_MAX_PAYLOAD
247
248/*
249 * sp_features
250 */
251#define FC_SP_FT_CIRO 0x8000 /* continuously increasing rel. off. */
252#define FC_SP_FT_CLAD 0x8000 /* clean address (in FLOGI LS_ACC) */
253#define FC_SP_FT_RAND 0x4000 /* random relative offset */
254#define FC_SP_FT_VAL 0x2000 /* valid vendor version level */
255#define FC_SP_FT_FPORT 0x1000 /* F port (1) vs. N port (0) */
256#define FC_SP_FT_ABB 0x0800 /* alternate BB_credit management */
257#define FC_SP_FT_EDTR 0x0400 /* E_D_TOV Resolution is nanoseconds */
258#define FC_SP_FT_MCAST 0x0200 /* multicast */
259#define FC_SP_FT_BCAST 0x0100 /* broadcast */
260#define FC_SP_FT_HUNT 0x0080 /* hunt group */
261#define FC_SP_FT_SIMP 0x0040 /* dedicated simplex */
262#define FC_SP_FT_SEC 0x0020 /* reserved for security */
263#define FC_SP_FT_CSYN 0x0010 /* clock synch. supported */
264#define FC_SP_FT_RTTOV 0x0008 /* R_T_TOV value 100 uS, else 100 mS */
265#define FC_SP_FT_HALF 0x0004 /* dynamic half duplex */
266#define FC_SP_FT_SEQC 0x0002 /* SEQ_CNT */
267#define FC_SP_FT_PAYL 0x0001 /* FLOGI payload length 256, else 116 */
268
269/*
270 * Class-specific service parameters.
271 */
272struct fc_els_cssp {
273 __be16 cp_class; /* class flags */
274 __be16 cp_init; /* initiator flags */
275 __be16 cp_recip; /* recipient flags */
276 __be16 cp_rdfs; /* receive data field size */
277 __be16 cp_con_seq; /* concurrent sequences */
278 __be16 cp_ee_cred; /* N-port end-to-end credit */
279 __u8 cp_resv1; /* reserved */
280 __u8 cp_open_seq; /* open sequences per exchange */
281 __u8 _cp_resv2[2]; /* reserved */
282};
283
284/*
285 * cp_class flags.
286 */
287#define FC_CPC_VALID 0x8000 /* class valid */
288#define FC_CPC_IMIX 0x4000 /* intermix mode */
289#define FC_CPC_SEQ 0x0800 /* sequential delivery */
290#define FC_CPC_CAMP 0x0200 /* camp-on */
291#define FC_CPC_PRI 0x0080 /* priority */
292
293/*
294 * cp_init flags.
295 * (TBD: not all flags defined here).
296 */
297#define FC_CPI_CSYN 0x0010 /* clock synch. capable */
298
299/*
300 * cp_recip flags.
301 */
302#define FC_CPR_CSYN 0x0008 /* clock synch. capable */
303
304/*
305 * NFC_ELS_FLOGI: Fabric login request.
306 * NFC_ELS_PLOGI: Port login request (same format).
307 */
308struct fc_els_flogi {
309 __u8 fl_cmd; /* command */
310 __u8 _fl_resvd[3]; /* must be zero */
311 struct fc_els_csp fl_csp; /* common service parameters */
312 __be64 fl_wwpn; /* port name */
313 __be64 fl_wwnn; /* node name */
314 struct fc_els_cssp fl_cssp[4]; /* class 1-4 service parameters */
315 __u8 fl_vend[16]; /* vendor version level */
316} __attribute__((__packed__));
317
318/*
319 * Process login service parameter page.
320 */
321struct fc_els_spp {
322 __u8 spp_type; /* type code or common service params */
323 __u8 spp_type_ext; /* type code extension */
324 __u8 spp_flags;
325 __u8 _spp_resvd;
326 __be32 spp_orig_pa; /* originator process associator */
327 __be32 spp_resp_pa; /* responder process associator */
328 __be32 spp_params; /* service parameters */
329};
330
331/*
332 * spp_flags.
333 */
334#define FC_SPP_OPA_VAL 0x80 /* originator proc. assoc. valid */
335#define FC_SPP_RPA_VAL 0x40 /* responder proc. assoc. valid */
336#define FC_SPP_EST_IMG_PAIR 0x20 /* establish image pair */
337#define FC_SPP_RESP_MASK 0x0f /* mask for response code (below) */
338
339/*
340 * SPP response code in spp_flags - lower 4 bits.
341 */
342enum fc_els_spp_resp {
343 FC_SPP_RESP_ACK = 1, /* request executed */
344 FC_SPP_RESP_RES = 2, /* unable due to lack of resources */
345 FC_SPP_RESP_INIT = 3, /* initialization not complete */
346 FC_SPP_RESP_NO_PA = 4, /* unknown process associator */
347 FC_SPP_RESP_CONF = 5, /* configuration precludes image pair */
348 FC_SPP_RESP_COND = 6, /* request completed conditionally */
349 FC_SPP_RESP_MULT = 7, /* unable to handle multiple SPPs */
350 FC_SPP_RESP_INVL = 8, /* SPP is invalid */
351};
352
353/*
354 * ELS_RRQ - Reinstate Recovery Qualifier
355 */
356struct fc_els_rrq {
357 __u8 rrq_cmd; /* command (0x12) */
358 __u8 rrq_zero[3]; /* specified as zero - part of cmd */
359 __u8 rrq_resvd; /* reserved */
360 __u8 rrq_s_id[3]; /* originator FID */
361 __be16 rrq_ox_id; /* originator exchange ID */
362 __be16 rrq_rx_id; /* responders exchange ID */
363};
364
365/*
366 * ELS_REC - Read exchange concise.
367 */
368struct fc_els_rec {
369 __u8 rec_cmd; /* command (0x13) */
370 __u8 rec_zero[3]; /* specified as zero - part of cmd */
371 __u8 rec_resvd; /* reserved */
372 __u8 rec_s_id[3]; /* originator FID */
373 __be16 rec_ox_id; /* originator exchange ID */
374 __be16 rec_rx_id; /* responders exchange ID */
375};
376
377/*
378 * ELS_REC LS_ACC payload.
379 */
380struct fc_els_rec_acc {
381 __u8 reca_cmd; /* accept (0x02) */
382 __u8 reca_zero[3]; /* specified as zero - part of cmd */
383 __be16 reca_ox_id; /* originator exchange ID */
384 __be16 reca_rx_id; /* responders exchange ID */
385 __u8 reca_resvd1; /* reserved */
386 __u8 reca_ofid[3]; /* originator FID */
387 __u8 reca_resvd2; /* reserved */
388 __u8 reca_rfid[3]; /* responder FID */
389 __be32 reca_fc4value; /* FC4 value */
390 __be32 reca_e_stat; /* ESB (exchange status block) status */
391};
392
393/*
394 * ELS_PRLI - Process login request and response.
395 */
396struct fc_els_prli {
397 __u8 prli_cmd; /* command */
398 __u8 prli_spp_len; /* length of each serv. parm. page */
399 __be16 prli_len; /* length of entire payload */
400 /* service parameter pages follow */
401};
402
403/*
404 * ELS_ADISC payload
405 */
406struct fc_els_adisc {
407 __u8 adisc_cmd;
408 __u8 adisc_resv[3];
409 __u8 adisc_resv1;
410 __u8 adisc_hard_addr[3];
411 __be64 adisc_wwpn;
412 __be64 adisc_wwnn;
413 __u8 adisc_resv2;
414 __u8 adisc_port_id[3];
415} __attribute__((__packed__));
416
417/*
418 * ELS_LOGO - process or fabric logout.
419 */
420struct fc_els_logo {
421 __u8 fl_cmd; /* command code */
422 __u8 fl_zero[3]; /* specified as zero - part of cmd */
423 __u8 fl_resvd; /* reserved */
424 __u8 fl_n_port_id[3];/* N port ID */
425 __be64 fl_n_port_wwn; /* port name */
426};
427
428/*
429 * ELS_RTV - read timeout value.
430 */
431struct fc_els_rtv {
432 __u8 rtv_cmd; /* command code 0x0e */
433 __u8 rtv_zero[3]; /* specified as zero - part of cmd */
434};
435
436/*
437 * LS_ACC for ELS_RTV - read timeout value.
438 */
439struct fc_els_rtv_acc {
440 __u8 rtv_cmd; /* command code 0x02 */
441 __u8 rtv_zero[3]; /* specified as zero - part of cmd */
442 __be32 rtv_r_a_tov; /* resource allocation timeout value */
443 __be32 rtv_e_d_tov; /* error detection timeout value */
444 __be32 rtv_toq; /* timeout qualifier (see below) */
445};
446
447/*
448 * rtv_toq bits.
449 */
450#define FC_ELS_RTV_EDRES (1 << 26) /* E_D_TOV resolution is nS else mS */
451#define FC_ELS_RTV_RTTOV (1 << 19) /* R_T_TOV is 100 uS else 100 mS */
452
453/*
454 * ELS_SCR - state change registration payload.
455 */
456struct fc_els_scr {
457 __u8 scr_cmd; /* command code */
458 __u8 scr_resv[6]; /* reserved */
459 __u8 scr_reg_func; /* registration function (see below) */
460};
461
462enum fc_els_scr_func {
463 ELS_SCRF_FAB = 1, /* fabric-detected registration */
464 ELS_SCRF_NPORT = 2, /* Nx_Port-detected registration */
465 ELS_SCRF_FULL = 3, /* full registration */
466 ELS_SCRF_CLEAR = 255, /* remove any current registrations */
467};
468
469/*
470 * ELS_RSCN - registered state change notification payload.
471 */
472struct fc_els_rscn {
473 __u8 rscn_cmd; /* RSCN opcode (0x61) */
474 __u8 rscn_page_len; /* page length (4) */
475 __be16 rscn_plen; /* payload length including this word */
476
477 /* followed by 4-byte generic affected Port_ID pages */
478};
479
480struct fc_els_rscn_page {
481 __u8 rscn_page_flags; /* event and address format */
482 __u8 rscn_fid[3]; /* fabric ID */
483};
484
485#define ELS_RSCN_EV_QUAL_BIT 2 /* shift count for event qualifier */
486#define ELS_RSCN_EV_QUAL_MASK 0xf /* mask for event qualifier */
487#define ELS_RSCN_ADDR_FMT_BIT 0 /* shift count for address format */
488#define ELS_RSCN_ADDR_FMT_MASK 0x3 /* mask for address format */
489
490enum fc_els_rscn_ev_qual {
491 ELS_EV_QUAL_NONE = 0, /* unspecified */
492 ELS_EV_QUAL_NS_OBJ = 1, /* changed name server object */
493 ELS_EV_QUAL_PORT_ATTR = 2, /* changed port attribute */
494 ELS_EV_QUAL_SERV_OBJ = 3, /* changed service object */
495 ELS_EV_QUAL_SW_CONFIG = 4, /* changed switch configuration */
496 ELS_EV_QUAL_REM_OBJ = 5, /* removed object */
497};
498
499enum fc_els_rscn_addr_fmt {
500 ELS_ADDR_FMT_PORT = 0, /* rscn_fid is a port address */
501 ELS_ADDR_FMT_AREA = 1, /* rscn_fid is a area address */
502 ELS_ADDR_FMT_DOM = 2, /* rscn_fid is a domain address */
503 ELS_ADDR_FMT_FAB = 3, /* anything on fabric may have changed */
504};
505
506/*
507 * ELS_RNID - request Node ID.
508 */
509struct fc_els_rnid {
510 __u8 rnid_cmd; /* RNID opcode (0x78) */
511 __u8 rnid_resv[3]; /* reserved */
512 __u8 rnid_fmt; /* data format */
513 __u8 rnid_resv2[3]; /* reserved */
514};
515
516/*
517 * Node Identification Data formats (rnid_fmt)
518 */
519enum fc_els_rnid_fmt {
520 ELS_RNIDF_NONE = 0, /* no specific identification data */
521 ELS_RNIDF_GEN = 0xdf, /* general topology discovery format */
522};
523
524/*
525 * ELS_RNID response.
526 */
527struct fc_els_rnid_resp {
528 __u8 rnid_cmd; /* response code (LS_ACC) */
529 __u8 rnid_resv[3]; /* reserved */
530 __u8 rnid_fmt; /* data format */
531 __u8 rnid_cid_len; /* common ID data length */
532 __u8 rnid_resv2; /* reserved */
533 __u8 rnid_sid_len; /* specific ID data length */
534};
535
536struct fc_els_rnid_cid {
537 __be64 rnid_wwpn; /* N port name */
538 __be64 rnid_wwnn; /* node name */
539};
540
541struct fc_els_rnid_gen {
542 __u8 rnid_vend_id[16]; /* vendor-unique ID */
543 __be32 rnid_atype; /* associated type (see below) */
544 __be32 rnid_phys_port; /* physical port number */
545 __be32 rnid_att_nodes; /* number of attached nodes */
546 __u8 rnid_node_mgmt; /* node management (see below) */
547 __u8 rnid_ip_ver; /* IP version (see below) */
548 __be16 rnid_prot_port; /* UDP / TCP port number */
549 __be32 rnid_ip_addr[4]; /* IP address */
550 __u8 rnid_resvd[2]; /* reserved */
551 __be16 rnid_vend_spec; /* vendor-specific field */
552};
553
554enum fc_els_rnid_atype {
555 ELS_RNIDA_UNK = 0x01, /* unknown */
556 ELS_RNIDA_OTHER = 0x02, /* none of the following */
557 ELS_RNIDA_HUB = 0x03,
558 ELS_RNIDA_SWITCH = 0x04,
559 ELS_RNIDA_GATEWAY = 0x05,
560 ELS_RNIDA_CONV = 0x06, /* Obsolete, do not use this value */
561 ELS_RNIDA_HBA = 0x07, /* Obsolete, do not use this value */
562 ELS_RNIDA_PROXY = 0x08, /* Obsolete, do not use this value */
563 ELS_RNIDA_STORAGE = 0x09,
564 ELS_RNIDA_HOST = 0x0a,
565 ELS_RNIDA_SUBSYS = 0x0b, /* storage subsystem (e.g., RAID) */
566 ELS_RNIDA_ACCESS = 0x0e, /* access device (e.g. media changer) */
567 ELS_RNIDA_NAS = 0x11, /* NAS server */
568 ELS_RNIDA_BRIDGE = 0x12, /* bridge */
569 ELS_RNIDA_VIRT = 0x13, /* virtualization device */
570 ELS_RNIDA_MF = 0xff, /* multifunction device (bits below) */
571 ELS_RNIDA_MF_HUB = 1UL << 31, /* hub */
572 ELS_RNIDA_MF_SW = 1UL << 30, /* switch */
573 ELS_RNIDA_MF_GW = 1UL << 29, /* gateway */
574 ELS_RNIDA_MF_ST = 1UL << 28, /* storage */
575 ELS_RNIDA_MF_HOST = 1UL << 27, /* host */
576 ELS_RNIDA_MF_SUB = 1UL << 26, /* storage subsystem */
577 ELS_RNIDA_MF_ACC = 1UL << 25, /* storage access dev */
578 ELS_RNIDA_MF_WDM = 1UL << 24, /* wavelength division mux */
579 ELS_RNIDA_MF_NAS = 1UL << 23, /* NAS server */
580 ELS_RNIDA_MF_BR = 1UL << 22, /* bridge */
581 ELS_RNIDA_MF_VIRT = 1UL << 21, /* virtualization device */
582};
583
584enum fc_els_rnid_mgmt {
585 ELS_RNIDM_SNMP = 0,
586 ELS_RNIDM_TELNET = 1,
587 ELS_RNIDM_HTTP = 2,
588 ELS_RNIDM_HTTPS = 3,
589 ELS_RNIDM_XML = 4, /* HTTP + XML */
590};
591
592enum fc_els_rnid_ipver {
593 ELS_RNIDIP_NONE = 0, /* no IP support or node mgmt. */
594 ELS_RNIDIP_V4 = 1, /* IPv4 */
595 ELS_RNIDIP_V6 = 2, /* IPv6 */
596};
597
598/*
599 * ELS RPL - Read Port List.
600 */
601struct fc_els_rpl {
602 __u8 rpl_cmd; /* command */
603 __u8 rpl_resv[5]; /* reserved - must be zero */
604 __be16 rpl_max_size; /* maximum response size or zero */
605 __u8 rpl_resv1; /* reserved - must be zero */
606 __u8 rpl_index[3]; /* starting index */
607};
608
609/*
610 * Port number block in RPL response.
611 */
612struct fc_els_pnb {
613 __be32 pnb_phys_pn; /* physical port number */
614 __u8 pnb_resv; /* reserved */
615 __u8 pnb_port_id[3]; /* port ID */
616 __be64 pnb_wwpn; /* port name */
617};
618
619/*
620 * RPL LS_ACC response.
621 */
622struct fc_els_rpl_resp {
623 __u8 rpl_cmd; /* ELS_LS_ACC */
624 __u8 rpl_resv1; /* reserved - must be zero */
625 __be16 rpl_plen; /* payload length */
626 __u8 rpl_resv2; /* reserved - must be zero */
627 __u8 rpl_llen[3]; /* list length */
628 __u8 rpl_resv3; /* reserved - must be zero */
629 __u8 rpl_index[3]; /* starting index */
630 struct fc_els_pnb rpl_pnb[1]; /* variable number of PNBs */
631};
632
633/*
634 * Link Error Status Block.
635 */
636struct fc_els_lesb {
637 __be32 lesb_link_fail; /* link failure count */
638 __be32 lesb_sync_loss; /* loss of synchronization count */
639 __be32 lesb_sig_loss; /* loss of signal count */
640 __be32 lesb_prim_err; /* primitive sequence error count */
641 __be32 lesb_inv_word; /* invalid transmission word count */
642 __be32 lesb_inv_crc; /* invalid CRC count */
643};
644
645/*
646 * ELS RPS - Read Port Status Block request.
647 */
648struct fc_els_rps {
649 __u8 rps_cmd; /* command */
650 __u8 rps_resv[2]; /* reserved - must be zero */
651 __u8 rps_flag; /* flag - see below */
652 __be64 rps_port_spec; /* port selection */
653};
654
655enum fc_els_rps_flag {
656 FC_ELS_RPS_DID = 0x00, /* port identified by D_ID of req. */
657 FC_ELS_RPS_PPN = 0x01, /* port_spec is physical port number */
658 FC_ELS_RPS_WWPN = 0x02, /* port_spec is port WWN */
659};
660
661/*
662 * ELS RPS LS_ACC response.
663 */
664struct fc_els_rps_resp {
665 __u8 rps_cmd; /* command - LS_ACC */
666 __u8 rps_resv[2]; /* reserved - must be zero */
667 __u8 rps_flag; /* flag - see below */
668 __u8 rps_resv2[2]; /* reserved */
669 __be16 rps_status; /* port status - see below */
670 struct fc_els_lesb rps_lesb; /* link error status block */
671};
672
673enum fc_els_rps_resp_flag {
674 FC_ELS_RPS_LPEV = 0x01, /* L_port extension valid */
675};
676
677enum fc_els_rps_resp_status {
678 FC_ELS_RPS_PTP = 1 << 5, /* point-to-point connection */
679 FC_ELS_RPS_LOOP = 1 << 4, /* loop mode */
680 FC_ELS_RPS_FAB = 1 << 3, /* fabric present */
681 FC_ELS_RPS_NO_SIG = 1 << 2, /* loss of signal */
682 FC_ELS_RPS_NO_SYNC = 1 << 1, /* loss of synchronization */
683 FC_ELS_RPS_RESET = 1 << 0, /* in link reset protocol */
684};
685
686/*
687 * ELS LIRR - Link Incident Record Registration request.
688 */
689struct fc_els_lirr {
690 __u8 lirr_cmd; /* command */
691 __u8 lirr_resv[3]; /* reserved - must be zero */
692 __u8 lirr_func; /* registration function */
693 __u8 lirr_fmt; /* FC-4 type of RLIR requested */
694 __u8 lirr_resv2[2]; /* reserved - must be zero */
695};
696
697enum fc_els_lirr_func {
698 ELS_LIRR_SET_COND = 0x01, /* set - conditionally receive */
699 ELS_LIRR_SET_UNCOND = 0x02, /* set - unconditionally receive */
700 ELS_LIRR_CLEAR = 0xff /* clear registration */
701};
702
703/*
704 * ELS SRL - Scan Remote Loop request.
705 */
706struct fc_els_srl {
707 __u8 srl_cmd; /* command */
708 __u8 srl_resv[3]; /* reserved - must be zero */
709 __u8 srl_flag; /* flag - see below */
710 __u8 srl_flag_param[3]; /* flag parameter */
711};
712
713enum fc_els_srl_flag {
714 FC_ELS_SRL_ALL = 0x00, /* scan all FL ports */
715 FC_ELS_SRL_ONE = 0x01, /* scan specified loop */
716 FC_ELS_SRL_EN_PER = 0x02, /* enable periodic scanning (param) */
717 FC_ELS_SRL_DIS_PER = 0x03, /* disable periodic scanning */
718};
719
720/*
721 * ELS RLS - Read Link Error Status Block request.
722 */
723struct fc_els_rls {
724 __u8 rls_cmd; /* command */
725 __u8 rls_resv[4]; /* reserved - must be zero */
726 __u8 rls_port_id[3]; /* port ID */
727};
728
729/*
730 * ELS RLS LS_ACC Response.
731 */
732struct fc_els_rls_resp {
733 __u8 rls_cmd; /* ELS_LS_ACC */
734 __u8 rls_resv[3]; /* reserved - must be zero */
735 struct fc_els_lesb rls_lesb; /* link error status block */
736};
737
738/*
739 * ELS RLIR - Registered Link Incident Report.
740 * This is followed by the CLIR and the CLID, described below.
741 */
742struct fc_els_rlir {
743 __u8 rlir_cmd; /* command */
744 __u8 rlir_resv[3]; /* reserved - must be zero */
745 __u8 rlir_fmt; /* format (FC4-type if type specific) */
746 __u8 rlir_clr_len; /* common link incident record length */
747 __u8 rlir_cld_len; /* common link incident desc. length */
748 __u8 rlir_slr_len; /* spec. link incident record length */
749};
750
751/*
752 * CLIR - Common Link Incident Record Data. - Sent via RLIR.
753 */
754struct fc_els_clir {
755 __be64 clir_wwpn; /* incident port name */
756 __be64 clir_wwnn; /* incident port node name */
757 __u8 clir_port_type; /* incident port type */
758 __u8 clir_port_id[3]; /* incident port ID */
759
760 __be64 clir_conn_wwpn; /* connected port name */
761 __be64 clir_conn_wwnn; /* connected node name */
762 __be64 clir_fab_name; /* fabric name */
763 __be32 clir_phys_port; /* physical port number */
764 __be32 clir_trans_id; /* transaction ID */
765 __u8 clir_resv[3]; /* reserved */
766 __u8 clir_ts_fmt; /* time stamp format */
767 __be64 clir_timestamp; /* time stamp */
768};
769
770/*
771 * CLIR clir_ts_fmt - time stamp format values.
772 */
773enum fc_els_clir_ts_fmt {
774 ELS_CLIR_TS_UNKNOWN = 0, /* time stamp field unknown */
775 ELS_CLIR_TS_SEC_FRAC = 1, /* time in seconds and fractions */
776 ELS_CLIR_TS_CSU = 2, /* time in clock synch update format */
777};
778
779/*
780 * Common Link Incident Descriptor - sent via RLIR.
781 */
782struct fc_els_clid {
783 __u8 clid_iq; /* incident qualifier flags */
784 __u8 clid_ic; /* incident code */
785 __be16 clid_epai; /* domain/area of ISL */
786};
787
788/*
789 * CLID incident qualifier flags.
790 */
791enum fc_els_clid_iq {
792 ELS_CLID_SWITCH = 0x20, /* incident port is a switch node */
793 ELS_CLID_E_PORT = 0x10, /* incident is an ISL (E) port */
794 ELS_CLID_SEV_MASK = 0x0c, /* severity 2-bit field mask */
795 ELS_CLID_SEV_INFO = 0x00, /* report is informational */
796 ELS_CLID_SEV_INOP = 0x08, /* link not operational */
797 ELS_CLID_SEV_DEG = 0x04, /* link degraded but operational */
798 ELS_CLID_LASER = 0x02, /* subassembly is a laser */
799 ELS_CLID_FRU = 0x01, /* format can identify a FRU */
800};
801
802/*
803 * CLID incident code.
804 */
805enum fc_els_clid_ic {
806 ELS_CLID_IC_IMPL = 1, /* implicit incident */
807 ELS_CLID_IC_BER = 2, /* bit-error-rate threshold exceeded */
808 ELS_CLID_IC_LOS = 3, /* loss of synch or signal */
809 ELS_CLID_IC_NOS = 4, /* non-operational primitive sequence */
810 ELS_CLID_IC_PST = 5, /* primitive sequence timeout */
811 ELS_CLID_IC_INVAL = 6, /* invalid primitive sequence */
812 ELS_CLID_IC_LOOP_TO = 7, /* loop initialization time out */
813 ELS_CLID_IC_LIP = 8, /* receiving LIP */
814};
815
816#endif /* _FC_ELS_H_ */
diff --git a/include/scsi/fc/fc_encaps.h b/include/scsi/fc/fc_encaps.h
new file mode 100644
index 000000000000..f180c3e16220
--- /dev/null
+++ b/include/scsi/fc/fc_encaps.h
@@ -0,0 +1,138 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19#ifndef _FC_ENCAPS_H_
20#define _FC_ENCAPS_H_
21
22/*
23 * Protocol definitions from RFC 3643 - Fibre Channel Frame Encapsulation.
24 *
25 * Note: The frame length field is the number of 32-bit words in
26 * the encapsulation including the fcip_encaps_header, CRC and EOF words.
27 * The minimum frame length value in bytes is (32 + 24 + 4 + 4) * 4 = 64.
28 * The maximum frame length value in bytes is (32 + 24 + 2112 + 4 + 4) = 2172.
29 */
30#define FC_ENCAPS_MIN_FRAME_LEN 64 /* min frame len (bytes) (see above) */
31#define FC_ENCAPS_MAX_FRAME_LEN (FC_ENCAPS_MIN_FRAME_LEN + FC_MAX_PAYLOAD)
32
33#define FC_ENCAPS_VER 1 /* current version number */
34
35struct fc_encaps_hdr {
36 __u8 fc_proto; /* protocol number */
37 __u8 fc_ver; /* version of encapsulation */
38 __u8 fc_proto_n; /* ones complement of protocol */
39 __u8 fc_ver_n; /* ones complement of version */
40
41 unsigned char fc_proto_data[8]; /* protocol specific data */
42
43 __be16 fc_len_flags; /* 10-bit length/4 w/ 6 flag bits */
44 __be16 fc_len_flags_n; /* ones complement of length / flags */
45
46 /*
47 * Offset 0x10
48 */
49 __be32 fc_time[2]; /* time stamp: seconds and fraction */
50 __be32 fc_crc; /* CRC */
51 __be32 fc_sof; /* start of frame (see FC_SOF below) */
52
53 /* 0x20 - FC frame content followed by EOF word */
54};
55
56#define FCIP_ENCAPS_HDR_LEN 0x20 /* expected length for asserts */
57
58/*
59 * Macro's for making redundant copies of EOF and SOF.
60 */
61#define FC_XY(x, y) ((((x) & 0xff) << 8) | ((y) & 0xff))
62#define FC_XYXY(x, y) ((FCIP_XY(x, y) << 16) | FCIP_XY(x, y))
63#define FC_XYNN(x, y) (FCIP_XYXY(x, y) ^ 0xffff)
64
65#define FC_SOF_ENCODE(n) FC_XYNN(n, n)
66#define FC_EOF_ENCODE(n) FC_XYNN(n, n)
67
68/*
69 * SOF / EOF bytes.
70 */
71enum fc_sof {
72 FC_SOF_F = 0x28, /* fabric */
73 FC_SOF_I4 = 0x29, /* initiate class 4 */
74 FC_SOF_I2 = 0x2d, /* initiate class 2 */
75 FC_SOF_I3 = 0x2e, /* initiate class 3 */
76 FC_SOF_N4 = 0x31, /* normal class 4 */
77 FC_SOF_N2 = 0x35, /* normal class 2 */
78 FC_SOF_N3 = 0x36, /* normal class 3 */
79 FC_SOF_C4 = 0x39, /* activate class 4 */
80} __attribute__((packed));
81
82enum fc_eof {
83 FC_EOF_N = 0x41, /* normal (not last frame of seq) */
84 FC_EOF_T = 0x42, /* terminate (last frame of sequence) */
85 FC_EOF_RT = 0x44,
86 FC_EOF_DT = 0x46, /* disconnect-terminate class-1 */
87 FC_EOF_NI = 0x49, /* normal-invalid */
88 FC_EOF_DTI = 0x4e, /* disconnect-terminate-invalid */
89 FC_EOF_RTI = 0x4f,
90 FC_EOF_A = 0x50, /* abort */
91} __attribute__((packed));
92
93#define FC_SOF_CLASS_MASK 0x06 /* mask for class of service in SOF */
94
95/*
96 * Define classes in terms of the SOF code (initial).
97 */
98enum fc_class {
99 FC_CLASS_NONE = 0, /* software value indicating no class */
100 FC_CLASS_2 = FC_SOF_I2,
101 FC_CLASS_3 = FC_SOF_I3,
102 FC_CLASS_4 = FC_SOF_I4,
103 FC_CLASS_F = FC_SOF_F,
104};
105
106/*
107 * Determine whether SOF code indicates the need for a BLS ACK.
108 */
109static inline int fc_sof_needs_ack(enum fc_sof sof)
110{
111 return (~sof) & 0x02; /* true for class 1, 2, 4, 6, or F */
112}
113
114/*
115 * Given an fc_class, return the normal (non-initial) SOF value.
116 */
117static inline enum fc_sof fc_sof_normal(enum fc_class class)
118{
119 return class + FC_SOF_N3 - FC_SOF_I3; /* diff is always 8 */
120}
121
122/*
123 * Compute class from SOF value.
124 */
125static inline enum fc_class fc_sof_class(enum fc_sof sof)
126{
127 return (sof & 0x7) | FC_SOF_F;
128}
129
130/*
131 * Determine whether SOF is for the initial frame of a sequence.
132 */
133static inline int fc_sof_is_init(enum fc_sof sof)
134{
135 return sof < 0x30;
136}
137
138#endif /* _FC_ENCAPS_H_ */
diff --git a/include/scsi/fc/fc_fc2.h b/include/scsi/fc/fc_fc2.h
new file mode 100644
index 000000000000..cff8a8c22f50
--- /dev/null
+++ b/include/scsi/fc/fc_fc2.h
@@ -0,0 +1,124 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_FC2_H_
21#define _FC_FC2_H_
22
23/*
24 * Fibre Channel Exchanges and Sequences.
25 */
26#ifndef PACKED
27#define PACKED __attribute__ ((__packed__))
28#endif /* PACKED */
29
30
31/*
32 * Sequence Status Block.
33 * This format is set by the FC-FS standard and is sent over the wire.
34 * Note that the fields aren't all naturally aligned.
35 */
36struct fc_ssb {
37 __u8 ssb_seq_id; /* sequence ID */
38 __u8 _ssb_resvd;
39 __be16 ssb_low_seq_cnt; /* lowest SEQ_CNT */
40
41 __be16 ssb_high_seq_cnt; /* highest SEQ_CNT */
42 __be16 ssb_s_stat; /* sequence status flags */
43
44 __be16 ssb_err_seq_cnt; /* error SEQ_CNT */
45 __u8 ssb_fh_cs_ctl; /* frame header CS_CTL */
46 __be16 ssb_fh_ox_id; /* frame header OX_ID */
47 __be16 ssb_rx_id; /* responder's exchange ID */
48 __u8 _ssb_resvd2[2];
49} PACKED;
50
51/*
52 * The SSB should be 17 bytes. Since it's layout is somewhat strange,
53 * we define the size here so that code can ASSERT that the size comes out
54 * correct.
55 */
56#define FC_SSB_SIZE 17 /* length of fc_ssb for assert */
57
58/*
59 * ssb_s_stat - flags from FC-FS-2 T11/1619-D Rev 0.90.
60 */
61#define SSB_ST_RESP (1 << 15) /* sequence responder */
62#define SSB_ST_ACTIVE (1 << 14) /* sequence is active */
63#define SSB_ST_ABNORMAL (1 << 12) /* abnormal ending condition */
64
65#define SSB_ST_REQ_MASK (3 << 10) /* ACK, abort sequence condition */
66#define SSB_ST_REQ_CONT (0 << 10)
67#define SSB_ST_REQ_ABORT (1 << 10)
68#define SSB_ST_REQ_STOP (2 << 10)
69#define SSB_ST_REQ_RETRANS (3 << 10)
70
71#define SSB_ST_ABTS (1 << 9) /* ABTS protocol completed */
72#define SSB_ST_RETRANS (1 << 8) /* retransmission completed */
73#define SSB_ST_TIMEOUT (1 << 7) /* sequence timed out by recipient */
74#define SSB_ST_P_RJT (1 << 6) /* P_RJT transmitted */
75
76#define SSB_ST_CLASS_BIT 4 /* class of service field LSB */
77#define SSB_ST_CLASS_MASK 3 /* class of service mask */
78#define SSB_ST_ACK (1 << 3) /* ACK (EOFt or EOFdt) transmitted */
79
80/*
81 * Exchange Status Block.
82 * This format is set by the FC-FS standard and is sent over the wire.
83 * Note that the fields aren't all naturally aligned.
84 */
85struct fc_esb {
86 __u8 esb_cs_ctl; /* CS_CTL for frame header */
87 __be16 esb_ox_id; /* originator exchange ID */
88 __be16 esb_rx_id; /* responder exchange ID */
89 __be32 esb_orig_fid; /* fabric ID of originator */
90 __be32 esb_resp_fid; /* fabric ID of responder */
91 __be32 esb_e_stat; /* status */
92 __u8 _esb_resvd[4];
93 __u8 esb_service_params[112]; /* TBD */
94 __u8 esb_seq_status[8]; /* sequence statuses, 8 bytes each */
95} __attribute__((packed));;
96
97
98/*
99 * Define expected size for ASSERTs.
100 * See comments on FC_SSB_SIZE.
101 */
102#define FC_ESB_SIZE (1 + 5*4 + 112 + 8) /* expected size */
103
104/*
105 * esb_e_stat - flags from FC-FS-2 T11/1619-D Rev 0.90.
106 */
107#define ESB_ST_RESP (1 << 31) /* responder to exchange */
108#define ESB_ST_SEQ_INIT (1 << 30) /* port holds sequence initiaive */
109#define ESB_ST_COMPLETE (1 << 29) /* exchange is complete */
110#define ESB_ST_ABNORMAL (1 << 28) /* abnormal ending condition */
111#define ESB_ST_REC_QUAL (1 << 26) /* recovery qualifier active */
112
113#define ESB_ST_ERRP_BIT 24 /* LSB for error policy */
114#define ESB_ST_ERRP_MASK (3 << 24) /* mask for error policy */
115#define ESB_ST_ERRP_MULT (0 << 24) /* abort, discard multiple sequences */
116#define ESB_ST_ERRP_SING (1 << 24) /* abort, discard single sequence */
117#define ESB_ST_ERRP_INF (2 << 24) /* process with infinite buffers */
118#define ESB_ST_ERRP_IMM (3 << 24) /* discard mult. with immed. retran. */
119
120#define ESB_ST_OX_ID_INVL (1 << 23) /* originator XID invalid */
121#define ESB_ST_RX_ID_INVL (1 << 22) /* responder XID invalid */
122#define ESB_ST_PRI_INUSE (1 << 21) /* priority / preemption in use */
123
124#endif /* _FC_FC2_H_ */
diff --git a/include/scsi/fc/fc_fcoe.h b/include/scsi/fc/fc_fcoe.h
new file mode 100644
index 000000000000..57aaa8f0d613
--- /dev/null
+++ b/include/scsi/fc/fc_fcoe.h
@@ -0,0 +1,114 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_FCOE_H_
21#define _FC_FCOE_H_
22
23/*
24 * FCoE - Fibre Channel over Ethernet.
25 */
26
27/*
28 * The FCoE ethertype eventually goes in net/if_ether.h.
29 */
30#ifndef ETH_P_FCOE
31#define ETH_P_FCOE 0x8906 /* FCOE ether type */
32#endif
33
34#ifndef ETH_P_8021Q
35#define ETH_P_8021Q 0x8100
36#endif
37
38/*
39 * FC_FCOE_OUI hasn't been standardized yet. XXX TBD.
40 */
41#ifndef FC_FCOE_OUI
42#define FC_FCOE_OUI 0x0efc00 /* upper 24 bits of FCOE dest MAC TBD */
43#endif
44
45/*
46 * The destination MAC address for the fabric login may get a different OUI.
47 * This isn't standardized yet.
48 */
49#ifndef FC_FCOE_FLOGI_MAC
50/* gateway MAC - TBD */
51#define FC_FCOE_FLOGI_MAC { 0x0e, 0xfc, 0x00, 0xff, 0xff, 0xfe }
52#endif
53
54#define FC_FCOE_VER 0 /* version */
55
56/*
57 * Ethernet Addresses based on FC S_ID and D_ID.
58 * Generated by FC_FCOE_OUI | S_ID/D_ID
59 */
60#define FC_FCOE_ENCAPS_ID(n) (((u64) FC_FCOE_OUI << 24) | (n))
61#define FC_FCOE_DECAPS_ID(n) ((n) >> 24)
62
63/*
64 * FCoE frame header - 14 bytes
65 *
66 * This is the August 2007 version of the FCoE header as defined by T11.
67 * This follows the VLAN header, which includes the ethertype.
68 */
69struct fcoe_hdr {
70 __u8 fcoe_ver; /* version field - upper 4 bits */
71 __u8 fcoe_resvd[12]; /* reserved - send zero and ignore */
72 __u8 fcoe_sof; /* start of frame per RFC 3643 */
73};
74
75#define FC_FCOE_DECAPS_VER(hp) ((hp)->fcoe_ver >> 4)
76#define FC_FCOE_ENCAPS_VER(hp, ver) ((hp)->fcoe_ver = (ver) << 4)
77
78/*
79 * FCoE CRC & EOF - 8 bytes.
80 */
81struct fcoe_crc_eof {
82 __le32 fcoe_crc32; /* CRC for FC packet */
83 __u8 fcoe_eof; /* EOF from RFC 3643 */
84 __u8 fcoe_resvd[3]; /* reserved - send zero and ignore */
85} __attribute__((packed));
86
87/*
88 * Minimum FCoE + FC header length
89 * 14 bytes FCoE header + 24 byte FC header = 38 bytes
90 */
91#define FCOE_HEADER_LEN 38
92
93/*
94 * Minimum FCoE frame size
95 * 14 bytes FCoE header + 24 byte FC header + 8 byte FCoE trailer = 46 bytes
96 */
97#define FCOE_MIN_FRAME 46
98
99/*
100 * fc_fcoe_set_mac - Store OUI + DID into MAC address field.
101 * @mac: mac address to be set
102 * @did: fc dest id to use
103 */
104static inline void fc_fcoe_set_mac(u8 *mac, u8 *did)
105{
106 mac[0] = (u8) (FC_FCOE_OUI >> 16);
107 mac[1] = (u8) (FC_FCOE_OUI >> 8);
108 mac[2] = (u8) FC_FCOE_OUI;
109 mac[3] = did[0];
110 mac[4] = did[1];
111 mac[5] = did[2];
112}
113
114#endif /* _FC_FCOE_H_ */
diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h
new file mode 100644
index 000000000000..5d38f1989f37
--- /dev/null
+++ b/include/scsi/fc/fc_fcp.h
@@ -0,0 +1,199 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_FCP_H_
21#define _FC_FCP_H_
22
23/*
24 * Fibre Channel Protocol for SCSI.
25 * From T10 FCP-3, T10 project 1560-D Rev 4, Sept. 13, 2005.
26 */
27
28/*
29 * fc/fs.h defines FC_TYPE_FCP.
30 */
31
32/*
33 * Service parameter page parameters (word 3 bits) for Process Login.
34 */
35#define FCP_SPPF_TASK_RETRY_ID 0x0200 /* task retry ID requested */
36#define FCP_SPPF_RETRY 0x0100 /* retry supported */
37#define FCP_SPPF_CONF_COMPL 0x0080 /* confirmed completion allowed */
38#define FCP_SPPF_OVLY_ALLOW 0x0040 /* data overlay allowed */
39#define FCP_SPPF_INIT_FCN 0x0020 /* initiator function */
40#define FCP_SPPF_TARG_FCN 0x0010 /* target function */
41#define FCP_SPPF_RD_XRDY_DIS 0x0002 /* disable XFER_RDY for reads */
42#define FCP_SPPF_WR_XRDY_DIS 0x0001 /* disable XFER_RDY for writes */
43
44/*
45 * FCP_CMND IU Payload.
46 */
47struct fcp_cmnd {
48 __u8 fc_lun[8]; /* logical unit number */
49 __u8 fc_cmdref; /* commmand reference number */
50 __u8 fc_pri_ta; /* priority and task attribute */
51 __u8 fc_tm_flags; /* task management flags */
52 __u8 fc_flags; /* additional len & flags */
53 __u8 fc_cdb[16]; /* base CDB */
54 __be32 fc_dl; /* data length (must follow fc_cdb) */
55};
56
57#define FCP_CMND_LEN 32 /* expected length of structure */
58
59struct fcp_cmnd32 {
60 __u8 fc_lun[8]; /* logical unit number */
61 __u8 fc_cmdref; /* commmand reference number */
62 __u8 fc_pri_ta; /* priority and task attribute */
63 __u8 fc_tm_flags; /* task management flags */
64 __u8 fc_flags; /* additional len & flags */
65 __u8 fc_cdb[32]; /* base CDB */
66 __be32 fc_dl; /* data length (must follow fc_cdb) */
67};
68
69#define FCP_CMND32_LEN 48 /* expected length of structure */
70#define FCP_CMND32_ADD_LEN (16 / 4) /* Additional cdb length */
71
72/*
73 * fc_pri_ta.
74 */
75#define FCP_PTA_SIMPLE 0 /* simple task attribute */
76#define FCP_PTA_HEADQ 1 /* head of queue task attribute */
77#define FCP_PTA_ORDERED 2 /* ordered task attribute */
78#define FCP_PTA_ACA 4 /* auto. contigent allegiance */
79#define FCP_PRI_SHIFT 3 /* priority field starts in bit 3 */
80#define FCP_PRI_RESVD_MASK 0x80 /* reserved bits in priority field */
81
82/*
83 * fc_tm_flags - task management flags field.
84 */
85#define FCP_TMF_CLR_ACA 0x40 /* clear ACA condition */
86#define FCP_TMF_LUN_RESET 0x10 /* logical unit reset task management */
87#define FCP_TMF_CLR_TASK_SET 0x04 /* clear task set */
88#define FCP_TMF_ABT_TASK_SET 0x02 /* abort task set */
89
90/*
91 * fc_flags.
92 * Bits 7:2 are the additional FCP_CDB length / 4.
93 */
94#define FCP_CFL_LEN_MASK 0xfc /* mask for additional length */
95#define FCP_CFL_LEN_SHIFT 2 /* shift bits for additional length */
96#define FCP_CFL_RDDATA 0x02 /* read data */
97#define FCP_CFL_WRDATA 0x01 /* write data */
98
99/*
100 * FCP_TXRDY IU - transfer ready payload.
101 */
102struct fcp_txrdy {
103 __be32 ft_data_ro; /* data relative offset */
104 __be32 ft_burst_len; /* burst length */
105 __u8 _ft_resvd[4]; /* reserved */
106};
107
108#define FCP_TXRDY_LEN 12 /* expected length of structure */
109
110/*
111 * FCP_RESP IU - response payload.
112 *
113 * The response payload comes in three parts: the flags/status, the
114 * sense/response lengths and the sense data/response info section.
115 *
116 * From FCP3r04, note 6 of section 9.5.13:
117 *
118 * Some early implementations presented the FCP_RSP IU without the FCP_RESID,
119 * FCP_SNS_LEN, and FCP_RSP_LEN fields if the FCP_RESID_UNDER, FCP_RESID_OVER,
120 * FCP_SNS_LEN_VALID, and FCP_RSP_LEN_VALID bits were all set to zero. This
121 * non-standard behavior should be tolerated.
122 *
123 * All response frames will always contain the fcp_resp template. Some
124 * will also include the fcp_resp_len template.
125 */
126struct fcp_resp {
127 __u8 _fr_resvd[8]; /* reserved */
128 __be16 fr_retry_delay; /* retry delay timer */
129 __u8 fr_flags; /* flags */
130 __u8 fr_status; /* SCSI status code */
131};
132
133#define FCP_RESP_LEN 12 /* expected length of structure */
134
135struct fcp_resp_ext {
136 __be32 fr_resid; /* Residual value */
137 __be32 fr_sns_len; /* SCSI Sense length */
138 __be32 fr_rsp_len; /* Response Info length */
139
140 /*
141 * Optionally followed by RSP info and/or SNS info and/or
142 * bidirectional read residual length, if any.
143 */
144};
145
146#define FCP_RESP_EXT_LEN 12 /* expected length of the structure */
147
148struct fcp_resp_rsp_info {
149 __u8 _fr_resvd[3]; /* reserved */
150 __u8 rsp_code; /* Response Info Code */
151 __u8 _fr_resvd2[4]; /* reserved */
152};
153
154struct fcp_resp_with_ext {
155 struct fcp_resp resp;
156 struct fcp_resp_ext ext;
157};
158
159#define FCP_RESP_WITH_EXT (FCP_RESP_LEN + FCP_RESP_EXT_LEN)
160
161/*
162 * fr_flags.
163 */
164#define FCP_BIDI_RSP 0x80 /* bidirectional read response */
165#define FCP_BIDI_READ_UNDER 0x40 /* bidir. read less than requested */
166#define FCP_BIDI_READ_OVER 0x20 /* DL insufficient for full transfer */
167#define FCP_CONF_REQ 0x10 /* confirmation requested */
168#define FCP_RESID_UNDER 0x08 /* transfer shorter than expected */
169#define FCP_RESID_OVER 0x04 /* DL insufficient for full transfer */
170#define FCP_SNS_LEN_VAL 0x02 /* SNS_LEN field is valid */
171#define FCP_RSP_LEN_VAL 0x01 /* RSP_LEN field is valid */
172
173/*
174 * rsp_codes
175 */
176enum fcp_resp_rsp_codes {
177 FCP_TMF_CMPL = 0,
178 FCP_DATA_LEN_INVALID = 1,
179 FCP_CMND_FIELDS_INVALID = 2,
180 FCP_DATA_PARAM_MISMATCH = 3,
181 FCP_TMF_REJECTED = 4,
182 FCP_TMF_FAILED = 5,
183 FCP_TMF_INVALID_LUN = 9,
184};
185
186/*
187 * FCP SRR Link Service request - Sequence Retransmission Request.
188 */
189struct fcp_srr {
190 __u8 srr_op; /* opcode ELS_SRR */
191 __u8 srr_resvd[3]; /* opcode / reserved - must be zero */
192 __be16 srr_ox_id; /* OX_ID of failed command */
193 __be16 srr_rx_id; /* RX_ID of failed command */
194 __be32 srr_rel_off; /* relative offset */
195 __u8 srr_r_ctl; /* r_ctl for the information unit */
196 __u8 srr_resvd2[3]; /* reserved */
197};
198
199#endif /* _FC_FCP_H_ */
diff --git a/include/scsi/fc/fc_fs.h b/include/scsi/fc/fc_fs.h
new file mode 100644
index 000000000000..3e4801d2bdbb
--- /dev/null
+++ b/include/scsi/fc/fc_fs.h
@@ -0,0 +1,340 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_FS_H_
21#define _FC_FS_H_
22
23/*
24 * Fibre Channel Framing and Signalling definitions.
25 * From T11 FC-FS-2 Rev 0.90 - 9 August 2005.
26 */
27
28/*
29 * Frame header
30 */
31struct fc_frame_header {
32 __u8 fh_r_ctl; /* routing control */
33 __u8 fh_d_id[3]; /* Destination ID */
34
35 __u8 fh_cs_ctl; /* class of service control / pri */
36 __u8 fh_s_id[3]; /* Source ID */
37
38 __u8 fh_type; /* see enum fc_fh_type below */
39 __u8 fh_f_ctl[3]; /* frame control */
40
41 __u8 fh_seq_id; /* sequence ID */
42 __u8 fh_df_ctl; /* data field control */
43 __be16 fh_seq_cnt; /* sequence count */
44
45 __be16 fh_ox_id; /* originator exchange ID */
46 __be16 fh_rx_id; /* responder exchange ID */
47 __be32 fh_parm_offset; /* parameter or relative offset */
48};
49
50#define FC_FRAME_HEADER_LEN 24 /* expected length of structure */
51
52#define FC_MAX_PAYLOAD 2112U /* max payload length in bytes */
53#define FC_MIN_MAX_PAYLOAD 256U /* lower limit on max payload */
54
55#define FC_MAX_FRAME (FC_MAX_PAYLOAD + FC_FRAME_HEADER_LEN)
56#define FC_MIN_MAX_FRAME (FC_MIN_MAX_PAYLOAD + FC_FRAME_HEADER_LEN)
57
58/*
59 * fh_r_ctl - Routing control definitions.
60 */
61 /*
62 * FC-4 device_data.
63 */
64enum fc_rctl {
65 FC_RCTL_DD_UNCAT = 0x00, /* uncategorized information */
66 FC_RCTL_DD_SOL_DATA = 0x01, /* solicited data */
67 FC_RCTL_DD_UNSOL_CTL = 0x02, /* unsolicited control */
68 FC_RCTL_DD_SOL_CTL = 0x03, /* solicited control or reply */
69 FC_RCTL_DD_UNSOL_DATA = 0x04, /* unsolicited data */
70 FC_RCTL_DD_DATA_DESC = 0x05, /* data descriptor */
71 FC_RCTL_DD_UNSOL_CMD = 0x06, /* unsolicited command */
72 FC_RCTL_DD_CMD_STATUS = 0x07, /* command status */
73
74#define FC_RCTL_ILS_REQ FC_RCTL_DD_UNSOL_CTL /* ILS request */
75#define FC_RCTL_ILS_REP FC_RCTL_DD_SOL_CTL /* ILS reply */
76
77 /*
78 * Extended Link_Data
79 */
80 FC_RCTL_ELS_REQ = 0x22, /* extended link services request */
81 FC_RCTL_ELS_REP = 0x23, /* extended link services reply */
82 FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */
83 FC_RCTL_ELS4_REP = 0x33, /* FC-4 ELS reply */
84 /*
85 * Optional Extended Headers
86 */
87 FC_RCTL_VFTH = 0x50, /* virtual fabric tagging header */
88 FC_RCTL_IFRH = 0x51, /* inter-fabric routing header */
89 FC_RCTL_ENCH = 0x52, /* encapsulation header */
90 /*
91 * Basic Link Services fh_r_ctl values.
92 */
93 FC_RCTL_BA_NOP = 0x80, /* basic link service NOP */
94 FC_RCTL_BA_ABTS = 0x81, /* basic link service abort */
95 FC_RCTL_BA_RMC = 0x82, /* remove connection */
96 FC_RCTL_BA_ACC = 0x84, /* basic accept */
97 FC_RCTL_BA_RJT = 0x85, /* basic reject */
98 FC_RCTL_BA_PRMT = 0x86, /* dedicated connection preempted */
99 /*
100 * Link Control Information.
101 */
102 FC_RCTL_ACK_1 = 0xc0, /* acknowledge_1 */
103 FC_RCTL_ACK_0 = 0xc1, /* acknowledge_0 */
104 FC_RCTL_P_RJT = 0xc2, /* port reject */
105 FC_RCTL_F_RJT = 0xc3, /* fabric reject */
106 FC_RCTL_P_BSY = 0xc4, /* port busy */
107 FC_RCTL_F_BSY = 0xc5, /* fabric busy to data frame */
108 FC_RCTL_F_BSYL = 0xc6, /* fabric busy to link control frame */
109 FC_RCTL_LCR = 0xc7, /* link credit reset */
110 FC_RCTL_END = 0xc9, /* end */
111};
112 /* incomplete list of definitions */
113
114/*
115 * R_CTL names initializer.
116 * Please keep this matching the above definitions.
117 */
118#define FC_RCTL_NAMES_INIT { \
119 [FC_RCTL_DD_UNCAT] = "uncat", \
120 [FC_RCTL_DD_SOL_DATA] = "sol data", \
121 [FC_RCTL_DD_UNSOL_CTL] = "unsol ctl", \
122 [FC_RCTL_DD_SOL_CTL] = "sol ctl/reply", \
123 [FC_RCTL_DD_UNSOL_DATA] = "unsol data", \
124 [FC_RCTL_DD_DATA_DESC] = "data desc", \
125 [FC_RCTL_DD_UNSOL_CMD] = "unsol cmd", \
126 [FC_RCTL_DD_CMD_STATUS] = "cmd status", \
127 [FC_RCTL_ELS_REQ] = "ELS req", \
128 [FC_RCTL_ELS_REP] = "ELS rep", \
129 [FC_RCTL_ELS4_REQ] = "FC-4 ELS req", \
130 [FC_RCTL_ELS4_REP] = "FC-4 ELS rep", \
131 [FC_RCTL_BA_NOP] = "BLS NOP", \
132 [FC_RCTL_BA_ABTS] = "BLS abort", \
133 [FC_RCTL_BA_RMC] = "BLS remove connection", \
134 [FC_RCTL_BA_ACC] = "BLS accept", \
135 [FC_RCTL_BA_RJT] = "BLS reject", \
136 [FC_RCTL_BA_PRMT] = "BLS dedicated connection preempted", \
137 [FC_RCTL_ACK_1] = "LC ACK_1", \
138 [FC_RCTL_ACK_0] = "LC ACK_0", \
139 [FC_RCTL_P_RJT] = "LC port reject", \
140 [FC_RCTL_F_RJT] = "LC fabric reject", \
141 [FC_RCTL_P_BSY] = "LC port busy", \
142 [FC_RCTL_F_BSY] = "LC fabric busy to data frame", \
143 [FC_RCTL_F_BSYL] = "LC fabric busy to link control frame",\
144 [FC_RCTL_LCR] = "LC link credit reset", \
145 [FC_RCTL_END] = "LC end", \
146}
147
148/*
149 * Well-known fabric addresses.
150 */
151enum fc_well_known_fid {
152 FC_FID_BCAST = 0xffffff, /* broadcast */
153 FC_FID_FLOGI = 0xfffffe, /* fabric login */
154 FC_FID_FCTRL = 0xfffffd, /* fabric controller */
155 FC_FID_DIR_SERV = 0xfffffc, /* directory server */
156 FC_FID_TIME_SERV = 0xfffffb, /* time server */
157 FC_FID_MGMT_SERV = 0xfffffa, /* management server */
158 FC_FID_QOS = 0xfffff9, /* QoS Facilitator */
159 FC_FID_ALIASES = 0xfffff8, /* alias server (FC-PH2) */
160 FC_FID_SEC_KEY = 0xfffff7, /* Security key dist. server */
161 FC_FID_CLOCK = 0xfffff6, /* clock synch server */
162 FC_FID_MCAST_SERV = 0xfffff5, /* multicast server */
163};
164
165#define FC_FID_WELL_KNOWN_MAX 0xffffff /* highest well-known fabric ID */
166#define FC_FID_WELL_KNOWN_BASE 0xfffff5 /* start of well-known fabric ID */
167
168/*
169 * Other well-known addresses, outside the above contiguous range.
170 */
171#define FC_FID_DOM_MGR 0xfffc00 /* domain manager base */
172
173/*
174 * Fabric ID bytes.
175 */
176#define FC_FID_DOMAIN 0
177#define FC_FID_PORT 1
178#define FC_FID_LINK 2
179
180/*
181 * fh_type codes
182 */
183enum fc_fh_type {
184 FC_TYPE_BLS = 0x00, /* basic link service */
185 FC_TYPE_ELS = 0x01, /* extended link service */
186 FC_TYPE_IP = 0x05, /* IP over FC, RFC 4338 */
187 FC_TYPE_FCP = 0x08, /* SCSI FCP */
188 FC_TYPE_CT = 0x20, /* Fibre Channel Services (FC-CT) */
189 FC_TYPE_ILS = 0x22, /* internal link service */
190};
191
192/*
193 * FC_TYPE names initializer.
194 * Please keep this matching the above definitions.
195 */
196#define FC_TYPE_NAMES_INIT { \
197 [FC_TYPE_BLS] = "BLS", \
198 [FC_TYPE_ELS] = "ELS", \
199 [FC_TYPE_IP] = "IP", \
200 [FC_TYPE_FCP] = "FCP", \
201 [FC_TYPE_CT] = "CT", \
202 [FC_TYPE_ILS] = "ILS", \
203}
204
205/*
206 * Exchange IDs.
207 */
208#define FC_XID_UNKNOWN 0xffff /* unknown exchange ID */
209#define FC_XID_MIN 0x0 /* supported min exchange ID */
210#define FC_XID_MAX 0xfffe /* supported max exchange ID */
211
212/*
213 * fh_f_ctl - Frame control flags.
214 */
215#define FC_FC_EX_CTX (1 << 23) /* sent by responder to exchange */
216#define FC_FC_SEQ_CTX (1 << 22) /* sent by responder to sequence */
217#define FC_FC_FIRST_SEQ (1 << 21) /* first sequence of this exchange */
218#define FC_FC_LAST_SEQ (1 << 20) /* last sequence of this exchange */
219#define FC_FC_END_SEQ (1 << 19) /* last frame of sequence */
220#define FC_FC_END_CONN (1 << 18) /* end of class 1 connection pending */
221#define FC_FC_RES_B17 (1 << 17) /* reserved */
222#define FC_FC_SEQ_INIT (1 << 16) /* transfer of sequence initiative */
223#define FC_FC_X_ID_REASS (1 << 15) /* exchange ID has been changed */
224#define FC_FC_X_ID_INVAL (1 << 14) /* exchange ID invalidated */
225
226#define FC_FC_ACK_1 (1 << 12) /* 13:12 = 1: ACK_1 expected */
227#define FC_FC_ACK_N (2 << 12) /* 13:12 = 2: ACK_N expected */
228#define FC_FC_ACK_0 (3 << 12) /* 13:12 = 3: ACK_0 expected */
229
230#define FC_FC_RES_B11 (1 << 11) /* reserved */
231#define FC_FC_RES_B10 (1 << 10) /* reserved */
232#define FC_FC_RETX_SEQ (1 << 9) /* retransmitted sequence */
233#define FC_FC_UNI_TX (1 << 8) /* unidirectional transmit (class 1) */
234#define FC_FC_CONT_SEQ(i) ((i) << 6)
235#define FC_FC_ABT_SEQ(i) ((i) << 4)
236#define FC_FC_REL_OFF (1 << 3) /* parameter is relative offset */
237#define FC_FC_RES2 (1 << 2) /* reserved */
238#define FC_FC_FILL(i) ((i) & 3) /* 1:0: bytes of trailing fill */
239
240/*
241 * BA_ACC payload.
242 */
243struct fc_ba_acc {
244 __u8 ba_seq_id_val; /* SEQ_ID validity */
245#define FC_BA_SEQ_ID_VAL 0x80
246 __u8 ba_seq_id; /* SEQ_ID of seq last deliverable */
247 __u8 ba_resvd[2]; /* reserved */
248 __be16 ba_ox_id; /* OX_ID for aborted seq or exch */
249 __be16 ba_rx_id; /* RX_ID for aborted seq or exch */
250 __be16 ba_low_seq_cnt; /* low SEQ_CNT of aborted seq */
251 __be16 ba_high_seq_cnt; /* high SEQ_CNT of aborted seq */
252};
253
254/*
255 * BA_RJT: Basic Reject payload.
256 */
257struct fc_ba_rjt {
258 __u8 br_resvd; /* reserved */
259 __u8 br_reason; /* reason code */
260 __u8 br_explan; /* reason explanation */
261 __u8 br_vendor; /* vendor unique code */
262};
263
264/*
265 * BA_RJT reason codes.
266 * From FS-2.
267 */
268enum fc_ba_rjt_reason {
269 FC_BA_RJT_NONE = 0, /* in software this means no reject */
270 FC_BA_RJT_INVL_CMD = 0x01, /* invalid command code */
271 FC_BA_RJT_LOG_ERR = 0x03, /* logical error */
272 FC_BA_RJT_LOG_BUSY = 0x05, /* logical busy */
273 FC_BA_RJT_PROTO_ERR = 0x07, /* protocol error */
274 FC_BA_RJT_UNABLE = 0x09, /* unable to perform request */
275 FC_BA_RJT_VENDOR = 0xff, /* vendor-specific (see br_vendor) */
276};
277
278/*
279 * BA_RJT reason code explanations.
280 */
281enum fc_ba_rjt_explan {
282 FC_BA_RJT_EXP_NONE = 0x00, /* no additional expanation */
283 FC_BA_RJT_INV_XID = 0x03, /* invalid OX_ID-RX_ID combination */
284 FC_BA_RJT_ABT = 0x05, /* sequence aborted, no seq info */
285};
286
287/*
288 * P_RJT or F_RJT: Port Reject or Fabric Reject parameter field.
289 */
290struct fc_pf_rjt {
291 __u8 rj_action; /* reserved */
292 __u8 rj_reason; /* reason code */
293 __u8 rj_resvd; /* reserved */
294 __u8 rj_vendor; /* vendor unique code */
295};
296
297/*
298 * P_RJT and F_RJT reject reason codes.
299 */
300enum fc_pf_rjt_reason {
301 FC_RJT_NONE = 0, /* non-reject (reserved by standard) */
302 FC_RJT_INVL_DID = 0x01, /* invalid destination ID */
303 FC_RJT_INVL_SID = 0x02, /* invalid source ID */
304 FC_RJT_P_UNAV_T = 0x03, /* port unavailable, temporary */
305 FC_RJT_P_UNAV = 0x04, /* port unavailable, permanent */
306 FC_RJT_CLS_UNSUP = 0x05, /* class not supported */
307 FC_RJT_DEL_USAGE = 0x06, /* delimiter usage error */
308 FC_RJT_TYPE_UNSUP = 0x07, /* type not supported */
309 FC_RJT_LINK_CTL = 0x08, /* invalid link control */
310 FC_RJT_R_CTL = 0x09, /* invalid R_CTL field */
311 FC_RJT_F_CTL = 0x0a, /* invalid F_CTL field */
312 FC_RJT_OX_ID = 0x0b, /* invalid originator exchange ID */
313 FC_RJT_RX_ID = 0x0c, /* invalid responder exchange ID */
314 FC_RJT_SEQ_ID = 0x0d, /* invalid sequence ID */
315 FC_RJT_DF_CTL = 0x0e, /* invalid DF_CTL field */
316 FC_RJT_SEQ_CNT = 0x0f, /* invalid SEQ_CNT field */
317 FC_RJT_PARAM = 0x10, /* invalid parameter field */
318 FC_RJT_EXCH_ERR = 0x11, /* exchange error */
319 FC_RJT_PROTO = 0x12, /* protocol error */
320 FC_RJT_LEN = 0x13, /* incorrect length */
321 FC_RJT_UNEXP_ACK = 0x14, /* unexpected ACK */
322 FC_RJT_FAB_CLASS = 0x15, /* class unsupported by fabric entity */
323 FC_RJT_LOGI_REQ = 0x16, /* login required */
324 FC_RJT_SEQ_XS = 0x17, /* excessive sequences attempted */
325 FC_RJT_EXCH_EST = 0x18, /* unable to establish exchange */
326 FC_RJT_FAB_UNAV = 0x1a, /* fabric unavailable */
327 FC_RJT_VC_ID = 0x1b, /* invalid VC_ID (class 4) */
328 FC_RJT_CS_CTL = 0x1c, /* invalid CS_CTL field */
329 FC_RJT_INSUF_RES = 0x1d, /* insuff. resources for VC (Class 4) */
330 FC_RJT_INVL_CLS = 0x1f, /* invalid class of service */
331 FC_RJT_PREEMT_RJT = 0x20, /* preemption request rejected */
332 FC_RJT_PREEMT_DIS = 0x21, /* preemption not enabled */
333 FC_RJT_MCAST_ERR = 0x22, /* multicast error */
334 FC_RJT_MCAST_ET = 0x23, /* multicast error terminate */
335 FC_RJT_PRLI_REQ = 0x24, /* process login required */
336 FC_RJT_INVL_ATT = 0x25, /* invalid attachment */
337 FC_RJT_VENDOR = 0xff, /* vendor specific reject */
338};
339
340#endif /* _FC_FS_H_ */
diff --git a/include/scsi/fc/fc_gs.h b/include/scsi/fc/fc_gs.h
new file mode 100644
index 000000000000..ffab0272c65a
--- /dev/null
+++ b/include/scsi/fc/fc_gs.h
@@ -0,0 +1,93 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_GS_H_
21#define _FC_GS_H_
22
23/*
24 * Fibre Channel Services - Common Transport.
25 * From T11.org FC-GS-2 Rev 5.3 November 1998.
26 */
27
28struct fc_ct_hdr {
29 __u8 ct_rev; /* revision */
30 __u8 ct_in_id[3]; /* N_Port ID of original requestor */
31 __u8 ct_fs_type; /* type of fibre channel service */
32 __u8 ct_fs_subtype; /* subtype */
33 __u8 ct_options;
34 __u8 _ct_resvd1;
35 __be16 ct_cmd; /* command / response code */
36 __be16 ct_mr_size; /* maximum / residual size */
37 __u8 _ct_resvd2;
38 __u8 ct_reason; /* reject reason */
39 __u8 ct_explan; /* reason code explanation */
40 __u8 ct_vendor; /* vendor unique data */
41};
42
43#define FC_CT_HDR_LEN 16 /* expected sizeof (struct fc_ct_hdr) */
44
45enum fc_ct_rev {
46 FC_CT_REV = 1 /* common transport revision */
47};
48
49/*
50 * ct_fs_type values.
51 */
52enum fc_ct_fs_type {
53 FC_FST_ALIAS = 0xf8, /* alias service */
54 FC_FST_MGMT = 0xfa, /* management service */
55 FC_FST_TIME = 0xfb, /* time service */
56 FC_FST_DIR = 0xfc, /* directory service */
57};
58
59/*
60 * ct_cmd: Command / response codes
61 */
62enum fc_ct_cmd {
63 FC_FS_RJT = 0x8001, /* reject */
64 FC_FS_ACC = 0x8002, /* accept */
65};
66
67/*
68 * FS_RJT reason codes.
69 */
70enum fc_ct_reason {
71 FC_FS_RJT_CMD = 0x01, /* invalid command code */
72 FC_FS_RJT_VER = 0x02, /* invalid version level */
73 FC_FS_RJT_LOG = 0x03, /* logical error */
74 FC_FS_RJT_IUSIZ = 0x04, /* invalid IU size */
75 FC_FS_RJT_BSY = 0x05, /* logical busy */
76 FC_FS_RJT_PROTO = 0x07, /* protocol error */
77 FC_FS_RJT_UNABL = 0x09, /* unable to perform command request */
78 FC_FS_RJT_UNSUP = 0x0b, /* command not supported */
79};
80
81/*
82 * FS_RJT reason code explanations.
83 */
84enum fc_ct_explan {
85 FC_FS_EXP_NONE = 0x00, /* no additional explanation */
86 FC_FS_EXP_PID = 0x01, /* port ID not registered */
87 FC_FS_EXP_PNAM = 0x02, /* port name not registered */
88 FC_FS_EXP_NNAM = 0x03, /* node name not registered */
89 FC_FS_EXP_COS = 0x04, /* class of service not registered */
90 /* definitions not complete */
91};
92
93#endif /* _FC_GS_H_ */
diff --git a/include/scsi/fc/fc_ns.h b/include/scsi/fc/fc_ns.h
new file mode 100644
index 000000000000..790d7b97d4bc
--- /dev/null
+++ b/include/scsi/fc/fc_ns.h
@@ -0,0 +1,159 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_NS_H_
21#define _FC_NS_H_
22
23/*
24 * Fibre Channel Services - Name Service (dNS)
25 * From T11.org FC-GS-2 Rev 5.3 November 1998.
26 */
27
28/*
29 * Common-transport sub-type for Name Server.
30 */
31#define FC_NS_SUBTYPE 2 /* fs_ct_hdr.ct_fs_subtype */
32
33/*
34 * Name server Requests.
35 * Note: this is an incomplete list, some unused requests are omitted.
36 */
37enum fc_ns_req {
38 FC_NS_GA_NXT = 0x0100, /* get all next */
39 FC_NS_GI_A = 0x0101, /* get identifiers - scope */
40 FC_NS_GPN_ID = 0x0112, /* get port name by ID */
41 FC_NS_GNN_ID = 0x0113, /* get node name by ID */
42 FC_NS_GID_PN = 0x0121, /* get ID for port name */
43 FC_NS_GID_NN = 0x0131, /* get IDs for node name */
44 FC_NS_GID_FT = 0x0171, /* get IDs by FC4 type */
45 FC_NS_GPN_FT = 0x0172, /* get port names by FC4 type */
46 FC_NS_GID_PT = 0x01a1, /* get IDs by port type */
47 FC_NS_RFT_ID = 0x0217, /* reg FC4 type for ID */
48 FC_NS_RPN_ID = 0x0212, /* reg port name for ID */
49 FC_NS_RNN_ID = 0x0213, /* reg node name for ID */
50};
51
52/*
53 * Port type values.
54 */
55enum fc_ns_pt {
56 FC_NS_UNID_PORT = 0x00, /* unidentified */
57 FC_NS_N_PORT = 0x01, /* N port */
58 FC_NS_NL_PORT = 0x02, /* NL port */
59 FC_NS_FNL_PORT = 0x03, /* F/NL port */
60 FC_NS_NX_PORT = 0x7f, /* Nx port */
61 FC_NS_F_PORT = 0x81, /* F port */
62 FC_NS_FL_PORT = 0x82, /* FL port */
63 FC_NS_E_PORT = 0x84, /* E port */
64 FC_NS_B_PORT = 0x85, /* B port */
65};
66
67/*
68 * Port type object.
69 */
70struct fc_ns_pt_obj {
71 __u8 pt_type;
72};
73
74/*
75 * Port ID object
76 */
77struct fc_ns_fid {
78 __u8 fp_flags; /* flags for responses only */
79 __u8 fp_fid[3];
80};
81
82/*
83 * fp_flags in port ID object, for responses only.
84 */
85#define FC_NS_FID_LAST 0x80 /* last object */
86
87/*
88 * FC4-types object.
89 */
90#define FC_NS_TYPES 256 /* number of possible FC-4 types */
91#define FC_NS_BPW 32 /* bits per word in bitmap */
92
93struct fc_ns_fts {
94 __be32 ff_type_map[FC_NS_TYPES / FC_NS_BPW]; /* bitmap of FC-4 types */
95};
96
97/*
98 * GID_PT request.
99 */
100struct fc_ns_gid_pt {
101 __u8 fn_pt_type;
102 __u8 fn_domain_id_scope;
103 __u8 fn_area_id_scope;
104 __u8 fn_resvd;
105};
106
107/*
108 * GID_FT or GPN_FT request.
109 */
110struct fc_ns_gid_ft {
111 __u8 fn_resvd;
112 __u8 fn_domain_id_scope;
113 __u8 fn_area_id_scope;
114 __u8 fn_fc4_type;
115};
116
117/*
118 * GPN_FT response.
119 */
120struct fc_gpn_ft_resp {
121 __u8 fp_flags; /* see fp_flags definitions above */
122 __u8 fp_fid[3]; /* port ID */
123 __be32 fp_resvd;
124 __be64 fp_wwpn; /* port name */
125};
126
127/*
128 * GID_PN request
129 */
130struct fc_ns_gid_pn {
131 __be64 fn_wwpn; /* port name */
132};
133
134/*
135 * GID_PN response
136 */
137struct fc_gid_pn_resp {
138 __u8 fp_resvd;
139 __u8 fp_fid[3]; /* port ID */
140};
141
142/*
143 * RFT_ID request - register FC-4 types for ID.
144 */
145struct fc_ns_rft_id {
146 struct fc_ns_fid fr_fid; /* port ID object */
147 struct fc_ns_fts fr_fts; /* FC-4 types object */
148};
149
150/*
151 * RPN_ID request - register port name for ID.
152 * RNN_ID request - register node name for ID.
153 */
154struct fc_ns_rn_id {
155 struct fc_ns_fid fr_fid; /* port ID object */
156 __be64 fr_wwn; /* node name or port name */
157} __attribute__((__packed__));
158
159#endif /* _FC_NS_H_ */
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
new file mode 100644
index 000000000000..6300f556bce5
--- /dev/null
+++ b/include/scsi/fc_encode.h
@@ -0,0 +1,309 @@
1/*
2 * Copyright(c) 2008 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_ENCODE_H_
21#define _FC_ENCODE_H_
22#include <asm/unaligned.h>
23
24struct fc_ns_rft {
25 struct fc_ns_fid fid; /* port ID object */
26 struct fc_ns_fts fts; /* FC4-types object */
27};
28
29struct fc_ct_req {
30 struct fc_ct_hdr hdr;
31 union {
32 struct fc_ns_gid_ft gid;
33 struct fc_ns_rn_id rn;
34 struct fc_ns_rft rft;
35 } payload;
36};
37
38/**
39 * fill FC header fields in specified fc_frame
40 */
41static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
42 u32 did, u32 sid, enum fc_fh_type type,
43 u32 f_ctl, u32 parm_offset)
44{
45 struct fc_frame_header *fh;
46
47 fh = fc_frame_header_get(fp);
48 WARN_ON(r_ctl == 0);
49 fh->fh_r_ctl = r_ctl;
50 hton24(fh->fh_d_id, did);
51 hton24(fh->fh_s_id, sid);
52 fh->fh_type = type;
53 hton24(fh->fh_f_ctl, f_ctl);
54 fh->fh_cs_ctl = 0;
55 fh->fh_df_ctl = 0;
56 fh->fh_parm_offset = htonl(parm_offset);
57}
58
59/**
60 * fc_ct_hdr_fill- fills ct header and reset ct payload
61 * returns pointer to ct request.
62 */
63static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
64 unsigned int op, size_t req_size)
65{
66 struct fc_ct_req *ct;
67 size_t ct_plen;
68
69 ct_plen = sizeof(struct fc_ct_hdr) + req_size;
70 ct = fc_frame_payload_get(fp, ct_plen);
71 memset(ct, 0, ct_plen);
72 ct->hdr.ct_rev = FC_CT_REV;
73 ct->hdr.ct_fs_type = FC_FST_DIR;
74 ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE;
75 ct->hdr.ct_cmd = htons((u16) op);
76 return ct;
77}
78
79/**
80 * fc_ct_fill - Fill in a name service request frame
81 */
82static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
83 unsigned int op, enum fc_rctl *r_ctl, u32 *did,
84 enum fc_fh_type *fh_type)
85{
86 struct fc_ct_req *ct;
87
88 switch (op) {
89 case FC_NS_GPN_FT:
90 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft));
91 ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
92 break;
93
94 case FC_NS_RFT_ID:
95 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft));
96 hton24(ct->payload.rft.fid.fp_fid,
97 fc_host_port_id(lport->host));
98 ct->payload.rft.fts = lport->fcts;
99 break;
100
101 case FC_NS_RPN_ID:
102 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id));
103 hton24(ct->payload.rn.fr_fid.fp_fid,
104 fc_host_port_id(lport->host));
105 ct->payload.rft.fts = lport->fcts;
106 put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn);
107 break;
108
109 default:
110 FC_DBG("Invalid op code %x \n", op);
111 return -EINVAL;
112 }
113 *r_ctl = FC_RCTL_DD_UNSOL_CTL;
114 *did = FC_FID_DIR_SERV;
115 *fh_type = FC_TYPE_CT;
116 return 0;
117}
118
119/**
120 * fc_plogi_fill - Fill in plogi request frame
121 */
122static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
123 unsigned int op)
124{
125 struct fc_els_flogi *plogi;
126 struct fc_els_csp *csp;
127 struct fc_els_cssp *cp;
128
129 plogi = fc_frame_payload_get(fp, sizeof(*plogi));
130 memset(plogi, 0, sizeof(*plogi));
131 plogi->fl_cmd = (u8) op;
132 put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn);
133 put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn);
134
135 csp = &plogi->fl_csp;
136 csp->sp_hi_ver = 0x20;
137 csp->sp_lo_ver = 0x20;
138 csp->sp_bb_cred = htons(10); /* this gets set by gateway */
139 csp->sp_bb_data = htons((u16) lport->mfs);
140 cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */
141 cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
142 csp->sp_features = htons(FC_SP_FT_CIRO);
143 csp->sp_tot_seq = htons(255); /* seq. we accept */
144 csp->sp_rel_off = htons(0x1f);
145 csp->sp_e_d_tov = htonl(lport->e_d_tov);
146
147 cp->cp_rdfs = htons((u16) lport->mfs);
148 cp->cp_con_seq = htons(255);
149 cp->cp_open_seq = 1;
150}
151
152/**
153 * fc_flogi_fill - Fill in a flogi request frame.
154 */
155static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
156{
157 struct fc_els_csp *sp;
158 struct fc_els_cssp *cp;
159 struct fc_els_flogi *flogi;
160
161 flogi = fc_frame_payload_get(fp, sizeof(*flogi));
162 memset(flogi, 0, sizeof(*flogi));
163 flogi->fl_cmd = (u8) ELS_FLOGI;
164 put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
165 put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
166 sp = &flogi->fl_csp;
167 sp->sp_hi_ver = 0x20;
168 sp->sp_lo_ver = 0x20;
169 sp->sp_bb_cred = htons(10); /* this gets set by gateway */
170 sp->sp_bb_data = htons((u16) lport->mfs);
171 cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */
172 cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
173}
174
175/**
176 * fc_logo_fill - Fill in a logo request frame.
177 */
178static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
179{
180 struct fc_els_logo *logo;
181
182 logo = fc_frame_payload_get(fp, sizeof(*logo));
183 memset(logo, 0, sizeof(*logo));
184 logo->fl_cmd = ELS_LOGO;
185 hton24(logo->fl_n_port_id, fc_host_port_id(lport->host));
186 logo->fl_n_port_wwn = htonll(lport->wwpn);
187}
188
189/**
190 * fc_rtv_fill - Fill in RTV (read timeout value) request frame.
191 */
192static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
193{
194 struct fc_els_rtv *rtv;
195
196 rtv = fc_frame_payload_get(fp, sizeof(*rtv));
197 memset(rtv, 0, sizeof(*rtv));
198 rtv->rtv_cmd = ELS_RTV;
199}
200
201/**
202 * fc_rec_fill - Fill in rec request frame
203 */
204static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
205{
206 struct fc_els_rec *rec;
207 struct fc_exch *ep = fc_seq_exch(fr_seq(fp));
208
209 rec = fc_frame_payload_get(fp, sizeof(*rec));
210 memset(rec, 0, sizeof(*rec));
211 rec->rec_cmd = ELS_REC;
212 hton24(rec->rec_s_id, fc_host_port_id(lport->host));
213 rec->rec_ox_id = htons(ep->oxid);
214 rec->rec_rx_id = htons(ep->rxid);
215}
216
217/**
218 * fc_prli_fill - Fill in prli request frame
219 */
220static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
221{
222 struct {
223 struct fc_els_prli prli;
224 struct fc_els_spp spp;
225 } *pp;
226
227 pp = fc_frame_payload_get(fp, sizeof(*pp));
228 memset(pp, 0, sizeof(*pp));
229 pp->prli.prli_cmd = ELS_PRLI;
230 pp->prli.prli_spp_len = sizeof(struct fc_els_spp);
231 pp->prli.prli_len = htons(sizeof(*pp));
232 pp->spp.spp_type = FC_TYPE_FCP;
233 pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
234 pp->spp.spp_params = htonl(lport->service_params);
235}
236
237/**
238 * fc_scr_fill - Fill in a scr request frame.
239 */
240static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
241{
242 struct fc_els_scr *scr;
243
244 scr = fc_frame_payload_get(fp, sizeof(*scr));
245 memset(scr, 0, sizeof(*scr));
246 scr->scr_cmd = ELS_SCR;
247 scr->scr_reg_func = ELS_SCRF_FULL;
248}
249
250/**
251 * fc_els_fill - Fill in an ELS request frame
252 */
253static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport,
254 struct fc_frame *fp, unsigned int op,
255 enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type)
256{
257 switch (op) {
258 case ELS_PLOGI:
259 fc_plogi_fill(lport, fp, ELS_PLOGI);
260 *did = rport->port_id;
261 break;
262
263 case ELS_FLOGI:
264 fc_flogi_fill(lport, fp);
265 *did = FC_FID_FLOGI;
266 break;
267
268 case ELS_LOGO:
269 fc_logo_fill(lport, fp);
270 *did = FC_FID_FLOGI;
271 /*
272 * if rport is valid then it
273 * is port logo, therefore
274 * set did to rport id.
275 */
276 if (rport)
277 *did = rport->port_id;
278 break;
279
280 case ELS_RTV:
281 fc_rtv_fill(lport, fp);
282 *did = rport->port_id;
283 break;
284
285 case ELS_REC:
286 fc_rec_fill(lport, fp);
287 *did = rport->port_id;
288 break;
289
290 case ELS_PRLI:
291 fc_prli_fill(lport, fp);
292 *did = rport->port_id;
293 break;
294
295 case ELS_SCR:
296 fc_scr_fill(lport, fp);
297 *did = FC_FID_FCTRL;
298 break;
299
300 default:
301 FC_DBG("Invalid op code %x \n", op);
302 return -EINVAL;
303 }
304
305 *r_ctl = FC_RCTL_ELS_REQ;
306 *fh_type = FC_TYPE_ELS;
307 return 0;
308}
309#endif /* _FC_ENCODE_H_ */
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
new file mode 100644
index 000000000000..04d34a71355f
--- /dev/null
+++ b/include/scsi/fc_frame.h
@@ -0,0 +1,242 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _FC_FRAME_H_
21#define _FC_FRAME_H_
22
23#include <linux/scatterlist.h>
24#include <linux/skbuff.h>
25#include <scsi/scsi_cmnd.h>
26
27#include <scsi/fc/fc_fs.h>
28#include <scsi/fc/fc_fcp.h>
29#include <scsi/fc/fc_encaps.h>
30
31/*
32 * The fc_frame interface is used to pass frame data between functions.
33 * The frame includes the data buffer, length, and SOF / EOF delimiter types.
34 * A pointer to the port structure of the receiving port is also includeded.
35 */
36
37#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */
38#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */
39
40/*
41 * Information about an individual fibre channel frame received or to be sent.
42 * The buffer may be in up to 4 additional non-contiguous sections,
43 * but the linear section must hold the frame header.
44 */
45#define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */
46
47#define fp_skb(fp) (&((fp)->skb))
48#define fr_hdr(fp) ((fp)->skb.data)
49#define fr_len(fp) ((fp)->skb.len)
50#define fr_cb(fp) ((struct fcoe_rcv_info *)&((fp)->skb.cb[0]))
51#define fr_dev(fp) (fr_cb(fp)->fr_dev)
52#define fr_seq(fp) (fr_cb(fp)->fr_seq)
53#define fr_sof(fp) (fr_cb(fp)->fr_sof)
54#define fr_eof(fp) (fr_cb(fp)->fr_eof)
55#define fr_flags(fp) (fr_cb(fp)->fr_flags)
56#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload)
57#define fr_cmd(fp) (fr_cb(fp)->fr_cmd)
58#define fr_dir(fp) (fr_cmd(fp)->sc_data_direction)
59#define fr_crc(fp) (fr_cb(fp)->fr_crc)
60
61struct fc_frame {
62 struct sk_buff skb;
63};
64
65struct fcoe_rcv_info {
66 struct packet_type *ptype;
67 struct fc_lport *fr_dev; /* transport layer private pointer */
68 struct fc_seq *fr_seq; /* for use with exchange manager */
69 struct scsi_cmnd *fr_cmd; /* for use of scsi command */
70 u32 fr_crc;
71 u16 fr_max_payload; /* max FC payload */
72 enum fc_sof fr_sof; /* start of frame delimiter */
73 enum fc_eof fr_eof; /* end of frame delimiter */
74 u8 fr_flags; /* flags - see below */
75};
76
77
78/*
79 * Get fc_frame pointer for an skb that's already been imported.
80 */
81static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb)
82{
83 BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb));
84 return (struct fcoe_rcv_info *) skb->cb;
85}
86
87/*
88 * fr_flags.
89 */
90#define FCPHF_CRC_UNCHECKED 0x01 /* CRC not computed, still appended */
91
92/*
93 * Initialize a frame.
94 * We don't do a complete memset here for performance reasons.
95 * The caller must set fr_free, fr_hdr, fr_len, fr_sof, and fr_eof eventually.
96 */
97static inline void fc_frame_init(struct fc_frame *fp)
98{
99 fr_dev(fp) = NULL;
100 fr_seq(fp) = NULL;
101 fr_flags(fp) = 0;
102}
103
104struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len);
105
106struct fc_frame *__fc_frame_alloc(size_t payload_len);
107
108/*
109 * Get frame for sending via port.
110 */
111static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev,
112 size_t payload_len)
113{
114 return __fc_frame_alloc(payload_len);
115}
116
117/*
118 * Allocate fc_frame structure and buffer. Set the initial length to
119 * payload_size + sizeof (struct fc_frame_header).
120 */
121static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len)
122{
123 struct fc_frame *fp;
124
125 /*
126 * Note: Since len will often be a constant multiple of 4,
127 * this check will usually be evaluated and eliminated at compile time.
128 */
129 if ((len % 4) != 0)
130 fp = fc_frame_alloc_fill(dev, len);
131 else
132 fp = _fc_frame_alloc(dev, len);
133 return fp;
134}
135
136/*
137 * Free the fc_frame structure and buffer.
138 */
139static inline void fc_frame_free(struct fc_frame *fp)
140{
141 kfree_skb(fp_skb(fp));
142}
143
144static inline int fc_frame_is_linear(struct fc_frame *fp)
145{
146 return !skb_is_nonlinear(fp_skb(fp));
147}
148
149/*
150 * Get frame header from message in fc_frame structure.
151 * This hides a cast and provides a place to add some checking.
152 */
153static inline
154struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp)
155{
156 WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header));
157 return (struct fc_frame_header *) fr_hdr(fp);
158}
159
160/*
161 * Get frame payload from message in fc_frame structure.
162 * This hides a cast and provides a place to add some checking.
163 * The len parameter is the minimum length for the payload portion.
164 * Returns NULL if the frame is too short.
165 *
166 * This assumes the interesting part of the payload is in the first part
167 * of the buffer for received data. This may not be appropriate to use for
168 * buffers being transmitted.
169 */
170static inline void *fc_frame_payload_get(const struct fc_frame *fp,
171 size_t len)
172{
173 void *pp = NULL;
174
175 if (fr_len(fp) >= sizeof(struct fc_frame_header) + len)
176 pp = fc_frame_header_get(fp) + 1;
177 return pp;
178}
179
180/*
181 * Get frame payload opcode (first byte) from message in fc_frame structure.
182 * This hides a cast and provides a place to add some checking. Return 0
183 * if the frame has no payload.
184 */
185static inline u8 fc_frame_payload_op(const struct fc_frame *fp)
186{
187 u8 *cp;
188
189 cp = fc_frame_payload_get(fp, sizeof(u8));
190 if (!cp)
191 return 0;
192 return *cp;
193
194}
195
196/*
197 * Get FC class from frame.
198 */
199static inline enum fc_class fc_frame_class(const struct fc_frame *fp)
200{
201 return fc_sof_class(fr_sof(fp));
202}
203
204/*
205 * Check the CRC in a frame.
206 * The CRC immediately follows the last data item *AFTER* the length.
207 * The return value is zero if the CRC matches.
208 */
209u32 fc_frame_crc_check(struct fc_frame *);
210
211static inline u8 fc_frame_rctl(const struct fc_frame *fp)
212{
213 return fc_frame_header_get(fp)->fh_r_ctl;
214}
215
216static inline bool fc_frame_is_cmd(const struct fc_frame *fp)
217{
218 return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD;
219}
220
221static inline bool fc_frame_is_read(const struct fc_frame *fp)
222{
223 if (fc_frame_is_cmd(fp) && fr_cmd(fp))
224 return fr_dir(fp) == DMA_FROM_DEVICE;
225 return false;
226}
227
228static inline bool fc_frame_is_write(const struct fc_frame *fp)
229{
230 if (fc_frame_is_cmd(fp) && fr_cmd(fp))
231 return fr_dir(fp) == DMA_TO_DEVICE;
232 return false;
233}
234
235/*
236 * Check for leaks.
237 * Print the frame header of any currently allocated frame, assuming there
238 * should be none at this point.
239 */
240void fc_frame_leak_check(void);
241
242#endif /* _FC_FRAME_H_ */
diff --git a/include/scsi/fc_transport_fcoe.h b/include/scsi/fc_transport_fcoe.h
new file mode 100644
index 000000000000..8dca2af14ffc
--- /dev/null
+++ b/include/scsi/fc_transport_fcoe.h
@@ -0,0 +1,54 @@
1#ifndef FC_TRANSPORT_FCOE_H
2#define FC_TRANSPORT_FCOE_H
3
4#include <linux/device.h>
5#include <linux/netdevice.h>
6#include <scsi/scsi_host.h>
7#include <scsi/libfc.h>
8
9/**
10 * struct fcoe_transport - FCoE transport struct for generic transport
11 * for Ethernet devices as well as pure HBAs
12 *
13 * @name: name for thsi transport
14 * @bus: physical bus type (pci_bus_type)
15 * @driver: physical bus driver for network device
16 * @create: entry create function
17 * @destroy: exit destroy function
18 * @list: list of transports
19 */
20struct fcoe_transport {
21 char *name;
22 unsigned short vendor;
23 unsigned short device;
24 struct bus_type *bus;
25 struct device_driver *driver;
26 int (*create)(struct net_device *device);
27 int (*destroy)(struct net_device *device);
28 bool (*match)(struct net_device *device);
29 struct list_head list;
30 struct list_head devlist;
31 struct mutex devlock;
32};
33
34/**
35 * MODULE_ALIAS_FCOE_PCI
36 *
37 * some care must be taken with this, vendor and device MUST be a hex value
38 * preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB)
39 */
40#define MODULE_ALIAS_FCOE_PCI(vendor, device) \
41 MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device))
42
43/* exported funcs */
44int fcoe_transport_attach(struct net_device *netdev);
45int fcoe_transport_release(struct net_device *netdev);
46int fcoe_transport_register(struct fcoe_transport *t);
47int fcoe_transport_unregister(struct fcoe_transport *t);
48int fcoe_load_transport_driver(struct net_device *netdev);
49int __init fcoe_transport_init(void);
50int __exit fcoe_transport_exit(void);
51
52/* fcow_sw is the default transport */
53extern struct fcoe_transport fcoe_sw_transport;
54#endif /* FC_TRANSPORT_FCOE_H */
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 0c9514de5df7..d0ed5226f8c4 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -333,8 +333,11 @@ enum iscsi_host_param {
333#define CAP_TEXT_NEGO 0x80 333#define CAP_TEXT_NEGO 0x80
334#define CAP_MARKERS 0x100 334#define CAP_MARKERS 0x100
335#define CAP_FW_DB 0x200 335#define CAP_FW_DB 0x200
336#define CAP_SENDTARGETS_OFFLOAD 0x400 336#define CAP_SENDTARGETS_OFFLOAD 0x400 /* offload discovery process */
337#define CAP_DATA_PATH_OFFLOAD 0x800 337#define CAP_DATA_PATH_OFFLOAD 0x800 /* offload entire IO path */
338#define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */
339#define CAP_PADDING_OFFLOAD 0x2000 /* offload padding insertion, removal,
340 and verification */
338 341
339/* 342/*
340 * These flags describes reason of stop_conn() call 343 * These flags describes reason of stop_conn() call
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
new file mode 100644
index 000000000000..9f2876397dda
--- /dev/null
+++ b/include/scsi/libfc.h
@@ -0,0 +1,938 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _LIBFC_H_
21#define _LIBFC_H_
22
23#include <linux/timer.h>
24#include <linux/if.h>
25
26#include <scsi/scsi_transport.h>
27#include <scsi/scsi_transport_fc.h>
28
29#include <scsi/fc/fc_fcp.h>
30#include <scsi/fc/fc_ns.h>
31#include <scsi/fc/fc_els.h>
32#include <scsi/fc/fc_gs.h>
33
34#include <scsi/fc_frame.h>
35
36#define LIBFC_DEBUG
37
38#ifdef LIBFC_DEBUG
39/* Log messages */
40#define FC_DBG(fmt, args...) \
41 do { \
42 printk(KERN_INFO "%s " fmt, __func__, ##args); \
43 } while (0)
44#else
45#define FC_DBG(fmt, args...)
46#endif
47
48/*
49 * libfc error codes
50 */
51#define FC_NO_ERR 0 /* no error */
52#define FC_EX_TIMEOUT 1 /* Exchange timeout */
53#define FC_EX_CLOSED 2 /* Exchange closed */
54
55/* some helpful macros */
56
57#define ntohll(x) be64_to_cpu(x)
58#define htonll(x) cpu_to_be64(x)
59
60#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
61
62#define hton24(p, v) do { \
63 p[0] = (((v) >> 16) & 0xFF); \
64 p[1] = (((v) >> 8) & 0xFF); \
65 p[2] = ((v) & 0xFF); \
66 } while (0)
67
68/*
69 * FC HBA status
70 */
71#define FC_PAUSE (1 << 1)
72#define FC_LINK_UP (1 << 0)
73
74enum fc_lport_state {
75 LPORT_ST_NONE = 0,
76 LPORT_ST_FLOGI,
77 LPORT_ST_DNS,
78 LPORT_ST_RPN_ID,
79 LPORT_ST_RFT_ID,
80 LPORT_ST_SCR,
81 LPORT_ST_READY,
82 LPORT_ST_LOGO,
83 LPORT_ST_RESET
84};
85
86enum fc_disc_event {
87 DISC_EV_NONE = 0,
88 DISC_EV_SUCCESS,
89 DISC_EV_FAILED
90};
91
92enum fc_rport_state {
93 RPORT_ST_NONE = 0,
94 RPORT_ST_INIT, /* initialized */
95 RPORT_ST_PLOGI, /* waiting for PLOGI completion */
96 RPORT_ST_PRLI, /* waiting for PRLI completion */
97 RPORT_ST_RTV, /* waiting for RTV completion */
98 RPORT_ST_READY, /* ready for use */
99 RPORT_ST_LOGO, /* port logout sent */
100};
101
102enum fc_rport_trans_state {
103 FC_PORTSTATE_ROGUE,
104 FC_PORTSTATE_REAL,
105};
106
107/**
108 * struct fc_disc_port - temporary discovery port to hold rport identifiers
109 * @lp: Fibre Channel host port instance
110 * @peers: node for list management during discovery and RSCN processing
111 * @ids: identifiers structure to pass to fc_remote_port_add()
112 * @rport_work: work struct for starting the rport state machine
113 */
114struct fc_disc_port {
115 struct fc_lport *lp;
116 struct list_head peers;
117 struct fc_rport_identifiers ids;
118 struct work_struct rport_work;
119};
120
121enum fc_rport_event {
122 RPORT_EV_NONE = 0,
123 RPORT_EV_CREATED,
124 RPORT_EV_FAILED,
125 RPORT_EV_STOP,
126 RPORT_EV_LOGO
127};
128
129struct fc_rport_operations {
130 void (*event_callback)(struct fc_lport *, struct fc_rport *,
131 enum fc_rport_event);
132};
133
134/**
135 * struct fc_rport_libfc_priv - libfc internal information about a remote port
136 * @local_port: Fibre Channel host port instance
137 * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges
138 * @flags: REC and RETRY supported flags
139 * @max_seq: maximum number of concurrent sequences
140 * @retries: retry count in current state
141 * @e_d_tov: error detect timeout value (in msec)
142 * @r_a_tov: resource allocation timeout value (in msec)
143 * @rp_mutex: mutex protects rport
144 * @retry_work:
145 * @event_callback: Callback for rport READY, FAILED or LOGO
146 */
147struct fc_rport_libfc_priv {
148 struct fc_lport *local_port;
149 enum fc_rport_state rp_state;
150 u16 flags;
151 #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)
152 #define FC_RP_FLAGS_RETRY (1 << 1)
153 u16 max_seq;
154 unsigned int retries;
155 unsigned int e_d_tov;
156 unsigned int r_a_tov;
157 enum fc_rport_trans_state trans_state;
158 struct mutex rp_mutex;
159 struct delayed_work retry_work;
160 enum fc_rport_event event;
161 struct fc_rport_operations *ops;
162 struct list_head peers;
163 struct work_struct event_work;
164};
165
166#define PRIV_TO_RPORT(x) \
167 (struct fc_rport *)((void *)x - sizeof(struct fc_rport));
168#define RPORT_TO_PRIV(x) \
169 (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport));
170
171struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *);
172
173static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn)
174{
175 rport->node_name = wwnn;
176 rport->port_name = wwpn;
177}
178
179/*
180 * fcoe stats structure
181 */
182struct fcoe_dev_stats {
183 u64 SecondsSinceLastReset;
184 u64 TxFrames;
185 u64 TxWords;
186 u64 RxFrames;
187 u64 RxWords;
188 u64 ErrorFrames;
189 u64 DumpedFrames;
190 u64 LinkFailureCount;
191 u64 LossOfSignalCount;
192 u64 InvalidTxWordCount;
193 u64 InvalidCRCCount;
194 u64 InputRequests;
195 u64 OutputRequests;
196 u64 ControlRequests;
197 u64 InputMegabytes;
198 u64 OutputMegabytes;
199};
200
201/*
202 * els data is used for passing ELS respone specific
203 * data to send ELS response mainly using infomation
204 * in exchange and sequence in EM layer.
205 */
206struct fc_seq_els_data {
207 struct fc_frame *fp;
208 enum fc_els_rjt_reason reason;
209 enum fc_els_rjt_explan explan;
210};
211
212/*
213 * FCP request structure, one for each scsi cmd request
214 */
215struct fc_fcp_pkt {
216 /*
217 * housekeeping stuff
218 */
219 struct fc_lport *lp; /* handle to hba struct */
220 u16 state; /* scsi_pkt state state */
221 u16 tgt_flags; /* target flags */
222 atomic_t ref_cnt; /* fcp pkt ref count */
223 spinlock_t scsi_pkt_lock; /* Must be taken before the host lock
224 * if both are held at the same time */
225 /*
226 * SCSI I/O related stuff
227 */
228 struct scsi_cmnd *cmd; /* scsi command pointer. set/clear
229 * under host lock */
230 struct list_head list; /* tracks queued commands. access under
231 * host lock */
232 /*
233 * timeout related stuff
234 */
235 struct timer_list timer; /* command timer */
236 struct completion tm_done;
237 int wait_for_comp;
238 unsigned long start_time; /* start jiffie */
239 unsigned long end_time; /* end jiffie */
240 unsigned long last_pkt_time; /* jiffies of last frame received */
241
242 /*
243 * scsi cmd and data transfer information
244 */
245 u32 data_len;
246 /*
247 * transport related veriables
248 */
249 struct fcp_cmnd cdb_cmd;
250 size_t xfer_len;
251 u32 xfer_contig_end; /* offset of end of contiguous xfer */
252 u16 max_payload; /* max payload size in bytes */
253
254 /*
255 * scsi/fcp return status
256 */
257 u32 io_status; /* SCSI result upper 24 bits */
258 u8 cdb_status;
259 u8 status_code; /* FCP I/O status */
260 /* bit 3 Underrun bit 2: overrun */
261 u8 scsi_comp_flags;
262 u32 req_flags; /* bit 0: read bit:1 write */
263 u32 scsi_resid; /* residule length */
264
265 struct fc_rport *rport; /* remote port pointer */
266 struct fc_seq *seq_ptr; /* current sequence pointer */
267 /*
268 * Error Processing
269 */
270 u8 recov_retry; /* count of recovery retries */
271 struct fc_seq *recov_seq; /* sequence for REC or SRR */
272};
273
274/*
275 * Structure and function definitions for managing Fibre Channel Exchanges
276 * and Sequences
277 *
278 * fc_exch holds state for one exchange and links to its active sequence.
279 *
280 * fc_seq holds the state for an individual sequence.
281 */
282
283struct fc_exch_mgr;
284
285/*
286 * Sequence.
287 */
288struct fc_seq {
289 u8 id; /* seq ID */
290 u16 ssb_stat; /* status flags for sequence status block */
291 u16 cnt; /* frames sent so far on sequence */
292 u32 rec_data; /* FC-4 value for REC */
293};
294
295#define FC_EX_DONE (1 << 0) /* ep is completed */
296#define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */
297
298/*
299 * Exchange.
300 *
301 * Locking notes: The ex_lock protects following items:
302 * state, esb_stat, f_ctl, seq.ssb_stat
303 * seq_id
304 * sequence allocation
305 */
306struct fc_exch {
307 struct fc_exch_mgr *em; /* exchange manager */
308 u32 state; /* internal driver state */
309 u16 xid; /* our exchange ID */
310 struct list_head ex_list; /* free or busy list linkage */
311 spinlock_t ex_lock; /* lock covering exchange state */
312 atomic_t ex_refcnt; /* reference counter */
313 struct delayed_work timeout_work; /* timer for upper level protocols */
314 struct fc_lport *lp; /* fc device instance */
315 u16 oxid; /* originator's exchange ID */
316 u16 rxid; /* responder's exchange ID */
317 u32 oid; /* originator's FCID */
318 u32 sid; /* source FCID */
319 u32 did; /* destination FCID */
320 u32 esb_stat; /* exchange status for ESB */
321 u32 r_a_tov; /* r_a_tov from rport (msec) */
322 u8 seq_id; /* next sequence ID to use */
323 u32 f_ctl; /* F_CTL flags for sequences */
324 u8 fh_type; /* frame type */
325 enum fc_class class; /* class of service */
326 struct fc_seq seq; /* single sequence */
327 /*
328 * Handler for responses to this current exchange.
329 */
330 void (*resp)(struct fc_seq *, struct fc_frame *, void *);
331 void (*destructor)(struct fc_seq *, void *);
332 /*
333 * arg is passed as void pointer to exchange
334 * resp and destructor handlers
335 */
336 void *arg;
337};
338#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
339
340struct libfc_function_template {
341
342 /**
343 * Mandatory Fields
344 *
345 * These handlers must be implemented by the LLD.
346 */
347
348 /*
349 * Interface to send a FC frame
350 */
351 int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp);
352
353 /**
354 * Optional Fields
355 *
356 * The LLD may choose to implement any of the following handlers.
357 * If LLD doesn't specify hander and leaves its pointer NULL then
358 * the default libfc function will be used for that handler.
359 */
360
361 /**
362 * ELS/CT interfaces
363 */
364
365 /*
366 * elsct_send - sends ELS/CT frame
367 */
368 struct fc_seq *(*elsct_send)(struct fc_lport *lport,
369 struct fc_rport *rport,
370 struct fc_frame *fp,
371 unsigned int op,
372 void (*resp)(struct fc_seq *,
373 struct fc_frame *fp,
374 void *arg),
375 void *arg, u32 timer_msec);
376 /**
377 * Exhance Manager interfaces
378 */
379
380 /*
381 * Send the FC frame payload using a new exchange and sequence.
382 *
383 * The frame pointer with some of the header's fields must be
384 * filled before calling exch_seq_send(), those fields are,
385 *
386 * - routing control
387 * - FC port did
388 * - FC port sid
389 * - FC header type
390 * - frame control
391 * - parameter or relative offset
392 *
393 * The exchange response handler is set in this routine to resp()
394 * function pointer. It can be called in two scenarios: if a timeout
395 * occurs or if a response frame is received for the exchange. The
396 * fc_frame pointer in response handler will also indicate timeout
397 * as error using IS_ERR related macros.
398 *
399 * The exchange destructor handler is also set in this routine.
400 * The destructor handler is invoked by EM layer when exchange
401 * is about to free, this can be used by caller to free its
402 * resources along with exchange free.
403 *
404 * The arg is passed back to resp and destructor handler.
405 *
406 * The timeout value (in msec) for an exchange is set if non zero
407 * timer_msec argument is specified. The timer is canceled when
408 * it fires or when the exchange is done. The exchange timeout handler
409 * is registered by EM layer.
410 */
411 struct fc_seq *(*exch_seq_send)(struct fc_lport *lp,
412 struct fc_frame *fp,
413 void (*resp)(struct fc_seq *sp,
414 struct fc_frame *fp,
415 void *arg),
416 void (*destructor)(struct fc_seq *sp,
417 void *arg),
418 void *arg, unsigned int timer_msec);
419
420 /*
421 * send a frame using existing sequence and exchange.
422 */
423 int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp,
424 struct fc_frame *fp);
425
426 /*
427 * Send ELS response using mainly infomation
428 * in exchange and sequence in EM layer.
429 */
430 void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd,
431 struct fc_seq_els_data *els_data);
432
433 /*
434 * Abort an exchange and sequence. Generally called because of a
435 * exchange timeout or an abort from the upper layer.
436 *
437 * A timer_msec can be specified for abort timeout, if non-zero
438 * timer_msec value is specified then exchange resp handler
439 * will be called with timeout error if no response to abort.
440 */
441 int (*seq_exch_abort)(const struct fc_seq *req_sp,
442 unsigned int timer_msec);
443
444 /*
445 * Indicate that an exchange/sequence tuple is complete and the memory
446 * allocated for the related objects may be freed.
447 */
448 void (*exch_done)(struct fc_seq *sp);
449
450 /*
451 * Assigns a EM and a free XID for an new exchange and then
452 * allocates a new exchange and sequence pair.
453 * The fp can be used to determine free XID.
454 */
455 struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp);
456
457 /*
458 * Release previously assigned XID by exch_get API.
459 * The LLD may implement this if XID is assigned by LLD
460 * in exch_get().
461 */
462 void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp,
463 u16 ex_id);
464
465 /*
466 * Start a new sequence on the same exchange/sequence tuple.
467 */
468 struct fc_seq *(*seq_start_next)(struct fc_seq *sp);
469
470 /*
471 * Reset an exchange manager, completing all sequences and exchanges.
472 * If s_id is non-zero, reset only exchanges originating from that FID.
473 * If d_id is non-zero, reset only exchanges sending to that FID.
474 */
475 void (*exch_mgr_reset)(struct fc_exch_mgr *,
476 u32 s_id, u32 d_id);
477
478 void (*rport_flush_queue)(void);
479 /**
480 * Local Port interfaces
481 */
482
483 /*
484 * Receive a frame to a local port.
485 */
486 void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp,
487 struct fc_frame *fp);
488
489 int (*lport_reset)(struct fc_lport *);
490
491 /**
492 * Remote Port interfaces
493 */
494
495 /*
496 * Initiates the RP state machine. It is called from the LP module.
497 * This function will issue the following commands to the N_Port
498 * identified by the FC ID provided.
499 *
500 * - PLOGI
501 * - PRLI
502 * - RTV
503 */
504 int (*rport_login)(struct fc_rport *rport);
505
506 /*
507 * Logoff, and remove the rport from the transport if
508 * it had been added. This will send a LOGO to the target.
509 */
510 int (*rport_logoff)(struct fc_rport *rport);
511
512 /*
513 * Recieve a request from a remote port.
514 */
515 void (*rport_recv_req)(struct fc_seq *, struct fc_frame *,
516 struct fc_rport *);
517
518 struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32);
519
520 /**
521 * FCP interfaces
522 */
523
524 /*
525 * Send a fcp cmd from fsp pkt.
526 * Called with the SCSI host lock unlocked and irqs disabled.
527 *
528 * The resp handler is called when FCP_RSP received.
529 *
530 */
531 int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
532 void (*resp)(struct fc_seq *, struct fc_frame *fp,
533 void *arg));
534
535 /*
536 * Used at least durring linkdown and reset
537 */
538 void (*fcp_cleanup)(struct fc_lport *lp);
539
540 /*
541 * Abort all I/O on a local port
542 */
543 void (*fcp_abort_io)(struct fc_lport *lp);
544
545 /**
546 * Discovery interfaces
547 */
548
549 void (*disc_recv_req)(struct fc_seq *,
550 struct fc_frame *, struct fc_lport *);
551
552 /*
553 * Start discovery for a local port.
554 */
555 void (*disc_start)(void (*disc_callback)(struct fc_lport *,
556 enum fc_disc_event),
557 struct fc_lport *);
558
559 /*
560 * Stop discovery for a given lport. This will remove
561 * all discovered rports
562 */
563 void (*disc_stop) (struct fc_lport *);
564
565 /*
566 * Stop discovery for a given lport. This will block
567 * until all discovered rports are deleted from the
568 * FC transport class
569 */
570 void (*disc_stop_final) (struct fc_lport *);
571};
572
573/* information used by the discovery layer */
574struct fc_disc {
575 unsigned char retry_count;
576 unsigned char delay;
577 unsigned char pending;
578 unsigned char requested;
579 unsigned short seq_count;
580 unsigned char buf_len;
581 enum fc_disc_event event;
582
583 void (*disc_callback)(struct fc_lport *,
584 enum fc_disc_event);
585
586 struct list_head rports;
587 struct fc_lport *lport;
588 struct mutex disc_mutex;
589 struct fc_gpn_ft_resp partial_buf; /* partial name buffer */
590 struct delayed_work disc_work;
591};
592
593struct fc_lport {
594 struct list_head list;
595
596 /* Associations */
597 struct Scsi_Host *host;
598 struct fc_exch_mgr *emp;
599 struct fc_rport *dns_rp;
600 struct fc_rport *ptp_rp;
601 void *scsi_priv;
602 struct fc_disc disc;
603
604 /* Operational Information */
605 struct libfc_function_template tt;
606 u16 link_status;
607 enum fc_lport_state state;
608 unsigned long boot_time;
609
610 struct fc_host_statistics host_stats;
611 struct fcoe_dev_stats *dev_stats[NR_CPUS];
612 u64 wwpn;
613 u64 wwnn;
614 u8 retry_count;
615
616 /* Capabilities */
617 u32 sg_supp:1; /* scatter gather supported */
618 u32 seq_offload:1; /* seq offload supported */
619 u32 crc_offload:1; /* crc offload supported */
620 u32 lro_enabled:1; /* large receive offload */
621 u32 mfs; /* max FC payload size */
622 unsigned int service_params;
623 unsigned int e_d_tov;
624 unsigned int r_a_tov;
625 u8 max_retry_count;
626 u16 link_speed;
627 u16 link_supported_speeds;
628 u16 lro_xid; /* max xid for fcoe lro */
629 struct fc_ns_fts fcts; /* FC-4 type masks */
630 struct fc_els_rnid_gen rnid_gen; /* RNID information */
631
632 /* Semaphores */
633 struct mutex lp_mutex;
634
635 /* Miscellaneous */
636 struct delayed_work retry_work;
637 struct delayed_work disc_work;
638};
639
640/**
641 * FC_LPORT HELPER FUNCTIONS
642 *****************************/
643static inline void *lport_priv(const struct fc_lport *lp)
644{
645 return (void *)(lp + 1);
646}
647
648static inline int fc_lport_test_ready(struct fc_lport *lp)
649{
650 return lp->state == LPORT_ST_READY;
651}
652
653static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn)
654{
655 lp->wwnn = wwnn;
656}
657
658static inline void fc_set_wwpn(struct fc_lport *lp, u64 wwnn)
659{
660 lp->wwpn = wwnn;
661}
662
663static inline void fc_lport_state_enter(struct fc_lport *lp,
664 enum fc_lport_state state)
665{
666 if (state != lp->state)
667 lp->retry_count = 0;
668 lp->state = state;
669}
670
671
672/**
673 * LOCAL PORT LAYER
674 *****************************/
675int fc_lport_init(struct fc_lport *lp);
676
677/*
678 * Destroy the specified local port by finding and freeing all
679 * fc_rports associated with it and then by freeing the fc_lport
680 * itself.
681 */
682int fc_lport_destroy(struct fc_lport *lp);
683
684/*
685 * Logout the specified local port from the fabric
686 */
687int fc_fabric_logoff(struct fc_lport *lp);
688
689/*
690 * Initiate the LP state machine. This handler will use fc_host_attr
691 * to store the FLOGI service parameters, so fc_host_attr must be
692 * initialized before calling this handler.
693 */
694int fc_fabric_login(struct fc_lport *lp);
695
696/*
697 * The link is up for the given local port.
698 */
699void fc_linkup(struct fc_lport *);
700
701/*
702 * Link is down for the given local port.
703 */
704void fc_linkdown(struct fc_lport *);
705
706/*
707 * Pause and unpause traffic.
708 */
709void fc_pause(struct fc_lport *);
710void fc_unpause(struct fc_lport *);
711
712/*
713 * Configure the local port.
714 */
715int fc_lport_config(struct fc_lport *);
716
717/*
718 * Reset the local port.
719 */
720int fc_lport_reset(struct fc_lport *);
721
722/*
723 * Set the mfs or reset
724 */
725int fc_set_mfs(struct fc_lport *lp, u32 mfs);
726
727
728/**
729 * REMOTE PORT LAYER
730 *****************************/
731int fc_rport_init(struct fc_lport *lp);
732void fc_rport_terminate_io(struct fc_rport *rp);
733
734/**
735 * DISCOVERY LAYER
736 *****************************/
737int fc_disc_init(struct fc_lport *lp);
738
739
740/**
741 * SCSI LAYER
742 *****************************/
743/*
744 * Initialize the SCSI block of libfc
745 */
746int fc_fcp_init(struct fc_lport *);
747
748/*
749 * This section provides an API which allows direct interaction
750 * with the SCSI-ml. Each of these functions satisfies a function
751 * pointer defined in Scsi_Host and therefore is always called
752 * directly from the SCSI-ml.
753 */
754int fc_queuecommand(struct scsi_cmnd *sc_cmd,
755 void (*done)(struct scsi_cmnd *));
756
757/*
758 * complete processing of a fcp packet
759 *
760 * This function may sleep if a fsp timer is pending.
761 * The host lock must not be held by caller.
762 */
763void fc_fcp_complete(struct fc_fcp_pkt *fsp);
764
765/*
766 * Send an ABTS frame to the target device. The sc_cmd argument
767 * is a pointer to the SCSI command to be aborted.
768 */
769int fc_eh_abort(struct scsi_cmnd *sc_cmd);
770
771/*
772 * Reset a LUN by sending send the tm cmd to the target.
773 */
774int fc_eh_device_reset(struct scsi_cmnd *sc_cmd);
775
776/*
777 * Reset the host adapter.
778 */
779int fc_eh_host_reset(struct scsi_cmnd *sc_cmd);
780
781/*
782 * Check rport status.
783 */
784int fc_slave_alloc(struct scsi_device *sdev);
785
786/*
787 * Adjust the queue depth.
788 */
789int fc_change_queue_depth(struct scsi_device *sdev, int qdepth);
790
791/*
792 * Change the tag type.
793 */
794int fc_change_queue_type(struct scsi_device *sdev, int tag_type);
795
796/*
797 * Free memory pools used by the FCP layer.
798 */
799void fc_fcp_destroy(struct fc_lport *);
800
801/**
802 * ELS/CT interface
803 *****************************/
804/*
805 * Initializes ELS/CT interface
806 */
807int fc_elsct_init(struct fc_lport *lp);
808
809
810/**
811 * EXCHANGE MANAGER LAYER
812 *****************************/
813/*
814 * Initializes Exchange Manager related
815 * function pointers in struct libfc_function_template.
816 */
817int fc_exch_init(struct fc_lport *lp);
818
819/*
820 * Allocates an Exchange Manager (EM).
821 *
822 * The EM manages exchanges for their allocation and
823 * free, also allows exchange lookup for received
824 * frame.
825 *
826 * The class is used for initializing FC class of
827 * allocated exchange from EM.
828 *
829 * The min_xid and max_xid will limit new
830 * exchange ID (XID) within this range for
831 * a new exchange.
832 * The LLD may choose to have multiple EMs,
833 * e.g. one EM instance per CPU receive thread in LLD.
834 * The LLD can use exch_get() of struct libfc_function_template
835 * to specify XID for a new exchange within
836 * a specified EM instance.
837 *
838 * The em_idx to uniquely identify an EM instance.
839 */
840struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
841 enum fc_class class,
842 u16 min_xid,
843 u16 max_xid);
844
845/*
846 * Free an exchange manager.
847 */
848void fc_exch_mgr_free(struct fc_exch_mgr *mp);
849
850/*
851 * Receive a frame on specified local port and exchange manager.
852 */
853void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
854 struct fc_frame *fp);
855
856/*
857 * This function is for exch_seq_send function pointer in
858 * struct libfc_function_template, see comment block on
859 * exch_seq_send for description of this function.
860 */
861struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
862 struct fc_frame *fp,
863 void (*resp)(struct fc_seq *sp,
864 struct fc_frame *fp,
865 void *arg),
866 void (*destructor)(struct fc_seq *sp,
867 void *arg),
868 void *arg, u32 timer_msec);
869
870/*
871 * send a frame using existing sequence and exchange.
872 */
873int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp);
874
875/*
876 * Send ELS response using mainly infomation
877 * in exchange and sequence in EM layer.
878 */
879void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
880 struct fc_seq_els_data *els_data);
881
882/*
883 * This function is for seq_exch_abort function pointer in
884 * struct libfc_function_template, see comment block on
885 * seq_exch_abort for description of this function.
886 */
887int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec);
888
889/*
890 * Indicate that an exchange/sequence tuple is complete and the memory
891 * allocated for the related objects may be freed.
892 */
893void fc_exch_done(struct fc_seq *sp);
894
895/*
896 * Assigns a EM and XID for a frame and then allocates
897 * a new exchange and sequence pair.
898 * The fp can be used to determine free XID.
899 */
900struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp);
901
902/*
903 * Allocate a new exchange and sequence pair.
904 * if ex_id is zero then next free exchange id
905 * from specified exchange manger mp will be assigned.
906 */
907struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
908 struct fc_frame *fp, u16 ex_id);
909/*
910 * Start a new sequence on the same exchange as the supplied sequence.
911 */
912struct fc_seq *fc_seq_start_next(struct fc_seq *sp);
913
914/*
915 * Reset an exchange manager, completing all sequences and exchanges.
916 * If s_id is non-zero, reset only exchanges originating from that FID.
917 * If d_id is non-zero, reset only exchanges sending to that FID.
918 */
919void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id);
920
921/*
922 * Functions for fc_functions_template
923 */
924void fc_get_host_speed(struct Scsi_Host *shost);
925void fc_get_host_port_type(struct Scsi_Host *shost);
926void fc_get_host_port_state(struct Scsi_Host *shost);
927void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout);
928struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *);
929
930/*
931 * module setup functions.
932 */
933int fc_setup_exch_mgr(void);
934void fc_destroy_exch_mgr(void);
935int fc_setup_rport(void);
936void fc_destroy_rport(void);
937
938#endif /* _LIBFC_H_ */
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
new file mode 100644
index 000000000000..89fdbb9a6a1b
--- /dev/null
+++ b/include/scsi/libfcoe.h
@@ -0,0 +1,176 @@
1/*
2 * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Maintained at www.Open-FCoE.org
18 */
19
20#ifndef _LIBFCOE_H
21#define _LIBFCOE_H
22
23#include <linux/netdevice.h>
24#include <linux/skbuff.h>
25#include <scsi/fc/fc_fcoe.h>
26#include <scsi/libfc.h>
27
28/*
29 * this percpu struct for fcoe
30 */
31struct fcoe_percpu_s {
32 int cpu;
33 struct task_struct *thread;
34 struct sk_buff_head fcoe_rx_list;
35 struct page *crc_eof_page;
36 int crc_eof_offset;
37};
38
39/*
40 * the fcoe sw transport private data
41 */
42struct fcoe_softc {
43 struct list_head list;
44 struct fc_lport *lp;
45 struct net_device *real_dev;
46 struct net_device *phys_dev; /* device with ethtool_ops */
47 struct packet_type fcoe_packet_type;
48 struct sk_buff_head fcoe_pending_queue;
49
50 u8 dest_addr[ETH_ALEN];
51 u8 ctl_src_addr[ETH_ALEN];
52 u8 data_src_addr[ETH_ALEN];
53 /*
54 * fcoe protocol address learning related stuff
55 */
56 u16 flogi_oxid;
57 u8 flogi_progress;
58 u8 address_mode;
59};
60
61static inline struct fcoe_softc *fcoe_softc(
62 const struct fc_lport *lp)
63{
64 return (struct fcoe_softc *)lport_priv(lp);
65}
66
67static inline struct net_device *fcoe_netdev(
68 const struct fc_lport *lp)
69{
70 return fcoe_softc(lp)->real_dev;
71}
72
73static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb)
74{
75 return (struct fcoe_hdr *)skb_network_header(skb);
76}
77
78static inline int skb_fcoe_offset(const struct sk_buff *skb)
79{
80 return skb_network_offset(skb);
81}
82
83static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb)
84{
85 return (struct fc_frame_header *)skb_transport_header(skb);
86}
87
88static inline int skb_fc_offset(const struct sk_buff *skb)
89{
90 return skb_transport_offset(skb);
91}
92
93static inline void skb_reset_fc_header(struct sk_buff *skb)
94{
95 skb_reset_network_header(skb);
96 skb_set_transport_header(skb, skb_network_offset(skb) +
97 sizeof(struct fcoe_hdr));
98}
99
100static inline bool skb_fc_is_data(const struct sk_buff *skb)
101{
102 return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA;
103}
104
105static inline bool skb_fc_is_cmd(const struct sk_buff *skb)
106{
107 return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD;
108}
109
110static inline bool skb_fc_has_exthdr(const struct sk_buff *skb)
111{
112 return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) ||
113 (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) ||
114 (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH);
115}
116
117static inline bool skb_fc_is_roff(const struct sk_buff *skb)
118{
119 return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF;
120}
121
122static inline u16 skb_fc_oxid(const struct sk_buff *skb)
123{
124 return be16_to_cpu(skb_fc_header(skb)->fh_ox_id);
125}
126
127static inline u16 skb_fc_rxid(const struct sk_buff *skb)
128{
129 return be16_to_cpu(skb_fc_header(skb)->fh_rx_id);
130}
131
132/* FIXME - DMA_BIDIRECTIONAL ? */
133#define skb_cb(skb) ((struct fcoe_rcv_info *)&((skb)->cb[0]))
134#define skb_cmd(skb) (skb_cb(skb)->fr_cmd)
135#define skb_dir(skb) (skb_cmd(skb)->sc_data_direction)
136static inline bool skb_fc_is_read(const struct sk_buff *skb)
137{
138 if (skb_fc_is_cmd(skb) && skb_cmd(skb))
139 return skb_dir(skb) == DMA_FROM_DEVICE;
140 return false;
141}
142
143static inline bool skb_fc_is_write(const struct sk_buff *skb)
144{
145 if (skb_fc_is_cmd(skb) && skb_cmd(skb))
146 return skb_dir(skb) == DMA_TO_DEVICE;
147 return false;
148}
149
150/* libfcoe funcs */
151int fcoe_reset(struct Scsi_Host *shost);
152u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
153 unsigned int scheme, unsigned int port);
154
155u32 fcoe_fc_crc(struct fc_frame *fp);
156int fcoe_xmit(struct fc_lport *, struct fc_frame *);
157int fcoe_rcv(struct sk_buff *, struct net_device *,
158 struct packet_type *, struct net_device *);
159
160int fcoe_percpu_receive_thread(void *arg);
161void fcoe_clean_pending_queue(struct fc_lport *lp);
162void fcoe_percpu_clean(struct fc_lport *lp);
163void fcoe_watchdog(ulong vp);
164int fcoe_link_ok(struct fc_lport *lp);
165
166struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
167int fcoe_hostlist_add(const struct fc_lport *);
168int fcoe_hostlist_remove(const struct fc_lport *);
169
170struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int);
171int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *);
172
173/* fcoe sw hba */
174int __init fcoe_sw_init(void);
175int __exit fcoe_sw_exit(void);
176#endif /* _LIBFCOE_H */
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 61e53f14f7e1..7360e1916e75 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -30,6 +30,7 @@
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <scsi/iscsi_proto.h> 31#include <scsi/iscsi_proto.h>
32#include <scsi/iscsi_if.h> 32#include <scsi/iscsi_if.h>
33#include <scsi/scsi_transport_iscsi.h>
33 34
34struct scsi_transport_template; 35struct scsi_transport_template;
35struct scsi_host_template; 36struct scsi_host_template;
@@ -70,12 +71,12 @@ enum {
70/* Connection suspend "bit" */ 71/* Connection suspend "bit" */
71#define ISCSI_SUSPEND_BIT 1 72#define ISCSI_SUSPEND_BIT 1
72 73
73#define ISCSI_ITT_MASK (0x1fff) 74#define ISCSI_ITT_MASK 0x1fff
74#define ISCSI_TOTAL_CMDS_MAX 4096 75#define ISCSI_TOTAL_CMDS_MAX 4096
75/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */ 76/* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */
76#define ISCSI_TOTAL_CMDS_MIN 16 77#define ISCSI_TOTAL_CMDS_MIN 16
77#define ISCSI_AGE_SHIFT 28 78#define ISCSI_AGE_SHIFT 28
78#define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) 79#define ISCSI_AGE_MASK 0xf
79 80
80#define ISCSI_ADDRESS_BUF_LEN 64 81#define ISCSI_ADDRESS_BUF_LEN 64
81 82
@@ -93,24 +94,38 @@ enum {
93 ISCSI_TASK_RUNNING, 94 ISCSI_TASK_RUNNING,
94}; 95};
95 96
97struct iscsi_r2t_info {
98 __be32 ttt; /* copied from R2T */
99 __be32 exp_statsn; /* copied from R2T */
100 uint32_t data_length; /* copied from R2T */
101 uint32_t data_offset; /* copied from R2T */
102 int data_count; /* DATA-Out payload progress */
103 int datasn;
104 /* LLDs should set/update these values */
105 int sent; /* R2T sequence progress */
106};
107
96struct iscsi_task { 108struct iscsi_task {
97 /* 109 /*
98 * Because LLDs allocate their hdr differently, this is a pointer 110 * Because LLDs allocate their hdr differently, this is a pointer
99 * and length to that storage. It must be setup at session 111 * and length to that storage. It must be setup at session
100 * creation time. 112 * creation time.
101 */ 113 */
102 struct iscsi_cmd *hdr; 114 struct iscsi_hdr *hdr;
103 unsigned short hdr_max; 115 unsigned short hdr_max;
104 unsigned short hdr_len; /* accumulated size of hdr used */ 116 unsigned short hdr_len; /* accumulated size of hdr used */
117 /* copied values in case we need to send tmfs */
118 itt_t hdr_itt;
119 __be32 cmdsn;
120 uint8_t lun[8];
121
105 int itt; /* this ITT */ 122 int itt; /* this ITT */
106 123
107 uint32_t unsol_datasn;
108 unsigned imm_count; /* imm-data (bytes) */ 124 unsigned imm_count; /* imm-data (bytes) */
109 unsigned unsol_count; /* unsolicited (bytes)*/
110 /* offset in unsolicited stream (bytes); */ 125 /* offset in unsolicited stream (bytes); */
111 unsigned unsol_offset; 126 struct iscsi_r2t_info unsol_r2t;
112 unsigned data_count; /* remaining Data-Out */
113 char *data; /* mgmt payload */ 127 char *data; /* mgmt payload */
128 unsigned data_count;
114 struct scsi_cmnd *sc; /* associated SCSI cmd*/ 129 struct scsi_cmnd *sc; /* associated SCSI cmd*/
115 struct iscsi_conn *conn; /* used connection */ 130 struct iscsi_conn *conn; /* used connection */
116 131
@@ -121,6 +136,11 @@ struct iscsi_task {
121 void *dd_data; /* driver/transport data */ 136 void *dd_data; /* driver/transport data */
122}; 137};
123 138
139static inline int iscsi_task_has_unsol_data(struct iscsi_task *task)
140{
141 return task->unsol_r2t.data_length > task->unsol_r2t.sent;
142}
143
124static inline void* iscsi_next_hdr(struct iscsi_task *task) 144static inline void* iscsi_next_hdr(struct iscsi_task *task)
125{ 145{
126 return (void*)task->hdr + task->hdr_len; 146 return (void*)task->hdr + task->hdr_len;
@@ -376,8 +396,9 @@ extern void iscsi_suspend_tx(struct iscsi_conn *conn);
376 * pdu and task processing 396 * pdu and task processing
377 */ 397 */
378extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); 398extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *);
379extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *, 399extern void iscsi_prep_data_out_pdu(struct iscsi_task *task,
380 struct iscsi_data *hdr); 400 struct iscsi_r2t_info *r2t,
401 struct iscsi_data *hdr);
381extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, 402extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
382 char *, uint32_t); 403 char *, uint32_t);
383extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, 404extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h
new file mode 100644
index 000000000000..83e32f6d7859
--- /dev/null
+++ b/include/scsi/libiscsi_tcp.h
@@ -0,0 +1,132 @@
1/*
2 * iSCSI over TCP/IP Data-Path lib
3 *
4 * Copyright (C) 2008 Mike Christie
5 * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
6 * maintained by open-iscsi@googlegroups.com
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * See the file COPYING included with this distribution for more details.
19 */
20
21#ifndef LIBISCSI_TCP_H
22#define LIBISCSI_TCP_H
23
24#include <scsi/libiscsi.h>
25
26struct iscsi_tcp_conn;
27struct iscsi_segment;
28struct sk_buff;
29struct hash_desc;
30
31typedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *,
32 struct iscsi_segment *);
33
34struct iscsi_segment {
35 unsigned char *data;
36 unsigned int size;
37 unsigned int copied;
38 unsigned int total_size;
39 unsigned int total_copied;
40
41 struct hash_desc *hash;
42 unsigned char recv_digest[ISCSI_DIGEST_SIZE];
43 unsigned char digest[ISCSI_DIGEST_SIZE];
44 unsigned int digest_len;
45
46 struct scatterlist *sg;
47 void *sg_mapped;
48 unsigned int sg_offset;
49
50 iscsi_segment_done_fn_t *done;
51};
52
53/* Socket connection recieve helper */
54struct iscsi_tcp_recv {
55 struct iscsi_hdr *hdr;
56 struct iscsi_segment segment;
57
58 /* Allocate buffer for BHS + AHS */
59 uint32_t hdr_buf[64];
60
61 /* copied and flipped values */
62 int datalen;
63};
64
65struct iscsi_tcp_conn {
66 struct iscsi_conn *iscsi_conn;
67 void *dd_data;
68 int stop_stage; /* conn_stop() flag: *
69 * stop to recover, *
70 * stop to terminate */
71 /* control data */
72 struct iscsi_tcp_recv in; /* TCP receive context */
73 /* CRC32C (Rx) LLD should set this is they do not offload */
74 struct hash_desc *rx_hash;
75};
76
77struct iscsi_tcp_task {
78 uint32_t exp_datasn; /* expected target's R2TSN/DataSN */
79 int data_offset;
80 struct iscsi_r2t_info *r2t; /* in progress solict R2T */
81 struct iscsi_pool r2tpool;
82 struct kfifo *r2tqueue;
83 void *dd_data;
84};
85
86enum {
87 ISCSI_TCP_SEGMENT_DONE, /* curr seg has been processed */
88 ISCSI_TCP_SKB_DONE, /* skb is out of data */
89 ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */
90 ISCSI_TCP_SUSPENDED, /* conn is suspended */
91};
92
93extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn);
94extern int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb,
95 unsigned int offset, bool offloaded, int *status);
96extern void iscsi_tcp_cleanup_task(struct iscsi_task *task);
97extern int iscsi_tcp_task_init(struct iscsi_task *task);
98extern int iscsi_tcp_task_xmit(struct iscsi_task *task);
99
100/* segment helpers */
101extern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn);
102extern int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
103 struct iscsi_segment *segment, int recv,
104 unsigned copied);
105extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment);
106
107extern void iscsi_segment_init_linear(struct iscsi_segment *segment,
108 void *data, size_t size,
109 iscsi_segment_done_fn_t *done,
110 struct hash_desc *hash);
111extern int
112iscsi_segment_seek_sg(struct iscsi_segment *segment,
113 struct scatterlist *sg_list, unsigned int sg_count,
114 unsigned int offset, size_t size,
115 iscsi_segment_done_fn_t *done, struct hash_desc *hash);
116
117/* digest helpers */
118extern void iscsi_tcp_dgst_header(struct hash_desc *hash, const void *hdr,
119 size_t hdrlen,
120 unsigned char digest[ISCSI_DIGEST_SIZE]);
121extern struct iscsi_cls_conn *
122iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size,
123 uint32_t conn_idx);
124extern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn);
125
126/* misc helpers */
127extern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session);
128extern void iscsi_tcp_r2tpool_free(struct iscsi_session *session);
129
130extern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
131 struct iscsi_stats *stats);
132#endif /* LIBISCSI_TCP_H */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index a37a8148a310..01a4c58f8bad 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -159,8 +159,6 @@ struct scsi_device {
159 atomic_t iodone_cnt; 159 atomic_t iodone_cnt;
160 atomic_t ioerr_cnt; 160 atomic_t ioerr_cnt;
161 161
162 int timeout;
163
164 struct device sdev_gendev, 162 struct device sdev_gendev,
165 sdev_dev; 163 sdev_dev;
166 164
@@ -367,10 +365,11 @@ extern int scsi_is_target_device(const struct device *);
367extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, 365extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
368 int data_direction, void *buffer, unsigned bufflen, 366 int data_direction, void *buffer, unsigned bufflen,
369 unsigned char *sense, int timeout, int retries, 367 unsigned char *sense, int timeout, int retries,
370 int flag); 368 int flag, int *resid);
371extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, 369extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
372 int data_direction, void *buffer, unsigned bufflen, 370 int data_direction, void *buffer, unsigned bufflen,
373 struct scsi_sense_hdr *, int timeout, int retries); 371 struct scsi_sense_hdr *, int timeout, int retries,
372 int *resid);
374extern int scsi_execute_async(struct scsi_device *sdev, 373extern int scsi_execute_async(struct scsi_device *sdev,
375 const unsigned char *cmd, int cmd_len, int data_direction, 374 const unsigned char *cmd, int cmd_len, int data_direction,
376 void *buffer, unsigned bufflen, int use_sg, 375 void *buffer, unsigned bufflen, int use_sg,
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index c667cc396545..b50aabe2861e 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -113,10 +113,18 @@ struct iscsi_transport {
113 char *data, uint32_t data_size); 113 char *data, uint32_t data_size);
114 void (*get_stats) (struct iscsi_cls_conn *conn, 114 void (*get_stats) (struct iscsi_cls_conn *conn,
115 struct iscsi_stats *stats); 115 struct iscsi_stats *stats);
116
116 int (*init_task) (struct iscsi_task *task); 117 int (*init_task) (struct iscsi_task *task);
117 int (*xmit_task) (struct iscsi_task *task); 118 int (*xmit_task) (struct iscsi_task *task);
118 void (*cleanup_task) (struct iscsi_conn *conn, 119 void (*cleanup_task) (struct iscsi_task *task);
119 struct iscsi_task *task); 120
121 int (*alloc_pdu) (struct iscsi_task *task, uint8_t opcode);
122 int (*xmit_pdu) (struct iscsi_task *task);
123 int (*init_pdu) (struct iscsi_task *task, unsigned int offset,
124 unsigned int count);
125 void (*parse_pdu_itt) (struct iscsi_conn *conn, itt_t itt,
126 int *index, int *age);
127
120 void (*session_recovery_timedout) (struct iscsi_cls_session *session); 128 void (*session_recovery_timedout) (struct iscsi_cls_session *session);
121 struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr, 129 struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr,
122 int non_blocking); 130 int non_blocking);