Commit 5c553114 authored by Srujana Challa's avatar Srujana Challa Committed by Herbert Xu
Browse files

crypto: octeontx2 - add support for AF to CPT PF uplink mbox



This patch adds support for AF -> CPT PF uplink mailbox messages
and adds a mailbox handler to submit a CPT instruction from AF as
current architecture doesn't allow AF to submit CPT instruction
directly to HW.

Signed-off-by: default avatarSrujana Challa <schalla@marvell.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent dee3590c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ struct otx2_cptpf_dev {
	struct work_struct	afpf_mbox_work;
	struct workqueue_struct *afpf_mbox_wq;

	struct otx2_mbox	afpf_mbox_up;
	struct work_struct	afpf_mbox_up_work;

	/* VF <=> PF mbox */
	struct otx2_mbox	vfpf_mbox;
	struct workqueue_struct *vfpf_mbox_wq;
@@ -61,6 +64,7 @@ struct otx2_cptpf_dev {

irqreturn_t otx2_cptpf_afpf_mbox_intr(int irq, void *arg);
void otx2_cptpf_afpf_mbox_handler(struct work_struct *work);
void otx2_cptpf_afpf_mbox_up_handler(struct work_struct *work);
irqreturn_t otx2_cptpf_vfpf_mbox_intr(int irq, void *arg);
void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work);

+10 −0
Original line number Diff line number Diff line
@@ -473,10 +473,19 @@ static int cptpf_afpf_mbox_init(struct otx2_cptpf_dev *cptpf)
	if (err)
		goto error;

	err = otx2_mbox_init(&cptpf->afpf_mbox_up, cptpf->afpf_mbox_base,
			     pdev, cptpf->reg_base, MBOX_DIR_PFAF_UP, 1);
	if (err)
		goto mbox_cleanup;

	INIT_WORK(&cptpf->afpf_mbox_work, otx2_cptpf_afpf_mbox_handler);
	INIT_WORK(&cptpf->afpf_mbox_up_work, otx2_cptpf_afpf_mbox_up_handler);
	mutex_init(&cptpf->lock);

	return 0;

mbox_cleanup:
	otx2_mbox_destroy(&cptpf->afpf_mbox);
error:
	destroy_workqueue(cptpf->afpf_mbox_wq);
	return err;
@@ -486,6 +495,7 @@ static void cptpf_afpf_mbox_destroy(struct otx2_cptpf_dev *cptpf)
{
	destroy_workqueue(cptpf->afpf_mbox_wq);
	otx2_mbox_destroy(&cptpf->afpf_mbox);
	otx2_mbox_destroy(&cptpf->afpf_mbox_up);
}

static ssize_t kvf_limits_show(struct device *dev,
+84 −2
Original line number Diff line number Diff line
@@ -224,14 +224,28 @@ void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work)
irqreturn_t otx2_cptpf_afpf_mbox_intr(int __always_unused irq, void *arg)
{
	struct otx2_cptpf_dev *cptpf = arg;
	struct otx2_mbox_dev *mdev;
	struct otx2_mbox *mbox;
	struct mbox_hdr *hdr;
	u64 intr;

	/* Read the interrupt bits */
	intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT);

	if (intr & 0x1ULL) {
		mbox = &cptpf->afpf_mbox;
		mdev = &mbox->dev[0];
		hdr = mdev->mbase + mbox->rx_start;
		if (hdr->num_msgs)
			/* Schedule work queue function to process the MBOX request */
			queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_work);

		mbox = &cptpf->afpf_mbox_up;
		mdev = &mbox->dev[0];
		hdr = mdev->mbase + mbox->rx_start;
		if (hdr->num_msgs)
			/* Schedule work queue function to process the MBOX request */
			queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_up_work);
		/* Clear and ack the interrupt */
		otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT,
				 0x1ULL);
@@ -367,3 +381,71 @@ void otx2_cptpf_afpf_mbox_handler(struct work_struct *work)
	}
	otx2_mbox_reset(afpf_mbox, 0);
}

static void handle_msg_cpt_inst_lmtst(struct otx2_cptpf_dev *cptpf,
				      struct mbox_msghdr *msg)
{
	struct cpt_inst_lmtst_req *req = (struct cpt_inst_lmtst_req *)msg;
	struct otx2_cptlfs_info *lfs = &cptpf->lfs;
	struct msg_rsp *rsp;

	if (cptpf->lfs.lfs_num)
		lfs->ops->send_cmd((union otx2_cpt_inst_s *)req->inst, 1,
				   &lfs->lf[0]);

	rsp = (struct msg_rsp *)otx2_mbox_alloc_msg(&cptpf->afpf_mbox_up, 0,
						    sizeof(*rsp));
	if (!rsp)
		return;

	rsp->hdr.id = msg->id;
	rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
	rsp->hdr.pcifunc = 0;
	rsp->hdr.rc = 0;
}

static void process_afpf_mbox_up_msg(struct otx2_cptpf_dev *cptpf,
				     struct mbox_msghdr *msg)
{
	if (msg->id >= MBOX_MSG_MAX) {
		dev_err(&cptpf->pdev->dev,
			"MBOX msg with unknown ID %d\n", msg->id);
		return;
	}

	switch (msg->id) {
	case MBOX_MSG_CPT_INST_LMTST:
		handle_msg_cpt_inst_lmtst(cptpf, msg);
		break;
	default:
		otx2_reply_invalid_msg(&cptpf->afpf_mbox_up, 0, 0, msg->id);
	}
}

void otx2_cptpf_afpf_mbox_up_handler(struct work_struct *work)
{
	struct otx2_cptpf_dev *cptpf;
	struct otx2_mbox_dev *mdev;
	struct mbox_hdr *rsp_hdr;
	struct mbox_msghdr *msg;
	struct otx2_mbox *mbox;
	int offset, i;

	cptpf = container_of(work, struct otx2_cptpf_dev, afpf_mbox_up_work);
	mbox = &cptpf->afpf_mbox_up;
	mdev = &mbox->dev[0];
	/* Sync mbox data into memory */
	smp_wmb();

	rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
	offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);

	for (i = 0; i < rsp_hdr->num_msgs; i++) {
		msg = (struct mbox_msghdr *)(mdev->mbase + offset);

		process_afpf_mbox_up_msg(cptpf, msg);

		offset = mbox->rx_start + msg->next_msgoff;
	}
	otx2_mbox_msg_send(mbox, 0);
}