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

scsi: lpfc: Add EDC ELS support

When congestion management is enabled, issue EDC ELS to register congestion
signaling capabilities with the fabric. The response handling will process
the fabric parameters and set the reporting parameters.

Similarly, add support for receiving an EDC request from the fabric
generating a corresponding response.

Implement handlers for congestion signals from the fabric and maintain
statistics for them.

Link: https://lore.kernel.org/r/20210816162901.121235-6-jsmart2021@gmail.com


Co-developed-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 428569e6
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -403,6 +403,11 @@ struct lpfc_trunk_link {
				     link3;
};

struct lpfc_cgn_acqe_stat {
	atomic64_t alarm;
	atomic64_t warn;
};

struct lpfc_vport {
	struct lpfc_hba *phba;
	struct list_head listentry;
@@ -1343,6 +1348,36 @@ struct lpfc_hba {
	uint64_t ktime_seg10_min;
	uint64_t ktime_seg10_max;
#endif
	/* CMF objects */
	u32 cmf_active_mode;
#define LPFC_CFG_OFF		0

	/* Signal / FPIN handling for Congestion Mgmt */
	u8 cgn_reg_fpin;           /* Negotiated value from RDF */
	u8 cgn_init_reg_fpin;      /* Initial value from READ_CONFIG */
#define LPFC_CGN_FPIN_NONE	0x0
#define LPFC_CGN_FPIN_WARN	0x1
#define LPFC_CGN_FPIN_ALARM	0x2
#define LPFC_CGN_FPIN_BOTH	(LPFC_CGN_FPIN_WARN | LPFC_CGN_FPIN_ALARM)

	u8 cgn_reg_signal;          /* Negotiated value from EDC */
	u8 cgn_init_reg_signal;     /* Initial value from READ_CONFIG */
		/* cgn_reg_signal and cgn_init_reg_signal use
		 * enum fc_edc_cg_signal_cap_types
		 */
	u16 cgn_fpin_frequency;
#define LPFC_FPIN_INIT_FREQ	0xffff
	u32 cgn_sig_freq;
	u32 cgn_acqe_cnt;

	/* Statistics counter for ACQE cgn alarms and warnings */
	struct lpfc_cgn_acqe_stat cgn_acqe_stat;

	/* Congestion buffer information */
	atomic_t cgn_fabric_warn_cnt;   /* Total warning cgn events for info */
	atomic_t cgn_fabric_alarm_cnt;  /* Total alarm cgn events for info */
	atomic_t cgn_sync_warn_cnt;     /* Total warning events for SYNC wqe */
	atomic_t cgn_sync_alarm_cnt;    /* Total alarm events for SYNC wqe */

	struct hlist_node cpuhp;	/* used for cpuhp per hba callback */
	struct timer_list cpuhp_poll_timer;
+27 −0
Original line number Diff line number Diff line
@@ -6150,6 +6150,19 @@ LPFC_ATTR_RW(ras_fwlog_func, 0, 0, 7, "Firmware Logging Enabled on Function");
 */
LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");

/* Signaling module parameters */
int lpfc_fabric_cgn_frequency = 100; /* 100 ms default */
module_param(lpfc_fabric_cgn_frequency, int, 0444);
MODULE_PARM_DESC(lpfc_fabric_cgn_frequency, "Congestion signaling fabric freq");

int lpfc_acqe_cgn_frequency = 10; /* 10 sec default */
module_param(lpfc_acqe_cgn_frequency, int, 0444);
MODULE_PARM_DESC(lpfc_acqe_cgn_frequency, "Congestion signaling ACQE freq");

int lpfc_use_cgn_signal = 1; /* 0 - only use FPINs, 1 - Use signals if avail  */
module_param(lpfc_use_cgn_signal, int, 0444);
MODULE_PARM_DESC(lpfc_use_cgn_signal, "Use Congestion signaling if available");

/*
 * lpfc_enable_dpp: Enable DPP on G7
 *       0  = DPP on G7 disabled
@@ -6915,6 +6928,9 @@ lpfc_get_stats(struct Scsi_Host *shost)
	hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
	hs->error_frames = pmb->un.varRdLnk.crcCnt;

	hs->cn_sig_warn = atomic64_read(&phba->cgn_acqe_stat.warn);
	hs->cn_sig_alarm = atomic64_read(&phba->cgn_acqe_stat.alarm);

	hs->link_failure_count -= lso->link_failure_count;
	hs->loss_of_sync_count -= lso->loss_of_sync_count;
	hs->loss_of_signal_count -= lso->loss_of_signal_count;
@@ -7026,6 +7042,12 @@ lpfc_reset_stats(struct Scsi_Host *shost)
	else
		lso->link_events = (phba->fc_eventTag >> 1);

	atomic64_set(&phba->cgn_acqe_stat.warn, 0);
	atomic64_set(&phba->cgn_acqe_stat.alarm, 0);

	memset(&shost_to_fc_host(shost)->fpin_stats, 0,
	       sizeof(shost_to_fc_host(shost)->fpin_stats));

	psli->stats_start = ktime_get_seconds();

	mempool_free(pmboxq, phba->mbox_mem_pool);
@@ -7459,6 +7481,11 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
	lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
	lpfc_enable_mi_init(phba, lpfc_enable_mi);

	phba->cmf_active_mode = LPFC_CFG_OFF;
	if (lpfc_fabric_cgn_frequency > EDC_CG_SIGFREQ_CNT_MAX ||
	   lpfc_fabric_cgn_frequency < EDC_CG_SIGFREQ_CNT_MIN)
		lpfc_fabric_cgn_frequency = 100; /* 100 ms default */

	if (phba->sli_rev != LPFC_SLI_REV4) {
		/* NVME only supported on SLI4 */
		phba->nvmet_support = 0;
+6 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ int lpfc_init_iocb_list(struct lpfc_hba *phba, int cnt);
void lpfc_free_iocb_list(struct lpfc_hba *phba);
int lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
			struct lpfc_queue *drq, int count, int idx);
int lpfc_config_cgn_signal(struct lpfc_hba *phba);

void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -143,6 +144,7 @@ int lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry);
int lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry);
int lpfc_issue_fabric_reglogin(struct lpfc_vport *);
int lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry);
int lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry);
int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
@@ -607,6 +609,10 @@ extern int lpfc_enable_nvmet_cnt;
extern unsigned long long lpfc_enable_nvmet[];
extern int lpfc_no_hba_reset_cnt;
extern unsigned long lpfc_no_hba_reset[];
extern int lpfc_acqe_cgn_frequency;
extern int lpfc_fabric_cgn_frequency;
extern int lpfc_use_cgn_signal;

extern union lpfc_wqe128 lpfc_iread_cmd_template;
extern union lpfc_wqe128 lpfc_iwrite_cmd_template;
extern union lpfc_wqe128 lpfc_icmnd_cmd_template;
+2 −0
Original line number Diff line number Diff line
@@ -2288,6 +2288,8 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
			/* No retry on Vendor, RPA only done on physical port */
			if (phba->link_flag & LS_CT_VEN_RPA) {
				phba->link_flag &= ~LS_CT_VEN_RPA;
				if (phba->cmf_active_mode == LPFC_CFG_OFF)
					return;
				lpfc_printf_log(phba, KERN_ERR,
						LOG_DISCOVERY | LOG_ELS,
						"6460 VEN FDMI RPA failure\n");
+633 −4

File changed.

Preview size limit exceeded, changes collapsed.

Loading