linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support
@ 2020-06-10 14:15 Nilesh Javali
  2020-06-10 14:15 ` [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests Nilesh Javali
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Nilesh Javali @ 2020-06-10 14:15 UTC (permalink / raw)
  To: martin.petersen; +Cc: linux-scsi, GR-QLogic-Storage-Upstream

Martin,

Please apply the updated qla2xxx patch series implementing SAN
Congestion Management (SCM) support to the scsi tree at your
earliest convenience.

We will follow this up with another patchset to add SCM statistics to
the scsi transport fc, as recommended by James.

v2->v3:
1. Updated Reviewed-by tags

v1->v2:
1. Applied changes to address warnings highlighted by Bart.
2. Removed data structures and functions that should be part of fc
transport, to be send out in a follow-up patchset.
3. Changed the existing code to use definitions from fc transport
headers.

Thanks,
Nilesh

Shyam Sundar (2):
  qla2xxx: Change in PUREX to handle FPIN ELS requests.
  qla2xxx: SAN congestion management(SCM) implementation.

 drivers/scsi/qla2xxx/qla_dbg.c  |  13 +-
 drivers/scsi/qla2xxx/qla_def.h  |  71 +++++++-
 drivers/scsi/qla2xxx/qla_fw.h   |   6 +-
 drivers/scsi/qla2xxx/qla_gbl.h  |   4 +-
 drivers/scsi/qla2xxx/qla_init.c |   9 +-
 drivers/scsi/qla2xxx/qla_isr.c  | 291 +++++++++++++++++++++++++++-----
 drivers/scsi/qla2xxx/qla_mbx.c  |  64 ++++++-
 drivers/scsi/qla2xxx/qla_os.c   |  37 +++-
 include/uapi/scsi/fc/fc_els.h   |   1 +
 9 files changed, 428 insertions(+), 68 deletions(-)


base-commit: 47742bde281b2920aae8bb82ed2d61d890aa4f56
-- 
2.19.0.rc0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests.
  2020-06-10 14:15 [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support Nilesh Javali
@ 2020-06-10 14:15 ` Nilesh Javali
  2020-06-25 23:38   ` James Smart
  2020-06-10 14:15 ` [PATCH v3 2/2] qla2xxx: SAN congestion management(SCM) implementation Nilesh Javali
  2020-06-18 22:46 ` [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support Shyam Sundar
  2 siblings, 1 reply; 9+ messages in thread
From: Nilesh Javali @ 2020-06-10 14:15 UTC (permalink / raw)
  To: martin.petersen; +Cc: linux-scsi, GR-QLogic-Storage-Upstream

From: Shyam Sundar <ssundar@marvell.com>

SAN Congestion Management generates ELS pkts whose size
can vary, and be > 64 bytes. Change the purex
handling code to support non standard ELS pkt size.

Signed-off-by: Shyam Sundar <ssundar@marvell.com>
Signed-off-by: Arun Easi <aeasi@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
---
 drivers/scsi/qla2xxx/qla_def.h |  20 +++++-
 drivers/scsi/qla2xxx/qla_gbl.h |   3 +-
 drivers/scsi/qla2xxx/qla_isr.c | 116 ++++++++++++++++++++++++---------
 drivers/scsi/qla2xxx/qla_mbx.c |  22 +++++--
 drivers/scsi/qla2xxx/qla_os.c  |  19 ++++--
 include/uapi/scsi/fc/fc_els.h  |   1 +
 6 files changed, 139 insertions(+), 42 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 172ea4e5887d..2e058ac4fec7 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -34,6 +34,8 @@
 #include <scsi/scsi_transport_fc.h>
 #include <scsi/scsi_bsg_fc.h>
 
+#include <uapi/scsi/fc/fc_els.h>
+
 /* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */
 typedef struct {
 	uint8_t domain;
@@ -1269,7 +1271,11 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
 #define RNID_TYPE_ASIC_TEMP	0xC
 
 #define ELS_CMD_MAP_SIZE	32
-#define ELS_COMMAND_RDP		0x18
+#define ELS_COMMAND_RDP		ELS_RDP
+/* Fabric Perf Impact Notification */
+#define ELS_COMMAND_FPIN	ELS_FPIN
+/* Read Diagnostic Functions */
+#define ELS_COMMAND_RDF		ELS_RDF
 
 /*
  * Firmware state codes from get firmware state mailbox command
@@ -4487,10 +4493,19 @@ struct active_regions {
 #define QLA_SET_DATA_RATE_NOLR	1
 #define QLA_SET_DATA_RATE_LR	2 /* Set speed and initiate LR */
 
+#define QLA_DEFAULT_PAYLOAD_SIZE	64
+/*
+ * This item might be allocated with a size > sizeof(struct purex_item).
+ * The "size" variable gives the size of the payload (which
+ * is variable) starting at "iocb".
+ */
 struct purex_item {
 	struct list_head list;
 	struct scsi_qla_host *vha;
-	void (*process_item)(struct scsi_qla_host *vha, void *pkt);
+	void (*process_item)(struct scsi_qla_host *vha,
+			     struct purex_item *pkt);
+	atomic_t in_use;
+	uint16_t size;
 	struct {
 		uint8_t iocb[64];
 	} iocb;
@@ -4690,6 +4705,7 @@ typedef struct scsi_qla_host {
 		struct list_head head;
 		spinlock_t lock;
 	} purex_list;
+	struct purex_item default_item;
 
 	struct name_list_extended gnl;
 	/* Count of active session/fcport */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index f62b71e47581..54d82f7d478f 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -229,7 +229,8 @@ void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
 int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
 int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
 void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);
-void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt);
+void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
+			       struct purex_item *pkt);
 
 /*
  * Global Functions in qla_mid.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a9e8513e1cf1..401ce0023cd5 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -31,35 +31,11 @@ const char *const port_state_str[] = {
 	"ONLINE"
 };
 
-static void qla24xx_purex_iocb(scsi_qla_host_t *vha, void *pkt,
-	void (*process_item)(struct scsi_qla_host *vha, void *pkt))
-{
-	struct purex_list *list = &vha->purex_list;
-	struct purex_item *item;
-	ulong flags;
-
-	item = kzalloc(sizeof(*item), GFP_KERNEL);
-	if (!item) {
-		ql_log(ql_log_warn, vha, 0x5092,
-		    ">> Failed allocate purex list item.\n");
-		return;
-	}
-
-	item->vha = vha;
-	item->process_item = process_item;
-	memcpy(&item->iocb, pkt, sizeof(item->iocb));
-
-	spin_lock_irqsave(&list->lock, flags);
-	list_add_tail(&item->list, &list->head);
-	spin_unlock_irqrestore(&list->lock, flags);
-
-	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
-}
-
 static void
-qla24xx_process_abts(struct scsi_qla_host *vha, void *pkt)
+qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
 {
-	struct abts_entry_24xx *abts = pkt;
+	struct abts_entry_24xx *abts =
+	    (struct abts_entry_24xx *)&pkt->iocb;
 	struct qla_hw_data *ha = vha->hw;
 	struct els_entry_24xx *rsp_els;
 	struct abts_entry_24xx *abts_rsp;
@@ -790,6 +766,76 @@ qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
 	}
 }
 
+struct purex_item *
+qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size)
+{
+	struct purex_item *item = NULL;
+	uint8_t item_hdr_size = sizeof(*item);
+	uint8_t default_usable = 0;
+
+	if (size > QLA_DEFAULT_PAYLOAD_SIZE) {
+		item = kzalloc(item_hdr_size +
+		    (size - QLA_DEFAULT_PAYLOAD_SIZE), GFP_ATOMIC);
+	} else {
+		item = kzalloc(item_hdr_size, GFP_ATOMIC);
+		default_usable = 1;
+	}
+	if (!item) {
+		if (default_usable &&
+		    (atomic_inc_return(&vha->default_item.in_use) == 1)) {
+			item = &vha->default_item;
+			goto initialize_purex_header;
+		}
+		ql_log(ql_log_warn, vha, 0x5092,
+		       ">> Failed allocate purex list item.\n");
+
+		return NULL;
+	}
+
+initialize_purex_header:
+	item->vha = vha;
+	item->size = size;
+	return item;
+}
+
+static void
+qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
+			 void (*process_item)(struct scsi_qla_host *vha,
+					      struct purex_item *pkt))
+{
+	struct purex_list *list = &vha->purex_list;
+	ulong flags;
+
+	pkt->process_item = process_item;
+
+	spin_lock_irqsave(&list->lock, flags);
+	list_add_tail(&pkt->list, &list->head);
+	spin_unlock_irqrestore(&list->lock, flags);
+
+	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
+}
+
+/**
+ * qla24xx_copy_std_pkt() - Copy over purex ELS which is
+ * contained in a single IOCB.
+ * purex packet.
+ * @vha: SCSI driver HA context
+ * @pkt: ELS packet
+ */
+struct purex_item
+*qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
+{
+	struct purex_item *item;
+
+	item = qla24xx_alloc_purex_item(vha,
+					QLA_DEFAULT_PAYLOAD_SIZE);
+	if (!item)
+		return item;
+
+	memcpy(&item->iocb, pkt, sizeof(item->iocb));
+	return item;
+}
+
 /**
  * qla2x00_async_event() - Process aynchronous events.
  * @vha: SCSI driver HA context
@@ -3233,6 +3279,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_item *pure_item;
 
 	if (!ha->flags.fw_started)
 		return;
@@ -3284,8 +3331,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 			break;
 		case ABTS_RECV_24XX:
 			if (qla_ini_mode_enabled(vha)) {
-				qla24xx_purex_iocb(vha, pkt,
-				    qla24xx_process_abts);
+				pure_item = qla24xx_copy_std_pkt(vha, pkt);
+				if (!pure_item)
+					break;
+
+				qla24xx_queue_purex_item(vha, pure_item,
+							 qla24xx_process_abts);
 				break;
 			}
 			if (IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
@@ -3342,7 +3393,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 				    purex->els_frame_payload[3]);
 				break;
 			}
-			qla24xx_purex_iocb(vha, pkt, qla24xx_process_purex_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;
 		}
 		default:
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 9fd83d1bffe0..a1f899bb8c94 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -59,6 +59,7 @@ static struct rom_cmd {
 	{ MBC_IOCB_COMMAND_A64 },
 	{ MBC_GET_ADAPTER_LOOP_ID },
 	{ MBC_READ_SFP },
+	{ MBC_SET_RNID_PARAMS },
 	{ MBC_GET_RNID_PARAMS },
 	{ MBC_GET_SET_ZIO_THRESHOLD },
 };
@@ -4867,6 +4868,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
 	return rval;
 }
 
+#define PUREX_CMD_COUNT	2
 int
 qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
 {
@@ -4875,12 +4877,12 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
 	mbx_cmd_t *mcp = &mc;
 	uint8_t *els_cmd_map;
 	dma_addr_t els_cmd_map_dma;
-	uint cmd_opcode = ELS_COMMAND_RDP;
-	uint index = cmd_opcode / 8;
-	uint bit = cmd_opcode % 8;
+	uint cmd_opcode[PUREX_CMD_COUNT];
+	uint i, index, purex_bit;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) && !IS_QLA27XX(ha))
+	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) &&
+	    !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
 		return QLA_SUCCESS;
 
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197,
@@ -4896,7 +4898,17 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
 
 	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
 
-	els_cmd_map[index] |= 1 << bit;
+	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
+
+	/* List of Purex ELS */
+	cmd_opcode[0] = ELS_COMMAND_FPIN;
+	cmd_opcode[1] = ELS_COMMAND_RDP;
+
+	for (i = 0; i < PUREX_CMD_COUNT; i++) {
+		index = cmd_opcode[i] / 8;
+		purex_bit = cmd_opcode[i] % 8;
+		els_cmd_map[index] |= 1 << purex_bit;
+	}
 
 	mcp->mb[0] = MBC_SET_RNID_PARAMS;
 	mcp->mb[1] = RNID_TYPE_ELS_CMD << 8;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 382e1f977d01..007f39128dbf 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -5891,10 +5891,12 @@ qla25xx_rdp_port_speed_currently(struct qla_hw_data *ha)
  * vha:	SCSI qla host
  * purex: RDP request received by HBA
  */
-void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
+void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
+			       struct purex_item *item)
 {
 	struct qla_hw_data *ha = vha->hw;
-	struct purex_entry_24xx *purex = pkt;
+	struct purex_entry_24xx *purex =
+	    (struct purex_entry_24xx *)&item->iocb;
 	dma_addr_t rsp_els_dma;
 	dma_addr_t rsp_payload_dma;
 	dma_addr_t stat_dma;
@@ -6304,6 +6306,15 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
 		    rsp_els, rsp_els_dma);
 }
 
+void
+qla24xx_free_purex_item(struct purex_item *item)
+{
+	if (item == &item->vha->default_item)
+		memset(&item->vha->default_item, 0, sizeof(struct purex_item));
+	else
+		kfree(item);
+}
+
 void qla24xx_process_purex_list(struct purex_list *list)
 {
 	struct list_head head = LIST_HEAD_INIT(head);
@@ -6316,8 +6327,8 @@ void qla24xx_process_purex_list(struct purex_list *list)
 
 	list_for_each_entry_safe(item, next, &head, list) {
 		list_del(&item->list);
-		item->process_item(item->vha, &item->iocb);
-		kfree(item);
+		item->process_item(item->vha, item);
+		qla24xx_free_purex_item(item);
 	}
 }
 
diff --git a/include/uapi/scsi/fc/fc_els.h b/include/uapi/scsi/fc/fc_els.h
index 66318c44acd7..cb7ffc37c4f9 100644
--- a/include/uapi/scsi/fc/fc_els.h
+++ b/include/uapi/scsi/fc/fc_els.h
@@ -41,6 +41,7 @@ enum fc_els_cmd {
 	ELS_REC =	0x13,	/* read exchange concise */
 	ELS_SRR =	0x14,	/* sequence retransmission request */
 	ELS_FPIN =	0x16,	/* Fabric Performance Impact Notification */
+	ELS_RDP =	0x18,	/* Read Diagnostic Parameters */
 	ELS_RDF =	0x19,	/* Register Diagnostic Functions */
 	ELS_PRLI =	0x20,	/* process login */
 	ELS_PRLO =	0x21,	/* process logout */
-- 
2.19.0.rc0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/2] qla2xxx: SAN congestion management(SCM) implementation.
  2020-06-10 14:15 [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support Nilesh Javali
  2020-06-10 14:15 ` [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests Nilesh Javali
@ 2020-06-10 14:15 ` Nilesh Javali
  2020-06-25 14:38   ` Himanshu Madhani
  2020-06-25 23:42   ` James Smart
  2020-06-18 22:46 ` [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support Shyam Sundar
  2 siblings, 2 replies; 9+ messages in thread
From: Nilesh Javali @ 2020-06-10 14:15 UTC (permalink / raw)
  To: martin.petersen; +Cc: linux-scsi, GR-QLogic-Storage-Upstream

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.
* 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_dbg.c  |  13 +--
 drivers/scsi/qla2xxx/qla_def.h  |  51 +++++++++
 drivers/scsi/qla2xxx/qla_fw.h   |   6 +-
 drivers/scsi/qla2xxx/qla_gbl.h  |   1 +
 drivers/scsi/qla2xxx/qla_init.c |   9 +-
 drivers/scsi/qla2xxx/qla_isr.c  | 191 ++++++++++++++++++++++++++++----
 drivers/scsi/qla2xxx/qla_mbx.c  |  42 ++++++-
 drivers/scsi/qla2xxx/qla_os.c   |  18 +++
 8 files changed, 297 insertions(+), 34 deletions(-)

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 2e058ac4fec7..964567a8b48c 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1020,6 +1020,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. */
@@ -1480,6 +1481,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.
  */
@@ -2153,6 +2173,8 @@ typedef struct {
 	struct dsd64 rsp_dsd;
 } 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.
@@ -3822,6 +3844,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;
@@ -4139,6 +4167,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;
@@ -4201,6 +4236,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;
@@ -4511,6 +4552,15 @@ struct purex_item {
 	} 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
+struct qla_scm_port {
+} __packed;
+
 /*
  * Qlogic scsi host structure
  */
@@ -4719,6 +4769,7 @@ typedef struct scsi_qla_host {
 	__le16 dport_data[4];
 	struct list_head gpnid_list;
 	struct fab_scan scan;
+	uint8_t	scm_fabric_connection_flags;
 
 	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..a0d83c67dc23 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -723,6 +723,8 @@ struct ct_entry_24xx {
 	struct dsd64 dsd[2];
 };
 
+#define PURX_ELS_HEADER_SIZE	0x18
+
 /*
  * ISP queue - PUREX IOCB entry structure definition
  */
@@ -2020,7 +2022,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..35009ee93c97 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 ((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..fd4ead7fb047 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -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 int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
 	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[] = {
 	"Unknown",
@@ -822,7 +847,7 @@ qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
  * @vha: SCSI driver HA context
  * @pkt: ELS packet
  */
-struct purex_item
+static struct purex_item
 *qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
 {
 	struct purex_item *item;
@@ -836,6 +861,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
+ */
+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.
  * @vha: SCSI driver HA context
@@ -1350,6 +1480,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) {
+			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_ZIO_RESPONSE:
 		ql_dbg(ql_dbg_async, vha, 0x5015,
@@ -3279,6 +3422,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 +3478,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 +3527,39 @@ 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);
+			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 a1f899bb8c94..9d7e00652437 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_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))
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


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support
  2020-06-10 14:15 [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support Nilesh Javali
  2020-06-10 14:15 ` [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests Nilesh Javali
  2020-06-10 14:15 ` [PATCH v3 2/2] qla2xxx: SAN congestion management(SCM) implementation Nilesh Javali
@ 2020-06-18 22:46 ` Shyam Sundar
  2020-06-25 16:29   ` James Smart
  2 siblings, 1 reply; 9+ messages in thread
From: Shyam Sundar @ 2020-06-18 22:46 UTC (permalink / raw)
  To: james.smart
  Cc: Martin K . Petersen, linux-scsi, GR-QLogic-Storage-Upstream,
	Nilesh Javali

Hi James,
    Could you please review v3 patch-set and let us know if it looks appropriate.
   
    We should be sending out the next set of changes (to FC Transport) in the first week of July.

Thanks
Shyam


> On Jun 10, 2020, at 7:15 AM, Nilesh Javali <njavali@marvell.com> wrote:
> 
> Martin,
> 
> Please apply the updated qla2xxx patch series implementing SAN
> Congestion Management (SCM) support to the scsi tree at your
> earliest convenience.
> 
> We will follow this up with another patchset to add SCM statistics to
> the scsi transport fc, as recommended by James.
> 
> v2->v3:
> 1. Updated Reviewed-by tags
> 
> v1->v2:
> 1. Applied changes to address warnings highlighted by Bart.
> 2. Removed data structures and functions that should be part of fc
> transport, to be send out in a follow-up patchset.
> 3. Changed the existing code to use definitions from fc transport
> headers.
> 
> Thanks,
> Nilesh
> 
> Shyam Sundar (2):
>  qla2xxx: Change in PUREX to handle FPIN ELS requests.
>  qla2xxx: SAN congestion management(SCM) implementation.
> 
> drivers/scsi/qla2xxx/qla_dbg.c  |  13 +-
> drivers/scsi/qla2xxx/qla_def.h  |  71 +++++++-
> drivers/scsi/qla2xxx/qla_fw.h   |   6 +-
> drivers/scsi/qla2xxx/qla_gbl.h  |   4 +-
> drivers/scsi/qla2xxx/qla_init.c |   9 +-
> drivers/scsi/qla2xxx/qla_isr.c  | 291 +++++++++++++++++++++++++++-----
> drivers/scsi/qla2xxx/qla_mbx.c  |  64 ++++++-
> drivers/scsi/qla2xxx/qla_os.c   |  37 +++-
> include/uapi/scsi/fc/fc_els.h   |   1 +
> 9 files changed, 428 insertions(+), 68 deletions(-)
> 
> 
> base-commit: 47742bde281b2920aae8bb82ed2d61d890aa4f56
> -- 
> 2.19.0.rc0
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/2] qla2xxx: SAN congestion management(SCM) implementation.
  2020-06-10 14:15 ` [PATCH v3 2/2] qla2xxx: SAN congestion management(SCM) implementation Nilesh Javali
@ 2020-06-25 14:38   ` Himanshu Madhani
  2020-06-25 23:42   ` James Smart
  1 sibling, 0 replies; 9+ messages in thread
From: Himanshu Madhani @ 2020-06-25 14:38 UTC (permalink / raw)
  To: Nilesh Javali; +Cc: Martin K . Petersen, linux-scsi, GR-QLogic-Storage-Upstream



> On Jun 10, 2020, at 9:15 AM, Nilesh Javali <njavali@marvell.com> wrote:
> 
> 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.
> * 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_dbg.c  |  13 +--
> drivers/scsi/qla2xxx/qla_def.h  |  51 +++++++++
> drivers/scsi/qla2xxx/qla_fw.h   |   6 +-
> drivers/scsi/qla2xxx/qla_gbl.h  |   1 +
> drivers/scsi/qla2xxx/qla_init.c |   9 +-
> drivers/scsi/qla2xxx/qla_isr.c  | 191 ++++++++++++++++++++++++++++----
> drivers/scsi/qla2xxx/qla_mbx.c  |  42 ++++++-
> drivers/scsi/qla2xxx/qla_os.c   |  18 +++
> 8 files changed, 297 insertions(+), 34 deletions(-)
> 
> 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 2e058ac4fec7..964567a8b48c 100644
> --- a/drivers/scsi/qla2xxx/qla_def.h
> +++ b/drivers/scsi/qla2xxx/qla_def.h
> @@ -1020,6 +1020,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. */
> @@ -1480,6 +1481,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.
>  */
> @@ -2153,6 +2173,8 @@ typedef struct {
> 	struct dsd64 rsp_dsd;
> } 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.
> @@ -3822,6 +3844,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;
> @@ -4139,6 +4167,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;
> @@ -4201,6 +4236,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;
> @@ -4511,6 +4552,15 @@ struct purex_item {
> 	} 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
> +struct qla_scm_port {
> +} __packed;
> +

Small nit. This looks like stale definition. Please remove this.

> /*
>  * Qlogic scsi host structure
>  */
> @@ -4719,6 +4769,7 @@ typedef struct scsi_qla_host {
> 	__le16 dport_data[4];
> 	struct list_head gpnid_list;
> 	struct fab_scan scan;
> +	uint8_t	scm_fabric_connection_flags;
> 
> 	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..a0d83c67dc23 100644
> --- a/drivers/scsi/qla2xxx/qla_fw.h
> +++ b/drivers/scsi/qla2xxx/qla_fw.h
> @@ -723,6 +723,8 @@ struct ct_entry_24xx {
> 	struct dsd64 dsd[2];
> };
> 
> +#define PURX_ELS_HEADER_SIZE	0x18
> +
> /*
>  * ISP queue - PUREX IOCB entry structure definition
>  */
> @@ -2020,7 +2022,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..35009ee93c97 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 ((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..fd4ead7fb047 100644
> --- a/drivers/scsi/qla2xxx/qla_isr.c
> +++ b/drivers/scsi/qla2xxx/qla_isr.c
> @@ -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 int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
> 	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[] = {
> 	"Unknown",
> @@ -822,7 +847,7 @@ qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
>  * @vha: SCSI driver HA context
>  * @pkt: ELS packet
>  */
> -struct purex_item
> +static struct purex_item
> *qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
> {
> 	struct purex_item *item;
> @@ -836,6 +861,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
> + */
> +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.
>  * @vha: SCSI driver HA context
> @@ -1350,6 +1480,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) {
> +			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_ZIO_RESPONSE:
> 		ql_dbg(ql_dbg_async, vha, 0x5015,
> @@ -3279,6 +3422,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 +3478,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 +3527,39 @@ 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);
> +			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 a1f899bb8c94..9d7e00652437 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_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))
> 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
> 

Otherwise looks good.

Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>

--
Himanshu Madhani	Oracle Linux Engineering






^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support
  2020-06-18 22:46 ` [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support Shyam Sundar
@ 2020-06-25 16:29   ` James Smart
  0 siblings, 0 replies; 9+ messages in thread
From: James Smart @ 2020-06-25 16:29 UTC (permalink / raw)
  To: Shyam Sundar
  Cc: Martin K . Petersen, linux-scsi, GR-QLogic-Storage-Upstream,
	Nilesh Javali

yep - will do so shortly

On 6/18/2020 3:46 PM, Shyam Sundar wrote:
> Hi James,
>      Could you please review v3 patch-set and let us know if it looks appropriate.
>     
>      We should be sending out the next set of changes (to FC Transport) in the first week of July.
>
> Thanks
> Shyam
>

yep - will do so shortly

-- james



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests.
  2020-06-10 14:15 ` [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests Nilesh Javali
@ 2020-06-25 23:38   ` James Smart
  2020-06-25 23:59     ` Shyam Sundar
  0 siblings, 1 reply; 9+ messages in thread
From: James Smart @ 2020-06-25 23:38 UTC (permalink / raw)
  To: Nilesh Javali, martin.petersen; +Cc: linux-scsi, GR-QLogic-Storage-Upstream



On 6/10/2020 7:15 AM, Nilesh Javali wrote:
> From: Shyam Sundar <ssundar@marvell.com>
>
> SAN Congestion Management generates ELS pkts whose size
> can vary, and be > 64 bytes. Change the purex
> handling code to support non standard ELS pkt size.
>
> Signed-off-by: Shyam Sundar <ssundar@marvell.com>
> Signed-off-by: Arun Easi <aeasi@marvell.com>
> Signed-off-by: Nilesh Javali <njavali@marvell.com>
> Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
> ---
>   drivers/scsi/qla2xxx/qla_def.h |  20 +++++-
>   drivers/scsi/qla2xxx/qla_gbl.h |   3 +-
>   drivers/scsi/qla2xxx/qla_isr.c | 116 ++++++++++++++++++++++++---------
>   drivers/scsi/qla2xxx/qla_mbx.c |  22 +++++--
>   drivers/scsi/qla2xxx/qla_os.c  |  19 ++++--
>   include/uapi/scsi/fc/fc_els.h  |   1 +
>   6 files changed, 139 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
> index 172ea4e5887d..2e058ac4fec7 100644
> --- a/drivers/scsi/qla2xxx/qla_def.h
> +++ b/drivers/scsi/qla2xxx/qla_def.h
> @@ -34,6 +34,8 @@
>   #include <scsi/scsi_transport_fc.h>
>   #include <scsi/scsi_bsg_fc.h>
>   
> +#include <uapi/scsi/fc/fc_els.h>
> +
>   /* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */
>   typedef struct {
>   	uint8_t domain;
> @@ -1269,7 +1271,11 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
>   #define RNID_TYPE_ASIC_TEMP	0xC
>   
>   #define ELS_CMD_MAP_SIZE	32
> -#define ELS_COMMAND_RDP		0x18
> +#define ELS_COMMAND_RDP		ELS_RDP
> +/* Fabric Perf Impact Notification */
> +#define ELS_COMMAND_FPIN	ELS_FPIN
> +/* Read Diagnostic Functions */
> +#define ELS_COMMAND_RDF		ELS_RDF

there shouldn't be a need for a new define for these. The native ELS_xxx 
define should be used.

>   
>   /*
>    * Firmware state codes from get firmware state mailbox command
> @@ -4487,10 +4493,19 @@ struct active_regions {
>   #define QLA_SET_DATA_RATE_NOLR	1
>   #define QLA_SET_DATA_RATE_LR	2 /* Set speed and initiate LR */
>   
> +#define QLA_DEFAULT_PAYLOAD_SIZE	64
> +/*
> + * This item might be allocated with a size > sizeof(struct purex_item).
> + * The "size" variable gives the size of the payload (which
> + * is variable) starting at "iocb".
> + */
>   struct purex_item {
>   	struct list_head list;
>   	struct scsi_qla_host *vha;
> -	void (*process_item)(struct scsi_qla_host *vha, void *pkt);
> +	void (*process_item)(struct scsi_qla_host *vha,
> +			     struct purex_item *pkt);
> +	atomic_t in_use;
> +	uint16_t size;
>   	struct {
>   		uint8_t iocb[64];
>   	} iocb;
> @@ -4690,6 +4705,7 @@ typedef struct scsi_qla_host {
>   		struct list_head head;
>   		spinlock_t lock;
>   	} purex_list;
> +	struct purex_item default_item;
>   
>   	struct name_list_extended gnl;
>   	/* Count of active session/fcport */
> diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
> index f62b71e47581..54d82f7d478f 100644
> --- a/drivers/scsi/qla2xxx/qla_gbl.h
> +++ b/drivers/scsi/qla2xxx/qla_gbl.h
> @@ -229,7 +229,8 @@ void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
>   int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
>   int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
>   void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);
> -void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt);
> +void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
> +			       struct purex_item *pkt);
>   
>   /*
>    * Global Functions in qla_mid.c source file.
> diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
> index a9e8513e1cf1..401ce0023cd5 100644
> --- a/drivers/scsi/qla2xxx/qla_isr.c
> +++ b/drivers/scsi/qla2xxx/qla_isr.c
> @@ -31,35 +31,11 @@ const char *const port_state_str[] = {
>   	"ONLINE"
>   };
>   
> -static void qla24xx_purex_iocb(scsi_qla_host_t *vha, void *pkt,
> -	void (*process_item)(struct scsi_qla_host *vha, void *pkt))
> -{
> -	struct purex_list *list = &vha->purex_list;
> -	struct purex_item *item;
> -	ulong flags;
> -
> -	item = kzalloc(sizeof(*item), GFP_KERNEL);
> -	if (!item) {
> -		ql_log(ql_log_warn, vha, 0x5092,
> -		    ">> Failed allocate purex list item.\n");
> -		return;
> -	}
> -
> -	item->vha = vha;
> -	item->process_item = process_item;
> -	memcpy(&item->iocb, pkt, sizeof(item->iocb));
> -
> -	spin_lock_irqsave(&list->lock, flags);
> -	list_add_tail(&item->list, &list->head);
> -	spin_unlock_irqrestore(&list->lock, flags);
> -
> -	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
> -}
> -
>   static void
> -qla24xx_process_abts(struct scsi_qla_host *vha, void *pkt)
> +qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
>   {
> -	struct abts_entry_24xx *abts = pkt;
> +	struct abts_entry_24xx *abts =
> +	    (struct abts_entry_24xx *)&pkt->iocb;
>   	struct qla_hw_data *ha = vha->hw;
>   	struct els_entry_24xx *rsp_els;
>   	struct abts_entry_24xx *abts_rsp;
> @@ -790,6 +766,76 @@ qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
>   	}
>   }
>   
> +struct purex_item *
> +qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size)
> +{
> +	struct purex_item *item = NULL;
> +	uint8_t item_hdr_size = sizeof(*item);
> +	uint8_t default_usable = 0;
> +
> +	if (size > QLA_DEFAULT_PAYLOAD_SIZE) {
> +		item = kzalloc(item_hdr_size +
> +		    (size - QLA_DEFAULT_PAYLOAD_SIZE), GFP_ATOMIC);
> +	} else {
> +		item = kzalloc(item_hdr_size, GFP_ATOMIC);
I thought GFP_ATOMICs are looked down upon as a last resort. This is 
replacing code that used GFP_KERNEL.

> +		default_usable = 1;
> +	}
> +	if (!item) {
> +		if (default_usable &&
> +		    (atomic_inc_return(&vha->default_item.in_use) == 1)) {
> +			item = &vha->default_item;
> +			goto initialize_purex_header;
> +		}
> +		ql_log(ql_log_warn, vha, 0x5092,
> +		       ">> Failed allocate purex list item.\n");
> +
> +		return NULL;
> +	}
> +
> +initialize_purex_header:
> +	item->vha = vha;
> +	item->size = size;
> +	return item;
> +}
> +
> +static void
> +qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
> +			 void (*process_item)(struct scsi_qla_host *vha,
> +					      struct purex_item *pkt))
> +{
> +	struct purex_list *list = &vha->purex_list;
> +	ulong flags;
> +
> +	pkt->process_item = process_item;
> +
> +	spin_lock_irqsave(&list->lock, flags);
> +	list_add_tail(&pkt->list, &list->head);
> +	spin_unlock_irqrestore(&list->lock, flags);
> +
> +	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
> +}
> +
> +/**
> + * qla24xx_copy_std_pkt() - Copy over purex ELS which is
> + * contained in a single IOCB.
> + * purex packet.
> + * @vha: SCSI driver HA context
> + * @pkt: ELS packet
> + */
> +struct purex_item
> +*qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
> +{
> +	struct purex_item *item;
> +
> +	item = qla24xx_alloc_purex_item(vha,
> +					QLA_DEFAULT_PAYLOAD_SIZE);
> +	if (!item)
> +		return item;
> +
> +	memcpy(&item->iocb, pkt, sizeof(item->iocb));
> +	return item;
> +}
> +
>   /**
>    * qla2x00_async_event() - Process aynchronous events.
>    * @vha: SCSI driver HA context
> @@ -3233,6 +3279,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_item *pure_item;
>   
>   	if (!ha->flags.fw_started)
>   		return;
> @@ -3284,8 +3331,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
>   			break;
>   		case ABTS_RECV_24XX:
>   			if (qla_ini_mode_enabled(vha)) {
> -				qla24xx_purex_iocb(vha, pkt,
> -				    qla24xx_process_abts);
> +				pure_item = qla24xx_copy_std_pkt(vha, pkt);
> +				if (!pure_item)
> +					break;
> +
> +				qla24xx_queue_purex_item(vha, pure_item,
> +							 qla24xx_process_abts);
>   				break;
>   			}
>   			if (IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
> @@ -3342,7 +3393,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
>   				    purex->els_frame_payload[3]);
>   				break;
>   			}
> -			qla24xx_purex_iocb(vha, pkt, qla24xx_process_purex_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;
>   		}
>   		default:
> diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
> index 9fd83d1bffe0..a1f899bb8c94 100644
> --- a/drivers/scsi/qla2xxx/qla_mbx.c
> +++ b/drivers/scsi/qla2xxx/qla_mbx.c
> @@ -59,6 +59,7 @@ static struct rom_cmd {
>   	{ MBC_IOCB_COMMAND_A64 },
>   	{ MBC_GET_ADAPTER_LOOP_ID },
>   	{ MBC_READ_SFP },
> +	{ MBC_SET_RNID_PARAMS },
>   	{ MBC_GET_RNID_PARAMS },
>   	{ MBC_GET_SET_ZIO_THRESHOLD },
>   };
> @@ -4867,6 +4868,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
>   	return rval;
>   }
>   
> +#define PUREX_CMD_COUNT	2
>   int
>   qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>   {
> @@ -4875,12 +4877,12 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>   	mbx_cmd_t *mcp = &mc;
>   	uint8_t *els_cmd_map;
>   	dma_addr_t els_cmd_map_dma;
> -	uint cmd_opcode = ELS_COMMAND_RDP;
> -	uint index = cmd_opcode / 8;
> -	uint bit = cmd_opcode % 8;
> +	uint cmd_opcode[PUREX_CMD_COUNT];
> +	uint i, index, purex_bit;
>   	struct qla_hw_data *ha = vha->hw;
>   
> -	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) && !IS_QLA27XX(ha))
> +	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) &&
> +	    !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
>   		return QLA_SUCCESS;
>   
>   	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197,
> @@ -4896,7 +4898,17 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>   
>   	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
>   
> -	els_cmd_map[index] |= 1 << bit;
> +	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
> +
> +	/* List of Purex ELS */
> +	cmd_opcode[0] = ELS_COMMAND_FPIN;
> +	cmd_opcode[1] = ELS_COMMAND_RDP;
need to deal with endianness on this assigment ?   8bit values going 
into a uint ?

> +
> +	for (i = 0; i < PUREX_CMD_COUNT; i++) {
> +		index = cmd_opcode[i] / 8;
> +		purex_bit = cmd_opcode[i] % 8;
> +		els_cmd_map[index] |= 1 << purex_bit;
> +	}
>   
>   	mcp->mb[0] = MBC_SET_RNID_PARAMS;
>   	mcp->mb[1] = RNID_TYPE_ELS_CMD << 8;
> diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
> index 382e1f977d01..007f39128dbf 100644
> --- a/drivers/scsi/qla2xxx/qla_os.c
> +++ b/drivers/scsi/qla2xxx/qla_os.c
> @@ -5891,10 +5891,12 @@ qla25xx_rdp_port_speed_currently(struct qla_hw_data *ha)
>    * vha:	SCSI qla host
>    * purex: RDP request received by HBA
>    */
> -void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
> +void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
> +			       struct purex_item *item)
>   {
>   	struct qla_hw_data *ha = vha->hw;
> -	struct purex_entry_24xx *purex = pkt;
> +	struct purex_entry_24xx *purex =
> +	    (struct purex_entry_24xx *)&item->iocb;
>   	dma_addr_t rsp_els_dma;
>   	dma_addr_t rsp_payload_dma;
>   	dma_addr_t stat_dma;
> @@ -6304,6 +6306,15 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
>   		    rsp_els, rsp_els_dma);
>   }
>   
> +void
> +qla24xx_free_purex_item(struct purex_item *item)
> +{
> +	if (item == &item->vha->default_item)
> +		memset(&item->vha->default_item, 0, sizeof(struct purex_item));
> +	else
> +		kfree(item);
> +}
> +
>   void qla24xx_process_purex_list(struct purex_list *list)
>   {
>   	struct list_head head = LIST_HEAD_INIT(head);
> @@ -6316,8 +6327,8 @@ void qla24xx_process_purex_list(struct purex_list *list)
>   
>   	list_for_each_entry_safe(item, next, &head, list) {
>   		list_del(&item->list);
> -		item->process_item(item->vha, &item->iocb);
> -		kfree(item);
> +		item->process_item(item->vha, item);
> +		qla24xx_free_purex_item(item);
>   	}
>   }
>   
> diff --git a/include/uapi/scsi/fc/fc_els.h b/include/uapi/scsi/fc/fc_els.h
> index 66318c44acd7..cb7ffc37c4f9 100644
> --- a/include/uapi/scsi/fc/fc_els.h
> +++ b/include/uapi/scsi/fc/fc_els.h
> @@ -41,6 +41,7 @@ enum fc_els_cmd {
>   	ELS_REC =	0x13,	/* read exchange concise */
>   	ELS_SRR =	0x14,	/* sequence retransmission request */
>   	ELS_FPIN =	0x16,	/* Fabric Performance Impact Notification */
> +	ELS_RDP =	0x18,	/* Read Diagnostic Parameters */
>   	ELS_RDF =	0x19,	/* Register Diagnostic Functions */
>   	ELS_PRLI =	0x20,	/* process login */
>   	ELS_PRLO =	0x21,	/* process logout */
you're missing the :
   [ELS_RDP] =    "RDP",                 \

line in the respective location of FC_ELS_CMDS_INIT

-- james


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/2] qla2xxx: SAN congestion management(SCM) implementation.
  2020-06-10 14:15 ` [PATCH v3 2/2] qla2xxx: SAN congestion management(SCM) implementation Nilesh Javali
  2020-06-25 14:38   ` Himanshu Madhani
@ 2020-06-25 23:42   ` James Smart
  1 sibling, 0 replies; 9+ messages in thread
From: James Smart @ 2020-06-25 23:42 UTC (permalink / raw)
  To: Nilesh Javali, martin.petersen; +Cc: linux-scsi, GR-QLogic-Storage-Upstream



On 6/10/2020 7:15 AM, Nilesh Javali wrote:
> 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.
> * 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>
>

Reviewed-by: James Smart <james.smart@broadcom.com>

-- james


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests.
  2020-06-25 23:38   ` James Smart
@ 2020-06-25 23:59     ` Shyam Sundar
  0 siblings, 0 replies; 9+ messages in thread
From: Shyam Sundar @ 2020-06-25 23:59 UTC (permalink / raw)
  To: James Smart
  Cc: Nilesh Javali, Martin K. Petersen, linux-scsi,
	GR-QLogic-Storage-Upstream

Thanks for the review James, response inline.

> On Jun 25, 2020, at 4:38 PM, James Smart <james.smart@broadcom.com> wrote:
> 
> 
> 
> On 6/10/2020 7:15 AM, Nilesh Javali wrote:
>> From: Shyam Sundar <ssundar@marvell.com>
>> 
>> SAN Congestion Management generates ELS pkts whose size
>> can vary, and be > 64 bytes. Change the purex
>> handling code to support non standard ELS pkt size.
>> 
>> Signed-off-by: Shyam Sundar <ssundar@marvell.com>
>> Signed-off-by: Arun Easi <aeasi@marvell.com>
>> Signed-off-by: Nilesh Javali <njavali@marvell.com>
>> Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
>> ---
>>  drivers/scsi/qla2xxx/qla_def.h |  20 +++++-
>>  drivers/scsi/qla2xxx/qla_gbl.h |   3 +-
>>  drivers/scsi/qla2xxx/qla_isr.c | 116 ++++++++++++++++++++++++---------
>>  drivers/scsi/qla2xxx/qla_mbx.c |  22 +++++--
>>  drivers/scsi/qla2xxx/qla_os.c  |  19 ++++--
>>  include/uapi/scsi/fc/fc_els.h  |   1 +
>>  6 files changed, 139 insertions(+), 42 deletions(-)
>> 
>> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
>> index 172ea4e5887d..2e058ac4fec7 100644
>> --- a/drivers/scsi/qla2xxx/qla_def.h
>> +++ b/drivers/scsi/qla2xxx/qla_def.h
>> @@ -34,6 +34,8 @@
>>  #include <scsi/scsi_transport_fc.h>
>>  #include <scsi/scsi_bsg_fc.h>
>>  +#include <uapi/scsi/fc/fc_els.h>
>> +
>>  /* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */
>>  typedef struct {
>>  	uint8_t domain;
>> @@ -1269,7 +1271,11 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
>>  #define RNID_TYPE_ASIC_TEMP	0xC
>>    #define ELS_CMD_MAP_SIZE	32
>> -#define ELS_COMMAND_RDP		0x18
>> +#define ELS_COMMAND_RDP		ELS_RDP
>> +/* Fabric Perf Impact Notification */
>> +#define ELS_COMMAND_FPIN	ELS_FPIN
>> +/* Read Diagnostic Functions */
>> +#define ELS_COMMAND_RDF		ELS_RDF
> 
> there shouldn't be a need for a new define for these. The native ELS_xxx define should be used.
Was doing this to maintain uniformity, but I see the point, will change this.
> 
>>    /*
>>   * Firmware state codes from get firmware state mailbox command
>> @@ -4487,10 +4493,19 @@ struct active_regions {
>>  #define QLA_SET_DATA_RATE_NOLR	1
>>  #define QLA_SET_DATA_RATE_LR	2 /* Set speed and initiate LR */
>>  +#define QLA_DEFAULT_PAYLOAD_SIZE	64
>> +/*
>> + * This item might be allocated with a size > sizeof(struct purex_item).
>> + * The "size" variable gives the size of the payload (which
>> + * is variable) starting at "iocb".
>> + */
>>  struct purex_item {
>>  	struct list_head list;
>>  	struct scsi_qla_host *vha;
>> -	void (*process_item)(struct scsi_qla_host *vha, void *pkt);
>> +	void (*process_item)(struct scsi_qla_host *vha,
>> +			     struct purex_item *pkt);
>> +	atomic_t in_use;
>> +	uint16_t size;
>>  	struct {
>>  		uint8_t iocb[64];
>>  	} iocb;
>> @@ -4690,6 +4705,7 @@ typedef struct scsi_qla_host {
>>  		struct list_head head;
>>  		spinlock_t lock;
>>  	} purex_list;
>> +	struct purex_item default_item;
>>    	struct name_list_extended gnl;
>>  	/* Count of active session/fcport */
>> diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
>> index f62b71e47581..54d82f7d478f 100644
>> --- a/drivers/scsi/qla2xxx/qla_gbl.h
>> +++ b/drivers/scsi/qla2xxx/qla_gbl.h
>> @@ -229,7 +229,8 @@ void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
>>  int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
>>  int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
>>  void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);
>> -void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt);
>> +void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
>> +			       struct purex_item *pkt);
>>    /*
>>   * Global Functions in qla_mid.c source file.
>> diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
>> index a9e8513e1cf1..401ce0023cd5 100644
>> --- a/drivers/scsi/qla2xxx/qla_isr.c
>> +++ b/drivers/scsi/qla2xxx/qla_isr.c
>> @@ -31,35 +31,11 @@ const char *const port_state_str[] = {
>>  	"ONLINE"
>>  };
>>  -static void qla24xx_purex_iocb(scsi_qla_host_t *vha, void *pkt,
>> -	void (*process_item)(struct scsi_qla_host *vha, void *pkt))
>> -{
>> -	struct purex_list *list = &vha->purex_list;
>> -	struct purex_item *item;
>> -	ulong flags;
>> -
>> -	item = kzalloc(sizeof(*item), GFP_KERNEL);
>> -	if (!item) {
>> -		ql_log(ql_log_warn, vha, 0x5092,
>> -		    ">> Failed allocate purex list item.\n");
>> -		return;
>> -	}
>> -
>> -	item->vha = vha;
>> -	item->process_item = process_item;
>> -	memcpy(&item->iocb, pkt, sizeof(item->iocb));
>> -
>> -	spin_lock_irqsave(&list->lock, flags);
>> -	list_add_tail(&item->list, &list->head);
>> -	spin_unlock_irqrestore(&list->lock, flags);
>> -
>> -	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
>> -}
>> -
>>  static void
>> -qla24xx_process_abts(struct scsi_qla_host *vha, void *pkt)
>> +qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
>>  {
>> -	struct abts_entry_24xx *abts = pkt;
>> +	struct abts_entry_24xx *abts =
>> +	    (struct abts_entry_24xx *)&pkt->iocb;
>>  	struct qla_hw_data *ha = vha->hw;
>>  	struct els_entry_24xx *rsp_els;
>>  	struct abts_entry_24xx *abts_rsp;
>> @@ -790,6 +766,76 @@ qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
>>  	}
>>  }
>>  +struct purex_item *
>> +qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size)
>> +{
>> +	struct purex_item *item = NULL;
>> +	uint8_t item_hdr_size = sizeof(*item);
>> +	uint8_t default_usable = 0;
>> +
>> +	if (size > QLA_DEFAULT_PAYLOAD_SIZE) {
>> +		item = kzalloc(item_hdr_size +
>> +		    (size - QLA_DEFAULT_PAYLOAD_SIZE), GFP_ATOMIC);
>> +	} else {
>> +		item = kzalloc(item_hdr_size, GFP_ATOMIC);
> I thought GFP_ATOMICs are looked down upon as a last resort. This is replacing code that used GFP_KERNEL.
The use of GFP_KERNEL was leading to a stack trace on some systems given that this is invoked thru the interrupt handler, hence the change. Given that the allocation is for a small size (64-128 bytes in general), and it has a short life, we went on to use the GFP_ATOMIC.
>> +		default_usable = 1;
>> +	}
>> +	if (!item) {
>> +		if (default_usable &&
>> +		    (atomic_inc_return(&vha->default_item.in_use) == 1)) {
>> +			item = &vha->default_item;
>> +			goto initialize_purex_header;
>> +		}
>> +		ql_log(ql_log_warn, vha, 0x5092,
>> +		       ">> Failed allocate purex list item.\n");
>> +
>> +		return NULL;
>> +	}
>> +
>> +initialize_purex_header:
>> +	item->vha = vha;
>> +	item->size = size;
>> +	return item;
>> +}
>> +
>> +static void
>> +qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
>> +			 void (*process_item)(struct scsi_qla_host *vha,
>> +					      struct purex_item *pkt))
>> +{
>> +	struct purex_list *list = &vha->purex_list;
>> +	ulong flags;
>> +
>> +	pkt->process_item = process_item;
>> +
>> +	spin_lock_irqsave(&list->lock, flags);
>> +	list_add_tail(&pkt->list, &list->head);
>> +	spin_unlock_irqrestore(&list->lock, flags);
>> +
>> +	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
>> +}
>> +
>> +/**
>> + * qla24xx_copy_std_pkt() - Copy over purex ELS which is
>> + * contained in a single IOCB.
>> + * purex packet.
>> + * @vha: SCSI driver HA context
>> + * @pkt: ELS packet
>> + */
>> +struct purex_item
>> +*qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
>> +{
>> +	struct purex_item *item;
>> +
>> +	item = qla24xx_alloc_purex_item(vha,
>> +					QLA_DEFAULT_PAYLOAD_SIZE);
>> +	if (!item)
>> +		return item;
>> +
>> +	memcpy(&item->iocb, pkt, sizeof(item->iocb));
>> +	return item;
>> +}
>> +
>>  /**
>>   * qla2x00_async_event() - Process aynchronous events.
>>   * @vha: SCSI driver HA context
>> @@ -3233,6 +3279,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_item *pure_item;
>>    	if (!ha->flags.fw_started)
>>  		return;
>> @@ -3284,8 +3331,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
>>  			break;
>>  		case ABTS_RECV_24XX:
>>  			if (qla_ini_mode_enabled(vha)) {
>> -				qla24xx_purex_iocb(vha, pkt,
>> -				    qla24xx_process_abts);
>> +				pure_item = qla24xx_copy_std_pkt(vha, pkt);
>> +				if (!pure_item)
>> +					break;
>> +
>> +				qla24xx_queue_purex_item(vha, pure_item,
>> +							 qla24xx_process_abts);
>>  				break;
>>  			}
>>  			if (IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
>> @@ -3342,7 +3393,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
>>  				    purex->els_frame_payload[3]);
>>  				break;
>>  			}
>> -			qla24xx_purex_iocb(vha, pkt, qla24xx_process_purex_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;
>>  		}
>>  		default:
>> diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
>> index 9fd83d1bffe0..a1f899bb8c94 100644
>> --- a/drivers/scsi/qla2xxx/qla_mbx.c
>> +++ b/drivers/scsi/qla2xxx/qla_mbx.c
>> @@ -59,6 +59,7 @@ static struct rom_cmd {
>>  	{ MBC_IOCB_COMMAND_A64 },
>>  	{ MBC_GET_ADAPTER_LOOP_ID },
>>  	{ MBC_READ_SFP },
>> +	{ MBC_SET_RNID_PARAMS },
>>  	{ MBC_GET_RNID_PARAMS },
>>  	{ MBC_GET_SET_ZIO_THRESHOLD },
>>  };
>> @@ -4867,6 +4868,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
>>  	return rval;
>>  }
>>  +#define PUREX_CMD_COUNT	2
>>  int
>>  qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>>  {
>> @@ -4875,12 +4877,12 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>>  	mbx_cmd_t *mcp = &mc;
>>  	uint8_t *els_cmd_map;
>>  	dma_addr_t els_cmd_map_dma;
>> -	uint cmd_opcode = ELS_COMMAND_RDP;
>> -	uint index = cmd_opcode / 8;
>> -	uint bit = cmd_opcode % 8;
>> +	uint cmd_opcode[PUREX_CMD_COUNT];
>> +	uint i, index, purex_bit;
>>  	struct qla_hw_data *ha = vha->hw;
>>  -	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) && !IS_QLA27XX(ha))
>> +	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) &&
>> +	    !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
>>  		return QLA_SUCCESS;
>>    	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197,
>> @@ -4896,7 +4898,17 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>>    	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
>>  -	els_cmd_map[index] |= 1 << bit;
>> +	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
>> +
>> +	/* List of Purex ELS */
>> +	cmd_opcode[0] = ELS_COMMAND_FPIN;
>> +	cmd_opcode[1] = ELS_COMMAND_RDP;
> need to deal with endianness on this assigment ?   8bit values going into a uint ?
Agree, will address.
>> +
>> +	for (i = 0; i < PUREX_CMD_COUNT; i++) {
>> +		index = cmd_opcode[i] / 8;
>> +		purex_bit = cmd_opcode[i] % 8;
>> +		els_cmd_map[index] |= 1 << purex_bit;
>> +	}
>>    	mcp->mb[0] = MBC_SET_RNID_PARAMS;
>>  	mcp->mb[1] = RNID_TYPE_ELS_CMD << 8;
>> diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
>> index 382e1f977d01..007f39128dbf 100644
>> --- a/drivers/scsi/qla2xxx/qla_os.c
>> +++ b/drivers/scsi/qla2xxx/qla_os.c
>> @@ -5891,10 +5891,12 @@ qla25xx_rdp_port_speed_currently(struct qla_hw_data *ha)
>>   * vha:	SCSI qla host
>>   * purex: RDP request received by HBA
>>   */
>> -void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
>> +void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
>> +			       struct purex_item *item)
>>  {
>>  	struct qla_hw_data *ha = vha->hw;
>> -	struct purex_entry_24xx *purex = pkt;
>> +	struct purex_entry_24xx *purex =
>> +	    (struct purex_entry_24xx *)&item->iocb;
>>  	dma_addr_t rsp_els_dma;
>>  	dma_addr_t rsp_payload_dma;
>>  	dma_addr_t stat_dma;
>> @@ -6304,6 +6306,15 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
>>  		    rsp_els, rsp_els_dma);
>>  }
>>  +void
>> +qla24xx_free_purex_item(struct purex_item *item)
>> +{
>> +	if (item == &item->vha->default_item)
>> +		memset(&item->vha->default_item, 0, sizeof(struct purex_item));
>> +	else
>> +		kfree(item);
>> +}
>> +
>>  void qla24xx_process_purex_list(struct purex_list *list)
>>  {
>>  	struct list_head head = LIST_HEAD_INIT(head);
>> @@ -6316,8 +6327,8 @@ void qla24xx_process_purex_list(struct purex_list *list)
>>    	list_for_each_entry_safe(item, next, &head, list) {
>>  		list_del(&item->list);
>> -		item->process_item(item->vha, &item->iocb);
>> -		kfree(item);
>> +		item->process_item(item->vha, item);
>> +		qla24xx_free_purex_item(item);
>>  	}
>>  }
>>  diff --git a/include/uapi/scsi/fc/fc_els.h b/include/uapi/scsi/fc/fc_els.h
>> index 66318c44acd7..cb7ffc37c4f9 100644
>> --- a/include/uapi/scsi/fc/fc_els.h
>> +++ b/include/uapi/scsi/fc/fc_els.h
>> @@ -41,6 +41,7 @@ enum fc_els_cmd {
>>  	ELS_REC =	0x13,	/* read exchange concise */
>>  	ELS_SRR =	0x14,	/* sequence retransmission request */
>>  	ELS_FPIN =	0x16,	/* Fabric Performance Impact Notification */
>> +	ELS_RDP =	0x18,	/* Read Diagnostic Parameters */
>>  	ELS_RDF =	0x19,	/* Register Diagnostic Functions */
>>  	ELS_PRLI =	0x20,	/* process login */
>>  	ELS_PRLO =	0x21,	/* process logout */
> you're missing the :
>   [ELS_RDP] =    "RDP",                 \
> 
> line in the respective location of FC_ELS_CMDS_INIT
Agree, will address.
> 
> -- james


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-06-25 23:59 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-10 14:15 [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support Nilesh Javali
2020-06-10 14:15 ` [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests Nilesh Javali
2020-06-25 23:38   ` James Smart
2020-06-25 23:59     ` Shyam Sundar
2020-06-10 14:15 ` [PATCH v3 2/2] qla2xxx: SAN congestion management(SCM) implementation Nilesh Javali
2020-06-25 14:38   ` Himanshu Madhani
2020-06-25 23:42   ` James Smart
2020-06-18 22:46 ` [PATCH v3 0/2] qla2xxx SAN Congestion Management (SCM) support Shyam Sundar
2020-06-25 16:29   ` James Smart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).