123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /* SPDX-License-Identifier: GPL-2.0 */
- /*
- * Copyright (c) 2016, Avago Technologies
- */
- #ifndef _NVME_FC_TRANSPORT_H
- #define _NVME_FC_TRANSPORT_H 1
- /*
- * Common definitions between the nvme_fc (host) transport and
- * nvmet_fc (target) transport implementation.
- */
- /*
- * ****************** FC-NVME LS HANDLING ******************
- */
- union nvmefc_ls_requests {
- struct fcnvme_ls_rqst_w0 w0;
- struct fcnvme_ls_cr_assoc_rqst rq_cr_assoc;
- struct fcnvme_ls_cr_conn_rqst rq_cr_conn;
- struct fcnvme_ls_disconnect_assoc_rqst rq_dis_assoc;
- struct fcnvme_ls_disconnect_conn_rqst rq_dis_conn;
- } __aligned(128); /* alignment for other things alloc'd with */
- union nvmefc_ls_responses {
- struct fcnvme_ls_rjt rsp_rjt;
- struct fcnvme_ls_cr_assoc_acc rsp_cr_assoc;
- struct fcnvme_ls_cr_conn_acc rsp_cr_conn;
- struct fcnvme_ls_disconnect_assoc_acc rsp_dis_assoc;
- struct fcnvme_ls_disconnect_conn_acc rsp_dis_conn;
- } __aligned(128); /* alignment for other things alloc'd with */
- static inline void
- nvme_fc_format_rsp_hdr(void *buf, u8 ls_cmd, __be32 desc_len, u8 rqst_ls_cmd)
- {
- struct fcnvme_ls_acc_hdr *acc = buf;
- acc->w0.ls_cmd = ls_cmd;
- acc->desc_list_len = desc_len;
- acc->rqst.desc_tag = cpu_to_be32(FCNVME_LSDESC_RQST);
- acc->rqst.desc_len =
- fcnvme_lsdesc_len(sizeof(struct fcnvme_lsdesc_rqst));
- acc->rqst.w0.ls_cmd = rqst_ls_cmd;
- }
- static inline int
- nvme_fc_format_rjt(void *buf, u16 buflen, u8 ls_cmd,
- u8 reason, u8 explanation, u8 vendor)
- {
- struct fcnvme_ls_rjt *rjt = buf;
- nvme_fc_format_rsp_hdr(buf, FCNVME_LSDESC_RQST,
- fcnvme_lsdesc_len(sizeof(struct fcnvme_ls_rjt)),
- ls_cmd);
- rjt->rjt.desc_tag = cpu_to_be32(FCNVME_LSDESC_RJT);
- rjt->rjt.desc_len = fcnvme_lsdesc_len(sizeof(struct fcnvme_lsdesc_rjt));
- rjt->rjt.reason_code = reason;
- rjt->rjt.reason_explanation = explanation;
- rjt->rjt.vendor = vendor;
- return sizeof(struct fcnvme_ls_rjt);
- }
- /* Validation Error indexes into the string table below */
- enum {
- VERR_NO_ERROR = 0,
- VERR_CR_ASSOC_LEN = 1,
- VERR_CR_ASSOC_RQST_LEN = 2,
- VERR_CR_ASSOC_CMD = 3,
- VERR_CR_ASSOC_CMD_LEN = 4,
- VERR_ERSP_RATIO = 5,
- VERR_ASSOC_ALLOC_FAIL = 6,
- VERR_QUEUE_ALLOC_FAIL = 7,
- VERR_CR_CONN_LEN = 8,
- VERR_CR_CONN_RQST_LEN = 9,
- VERR_ASSOC_ID = 10,
- VERR_ASSOC_ID_LEN = 11,
- VERR_NO_ASSOC = 12,
- VERR_CONN_ID = 13,
- VERR_CONN_ID_LEN = 14,
- VERR_INVAL_CONN = 15,
- VERR_CR_CONN_CMD = 16,
- VERR_CR_CONN_CMD_LEN = 17,
- VERR_DISCONN_LEN = 18,
- VERR_DISCONN_RQST_LEN = 19,
- VERR_DISCONN_CMD = 20,
- VERR_DISCONN_CMD_LEN = 21,
- VERR_DISCONN_SCOPE = 22,
- VERR_RS_LEN = 23,
- VERR_RS_RQST_LEN = 24,
- VERR_RS_CMD = 25,
- VERR_RS_CMD_LEN = 26,
- VERR_RS_RCTL = 27,
- VERR_RS_RO = 28,
- VERR_LSACC = 29,
- VERR_LSDESC_RQST = 30,
- VERR_LSDESC_RQST_LEN = 31,
- VERR_CR_ASSOC = 32,
- VERR_CR_ASSOC_ACC_LEN = 33,
- VERR_CR_CONN = 34,
- VERR_CR_CONN_ACC_LEN = 35,
- VERR_DISCONN = 36,
- VERR_DISCONN_ACC_LEN = 37,
- };
- static char *validation_errors[] = {
- "OK",
- "Bad CR_ASSOC Length",
- "Bad CR_ASSOC Rqst Length",
- "Not CR_ASSOC Cmd",
- "Bad CR_ASSOC Cmd Length",
- "Bad Ersp Ratio",
- "Association Allocation Failed",
- "Queue Allocation Failed",
- "Bad CR_CONN Length",
- "Bad CR_CONN Rqst Length",
- "Not Association ID",
- "Bad Association ID Length",
- "No Association",
- "Not Connection ID",
- "Bad Connection ID Length",
- "Invalid Connection ID",
- "Not CR_CONN Cmd",
- "Bad CR_CONN Cmd Length",
- "Bad DISCONN Length",
- "Bad DISCONN Rqst Length",
- "Not DISCONN Cmd",
- "Bad DISCONN Cmd Length",
- "Bad Disconnect Scope",
- "Bad RS Length",
- "Bad RS Rqst Length",
- "Not RS Cmd",
- "Bad RS Cmd Length",
- "Bad RS R_CTL",
- "Bad RS Relative Offset",
- "Not LS_ACC",
- "Not LSDESC_RQST",
- "Bad LSDESC_RQST Length",
- "Not CR_ASSOC Rqst",
- "Bad CR_ASSOC ACC Length",
- "Not CR_CONN Rqst",
- "Bad CR_CONN ACC Length",
- "Not Disconnect Rqst",
- "Bad Disconnect ACC Length",
- };
- #define NVME_FC_LAST_LS_CMD_VALUE FCNVME_LS_DISCONNECT_CONN
- static char *nvmefc_ls_names[] = {
- "Reserved (0)",
- "RJT (1)",
- "ACC (2)",
- "Create Association",
- "Create Connection",
- "Disconnect Association",
- "Disconnect Connection",
- };
- static inline void
- nvmefc_fmt_lsreq_discon_assoc(struct nvmefc_ls_req *lsreq,
- struct fcnvme_ls_disconnect_assoc_rqst *discon_rqst,
- struct fcnvme_ls_disconnect_assoc_acc *discon_acc,
- u64 association_id)
- {
- lsreq->rqstaddr = discon_rqst;
- lsreq->rqstlen = sizeof(*discon_rqst);
- lsreq->rspaddr = discon_acc;
- lsreq->rsplen = sizeof(*discon_acc);
- lsreq->timeout = NVME_FC_LS_TIMEOUT_SEC;
- discon_rqst->w0.ls_cmd = FCNVME_LS_DISCONNECT_ASSOC;
- discon_rqst->desc_list_len = cpu_to_be32(
- sizeof(struct fcnvme_lsdesc_assoc_id) +
- sizeof(struct fcnvme_lsdesc_disconn_cmd));
- discon_rqst->associd.desc_tag = cpu_to_be32(FCNVME_LSDESC_ASSOC_ID);
- discon_rqst->associd.desc_len =
- fcnvme_lsdesc_len(
- sizeof(struct fcnvme_lsdesc_assoc_id));
- discon_rqst->associd.association_id = cpu_to_be64(association_id);
- discon_rqst->discon_cmd.desc_tag = cpu_to_be32(
- FCNVME_LSDESC_DISCONN_CMD);
- discon_rqst->discon_cmd.desc_len =
- fcnvme_lsdesc_len(
- sizeof(struct fcnvme_lsdesc_disconn_cmd));
- }
- static inline int
- nvmefc_vldt_lsreq_discon_assoc(u32 rqstlen,
- struct fcnvme_ls_disconnect_assoc_rqst *rqst)
- {
- int ret = 0;
- if (rqstlen < sizeof(struct fcnvme_ls_disconnect_assoc_rqst))
- ret = VERR_DISCONN_LEN;
- else if (rqst->desc_list_len !=
- fcnvme_lsdesc_len(
- sizeof(struct fcnvme_ls_disconnect_assoc_rqst)))
- ret = VERR_DISCONN_RQST_LEN;
- else if (rqst->associd.desc_tag != cpu_to_be32(FCNVME_LSDESC_ASSOC_ID))
- ret = VERR_ASSOC_ID;
- else if (rqst->associd.desc_len !=
- fcnvme_lsdesc_len(
- sizeof(struct fcnvme_lsdesc_assoc_id)))
- ret = VERR_ASSOC_ID_LEN;
- else if (rqst->discon_cmd.desc_tag !=
- cpu_to_be32(FCNVME_LSDESC_DISCONN_CMD))
- ret = VERR_DISCONN_CMD;
- else if (rqst->discon_cmd.desc_len !=
- fcnvme_lsdesc_len(
- sizeof(struct fcnvme_lsdesc_disconn_cmd)))
- ret = VERR_DISCONN_CMD_LEN;
- /*
- * As the standard changed on the LS, check if old format and scope
- * something other than Association (e.g. 0).
- */
- else if (rqst->discon_cmd.rsvd8[0])
- ret = VERR_DISCONN_SCOPE;
- return ret;
- }
- #endif /* _NVME_FC_TRANSPORT_H */
|