Commit 9f2475fe authored by Shyam Sundar's avatar Shyam Sundar Committed by Martin K. Petersen

scsi: qla2xxx: SAN congestion management implementation

* Firmware Initialization with SCM enabled based on NVRAM setting and
  firmware support (About Firmware).

* Enable PUREX and add support for fabric performance impact
  notification (FPIN) handling.

* Allocate a default PUREX item for each vha to handle memory allocation
  failures in ISR.

Link: https://lore.kernel.org/r/20200630102229.29660-3-njavali@marvell.comReviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Reviewed-by: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarShyam Sundar <ssundar@marvell.com>
Signed-off-by: default avatarArun Easi <aeasi@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 62e9dd17
...@@ -11,10 +11,8 @@ ...@@ -11,10 +11,8 @@
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* | Level | Last Value Used | Holes | * | Level | Last Value Used | Holes |
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* | Module Init and Probe | 0x0193 | 0x0146 | * | Module Init and Probe | 0x0199 | |
* | | | 0x015b-0x0160 | * | Mailbox commands | 0x1206 | 0x11a5-0x11ff |
* | | | 0x016e |
* | Mailbox commands | 0x1206 | 0x11a2-0x11ff |
* | Device Discovery | 0x2134 | 0x210e-0x2116 | * | Device Discovery | 0x2134 | 0x210e-0x2116 |
* | | | 0x211a | * | | | 0x211a |
* | | | 0x211c-0x2128 | * | | | 0x211c-0x2128 |
...@@ -26,11 +24,7 @@ ...@@ -26,11 +24,7 @@
* | | | 0x3036,0x3038 | * | | | 0x3036,0x3038 |
* | | | 0x303a | * | | | 0x303a |
* | DPC Thread | 0x4023 | 0x4002,0x4013 | * | DPC Thread | 0x4023 | 0x4002,0x4013 |
* | Async Events | 0x5090 | 0x502b-0x502f | * | Async Events | 0x509c | |
* | | | 0x5047 |
* | | | 0x5084,0x5075 |
* | | | 0x503d,0x5044 |
* | | | 0x505f |
* | Timer Routines | 0x6012 | | * | Timer Routines | 0x6012 | |
* | User Space Interactions | 0x70e3 | 0x7018,0x702e | * | User Space Interactions | 0x70e3 | 0x7018,0x702e |
* | | | 0x7020,0x7024 | * | | | 0x7020,0x7024 |
...@@ -2662,7 +2656,6 @@ ql_dump_regs(uint level, scsi_qla_host_t *vha, uint id) ...@@ -2662,7 +2656,6 @@ ql_dump_regs(uint level, scsi_qla_host_t *vha, uint id)
"mbox[%d] %#04x\n", i, rd_reg_word(mbx_reg)); "mbox[%d] %#04x\n", i, rd_reg_word(mbx_reg));
} }
void void
ql_dump_buffer(uint level, scsi_qla_host_t *vha, uint id, const void *buf, ql_dump_buffer(uint level, scsi_qla_host_t *vha, uint id, const void *buf,
uint size) uint size)
......
...@@ -1055,6 +1055,7 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs) ...@@ -1055,6 +1055,7 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
#define MBA_LIP_F8 0x8016 /* Received a LIP F8. */ #define MBA_LIP_F8 0x8016 /* Received a LIP F8. */
#define MBA_LOOP_INIT_ERR 0x8017 /* Loop Initialization Error. */ #define MBA_LOOP_INIT_ERR 0x8017 /* Loop Initialization Error. */
#define MBA_FABRIC_AUTH_REQ 0x801b /* Fabric Authentication Required. */ #define MBA_FABRIC_AUTH_REQ 0x801b /* Fabric Authentication Required. */
#define MBA_CONGN_NOTI_RECV 0x801e /* Congestion Notification Received */
#define MBA_SCSI_COMPLETION 0x8020 /* SCSI Command Complete. */ #define MBA_SCSI_COMPLETION 0x8020 /* SCSI Command Complete. */
#define MBA_CTIO_COMPLETION 0x8021 /* CTIO Complete. */ #define MBA_CTIO_COMPLETION 0x8021 /* CTIO Complete. */
#define MBA_IP_COMPLETION 0x8022 /* IP Transmit Command Complete. */ #define MBA_IP_COMPLETION 0x8022 /* IP Transmit Command Complete. */
...@@ -1510,6 +1511,25 @@ typedef struct { ...@@ -1510,6 +1511,25 @@ typedef struct {
uint8_t reserved_3[26]; uint8_t reserved_3[26];
} init_cb_t; } init_cb_t;
/* Special Features Control Block */
struct init_sf_cb {
uint8_t format;
uint8_t reserved0;
/*
* BIT 15-14 = Reserved
* BIT_13 = SAN Congestion Management (1 - Enabled, 0 - Disabled)
* BIT_12 = Remote Write Optimization (1 - Enabled, 0 - Disabled)
* BIT 11-0 = Reserved
*/
uint16_t flags;
uint8_t reserved1[32];
uint16_t discard_OHRB_timeout_value;
uint16_t remote_write_opt_queue_num;
uint8_t reserved2[40];
uint8_t scm_related_parameter[16];
uint8_t reserved3[32];
};
/* /*
* Get Link Status mailbox command return buffer. * Get Link Status mailbox command return buffer.
*/ */
...@@ -2183,6 +2203,8 @@ typedef struct { ...@@ -2183,6 +2203,8 @@ typedef struct {
struct dsd64 rsp_dsd; struct dsd64 rsp_dsd;
} ms_iocb_entry_t; } ms_iocb_entry_t;
#define SCM_EDC_ACC_RECEIVED BIT_6
#define SCM_RDF_ACC_RECEIVED BIT_7
/* /*
* ISP queue - Mailbox Command entry structure definition. * ISP queue - Mailbox Command entry structure definition.
...@@ -3852,6 +3874,12 @@ struct qla_hw_data { ...@@ -3852,6 +3874,12 @@ struct qla_hw_data {
uint32_t n2n_bigger:1; uint32_t n2n_bigger:1;
uint32_t secure_adapter:1; uint32_t secure_adapter:1;
uint32_t secure_fw:1; uint32_t secure_fw:1;
/* Supported by Adapter */
uint32_t scm_supported_a:1;
/* Supported by Firmware */
uint32_t scm_supported_f:1;
/* Enabled in Driver */
uint32_t scm_enabled:1;
} flags; } flags;
uint16_t max_exchg; uint16_t max_exchg;
...@@ -4169,6 +4197,13 @@ struct qla_hw_data { ...@@ -4169,6 +4197,13 @@ struct qla_hw_data {
int init_cb_size; int init_cb_size;
dma_addr_t ex_init_cb_dma; dma_addr_t ex_init_cb_dma;
struct ex_init_cb_81xx *ex_init_cb; struct ex_init_cb_81xx *ex_init_cb;
dma_addr_t sf_init_cb_dma;
struct init_sf_cb *sf_init_cb;
void *scm_fpin_els_buff;
uint64_t scm_fpin_els_buff_size;
bool scm_fpin_valid;
bool scm_fpin_payload_size;
void *async_pd; void *async_pd;
dma_addr_t async_pd_dma; dma_addr_t async_pd_dma;
...@@ -4231,6 +4266,12 @@ struct qla_hw_data { ...@@ -4231,6 +4266,12 @@ struct qla_hw_data {
#define FW_ATTR_H_NVME BIT_10 #define FW_ATTR_H_NVME BIT_10
#define FW_ATTR_H_NVME_UPDATED BIT_14 #define FW_ATTR_H_NVME_UPDATED BIT_14
/* About firmware SCM support */
#define FW_ATTR_EXT0_SCM_SUPPORTED BIT_12
/* Brocade fabric attached */
#define FW_ATTR_EXT0_SCM_BROCADE 0x00001000
/* Cisco fabric attached */
#define FW_ATTR_EXT0_SCM_CISCO 0x00002000
uint16_t fw_attributes_ext[2]; uint16_t fw_attributes_ext[2];
uint32_t fw_memory_size; uint32_t fw_memory_size;
uint32_t fw_transfer_size; uint32_t fw_transfer_size;
...@@ -4541,6 +4582,13 @@ struct purex_item { ...@@ -4541,6 +4582,13 @@ struct purex_item {
} iocb; } iocb;
}; };
#define SCM_FLAG_RDF_REJECT 0x00
#define SCM_FLAG_RDF_COMPLETED 0x01
#define QLA_CON_PRIMITIVE_RECEIVED 0x1
#define QLA_CONGESTION_ARB_WARNING 0x1
#define QLA_CONGESTION_ARB_ALARM 0X2
/* /*
* Qlogic scsi host structure * Qlogic scsi host structure
*/ */
...@@ -4749,6 +4797,7 @@ typedef struct scsi_qla_host { ...@@ -4749,6 +4797,7 @@ typedef struct scsi_qla_host {
__le16 dport_data[4]; __le16 dport_data[4];
struct list_head gpnid_list; struct list_head gpnid_list;
struct fab_scan scan; struct fab_scan scan;
uint8_t scm_fabric_connection_flags;
unsigned int irq_offset; unsigned int irq_offset;
} scsi_qla_host_t; } scsi_qla_host_t;
......
...@@ -723,6 +723,8 @@ struct ct_entry_24xx { ...@@ -723,6 +723,8 @@ struct ct_entry_24xx {
struct dsd64 dsd[2]; struct dsd64 dsd[2];
}; };
#define PURX_ELS_HEADER_SIZE 0x18
/* /*
* ISP queue - PUREX IOCB entry structure definition * ISP queue - PUREX IOCB entry structure definition
*/ */
...@@ -2020,7 +2022,9 @@ struct nvram_81xx { ...@@ -2020,7 +2022,9 @@ struct nvram_81xx {
* BIT 0 = Extended BB credits for LR * BIT 0 = Extended BB credits for LR
* BIT 1 = Virtual Fabric Enable * BIT 1 = Virtual Fabric Enable
* BIT 2-5 = Distance Support if BIT 0 is on * BIT 2-5 = Distance Support if BIT 0 is on
* BIT 6-15 = Unused * BIT 6 = Prefer FCP
* BIT 7 = SCM Disabled if BIT is set (1)
* BIT 8-15 = Unused
*/ */
uint16_t enhanced_features; uint16_t enhanced_features;
......
...@@ -127,6 +127,7 @@ int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport); ...@@ -127,6 +127,7 @@ int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport); void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *); int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *);
void qla_rscn_replay(fc_port_t *fcport); void qla_rscn_replay(fc_port_t *fcport);
void qla24xx_free_purex_item(struct purex_item *item);
extern bool qla24xx_risc_firmware_invalid(uint32_t *); extern bool qla24xx_risc_firmware_invalid(uint32_t *);
/* /*
......
...@@ -3749,7 +3749,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) ...@@ -3749,7 +3749,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
} }
/* Enable PUREX PASSTHRU */ /* Enable PUREX PASSTHRU */
if (ql2xrdpenable) if (ql2xrdpenable || ha->flags.scm_supported_f)
qla25xx_set_els_cmds_supported(vha); qla25xx_set_els_cmds_supported(vha);
} else } else
goto failed; goto failed;
...@@ -3962,7 +3962,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha) ...@@ -3962,7 +3962,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_8; ha->fw_options[2] &= ~BIT_8;
} }
if (ql2xrdpenable) if (ql2xrdpenable || ha->flags.scm_supported_f)
ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB; ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
/* Enable Async 8130/8131 events -- transceiver insertion/removal */ /* Enable Async 8130/8131 events -- transceiver insertion/removal */
...@@ -8519,6 +8519,11 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) ...@@ -8519,6 +8519,11 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
icb->node_name[0] &= 0xF0; icb->node_name[0] &= 0xF0;
} }
if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
if ((nv->enhanced_features & BIT_7) == 0)
ha->flags.scm_supported_a = 1;
}
/* Set host adapter parameters. */ /* Set host adapter parameters. */
ha->flags.disable_risc_code_load = 0; ha->flags.disable_risc_code_load = 0;
ha->flags.enable_lip_reset = 0; ha->flags.enable_lip_reset = 0;
......
...@@ -22,6 +22,31 @@ static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *); ...@@ -22,6 +22,31 @@ static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *); static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
sts_entry_t *); sts_entry_t *);
static void qla27xx_process_purex_fpin(struct scsi_qla_host *vha,
struct purex_item *item);
static struct purex_item *qla24xx_alloc_purex_item(scsi_qla_host_t *vha,
uint16_t size);
static struct purex_item *qla24xx_copy_std_pkt(struct scsi_qla_host *vha,
void *pkt);
static struct purex_item *qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha,
void **pkt, struct rsp_que **rsp);
static void
qla27xx_process_purex_fpin(struct scsi_qla_host *vha, struct purex_item *item)
{
void *pkt = &item->iocb;
uint16_t pkt_size = item->size;
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x508d,
"%s: Enter\n", __func__);
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x508e,
"-------- ELS REQ -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x508f,
pkt, pkt_size);
fc_host_fpin_rcv(vha->host, pkt_size, (char *)pkt);
}
const char *const port_state_str[] = { const char *const port_state_str[] = {
"Unknown", "Unknown",
...@@ -819,7 +844,7 @@ qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt, ...@@ -819,7 +844,7 @@ qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
* @vha: SCSI driver HA context * @vha: SCSI driver HA context
* @pkt: ELS packet * @pkt: ELS packet
*/ */
struct purex_item static struct purex_item
*qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt) *qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
{ {
struct purex_item *item; struct purex_item *item;
...@@ -833,6 +858,111 @@ struct purex_item ...@@ -833,6 +858,111 @@ struct purex_item
return item; return item;
} }
/**
* qla27xx_copy_fpin_pkt() - Copy over fpin packets that can
* span over multiple IOCBs.
* @vha: SCSI driver HA context
* @pkt: ELS packet
* @rsp: Response queue
*/
static struct purex_item *
qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
struct rsp_que **rsp)
{
struct purex_entry_24xx *purex = *pkt;
struct rsp_que *rsp_q = *rsp;
sts_cont_entry_t *new_pkt;
uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0;
uint16_t buffer_copy_offset = 0;
uint16_t entry_count, entry_count_remaining;
struct purex_item *item;
void *fpin_pkt = NULL;
total_bytes = le16_to_cpu(purex->frame_size & 0x0FFF)
- PURX_ELS_HEADER_SIZE;
pending_bytes = total_bytes;
entry_count = entry_count_remaining = purex->entry_count;
no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
sizeof(purex->els_frame_payload) : pending_bytes;
ql_log(ql_log_info, vha, 0x509a,
"FPIN ELS, frame_size 0x%x, entry count %d\n",
total_bytes, entry_count);
item = qla24xx_alloc_purex_item(vha, total_bytes);
if (!item)
return item;
fpin_pkt = &item->iocb;
memcpy(fpin_pkt, &purex->els_frame_payload[0], no_bytes);
buffer_copy_offset += no_bytes;
pending_bytes -= no_bytes;
--entry_count_remaining;
((response_t *)purex)->signature = RESPONSE_PROCESSED;
wmb();
do {
while ((total_bytes > 0) && (entry_count_remaining > 0)) {
if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) {
ql_dbg(ql_dbg_async, vha, 0x5084,
"Ran out of IOCBs, partial data 0x%x\n",
buffer_copy_offset);
cpu_relax();
continue;
}
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
*pkt = new_pkt;
if (new_pkt->entry_type != STATUS_CONT_TYPE) {
ql_log(ql_log_warn, vha, 0x507a,
"Unexpected IOCB type, partial data 0x%x\n",
buffer_copy_offset);
break;
}
rsp_q->ring_index++;
if (rsp_q->ring_index == rsp_q->length) {
rsp_q->ring_index = 0;
rsp_q->ring_ptr = rsp_q->ring;
} else {
rsp_q->ring_ptr++;
}
no_bytes = (pending_bytes > sizeof(new_pkt->data)) ?
sizeof(new_pkt->data) : pending_bytes;
if ((buffer_copy_offset + no_bytes) <= total_bytes) {
memcpy(((uint8_t *)fpin_pkt +
buffer_copy_offset), new_pkt->data,
no_bytes);
buffer_copy_offset += no_bytes;
pending_bytes -= no_bytes;
--entry_count_remaining;
} else {
ql_log(ql_log_warn, vha, 0x5044,
"Attempt to copy more that we got, optimizing..%x\n",
buffer_copy_offset);
memcpy(((uint8_t *)fpin_pkt +
buffer_copy_offset), new_pkt->data,
total_bytes - buffer_copy_offset);
}
((response_t *)new_pkt)->signature = RESPONSE_PROCESSED;
wmb();
}
if (pending_bytes != 0 || entry_count_remaining != 0) {
ql_log(ql_log_fatal, vha, 0x508b,
"Dropping partial FPIN, underrun bytes = 0x%x, entry cnts 0x%x\n",
total_bytes, entry_count_remaining);
qla24xx_free_purex_item(item);
return NULL;
}
} while (entry_count_remaining > 0);
host_to_fcp_swap((uint8_t *)&item->iocb, total_bytes);
return item;
}
/** /**
* qla2x00_async_event() - Process aynchronous events. * qla2x00_async_event() - Process aynchronous events.
* @vha: SCSI driver HA context * @vha: SCSI driver HA context
...@@ -1346,6 +1476,19 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ...@@ -1346,6 +1476,19 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry); qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry);
} }
break; break;
case MBA_CONGN_NOTI_RECV:
if (!ha->flags.scm_enabled ||
mb[1] != QLA_CON_PRIMITIVE_RECEIVED)
break;
if (mb[2] == QLA_CONGESTION_ARB_WARNING) {
ql_dbg(ql_dbg_async, vha, 0x509b,
"Congestion Warning %04x %04x.\n", mb[1], mb[2]);
} else if (mb[2] == QLA_CONGESTION_ARB_ALARM) {
ql_log(ql_log_warn, vha, 0x509b,
"Congestion Alarm %04x %04x.\n", mb[1], mb[2]);
}
break;
/* case MBA_RIO_RESPONSE: */ /* case MBA_RIO_RESPONSE: */
case MBA_ZIO_RESPONSE: case MBA_ZIO_RESPONSE:
ql_dbg(ql_dbg_async, vha, 0x5015, ql_dbg(ql_dbg_async, vha, 0x5015,
...@@ -3273,6 +3416,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -3273,6 +3416,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
{ {
struct sts_entry_24xx *pkt; struct sts_entry_24xx *pkt;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct purex_entry_24xx *purex_entry;
struct purex_item *pure_item; struct purex_item *pure_item;
if (!ha->flags.fw_started) if (!ha->flags.fw_started)
...@@ -3328,7 +3472,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -3328,7 +3472,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
pure_item = qla24xx_copy_std_pkt(vha, pkt); pure_item = qla24xx_copy_std_pkt(vha, pkt);
if (!pure_item) if (!pure_item)
break; break;
qla24xx_queue_purex_item(vha, pure_item, qla24xx_queue_purex_item(vha, pure_item,
qla24xx_process_abts); qla24xx_process_abts);
break; break;
...@@ -3378,29 +3521,40 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -3378,29 +3521,40 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
(struct vp_ctrl_entry_24xx *)pkt); (struct vp_ctrl_entry_24xx *)pkt);
break; break;
case PUREX_IOCB_TYPE: case PUREX_IOCB_TYPE:
{ purex_entry = (void *)pkt;
struct purex_entry_24xx *purex = (void *)pkt; switch (purex_entry->els_frame_payload[3]) {
case ELS_RDP:
if (purex->els_frame_payload[3] != ELS_RDP) { pure_item = qla24xx_copy_std_pkt(vha, pkt);
ql_dbg(ql_dbg_init, vha, 0x5091, if (!pure_item)
"Discarding ELS Request opcode %#x...\n", break;
purex->els_frame_payload[3]); qla24xx_queue_purex_item(vha, pure_item,
qla24xx_process_purex_rdp);
break; break;
} case ELS_FPIN:
pure_item = qla24xx_copy_std_pkt(vha, pkt); if (!vha->hw->flags.scm_enabled) {
if (!pure_item) ql_log(ql_log_warn, vha, 0x5094,
"SCM not active for this port\n");
break;
}
pure_item = qla27xx_copy_fpin_pkt(vha,
(void **)&pkt, &rsp);
if (!pure_item)
break;
qla24xx_queue_purex_item(vha, pure_item,
qla27xx_process_purex_fpin);
break; break;
qla24xx_queue_purex_item(vha, pure_item, default:
qla24xx_process_purex_rdp); ql_log(ql_log_warn, vha, 0x509c,
"Discarding ELS Request opcode 0x%x\n",
purex_entry->els_frame_payload[3]);
}
break; break;
}
default: default:
/* Type Not Supported. */ /* Type Not Supported. */
ql_dbg(ql_dbg_async, vha, 0x5042, ql_dbg(ql_dbg_async, vha, 0x5042,
"Received unknown response pkt type %x " "Received unknown response pkt type 0x%x entry status=%x.\n",
"entry status=%x.\n", pkt->entry_type, pkt->entry_status);
pkt->entry_type, pkt->entry_status);
break; break;
} }
((response_t *)pkt)->signature = RESPONSE_PROCESSED; ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
......
...@@ -1125,6 +1125,16 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) ...@@ -1125,6 +1125,16 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
(ha->flags.secure_fw) ? "Supported" : (ha->flags.secure_fw) ? "Supported" :
"Not Supported"); "Not Supported");
} }
if (ha->flags.scm_supported_a &&
(ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) {
ha->flags.scm_supported_f = 1;
memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb));
ha->sf_init_cb->flags |= BIT_13;
}
ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n",
(ha->flags.scm_supported_f) ? "Supported" :
"Not Supported");
} }
failed: failed:
...@@ -1634,8 +1644,11 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, ...@@ -1634,8 +1644,11 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10; mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
if (IS_FWI2_CAPABLE(vha->hw)) if (IS_FWI2_CAPABLE(vha->hw))
mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16; mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) {
mcp->in_mb |= MBX_15; mcp->in_mb |= MBX_15;
mcp->out_mb |= MBX_7|MBX_21|MBX_22|MBX_23;
}
mcp->tov = MBX_TOV_SECONDS; mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0; mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp); rval = qla2x00_mailbox_command(vha, mcp);
...@@ -1688,8 +1701,22 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, ...@@ -1688,8 +1701,22 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
} }
} }
if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) {
vha->bbcr = mcp->mb[15]; vha->bbcr = mcp->mb[15];
if (mcp->mb[7] & SCM_EDC_ACC_RECEIVED) {
ql_log(ql_log_info, vha, 0x11a4,
"SCM: EDC ELS completed, flags 0x%x\n",
mcp->mb[21]);
}
if (mcp->mb[7] & SCM_RDF_ACC_RECEIVED) {
vha->hw->flags.scm_enabled = 1;
vha->scm_fabric_connection_flags |=
SCM_FLAG_RDF_COMPLETED;
ql_log(ql_log_info, vha, 0x11a5,
"SCM: RDF ELS completed, flags 0x%x\n",
mcp->mb[23]);
}
}
} }
return rval; return rval;
...@@ -1802,6 +1829,17 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) ...@@ -1802,6 +1829,17 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
mcp->mb[14] = sizeof(*ha->ex_init_cb); mcp->mb[14] = sizeof(*ha->ex_init_cb);
mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10; mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
} }
if (ha->flags.scm_supported_f) {
mcp->mb[1] |= BIT_1;
mcp->mb[16] = MSW(ha->sf_init_cb_dma);
mcp->mb[17] = LSW(ha->sf_init_cb_dma);
mcp->mb[18] = MSW(MSD(ha->sf_init_cb_dma));
mcp->mb[19] = LSW(MSD(ha->sf_init_cb_dma));
mcp->mb[15] = sizeof(*ha->sf_init_cb);
mcp->out_mb |= MBX_19|MBX_18|MBX_17|MBX_16|MBX_15;
}
/* 1 and 2 should normally be captured. */ /* 1 and 2 should normally be captured. */
mcp->in_mb = MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_2|MBX_1|MBX_0;
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
......
...@@ -4218,6 +4218,16 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -4218,6 +4218,16 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
"ex_init_cb=%p.\n", ha->ex_init_cb); "ex_init_cb=%p.\n", ha->ex_init_cb);
} }
/* Get consistent memory allocated for Special Features-CB. */
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
ha->sf_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
&ha->sf_init_cb_dma);
if (!ha->sf_init_cb)
goto fail_sf_init_cb;
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199,
"sf_init_cb=%p.\n", ha->sf_init_cb);
}
INIT_LIST_HEAD(&ha->gbl_dsd_list); INIT_LIST_HEAD(&ha->gbl_dsd_list);
/* Get consistent memory allocated for Async Port-Database. */ /* Get consistent memory allocated for Async Port-Database. */
...@@ -4271,6 +4281,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -4271,6 +4281,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
fail_loop_id_map: fail_loop_id_map:
dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
fail_async_pd: fail_async_pd:
dma_pool_free(ha->s_dma_pool, ha->sf_init_cb, ha->sf_init_cb_dma);
fail_sf_init_cb:
dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
fail_ex_init_cb: fail_ex_init_cb:
kfree(ha->npiv_info); kfree(ha->npiv_info);
...@@ -4693,6 +4705,10 @@ qla2x00_mem_free(struct qla_hw_data *ha) ...@@ -4693,6 +4705,10 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->ms_iocb = NULL; ha->ms_iocb = NULL;
ha->ms_iocb_dma = 0; ha->ms_iocb_dma = 0;
if (ha->sf_init_cb)
dma_pool_free(ha->s_dma_pool,
ha->sf_init_cb, ha->sf_init_cb_dma);
if (ha->ex_init_cb) if (ha->ex_init_cb)
dma_pool_free(ha->s_dma_pool, dma_pool_free(ha->s_dma_pool,
ha->ex_init_cb, ha->ex_init_cb_dma); ha->ex_init_cb, ha->ex_init_cb_dma);
...@@ -4780,6 +4796,8 @@ qla2x00_mem_free(struct qla_hw_data *ha) ...@@ -4780,6 +4796,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
kfree(ha->swl); kfree(ha->swl);
ha->swl = NULL; ha->swl = NULL;
kfree(ha->loop_id_map); kfree(ha->loop_id_map);
ha->sf_init_cb = NULL;
ha->sf_init_cb_dma = 0;
ha->loop_id_map = NULL; ha->loop_id_map = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment