Skip to content

Commit

Permalink
scsi: qla2xxx: Secure flash update support for ISP28XX
Browse files Browse the repository at this point in the history
This patch adds support for Secure flash update with ISP28xx.

Signed-off-by: Michael Hernandez <mhernandez@marvell.com>
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Michael Hernandez authored and Martin K. Petersen committed Mar 19, 2019
1 parent 5fa8774 commit 3f006ac
Show file tree
Hide file tree
Showing 9 changed files with 616 additions and 49 deletions.
31 changes: 29 additions & 2 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ struct mbx_cmd_32 {
#define MBC_GET_FIRMWARE_VERSION 8 /* Get firmware revision. */
#define MBC_LOAD_RISC_RAM 9 /* Load RAM command. */
#define MBC_DUMP_RISC_RAM 0xa /* Dump RAM command. */
#define MBC_SECURE_FLASH_UPDATE 0xa /* Secure Flash Update(28xx) */
#define MBC_LOAD_RISC_RAM_EXTENDED 0xb /* Load RAM extended. */
#define MBC_DUMP_RISC_RAM_EXTENDED 0xc /* Dump RAM extended. */
#define MBC_WRITE_RAM_WORD_EXTENDED 0xd /* Write RAM word extended */
Expand Down Expand Up @@ -3135,10 +3136,10 @@ struct rsp_que;
struct isp_operations {

int (*pci_config) (struct scsi_qla_host *);
void (*reset_chip) (struct scsi_qla_host *);
int (*reset_chip)(struct scsi_qla_host *);
int (*chip_diag) (struct scsi_qla_host *);
void (*config_rings) (struct scsi_qla_host *);
void (*reset_adapter) (struct scsi_qla_host *);
int (*reset_adapter)(struct scsi_qla_host *);
int (*nvram_config) (struct scsi_qla_host *);
void (*update_fw_options) (struct scsi_qla_host *);
int (*load_risc) (struct scsi_qla_host *, uint32_t *);
Expand Down Expand Up @@ -3627,6 +3628,8 @@ struct qla_hw_data {
uint32_t rida_fmt2:1;
uint32_t purge_mbox:1;
uint32_t n2n_bigger:1;
uint32_t secure_adapter:1;
uint32_t secure_fw:1;
} flags;

uint16_t max_exchg;
Expand Down Expand Up @@ -3915,6 +3918,9 @@ struct qla_hw_data {
void *sfp_data;
dma_addr_t sfp_data_dma;

void *flt;
dma_addr_t flt_dma;

#define XGMAC_DATA_SIZE 4096
void *xgmac_data;
dma_addr_t xgmac_data_dma;
Expand Down Expand Up @@ -4362,6 +4368,7 @@ typedef struct scsi_qla_host {
#define N2N_LOGIN_NEEDED 30
#define IOCB_WORK_ACTIVE 31
#define SET_ZIO_THRESHOLD_NEEDED 32
#define ISP_ABORT_TO_ROM 33

unsigned long pci_flags;
#define PFLG_DISCONNECTED 0 /* PCI device removed */
Expand Down Expand Up @@ -4549,6 +4556,24 @@ struct qla2_sgx {
} \
}


#define SFUB_CHECKSUM_SIZE 4

struct secure_flash_update_block {
uint32_t block_info;
uint32_t signature_lo;
uint32_t signature_hi;
uint32_t signature_upper[0x3e];
};

struct secure_flash_update_block_pk {
uint32_t block_info;
uint32_t signature_lo;
uint32_t signature_hi;
uint32_t signature_upper[0x3e];
uint32_t public_key[0x41];
};

/*
* Macros to help code, maintain, etc.
*/
Expand Down Expand Up @@ -4749,6 +4774,8 @@ struct sff_8247_a0 {
IS_QLA83XX(_vha->hw) || IS_QLA27XX(_vha->hw) || \
IS_QLA28XX(_vha->hw)))

#define FLASH_SEMAPHORE_REGISTER_ADDR 0x00101016

#define USER_CTRL_IRQ(_ha) (ql2xuctrlirq && QLA_TGT_MODE_ENABLED() && \
(IS_QLA27XX(_ha) || IS_QLA28XX(_ha) || IS_QLA83XX(_ha)))

Expand Down
8 changes: 8 additions & 0 deletions drivers/scsi/qla2xxx/qla_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,10 @@ struct qla_flt_region {
uint32_t end;
};

#define FLT_REGION_SIZE 16
#define FLT_MAX_REGIONS 0xFF
#define FLT_REGIONS_SIZE (FLT_REGION_SIZE * FLT_MAX_REGIONS)

/* Flash NPIV Configuration Table ********************************************/

struct qla_npiv_header {
Expand Down Expand Up @@ -1725,6 +1729,10 @@ struct access_chip_rsp_84xx {
#define LR_DIST_FW_SHIFT (LR_DIST_FW_POS - LR_DIST_NV_POS)
#define LR_DIST_FW_FIELD(x) ((x) << LR_DIST_FW_SHIFT & 0xf000)

/* FAC semaphore defines */
#define FAC_SEMAPHORE_UNLOCK 0
#define FAC_SEMAPHORE_LOCK 1

struct nvram_81xx {
/* NVRAM header. */
uint8_t id[4];
Expand Down
22 changes: 16 additions & 6 deletions drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ extern int qla2100_pci_config(struct scsi_qla_host *);
extern int qla2300_pci_config(struct scsi_qla_host *);
extern int qla24xx_pci_config(scsi_qla_host_t *);
extern int qla25xx_pci_config(scsi_qla_host_t *);
extern void qla2x00_reset_chip(struct scsi_qla_host *);
extern void qla24xx_reset_chip(struct scsi_qla_host *);
extern int qla2x00_reset_chip(struct scsi_qla_host *);
extern int qla24xx_reset_chip(struct scsi_qla_host *);
extern int qla2x00_chip_diag(struct scsi_qla_host *);
extern int qla24xx_chip_diag(struct scsi_qla_host *);
extern void qla2x00_config_rings(struct scsi_qla_host *);
extern void qla24xx_config_rings(struct scsi_qla_host *);
extern void qla2x00_reset_adapter(struct scsi_qla_host *);
extern void qla24xx_reset_adapter(struct scsi_qla_host *);
extern int qla2x00_reset_adapter(struct scsi_qla_host *);
extern int qla24xx_reset_adapter(struct scsi_qla_host *);
extern int qla2x00_nvram_config(struct scsi_qla_host *);
extern int qla24xx_nvram_config(struct scsi_qla_host *);
extern int qla81xx_nvram_config(struct scsi_qla_host *);
Expand Down Expand Up @@ -471,6 +471,8 @@ qla81xx_fac_do_write_enable(scsi_qla_host_t *, int);
extern int
qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t);

extern int qla81xx_fac_semaphore_access(scsi_qla_host_t *, int);

extern int
qla2x00_get_xgmac_stats(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t *);

Expand Down Expand Up @@ -516,6 +518,14 @@ extern int qla27xx_get_zio_threshold(scsi_qla_host_t *, uint16_t *);
extern int qla27xx_set_zio_threshold(scsi_qla_host_t *, uint16_t);
int qla24xx_res_count_wait(struct scsi_qla_host *, uint16_t *, int);

extern int qla28xx_secure_flash_update(scsi_qla_host_t *, uint16_t, uint16_t,
uint32_t, dma_addr_t, uint32_t);

extern int qla2xxx_read_remote_register(scsi_qla_host_t *, uint32_t,
uint32_t *);
extern int qla2xxx_write_remote_register(scsi_qla_host_t *, uint32_t,
uint32_t);

/*
* Global Function Prototypes in qla_isr.c source file.
*/
Expand Down Expand Up @@ -721,7 +731,7 @@ extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t);
/* qlafx00 related functions */
extern int qlafx00_pci_config(struct scsi_qla_host *);
extern int qlafx00_initialize_adapter(struct scsi_qla_host *);
extern void qlafx00_soft_reset(scsi_qla_host_t *);
extern int qlafx00_soft_reset(scsi_qla_host_t *);
extern int qlafx00_chip_diag(scsi_qla_host_t *);
extern void qlafx00_config_rings(struct scsi_qla_host *);
extern char *qlafx00_pci_info_str(struct scsi_qla_host *, char *);
Expand Down Expand Up @@ -764,7 +774,7 @@ extern int qla82xx_pci_region_offset(struct pci_dev *, int);
extern int qla82xx_iospace_config(struct qla_hw_data *);

/* Initialization related functions */
extern void qla82xx_reset_chip(struct scsi_qla_host *);
extern int qla82xx_reset_chip(struct scsi_qla_host *);
extern void qla82xx_config_rings(struct scsi_qla_host *);
extern void qla82xx_watchdog(scsi_qla_host_t *);
extern int qla82xx_start_firmware(scsi_qla_host_t *);
Expand Down
47 changes: 38 additions & 9 deletions drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -2102,6 +2102,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
int rval;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0];
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;

memset(&vha->qla_stats, 0, sizeof(vha->qla_stats));
memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat));
Expand Down Expand Up @@ -2136,6 +2137,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)

