Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f358dd0c authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: NVME Target: Base modifications



NVME Target: Base modifications

This set of patches adds the base modifications for NVME target support

The base modifications consist of:
- Additional module parameters or configuration tuning
- Enablement of configuration mode for NVME target. Ties into the
  queueing model put into place by the initiator basemods patches.
- Target-specific buffer pools, dma pools, sgl pools

[mkp: fixed space at end of file]

Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent bd2cdd5e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -741,6 +741,7 @@ struct lpfc_hba {
	uint8_t  fcp_embed_io;
	uint8_t  nvme_support;	/* Firmware supports NVME */
	uint8_t  nvmet_support;	/* driver supports NVMET */
#define LPFC_NVMET_MAX_PORTS	32
	uint8_t  mds_diags_support;

	/* HBA Config Parameters */
@@ -766,8 +767,10 @@ struct lpfc_hba {
	uint32_t cfg_fcp_imax;
	uint32_t cfg_fcp_cpu_map;
	uint32_t cfg_fcp_io_channel;
	uint32_t cfg_suppress_rsp;
	uint32_t cfg_nvme_oas;
	uint32_t cfg_nvme_io_channel;
	uint32_t cfg_enable_nvmet;
	uint32_t cfg_nvme_enable_fb;
	uint32_t cfg_total_seg_cnt;
	uint32_t cfg_sg_seg_cnt;
@@ -820,6 +823,7 @@ struct lpfc_hba {
#define LPFC_ENABLE_NVME 2
#define LPFC_ENABLE_BOTH 3
	uint32_t io_channel_irqs;	/* number of irqs for io channels */
	struct nvmet_fc_target_port *targetport;
	lpfc_vpd_t vpd;		/* vital product data */

	struct pci_dev *pcidev;
@@ -1103,6 +1107,8 @@ struct lpfc_hba {
	uint16_t cpucheck_on;
#define LPFC_CHECK_OFF		0
#define LPFC_CHECK_NVME_IO	1
#define LPFC_CHECK_NVMET_RCV	2
#define LPFC_CHECK_NVMET_IO	4
	uint16_t ktime_on;
	uint64_t ktime_data_samples;
	uint64_t ktime_status_samples;
+123 −8
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include "lpfc.h"
#include "lpfc_scsi.h"
#include "lpfc_nvme.h"
#include "lpfc_nvmet.h"
#include "lpfc_logmsg.h"
#include "lpfc_version.h"
#include "lpfc_compat.h"
@@ -139,6 +140,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
	struct Scsi_Host *shost = class_to_shost(dev);
	struct lpfc_vport *vport = shost_priv(shost);
	struct lpfc_hba   *phba = vport->phba;
	struct lpfc_nvmet_tgtport *tgtp;
	struct nvme_fc_local_port *localport;
	struct lpfc_nvme_lport *lport;
	struct lpfc_nvme_rport *rport;
@@ -150,6 +152,92 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
		len += snprintf(buf, PAGE_SIZE, "NVME Disabled\n");
		return len;
	}
	if (phba->nvmet_support) {
		if (!phba->targetport) {
			len = snprintf(buf, PAGE_SIZE,
					"NVME Target: x%llx is not allocated\n",
					wwn_to_u64(vport->fc_portname.u.wwn));
			return len;
		}
		/* Port state is only one of two values for now. */
		if (phba->targetport->port_id)
			statep = "REGISTERED";
		else
			statep = "INIT";
		len += snprintf(buf + len, PAGE_SIZE - len,
				"NVME Target: Enabled  State %s\n",
				statep);
		len += snprintf(buf + len, PAGE_SIZE - len,
				"%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
				"NVME Target: lpfc",
				phba->brd_no,
				wwn_to_u64(vport->fc_portname.u.wwn),
				wwn_to_u64(vport->fc_nodename.u.wwn),
				phba->targetport->port_id);

		len += snprintf(buf + len, PAGE_SIZE,
				"\nNVME Target: Statistics\n");
		tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
		len += snprintf(buf+len, PAGE_SIZE-len,
				"LS: Rcv %08x Drop %08x Abort %08x\n",
				atomic_read(&tgtp->rcv_ls_req_in),
				atomic_read(&tgtp->rcv_ls_req_drop),
				atomic_read(&tgtp->xmt_ls_abort));
		if (atomic_read(&tgtp->rcv_ls_req_in) !=
		    atomic_read(&tgtp->rcv_ls_req_out)) {
			len += snprintf(buf+len, PAGE_SIZE-len,
					"Rcv LS: in %08x != out %08x\n",
					atomic_read(&tgtp->rcv_ls_req_in),
					atomic_read(&tgtp->rcv_ls_req_out));
		}

		len += snprintf(buf+len, PAGE_SIZE-len,
				"LS: Xmt %08x Drop %08x Cmpl %08x Err %08x\n",
				atomic_read(&tgtp->xmt_ls_rsp),
				atomic_read(&tgtp->xmt_ls_drop),
				atomic_read(&tgtp->xmt_ls_rsp_cmpl),
				atomic_read(&tgtp->xmt_ls_rsp_error));

		len += snprintf(buf+len, PAGE_SIZE-len,
				"FCP: Rcv %08x Drop %08x\n",
				atomic_read(&tgtp->rcv_fcp_cmd_in),
				atomic_read(&tgtp->rcv_fcp_cmd_drop));

		if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
		    atomic_read(&tgtp->rcv_fcp_cmd_out)) {
			len += snprintf(buf+len, PAGE_SIZE-len,
					"Rcv FCP: in %08x != out %08x\n",
					atomic_read(&tgtp->rcv_fcp_cmd_in),
					atomic_read(&tgtp->rcv_fcp_cmd_out));
		}

		len += snprintf(buf+len, PAGE_SIZE-len,
				"FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x\n",
				atomic_read(&tgtp->xmt_fcp_read),
				atomic_read(&tgtp->xmt_fcp_read_rsp),
				atomic_read(&tgtp->xmt_fcp_write),
				atomic_read(&tgtp->xmt_fcp_rsp));

		len += snprintf(buf+len, PAGE_SIZE-len,
				"FCP Rsp: abort %08x drop %08x\n",
				atomic_read(&tgtp->xmt_fcp_abort),
				atomic_read(&tgtp->xmt_fcp_drop));

		len += snprintf(buf+len, PAGE_SIZE-len,
				"FCP Rsp Cmpl: %08x err %08x drop %08x\n",
				atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
				atomic_read(&tgtp->xmt_fcp_rsp_error),
				atomic_read(&tgtp->xmt_fcp_rsp_drop));

		len += snprintf(buf+len, PAGE_SIZE-len,
				"ABORT: Xmt %08x Err %08x Cmpl %08x",
				atomic_read(&tgtp->xmt_abort_rsp),
				atomic_read(&tgtp->xmt_abort_rsp_error),
				atomic_read(&tgtp->xmt_abort_cmpl));

		len +=  snprintf(buf+len, PAGE_SIZE-len, "\n");
		return len;
	}

	localport = vport->localport;
	if (!localport) {
@@ -2899,6 +2987,13 @@ lpfc_oas_lun_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(lpfc_xlane_lun, S_IRUGO | S_IWUSR,
		   lpfc_oas_lun_show, lpfc_oas_lun_store);

int lpfc_enable_nvmet_cnt;
unsigned long long lpfc_enable_nvmet[LPFC_NVMET_MAX_PORTS] = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
module_param_array(lpfc_enable_nvmet, ullong, &lpfc_enable_nvmet_cnt, 0444);
MODULE_PARM_DESC(lpfc_enable_nvmet, "Enable HBA port(s) WWPN as a NVME Target");

static int lpfc_poll = 0;
module_param(lpfc_poll, int, S_IRUGO);
MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
@@ -3177,6 +3272,15 @@ lpfc_vport_param_store(devloss_tmo)
static DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
		   lpfc_devloss_tmo_show, lpfc_devloss_tmo_store);

/*
 * lpfc_suppress_rsp: Enable suppress rsp feature is firmware supports it
 * lpfc_suppress_rsp = 0  Disable
 * lpfc_suppress_rsp = 1  Enable (default)
 *
 */
LPFC_ATTR_R(suppress_rsp, 1, 0, 1,
	    "Enable suppress rsp feature is firmware supports it");

/*
 * lpfc_enable_fc4_type: Defines what FC4 types are supported.
 * Supported Values:  1 - register just FCP
@@ -3190,7 +3294,8 @@ LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_BOTH,
/*
 * lpfc_xri_split: Defines the division of XRI resources between SCSI and NVME
 * This parameter is only used if:
 *     lpfc_enable_fc4_type is 3 - register both FCP and NVME
 *     lpfc_enable_fc4_type is 3 - register both FCP and NVME and
 *     port is not configured for NVMET.
 *
 * ELS/CT always get 10% of XRIs, up to a maximum of 250
 * The remaining XRIs get split up based on lpfc_xri_split per port:
@@ -4754,7 +4859,7 @@ LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
	    "MSI-X (2), if possible");

/*
 * lpfc_nvme_oas: Use the oas bit when sending NVME IOs
 * lpfc_nvme_oas: Use the oas bit when sending NVME/NVMET IOs
 *
 *      0  = NVME OAS disabled
 *      1  = NVME OAS enabled
@@ -4992,6 +5097,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
	&dev_attr_lpfc_fcp_imax,
	&dev_attr_lpfc_fcp_cpu_map,
	&dev_attr_lpfc_fcp_io_channel,
	&dev_attr_lpfc_suppress_rsp,
	&dev_attr_lpfc_nvme_io_channel,
	&dev_attr_lpfc_nvme_enable_fb,
	&dev_attr_lpfc_enable_bg,
@@ -6027,6 +6133,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
		phba->cfg_poll = 0;
	else
		phba->cfg_poll = lpfc_poll;
	lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);

	lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);

@@ -6046,17 +6153,17 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	}

	/* A value of 0 means use the number of CPUs found in the system */
	if (phba->cfg_nvme_io_channel == 0)
		phba->cfg_nvme_io_channel = phba->sli4_hba.num_present_cpu;
	if (phba->cfg_fcp_io_channel == 0)
		phba->cfg_fcp_io_channel = phba->sli4_hba.num_present_cpu;

	if (phba->cfg_enable_fc4_type == LPFC_ENABLE_FCP)
		phba->cfg_nvme_io_channel = 0;
	if (phba->cfg_nvme_io_channel == 0)
		phba->cfg_nvme_io_channel = phba->sli4_hba.num_present_cpu;

	if (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)
		phba->cfg_fcp_io_channel = 0;

	if (phba->cfg_enable_fc4_type == LPFC_ENABLE_FCP)
		phba->cfg_nvme_io_channel = 0;

	if (phba->cfg_fcp_io_channel > phba->cfg_nvme_io_channel)
		phba->io_channel_irqs = phba->cfg_fcp_io_channel;
	else
@@ -6088,12 +6195,20 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
void
lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
{
	phba->nvmet_support = 0;
	if (phba->cfg_nvme_io_channel > phba->sli4_hba.num_present_cpu)
		phba->cfg_nvme_io_channel = phba->sli4_hba.num_present_cpu;

	if (phba->cfg_fcp_io_channel > phba->sli4_hba.num_present_cpu)
		phba->cfg_fcp_io_channel = phba->sli4_hba.num_present_cpu;

	if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
	    phba->nvmet_support) {
		phba->cfg_enable_fc4_type &= ~LPFC_ENABLE_FCP;
		phba->cfg_fcp_io_channel = 0;
	} else
		/* Not NVME Target mode.  Turn off Target parameters. */
		phba->nvmet_support = 0;

	if (phba->cfg_fcp_io_channel > phba->cfg_nvme_io_channel)
		phba->io_channel_irqs = phba->cfg_fcp_io_channel;
	else
+10 −0
Original line number Diff line number Diff line
@@ -240,6 +240,8 @@ struct hbq_dmabuf *lpfc_els_hbq_alloc(struct lpfc_hba *);
void lpfc_els_hbq_free(struct lpfc_hba *, struct hbq_dmabuf *);
struct hbq_dmabuf *lpfc_sli4_rb_alloc(struct lpfc_hba *);
void lpfc_sli4_rb_free(struct lpfc_hba *, struct hbq_dmabuf *);
struct rqb_dmabuf *lpfc_sli4_nvmet_alloc(struct lpfc_hba *phba);
void lpfc_sli4_nvmet_free(struct lpfc_hba *phba, struct rqb_dmabuf *dmab);
void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
			uint16_t);
int lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
@@ -304,6 +306,8 @@ int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
int lpfc_sli4_issue_wqe(struct lpfc_hba *phba, uint32_t rnum,
			struct lpfc_iocbq *iocbq);
struct lpfc_sglq *__lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xri);
struct lpfc_sglq *__lpfc_sli_get_nvmet_sglq(struct lpfc_hba *phba,
					    struct lpfc_iocbq *piocbq);
