Commit acbaa8c8 authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Add bsg support for retrieving adapter cmf data

Add a bsg ioctl to allow user applications to retrieve the adapter
congestion management framework buffer.

Link: https://lore.kernel.org/r/20210816162901.121235-15-jsmart2021@gmail.com


Co-developed-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 74a7baa2
Loading
Loading
Loading
Loading
+89 −0
Original line number Diff line number Diff line
@@ -5751,6 +5751,92 @@ lpfc_get_trunk_info(struct bsg_job *job)

}

static int
lpfc_get_cgnbuf_info(struct bsg_job *job)
{
	struct lpfc_vport *vport = shost_priv(fc_bsg_to_shost(job));
	struct lpfc_hba *phba = vport->phba;
	struct fc_bsg_request *bsg_request = job->request;
	struct fc_bsg_reply *bsg_reply = job->reply;
	struct get_cgnbuf_info_req *cgnbuf_req;
	struct lpfc_cgn_info *cp;
	uint8_t *cgn_buff;
	int size, cinfosz;
	int  rc = 0;

	if (job->request_len < sizeof(struct fc_bsg_request) +
	    sizeof(struct get_cgnbuf_info_req)) {
		rc = -ENOMEM;
		goto job_exit;
	}

	if (!phba->sli4_hba.pc_sli4_params.cmf) {
		rc = -ENOENT;
		goto job_exit;
	}

	if (!phba->cgn_i || !phba->cgn_i->virt) {
		rc = -ENOENT;
		goto job_exit;
	}

	cp = phba->cgn_i->virt;
	if (cp->cgn_info_version < LPFC_CGN_INFO_V3) {
		rc = -EPERM;
		goto job_exit;
	}

	cgnbuf_req = (struct get_cgnbuf_info_req *)
		bsg_request->rqst_data.h_vendor.vendor_cmd;

	/* For reset or size == 0 */
	bsg_reply->reply_payload_rcv_len = 0;

	if (cgnbuf_req->reset == LPFC_BSG_CGN_RESET_STAT) {
		lpfc_init_congestion_stat(phba);
		goto job_exit;
	}

	/* We don't want to include the CRC at the end */
	cinfosz = sizeof(struct lpfc_cgn_info) - sizeof(uint32_t);

	size = cgnbuf_req->read_size;
	if (!size)
		goto job_exit;

	if (size < cinfosz) {
		/* Just copy back what we can */
		cinfosz = size;
		rc = -E2BIG;
	}

	/* Allocate memory to read congestion info */
	cgn_buff = vmalloc(cinfosz);
	if (!cgn_buff) {
		rc = -ENOMEM;
		goto job_exit;
	}

	memcpy(cgn_buff, cp, cinfosz);

	bsg_reply->reply_payload_rcv_len =
		sg_copy_from_buffer(job->reply_payload.sg_list,
				    job->reply_payload.sg_cnt,
				    cgn_buff, cinfosz);

	vfree(cgn_buff);

job_exit:
	bsg_reply->result = rc;
	if (!rc)
		bsg_job_done(job, bsg_reply->result,
			     bsg_reply->reply_payload_rcv_len);
	else
		lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
				"2724 GET CGNBUF error: %d\n", rc);
	return rc;
}

/**
 * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
 * @job: fc_bsg_job to handle
@@ -5813,6 +5899,9 @@ lpfc_bsg_hst_vendor(struct bsg_job *job)
	case LPFC_BSG_VENDOR_GET_TRUNK_INFO:
		rc = lpfc_get_trunk_info(job);
		break;
	case LPFC_BSG_VENDOR_GET_CGNBUF_INFO:
		rc = lpfc_get_cgnbuf_info(job);
		break;
	default:
		rc = -EINVAL;
		bsg_reply->reply_payload_rcv_len = 0;
+8 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#define LPFC_BSG_VENDOR_RAS_GET_CONFIG		18
#define LPFC_BSG_VENDOR_RAS_SET_CONFIG		19
#define LPFC_BSG_VENDOR_GET_TRUNK_INFO		20
#define LPFC_BSG_VENDOR_GET_CGNBUF_INFO		21

struct set_ct_event {
	uint32_t command;
@@ -386,6 +387,13 @@ struct get_trunk_info_req {
	uint32_t command;
};

struct get_cgnbuf_info_req {
	uint32_t command;
	uint32_t read_size;
	uint32_t reset;
#define LPFC_BSG_CGN_RESET_STAT		1
};

/* driver only */
#define SLI_CONFIG_NOT_HANDLED		0
#define SLI_CONFIG_HANDLED		1