Commit 83ffcf78 authored by Srujana Challa's avatar Srujana Challa Committed by Herbert Xu
Browse files

crypto: octeontx2 - add mailbox communication with AF



In the resource virtualization unit (RVU) each of the PF and AF
(admin function) share a 64KB of reserved memory region for
communication. This patch initializes PF <=> AF mailbox IRQs,
registers handlers for processing these communication messages.

Signed-off-by: default avatarSuheil Chandran <schandran@marvell.com>
Signed-off-by: default avatarLukasz Bartosik <lbartosik@marvell.com>
Signed-off-by: default avatarSrujana Challa <schalla@marvell.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 5e8ce833
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CRYPTO_DEV_OCTEONTX2_CPT) += octeontx2-cpt.o

octeontx2-cpt-objs := otx2_cptpf_main.o
octeontx2-cpt-objs := otx2_cptpf_main.o otx2_cptpf_mbox.o \
		      otx2_cpt_mbox_common.o

ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
+4 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/crypto.h>
#include "otx2_cpt_hw_types.h"
#include "rvu.h"
#include "mbox.h"

#define OTX2_CPT_RVU_FUNC_ADDR_S(blk, slot, offs) \
		(((blk) << 20) | ((slot) << 12) | (offs))
@@ -29,4 +30,7 @@ static inline u64 otx2_cpt_read64(void __iomem *reg_base, u64 blk, u64 slot,
	return readq_relaxed(reg_base +
			     OTX2_CPT_RVU_FUNC_ADDR_S(blk, slot, offs));
}

int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev);
int otx2_cpt_send_mbox_msg(struct otx2_mbox *mbox, struct pci_dev *pdev);
#endif /* __OTX2_CPT_COMMON_H */
+37 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2020 Marvell. */

#include "otx2_cpt_common.h"

int otx2_cpt_send_mbox_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
{
	int ret;

	otx2_mbox_msg_send(mbox, 0);
	ret = otx2_mbox_wait_for_rsp(mbox, 0);
	if (ret == -EIO) {
		dev_err(&pdev->dev, "RVU MBOX timeout.\n");
		return ret;
	} else if (ret) {
		dev_err(&pdev->dev, "RVU MBOX error: %d.\n", ret);
		return -EFAULT;
	}
	return ret;
}

int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
{
	struct mbox_msghdr *req;

	req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
				      sizeof(struct ready_msg_rsp));
	if (req == NULL) {
		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
		return -EFAULT;
	}
	req->id = MBOX_MSG_READY;
	req->sig = OTX2_MBOX_REQ_SIG;
	req->pcifunc = 0;

	return otx2_cpt_send_mbox_msg(mbox, pdev);
}
+12 −0
Original line number Diff line number Diff line
@@ -5,9 +5,21 @@
#ifndef __OTX2_CPTPF_H
#define __OTX2_CPTPF_H

#include "otx2_cpt_common.h"

struct otx2_cptpf_dev {
	void __iomem *reg_base;		/* CPT PF registers start address */
	void __iomem *afpf_mbox_base;	/* PF-AF mbox start address */
	struct pci_dev *pdev;		/* PCI device handle */
	/* AF <=> PF mbox */
	struct otx2_mbox	afpf_mbox;
	struct work_struct	afpf_mbox_work;
	struct workqueue_struct *afpf_mbox_wq;

	u8 pf_id;               /* RVU PF number */
};

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

#endif /* __OTX2_CPTPF_H */
+101 −1
Original line number Diff line number Diff line
@@ -10,6 +10,75 @@
#define OTX2_CPT_DRV_NAME    "octeontx2-cpt"
#define OTX2_CPT_DRV_STRING  "Marvell OcteonTX2 CPT Physical Function Driver"

static void cptpf_disable_afpf_mbox_intr(struct otx2_cptpf_dev *cptpf)
{
	/* Disable AF-PF interrupt */
	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT_ENA_W1C,
			 0x1ULL);
	/* Clear interrupt if any */
	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT, 0x1ULL);
}

