linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch
@ 2013-11-22 10:28 vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 1/8] qla4xxx: Added support for Diagnostics MBOX command vikas.chaudhary
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc; +Cc: linux-scsi, vikas.chaudhary, lalit.chandivade

From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>

James,

Please apply the following patches to the scsi tree at your earliest convenience.

These patches are on top of other qla4xxx patch posted on list here:
http://marc.info/?l=linux-scsi&m=138210321629250&w=2

Adheer Chandravanshi (4):
      scsi_transport_iscsi: Export ISCSI_PARAM_LOCAL_IPADDR attr for iscsi_connection
      libiscsi: Add local_ipaddr parameter in iscsi_conn struct
      qla4xxx: Add support for ISCSI_PARAM_LOCAL_IPADDR sysfs attr
      qla4xxx: Recreate chap data list during get chap operation

Lalit Chandivade (2):
      scsi_transport_iscsi: Add host statistics support
      qla4xxx: Add host statistics support

Vikas Chaudhary (2):
      qla4xxx: Added support for Diagnostics MBOX command
      qla4xxx: Update driver version to 5.04.00-k3

Thanks,
Vikas.

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

* [PATCH 1/8] qla4xxx: Added support for Diagnostics MBOX command
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
@ 2013-11-22 10:28 ` vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 2/8] scsi_transport_iscsi: Add host statistics support vikas.chaudhary
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc; +Cc: linux-scsi, vikas.chaudhary, lalit.chandivade

From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>

Added support for Diagnostics MBOX command via BSG Vendor
HST_VENDOR interface.
This command provides various tests for validating hardware
functionality.

Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
 drivers/scsi/qla4xxx/ql4_bsg.c  | 360 ++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/qla4xxx/ql4_bsg.h  |  13 ++
 drivers/scsi/qla4xxx/ql4_def.h  |   8 +
 drivers/scsi/qla4xxx/ql4_fw.h   |  14 +-
 drivers/scsi/qla4xxx/ql4_glbl.h |   2 +
 drivers/scsi/qla4xxx/ql4_isr.c  |  19 ++-
 drivers/scsi/qla4xxx/ql4_mbx.c  |  43 +++++
 drivers/scsi/qla4xxx/ql4_os.c   |   3 +
 8 files changed, 455 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_bsg.c b/drivers/scsi/qla4xxx/ql4_bsg.c
index cf8fdf1..04a0027 100644
--- a/drivers/scsi/qla4xxx/ql4_bsg.c
+++ b/drivers/scsi/qla4xxx/ql4_bsg.c
@@ -446,6 +446,363 @@ leave:
 	return rval;
 }
 
+static void ql4xxx_execute_diag_cmd(struct bsg_job *bsg_job)
+{
+	struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
+	struct scsi_qla_host *ha = to_qla_host(host);
+	struct iscsi_bsg_request *bsg_req = bsg_job->request;
+	struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
+	uint8_t *rsp_ptr = NULL;
+	uint32_t mbox_cmd[MBOX_REG_COUNT];
+	uint32_t mbox_sts[MBOX_REG_COUNT];
+	int status = QLA_ERROR;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
+
+	if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
+		ql4_printk(KERN_INFO, ha, "%s: Adapter reset in progress. Invalid Request\n",
+			   __func__);
+		bsg_reply->result = DID_ERROR << 16;
+		goto exit_diag_mem_test;
+	}
+
+	bsg_reply->reply_payload_rcv_len = 0;
+	memcpy(mbox_cmd, &bsg_req->rqst_data.h_vendor.vendor_cmd[1],
+	       sizeof(uint32_t) * MBOX_REG_COUNT);
+
+	DEBUG2(ql4_printk(KERN_INFO, ha,
+			  "%s: mbox_cmd: %08X %08X %08X %08X %08X %08X %08X %08X\n",
+			  __func__, mbox_cmd[0], mbox_cmd[1], mbox_cmd[2],
+			  mbox_cmd[3], mbox_cmd[4], mbox_cmd[5], mbox_cmd[6],
+			  mbox_cmd[7]));
+
+	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
+					 &mbox_sts[0]);
+
+	DEBUG2(ql4_printk(KERN_INFO, ha,
+			  "%s: mbox_sts: %08X %08X %08X %08X %08X %08X %08X %08X\n",
+			  __func__, mbox_sts[0], mbox_sts[1], mbox_sts[2],
+			  mbox_sts[3], mbox_sts[4], mbox_sts[5], mbox_sts[6],
+			  mbox_sts[7]));
+
+	if (status == QLA_SUCCESS)
+		bsg_reply->result = DID_OK << 16;
+	else
+		bsg_reply->result = DID_ERROR << 16;
+
+	/* Send mbox_sts to application */
+	bsg_job->reply_len = sizeof(struct iscsi_bsg_reply) + sizeof(mbox_sts);
+	rsp_ptr = ((uint8_t *)bsg_reply) + sizeof(struct iscsi_bsg_reply);
+	memcpy(rsp_ptr, mbox_sts, sizeof(mbox_sts));
+
+exit_diag_mem_test:
+	DEBUG2(ql4_printk(KERN_INFO, ha,
+			  "%s: bsg_reply->result = x%x, status = %s\n",
+			  __func__, bsg_reply->result, STATUS(status)));
+
+	bsg_job_done(bsg_job, bsg_reply->result,
+		     bsg_reply->reply_payload_rcv_len);
+}
+
+static int qla4_83xx_wait_for_loopback_config_comp(struct scsi_qla_host *ha,
+						   int wait_for_link)
+{
+	int status = QLA_SUCCESS;
+
+	if (!wait_for_completion_timeout(&ha->idc_comp, (IDC_COMP_TOV * HZ))) {
+		ql4_printk(KERN_INFO, ha, "%s: IDC Complete notification not received, Waiting for another %d timeout",
+			   __func__, ha->idc_extend_tmo);
+		if (ha->idc_extend_tmo) {
+			if (!wait_for_completion_timeout(&ha->idc_comp,
+						(ha->idc_extend_tmo * HZ))) {
+				ha->notify_idc_comp = 0;
+				ha->notify_link_up_comp = 0;
+				ql4_printk(KERN_WARNING, ha, "%s: IDC Complete notification not received",
+					   __func__);
+				status = QLA_ERROR;
+				goto exit_wait;
+			} else {
+				DEBUG2(ql4_printk(KERN_INFO, ha,
+						  "%s: IDC Complete notification received\n",
+						  __func__));
+			}
+		}
+	} else {
+		DEBUG2(ql4_printk(KERN_INFO, ha,
+				  "%s: IDC Complete notification received\n",
+				  __func__));
+	}
+	ha->notify_idc_comp = 0;
+
+	if (wait_for_link) {
+		if (!wait_for_completion_timeout(&ha->link_up_comp,
+						 (IDC_COMP_TOV * HZ))) {
+			ha->notify_link_up_comp = 0;
+			ql4_printk(KERN_WARNING, ha, "%s: LINK UP notification not received",
+				   __func__);
+			status = QLA_ERROR;
+			goto exit_wait;
+		} else {
+			DEBUG2(ql4_printk(KERN_INFO, ha,
+					  "%s: LINK UP notification received\n",
+					  __func__));
+		}
+		ha->notify_link_up_comp = 0;
+	}
+
+exit_wait:
+	return status;
+}
+
+static int qla4_83xx_pre_loopback_config(struct scsi_qla_host *ha,
+					 uint32_t *mbox_cmd)
+{
+	uint32_t config = 0;
+	int status = QLA_SUCCESS;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
+
+	status = qla4_83xx_get_port_config(ha, &config);
+	if (status != QLA_SUCCESS)
+		goto exit_pre_loopback_config;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Default port config=%08X\n",
+			  __func__, config));
+
+	if ((config & ENABLE_INTERNAL_LOOPBACK) ||
+	    (config & ENABLE_EXTERNAL_LOOPBACK)) {
+		ql4_printk(KERN_INFO, ha, "%s: Loopback diagnostics already in progress. Invalid requiest\n",
+			   __func__);
+		goto exit_pre_loopback_config;
+	}
+
+	if (mbox_cmd[1] == QL_DIAG_CMD_TEST_INT_LOOPBACK)
+		config |= ENABLE_INTERNAL_LOOPBACK;
+
+	if (mbox_cmd[1] == QL_DIAG_CMD_TEST_EXT_LOOPBACK)
+		config |= ENABLE_EXTERNAL_LOOPBACK;
+
+	config &= ~ENABLE_DCBX;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: New port config=%08X\n",
+			  __func__, config));
+
+	ha->notify_idc_comp = 1;
+	ha->notify_link_up_comp = 1;
+
+	/* get the link state */
+	qla4xxx_get_firmware_state(ha);
+
+	status = qla4_83xx_set_port_config(ha, &config);
+	if (status != QLA_SUCCESS) {
+		ha->notify_idc_comp = 0;
+		ha->notify_link_up_comp = 0;
+		goto exit_pre_loopback_config;
+	}
+exit_pre_loopback_config:
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: status = %s\n", __func__,
+			  STATUS(status)));
+	return status;
+}
+
+static int qla4_83xx_post_loopback_config(struct scsi_qla_host *ha,
+					  uint32_t *mbox_cmd)
+{
+	int status = QLA_SUCCESS;
+	uint32_t config = 0;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
+
+	status = qla4_83xx_get_port_config(ha, &config);
+	if (status != QLA_SUCCESS)
+		goto exit_post_loopback_config;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: port config=%08X\n", __func__,
+			  config));
+
+	if (mbox_cmd[1] == QL_DIAG_CMD_TEST_INT_LOOPBACK)
+		config &= ~ENABLE_INTERNAL_LOOPBACK;
+	else if (mbox_cmd[1] == QL_DIAG_CMD_TEST_EXT_LOOPBACK)
+		config &= ~ENABLE_EXTERNAL_LOOPBACK;
+
+	config |= ENABLE_DCBX;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha,
+			  "%s: Restore default port config=%08X\n", __func__,
+			  config));
+
+	ha->notify_idc_comp = 1;
+	if (ha->addl_fw_state & FW_ADDSTATE_LINK_UP)
+		ha->notify_link_up_comp = 1;
+
+	status = qla4_83xx_set_port_config(ha, &config);
+	if (status != QLA_SUCCESS) {
+		ql4_printk(KERN_INFO, ha, "%s: Scheduling adapter reset\n",
+			   __func__);
+		set_bit(DPC_RESET_HA, &ha->dpc_flags);
+		clear_bit(AF_LOOPBACK, &ha->flags);
+		goto exit_post_loopback_config;
+	}
+
+exit_post_loopback_config:
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: status = %s\n", __func__,
+			  STATUS(status)));
+	return status;
+}
+
+static void qla4xxx_execute_diag_loopback_cmd(struct bsg_job *bsg_job)
+{
+	struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
+	struct scsi_qla_host *ha = to_qla_host(host);
+	struct iscsi_bsg_request *bsg_req = bsg_job->request;
+	struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
+	uint8_t *rsp_ptr = NULL;
+	uint32_t mbox_cmd[MBOX_REG_COUNT];
+	uint32_t mbox_sts[MBOX_REG_COUNT];
+	int wait_for_link = 1;
+	int status = QLA_ERROR;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
+
+	bsg_reply->reply_payload_rcv_len = 0;
+
+	if (test_bit(AF_LOOPBACK, &ha->flags)) {
+		ql4_printk(KERN_INFO, ha, "%s: Loopback Diagnostics already in progress. Invalid Request\n",
+			   __func__);
+		bsg_reply->result = DID_ERROR << 16;
+		goto exit_loopback_cmd;
+	}
+
+	if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
+		ql4_printk(KERN_INFO, ha, "%s: Adapter reset in progress. Invalid Request\n",
+			   __func__);
+		bsg_reply->result = DID_ERROR << 16;
+		goto exit_loopback_cmd;
+	}
+
+	memcpy(mbox_cmd, &bsg_req->rqst_data.h_vendor.vendor_cmd[1],
+	       sizeof(uint32_t) * MBOX_REG_COUNT);
+
+	if (is_qla8032(ha) || is_qla8042(ha)) {
+		status = qla4_83xx_pre_loopback_config(ha, mbox_cmd);
+		if (status != QLA_SUCCESS) {
+			bsg_reply->result = DID_ERROR << 16;
+			goto exit_loopback_cmd;
+		}
+
+		status = qla4_83xx_wait_for_loopback_config_comp(ha,
+								 wait_for_link);
+		if (status != QLA_SUCCESS) {
+			bsg_reply->result = DID_TIME_OUT << 16;
+			goto restore;
+		}
+	}
+
+	DEBUG2(ql4_printk(KERN_INFO, ha,
+			  "%s: mbox_cmd: %08X %08X %08X %08X %08X %08X %08X %08X\n",
+			  __func__, mbox_cmd[0], mbox_cmd[1], mbox_cmd[2],
+			  mbox_cmd[3], mbox_cmd[4], mbox_cmd[5], mbox_cmd[6],
+			  mbox_cmd[7]));
+
+	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
+				&mbox_sts[0]);
+
+	if (status == QLA_SUCCESS)
+		bsg_reply->result = DID_OK << 16;
+	else
+		bsg_reply->result = DID_ERROR << 16;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha,
+			  "%s: mbox_sts: %08X %08X %08X %08X %08X %08X %08X %08X\n",
+			  __func__, mbox_sts[0], mbox_sts[1], mbox_sts[2],
+			  mbox_sts[3], mbox_sts[4], mbox_sts[5], mbox_sts[6],
+			  mbox_sts[7]));
+
+	/* Send mbox_sts to application */
+	bsg_job->reply_len = sizeof(struct iscsi_bsg_reply) + sizeof(mbox_sts);
+	rsp_ptr = ((uint8_t *)bsg_reply) + sizeof(struct iscsi_bsg_reply);
+	memcpy(rsp_ptr, mbox_sts, sizeof(mbox_sts));
+restore:
+	if (is_qla8032(ha) || is_qla8042(ha)) {
+		status = qla4_83xx_post_loopback_config(ha, mbox_cmd);
+		if (status != QLA_SUCCESS) {
+			bsg_reply->result = DID_ERROR << 16;
+			goto exit_loopback_cmd;
+		}
+
+		/* for pre_loopback_config() wait for LINK UP only
+		 * if PHY LINK is UP */
+		if (!(ha->addl_fw_state & FW_ADDSTATE_LINK_UP))
+			wait_for_link = 0;
+
+		status = qla4_83xx_wait_for_loopback_config_comp(ha,
+								 wait_for_link);
+		if (status != QLA_SUCCESS) {
+			bsg_reply->result = DID_TIME_OUT << 16;
+			goto exit_loopback_cmd;
+		}
+	}
+exit_loopback_cmd:
+	DEBUG2(ql4_printk(KERN_INFO, ha,
+			  "%s: bsg_reply->result = x%x, status = %s\n",
+			  __func__, bsg_reply->result, STATUS(status)));
+	bsg_job_done(bsg_job, bsg_reply->result,
+		     bsg_reply->reply_payload_rcv_len);
+}
+
+static int qla4xxx_execute_diag_test(struct bsg_job *bsg_job)
+{
+	struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
+	struct scsi_qla_host *ha = to_qla_host(host);
+	struct iscsi_bsg_request *bsg_req = bsg_job->request;
+	uint32_t diag_cmd;
+	int rval = -EINVAL;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
+
+	diag_cmd = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
+	if (diag_cmd == MBOX_CMD_DIAG_TEST) {
+		switch (bsg_req->rqst_data.h_vendor.vendor_cmd[2]) {
+		case QL_DIAG_CMD_TEST_DDR_SIZE:
+		case QL_DIAG_CMD_TEST_DDR_RW:
+		case QL_DIAG_CMD_TEST_ONCHIP_MEM_RW:
+		case QL_DIAG_CMD_TEST_NVRAM:
+		case QL_DIAG_CMD_TEST_FLASH_ROM:
+		case QL_DIAG_CMD_TEST_DMA_XFER:
+		case QL_DIAG_CMD_SELF_DDR_RW:
+		case QL_DIAG_CMD_SELF_ONCHIP_MEM_RW:
+			/* Execute diag test for adapter RAM/FLASH */
+			ql4xxx_execute_diag_cmd(bsg_job);
+			/* Always return success as we want to sent bsg_reply
+			 * to Application */
+			rval = QLA_SUCCESS;
+			break;
+
+		case QL_DIAG_CMD_TEST_INT_LOOPBACK:
+		case QL_DIAG_CMD_TEST_EXT_LOOPBACK:
+			/* Execute diag test for Network */
+			qla4xxx_execute_diag_loopback_cmd(bsg_job);
+			/* Always return success as we want to sent bsg_reply
+			 * to Application */
+			rval = QLA_SUCCESS;
+			break;
+		default:
+			ql4_printk(KERN_ERR, ha, "%s: Invalid diag test: 0x%x\n",
+				   __func__,
+				   bsg_req->rqst_data.h_vendor.vendor_cmd[2]);
+		}
+	} else if ((diag_cmd == MBOX_CMD_SET_LED_CONFIG) ||
+		   (diag_cmd == MBOX_CMD_GET_LED_CONFIG)) {
+		ql4xxx_execute_diag_cmd(bsg_job);
+		rval = QLA_SUCCESS;
+	} else {
+		ql4_printk(KERN_ERR, ha, "%s: Invalid diag cmd: 0x%x\n",
+			   __func__, diag_cmd);
+	}
+
+	return rval;
+}
+
 /**
  * qla4xxx_process_vendor_specific - handle vendor specific bsg request
  * @job: iscsi_bsg_job to handle
@@ -479,6 +836,9 @@ int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job)
 	case QLISCSI_VND_GET_ACB:
 		return qla4xxx_bsg_get_acb(bsg_job);
 
+	case QLISCSI_VND_DIAG_TEST:
+		return qla4xxx_execute_diag_test(bsg_job);
+
 	default:
 		ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: "
 			   "0x%x\n", __func__, bsg_req->msgcode);
diff --git a/drivers/scsi/qla4xxx/ql4_bsg.h b/drivers/scsi/qla4xxx/ql4_bsg.h
index c6a03645..88c2401 100644
--- a/drivers/scsi/qla4xxx/ql4_bsg.h
+++ b/drivers/scsi/qla4xxx/ql4_bsg.h
@@ -15,5 +15,18 @@
 #define QLISCSI_VND_UPDATE_NVRAM	5
 #define QLISCSI_VND_RESTORE_DEFAULTS	6
 #define QLISCSI_VND_GET_ACB		7
+#define QLISCSI_VND_DIAG_TEST		8
+
+/* QLISCSI_VND_DIAG_CMD sub code */
+#define QL_DIAG_CMD_TEST_DDR_SIZE	0x2
+#define QL_DIAG_CMD_TEST_DDR_RW		0x3
+#define QL_DIAG_CMD_TEST_ONCHIP_MEM_RW	0x4
+#define QL_DIAG_CMD_TEST_NVRAM		0x5	/* Only ISP4XXX */
+#define QL_DIAG_CMD_TEST_FLASH_ROM	0x6
+#define QL_DIAG_CMD_TEST_INT_LOOPBACK	0x7
+#define QL_DIAG_CMD_TEST_EXT_LOOPBACK	0x8
+#define QL_DIAG_CMD_TEST_DMA_XFER	0x9	/* Only ISP4XXX */
+#define QL_DIAG_CMD_SELF_DDR_RW		0xC
+#define QL_DIAG_CMD_SELF_ONCHIP_MEM_RW	0xD
 
 #endif
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index e2be308..aa67bb9 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -73,6 +73,7 @@
 
 #define QLA_SUCCESS			0
 #define QLA_ERROR			1
+#define STATUS(status)		status == QLA_ERROR ? "FAILED" : "SUCCEEDED"
 
 /*
  * Data bit definitions
@@ -210,6 +211,8 @@
 #define MAX_RESET_HA_RETRIES		2
 #define FW_ALIVE_WAIT_TOV		3
 #define IDC_EXTEND_TOV			8
+#define IDC_COMP_TOV			5
+#define LINK_UP_COMP_TOV		30
 
 #define CMD_SP(Cmnd)			((Cmnd)->SCp.ptr)
 
@@ -822,6 +825,11 @@ struct scsi_qla_host {
 	uint32_t pf_bit;
 	struct qla4_83xx_idc_information idc_info;
 	struct addr_ctrl_blk *saved_acb;
+	int notify_idc_comp;
+	int notify_link_up_comp;
+	int idc_extend_tmo;
+	struct completion idc_comp;
+	struct completion link_up_comp;
 };
 
 struct ql4_task_data {
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 3060652..fef311d 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -410,6 +410,7 @@ struct qla_flt_region {
 #define DDB_DS_LOGIN_IN_PROCESS			0x07
 #define MBOX_CMD_GET_FW_STATE			0x0069
 #define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK_DEFAULTS 0x006A
+#define MBOX_CMD_DIAG_TEST			0x0075
 #define MBOX_CMD_GET_SYS_INFO			0x0078
 #define MBOX_CMD_GET_NVRAM			0x0078	/* For 40xx */
 #define MBOX_CMD_SET_NVRAM			0x0079	/* For 40xx */
@@ -425,8 +426,17 @@ struct qla_flt_region {
 #define MBOX_CMD_GET_IP_ADDR_STATE		0x0091
 #define MBOX_CMD_SEND_IPV6_ROUTER_SOL		0x0092
 #define MBOX_CMD_GET_DB_ENTRY_CURRENT_IP_ADDR	0x0093
+#define MBOX_CMD_SET_PORT_CONFIG		0x0122
+#define MBOX_CMD_GET_PORT_CONFIG		0x0123
+#define MBOX_CMD_SET_LED_CONFIG			0x0125
+#define MBOX_CMD_GET_LED_CONFIG			0x0126
 #define MBOX_CMD_MINIDUMP			0x0129
 
+/* Port Config */
+#define ENABLE_INTERNAL_LOOPBACK		0x04
+#define ENABLE_EXTERNAL_LOOPBACK		0x08
+#define ENABLE_DCBX				0x10
+
 /* Minidump subcommand */
 #define MINIDUMP_GET_SIZE_SUBCOMMAND		0x00
 #define MINIDUMP_GET_TMPLT_SUBCOMMAND		0x01
@@ -535,10 +545,6 @@ struct qla_flt_region {
 #define FLASH_OPT_COMMIT	2
 #define FLASH_OPT_RMW_COMMIT	3
 
-/* Loopback type */
-#define ENABLE_INTERNAL_LOOPBACK	0x04
-#define ENABLE_EXTERNAL_LOOPBACK	0x08
-
 /* generic defines to enable/disable params */
 #define QL4_PARAM_DISABLE	0
 #define QL4_PARAM_ENABLE	1
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index b8e87b3..d67c50e 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -277,6 +277,8 @@ int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config);
 int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha,
 				uint64_t addr, uint32_t *data, uint32_t count);
 uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state);
+int qla4_83xx_get_port_config(struct scsi_qla_host *ha, uint32_t *config);
+int qla4_83xx_set_port_config(struct scsi_qla_host *ha, uint32_t *config);
 
 extern int ql4xextended_error_logging;
 extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 66cc9c1..a3c8bc7 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -650,6 +650,7 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 	int i;
 	uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
 	__le32 __iomem *mailbox_out;
+	uint32_t opcode = 0;
 
 	if (is_qla8032(ha) || is_qla8042(ha))
 		mailbox_out = &ha->qla4_83xx_reg->mailbox_out[0];
@@ -728,6 +729,11 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 			qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKUP,
 					      sizeof(mbox_sts),
 					      (uint8_t *) mbox_sts);
+
+			if ((is_qla8032(ha) || is_qla8042(ha)) &&
+			    ha->notify_link_up_comp)
+				complete(&ha->link_up_comp);
+
 			break;
 
 		case MBOX_ASTS_LINK_DOWN:
@@ -873,8 +879,6 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 			break;
 
 		case MBOX_ASTS_IDC_REQUEST_NOTIFICATION:
-		{
-			uint32_t opcode;
 			if (is_qla8032(ha) || is_qla8042(ha)) {
 				DEBUG2(ql4_printk(KERN_INFO, ha,
 						  "scsi%ld: AEN %04x, mbox_sts[1]=%08x, mbox_sts[2]=%08x, mbox_sts[3]=%08x, mbox_sts[4]=%08x\n",
@@ -894,7 +898,6 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 				}
 			}
 			break;
-		}
 
 		case MBOX_ASTS_IDC_COMPLETE:
 			if (is_qla8032(ha) || is_qla8042(ha)) {
@@ -907,6 +910,14 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 						  "scsi:%ld: AEN %04x IDC Complete notification\n",
 						  ha->host_no, mbox_sts[0]));
 
+				opcode = mbox_sts[1] >> 16;
+				if (ha->notify_idc_comp)
+					complete(&ha->idc_comp);
+
+				if ((opcode == MBOX_CMD_SET_PORT_CONFIG) ||
+				    (opcode == MBOX_CMD_PORT_RESET))
+					ha->idc_info.info2 = mbox_sts[3];
+
 				if (qla4_83xx_loopback_in_progress(ha)) {
 					set_bit(AF_LOOPBACK, &ha->flags);
 				} else {
@@ -939,6 +950,8 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 			DEBUG2(ql4_printk(KERN_INFO, ha,
 					  "scsi%ld: AEN %04x Received IDC Extend Timeout notification\n",
 					  ha->host_no, mbox_sts[0]));
+			/* new IDC timeout */
+			ha->idc_extend_tmo = mbox_sts[1];
 			break;
 
 		case MBOX_ASTS_INITIALIZATION_FAILED:
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 3c0ea1e..7da0646 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -2416,3 +2416,46 @@ exit_config_acb:
 			  rval == QLA_SUCCESS ? "SUCCEEDED" : "FAILED"));
 	return rval;
 }
+
+int qla4_83xx_get_port_config(struct scsi_qla_host *ha, uint32_t *config)
+{
+	uint32_t mbox_cmd[MBOX_REG_COUNT];
+	uint32_t mbox_sts[MBOX_REG_COUNT];
+	int status;
+
+	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+	memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+	mbox_cmd[0] = MBOX_CMD_GET_PORT_CONFIG;
+
+	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
+					 mbox_cmd, mbox_sts);
+	if (status == QLA_SUCCESS)
+		*config = mbox_sts[1];
+	else
+		ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,
+			   mbox_sts[0]);
+
+	return status;
+}
+
+int qla4_83xx_set_port_config(struct scsi_qla_host *ha, uint32_t *config)
+{
+	uint32_t mbox_cmd[MBOX_REG_COUNT];
+	uint32_t mbox_sts[MBOX_REG_COUNT];
+	int status;
+
+	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+	memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+	mbox_cmd[0] = MBOX_CMD_SET_PORT_CONFIG;
+	mbox_cmd[1] = *config;
+
+	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
+				mbox_cmd, mbox_sts);
+	if (status != QLA_SUCCESS)
+		ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,
+			   mbox_sts[0]);
+
+	return status;
+}
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index da9fdcc..60d050e 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -8397,6 +8397,9 @@ static int qla4xxx_probe_adapter(struct pci_dev *pdev,
 	mutex_init(&ha->chap_sem);
 	init_completion(&ha->mbx_intr_comp);
 	init_completion(&ha->disable_acb_comp);
+	init_completion(&ha->idc_comp);
+	init_completion(&ha->link_up_comp);
+	init_completion(&ha->disable_acb_comp);
 
 	spin_lock_init(&ha->hardware_lock);
 	spin_lock_init(&ha->work_lock);
-- 
1.8.2.GIT


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

* [PATCH 2/8] scsi_transport_iscsi: Add host statistics support
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 1/8] qla4xxx: Added support for Diagnostics MBOX command vikas.chaudhary
@ 2013-11-22 10:28 ` vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 3/8] qla4xxx: " vikas.chaudhary
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc; +Cc: linux-scsi, vikas.chaudhary, lalit.chandivade

