Skip to content

Commit 83ffcf7

Browse files
SruChallaherbertx
authored andcommitted
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: Suheil Chandran <schandran@marvell.com> Signed-off-by: Lukasz Bartosik <lbartosik@marvell.com> Signed-off-by: Srujana Challa <schalla@marvell.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 5e8ce83 commit 83ffcf7

File tree

6 files changed

+236
-2
lines changed

6 files changed

+236
-2
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
obj-$(CONFIG_CRYPTO_DEV_OCTEONTX2_CPT) += octeontx2-cpt.o
33

4-
octeontx2-cpt-objs := otx2_cptpf_main.o
4+
octeontx2-cpt-objs := otx2_cptpf_main.o otx2_cptpf_mbox.o \
5+
otx2_cpt_mbox_common.o
56

67
ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af

drivers/crypto/marvell/octeontx2/otx2_cpt_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/crypto.h>
1313
#include "otx2_cpt_hw_types.h"
1414
#include "rvu.h"
15+
#include "mbox.h"
1516

1617
#define OTX2_CPT_RVU_FUNC_ADDR_S(blk, slot, offs) \
1718
(((blk) << 20) | ((slot) << 12) | (offs))
@@ -29,4 +30,7 @@ static inline u64 otx2_cpt_read64(void __iomem *reg_base, u64 blk, u64 slot,
2930
return readq_relaxed(reg_base +
3031
OTX2_CPT_RVU_FUNC_ADDR_S(blk, slot, offs));
3132
}
33+
34+
int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev);
35+
int otx2_cpt_send_mbox_msg(struct otx2_mbox *mbox, struct pci_dev *pdev);
3236
#endif /* __OTX2_CPT_COMMON_H */
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (C) 2020 Marvell. */
3+
4+
#include "otx2_cpt_common.h"
5+
6+
int otx2_cpt_send_mbox_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
7+
{
8+
int ret;
9+
10+
otx2_mbox_msg_send(mbox, 0);
11+
ret = otx2_mbox_wait_for_rsp(mbox, 0);
12+
if (ret == -EIO) {
13+
dev_err(&pdev->dev, "RVU MBOX timeout.\n");
14+
return ret;
15+
} else if (ret) {
16+
dev_err(&pdev->dev, "RVU MBOX error: %d.\n", ret);
17+
return -EFAULT;
18+
}
19+
return ret;
20+
}
21+
22+
int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
23+
{
24+
struct mbox_msghdr *req;
25+
26+
req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
27+
sizeof(struct ready_msg_rsp));
28+
if (req == NULL) {
29+
dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
30+
return -EFAULT;
31+
}
32+
req->id = MBOX_MSG_READY;
33+
req->sig = OTX2_MBOX_REQ_SIG;
34+
req->pcifunc = 0;
35+
36+
return otx2_cpt_send_mbox_msg(mbox, pdev);
37+
}

drivers/crypto/marvell/octeontx2/otx2_cptpf.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,21 @@
55
#ifndef __OTX2_CPTPF_H
66
#define __OTX2_CPTPF_H
77

8+
#include "otx2_cpt_common.h"
9+
810
struct otx2_cptpf_dev {
911
void __iomem *reg_base; /* CPT PF registers start address */
12+
void __iomem *afpf_mbox_base; /* PF-AF mbox start address */
1013
struct pci_dev *pdev; /* PCI device handle */
14+
/* AF <=> PF mbox */
15+
struct otx2_mbox afpf_mbox;
16+
struct work_struct afpf_mbox_work;
17+
struct workqueue_struct *afpf_mbox_wq;
18+
19+
u8 pf_id; /* RVU PF number */
1120
};
1221

22+
irqreturn_t otx2_cptpf_afpf_mbox_intr(int irq, void *arg);
23+
void otx2_cptpf_afpf_mbox_handler(struct work_struct *work);
24+
1325
#endif /* __OTX2_CPTPF_H */

drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,75 @@
1010
#define OTX2_CPT_DRV_NAME "octeontx2-cpt"
1111
#define OTX2_CPT_DRV_STRING "Marvell OcteonTX2 CPT Physical Function Driver"
1212