void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t);
void lpfc_sli_bemem_bcopy(void *, void *, uint32_t);
void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
@@ -353,6 +357,9 @@ void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *);
void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *);
void __lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
void *lpfc_nvmet_buf_alloc(struct lpfc_hba *phba, int flags,
			dma_addr_t *handle);
void lpfc_nvmet_buf_free(struct lpfc_hba *phba, void *virtp, dma_addr_t dma);

void lpfc_in_buf_free(struct lpfc_hba *, struct lpfc_dmabuf *);
/* Function prototypes. */
@@ -492,6 +499,7 @@ int lpfc_selective_reset(struct lpfc_hba *);
int lpfc_sli4_read_config(struct lpfc_hba *);
void lpfc_sli4_node_prep(struct lpfc_hba *);
int lpfc_sli4_els_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_scsi_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_nvme_sgl_update(struct lpfc_hba *phba);
void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *);
@@ -531,3 +539,5 @@ void lpfc_nvme_mod_param_dep(struct lpfc_hba *phba);
void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba,
				struct lpfc_iocbq *cmdiocb,
				struct lpfc_wcqe_complete *abts_cmpl);
extern int lpfc_enable_nvmet_cnt;
extern unsigned long long lpfc_enable_nvmet[];
+5 −2
Original line number Diff line number Diff line
@@ -828,7 +828,6 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size)
			phba->ktime_data_samples));
		return len;
	}

	return len;
}

