1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2016 Cavium, Inc.
8 static void cptvf_send_msg_to_pf(struct cpt_vf
*cptvf
, struct cpt_mbox
*mbx
)
10 /* Writing mbox(1) causes interrupt */
11 cpt_write_csr64(cptvf
->reg_base
, CPTX_VFX_PF_MBOXX(0, 0, 0),
13 cpt_write_csr64(cptvf
->reg_base
, CPTX_VFX_PF_MBOXX(0, 0, 1),
17 /* Interrupt handler to handle mailbox messages from VFs */
18 void cptvf_handle_mbox_intr(struct cpt_vf
*cptvf
)
20 struct cpt_mbox mbx
= {};
23 * MBOX[0] contains msg
24 * MBOX[1] contains data
26 mbx
.msg
= cpt_read_csr64(cptvf
->reg_base
, CPTX_VFX_PF_MBOXX(0, 0, 0));
27 mbx
.data
= cpt_read_csr64(cptvf
->reg_base
, CPTX_VFX_PF_MBOXX(0, 0, 1));
28 dev_dbg(&cptvf
->pdev
->dev
, "%s: Mailbox msg 0x%llx from PF\n",
33 cptvf
->pf_acked
= true;
34 cptvf
->vfid
= mbx
.data
;
35 dev_dbg(&cptvf
->pdev
->dev
, "Received VFID %d\n", cptvf
->vfid
);
38 case CPT_MSG_QBIND_GRP
:
39 cptvf
->pf_acked
= true;
40 cptvf
->vftype
= mbx
.data
;
41 dev_dbg(&cptvf
->pdev
->dev
, "VF %d type %s group %d\n",
42 cptvf
->vfid
, ((mbx
.data
== SE_TYPES
) ? "SE" : "AE"),
45 case CPT_MBOX_MSG_TYPE_ACK
:
46 cptvf
->pf_acked
= true;
48 case CPT_MBOX_MSG_TYPE_NACK
:
49 cptvf
->pf_nacked
= true;
52 dev_err(&cptvf
->pdev
->dev
, "Invalid msg from PF, msg 0x%llx\n",
58 static int cptvf_send_msg_to_pf_timeout(struct cpt_vf
*cptvf
,
61 int timeout
= CPT_MBOX_MSG_TIMEOUT
;
64 cptvf
->pf_acked
= false;
65 cptvf
->pf_nacked
= false;
66 cptvf_send_msg_to_pf(cptvf
, mbx
);
67 /* Wait for previous message to be acked, timeout 2sec */
68 while (!cptvf
->pf_acked
) {
76 dev_err(&cptvf
->pdev
->dev
, "PF didn't ack to mbox msg %llx from VF%u\n",
77 (mbx
->msg
& 0xFF), cptvf
->vfid
);
86 * Checks if VF is able to comminicate with PF
87 * and also gets the CPT number this VF is associated to.
89 int cptvf_check_pf_ready(struct cpt_vf
*cptvf
)
91 struct pci_dev
*pdev
= cptvf
->pdev
;
92 struct cpt_mbox mbx
= {};
94 mbx
.msg
= CPT_MSG_READY
;
95 if (cptvf_send_msg_to_pf_timeout(cptvf
, &mbx
)) {
96 dev_err(&pdev
->dev
, "PF didn't respond to READY msg\n");
104 * Communicate VQs size to PF to program CPT(0)_PF_Q(0-15)_CTL of the VF.
107 int cptvf_send_vq_size_msg(struct cpt_vf
*cptvf
)
109 struct pci_dev
*pdev
= cptvf
->pdev
;
110 struct cpt_mbox mbx
= {};
112 mbx
.msg
= CPT_MSG_QLEN
;
113 mbx
.data
= cptvf
->qsize
;
114 if (cptvf_send_msg_to_pf_timeout(cptvf
, &mbx
)) {
115 dev_err(&pdev
->dev
, "PF didn't respond to vq_size msg\n");
123 * Communicate VF group required to PF and get the VQ binded to that group
125 int cptvf_send_vf_to_grp_msg(struct cpt_vf
*cptvf
)
127 struct pci_dev
*pdev
= cptvf
->pdev
;
128 struct cpt_mbox mbx
= {};
130 mbx
.msg
= CPT_MSG_QBIND_GRP
;
131 /* Convey group of the VF */
132 mbx
.data
= cptvf
->vfgrp
;
133 if (cptvf_send_msg_to_pf_timeout(cptvf
, &mbx
)) {
134 dev_err(&pdev
->dev
, "PF didn't respond to vf_type msg\n");
142 * Communicate VF group required to PF and get the VQ binded to that group
144 int cptvf_send_vf_priority_msg(struct cpt_vf
*cptvf
)
146 struct pci_dev
*pdev
= cptvf
->pdev
;
147 struct cpt_mbox mbx
= {};
149 mbx
.msg
= CPT_MSG_VQ_PRIORITY
;
150 /* Convey group of the VF */
151 mbx
.data
= cptvf
->priority
;
152 if (cptvf_send_msg_to_pf_timeout(cptvf
, &mbx
)) {
153 dev_err(&pdev
->dev
, "PF didn't respond to vf_type msg\n");
160 * Communicate to PF that VF is UP and running
162 int cptvf_send_vf_up(struct cpt_vf
*cptvf
)
164 struct pci_dev
*pdev
= cptvf
->pdev
;
165 struct cpt_mbox mbx
= {};
167 mbx
.msg
= CPT_MSG_VF_UP
;
168 if (cptvf_send_msg_to_pf_timeout(cptvf
, &mbx
)) {
169 dev_err(&pdev
->dev
, "PF didn't respond to UP msg\n");
177 * Communicate to PF that VF is DOWN and running
179 int cptvf_send_vf_down(struct cpt_vf
*cptvf
)
181 struct pci_dev
*pdev
= cptvf
->pdev
;
182 struct cpt_mbox mbx
= {};
184 mbx
.msg
= CPT_MSG_VF_DOWN
;
185 if (cptvf_send_msg_to_pf_timeout(cptvf
, &mbx
)) {
186 dev_err(&pdev
->dev
, "PF didn't respond to DOWN msg\n");