From: Lalit Chandivade <lalit.chandivade@qlogic.com>

Add transport_iscsi hooks to get aggregate host statistics.
The statistics include MAC, TCP/IP & iSCSI statistics.

Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
 drivers/scsi/scsi_transport_iscsi.c |  70 ++++++++++++++++++++++
 include/scsi/iscsi_if.h             | 112 ++++++++++++++++++++++++++++++++++++
 include/scsi/scsi_transport_iscsi.h |   1 +
 3 files changed, 183 insertions(+)

diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 9477f84..4cf918a 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3416,6 +3416,73 @@ exit_logout_sid:
 }
 
 static int
+iscsi_get_host_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
+{
+	struct iscsi_uevent *ev = nlmsg_data(nlh);
+	struct Scsi_Host *shost = NULL;
+	struct iscsi_internal *priv;
+	struct sk_buff *skbhost_stats;
+	struct nlmsghdr *nlhhost_stats;
+	struct iscsi_uevent *evhost_stats;
+	int host_stats_size = 0;
+	int len, err = 0;
+	char *buf;
+
+	if (!transport->get_host_stats)
+		return -EINVAL;
+
+	priv = iscsi_if_transport_lookup(transport);
+	if (!priv)
+		return -EINVAL;
+
+	host_stats_size = sizeof(struct iscsi_offload_host_stats);
+	len = nlmsg_total_size(sizeof(*ev) + host_stats_size);
+
+	shost = scsi_host_lookup(ev->u.get_host_stats.host_no);
+	if (!shost) {
+		pr_err("%s: failed. Cound not find host no %u\n",
+		       __func__, ev->u.get_host_stats.host_no);
+		return -ENODEV;
+	}
+
+	do {
+		int actual_size;
+
+		skbhost_stats = alloc_skb(len, GFP_KERNEL);
+		if (!skbhost_stats) {
+			pr_err("cannot deliver host stats: OOM\n");
+			err = -ENOMEM;
+			goto exit_host_stats;
+		}
+
+		nlhhost_stats = __nlmsg_put(skbhost_stats, 0, 0, 0,
+				      (len - sizeof(*nlhhost_stats)), 0);
+		evhost_stats = nlmsg_data(nlhhost_stats);
+		memset(evhost_stats, 0, sizeof(*evhost_stats));
+		evhost_stats->transport_handle = iscsi_handle(transport);
+		evhost_stats->type = nlh->nlmsg_type;
+		evhost_stats->u.get_host_stats.host_no =
+					ev->u.get_host_stats.host_no;
+		buf = (char *)((char *)evhost_stats + sizeof(*evhost_stats));
+		memset(buf, 0, host_stats_size);
+
+		err = transport->get_host_stats(shost, buf, host_stats_size);
+
+		actual_size = nlmsg_total_size(sizeof(*ev) + host_stats_size);
+		skb_trim(skbhost_stats, NLMSG_ALIGN(actual_size));
+		nlhhost_stats->nlmsg_len = actual_size;
+
+		err = iscsi_multicast_skb(skbhost_stats, ISCSI_NL_GRP_ISCSID,
+					  GFP_KERNEL);
+	} while (err < 0 && err != -ECONNREFUSED);
+
+exit_host_stats:
+	scsi_host_put(shost);
+	return err;
+}
+
+
+static int
 iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 {
 	int err = 0;
@@ -3594,6 +3661,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 		err = iscsi_set_chap(transport, ev,
 				     nlmsg_attrlen(nlh, sizeof(*ev)));
 		break;
+	case ISCSI_UEVENT_GET_HOST_STATS:
+		err = iscsi_get_host_stats(transport, nlh);
+		break;
 	default:
 		err = -ENOSYS;
 		break;
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index a572083..3851a73 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -70,6 +70,7 @@ enum iscsi_uevent_e {
 	ISCSI_UEVENT_LOGOUT_FLASHNODE	= UEVENT_BASE + 29,
 	ISCSI_UEVENT_LOGOUT_FLASHNODE_SID	= UEVENT_BASE + 30,
 	ISCSI_UEVENT_SET_CHAP		= UEVENT_BASE + 31,
+	ISCSI_UEVENT_GET_HOST_STATS	= UEVENT_BASE + 32,
 
 	/* up events */
 	ISCSI_KEVENT_RECV_PDU		= KEVENT_BASE + 1,
@@ -242,6 +243,9 @@ struct iscsi_uevent {
 			uint32_t	host_no;
 			uint32_t	sid;
 		} logout_flashnode_sid;
+		struct msg_get_host_stats {
+			uint32_t host_no;
+		} get_host_stats;
 	} u;
 	union {
 		/* messages k -> u */
@@ -845,4 +849,112 @@ struct iscsi_chap_rec {
 	uint8_t password_length;
 };
 
+#define ISCSI_HOST_STATS_CUSTOM_MAX             32
+#define ISCSI_HOST_STATS_CUSTOM_DESC_MAX        64
+struct iscsi_host_stats_custom {
+	char desc[ISCSI_HOST_STATS_CUSTOM_DESC_MAX];
+	uint64_t value;
+};
+
+/* struct iscsi_offload_host_stats: Host statistics,
+ * Include statistics for MAC, IP, TCP & iSCSI.
+ */
+struct iscsi_offload_host_stats {
+	/* MAC */
+	uint64_t mactx_frames;
+	uint64_t mactx_bytes;
+	uint64_t mactx_multicast_frames;
+	uint64_t mactx_broadcast_frames;
+	uint64_t mactx_pause_frames;
+	uint64_t mactx_control_frames;
+	uint64_t mactx_deferral;
+	uint64_t mactx_excess_deferral;
+	uint64_t mactx_late_collision;
+	uint64_t mactx_abort;
+	uint64_t mactx_single_collision;
+	uint64_t mactx_multiple_collision;
+	uint64_t mactx_collision;
+	uint64_t mactx_frames_dropped;
+	uint64_t mactx_jumbo_frames;
+	uint64_t macrx_frames;
+	uint64_t macrx_bytes;
+	uint64_t macrx_unknown_control_frames;
+	uint64_t macrx_pause_frames;
+	uint64_t macrx_control_frames;
+	uint64_t macrx_dribble;
+	uint64_t macrx_frame_length_error;
+	uint64_t macrx_jabber;
+	uint64_t macrx_carrier_sense_error;
+	uint64_t macrx_frame_discarded;
+	uint64_t macrx_frames_dropped;
+	uint64_t mac_crc_error;
+	uint64_t mac_encoding_error;
+	uint64_t macrx_length_error_large;
+	uint64_t macrx_length_error_small;
+	uint64_t macrx_multicast_frames;
+	uint64_t macrx_broadcast_frames;
+	/* IP */
+	uint64_t iptx_packets;
+	uint64_t iptx_bytes;
+	uint64_t iptx_fragments;
+	uint64_t iprx_packets;
+	uint64_t iprx_bytes;
+	uint64_t iprx_fragments;
+	uint64_t ip_datagram_reassembly;
+	uint64_t ip_invalid_address_error;
+	uint64_t ip_error_packets;
+	uint64_t ip_fragrx_overlap;
+	uint64_t ip_fragrx_outoforder;
+	uint64_t ip_datagram_reassembly_timeout;
+	uint64_t ipv6tx_packets;
+	uint64_t ipv6tx_bytes;
+	uint64_t ipv6tx_fragments;
+	uint64_t ipv6rx_packets;
+	uint64_t ipv6rx_bytes;
+	uint64_t ipv6rx_fragments;
+	uint64_t ipv6_datagram_reassembly;
+	uint64_t ipv6_invalid_address_error;
+	uint64_t ipv6_error_packets;
+	uint64_t ipv6_fragrx_overlap;
+	uint64_t ipv6_fragrx_outoforder;
+	uint64_t ipv6_datagram_reassembly_timeout;
+	/* TCP */
+	uint64_t tcptx_segments;
+	uint64_t tcptx_bytes;
+	uint64_t tcprx_segments;
+	uint64_t tcprx_byte;
+	uint64_t tcp_duplicate_ack_retx;
+	uint64_t tcp_retx_timer_expired;
+	uint64_t tcprx_duplicate_ack;
+	uint64_t tcprx_pure_ackr;
+	uint64_t tcptx_delayed_ack;
+	uint64_t tcptx_pure_ack;
+	uint64_t tcprx_segment_error;
+	uint64_t tcprx_segment_outoforder;
+	uint64_t tcprx_window_probe;
+	uint64_t tcprx_window_update;
+	uint64_t tcptx_window_probe_persist;
+	/* ECC */
+	uint64_t ecc_error_correction;
+	/* iSCSI */
+	uint64_t iscsi_pdu_tx;
+	uint64_t iscsi_data_bytes_tx;
+	uint64_t iscsi_pdu_rx;
+	uint64_t iscsi_data_bytes_rx;
+	uint64_t iscsi_io_completed;
+	uint64_t iscsi_unexpected_io_rx;
+	uint64_t iscsi_format_error;
+	uint64_t iscsi_hdr_digest_error;
+	uint64_t iscsi_data_digest_error;
+	uint64_t iscsi_sequence_error;
+	/*
+	 * iSCSI Custom Host Statistics support, i.e. Transport could
+	 * extend existing host statistics with its own specific statistics
+	 * up to ISCSI_HOST_STATS_CUSTOM_MAX
+	 */
+	uint32_t custom_length;
+	struct iscsi_host_stats_custom custom[0]
+		__aligned(sizeof(uint64_t));
+};
+
 #endif
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 2ac11fe..88640a4 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -166,6 +166,7 @@ struct iscsi_transport {
 	int (*logout_flashnode) (struct iscsi_bus_flash_session *fnode_sess,
 				 struct iscsi_bus_flash_conn *fnode_conn);
 	int (*logout_flashnode_sid) (struct iscsi_cls_session *cls_sess);
+	int (*get_host_stats) (struct Scsi_Host *shost, char *buf, int len);
 };
 
 /*
-- 
1.8.2.GIT


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

* [PATCH 3/8] qla4xxx: Add host statistics support
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 1/8] qla4xxx: Added support for Diagnostics MBOX command vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 2/8] scsi_transport_iscsi: Add host statistics support vikas.chaudhary
@ 2013-11-22 10:28 ` vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 4/8] scsi_transport_iscsi: Export ISCSI_PARAM_LOCAL_IPADDR attr for iscsi_connection vikas.chaudhary
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc; +Cc: linux-scsi, vikas.chaudhary, lalit.chandivade

From: Lalit Chandivade <lalit.chandivade@qlogic.com>

The statistics include MAC, TCP/IP & iSCSI statistics.

Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
 drivers/scsi/qla4xxx/ql4_fw.h |  83 ++++++++++++++++-
 drivers/scsi/qla4xxx/ql4_os.c | 205 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 287 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index fef311d..8d4092b 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -1297,7 +1297,88 @@ struct response {
 };
 
 struct ql_iscsi_stats {
-	uint8_t reserved1[656]; /* 0000-028F */
+	uint64_t mac_tx_frames; /* 0000–0007 */
+	uint64_t mac_tx_bytes; /* 0008–000F */
+	uint64_t mac_tx_multicast_frames; /* 0010–0017 */
+	uint64_t mac_tx_broadcast_frames; /* 0018–001F */
+	uint64_t mac_tx_pause_frames; /* 0020–0027 */
+	uint64_t mac_tx_control_frames; /* 0028–002F */
+	uint64_t mac_tx_deferral; /* 0030–0037 */
+	uint64_t mac_tx_excess_deferral; /* 0038–003F */
+	uint64_t mac_tx_late_collision; /* 0040–0047 */
+	uint64_t mac_tx_abort; /* 0048–004F */
+	uint64_t mac_tx_single_collision; /* 0050–0057 */
+	uint64_t mac_tx_multiple_collision; /* 0058–005F */
+	uint64_t mac_tx_collision; /* 0060–0067 */
+	uint64_t mac_tx_frames_dropped; /* 0068–006F */
+	uint64_t mac_tx_jumbo_frames; /* 0070–0077 */
+	uint64_t mac_rx_frames; /* 0078–007F */
+	uint64_t mac_rx_bytes; /* 0080–0087 */
+	uint64_t mac_rx_unknown_control_frames; /* 0088–008F */
+	uint64_t mac_rx_pause_frames; /* 0090–0097 */
+	uint64_t mac_rx_control_frames; /* 0098–009F */
+	uint64_t mac_rx_dribble; /* 00A0–00A7 */
+	uint64_t mac_rx_frame_length_error; /* 00A8–00AF */
+	uint64_t mac_rx_jabber; /* 00B0–00B7 */
+	uint64_t mac_rx_carrier_sense_error; /* 00B8–00BF */
+	uint64_t mac_rx_frame_discarded; /* 00C0–00C7 */
+	uint64_t mac_rx_frames_dropped; /* 00C8–00CF */
+	uint64_t mac_crc_error; /* 00D0–00D7 */
+	uint64_t mac_encoding_error; /* 00D8–00DF */
+	uint64_t mac_rx_length_error_large; /* 00E0–00E7 */
+	uint64_t mac_rx_length_error_small; /* 00E8–00EF */
+	uint64_t mac_rx_multicast_frames; /* 00F0–00F7 */
+	uint64_t mac_rx_broadcast_frames; /* 00F8–00FF */
+	uint64_t ip_tx_packets; /* 0100–0107 */
+	uint64_t ip_tx_bytes; /* 0108–010F */
+	uint64_t ip_tx_fragments; /* 0110–0117 */
+	uint64_t ip_rx_packets; /* 0118–011F */
+	uint64_t ip_rx_bytes; /* 0120–0127 */
+	uint64_t ip_rx_fragments; /* 0128–012F */
+	uint64_t ip_datagram_reassembly; /* 0130–0137 */
+	uint64_t ip_invalid_address_error; /* 0138–013F */
+	uint64_t ip_error_packets; /* 0140–0147 */
+	uint64_t ip_fragrx_overlap; /* 0148–014F */
+	uint64_t ip_fragrx_outoforder; /* 0150–0157 */
+	uint64_t ip_datagram_reassembly_timeout; /* 0158–015F */
+	uint64_t ipv6_tx_packets; /* 0160–0167 */
+	uint64_t ipv6_tx_bytes; /* 0168–016F */
+	uint64_t ipv6_tx_fragments; /* 0170–0177 */
+	uint64_t ipv6_rx_packets; /* 0178–017F */
+	uint64_t ipv6_rx_bytes; /* 0180–0187 */
+	uint64_t ipv6_rx_fragments; /* 0188–018F */
+	uint64_t ipv6_datagram_reassembly; /* 0190–0197 */
+	uint64_t ipv6_invalid_address_error; /* 0198–019F */
+	uint64_t ipv6_error_packets; /* 01A0–01A7 */
+	uint64_t ipv6_fragrx_overlap; /* 01A8–01AF */
+	uint64_t ipv6_fragrx_outoforder; /* 01B0–01B7 */
+	uint64_t ipv6_datagram_reassembly_timeout; /* 01B8–01BF */
+	uint64_t tcp_tx_segments; /* 01C0–01C7 */
+	uint64_t tcp_tx_bytes; /* 01C8–01CF */
+	uint64_t tcp_rx_segments; /* 01D0–01D7 */
+	uint64_t tcp_rx_byte; /* 01D8–01DF */
+	uint64_t tcp_duplicate_ack_retx; /* 01E0–01E7 */
+	uint64_t tcp_retx_timer_expired; /* 01E8–01EF */
+	uint64_t tcp_rx_duplicate_ack; /* 01F0–01F7 */
+	uint64_t tcp_rx_pure_ackr; /* 01F8–01FF */
+	uint64_t tcp_tx_delayed_ack; /* 0200–0207 */
+	uint64_t tcp_tx_pure_ack; /* 0208–020F */
+	uint64_t tcp_rx_segment_error; /* 0210–0217 */
+	uint64_t tcp_rx_segment_outoforder; /* 0218–021F */
+	uint64_t tcp_rx_window_probe; /* 0220–0227 */
+	uint64_t tcp_rx_window_update; /* 0228–022F */
+	uint64_t tcp_tx_window_probe_persist; /* 0230–0237 */
+	uint64_t ecc_error_correction; /* 0238–023F */
+	uint64_t iscsi_pdu_tx; /* 0240-0247 */
+	uint64_t iscsi_data_bytes_tx; /* 0248-024F */
+	uint64_t iscsi_pdu_rx; /* 0250-0257 */
+	uint64_t iscsi_data_bytes_rx; /* 0258-025F */
+	uint64_t iscsi_io_completed; /* 0260-0267 */
+	uint64_t iscsi_unexpected_io_rx; /* 0268-026F */
+	uint64_t iscsi_format_error; /* 0270-0277 */
+	uint64_t iscsi_hdr_digest_error; /* 0278-027F */
+	uint64_t iscsi_data_digest_error; /* 0280-0287 */
+	uint64_t iscsi_sequence_error; /* 0288-028F */
 	uint32_t tx_cmd_pdu; /* 0290-0293 */
 	uint32_t tx_resp_pdu; /* 0294-0297 */
 	uint32_t rx_cmd_pdu; /* 0298-029B */
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 60d050e..aa438f2 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -151,6 +151,7 @@ static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx,
 static int qla4xxx_delete_chap(struct Scsi_Host *shost, uint16_t chap_tbl_idx);
 static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void  *data,
 				  int len);
+static int qla4xxx_get_host_stats(struct Scsi_Host *shost, char *buf, int len);
 
 /*
  * SCSI host template entry points
@@ -262,6 +263,7 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
 	.login_flashnode	= qla4xxx_sysfs_ddb_login,
 	.logout_flashnode	= qla4xxx_sysfs_ddb_logout,
 	.logout_flashnode_sid	= qla4xxx_sysfs_ddb_logout_sid,
+	.get_host_stats		= qla4xxx_get_host_stats,
 };
 
 static struct scsi_transport_template *qla4xxx_scsi_transport;
@@ -947,6 +949,209 @@ exit_set_chap:
 	return rc;
 }
 
+
+static int qla4xxx_get_host_stats(struct Scsi_Host *shost, char *buf, int len)
+{
+	struct scsi_qla_host *ha = to_qla_host(shost);
+	struct iscsi_offload_host_stats *host_stats = NULL;
+	int host_stats_size;
+	int ret = 0;
+	int ddb_idx = 0;
+	struct ql_iscsi_stats *ql_iscsi_stats = NULL;
+	int stats_size;
+	dma_addr_t iscsi_stats_dma;
+
+	DEBUG2(ql4_printk(KERN_INFO, ha, "Func: %s\n", __func__));
+
+	host_stats_size = sizeof(struct iscsi_offload_host_stats);
+
+	if (host_stats_size != len) {
+		ql4_printk(KERN_INFO, ha, "%s: host_stats size mismatch expected = %d, is = %d\n",
+			   __func__, len, host_stats_size);
+		ret = -EINVAL;
+		goto exit_host_stats;
+	}
+	host_stats = (struct iscsi_offload_host_stats *)buf;
+
+	if (!buf) {
+		ret = -ENOMEM;
+		goto exit_host_stats;
+	}
+
+	stats_size = PAGE_ALIGN(sizeof(struct ql_iscsi_stats));
+
+	ql_iscsi_stats = dma_alloc_coherent(&ha->pdev->dev, stats_size,
+					    &iscsi_stats_dma, GFP_KERNEL);
+	if (!ql_iscsi_stats) {
+		ql4_printk(KERN_ERR, ha,
+			   "Unable to allocate memory for iscsi stats\n");
+		goto exit_host_stats;
+	}
+
+	ret =  qla4xxx_get_mgmt_data(ha, ddb_idx, stats_size,
+				     iscsi_stats_dma);
+	if (ret != QLA_SUCCESS) {
+		ql4_printk(KERN_ERR, ha,
+			   "Unable to retrieve iscsi stats\n");
+		goto exit_host_stats;
+	}
+	host_stats->mactx_frames = le64_to_cpu(ql_iscsi_stats->mac_tx_frames);
+	host_stats->mactx_bytes = le64_to_cpu(ql_iscsi_stats->mac_tx_bytes);
+	host_stats->mactx_multicast_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_multicast_frames);
+	host_stats->mactx_broadcast_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_broadcast_frames);
+	host_stats->mactx_pause_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_pause_frames);
+	host_stats->mactx_control_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_control_frames);
+	host_stats->mactx_deferral =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_deferral);
+	host_stats->mactx_excess_deferral =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_excess_deferral);
+	host_stats->mactx_late_collision =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_late_collision);
+	host_stats->mactx_abort	= le64_to_cpu(ql_iscsi_stats->mac_tx_abort);
+	host_stats->mactx_single_collision =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_single_collision);
+	host_stats->mactx_multiple_collision =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_multiple_collision);
+	host_stats->mactx_collision =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_collision);
+	host_stats->mactx_frames_dropped =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_frames_dropped);
+	host_stats->mactx_jumbo_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_tx_jumbo_frames);
+	host_stats->macrx_frames = le64_to_cpu(ql_iscsi_stats->mac_rx_frames);
+	host_stats->macrx_bytes = le64_to_cpu(ql_iscsi_stats->mac_rx_bytes);
+	host_stats->macrx_unknown_control_frames =
+		le64_to_cpu(ql_iscsi_stats->mac_rx_unknown_control_frames);
+	host_stats->macrx_pause_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_pause_frames);
+	host_stats->macrx_control_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_control_frames);
+	host_stats->macrx_dribble =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_dribble);
+	host_stats->macrx_frame_length_error =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_frame_length_error);
+	host_stats->macrx_jabber = le64_to_cpu(ql_iscsi_stats->mac_rx_jabber);
+	host_stats->macrx_carrier_sense_error =
+		le64_to_cpu(ql_iscsi_stats->mac_rx_carrier_sense_error);
+	host_stats->macrx_frame_discarded =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_frame_discarded);
+	host_stats->macrx_frames_dropped =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_frames_dropped);
+	host_stats->mac_crc_error = le64_to_cpu(ql_iscsi_stats->mac_crc_error);
+	host_stats->mac_encoding_error =
+			le64_to_cpu(ql_iscsi_stats->mac_encoding_error);
+	host_stats->macrx_length_error_large =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_length_error_large);
+	host_stats->macrx_length_error_small =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_length_error_small);
+	host_stats->macrx_multicast_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_multicast_frames);
+	host_stats->macrx_broadcast_frames =
+			le64_to_cpu(ql_iscsi_stats->mac_rx_broadcast_frames);
+	host_stats->iptx_packets = le64_to_cpu(ql_iscsi_stats->ip_tx_packets);
+	host_stats->iptx_bytes = le64_to_cpu(ql_iscsi_stats->ip_tx_bytes);
+	host_stats->iptx_fragments =
+			le64_to_cpu(ql_iscsi_stats->ip_tx_fragments);
+	host_stats->iprx_packets = le64_to_cpu(ql_iscsi_stats->ip_rx_packets);
+	host_stats->iprx_bytes = le64_to_cpu(ql_iscsi_stats->ip_rx_bytes);
+	host_stats->iprx_fragments =
+			le64_to_cpu(ql_iscsi_stats->ip_rx_fragments);
+	host_stats->ip_datagram_reassembly =
+			le64_to_cpu(ql_iscsi_stats->ip_datagram_reassembly);
+	host_stats->ip_invalid_address_error =
+			le64_to_cpu(ql_iscsi_stats->ip_invalid_address_error);
+	host_stats->ip_error_packets =
+			le64_to_cpu(ql_iscsi_stats->ip_error_packets);
+	host_stats->ip_fragrx_overlap =
+			le64_to_cpu(ql_iscsi_stats->ip_fragrx_overlap);
+	host_stats->ip_fragrx_outoforder =
+			le64_to_cpu(ql_iscsi_stats->ip_fragrx_outoforder);
+	host_stats->ip_datagram_reassembly_timeout =
+		le64_to_cpu(ql_iscsi_stats->ip_datagram_reassembly_timeout);
+	host_stats->ipv6tx_packets =
+			le64_to_cpu(ql_iscsi_stats->ipv6_tx_packets);
+	host_stats->ipv6tx_bytes = le64_to_cpu(ql_iscsi_stats->ipv6_tx_bytes);
+	host_stats->ipv6tx_fragments =
+			le64_to_cpu(ql_iscsi_stats->ipv6_tx_fragments);
+	host_stats->ipv6rx_packets =
+			le64_to_cpu(ql_iscsi_stats->ipv6_rx_packets);
+	host_stats->ipv6rx_bytes = le64_to_cpu(ql_iscsi_stats->ipv6_rx_bytes);
+	host_stats->ipv6rx_fragments =
+			le64_to_cpu(ql_iscsi_stats->ipv6_rx_fragments);
+	host_stats->ipv6_datagram_reassembly =
+			le64_to_cpu(ql_iscsi_stats->ipv6_datagram_reassembly);
+	host_stats->ipv6_invalid_address_error =
+		le64_to_cpu(ql_iscsi_stats->ipv6_invalid_address_error);
+	host_stats->ipv6_error_packets =
+			le64_to_cpu(ql_iscsi_stats->ipv6_error_packets);
+	host_stats->ipv6_fragrx_overlap =
+			le64_to_cpu(ql_iscsi_stats->ipv6_fragrx_overlap);
+	host_stats->ipv6_fragrx_outoforder =
+			le64_to_cpu(ql_iscsi_stats->ipv6_fragrx_outoforder);
+	host_stats->ipv6_datagram_reassembly_timeout =
+		le64_to_cpu(ql_iscsi_stats->ipv6_datagram_reassembly_timeout);
+	host_stats->tcptx_segments =
+			le64_to_cpu(ql_iscsi_stats->tcp_tx_segments);
+	host_stats->tcptx_bytes	= le64_to_cpu(ql_iscsi_stats->tcp_tx_bytes);
+	host_stats->tcprx_segments =
+			le64_to_cpu(ql_iscsi_stats->tcp_rx_segments);
+	host_stats->tcprx_byte = le64_to_cpu(ql_iscsi_stats->tcp_rx_byte);
+	host_stats->tcp_duplicate_ack_retx =
+			le64_to_cpu(ql_iscsi_stats->tcp_duplicate_ack_retx);
+	host_stats->tcp_retx_timer_expired =
+			le64_to_cpu(ql_iscsi_stats->tcp_retx_timer_expired);
+	host_stats->tcprx_duplicate_ack	=
+			le64_to_cpu(ql_iscsi_stats->tcp_rx_duplicate_ack);
+	host_stats->tcprx_pure_ackr =
+			le64_to_cpu(ql_iscsi_stats->tcp_rx_pure_ackr);
+	host_stats->tcptx_delayed_ack =
+			le64_to_cpu(ql_iscsi_stats->tcp_tx_delayed_ack);
+	host_stats->tcptx_pure_ack =
+			le64_to_cpu(ql_iscsi_stats->tcp_tx_pure_ack);
+	host_stats->tcprx_segment_error =
+			le64_to_cpu(ql_iscsi_stats->tcp_rx_segment_error);
+	host_stats->tcprx_segment_outoforder =
+			le64_to_cpu(ql_iscsi_stats->tcp_rx_segment_outoforder);
+	host_stats->tcprx_window_probe =
+			le64_to_cpu(ql_iscsi_stats->tcp_rx_window_probe);
+	host_stats->tcprx_window_update =
+			le64_to_cpu(ql_iscsi_stats->tcp_rx_window_update);
+	host_stats->tcptx_window_probe_persist =
+		le64_to_cpu(ql_iscsi_stats->tcp_tx_window_probe_persist);
+	host_stats->ecc_error_correction =
+			le64_to_cpu(ql_iscsi_stats->ecc_error_correction);
+	host_stats->iscsi_pdu_tx = le64_to_cpu(ql_iscsi_stats->iscsi_pdu_tx);
+	host_stats->iscsi_data_bytes_tx =
+			le64_to_cpu(ql_iscsi_stats->iscsi_data_bytes_tx);
+	host_stats->iscsi_pdu_rx = le64_to_cpu(ql_iscsi_stats->iscsi_pdu_rx);
+	host_stats->iscsi_data_bytes_rx	=
+			le64_to_cpu(ql_iscsi_stats->iscsi_data_bytes_rx);
+	host_stats->iscsi_io_completed =
+			le64_to_cpu(ql_iscsi_stats->iscsi_io_completed);
+	host_stats->iscsi_unexpected_io_rx =
+			le64_to_cpu(ql_iscsi_stats->iscsi_unexpected_io_rx);
+	host_stats->iscsi_format_error =
+			le64_to_cpu(ql_iscsi_stats->iscsi_format_error);
+	host_stats->iscsi_hdr_digest_error =
+			le64_to_cpu(ql_iscsi_stats->iscsi_hdr_digest_error);
+	host_stats->iscsi_data_digest_error =
+			le64_to_cpu(ql_iscsi_stats->iscsi_data_digest_error);
+	host_stats->iscsi_sequence_error =
+			le64_to_cpu(ql_iscsi_stats->iscsi_sequence_error);
+exit_host_stats:
+	if (ql_iscsi_stats)
+		dma_free_coherent(&ha->pdev->dev, host_stats_size,
+				  ql_iscsi_stats, iscsi_stats_dma);
+
+	ql4_printk(KERN_INFO, ha, "%s: Get host stats done\n",
+		   __func__);
+	return ret;
+}
+
 static int qla4xxx_get_iface_param(struct iscsi_iface *iface,
 				   enum iscsi_param_type param_type,
 				   int param, char *buf)
-- 
1.8.2.GIT

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 4/8] scsi_transport_iscsi: Export ISCSI_PARAM_LOCAL_IPADDR attr for iscsi_connection
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
                   ` (2 preceding siblings ...)
  2013-11-22 10:28 ` [PATCH 3/8] qla4xxx: " vikas.chaudhary
@ 2013-11-22 10:28 ` vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 5/8] libiscsi: Add local_ipaddr parameter in iscsi_conn struct vikas.chaudhary
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc
  Cc: linux-scsi, vikas.chaudhary, lalit.chandivade,
	Adheer Chandravanshi

From: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>

This attribute specifies the local IP address used to establish connection.

Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
 drivers/scsi/scsi_transport_iscsi.c | 4 ++++
 include/scsi/iscsi_if.h             | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 4cf918a..fd8ffe6 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3772,6 +3772,7 @@ iscsi_conn_attr(ipv6_flow_label, ISCSI_PARAM_IPV6_FLOW_LABEL);
 iscsi_conn_attr(is_fw_assigned_ipv6, ISCSI_PARAM_IS_FW_ASSIGNED_IPV6);
 iscsi_conn_attr(tcp_xmit_wsf, ISCSI_PARAM_TCP_XMIT_WSF);
 iscsi_conn_attr(tcp_recv_wsf, ISCSI_PARAM_TCP_RECV_WSF);
+iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR);
 
 
 #define iscsi_conn_ep_attr_show(param)					\
@@ -3841,6 +3842,7 @@ static struct attribute *iscsi_conn_attrs[] = {
 	&dev_attr_conn_is_fw_assigned_ipv6.attr,
 	&dev_attr_conn_tcp_xmit_wsf.attr,
 	&dev_attr_conn_tcp_recv_wsf.attr,
+	&dev_attr_conn_local_ipaddr.attr,
 	NULL,
 };
 
@@ -3910,6 +3912,8 @@ static umode_t iscsi_conn_attr_is_visible(struct kobject *kobj,
 		param = ISCSI_PARAM_TCP_XMIT_WSF;
 	else if (attr == &dev_attr_conn_tcp_recv_wsf.attr)
 		param = ISCSI_PARAM_TCP_RECV_WSF;
+	else if (attr == &dev_attr_conn_local_ipaddr.attr)
+		param = ISCSI_PARAM_LOCAL_IPADDR;
 	else {
 		WARN_ONCE(1, "Invalid conn attr");
 		return 0;
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 3851a73..fd0421c 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -618,6 +618,7 @@ enum iscsi_param {
 
 	ISCSI_PARAM_DISCOVERY_PARENT_IDX,
 	ISCSI_PARAM_DISCOVERY_PARENT_TYPE,
+	ISCSI_PARAM_LOCAL_IPADDR,
 	/* must always be last */
 	ISCSI_PARAM_MAX,
 };
