1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2016, Avago Technologies
6 #ifndef _NVME_FC_TRANSPORT_H
7 #define _NVME_FC_TRANSPORT_H 1
11 * Common definitions between the nvme_fc (host) transport and
12 * nvmet_fc (target) transport implementation.
16 * ****************** FC-NVME LS HANDLING ******************
19 union nvmefc_ls_requests
{
20 struct fcnvme_ls_rqst_w0 w0
;
21 struct fcnvme_ls_cr_assoc_rqst rq_cr_assoc
;
22 struct fcnvme_ls_cr_conn_rqst rq_cr_conn
;
23 struct fcnvme_ls_disconnect_assoc_rqst rq_dis_assoc
;
24 struct fcnvme_ls_disconnect_conn_rqst rq_dis_conn
;
25 } __aligned(128); /* alignment for other things alloc'd with */
27 union nvmefc_ls_responses
{
28 struct fcnvme_ls_rjt rsp_rjt
;
29 struct fcnvme_ls_cr_assoc_acc rsp_cr_assoc
;
30 struct fcnvme_ls_cr_conn_acc rsp_cr_conn
;
31 struct fcnvme_ls_disconnect_assoc_acc rsp_dis_assoc
;
32 struct fcnvme_ls_disconnect_conn_acc rsp_dis_conn
;
33 } __aligned(128); /* alignment for other things alloc'd with */
36 nvme_fc_format_rsp_hdr(void *buf
, u8 ls_cmd
, __be32 desc_len
, u8 rqst_ls_cmd
)
38 struct fcnvme_ls_acc_hdr
*acc
= buf
;
40 acc
->w0
.ls_cmd
= ls_cmd
;
41 acc
->desc_list_len
= desc_len
;
42 acc
->rqst
.desc_tag
= cpu_to_be32(FCNVME_LSDESC_RQST
);
44 fcnvme_lsdesc_len(sizeof(struct fcnvme_lsdesc_rqst
));
45 acc
->rqst
.w0
.ls_cmd
= rqst_ls_cmd
;
49 nvme_fc_format_rjt(void *buf
, u16 buflen
, u8 ls_cmd
,
50 u8 reason
, u8 explanation
, u8 vendor
)
52 struct fcnvme_ls_rjt
*rjt
= buf
;
54 nvme_fc_format_rsp_hdr(buf
, FCNVME_LSDESC_RQST
,
55 fcnvme_lsdesc_len(sizeof(struct fcnvme_ls_rjt
)),
57 rjt
->rjt
.desc_tag
= cpu_to_be32(FCNVME_LSDESC_RJT
);
58 rjt
->rjt
.desc_len
= fcnvme_lsdesc_len(sizeof(struct fcnvme_lsdesc_rjt
));
59 rjt
->rjt
.reason_code
= reason
;
60 rjt
->rjt
.reason_explanation
= explanation
;
61 rjt
->rjt
.vendor
= vendor
;
63 return sizeof(struct fcnvme_ls_rjt
);
66 /* Validation Error indexes into the string table below */
69 VERR_CR_ASSOC_LEN
= 1,
70 VERR_CR_ASSOC_RQST_LEN
= 2,
71 VERR_CR_ASSOC_CMD
= 3,
72 VERR_CR_ASSOC_CMD_LEN
= 4,
74 VERR_ASSOC_ALLOC_FAIL
= 6,
75 VERR_QUEUE_ALLOC_FAIL
= 7,
77 VERR_CR_CONN_RQST_LEN
= 9,
79 VERR_ASSOC_ID_LEN
= 11,
82 VERR_CONN_ID_LEN
= 14,
84 VERR_CR_CONN_CMD
= 16,
85 VERR_CR_CONN_CMD_LEN
= 17,
86 VERR_DISCONN_LEN
= 18,
87 VERR_DISCONN_RQST_LEN
= 19,
88 VERR_DISCONN_CMD
= 20,
89 VERR_DISCONN_CMD_LEN
= 21,
90 VERR_DISCONN_SCOPE
= 22,
92 VERR_RS_RQST_LEN
= 24,
98 VERR_LSDESC_RQST
= 30,
99 VERR_LSDESC_RQST_LEN
= 31,
101 VERR_CR_ASSOC_ACC_LEN
= 33,
103 VERR_CR_CONN_ACC_LEN
= 35,
105 VERR_DISCONN_ACC_LEN
= 37,
108 static char *validation_errors
[] = {
110 "Bad CR_ASSOC Length",
111 "Bad CR_ASSOC Rqst Length",
113 "Bad CR_ASSOC Cmd Length",
115 "Association Allocation Failed",
116 "Queue Allocation Failed",
117 "Bad CR_CONN Length",
118 "Bad CR_CONN Rqst Length",
119 "Not Association ID",
120 "Bad Association ID Length",
123 "Bad Connection ID Length",
124 "Invalid Connection ID",
126 "Bad CR_CONN Cmd Length",
127 "Bad DISCONN Length",
128 "Bad DISCONN Rqst Length",
130 "Bad DISCONN Cmd Length",
131 "Bad Disconnect Scope",
133 "Bad RS Rqst Length",
137 "Bad RS Relative Offset",
140 "Bad LSDESC_RQST Length",
142 "Bad CR_ASSOC ACC Length",
144 "Bad CR_CONN ACC Length",
145 "Not Disconnect Rqst",
146 "Bad Disconnect ACC Length",
149 #define NVME_FC_LAST_LS_CMD_VALUE FCNVME_LS_DISCONNECT_CONN
151 static char *nvmefc_ls_names
[] = {
155 "Create Association",
157 "Disconnect Association",
158 "Disconnect Connection",
162 nvmefc_fmt_lsreq_discon_assoc(struct nvmefc_ls_req
*lsreq
,
163 struct fcnvme_ls_disconnect_assoc_rqst
*discon_rqst
,
164 struct fcnvme_ls_disconnect_assoc_acc
*discon_acc
,
167 lsreq
->rqstaddr
= discon_rqst
;
168 lsreq
->rqstlen
= sizeof(*discon_rqst
);
169 lsreq
->rspaddr
= discon_acc
;
170 lsreq
->rsplen
= sizeof(*discon_acc
);
171 lsreq
->timeout
= NVME_FC_LS_TIMEOUT_SEC
;
173 discon_rqst
->w0
.ls_cmd
= FCNVME_LS_DISCONNECT_ASSOC
;
174 discon_rqst
->desc_list_len
= cpu_to_be32(
175 sizeof(struct fcnvme_lsdesc_assoc_id
) +
176 sizeof(struct fcnvme_lsdesc_disconn_cmd
));
178 discon_rqst
->associd
.desc_tag
= cpu_to_be32(FCNVME_LSDESC_ASSOC_ID
);
179 discon_rqst
->associd
.desc_len
=
181 sizeof(struct fcnvme_lsdesc_assoc_id
));
183 discon_rqst
->associd
.association_id
= cpu_to_be64(association_id
);
185 discon_rqst
->discon_cmd
.desc_tag
= cpu_to_be32(
186 FCNVME_LSDESC_DISCONN_CMD
);
187 discon_rqst
->discon_cmd
.desc_len
=
189 sizeof(struct fcnvme_lsdesc_disconn_cmd
));
193 nvmefc_vldt_lsreq_discon_assoc(u32 rqstlen
,
194 struct fcnvme_ls_disconnect_assoc_rqst
*rqst
)
198 if (rqstlen
< sizeof(struct fcnvme_ls_disconnect_assoc_rqst
))
199 ret
= VERR_DISCONN_LEN
;
200 else if (rqst
->desc_list_len
!=
202 sizeof(struct fcnvme_ls_disconnect_assoc_rqst
)))
203 ret
= VERR_DISCONN_RQST_LEN
;
204 else if (rqst
->associd
.desc_tag
!= cpu_to_be32(FCNVME_LSDESC_ASSOC_ID
))
206 else if (rqst
->associd
.desc_len
!=
208 sizeof(struct fcnvme_lsdesc_assoc_id
)))
209 ret
= VERR_ASSOC_ID_LEN
;
210 else if (rqst
->discon_cmd
.desc_tag
!=
211 cpu_to_be32(FCNVME_LSDESC_DISCONN_CMD
))
212 ret
= VERR_DISCONN_CMD
;
213 else if (rqst
->discon_cmd
.desc_len
!=
215 sizeof(struct fcnvme_lsdesc_disconn_cmd
)))
216 ret
= VERR_DISCONN_CMD_LEN
;
218 * As the standard changed on the LS, check if old format and scope
219 * something other than Association (e.g. 0).
221 else if (rqst
->discon_cmd
.rsvd8
[0])
222 ret
= VERR_DISCONN_SCOPE
;
227 #endif /* _NVME_FC_TRANSPORT_H */