ha->isp_ops->reset_chip(vha);

/* Check for secure flash support */
if (IS_QLA28XX(ha)) {
if (RD_REG_DWORD(&reg->mailbox12) & BIT_0) {
ql_log(ql_log_info, vha, 0xffff, "Adapter is Secure\n");
ha->flags.secure_adapter = 1;
}
}


rval = qla2xxx_get_flash_info(vha);
if (rval) {
ql_log(ql_log_fatal, vha, 0x004f,
Expand Down Expand Up @@ -2452,17 +2462,18 @@ qla2x00_isp_firmware(scsi_qla_host_t *vha)
*
* Returns 0 on success.
*/
void
int
qla2x00_reset_chip(scsi_qla_host_t *vha)
{
unsigned long flags = 0;
struct qla_hw_data *ha = vha->hw;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
uint32_t cnt;
uint16_t cmd;
int rval = QLA_FUNCTION_FAILED;

if (unlikely(pci_channel_offline(ha->pdev)))
return;
return rval;

ha->isp_ops->disable_intrs(ha);

Expand Down Expand Up @@ -2588,6 +2599,8 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
}

spin_unlock_irqrestore(&ha->hardware_lock, flags);

return QLA_SUCCESS;
}

/**
Expand Down Expand Up @@ -2828,22 +2841,25 @@ qla25xx_manipulate_risc_semaphore(scsi_qla_host_t *vha)
*
* Returns 0 on success.
*/
void
int
qla24xx_reset_chip(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
int rval = QLA_FUNCTION_FAILED;

if (pci_channel_offline(ha->pdev) &&
ha->flags.pci_channel_io_perm_failure) {
return;
return rval;
}

ha->isp_ops->disable_intrs(ha);

qla25xx_manipulate_risc_semaphore(vha);

/* Perform RISC reset. */
qla24xx_reset_risc(vha);
rval = qla24xx_reset_risc(vha);

return rval;
}

/**
Expand Down Expand Up @@ -6671,6 +6687,14 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
if (vha->flags.online) {
qla2x00_abort_isp_cleanup(vha);

if (test_and_clear_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags)) {
ha->flags.chip_reset_done = 1;
vha->flags.online = 1;
status = 0;
clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
return status;
}

if (IS_QLA8031(ha)) {
ql_dbg(ql_dbg_p3p, vha, 0xb05c,
"Clearing fcoe driver presence.\n");
Expand Down Expand Up @@ -6911,7 +6935,7 @@ qla25xx_init_queues(struct qla_hw_data *ha)
* Input:
* ha = adapter block pointer.
*/
void
int
qla2x00_reset_adapter(scsi_qla_host_t *vha)
{
unsigned long flags = 0;
Expand All @@ -6927,17 +6951,20 @@ qla2x00_reset_adapter(scsi_qla_host_t *vha)
WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
RD_REG_WORD(&reg->hccr); /* PCI Posting. */
spin_unlock_irqrestore(&ha->hardware_lock, flags);

return QLA_SUCCESS;
}

void
int
qla24xx_reset_adapter(scsi_qla_host_t *vha)
{
unsigned long flags = 0;
struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
int rval = QLA_SUCCESS;

if (IS_P3P_TYPE(ha))
return;
return rval;

vha->flags.online = 0;
ha->isp_ops->disable_intrs(ha);
Expand All @@ -6951,6 +6978,8 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)

if (IS_NOPOLLING_TYPE(ha))
ha->isp_ops->enable_intrs(ha);

return rval;
}

/* On sparc systems, obtain port and node WWN from firmware
Expand Down Expand Up @@ -8188,7 +8217,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
ha->vpd_size = FA_VPD_SIZE_82XX;

if (IS_QLA28XX(ha))
if (IS_QLA28XX(ha) || IS_QLA27XX(ha))
qla28xx_get_aux_images(vha, &active_regions);

/* Get VPD data into cache */
Expand Down
Loading

0 comments on commit 3f006ac

Please sign in to comment.