static int cptpf_register_afpf_mbox_intr(struct otx2_cptpf_dev *cptpf)
{
	struct pci_dev *pdev = cptpf->pdev;
	struct device *dev = &pdev->dev;
	int ret, irq;

	irq = pci_irq_vector(pdev, RVU_PF_INT_VEC_AFPF_MBOX);
	/* Register AF-PF mailbox interrupt handler */
	ret = devm_request_irq(dev, irq, otx2_cptpf_afpf_mbox_intr, 0,
			       "CPTAFPF Mbox", cptpf);
	if (ret) {
		dev_err(dev,
			"IRQ registration failed for PFAF mbox irq\n");
		return ret;
	}
	/* Clear interrupt if any, to avoid spurious interrupts */
	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT, 0x1ULL);
	/* Enable AF-PF interrupt */
	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT_ENA_W1S,
			 0x1ULL);

	ret = otx2_cpt_send_ready_msg(&cptpf->afpf_mbox, cptpf->pdev);
	if (ret) {
		dev_warn(dev,
			 "AF not responding to mailbox, deferring probe\n");
		cptpf_disable_afpf_mbox_intr(cptpf);
		return -EPROBE_DEFER;
	}
	return 0;
}

static int cptpf_afpf_mbox_init(struct otx2_cptpf_dev *cptpf)
{
	int err;

	cptpf->afpf_mbox_wq = alloc_workqueue("cpt_afpf_mailbox",
					      WQ_UNBOUND | WQ_HIGHPRI |
					      WQ_MEM_RECLAIM, 1);
	if (!cptpf->afpf_mbox_wq)
		return -ENOMEM;

	err = otx2_mbox_init(&cptpf->afpf_mbox, cptpf->afpf_mbox_base,
			     cptpf->pdev, cptpf->reg_base, MBOX_DIR_PFAF, 1);
	if (err)
		goto error;

	INIT_WORK(&cptpf->afpf_mbox_work, otx2_cptpf_afpf_mbox_handler);
	return 0;

error:
	destroy_workqueue(cptpf->afpf_mbox_wq);
	return err;
}

static void cptpf_afpf_mbox_destroy(struct otx2_cptpf_dev *cptpf)
{
	destroy_workqueue(cptpf->afpf_mbox_wq);
	otx2_mbox_destroy(&cptpf->afpf_mbox);
}

static int cpt_is_pf_usable(struct otx2_cptpf_dev *cptpf)
{
	u64 rev;
@@ -33,6 +102,7 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
			    const struct pci_device_id *ent)
{
	struct device *dev = &pdev->dev;
	resource_size_t offset, size;
	struct otx2_cptpf_dev *cptpf;
	int err;

@@ -69,8 +139,35 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
	if (err)
		goto clear_drvdata;

	offset = pci_resource_start(pdev, PCI_MBOX_BAR_NUM);
	size = pci_resource_len(pdev, PCI_MBOX_BAR_NUM);
	/* Map AF-PF mailbox memory */
	cptpf->afpf_mbox_base = devm_ioremap_wc(dev, offset, size);
	if (!cptpf->afpf_mbox_base) {
		dev_err(&pdev->dev, "Unable to map BAR4\n");
		err = -ENODEV;
		goto clear_drvdata;
	}
	err = pci_alloc_irq_vectors(pdev, RVU_PF_INT_VEC_CNT,
				    RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX);
	if (err < 0) {
		dev_err(dev, "Request for %d msix vectors failed\n",
			RVU_PF_INT_VEC_CNT);
		goto clear_drvdata;
	}
	/* Initialize AF-PF mailbox */
	err = cptpf_afpf_mbox_init(cptpf);
	if (err)
		goto clear_drvdata;
	/* Register mailbox interrupt */
	err = cptpf_register_afpf_mbox_intr(cptpf);
	if (err)
		goto destroy_afpf_mbox;

	return 0;

destroy_afpf_mbox:
	cptpf_afpf_mbox_destroy(cptpf);
clear_drvdata:
	pci_set_drvdata(pdev, NULL);
	return err;
@@ -82,7 +179,10 @@ static void otx2_cptpf_remove(struct pci_dev *pdev)

	if (!cptpf)
		return;

	/* Disable AF-PF mailbox interrupt */
	cptpf_disable_afpf_mbox_intr(cptpf);
	/* Destroy AF-PF mbox */
	cptpf_afpf_mbox_destroy(cptpf);
	pci_set_drvdata(pdev, NULL);
}

Loading