@@ -1961,7 +1960,11 @@ lpfc_debugfs_cpucheck_write(struct file *file, const char __user *buf,
		return strlen(pbuf);
	} else if ((strncmp(pbuf, "rcv",
		   sizeof("rcv") - 1) == 0)) {
		if (phba->nvmet_support)
			phba->cpucheck_on |= LPFC_CHECK_NVMET_RCV;
		else
			return -EINVAL;
		return strlen(pbuf);
	} else if ((strncmp(pbuf, "off",
		   sizeof("off") - 1) == 0)) {
		phba->cpucheck_on = LPFC_CHECK_OFF;
+1 −0
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ struct lpfc_node_rrq {
/* Defines for nlp_flag (uint32) */
#define NLP_IGNR_REG_CMPL  0x00000001 /* Rcvd rscn before we cmpl reg login */
#define NLP_REG_LOGIN_SEND 0x00000002   /* sent reglogin to adapter */
#define NLP_SUPPRESS_RSP   0x00000010	/* Remote NPort supports suppress rsp */
#define NLP_PLOGI_SND      0x00000020	/* sent PLOGI request for this entry */
#define NLP_PRLI_SND       0x00000040	/* sent PRLI request for this entry */
#define NLP_ADISC_SND      0x00000080	/* sent ADISC request for this entry */
Loading