1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2020 Marvell. */
3 
4 #include "otx2_cpt_common.h"
5 #include "otx2_cptlf.h"
6 
7 int otx2_cpt_send_mbox_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
8 {
9 	int ret;
10 
11 	otx2_mbox_msg_send(mbox, 0);
12 	ret = otx2_mbox_wait_for_rsp(mbox, 0);
13 	if (ret == -EIO) {
14 		dev_err(&pdev->dev, "RVU MBOX timeout.\n");
15 		return ret;
16 	} else if (ret) {
17 		dev_err(&pdev->dev, "RVU MBOX error: %d.\n", ret);
18 		return -EFAULT;
19 	}
20 	return ret;
21 }
22 
23 int otx2_cpt_send_ready_msg(struct otx2_mbox *mbox, struct pci_dev *pdev)
24 {
25 	struct mbox_msghdr *req;
26 
27 	req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
28 				      sizeof(struct ready_msg_rsp));
29 	if (req == NULL) {
30 		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
31 		return -EFAULT;
32 	}
33 	req->id = MBOX_MSG_READY;
34 	req->sig = OTX2_MBOX_REQ_SIG;
35 	req->pcifunc = 0;
36 
37 	return otx2_cpt_send_mbox_msg(mbox, pdev);
38 }
39 
40 int otx2_cpt_send_af_reg_requests(struct otx2_mbox *mbox, struct pci_dev *pdev)
41 {
42 	return otx2_cpt_send_mbox_msg(mbox, pdev);
43 }
44 
45 int otx2_cpt_add_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
46 			     u64 reg, u64 *val)
47 {
48 	struct cpt_rd_wr_reg_msg *reg_msg;
49 
50 	reg_msg = (struct cpt_rd_wr_reg_msg *)
51 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg),
52 						sizeof(*reg_msg));
53 	if (reg_msg == NULL) {
54 		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
55 		return -EFAULT;
56 	}
57 
58 	reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
59 	reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG;
60 	reg_msg->hdr.pcifunc = 0;
61 
62 	reg_msg->is_write = 0;
63 	reg_msg->reg_offset = reg;
64 	reg_msg->ret_val = val;
65 
66 	return 0;
67 }
68 
69 int otx2_cpt_add_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
70 			      u64 reg, u64 val)
71 {
72 	struct cpt_rd_wr_reg_msg *reg_msg;
73 
74 	reg_msg = (struct cpt_rd_wr_reg_msg *)
75 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg),
76 						sizeof(*reg_msg));
77 	if (reg_msg == NULL) {
78 		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
79 		return -EFAULT;
80 	}
81 
82 	reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER;
83 	reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG;
84 	reg_msg->hdr.pcifunc = 0;
85 
86 	reg_msg->is_write = 1;
87 	reg_msg->reg_offset = reg;
88 	reg_msg->val = val;
89 
90 	return 0;
91 }
92 
93 int otx2_cpt_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
94 			 u64 reg, u64 *val)
95 {
96 	int ret;
97 
98 	ret = otx2_cpt_add_read_af_reg(mbox, pdev, reg, val);
99 	if (ret)
100 		return ret;
101 
102 	return otx2_cpt_send_mbox_msg(mbox, pdev);
103 }
104 
105 int otx2_cpt_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev,
106 			  u64 reg, u64 val)
107 {
108 	int ret;
109 
110 	ret = otx2_cpt_add_write_af_reg(mbox, pdev, reg, val);
111 	if (ret)
112 		return ret;
113 
114 	return otx2_cpt_send_mbox_msg(mbox, pdev);
115 }
116 
117 int otx2_cpt_attach_rscrs_msg(struct otx2_cptlfs_info *lfs)
118 {
119 	struct otx2_mbox *mbox = lfs->mbox;
120 	struct rsrc_attach *req;
121 	int ret;
122 
123 	req = (struct rsrc_attach *)
124 			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
125 						sizeof(struct msg_rsp));
126 	if (req == NULL) {
127 		dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n");
128 		return -EFAULT;
129 	}
130 
131 	req->hdr.id = MBOX_MSG_ATTACH_RESOURCES;
132 	req->hdr.sig = OTX2_MBOX_REQ_SIG;
133 	req->hdr.pcifunc = 0;
134 	req->cptlfs = lfs->lfs_num;
135 	ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev);
136 	if (ret)
137 		return ret;
138 
139 	if (!lfs->are_lfs_attached)
140 		ret = -EINVAL;
141 
142 	return ret;
143 }
144 
145 int otx2_cpt_detach_rsrcs_msg(struct otx2_cptlfs_info *lfs)
146 {
147 	struct otx2_mbox *mbox = lfs->mbox;
148 	struct rsrc_detach *req;
149 	int ret;
150 
151 	req = (struct rsrc_detach *)
152 				otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
153 							sizeof(struct msg_rsp));
154 	if (req == NULL) {
155 		dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n");
156 		return -EFAULT;
157 	}
158 
159 	req->hdr.id = MBOX_MSG_DETACH_RESOURCES;
160 	req->hdr.sig = OTX2_MBOX_REQ_SIG;
161 	req->hdr.pcifunc = 0;
162 	ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev);
163 	if (ret)
164 		return ret;
165 
166 	if (lfs->are_lfs_attached)
167 		ret = -EINVAL;
168 
169 	return ret;
170 }
171 
172 int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs)
173 {
174 	struct otx2_mbox *mbox = lfs->mbox;
175 	struct pci_dev *pdev = lfs->pdev;
176 	struct mbox_msghdr *req;
177 	int ret, i;
178 
179 	req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
180 				      sizeof(struct msix_offset_rsp));
181 	if (req == NULL) {
182 		dev_err(&pdev->dev, "RVU MBOX failed to get message.\n");
183 		return -EFAULT;
184 	}
185 
186 	req->id = MBOX_MSG_MSIX_OFFSET;
187 	req->sig = OTX2_MBOX_REQ_SIG;
188 	req->pcifunc = 0;
189 	ret = otx2_cpt_send_mbox_msg(mbox, pdev);
190 	if (ret)
191 		return ret;
192 
193 	for (i = 0; i < lfs->lfs_num; i++) {
194 		if (lfs->lf[i].msix_offset == MSIX_VECTOR_INVALID) {
195 			dev_err(&pdev->dev,
196 				"Invalid msix offset %d for LF %d\n",
197 				lfs->lf[i].msix_offset, i);
198 			return -EINVAL;
199 		}
200 	}
201 	return ret;
202 }
203