-- 
1.8.2.GIT


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

* [PATCH 5/8] libiscsi: Add local_ipaddr parameter in iscsi_conn struct
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
                   ` (3 preceding siblings ...)
  2013-11-22 10:28 ` [PATCH 4/8] scsi_transport_iscsi: Export ISCSI_PARAM_LOCAL_IPADDR attr for iscsi_connection vikas.chaudhary
@ 2013-11-22 10:28 ` vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 6/8] qla4xxx: Add support for ISCSI_PARAM_LOCAL_IPADDR sysfs attr vikas.chaudhary
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc
  Cc: linux-scsi, vikas.chaudhary, lalit.chandivade,
	Adheer Chandravanshi

From: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>

Add local_ipaddr param and support get/set operations on it.

Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
 drivers/scsi/libiscsi.c | 6 ++++++
 include/scsi/libiscsi.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index e399561..4046241 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2945,6 +2945,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
 	free_pages((unsigned long) conn->data,
 		   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
 	kfree(conn->persistent_address);
+	kfree(conn->local_ipaddr);
 	kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 	if (session->leadconn == conn)
@@ -3269,6 +3270,8 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
 		sscanf(buf, "%d", &val);
 		session->discovery_sess = !!val;
 		break;
+	case ISCSI_PARAM_LOCAL_IPADDR:
+		return iscsi_switch_str_param(&conn->local_ipaddr, buf);
 	default:
 		return -ENOSYS;
 	}
@@ -3542,6 +3545,9 @@ int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
 	case ISCSI_PARAM_TCP_RECV_WSF:
 		len = sprintf(buf, "%u\n", conn->tcp_recv_wsf);
 		break;
+	case ISCSI_PARAM_LOCAL_IPADDR:
+		len = sprintf(buf, "%s\n", conn->local_ipaddr);
+		break;
 	default:
 		return -ENOSYS;
 	}
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 6ac9e17a..309f513 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -231,6 +231,7 @@ struct iscsi_conn {
 	uint8_t			ipv6_traffic_class;
 	uint8_t			ipv6_flow_label;
 	uint8_t			is_fw_assigned_ipv6;
+	char			*local_ipaddr;
 
 	/* MIB-statistics */
 	uint64_t		txdata_octets;
-- 
1.8.2.GIT


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

* [PATCH 6/8] qla4xxx: Add support for ISCSI_PARAM_LOCAL_IPADDR sysfs attr
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
                   ` (4 preceding siblings ...)
  2013-11-22 10:28 ` [PATCH 5/8] libiscsi: Add local_ipaddr parameter in iscsi_conn struct vikas.chaudhary
@ 2013-11-22 10:28 ` vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 7/8] qla4xxx: Recreate chap data list during get chap operation vikas.chaudhary
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc
  Cc: linux-scsi, vikas.chaudhary, lalit.chandivade,
	Adheer Chandravanshi

