254 lines · c
1/*******************************************************************2 * This file is part of the Emulex Linux Device Driver for *3 * Fibre Channel Host Bus Adapters. *4 * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term *5 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *6 * Copyright (C) 2004-2016 Emulex. All rights reserved. *7 * EMULEX and SLI are trademarks of Emulex. *8 * www.broadcom.com *9 * Portions Copyright (C) 2004-2005 Christoph Hellwig *10 * *11 * This program is free software; you can redistribute it and/or *12 * modify it under the terms of version 2 of the GNU General *13 * Public License as published by the Free Software Foundation. *14 * This program is distributed in the hope that it will be useful. *15 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *16 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *17 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *18 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *19 * TO BE LEGALLY INVALID. See the GNU General Public License for *20 * more details, a copy of which can be found in the file COPYING *21 * included with this package. *22 ********************************************************************/23 24#include <linux/nvme.h>25#include <linux/nvme-fc-driver.h>26#include <linux/nvme-fc.h>27 28#define LPFC_NVME_DEFAULT_SEGS (64 + 1) /* 256K IOs */29 30#define LPFC_NVME_ERSP_LEN 0x2031 32#define LPFC_NVME_WAIT_TMO 1033#define LPFC_NVME_EXPEDITE_XRICNT 834#define LPFC_NVME_FB_SHIFT 935#define LPFC_NVME_MAX_FB (1 << 20) /* 1M */36 37#define lpfc_ndlp_get_nrport(ndlp) \38 ((!ndlp->nrport || (ndlp->fc4_xpt_flags & NVME_XPT_UNREG_WAIT))\39 ? NULL : ndlp->nrport)40 41struct lpfc_nvme_qhandle {42 uint32_t index; /* WQ index to use */43 uint32_t qidx; /* queue index passed to create */44 uint32_t cpu_id; /* current cpu id at time of create */45};46 47/* Declare nvme-based local and remote port definitions. */48struct lpfc_nvme_lport {49 struct lpfc_vport *vport;50 struct completion *lport_unreg_cmp;51 /* Add stats counters here */52 atomic_t fc4NvmeLsRequests;53 atomic_t fc4NvmeLsCmpls;54 atomic_t xmt_fcp_noxri;55 atomic_t xmt_fcp_bad_ndlp;56 atomic_t xmt_fcp_qdepth;57 atomic_t xmt_fcp_wqerr;58 atomic_t xmt_fcp_err;59 atomic_t xmt_fcp_abort;60 atomic_t xmt_ls_abort;61 atomic_t xmt_ls_err;62 atomic_t cmpl_fcp_xb;63 atomic_t cmpl_fcp_err;64 atomic_t cmpl_ls_xb;65 atomic_t cmpl_ls_err;66};67 68struct lpfc_nvme_rport {69 struct lpfc_nvme_lport *lport;70 struct nvme_fc_remote_port *remoteport;71 struct lpfc_nodelist *ndlp;72 struct completion rport_unreg_done;73};74 75struct lpfc_nvme_fcpreq_priv {76 struct lpfc_io_buf *nvme_buf;77};78 79/*80 * set NVME LS request timeouts to 30s. It is larger than the 2*R_A_TOV81 * set by the spec, which appears to have issues with some devices.82 */83#define LPFC_NVME_LS_TIMEOUT 3084 85 86#define LPFC_NVMET_DEFAULT_SEGS (64 + 1) /* 256K IOs */87#define LPFC_NVMET_RQE_MIN_POST 12888#define LPFC_NVMET_RQE_DEF_POST 51289#define LPFC_NVMET_RQE_DEF_COUNT 204890#define LPFC_NVMET_SUCCESS_LEN 1291 92#define LPFC_NVMET_MRQ_AUTO 093#define LPFC_NVMET_MRQ_MAX 1694 95#define LPFC_NVMET_WAIT_TMO (5 * MSEC_PER_SEC)96 97/* Used for NVME Target */98#define LPFC_NVMET_INV_HOST_ACTIVE 199 100struct lpfc_nvmet_tgtport {101 struct lpfc_hba *phba;102 struct completion *tport_unreg_cmp;103 atomic_t state; /* tracks nvmet hosthandle invalidation */104 105 /* Stats counters - lpfc_nvmet_unsol_ls_buffer */106 atomic_t rcv_ls_req_in;107 atomic_t rcv_ls_req_out;108 atomic_t rcv_ls_req_drop;109 atomic_t xmt_ls_abort;110 atomic_t xmt_ls_abort_cmpl;111 112 /* Stats counters - lpfc_nvmet_xmt_ls_rsp */113 atomic_t xmt_ls_rsp;114 atomic_t xmt_ls_drop;115 116 /* Stats counters - lpfc_nvmet_xmt_ls_rsp_cmp */117 atomic_t xmt_ls_rsp_error;118 atomic_t xmt_ls_rsp_aborted;119 atomic_t xmt_ls_rsp_xb_set;120 atomic_t xmt_ls_rsp_cmpl;121 122 /* Stats counters - lpfc_nvmet_unsol_fcp_buffer */123 atomic_t rcv_fcp_cmd_in;124 atomic_t rcv_fcp_cmd_out;125 atomic_t rcv_fcp_cmd_drop;126 atomic_t rcv_fcp_cmd_defer;127 atomic_t xmt_fcp_release;128 129 /* Stats counters - lpfc_nvmet_xmt_fcp_op */130 atomic_t xmt_fcp_drop;131 atomic_t xmt_fcp_read_rsp;132 atomic_t xmt_fcp_read;133 atomic_t xmt_fcp_write;134 atomic_t xmt_fcp_rsp;135 136 /* Stats counters - lpfc_nvmet_xmt_fcp_op_cmp */137 atomic_t xmt_fcp_rsp_xb_set;138 atomic_t xmt_fcp_rsp_cmpl;139 atomic_t xmt_fcp_rsp_error;140 atomic_t xmt_fcp_rsp_aborted;141 atomic_t xmt_fcp_rsp_drop;142 143 /* Stats counters - lpfc_nvmet_xmt_fcp_abort */144 atomic_t xmt_fcp_xri_abort_cqe;145 atomic_t xmt_fcp_abort;146 atomic_t xmt_fcp_abort_cmpl;147 atomic_t xmt_abort_sol;148 atomic_t xmt_abort_unsol;149 atomic_t xmt_abort_rsp;150 atomic_t xmt_abort_rsp_error;151 152 /* Stats counters - defer IO */153 atomic_t defer_ctx;154 atomic_t defer_fod;155 atomic_t defer_wqfull;156};157 158struct lpfc_nvmet_ctx_info {159 struct list_head nvmet_ctx_list;160 spinlock_t nvmet_ctx_list_lock; /* lock per CPU */161 struct lpfc_nvmet_ctx_info *nvmet_ctx_next_cpu;162 struct lpfc_nvmet_ctx_info *nvmet_ctx_start_cpu;163 uint16_t nvmet_ctx_list_cnt;164 char pad[16]; /* pad to a cache-line */165};166 167/* This retrieves the context info associated with the specified cpu / mrq */168#define lpfc_get_ctx_list(phba, cpu, mrq) \169 (phba->sli4_hba.nvmet_ctx_info + ((cpu * phba->cfg_nvmet_mrq) + mrq))170 171/* Values for state field of struct lpfc_async_xchg_ctx */172#define LPFC_NVME_STE_LS_RCV 1173#define LPFC_NVME_STE_LS_ABORT 2174#define LPFC_NVME_STE_LS_RSP 3175#define LPFC_NVME_STE_RCV 4176#define LPFC_NVME_STE_DATA 5177#define LPFC_NVME_STE_ABORT 6178#define LPFC_NVME_STE_DONE 7179#define LPFC_NVME_STE_FREE 0xff180 181/* Values for flag field of struct lpfc_async_xchg_ctx */182#define LPFC_NVME_IO_INP 0x1 /* IO is in progress on exchange */183#define LPFC_NVME_ABORT_OP 0x2 /* Abort WQE issued on exchange */184#define LPFC_NVME_XBUSY 0x4 /* XB bit set on IO cmpl */185#define LPFC_NVME_CTX_RLS 0x8 /* ctx free requested */186#define LPFC_NVME_ABTS_RCV 0x10 /* ABTS received on exchange */187#define LPFC_NVME_CTX_REUSE_WQ 0x20 /* ctx reused via WQ */188#define LPFC_NVME_DEFER_WQFULL 0x40 /* Waiting on a free WQE */189#define LPFC_NVME_TNOTIFY 0x80 /* notify transport of abts */190 191struct lpfc_async_xchg_ctx {192 union {193 struct nvmefc_tgt_fcp_req fcp_req;194 } hdlrctx;195 struct list_head list;196 struct lpfc_hba *phba;197 struct lpfc_nodelist *ndlp;198 struct nvmefc_ls_req *ls_req;199 struct nvmefc_ls_rsp ls_rsp;200 struct lpfc_iocbq *wqeq;201 struct lpfc_iocbq *abort_wqeq;202 spinlock_t ctxlock; /* protect flag access */203 uint32_t sid;204 uint32_t offset;205 uint16_t oxid;206 uint16_t size;207 uint16_t entry_cnt;208 uint16_t cpu;209 uint16_t idx;210 uint16_t state;211 uint16_t flag;212 void *payload;213 struct rqb_dmabuf *rqb_buffer;214 struct lpfc_nvmet_ctxbuf *ctxbuf;215 struct lpfc_sli4_hdw_queue *hdwq;216 217#ifdef CONFIG_SCSI_LPFC_DEBUG_FS218 uint64_t ts_isr_cmd;219 uint64_t ts_cmd_nvme;220 uint64_t ts_nvme_data;221 uint64_t ts_data_wqput;222 uint64_t ts_isr_data;223 uint64_t ts_data_nvme;224 uint64_t ts_nvme_status;225 uint64_t ts_status_wqput;226 uint64_t ts_isr_status;227 uint64_t ts_status_nvme;228#endif229};230 231 232/* routines found in lpfc_nvme.c */233int __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,234 struct nvmefc_ls_req *pnvme_lsreq,235 void (*gen_req_cmp)(struct lpfc_hba *phba,236 struct lpfc_iocbq *cmdwqe,237 struct lpfc_iocbq *rspwqe));238void __lpfc_nvme_ls_req_cmp(struct lpfc_hba *phba, struct lpfc_vport *vport,239 struct lpfc_iocbq *cmdwqe, struct lpfc_wcqe_complete *wcqe);240int __lpfc_nvme_ls_abort(struct lpfc_vport *vport,241 struct lpfc_nodelist *ndlp, struct nvmefc_ls_req *pnvme_lsreq);242 243/* routines found in lpfc_nvmet.c */244int lpfc_nvme_unsol_ls_issue_abort(struct lpfc_hba *phba,245 struct lpfc_async_xchg_ctx *ctxp, uint32_t sid,246 uint16_t xri);247int __lpfc_nvme_xmt_ls_rsp(struct lpfc_async_xchg_ctx *axchg,248 struct nvmefc_ls_rsp *ls_rsp,249 void (*xmt_ls_rsp_cmp)(struct lpfc_hba *phba,250 struct lpfc_iocbq *cmdwqe,251 struct lpfc_iocbq *rspwqe));252void __lpfc_nvme_xmt_ls_rsp_cmp(struct lpfc_hba *phba,253 struct lpfc_iocbq *cmdwqe, struct lpfc_iocbq *rspwqe);254