Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0b9d3f7 authored by Vikas Chaudhary's avatar Vikas Chaudhary Committed by James Bottomley
Browse files

[SCSI] qla4xxx: Added ping support



Added ping support for network connection diagnostics.

Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent ac20c7bf
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -221,6 +221,15 @@ struct srb {
	uint16_t reserved2;
};

/* Mailbox request block structure */
struct mrb {
	struct scsi_qla_host *ha;
	struct mbox_cmd_iocb *mbox;
	uint32_t mbox_cmd;
	uint16_t iocb_cnt;		/* Number of used iocbs */
	uint32_t pid;
};

/*
 * Asynchronous Event Queue structure
 */
@@ -303,6 +312,7 @@ struct ql4_tuple_ddb {

enum qla4_work_type {
	QLA4_EVENT_AEN,
	QLA4_EVENT_PING_STATUS,
};

struct qla4_work_evt {
@@ -314,6 +324,12 @@ struct qla4_work_evt {
			uint32_t data_size;
			uint8_t data[0];
		} aen;
		struct {
			uint32_t status;
			uint32_t pid;
			uint32_t data_size;
			uint8_t data[0];
		} ping;
	} u;
};

@@ -690,6 +706,11 @@ struct scsi_qla_host {
	/* event work list */
	struct list_head work_list;
	spinlock_t work_lock;

	/* mbox iocb */
#define MAX_MRB		128
	struct mrb *active_mrb_array[MAX_MRB];
	uint32_t mrb_index;
};

struct ql4_task_data {
+20 −0
Original line number Diff line number Diff line
@@ -331,6 +331,10 @@ struct qla_flt_region {
/*  Mailbox command definitions */
#define MBOX_CMD_ABOUT_FW			0x0009
#define MBOX_CMD_PING				0x000B
#define PING_IPV6_PROTOCOL_ENABLE		0x1
#define PING_IPV6_LINKLOCAL_ADDR		0x4
#define PING_IPV6_ADDR0				0x8
#define PING_IPV6_ADDR1				0xC
#define MBOX_CMD_ENABLE_INTRS			0x0010
#define INTR_DISABLE				0
#define INTR_ENABLE				1
@@ -922,6 +926,8 @@ struct qla4_header {
#define ET_CMND_T3		 0x19
#define ET_PASSTHRU0		 0x3A
#define ET_PASSTHRU_STATUS	 0x3C
#define ET_MBOX_CMD		0x38
#define ET_MBOX_STATUS		0x39

	uint8_t entryStatus;
	uint8_t systemDefined;
@@ -1122,6 +1128,20 @@ struct passthru_status {
	uint8_t res4[16];	/* 30-3F */
};

struct mbox_cmd_iocb {
	struct qla4_header hdr;	/* 00-03 */
	uint32_t handle;	/* 04-07 */
	uint32_t in_mbox[8];	/* 08-25 */
	uint32_t res1[6];	/* 26-3F */
};

struct mbox_status_iocb {
	struct qla4_header hdr;	/* 00-03 */
	uint32_t handle;	/* 04-07 */
	uint32_t out_mbox[8];	/* 08-25 */
	uint32_t res1[6];	/* 26-3F */
};

/*
 * ISP queue - response queue entry definition.
 */
+5 −0
Original line number Diff line number Diff line
@@ -183,6 +183,11 @@ int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset);
int qla4xxx_post_aen_work(struct scsi_qla_host *ha, uint32_t aen_code,
			  uint32_t data_size, uint8_t *data);
int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
		      uint32_t payload_size, uint32_t pid, uint8_t *ipaddr);
int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,
			       uint32_t status, uint32_t pid,
			       uint32_t data_size, uint8_t *data);

/* BSG Functions */
int qla4xxx_bsg_request(struct bsg_job *bsg_job);
+5 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ static void qla4xxx_init_response_q_entries(struct scsi_qla_host *ha)
int qla4xxx_init_rings(struct scsi_qla_host *ha)
{
	unsigned long flags = 0;
	int i;

	/* Initialize request queue. */
	spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -125,6 +126,10 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha)

	qla4xxx_init_response_q_entries(ha);

	/* Initialize mabilbox active array */
	for (i = 0; i < MAX_MRB; i++)
		ha->active_mrb_array[i] = NULL;

	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	return QLA_SUCCESS;
+92 −0
Original line number Diff line number Diff line
@@ -445,3 +445,95 @@ queuing_error:
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
	return ret;
}

static struct mrb *qla4xxx_get_new_mrb(struct scsi_qla_host *ha)
{
	struct mrb *mrb;

	mrb = kzalloc(sizeof(*mrb), GFP_KERNEL);
	if (!mrb)
		return mrb;

	mrb->ha = ha;
	return mrb;
}

int qla4xxx_send_mbox_iocb(struct scsi_qla_host *ha, struct mrb *mrb,
			   uint32_t *in_mbox)
{
	int rval = QLA_SUCCESS;
	uint32_t i;
	unsigned long flags;
	uint32_t index = 0;

	/* Acquire hardware specific lock */
	spin_lock_irqsave(&ha->hardware_lock, flags);

	/* Get pointer to the queue entry for the marker */
	rval = qla4xxx_get_req_pkt(ha, (struct queue_entry **) &(mrb->mbox));
	if (rval != QLA_SUCCESS)
		goto exit_mbox_iocb;

	index = ha->mrb_index;
	/* get valid mrb index*/
	for (i = 0; i < MAX_MRB; i++) {
		index++;
		if (index == MAX_MRB)
			index = 1;
		if (ha->active_mrb_array[index] == NULL) {
			ha->mrb_index = index;
			break;
		}
	}

	mrb->iocb_cnt = 1;
	ha->active_mrb_array[index] = mrb;
	mrb->mbox->handle = index;
	mrb->mbox->hdr.entryType = ET_MBOX_CMD;
	mrb->mbox->hdr.entryCount = mrb->iocb_cnt;
	memcpy(mrb->mbox->in_mbox, in_mbox, 32);
	mrb->mbox_cmd = in_mbox[0];
	wmb();

	ha->isp_ops->queue_iocb(ha);
exit_mbox_iocb:
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
	return rval;
}

int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
		      uint32_t payload_size, uint32_t pid, uint8_t *ipaddr)
{
	uint32_t in_mbox[8];
	struct mrb *mrb = NULL;
	int rval = QLA_SUCCESS;

	memset(in_mbox, 0, sizeof(in_mbox));

	mrb = qla4xxx_get_new_mrb(ha);
	if (!mrb) {
		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: fail to get new mrb\n",
				  __func__));
		rval = QLA_ERROR;
		goto exit_ping;
	}

	in_mbox[0] = MBOX_CMD_PING;
	in_mbox[1] = options;
	memcpy(&in_mbox[2], &ipaddr[0], 4);
	memcpy(&in_mbox[3], &ipaddr[4], 4);
	memcpy(&in_mbox[4], &ipaddr[8], 4);
	memcpy(&in_mbox[5], &ipaddr[12], 4);
	in_mbox[6] = payload_size;

	mrb->pid = pid;
	rval = qla4xxx_send_mbox_iocb(ha, mrb, in_mbox);

	if (rval != QLA_SUCCESS)
		goto exit_ping;

	return rval;
exit_ping:
	kfree(mrb);
	return rval;
}
Loading