From: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>

Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
 drivers/scsi/qla4xxx/ql4_os.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index aa438f2..4181758 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -421,6 +421,7 @@ static umode_t qla4_attr_is_visible(int param_type, int param)
 		case ISCSI_PARAM_EXP_STATSN:
 		case ISCSI_PARAM_DISCOVERY_PARENT_IDX:
 		case ISCSI_PARAM_DISCOVERY_PARENT_TYPE:
+		case ISCSI_PARAM_LOCAL_IPADDR:
 			return S_IRUGO;
 		default:
 			return 0;
@@ -3619,6 +3620,7 @@ static void qla4xxx_copy_to_sess_conn_params(struct iscsi_conn *conn,
 	unsigned long options = 0;
 	uint16_t ddb_link;
 	uint16_t disc_parent;
+	char ip_addr[DDB_IPADDR_LEN];
 
 	options = le16_to_cpu(fw_ddb_entry->options);
 	conn->is_fw_assigned_ipv6 = test_bit(OPT_IS_FW_ASSIGNED_IPV6, &options);
@@ -3700,6 +3702,14 @@ static void qla4xxx_copy_to_sess_conn_params(struct iscsi_conn *conn,
 
 	iscsi_set_param(conn->cls_conn, ISCSI_PARAM_TARGET_ALIAS,
 			(char *)fw_ddb_entry->iscsi_alias, 0);
+
+	options = le16_to_cpu(fw_ddb_entry->options);
+	if (options & DDB_OPT_IPV6_DEVICE) {
+		memset(ip_addr, 0, sizeof(ip_addr));
+		sprintf(ip_addr, "%pI6", fw_ddb_entry->link_local_ipv6_addr);
+		iscsi_set_param(conn->cls_conn, ISCSI_PARAM_LOCAL_IPADDR,
+				(char *)ip_addr, 0);
+	}
 }
 
 static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha,
-- 
1.8.2.GIT


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

* [PATCH 7/8] qla4xxx: Recreate chap data list during get chap operation
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
                   ` (5 preceding siblings ...)
  2013-11-22 10:28 ` [PATCH 6/8] qla4xxx: Add support for ISCSI_PARAM_LOCAL_IPADDR sysfs attr vikas.chaudhary
@ 2013-11-22 10:28 ` vikas.chaudhary
  2013-11-22 10:28 ` [PATCH 8/8] qla4xxx: Update driver version to 5.04.00-k3 vikas.chaudhary
  2013-12-17  7:23 ` [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch Mike Christie
  8 siblings, 0 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc
  Cc: linux-scsi, vikas.chaudhary, lalit.chandivade,
	Adheer Chandravanshi

From: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>

Recreate the chap data list during the get chap operation in
qla4xxx_get_chap_list().

Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
 drivers/scsi/qla4xxx/ql4_os.c | 119 ++++++++++++++++++++++--------------------
 1 file changed, 61 insertions(+), 58 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 4181758..1c05f84 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -573,6 +573,65 @@ static umode_t qla4_attr_is_visible(int param_type, int param)
 	return 0;
 }
 
+/**
+ * qla4xxx_create chap_list - Create CHAP list from FLASH
+ * @ha: pointer to adapter structure
+ *
+ * Read flash and make a list of CHAP entries, during login when a CHAP entry
+ * is received, it will be checked in this list. If entry exist then the CHAP
+ * entry index is set in the DDB. If CHAP entry does not exist in this list
+ * then a new entry is added in FLASH in CHAP table and the index obtained is
+ * used in the DDB.
+ **/
+static void qla4xxx_create_chap_list(struct scsi_qla_host *ha)
+{
+	int rval = 0;
+	uint8_t *chap_flash_data = NULL;
+	uint32_t offset;
+	dma_addr_t chap_dma;
+	uint32_t chap_size = 0;
+
+	if (is_qla40XX(ha))
+		chap_size = MAX_CHAP_ENTRIES_40XX *
+			    sizeof(struct ql4_chap_table);
+	else	/* Single region contains CHAP info for both
+		 * ports which is divided into half for each port.
+		 */
+		chap_size = ha->hw.flt_chap_size / 2;
+
+	chap_flash_data = dma_alloc_coherent(&ha->pdev->dev, chap_size,
+					     &chap_dma, GFP_KERNEL);
+	if (!chap_flash_data) {
+		ql4_printk(KERN_ERR, ha, "No memory for chap_flash_data\n");
+		return;
+	}
+
+	if (is_qla40XX(ha)) {
+		offset = FLASH_CHAP_OFFSET;
+	} else {
+		offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);
+		if (ha->port_num == 1)
+			offset += chap_size;
+	}
+
+	rval = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);
+	if (rval != QLA_SUCCESS)
+		goto exit_chap_list;
+
+	if (ha->chap_list == NULL)
+		ha->chap_list = vmalloc(chap_size);
+	if (ha->chap_list == NULL) {
+		ql4_printk(KERN_ERR, ha, "No memory for ha->chap_list\n");
+		goto exit_chap_list;
+	}
+
+	memset(ha->chap_list, 0, chap_size);
+	memcpy(ha->chap_list, chap_flash_data, chap_size);
+
+exit_chap_list:
+	dma_free_coherent(&ha->pdev->dev, chap_size, chap_flash_data, chap_dma);
+}
+
 static int qla4xxx_get_chap_by_index(struct scsi_qla_host *ha,
 				     int16_t chap_index,
 				     struct ql4_chap_table **chap_entry)
@@ -686,6 +745,8 @@ static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx,
 		goto exit_get_chap_list;
 	}
 
+	qla4xxx_create_chap_list(ha);
+
 	chap_rec = (struct iscsi_chap_rec *) buf;
 	mutex_lock(&ha->chap_sem);
 	for (i = chap_tbl_idx; i < max_chap_entries; i++) {
@@ -6121,64 +6182,6 @@ kset_free:
 }
 
 
-/**
- * qla4xxx_create chap_list - Create CHAP list from FLASH
- * @ha: pointer to adapter structure
- *
- * Read flash and make a list of CHAP entries, during login when a CHAP entry
- * is received, it will be checked in this list. If entry exist then the CHAP
- * entry index is set in the DDB. If CHAP entry does not exist in this list
- * then a new entry is added in FLASH in CHAP table and the index obtained is
- * used in the DDB.
- **/
-static void qla4xxx_create_chap_list(struct scsi_qla_host *ha)
-{
-	int rval = 0;
-	uint8_t *chap_flash_data = NULL;
-	uint32_t offset;
-	dma_addr_t chap_dma;
-	uint32_t chap_size = 0;
-
-	if (is_qla40XX(ha))
-		chap_size = MAX_CHAP_ENTRIES_40XX  *
-					sizeof(struct ql4_chap_table);
-	else	/* Single region contains CHAP info for both
-		 * ports which is divided into half for each port.
-		 */
-		chap_size = ha->hw.flt_chap_size / 2;
-
-	chap_flash_data = dma_alloc_coherent(&ha->pdev->dev, chap_size,
-					  &chap_dma, GFP_KERNEL);
-	if (!chap_flash_data) {
-		ql4_printk(KERN_ERR, ha, "No memory for chap_flash_data\n");
-		return;
-	}
-	if (is_qla40XX(ha))
-		offset = FLASH_CHAP_OFFSET;
-	else {
-		offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);
-		if (ha->port_num == 1)
-			offset += chap_size;
-	}
-
-	rval = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);
-	if (rval != QLA_SUCCESS)
-		goto exit_chap_list;
-
-	if (ha->chap_list == NULL)
-		ha->chap_list = vmalloc(chap_size);
-	if (ha->chap_list == NULL) {
-		ql4_printk(KERN_ERR, ha, "No memory for ha->chap_list\n");
-		goto exit_chap_list;
-	}
-
-	memcpy(ha->chap_list, chap_flash_data, chap_size);
-
-exit_chap_list:
-	dma_free_coherent(&ha->pdev->dev, chap_size,
-			chap_flash_data, chap_dma);
-}
-
 static void qla4xxx_get_param_ddb(struct ddb_entry *ddb_entry,
 				  struct ql4_tuple_ddb *tddb)
 {
-- 
1.8.2.GIT


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

* [PATCH 8/8] qla4xxx: Update driver version to 5.04.00-k3
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
                   ` (6 preceding siblings ...)
  2013-11-22 10:28 ` [PATCH 7/8] qla4xxx: Recreate chap data list during get chap operation vikas.chaudhary
@ 2013-11-22 10:28 ` vikas.chaudhary
  2013-12-17  7:23 ` [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch Mike Christie
  8 siblings, 0 replies; 10+ messages in thread
From: vikas.chaudhary @ 2013-11-22 10:28 UTC (permalink / raw)
  To: jbottomley, michaelc; +Cc: linux-scsi, vikas.chaudhary, lalit.chandivade

From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>

Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
---
 drivers/scsi/qla4xxx/ql4_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
index 7427d94..9b29466 100644
--- a/drivers/scsi/qla4xxx/ql4_version.h
+++ b/drivers/scsi/qla4xxx/ql4_version.h
@@ -5,4 +5,4 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION	"5.04.00-k2"
+#define QLA4XXX_DRIVER_VERSION	"5.04.00-k3"
-- 
1.8.2.GIT


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

* Re: [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch
  2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
                   ` (7 preceding siblings ...)
  2013-11-22 10:28 ` [PATCH 8/8] qla4xxx: Update driver version to 5.04.00-k3 vikas.chaudhary
@ 2013-12-17  7:23 ` Mike Christie
  8 siblings, 0 replies; 10+ messages in thread
From: Mike Christie @ 2013-12-17  7:23 UTC (permalink / raw)
  To: vikas.chaudhary; +Cc: jbottomley, linux-scsi, lalit.chandivade

On 11/22/13 4:28 AM, vikas.chaudhary@qlogic.com wrote:
> From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
>
> James,
>
> Please apply the following patches to the scsi tree at your earliest convenience.
>
> These patches are on top of other qla4xxx patch posted on list here:
> http://marc.info/?l=linux-scsi&m=138210321629250&w=2
>
> Adheer Chandravanshi (4):
>        scsi_transport_iscsi: Export ISCSI_PARAM_LOCAL_IPADDR attr for iscsi_connection
>        libiscsi: Add local_ipaddr parameter in iscsi_conn struct
>        qla4xxx: Add support for ISCSI_PARAM_LOCAL_IPADDR sysfs attr
>        qla4xxx: Recreate chap data list during get chap operation
>
> Lalit Chandivade (2):
>        scsi_transport_iscsi: Add host statistics support
>        qla4xxx: Add host statistics support
>
> Vikas Chaudhary (2):
>        qla4xxx: Added support for Diagnostics MBOX command
>        qla4xxx: Update driver version to 5.04.00-k3
>

Patches look ok.

Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>


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

end of thread, other threads:[~2013-12-17  7:24 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-22 10:28 [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch vikas.chaudhary
2013-11-22 10:28 ` [PATCH 1/8] qla4xxx: Added support for Diagnostics MBOX command vikas.chaudhary
2013-11-22 10:28 ` [PATCH 2/8] scsi_transport_iscsi: Add host statistics support vikas.chaudhary
2013-11-22 10:28 ` [PATCH 3/8] qla4xxx: " vikas.chaudhary
2013-11-22 10:28 ` [PATCH 4/8] scsi_transport_iscsi: Export ISCSI_PARAM_LOCAL_IPADDR attr for iscsi_connection vikas.chaudhary
2013-11-22 10:28 ` [PATCH 5/8] libiscsi: Add local_ipaddr parameter in iscsi_conn struct vikas.chaudhary
2013-11-22 10:28 ` [PATCH 6/8] qla4xxx: Add support for ISCSI_PARAM_LOCAL_IPADDR sysfs attr vikas.chaudhary
2013-11-22 10:28 ` [PATCH 7/8] qla4xxx: Recreate chap data list during get chap operation vikas.chaudhary
2013-11-22 10:28 ` [PATCH 8/8] qla4xxx: Update driver version to 5.04.00-k3 vikas.chaudhary
2013-12-17  7:23 ` [PATCH 0/8] qla4xxx: 5.04.00-k3: Updates for scsi "misc" branch Mike Christie

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).