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

Commit 4243c115 authored by Sawan Chandak's avatar Sawan Chandak Committed by Martin K. Petersen
Browse files

qla2xxx: Add support for online flash update for ISP27XX.

parent f198cafa
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -562,6 +562,7 @@ qla2x00_sysfs_read_vpd(struct file *filp, struct kobject *kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;
	uint32_t faddr;

	if (unlikely(pci_channel_offline(ha->pdev)))
		return -EAGAIN;
@@ -569,9 +570,16 @@ qla2x00_sysfs_read_vpd(struct file *filp, struct kobject *kobj,
	if (!capable(CAP_SYS_ADMIN))
		return -EINVAL;

	if (IS_NOCACHE_VPD_TYPE(ha))
		ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
	if (IS_NOCACHE_VPD_TYPE(ha)) {
		faddr = ha->flt_region_vpd << 2;

		if (IS_QLA27XX(ha) &&
		    qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE)
			faddr = ha->flt_region_vpd_sec << 2;

		ha->isp_ops->read_optrom(vha, ha->vpd, faddr,
		    ha->vpd_size);
	}
	return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
}

+80 −0
Original line number Diff line number Diff line
@@ -2106,6 +2106,80 @@ qla8044_serdes_op(struct fc_bsg_job *bsg_job)
	return 0;
}

static int
qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
{
	struct Scsi_Host *host = bsg_job->shost;
	scsi_qla_host_t *vha = shost_priv(host);
	struct qla_hw_data *ha = vha->hw;
	struct qla_flash_update_caps cap;

	if (!(IS_QLA27XX(ha)))
		return -EPERM;

	memset(&cap, 0, sizeof(cap));
	cap.capabilities = (uint64_t)ha->fw_attributes_ext[1] << 48 |
			   (uint64_t)ha->fw_attributes_ext[0] << 32 |
			   (uint64_t)ha->fw_attributes_h << 16 |
			   (uint64_t)ha->fw_attributes;

	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	    bsg_job->reply_payload.sg_cnt, &cap, sizeof(cap));
	bsg_job->reply->reply_payload_rcv_len = sizeof(cap);

	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
	    EXT_STATUS_OK;

	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_job->reply->result = DID_OK << 16;
	bsg_job->job_done(bsg_job);
	return 0;
}

static int
qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
{
	struct Scsi_Host *host = bsg_job->shost;
	scsi_qla_host_t *vha = shost_priv(host);
	struct qla_hw_data *ha = vha->hw;
	uint64_t online_fw_attr = 0;
	struct qla_flash_update_caps cap;

	if (!(IS_QLA27XX(ha)))
		return -EPERM;

	memset(&cap, 0, sizeof(cap));
	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &cap, sizeof(cap));

	online_fw_attr = (uint64_t)ha->fw_attributes_ext[1] << 48 |
			 (uint64_t)ha->fw_attributes_ext[0] << 32 |
			 (uint64_t)ha->fw_attributes_h << 16 |
			 (uint64_t)ha->fw_attributes;

	if (online_fw_attr != cap.capabilities) {
		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
		    EXT_STATUS_INVALID_PARAM;
		return -EINVAL;
	}

	if (cap.outage_duration < MAX_LOOP_TIMEOUT)  {
		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
		    EXT_STATUS_INVALID_PARAM;
		return -EINVAL;
	}

	bsg_job->reply->reply_payload_rcv_len = 0;

	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
	    EXT_STATUS_OK;

	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_job->reply->result = DID_OK << 16;
	bsg_job->job_done(bsg_job);
	return 0;
}

static int
qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
{
@@ -2161,6 +2235,12 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
	case QL_VND_SERDES_OP_EX:
		return qla8044_serdes_op(bsg_job);

	case QL_VND_GET_FLASH_UPDATE_CAPS:
		return qla27xx_get_flash_upd_cap(bsg_job);

	case QL_VND_SET_FLASH_UPDATE_CAPS:
		return qla27xx_set_flash_upd_cap(bsg_job);

	default:
		return -ENOSYS;
	}
+7 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@
#define QL_VND_FX00_MGMT_CMD	0x12
#define QL_VND_SERDES_OP	0x13
#define	QL_VND_SERDES_OP_EX	0x14
#define QL_VND_GET_FLASH_UPDATE_CAPS    0x15
#define QL_VND_SET_FLASH_UPDATE_CAPS    0x16

/* BSG Vendor specific subcode returns */
#define EXT_STATUS_OK			0
@@ -232,4 +234,9 @@ struct qla_serdes_reg_ex {
	uint32_t val;
} __packed;

struct qla_flash_update_caps {
	uint64_t  capabilities;
	uint32_t  outage_duration;
	uint8_t   reserved[20];
} __packed;
#endif
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@
 * ----------------------------------------------------------------------
 * |             Level            |   Last Value Used  |     Holes	|
 * ----------------------------------------------------------------------
 * | Module Init and Probe        |       0x017f       | 0x0146         |
 * | Module Init and Probe        |       0x018f       | 0x0146         |
 * |                              |                    | 0x015b-0x0160	|
 * |                              |                    | 0x016e-0x0170  |
 * | Mailbox commands             |       0x1192       |		|
+22 −0
Original line number Diff line number Diff line
@@ -1060,6 +1060,12 @@ struct mbx_cmd_32 {
#define FSTATE_FATAL_ERROR         4
#define FSTATE_LOOP_BACK_CONN      5

#define QLA27XX_IMG_STATUS_VER_MAJOR   0x01
#define QLA27XX_IMG_STATUS_VER_MINOR    0x00
#define QLA27XX_IMG_STATUS_SIGN   0xFACEFADE
#define QLA27XX_PRIMARY_IMAGE  1
#define QLA27XX_SECONDARY_IMAGE    2

/*
 * Port Database structure definition
 * Little endian except where noted.
@@ -3433,14 +3439,20 @@ struct qla_hw_data {
	uint32_t        flt_region_flt;
	uint32_t        flt_region_fdt;
	uint32_t        flt_region_boot;
	uint32_t        flt_region_boot_sec;
	uint32_t        flt_region_fw;
	uint32_t        flt_region_fw_sec;
	uint32_t        flt_region_vpd_nvram;
	uint32_t        flt_region_vpd;
	uint32_t        flt_region_vpd_sec;
	uint32_t        flt_region_nvram;
	uint32_t        flt_region_npiv_conf;
	uint32_t	flt_region_gold_fw;
	uint32_t	flt_region_fcp_prio;
	uint32_t	flt_region_bootload;
	uint32_t	flt_region_img_status_pri;
	uint32_t	flt_region_img_status_sec;
	uint8_t         active_image;

	/* Needed for BEACON */
	uint16_t        beacon_blink_led;
@@ -3705,6 +3717,16 @@ typedef struct scsi_qla_host {
	struct qla_tgt_counters tgt_counters;
} scsi_qla_host_t;

struct qla27xx_image_status {
	uint8_t image_status_mask;
	uint16_t generation_number;
	uint8_t reserved[3];
	uint8_t ver_minor;
	uint8_t ver_major;
	uint32_t checksum;
	uint32_t signature;
} __packed;

#define SET_VP_IDX	1
#define SET_AL_PA	2
#define RESET_VP_IDX	3
Loading