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

scsi: lpfc: Add Buffer to Buffer credit recovery support



Add Buffer to buffer credit recovery support to the driver.  This is a
negotiated feature with the peer that allows for both sides to detect
dropped RRDY's and FC Frames and recover credit.

Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d58734f0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -733,7 +733,6 @@ struct lpfc_hba {
	uint32_t fc_rttov;	/* R_T_TOV timer value */
	uint32_t fc_altov;	/* AL_TOV timer value */
	uint32_t fc_crtov;	/* C_R_TOV timer value */
	uint32_t fc_citov;	/* C_I_TOV timer value */

	struct serv_parm fc_fabparam;	/* fabric service parameters buffer */
	uint8_t alpa_map[128];	/* AL_PA map from READ_LA */
@@ -757,6 +756,7 @@ struct lpfc_hba {
#define LPFC_NVMET_MAX_PORTS	32
	uint8_t  mds_diags_support;
	uint32_t initial_imax;
	uint8_t  bbcredit_support;

	/* HBA Config Parameters */
	uint32_t cfg_ack0;
@@ -836,6 +836,7 @@ struct lpfc_hba {
	uint32_t cfg_enable_SmartSAN;
	uint32_t cfg_enable_mds_diags;
	uint32_t cfg_enable_fc4_type;
	uint32_t cfg_enable_bbcr;	/*Enable BB Credit Recovery*/
	uint32_t cfg_xri_split;
#define LPFC_ENABLE_FCP  1
#define LPFC_ENABLE_NVME 2
+41 −0
Original line number Diff line number Diff line
@@ -1888,6 +1888,36 @@ static inline bool lpfc_rangecheck(uint val, uint min, uint max)
	return val >= min && val <= max;
}

/**
 * lpfc_enable_bbcr_set: Sets an attribute value.
 * @phba: pointer the the adapter structure.
 * @val: integer attribute value.
 *
 * Description:
 * Validates the min and max values then sets the
 * adapter config field if in the valid range. prints error message
 * and does not set the parameter if invalid.
 *
 * Returns:
 * zero on success
 * -EINVAL if val is invalid
 */
static ssize_t
lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val)
{
	if (lpfc_rangecheck(val, 0, 1) && phba->sli_rev == LPFC_SLI_REV4) {
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"3068 %s_enable_bbcr changed from %d to %d\n",
				LPFC_DRIVER_NAME, phba->cfg_enable_bbcr, val);
		phba->cfg_enable_bbcr = val;
		return 0;
	}
	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
			"0451 %s_enable_bbcr cannot set to %d, range is 0, 1\n",
			LPFC_DRIVER_NAME, val);
	return -EINVAL;
}

/**
 * lpfc_param_show - Return a cfg attribute value in decimal
 *
@@ -5111,6 +5141,14 @@ LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT,
 */
LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");

/*
 * lpfc_enable_bbcr: Enable BB Credit Recovery
 *       0  = BB Credit Recovery disabled
 *       1  = BB Credit Recovery enabled (default)
 * Value range is [0,1]. Default value is 1.
 */
LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");

struct device_attribute *lpfc_hba_attrs[] = {
	&dev_attr_nvme_info,
	&dev_attr_bg_info,
@@ -5218,6 +5256,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
	&dev_attr_protocol,
	&dev_attr_lpfc_xlane_supported,
	&dev_attr_lpfc_enable_mds_diags,
	&dev_attr_lpfc_enable_bbcr,
	NULL,
};

@@ -6229,11 +6268,13 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size);
	lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
	lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel);
	lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);

	if (phba->sli_rev != LPFC_SLI_REV4) {
		/* NVME only supported on SLI4 */
		phba->nvmet_support = 0;
		phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
		phba->cfg_enable_bbcr = 0;
	} else {
		/* We MUST have FCP support */
		if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
+10 −0
Original line number Diff line number Diff line
@@ -46,6 +46,16 @@ lpfc_param_store(name)\
static DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
		   lpfc_##name##_show, lpfc_##name##_store)

#define LPFC_BBCR_ATTR_RW(name, defval, minval, maxval, desc) \
static uint lpfc_##name = defval;\
module_param(lpfc_##name, uint, 0444);\
MODULE_PARM_DESC(lpfc_##name, desc);\
lpfc_param_show(name)\
lpfc_param_init(name, defval, minval, maxval)\
lpfc_param_store(name)\
static DEVICE_ATTR(lpfc_##name, 0444 | 0644,\
		   lpfc_##name##_show, lpfc_##name##_store)

#define LPFC_ATTR_HEX_R(name, defval, minval, maxval, desc) \
static uint lpfc_##name = defval;\
module_param(lpfc_##name, uint, S_IRUGO);\
+13 −1
Original line number Diff line number Diff line
@@ -2033,6 +2033,7 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)

	sp->cmn.valid_vendor_ver_level = 0;
	memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion));
	sp->cmn.bbRcvSizeMsb &= 0xF;

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
		"Issue PLOGI:     did:x%x",
@@ -3456,8 +3457,18 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
				maxretry = 3;
				delay = 1000;
				retry = 1;
				break;
			} else if (cmd == ELS_CMD_FLOGI &&
				   stat.un.b.lsRjtRsnCodeExp ==
						LSEXP_NOTHING_MORE) {
				vport->fc_sparam.cmn.bbRcvSizeMsb &= 0xf;
				retry = 1;
				lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
						 "0820 FLOGI Failed (x%x). "
						 "BBCredit Not Supported\n",
						 stat.un.lsRjtError);
			}
			break;

		case LSRJT_PROTOCOL_ERR:
			if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
			  (cmd == ELS_CMD_FDISC) &&
@@ -4201,6 +4212,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
			sp->cmn.valid_vendor_ver_level = 0;
			memset(sp->un.vendorVersion, 0,
			       sizeof(sp->un.vendorVersion));
			sp->cmn.bbRcvSizeMsb &= 0xF;

			/* If our firmware supports this feature, convey that
			 * info to the target using the vendor specific field.
+10 −2
Original line number Diff line number Diff line
@@ -1108,6 +1108,7 @@ void
lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
	struct lpfc_vport *vport = pmb->vport;
	uint8_t bbscn = 0;

	if (pmb->u.mb.mbxStatus)
		goto out;
@@ -1134,10 +1135,17 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	/* Start discovery by sending a FLOGI. port_state is identically
	 * LPFC_FLOGI while waiting for FLOGI cmpl
	 */
	if (vport->port_state != LPFC_FLOGI)
	if (vport->port_state != LPFC_FLOGI) {
		if (phba->bbcredit_support && phba->cfg_enable_bbcr) {
			bbscn = bf_get(lpfc_bbscn_def,
				       &phba->sli4_hba.bbscn_params);
			vport->fc_sparam.cmn.bbRcvSizeMsb &= 0xf;
			vport->fc_sparam.cmn.bbRcvSizeMsb |= (bbscn << 4);
		}
		lpfc_initial_flogi(vport);
	else if (vport->fc_flag & FC_PT2PT)
	} else if (vport->fc_flag & FC_PT2PT) {
		lpfc_disc_start(vport);
	}
	return;

out:
Loading