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

scsi: lpfc: Synchronize link speed with boot driver



Synchronize link speed with boot driver

Link speed settings set by the boot driver are reported by the hw.
Driver will attempt to read them, and if set, will respect their
values.
The driver can override the settings with its own if instructed by
user space (via bsg), with the new values being picked up by the
boot driver.

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>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 89533e9b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -648,6 +648,10 @@ struct lpfc_hba {
#define HBA_FCP_IOQ_FLUSH	0x8000 /* FCP I/O queues being flushed */
#define HBA_FW_DUMP_OP		0x10000 /* Skips fn reset before FW dump */
#define HBA_RECOVERABLE_UE	0x20000 /* Firmware supports recoverable UE */
#define HBA_FORCED_LINK_SPEED	0x40000 /*
					 * Firmware supports Forced Link Speed
					 * capability
					 */
	uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
	struct lpfc_dmabuf slim2p;

+6 −1
Original line number Diff line number Diff line
@@ -3668,7 +3668,12 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
	int nolip = 0;
	const char *val_buf = buf;
	int err;
	uint32_t prev_val;
	uint32_t prev_val, if_type;

	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
	if (if_type == LPFC_SLI_INTF_IF_TYPE_2 &&
	    phba->hba_flag & HBA_FORCED_LINK_SPEED)
		return -EPERM;

	if (!strncmp(buf, "nolip ", strlen("nolip "))) {
		nolip = 1;
+45 −0
Original line number Diff line number Diff line
@@ -5185,6 +5185,48 @@ lpfc_menlo_cmd(struct fc_bsg_job *job)
	return rc;
}

static int
lpfc_forced_link_speed(struct fc_bsg_job *job)
{
	struct Scsi_Host *shost = job->shost;
	struct lpfc_vport *vport = shost_priv(shost);
	struct lpfc_hba *phba = vport->phba;
	struct forced_link_speed_support_reply *forced_reply;
	int rc = 0;

	if (job->request_len <
	    sizeof(struct fc_bsg_request) +
	    sizeof(struct get_forced_link_speed_support)) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
				"0048 Received FORCED_LINK_SPEED request "
				"below minimum size\n");
		rc = -EINVAL;
		goto job_error;
	}

	forced_reply = (struct forced_link_speed_support_reply *)
		job->reply->reply_data.vendor_reply.vendor_rsp;

	if (job->reply_len <
	    sizeof(struct fc_bsg_request) +
	    sizeof(struct forced_link_speed_support_reply)) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
				"0049 Received FORCED_LINK_SPEED reply below "
				"minimum size\n");
		rc = -EINVAL;
		goto job_error;
	}

	forced_reply->supported = (phba->hba_flag & HBA_FORCED_LINK_SPEED)
				   ? LPFC_FORCED_LINK_SPEED_SUPPORTED
				   : LPFC_FORCED_LINK_SPEED_NOT_SUPPORTED;
job_error:
	job->reply->result = rc;
	if (rc == 0)
		job->job_done(job);
	return rc;
}

/**
 * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
 * @job: fc_bsg_job to handle
@@ -5227,6 +5269,9 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
	case LPFC_BSG_VENDOR_MENLO_DATA:
		rc = lpfc_menlo_cmd(job);
		break;
	case LPFC_BSG_VENDOR_FORCED_LINK_SPEED:
		rc = lpfc_forced_link_speed(job);
		break;
	default:
		rc = -EINVAL;
		job->reply->reply_payload_rcv_len = 0;
+10 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#define LPFC_BSG_VENDOR_MENLO_DATA		9
#define LPFC_BSG_VENDOR_DIAG_MODE_END		10
#define LPFC_BSG_VENDOR_LINK_DIAG_TEST		11
#define LPFC_BSG_VENDOR_FORCED_LINK_SPEED	14

struct set_ct_event {
	uint32_t command;
@@ -284,6 +285,15 @@ struct lpfc_sli_config_mbox {
	} un;
};

#define LPFC_FORCED_LINK_SPEED_NOT_SUPPORTED	0
#define LPFC_FORCED_LINK_SPEED_SUPPORTED	1
struct get_forced_link_speed_support {
	uint32_t command;
};
struct forced_link_speed_support_reply {
	uint8_t supported;
};

/* driver only */
#define SLI_CONFIG_NOT_HANDLED		0
#define SLI_CONFIG_HANDLED		1
+3 −0
Original line number Diff line number Diff line
@@ -2290,6 +2290,9 @@ struct lpfc_mbx_read_config {
#define lpfc_mbx_rd_conf_r_a_tov_SHIFT		0
#define lpfc_mbx_rd_conf_r_a_tov_MASK		0x0000FFFF
#define lpfc_mbx_rd_conf_r_a_tov_WORD		word6
#define lpfc_mbx_rd_conf_link_speed_SHIFT	16
#define lpfc_mbx_rd_conf_link_speed_MASK	0x0000FFFF
#define lpfc_mbx_rd_conf_link_speed_WORD	word6
	uint32_t rsvd_7;
	uint32_t rsvd_8;
	uint32_t word9;
Loading