From: Nilesh Javali <njavali@marvell.com>
To: <martin.petersen@oracle.com>
Cc: <linux-scsi@vger.kernel.org>, <GR-QLogic-Storage-Upstream@marvell.com>
Subject: [PATCH 2/3] qla2xxx: SAN congestion management(SCM) implementation.
Date: Thu, 14 May 2020 03:10:25 -0700 [thread overview]
Message-ID: <20200514101026.10040-3-njavali@marvell.com> (raw)
In-Reply-To: <20200514101026.10040-1-njavali@marvell.com>
From: Shyam Sundar <ssundar@marvell.com>
* 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.
* Support for the following FPIN descriptors:
1. Link Integrity Notification.
2. Delivery Notification.
3. Peer Congestion Notification.
4. Congestion Notification.
* Mark a device as slow when a Peer Congestion Notification is received.
* Allocate a default purex item for each vha, to handle memory
allocation failures in ISR.
Signed-off-by: Shyam Sundar <ssundar@marvell.com>
Signed-off-by: Arun Easi <aeasi@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
---
drivers/scsi/qla2xxx/qla_bsg.h | 115 +++++++
drivers/scsi/qla2xxx/qla_dbg.c | 13 +-
drivers/scsi/qla2xxx/qla_def.h | 89 ++++++
drivers/scsi/qla2xxx/qla_fw.h | 7 +-
drivers/scsi/qla2xxx/qla_gbl.h | 1 +
drivers/scsi/qla2xxx/qla_init.c | 9 +-
drivers/scsi/qla2xxx/qla_isr.c | 532 ++++++++++++++++++++++++++++++--
drivers/scsi/qla2xxx/qla_mbx.c | 45 ++-
drivers/scsi/qla2xxx/qla_os.c | 18 ++
9 files changed, 795 insertions(+), 34 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h
index 7594fad7b5b5..0b308859047c 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.h
+++ b/drivers/scsi/qla2xxx/qla_bsg.h
@@ -290,4 +290,119 @@ struct qla_active_regions {
uint8_t reserved[32];
} __packed;
+#define SCM_LINK_EVENT_UNKNOWN 0x0
+#define SCM_LINK_EVENT_LINK_FAILURE 0x1
+#define SCM_LINK_EVENT_LOSS_OF_SYNC 0x2
+#define SCM_LINK_EVENT_LOSS_OF_SIGNAL 0x3
+#define SCM_LINK_EVENT_PRIMITIVE_SEQ_PROTOCOL_ERROR 0x4
+#define SCM_LINK_EVENT_INVALID_TX_WORD 0x5
+#define SCM_LINK_EVENT_INVALID_CRC 0x6
+#define SCM_LINK_EVENT_DEVICE_SPECIFIC 0xF
+#define SCM_LINK_EVENT_V1_SIZE 20
+struct qla_scm_link_event {
+ uint64_t timestamp;
+ uint16_t event_type;
+ uint16_t event_modifier;
+ uint32_t event_threshold;
+ uint32_t event_count;
+ uint8_t reserved[12];
+} __packed;
+
+#define SCM_DELIVERY_REASON_UNKNOWN 0x0
+#define SCM_DELIVERY_REASON_TIMEOUT 0x1
+#define SCM_DELIVERY_REASON_UNABLE_TO_ROUTE 0x2
+#define SCM_DELIVERY_REASON_DEVICE_SPECIFIC 0xF
+struct qla_scm_delivery_event {
+ uint64_t timestamp;
+ uint32_t delivery_reason;
+ uint8_t deliver_frame_hdr[24];
+ uint8_t reserved[28];
+
+} __packed;
+
+#define SCM_CONGESTION_EVENT_CLEAR 0x0
+#define SCM_CONGESTION_EVENT_LOST_CREDIT 0x1
+#define SCM_CONGESTION_EVENT_CREDIT_STALL 0x2
+#define SCM_CONGESTION_EVENT_OVERSUBSCRIPTION 0x3
+#define SCM_CONGESTION_EVENT_DEVICE_SPECIFIC 0xF
+struct qla_scm_peer_congestion_event {
+ uint64_t timestamp;
+ uint16_t event_type;
+ uint16_t event_modifier;
+ uint32_t event_period;
+ uint8_t reserved[16];
+} __packed;
+
+#define SCM_CONGESTION_SEVERITY_WARNING 0xF1
+#define SCM_CONGESTION_SEVERITY_ERROR 0xF7
+struct qla_scm_congestion_event {
+ uint64_t timestamp;
+ uint16_t event_type;
+ uint16_t event_modifier;
+ uint32_t event_period;
+ uint8_t severity;
+ uint8_t reserved[15];
+} __packed;
+
+#define SCM_FLAG_RDF_REJECT 0x00
+#define SCM_FLAG_RDF_COMPLETED 0x01
+#define SCM_FLAG_BROCADE_CONNECTED 0x02
+#define SCM_FLAG_CISCO_CONNECTED 0x04
+
+#define SCM_STATE_CONGESTION 0x1
+#define SCM_STATE_DELIVERY 0x2
+#define SCM_STATE_LINK_INTEGRITY 0x4
+#define SCM_STATE_PEER_CONGESTION 0x8
+
+#define QLA_CON_PRIMITIVE_RECEIVED 0x1
+#define QLA_CONGESTION_ARB_WARNING 0x1
+#define QLA_CONGESTION_ARB_ALARM 0X2
+struct qla_scm_port {
+ uint32_t current_events;
+
+ struct qla_scm_link_event link_integrity;
+ struct qla_scm_delivery_event delivery;
+ struct qla_scm_congestion_event congestion;
+ uint64_t scm_congestion_alarm;
+ uint64_t scm_congestion_warning;
+ uint8_t scm_fabric_connection_flags;
+ uint8_t reserved[43];
+} __packed;
+
+struct qla_scm_target {
+ uint8_t wwpn[8];
+ uint32_t current_events;
+
+ struct qla_scm_link_event link_integrity;
+ struct qla_scm_delivery_event delivery;
+ struct qla_scm_peer_congestion_event peer_congestion;
+
+ uint32_t link_failure_count;
+ uint32_t loss_of_sync_count;
+ uint32_t loss_of_signals_count;
+ uint32_t primitive_seq_protocol_err_count;
+ uint32_t invalid_transmission_word_count;
+ uint32_t invalid_crc_count;
+
+ uint32_t delivery_failure_unknown;
+ uint32_t delivery_timeout;
+ uint32_t delivery_unable_to_route;
+ uint32_t delivery_failure_device_specific;
+
+ uint32_t peer_congestion_clear;
+ uint32_t peer_congestion_lost_credit;
+ uint32_t peer_congestion_credit_stall;
+ uint32_t peer_congestion_oversubscription;
+ uint32_t peer_congestion_device_specific;
+ uint32_t link_unknown_event;
+ uint32_t link_device_specific_event;
+ uint8_t reserved[48];
+} __packed;
+
+#define QLA_DRV_ATTR_SCM_SUPPORTED 0x00800000
+struct qla_drv_attr {
+ uint32_t attributes;
+ uint8_t reserved[28];
+} __packed;
+
#endif
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 1206f7c1ce6a..8af26be684d4 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -11,10 +11,8 @@
* ----------------------------------------------------------------------
* | Level | Last Value Used | Holes |
* ----------------------------------------------------------------------
- * | Module Init and Probe | 0x0193 | 0x0146 |
- * | | | 0x015b-0x0160 |
- * | | | 0x016e |
- * | Mailbox commands | 0x1206 | 0x11a2-0x11ff |
+ * | Module Init and Probe | 0x0199 | |
+ * | Mailbox commands | 0x1206 | 0x11a5-0x11ff |
* | Device Discovery | 0x2134 | 0x210e-0x2116 |
* | | | 0x211a |
* | | | 0x211c-0x2128 |
@@ -26,11 +24,7 @@
* | | | 0x3036,0x3038 |
* | | | 0x303a |
* | DPC Thread | 0x4023 | 0x4002,0x4013 |
- * | Async Events | 0x5090 | 0x502b-0x502f |
- * | | | 0x5047 |
- * | | | 0x5084,0x5075 |
- * | | | 0x503d,0x5044 |
- * | | | 0x505f |
+ * | Async Events | 0x509c | |
* | Timer Routines | 0x6012 | |
* | User Space Interactions | 0x70e3 | 0x7018,0x702e |
* | | | 0x7020,0x7024 |
@@ -2752,7 +2746,6 @@ ql_dump_regs(uint level, scsi_qla_host_t *vha, uint id)
"mbox[%d] %#04x\n", i, RD_REG_WORD(mbx_reg));
}
-
void
ql_dump_buffer(uint level, scsi_qla_host_t *vha, uint id, const void *buf,
uint size)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 954d1a230b8a..882961d7246b 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1018,6 +1018,7 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
#define MBA_LIP_F8 0x8016 /* Received a LIP F8. */
#define MBA_LOOP_INIT_ERR 0x8017 /* Loop Initialization Error. */
#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_CTIO_COMPLETION 0x8021 /* CTIO Complete. */
#define MBA_IP_COMPLETION 0x8022 /* IP Transmit Command Complete. */
@@ -1479,6 +1480,25 @@ typedef struct {
uint8_t reserved_3[26];
} 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.
*/
@@ -2152,6 +2172,52 @@ typedef struct {
struct dsd64 rsp_dsd;
} ms_iocb_entry_t;
+#define SCM_EDC_ACC_RECEIVED BIT_6
+#define SCM_RDF_ACC_RECEIVED BIT_7
+#define SCM_NOTIFICATION_TYPE_LINK_INTEGRITY 0x00020001
+#define SCM_NOTIFICATION_TYPE_DELIVERY 0x00020002
+#define SCM_NOTIFICATION_TYPE_PEER_CONGESTION 0x00020003
+#define SCM_NOTIFICATION_TYPE_CONGESTION 0x00020004
+#define FPIN_DESCRIPTOR_HEADER_SIZE 4
+#define FPIN_ELS_DESCRIPTOR_LIST_OFFSET 8
+struct fpin_descriptor {
+ __be32 descriptor_tag;
+ __be32 descriptor_length;
+ union {
+ uint8_t common_detecting_port_name[WWN_SIZE];
+ struct {
+ uint8_t detecting_port_name[WWN_SIZE];
+ uint8_t attached_port_name[WWN_SIZE];
+ __be16 event_type;
+ __be16 event_modifier;
+ __be32 event_threshold;
+ __be32 event_count;
+ __be32 port_name_count;
+ uint8_t port_name_list[1][WWN_SIZE];
+ } link_integrity;
+ struct {
+ uint8_t detecting_port_name[WWN_SIZE];
+ uint8_t attached_port_name[WWN_SIZE];
+ __be32 delivery_reason_code;
+ } delivery;
+ struct {
+ uint8_t detecting_port_name[WWN_SIZE];
+ uint8_t attached_port_name[WWN_SIZE];
+ __be16 event_type;
+ __be16 event_modifier;
+ __be32 event_period;
+ __be32 port_name_count;
+ uint8_t port_name_list[1][WWN_SIZE];
+ } peer_congestion;
+ struct {
+ __be16 event_type;
+ __be16 event_modifier;
+ __be32 event_period;
+ uint8_t severity;
+ uint8_t reserved[3];
+ } congestion;
+ };
+};
/*
* ISP queue - Mailbox Command entry structure definition.
@@ -2412,6 +2478,7 @@ typedef struct fc_port {
unsigned int n2n_flag:1;
unsigned int explicit_logout:1;
unsigned int prli_pend_timer:1;
+ unsigned int slow_device:1;
struct completion nvme_del_done;
uint32_t nvme_prli_service_param;
@@ -2491,6 +2558,8 @@ typedef struct fc_port {
u8 last_login_state;
u16 n2n_link_reset_cnt;
u16 n2n_chip_reset;
+
+ struct qla_scm_target scm_stats;
} fc_port_t;
enum {
@@ -3821,6 +3890,12 @@ struct qla_hw_data {
uint32_t n2n_bigger:1;
uint32_t secure_adapter: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;
uint16_t max_exchg;
@@ -4138,6 +4213,13 @@ struct qla_hw_data {
int init_cb_size;
dma_addr_t ex_init_cb_dma;
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;
dma_addr_t async_pd_dma;
@@ -4200,6 +4282,12 @@ struct qla_hw_data {
#define FW_ATTR_H_NVME BIT_10
#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];
uint32_t fw_memory_size;
uint32_t fw_transfer_size;
@@ -4718,6 +4806,7 @@ typedef struct scsi_qla_host {
__le16 dport_data[4];
struct list_head gpnid_list;
struct fab_scan scan;
+ struct qla_scm_port scm_stats;
unsigned int irq_offset;
} scsi_qla_host_t;
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index f9bad5bd7198..fa45fc7e6e2b 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -723,6 +723,9 @@ struct ct_entry_24xx {
struct dsd64 dsd[2];
};
+#define PURX_ELS_HEADER_SIZE 0x18
+#define FPIN_ELS_DESCRIPTOR_LIST_OFFSET 8
+
/*
* ISP queue - PUREX IOCB entry structure definition
*/
@@ -2020,7 +2023,9 @@ struct nvram_81xx {
* BIT 0 = Extended BB credits for LR
* BIT 1 = Virtual Fabric Enable
* 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;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 54d82f7d478f..3ba21368d5b6 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -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);
int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *);
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 *);
/*
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 95b6166ae0cc..dcadf1719711 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3752,7 +3752,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
}
/* Enable PUREX PASSTHRU */
- if (ql2xrdpenable)
+ if (ql2xrdpenable || ha->flags.scm_supported_f)
qla25xx_set_els_cmds_supported(vha);
} else
goto failed;
@@ -3965,7 +3965,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_8;
}
- if (ql2xrdpenable)
+ if (ql2xrdpenable || ha->flags.scm_supported_f)
ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
/* Enable Async 8130/8131 events -- transceiver insertion/removal */
@@ -8514,6 +8514,11 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
icb->node_name[0] &= 0xF0;
}
+ if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
+ if ((le16_to_cpu(nv->enhanced_features) & BIT_7) == 0)
+ ha->flags.scm_supported_a = 1;
+ }
+
/* Set host adapter parameters. */
ha->flags.disable_risc_code_load = 0;
ha->flags.enable_lip_reset = 0;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 401ce0023cd5..7ba8a881fd4b 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -23,6 +23,372 @@ 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 *,
sts_entry_t *);
+void
+qla_link_integrity_tgt_stats_update(struct fpin_descriptor *fpin_desc,
+ fc_port_t *fcport)
+{
+ ql_log(ql_log_info, fcport->vha, 0x502d,
+ "Link Integrity Event Type %d for Port %8phN\n",
+ be16_to_cpu(fpin_desc->link_integrity.event_type),
+ fcport->port_name);
+
+ fcport->scm_stats.link_integrity.event_type =
+ be16_to_cpu(fpin_desc->link_integrity.event_type);
+ fcport->scm_stats.link_integrity.event_modifier =
+ be16_to_cpu(fpin_desc->link_integrity.event_modifier);
+ fcport->scm_stats.link_integrity.event_threshold =
+ be32_to_cpu(fpin_desc->link_integrity.event_threshold);
+ fcport->scm_stats.link_integrity.event_count =
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ fcport->scm_stats.link_integrity.timestamp = ktime_get_real_seconds();
+
+ fcport->scm_stats.current_events |= SCM_STATE_LINK_INTEGRITY;
+ switch (be16_to_cpu(fpin_desc->link_integrity.event_type)) {
+ case SCM_LINK_EVENT_UNKNOWN:
+ fcport->scm_stats.link_unknown_event +=
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ break;
+ case SCM_LINK_EVENT_LINK_FAILURE:
+ fcport->scm_stats.link_failure_count +=
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ break;
+ case SCM_LINK_EVENT_LOSS_OF_SYNC:
+ fcport->scm_stats.loss_of_sync_count +=
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ break;
+ case SCM_LINK_EVENT_LOSS_OF_SIGNAL:
+ fcport->scm_stats.loss_of_signals_count +=
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ break;
+ case SCM_LINK_EVENT_PRIMITIVE_SEQ_PROTOCOL_ERROR:
+ fcport->scm_stats.primitive_seq_protocol_err_count +=
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ break;
+ case SCM_LINK_EVENT_INVALID_TX_WORD:
+ fcport->scm_stats.invalid_transmission_word_count +=
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ break;
+ case SCM_LINK_EVENT_INVALID_CRC:
+ fcport->scm_stats.invalid_crc_count +=
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ break;
+ case SCM_LINK_EVENT_DEVICE_SPECIFIC:
+ fcport->scm_stats.link_device_specific_event +=
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ break;
+ }
+}
+
+void
+qla_scm_process_link_integrity_d(struct scsi_qla_host *vha,
+ struct fpin_descriptor *fpin_desc)
+{
+ int i;
+ fc_port_t *fcport = NULL;
+ fc_port_t *d_fcport = NULL, *a_fcport = NULL;
+
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ fpin_desc->link_integrity.detecting_port_name,
+ 0);
+ if (fcport) {
+ d_fcport = fcport;
+ qla_link_integrity_tgt_stats_update(fpin_desc, fcport);
+ }
+
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ fpin_desc->link_integrity.attached_port_name,
+ 0);
+ if (fcport) {
+ a_fcport = fcport;
+ qla_link_integrity_tgt_stats_update(fpin_desc, fcport);
+ }
+
+ if (fpin_desc->link_integrity.port_name_count > 0) {
+ for (i = 0;
+ i < be32_to_cpu(fpin_desc->link_integrity.port_name_count);
+ i++) {
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ fpin_desc->link_integrity.port_name_list[i],
+ 0);
+ if (fcport && (fcport != d_fcport) &&
+ (fcport != a_fcport)) {
+ qla_link_integrity_tgt_stats_update(fpin_desc,
+ fcport);
+ }
+ }
+ }
+
+ if (memcmp(vha->port_name, fpin_desc->link_integrity.attached_port_name,
+ WWN_SIZE) == 0) {
+ ql_log(ql_log_info, vha, 0x5093,
+ "Link Integrity Event Type %d for HBA WWN %8phN\n",
+ be16_to_cpu(fpin_desc->link_integrity.event_type),
+ vha->port_name);
+
+ vha->scm_stats.current_events |= SCM_STATE_LINK_INTEGRITY;
+ vha->scm_stats.link_integrity.event_type =
+ be16_to_cpu(fpin_desc->link_integrity.event_type);
+ vha->scm_stats.link_integrity.event_modifier =
+ be16_to_cpu(fpin_desc->link_integrity.event_modifier);
+ vha->scm_stats.link_integrity.event_threshold =
+ be32_to_cpu(fpin_desc->link_integrity.event_threshold);
+ vha->scm_stats.link_integrity.event_count =
+ be32_to_cpu(fpin_desc->link_integrity.event_count);
+ vha->scm_stats.link_integrity.timestamp =
+ ktime_get_real_seconds();
+ }
+}
+
+void
+qla_delivery_tgt_stats_update(struct fpin_descriptor *fpin_desc,
+ fc_port_t *fcport)
+{
+ ql_log(ql_log_info, fcport->vha, 0x5095,
+ "Delivery Notification Reason Code %d for Port %8phN\n",
+ be32_to_cpu(fpin_desc->delivery.delivery_reason_code),
+ fcport->port_name);
+
+ switch (be32_to_cpu(fpin_desc->delivery.delivery_reason_code)) {
+ case SCM_DELIVERY_REASON_UNKNOWN:
+ fcport->scm_stats.delivery_failure_unknown++;
+ break;
+ case SCM_DELIVERY_REASON_TIMEOUT:
+ fcport->scm_stats.delivery_timeout++;
+ break;
+ case SCM_DELIVERY_REASON_UNABLE_TO_ROUTE:
+ fcport->scm_stats.delivery_unable_to_route++;
+ break;
+ case SCM_DELIVERY_REASON_DEVICE_SPECIFIC:
+ fcport->scm_stats.delivery_failure_device_specific++;
+ break;
+ }
+ fcport->scm_stats.delivery.timestamp =
+ ktime_get_real_seconds();
+}
+
+/*
+ * Process Delivery Notification Descriptor
+ */
+void
+qla_scm_process_delivery_notification_d(struct scsi_qla_host *vha,
+ struct fpin_descriptor *fpin_desc)
+{
+ fc_port_t *fcport = NULL;
+
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ fpin_desc->delivery.detecting_port_name, 0);
+ if (fcport)
+ qla_delivery_tgt_stats_update(fpin_desc, fcport);
+
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ fpin_desc->delivery.attached_port_name, 0);
+ if (fcport)
+ qla_delivery_tgt_stats_update(fpin_desc, fcport);
+
+ if (memcmp(vha->port_name, fpin_desc->delivery.attached_port_name,
+ WWN_SIZE) == 0) {
+ ql_log(ql_log_info, vha, 0x5096,
+ "Delivery Notification Reason Code %d for HBA WWN %8phN\n",
+ be32_to_cpu(fpin_desc->delivery.delivery_reason_code),
+ vha->port_name);
+
+ vha->scm_stats.delivery.delivery_reason =
+ be32_to_cpu(fpin_desc->delivery.delivery_reason_code);
+ vha->scm_stats.current_events |= SCM_STATE_DELIVERY;
+ vha->scm_stats.delivery.timestamp =
+ ktime_get_real_seconds();
+ }
+}
+
+void
+qla_scm_set_target_device_state(fc_port_t *fcport,
+ struct fpin_descriptor *fpin_desc)
+{
+ switch (be16_to_cpu(fpin_desc->peer_congestion.event_type)) {
+ case SCM_CONGESTION_EVENT_CLEAR:
+ ql_log(ql_log_warn, fcport->vha, 0x5097,
+ "Port %8phN Slow Device: Cleared\n", fcport->port_name);
+ fcport->slow_device = 0;
+ break;
+ case SCM_CONGESTION_EVENT_LOST_CREDIT:
+ break;
+ case SCM_CONGESTION_EVENT_CREDIT_STALL:
+ case SCM_CONGESTION_EVENT_OVERSUBSCRIPTION:
+ ql_log(ql_log_warn, fcport->vha, 0x508c,
+ "Port %8phN Slow Device: Set\n", fcport->port_name);
+ fcport->slow_device = 1;
+ break;
+ case SCM_CONGESTION_EVENT_DEVICE_SPECIFIC:
+ break;
+ }
+}
+
+void
+qla_peer_congestion_tgt_stats_update(struct fpin_descriptor *fpin_desc,
+ fc_port_t *fcport)
+{
+ ql_log(ql_log_info, fcport->vha, 0x5098,
+ "Peer Congestion Event Type %d for Port %8phN\n",
+ be16_to_cpu(fpin_desc->peer_congestion.event_type),
+ fcport->port_name);
+
+ fcport->scm_stats.peer_congestion.timestamp = ktime_get_real_seconds();
+ fcport->scm_stats.peer_congestion.event_type =
+ be16_to_cpu(fpin_desc->peer_congestion.event_type);
+ fcport->scm_stats.peer_congestion.event_modifier =
+ be16_to_cpu(fpin_desc->peer_congestion.event_modifier);
+ fcport->scm_stats.peer_congestion.event_period =
+ fpin_desc->peer_congestion.event_period;
+
+ // What is the API to get system time ?
+ fcport->scm_stats.current_events |= SCM_STATE_PEER_CONGESTION;
+ switch (be16_to_cpu(fpin_desc->peer_congestion.event_type)) {
+ case SCM_CONGESTION_EVENT_CLEAR:
+ fcport->scm_stats.peer_congestion_clear++;
+ fcport->scm_stats.current_events &= ~SCM_STATE_PEER_CONGESTION;
+ break;
+ case SCM_CONGESTION_EVENT_LOST_CREDIT:
+ fcport->scm_stats.peer_congestion_lost_credit++;
+ break;
+ case SCM_CONGESTION_EVENT_CREDIT_STALL:
+ fcport->scm_stats.peer_congestion_credit_stall++;
+ break;
+ case SCM_CONGESTION_EVENT_OVERSUBSCRIPTION:
+ fcport->scm_stats.peer_congestion_oversubscription++;
+ break;
+ case SCM_CONGESTION_EVENT_DEVICE_SPECIFIC:
+ fcport->scm_stats.peer_congestion_device_specific++;
+ break;
+ }
+ qla_scm_set_target_device_state(fcport, fpin_desc);
+}
+
+/*
+ * Process Peer-Congestion Notification Descriptor
+ */
+void
+qla_scm_process_peer_congestion_notification_d(struct scsi_qla_host *vha,
+ struct fpin_descriptor *fpin_desc)
+{
+ int i;
+ fc_port_t *fcport = NULL;
+ fc_port_t *d_fcport = NULL, *a_fcport = NULL;
+
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ fpin_desc->peer_congestion.detecting_port_name, 0);
+ if (fcport) {
+ d_fcport = fcport;
+ qla_peer_congestion_tgt_stats_update(fpin_desc, fcport);
+ }
+
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ fpin_desc->peer_congestion.attached_port_name, 0);
+ if (fcport) {
+ a_fcport = fcport;
+ qla_peer_congestion_tgt_stats_update(fpin_desc, fcport);
+ }
+
+ if (be32_to_cpu(fpin_desc->peer_congestion.port_name_count) > 0) {
+ for (i = 0;
+ i < be32_to_cpu(fpin_desc->peer_congestion.port_name_count);
+ i++) {
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+ fpin_desc->peer_congestion.port_name_list[i], 0);
+ if (fcport && fcport != d_fcport &&
+ fcport != a_fcport) {
+ qla_peer_congestion_tgt_stats_update(fpin_desc,
+ fcport);
+ }
+ }
+ }
+}
+
+/*
+ * qla_scm_process_congestion_notification_d() - Process
+ * Process Congestion Notification Descriptor
+ * @rsp: response queue
+ * @pkt: Entry pointer
+ */
+void
+qla_scm_process_congestion_notification_d(struct scsi_qla_host *vha,
+ struct fpin_descriptor *fpin_desc)
+{
+ ql_log(ql_log_info, vha, 0x5099,
+ "Congestion Notification Event Type %d\n",
+ be16_to_cpu(fpin_desc->congestion.event_type));
+
+ vha->scm_stats.congestion.event_type =
+ be16_to_cpu(fpin_desc->congestion.event_type);
+ vha->scm_stats.congestion.event_modifier =
+ be16_to_cpu(fpin_desc->congestion.event_modifier);
+ vha->scm_stats.congestion.event_period =
+ be32_to_cpu(fpin_desc->congestion.event_period);
+ vha->scm_stats.congestion.severity =
+ fpin_desc->congestion.severity;
+
+ if (be16_to_cpu(fpin_desc->congestion.event_type) ==
+ SCM_CONGESTION_EVENT_CLEAR)
+ vha->scm_stats.current_events &= ~SCM_STATE_CONGESTION;
+ else
+ vha->scm_stats.current_events |= SCM_STATE_CONGESTION;
+
+ if (fpin_desc->congestion.severity == SCM_CONGESTION_SEVERITY_WARNING)
+ vha->scm_stats.scm_congestion_warning++;
+ else if (fpin_desc->congestion.severity ==
+ SCM_CONGESTION_SEVERITY_ERROR)
+ vha->scm_stats.scm_congestion_alarm++;
+}
+
+void
+qla27xx_process_purex_fpin(struct scsi_qla_host *vha, struct purex_item *item)
+{
+ struct fpin_descriptor *fpin_desc;
+ uint16_t fpin_desc_len;
+ uint32_t fpin_offset = 0;
+ 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);
+
+ fpin_desc = (struct fpin_descriptor *)((uint8_t *)pkt +
+ FPIN_ELS_DESCRIPTOR_LIST_OFFSET);
+
+ fpin_desc_len = pkt_size - FPIN_ELS_DESCRIPTOR_LIST_OFFSET;
+ while (fpin_offset <= fpin_desc_len) {
+ fpin_desc = (struct fpin_descriptor *)((uint8_t *)fpin_desc +
+ fpin_offset);
+
+ if (fpin_offset >= fpin_desc_len - 8)
+ return;
+
+ switch (be32_to_cpu(fpin_desc->descriptor_tag)) {
+ case SCM_NOTIFICATION_TYPE_LINK_INTEGRITY:
+ qla_scm_process_link_integrity_d(vha, fpin_desc);
+ break;
+ case SCM_NOTIFICATION_TYPE_DELIVERY:
+ qla_scm_process_delivery_notification_d(vha, fpin_desc);
+ break;
+ case SCM_NOTIFICATION_TYPE_PEER_CONGESTION:
+ qla_scm_process_peer_congestion_notification_d(vha,
+ fpin_desc);
+ break;
+ case SCM_NOTIFICATION_TYPE_CONGESTION:
+ qla_scm_process_congestion_notification_d(vha,
+ fpin_desc);
+ break;
+ }
+ fpin_offset += be32_to_cpu(fpin_desc->descriptor_length) +
+ FPIN_DESCRIPTOR_HEADER_SIZE;
+ }
+ fc_host_fpin_rcv(vha->host, pkt_size, (char *)pkt);
+}
+
const char *const port_state_str[] = {
"Unknown",
"UNCONFIGURED",
@@ -836,6 +1202,111 @@ struct purex_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
+ */
+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.
* @vha: SCSI driver HA context
@@ -1350,6 +1821,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);
}
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) {
+ vha->scm_stats.scm_congestion_warning++;
+ } else if (mb[2] == QLA_CONGESTION_ARB_ALARM) {
+ ql_log(ql_log_warn, vha, 0x509b,
+ "Congestion Alarm %04x %04x.\n", mb[1], mb[2]);
+ vha->scm_stats.scm_congestion_alarm++;
+ }
+ break;
/* case MBA_RIO_RESPONSE: */
case MBA_ZIO_RESPONSE:
ql_dbg(ql_dbg_async, vha, 0x5015,
@@ -3279,6 +3763,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
{
struct sts_entry_24xx *pkt;
struct qla_hw_data *ha = vha->hw;
+ struct purex_entry_24xx *purex_entry;
struct purex_item *pure_item;
if (!ha->flags.fw_started)
@@ -3334,7 +3819,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
pure_item = qla24xx_copy_std_pkt(vha, pkt);
if (!pure_item)
break;
-
qla24xx_queue_purex_item(vha, pure_item,
qla24xx_process_abts);
break;
@@ -3384,29 +3868,41 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
(struct vp_ctrl_entry_24xx *)pkt);
break;
case PUREX_IOCB_TYPE:
- {
- struct purex_entry_24xx *purex = (void *)pkt;
-
- if (purex->els_frame_payload[3] != ELS_COMMAND_RDP) {
- ql_dbg(ql_dbg_init, vha, 0x5091,
- "Discarding ELS Request opcode %#x...\n",
- purex->els_frame_payload[3]);
+ purex_entry = (void *)pkt;
+ switch (purex_entry->els_frame_payload[3]) {
+ case ELS_COMMAND_RDP:
+ pure_item = qla24xx_copy_std_pkt(vha, pkt);
+ if (!pure_item)
+ break;
+ qla24xx_queue_purex_item(vha, pure_item,
+ qla24xx_process_purex_rdp);
break;
- }
- pure_item = qla24xx_copy_std_pkt(vha, pkt);
- if (!pure_item)
+ case ELS_COMMAND_FPIN:
+ if (!vha->hw->flags.scm_enabled) {
+ 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;
-
- qla24xx_queue_purex_item(vha, pure_item,
- qla24xx_process_purex_rdp);
+ case ELS_COMMAND_PUN:
+ break;
+ default:
+ ql_log(ql_log_warn, vha, 0x509c,
+ "Discarding ELS Request opcode 0x%x\n",
+ purex_entry->els_frame_payload[3]);
+ }
break;
- }
default:
/* Type Not Supported. */
ql_dbg(ql_dbg_async, vha, 0x5042,
- "Received unknown response pkt type %x "
- "entry status=%x.\n",
- pkt->entry_type, pkt->entry_status);
+ "Received unknown response pkt type 0x%x entry status=%x.\n",
+ pkt->entry_type, pkt->entry_status);
break;
}
((response_t *)pkt)->signature = RESPONSE_PROCESSED;
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 76a4f2bfdbed..3c411b5914ce 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1126,6 +1126,16 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
(ha->flags.secure_fw) ? "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:
@@ -1635,8 +1645,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;
if (IS_FWI2_CAPABLE(vha->hw))
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->out_mb |= MBX_7|MBX_21|MBX_22|MBX_23;
+ }
+
mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
@@ -1689,8 +1702,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];
+ 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_stats.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;
@@ -1803,6 +1830,17 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
mcp->mb[14] = sizeof(*ha->ex_init_cb);
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. */
mcp->in_mb = MBX_2|MBX_1|MBX_0;
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
@@ -4902,7 +4940,8 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
/* List of Purex ELS */
cmd_opcode[0] = ELS_COMMAND_FPIN;
- cmd_opcode[1] = ELS_COMMAND_PUN;
+ cmd_opcode[1] = ELS_COMMAND_RDP;
+ cmd_opcode[2] = ELS_COMMAND_PUN;
for (i = 0; i < PUREX_CMD_COUNT; i++) {
index = cmd_opcode[i] / 8;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 007f39128dbf..70241506d0ca 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4220,6 +4220,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);
}
+ /* 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);
/* Get consistent memory allocated for Async Port-Database. */
@@ -4273,6 +4283,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
fail_loop_id_map:
dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
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);
fail_ex_init_cb:
kfree(ha->npiv_info);
@@ -4695,6 +4707,10 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->ms_iocb = NULL;
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)
dma_pool_free(ha->s_dma_pool,
ha->ex_init_cb, ha->ex_init_cb_dma);
@@ -4782,6 +4798,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
kfree(ha->swl);
ha->swl = NULL;
kfree(ha->loop_id_map);
+ ha->sf_init_cb = NULL;
+ ha->sf_init_cb_dma = 0;
ha->loop_id_map = NULL;
}
--
2.19.0.rc0
next prev parent reply other threads:[~2020-05-14 10:11 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-14 10:10 [PATCH 0/3] qla2xxx SAN Congestion Management (SCM) support Nilesh Javali
2020-05-14 10:10 ` [PATCH 1/3] qla2xxx: Change in PUREX to handle FPIN ELS requests Nilesh Javali
2020-05-14 17:03 ` himanshu.madhani
2020-05-15 18:52 ` James Smart
2020-05-14 10:10 ` Nilesh Javali [this message]
2020-05-14 18:52 ` [PATCH 2/3] qla2xxx: SAN congestion management(SCM) implementation himanshu.madhani
2020-05-15 22:48 ` James Smart
[not found] ` <CA+ihqdiA7AN05k5MjPG=o8_pf=L-La6UigY4t0emKgJMXm=hnQ@mail.gmail.com>
[not found] ` <BYAPR18MB2805AEA357302FCFA20D2B57B48F0@BYAPR18MB2805.namprd18.prod.outlook.com>
2020-06-11 17:42 ` Shyam Sundar
2020-06-25 23:25 ` James Smart
2020-06-26 0:14 ` Shyam Sundar
2020-07-30 16:10 ` Shyam Sundar
2020-09-21 17:48 ` James Smart
[not found] ` <CA+ihqdjtoA=1q7N0pg1TQDAMGo1XtNN8+XnO1qXORyqGYfpq=A@mail.gmail.com>
2020-06-11 18:10 ` Shyam S
2020-05-14 10:10 ` [PATCH 3/3] qla2xxx: Pass SCM counters to the application Nilesh Javali
2020-05-14 19:15 ` himanshu.madhani
2020-05-14 14:11 ` [PATCH 0/3] qla2xxx SAN Congestion Management (SCM) support Bart Van Assche
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200514101026.10040-3-njavali@marvell.com \
--to=njavali@marvell.com \
--cc=GR-QLogic-Storage-Upstream@marvell.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.