13+
static void cptpf_disable_afpf_mbox_intr(struct otx2_cptpf_dev *cptpf)
14+
{
15+
/* Disable AF-PF interrupt */
16+
otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT_ENA_W1C,
17+
0x1ULL);
18+
/* Clear interrupt if any */
19+
otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT, 0x1ULL);
20+
}
21+
22+
static int cptpf_register_afpf_mbox_intr(struct otx2_cptpf_dev *cptpf)
23+
{
24+
struct pci_dev *pdev = cptpf->pdev;
25+
struct device *dev = &pdev->dev;
26+
int ret, irq;
27+
28+
irq = pci_irq_vector(pdev, RVU_PF_INT_VEC_AFPF_MBOX);
29+
/* Register AF-PF mailbox interrupt handler */
30+
ret = devm_request_irq(dev, irq, otx2_cptpf_afpf_mbox_intr, 0,
31+
"CPTAFPF Mbox", cptpf);
32+
if (ret) {
33+
dev_err(dev,
34+
"IRQ registration failed for PFAF mbox irq\n");
35+
return ret;
36+
}
37+
/* Clear interrupt if any, to avoid spurious interrupts */
38+
otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT, 0x1ULL);
39+
/* Enable AF-PF interrupt */
40+
otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT_ENA_W1S,
41+
0x1ULL);
42+
43+
ret = otx2_cpt_send_ready_msg(&cptpf->afpf_mbox, cptpf->pdev);
44+
if (ret) {
45+
dev_warn(dev,
46+
"AF not responding to mailbox, deferring probe\n");
47+
cptpf_disable_afpf_mbox_intr(cptpf);
48+
return -EPROBE_DEFER;
49+
}
50+
return 0;
51+
}
52+
53+
static int cptpf_afpf_mbox_init(struct otx2_cptpf_dev *cptpf)
54+
{
55+
int err;
56+
57+
cptpf->afpf_mbox_wq = alloc_workqueue("cpt_afpf_mailbox",
58+
WQ_UNBOUND | WQ_HIGHPRI |
59+
WQ_MEM_RECLAIM, 1);
60+
if (!cptpf->afpf_mbox_wq)
61+
return -ENOMEM;
62+
63+
err = otx2_mbox_init(&cptpf->afpf_mbox, cptpf->afpf_mbox_base,
64+
cptpf->pdev, cptpf->reg_base, MBOX_DIR_PFAF, 1);
65+
if (err)
66+
goto error;
67+
68+
INIT_WORK(&cptpf->afpf_mbox_work, otx2_cptpf_afpf_mbox_handler);
69+
return 0;
70+
71+
error:
72+
destroy_workqueue(cptpf->afpf_mbox_wq);
73+
return err;
74+
}
75+
76+
static void cptpf_afpf_mbox_destroy(struct otx2_cptpf_dev *cptpf)
77+
{
78+
destroy_workqueue(cptpf->afpf_mbox_wq);
79+
otx2_mbox_destroy(&cptpf->afpf_mbox);
80+
}
81+
1382
static int cpt_is_pf_usable(struct otx2_cptpf_dev *cptpf)
1483
{
1584
u64 rev;
@@ -33,6 +102,7 @@ static int otx2_cptpf_probe(struct pci_dev *pdev,
33102
const struct pci_device_id *ent)
34103
{
35104
struct device *dev = &pdev->dev;
105+
resource_size_t offset, size;
36106
struct otx2_cptpf_dev *cptpf;
37107
int err;
38108

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

142+
offset = pci_resource_start(pdev, PCI_MBOX_BAR_NUM);
143+
size = pci_resource_len(pdev, PCI_MBOX_BAR_NUM);
144+
/* Map AF-PF mailbox memory */
145+
cptpf->afpf_mbox_base = devm_ioremap_wc(dev, offset, size);
146+
if (!cptpf->afpf_mbox_base) {
147+
dev_err(&pdev->dev, "Unable to map BAR4\n");
148+
err = -ENODEV;
149+
goto clear_drvdata;
150+
}
151+
err = pci_alloc_irq_vectors(pdev, RVU_PF_INT_VEC_CNT,
152+
RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX);
153+
if (err < 0) {
154+
dev_err(dev, "Request for %d msix vectors failed\n",
155+
RVU_PF_INT_VEC_CNT);
156+
goto clear_drvdata;
157+
}
158+
/* Initialize AF-PF mailbox */
159+
err = cptpf_afpf_mbox_init(cptpf);
160+
if (err)
161+
goto clear_drvdata;
162+
/* Register mailbox interrupt */
163+
err = cptpf_register_afpf_mbox_intr(cptpf);
164+
if (err)
165+
goto destroy_afpf_mbox;
166+
72167
return 0;
73168

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

83180
if (!cptpf)
84181
return;
85-
182+
/* Disable AF-PF mailbox interrupt */
183+
cptpf_disable_afpf_mbox_intr(cptpf);
184+
/* Destroy AF-PF mbox */
185+
cptpf_afpf_mbox_destroy(cptpf);
86186
pci_set_drvdata(pdev, NULL);
87187
}
88188

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (C) 2020 Marvell. */
3+
4+
#include "otx2_cpt_common.h"
5+
#include "otx2_cptpf.h"
6+
#include "rvu_reg.h"
7+
8+
irqreturn_t otx2_cptpf_afpf_mbox_intr(int __always_unused irq, void *arg)
9+
{
10+
struct otx2_cptpf_dev *cptpf = arg;
11+
u64 intr;
12+
13+
/* Read the interrupt bits */
14+
intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT);
15+
16+
if (intr & 0x1ULL) {
17+
/* Schedule work queue function to process the MBOX request */
18+
queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_work);
19+
/* Clear and ack the interrupt */
20+
otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT,
21+
0x1ULL);
22+
}
23+
return IRQ_HANDLED;
24+
}
25+
26+
static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
27+
struct mbox_msghdr *msg)
28+
{
29+
struct device *dev = &cptpf->pdev->dev;
30+
31+
if (msg->id >= MBOX_MSG_MAX) {
32+
dev_err(dev, "MBOX msg with unknown ID %d\n", msg->id);
33+
return;
34+
}
35+
if (msg->sig != OTX2_MBOX_RSP_SIG) {
36+
dev_err(dev, "MBOX msg with wrong signature %x, ID %d\n",
37+
msg->sig, msg->id);
38+
return;
39+
}
40+
41+
switch (msg->id) {
42+
case MBOX_MSG_READY:
43+
cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) &
44+
RVU_PFVF_PF_MASK;
45+
break;
46+
default:
47+
dev_err(dev,
48+
"Unsupported msg %d received.\n", msg->id);
49+
break;
50+
}
51+
}
52+
53+
/* Handle mailbox messages received from AF */
54+
void otx2_cptpf_afpf_mbox_handler(struct work_struct *work)
55+
{
56+
struct otx2_cptpf_dev *cptpf;
57+
struct otx2_mbox *afpf_mbox;
58+
struct otx2_mbox_dev *mdev;
59+
struct mbox_hdr *rsp_hdr;
60+
struct mbox_msghdr *msg;
61+
int offset, i;
62+
63+
cptpf = container_of(work, struct otx2_cptpf_dev, afpf_mbox_work);
64+
afpf_mbox = &cptpf->afpf_mbox;
65+
mdev = &afpf_mbox->dev[0];
66+
/* Sync mbox data into memory */
67+
smp_wmb();
68+
69+
rsp_hdr = (struct mbox_hdr *)(mdev->mbase + afpf_mbox->rx_start);
70+
offset = ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
71+
72+
for (i = 0; i < rsp_hdr->num_msgs; i++) {
73+
msg = (struct mbox_msghdr *)(mdev->mbase + afpf_mbox->rx_start +
74+
offset);
75+
process_afpf_mbox_msg(cptpf, msg);
76+
offset = msg->next_msgoff;
77+
mdev->msgs_acked++;
78+
}
79+
otx2_mbox_reset(afpf_mbox, 0);
80+
}

0 commit comments

Comments
 (0)