0001
0002
0003
0004 #include "otx2_cpt_common.h"
0005 #include "otx2_cptpf.h"
0006 #include "rvu_reg.h"
0007
0008
0009
0010
0011
0012 #define OTX2_CPT_PF_DRV_VERSION 0x1
0013
0014 static int forward_to_af(struct otx2_cptpf_dev *cptpf,
0015 struct otx2_cptvf_info *vf,
0016 struct mbox_msghdr *req, int size)
0017 {
0018 struct mbox_msghdr *msg;
0019 int ret;
0020
0021 mutex_lock(&cptpf->lock);
0022 msg = otx2_mbox_alloc_msg(&cptpf->afpf_mbox, 0, size);
0023 if (msg == NULL) {
0024 mutex_unlock(&cptpf->lock);
0025 return -ENOMEM;
0026 }
0027
0028 memcpy((uint8_t *)msg + sizeof(struct mbox_msghdr),
0029 (uint8_t *)req + sizeof(struct mbox_msghdr), size);
0030 msg->id = req->id;
0031 msg->pcifunc = req->pcifunc;
0032 msg->sig = req->sig;
0033 msg->ver = req->ver;
0034
0035 ret = otx2_cpt_sync_mbox_msg(&cptpf->afpf_mbox);
0036
0037
0038
0039
0040
0041 if (ret == -EIO) {
0042 dev_warn(&cptpf->pdev->dev,
0043 "AF not responding to VF%d messages\n", vf->vf_id);
0044 mutex_unlock(&cptpf->lock);
0045 return ret;
0046 }
0047 mutex_unlock(&cptpf->lock);
0048 return 0;
0049 }
0050
0051 static int handle_msg_get_caps(struct otx2_cptpf_dev *cptpf,
0052 struct otx2_cptvf_info *vf,
0053 struct mbox_msghdr *req)
0054 {
0055 struct otx2_cpt_caps_rsp *rsp;
0056
0057 rsp = (struct otx2_cpt_caps_rsp *)
0058 otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id,
0059 sizeof(*rsp));
0060 if (!rsp)
0061 return -ENOMEM;
0062
0063 rsp->hdr.id = MBOX_MSG_GET_CAPS;
0064 rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
0065 rsp->hdr.pcifunc = req->pcifunc;
0066 rsp->cpt_pf_drv_version = OTX2_CPT_PF_DRV_VERSION;
0067 rsp->cpt_revision = cptpf->pdev->revision;
0068 memcpy(&rsp->eng_caps, &cptpf->eng_caps, sizeof(rsp->eng_caps));
0069
0070 return 0;
0071 }
0072
0073 static int handle_msg_get_eng_grp_num(struct otx2_cptpf_dev *cptpf,
0074 struct otx2_cptvf_info *vf,
0075 struct mbox_msghdr *req)
0076 {
0077 struct otx2_cpt_egrp_num_msg *grp_req;
0078 struct otx2_cpt_egrp_num_rsp *rsp;
0079
0080 grp_req = (struct otx2_cpt_egrp_num_msg *)req;
0081 rsp = (struct otx2_cpt_egrp_num_rsp *)
0082 otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id, sizeof(*rsp));
0083 if (!rsp)
0084 return -ENOMEM;
0085
0086 rsp->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;
0087 rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
0088 rsp->hdr.pcifunc = req->pcifunc;
0089 rsp->eng_type = grp_req->eng_type;
0090 rsp->eng_grp_num = otx2_cpt_get_eng_grp(&cptpf->eng_grps,
0091 grp_req->eng_type);
0092
0093 return 0;
0094 }
0095
0096 static int handle_msg_kvf_limits(struct otx2_cptpf_dev *cptpf,
0097 struct otx2_cptvf_info *vf,
0098 struct mbox_msghdr *req)
0099 {
0100 struct otx2_cpt_kvf_limits_rsp *rsp;
0101
0102 rsp = (struct otx2_cpt_kvf_limits_rsp *)
0103 otx2_mbox_alloc_msg(&cptpf->vfpf_mbox, vf->vf_id, sizeof(*rsp));
0104 if (!rsp)
0105 return -ENOMEM;
0106
0107 rsp->hdr.id = MBOX_MSG_GET_KVF_LIMITS;
0108 rsp->hdr.sig = OTX2_MBOX_RSP_SIG;
0109 rsp->hdr.pcifunc = req->pcifunc;
0110 rsp->kvf_limits = cptpf->kvf_limits;
0111
0112 return 0;
0113 }
0114
0115 static int cptpf_handle_vf_req(struct otx2_cptpf_dev *cptpf,
0116 struct otx2_cptvf_info *vf,
0117 struct mbox_msghdr *req, int size)
0118 {
0119 int err = 0;
0120
0121
0122 if (req->sig != OTX2_MBOX_REQ_SIG)
0123 goto inval_msg;
0124
0125 switch (req->id) {
0126 case MBOX_MSG_GET_ENG_GRP_NUM:
0127 err = handle_msg_get_eng_grp_num(cptpf, vf, req);
0128 break;
0129 case MBOX_MSG_GET_CAPS:
0130 err = handle_msg_get_caps(cptpf, vf, req);
0131 break;
0132 case MBOX_MSG_GET_KVF_LIMITS:
0133 err = handle_msg_kvf_limits(cptpf, vf, req);
0134 break;
0135 default:
0136 err = forward_to_af(cptpf, vf, req, size);
0137 break;
0138 }
0139 return err;
0140
0141 inval_msg:
0142 otx2_reply_invalid_msg(&cptpf->vfpf_mbox, vf->vf_id, 0, req->id);
0143 otx2_mbox_msg_send(&cptpf->vfpf_mbox, vf->vf_id);
0144 return err;
0145 }
0146
0147 irqreturn_t otx2_cptpf_vfpf_mbox_intr(int __always_unused irq, void *arg)
0148 {
0149 struct otx2_cptpf_dev *cptpf = arg;
0150 struct otx2_cptvf_info *vf;
0151 int i, vf_idx;
0152 u64 intr;
0153
0154
0155
0156
0157
0158 for (i = 0; i < 2; i++) {
0159
0160 intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0,
0161 RVU_PF_VFPF_MBOX_INTX(i));
0162
0163 for (vf_idx = i * 64; vf_idx < cptpf->enabled_vfs; vf_idx++) {
0164 vf = &cptpf->vf[vf_idx];
0165 if (intr & (1ULL << vf->intr_idx)) {
0166 queue_work(cptpf->vfpf_mbox_wq,
0167 &vf->vfpf_mbox_work);
0168
0169 otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM,
0170 0, RVU_PF_VFPF_MBOX_INTX(i),
0171 BIT_ULL(vf->intr_idx));
0172 }
0173 }
0174 }
0175 return IRQ_HANDLED;
0176 }
0177
0178 void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work)
0179 {
0180 struct otx2_cptpf_dev *cptpf;
0181 struct otx2_cptvf_info *vf;
0182 struct otx2_mbox_dev *mdev;
0183 struct mbox_hdr *req_hdr;
0184 struct mbox_msghdr *msg;
0185 struct otx2_mbox *mbox;
0186 int offset, i, err;
0187
0188 vf = container_of(work, struct otx2_cptvf_info, vfpf_mbox_work);
0189 cptpf = vf->cptpf;
0190 mbox = &cptpf->vfpf_mbox;
0191
0192 smp_rmb();
0193 mdev = &mbox->dev[vf->vf_id];
0194
0195 req_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
0196 offset = mbox->rx_start + ALIGN(sizeof(*req_hdr), MBOX_MSG_ALIGN);
0197
0198 for (i = 0; i < req_hdr->num_msgs; i++) {
0199 msg = (struct mbox_msghdr *)(mdev->mbase + offset);
0200
0201
0202 msg->pcifunc = ((u16)cptpf->pf_id << RVU_PFVF_PF_SHIFT) |
0203 ((vf->vf_id + 1) & RVU_PFVF_FUNC_MASK);
0204
0205 err = cptpf_handle_vf_req(cptpf, vf, msg,
0206 msg->next_msgoff - offset);
0207
0208
0209
0210
0211 if (err == -ENOMEM || err == -EIO)
0212 break;
0213 offset = msg->next_msgoff;
0214
0215
0216
0217 smp_wmb();
0218 }
0219
0220 if (mdev->num_msgs)
0221 otx2_mbox_msg_send(mbox, vf->vf_id);
0222 }
0223
0224 irqreturn_t otx2_cptpf_afpf_mbox_intr(int __always_unused irq, void *arg)
0225 {
0226 struct otx2_cptpf_dev *cptpf = arg;
0227 u64 intr;
0228
0229
0230 intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT);
0231
0232 if (intr & 0x1ULL) {
0233
0234 queue_work(cptpf->afpf_mbox_wq, &cptpf->afpf_mbox_work);
0235
0236 otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT,
0237 0x1ULL);
0238 }
0239 return IRQ_HANDLED;
0240 }
0241
0242 static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
0243 struct mbox_msghdr *msg)
0244 {
0245 struct device *dev = &cptpf->pdev->dev;
0246 struct cpt_rd_wr_reg_msg *rsp_rd_wr;
0247
0248 if (msg->id >= MBOX_MSG_MAX) {
0249 dev_err(dev, "MBOX msg with unknown ID %d\n", msg->id);
0250 return;
0251 }
0252 if (msg->sig != OTX2_MBOX_RSP_SIG) {
0253 dev_err(dev, "MBOX msg with wrong signature %x, ID %d\n",
0254 msg->sig, msg->id);
0255 return;
0256 }
0257
0258 switch (msg->id) {
0259 case MBOX_MSG_READY:
0260 cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) &
0261 RVU_PFVF_PF_MASK;
0262 break;
0263 case MBOX_MSG_CPT_RD_WR_REGISTER:
0264 rsp_rd_wr = (struct cpt_rd_wr_reg_msg *)msg;
0265 if (msg->rc) {
0266 dev_err(dev, "Reg %llx rd/wr(%d) failed %d\n",
0267 rsp_rd_wr->reg_offset, rsp_rd_wr->is_write,
0268 msg->rc);
0269 return;
0270 }
0271 if (!rsp_rd_wr->is_write)
0272 *rsp_rd_wr->ret_val = rsp_rd_wr->val;
0273 break;
0274 case MBOX_MSG_ATTACH_RESOURCES:
0275 if (!msg->rc)
0276 cptpf->lfs.are_lfs_attached = 1;
0277 break;
0278 case MBOX_MSG_DETACH_RESOURCES:
0279 if (!msg->rc)
0280 cptpf->lfs.are_lfs_attached = 0;
0281 break;
0282
0283 default:
0284 dev_err(dev,
0285 "Unsupported msg %d received.\n", msg->id);
0286 break;
0287 }
0288 }
0289
0290 static void forward_to_vf(struct otx2_cptpf_dev *cptpf, struct mbox_msghdr *msg,
0291 int vf_id, int size)
0292 {
0293 struct otx2_mbox *vfpf_mbox;
0294 struct mbox_msghdr *fwd;
0295
0296 if (msg->id >= MBOX_MSG_MAX) {
0297 dev_err(&cptpf->pdev->dev,
0298 "MBOX msg with unknown ID %d\n", msg->id);
0299 return;
0300 }
0301 if (msg->sig != OTX2_MBOX_RSP_SIG) {
0302 dev_err(&cptpf->pdev->dev,
0303 "MBOX msg with wrong signature %x, ID %d\n",
0304 msg->sig, msg->id);
0305 return;
0306 }
0307 vfpf_mbox = &cptpf->vfpf_mbox;
0308 vf_id--;
0309 if (vf_id >= cptpf->enabled_vfs) {
0310 dev_err(&cptpf->pdev->dev,
0311 "MBOX msg to unknown VF: %d >= %d\n",
0312 vf_id, cptpf->enabled_vfs);
0313 return;
0314 }
0315 if (msg->id == MBOX_MSG_VF_FLR)
0316 return;
0317
0318 fwd = otx2_mbox_alloc_msg(vfpf_mbox, vf_id, size);
0319 if (!fwd) {
0320 dev_err(&cptpf->pdev->dev,
0321 "Forwarding to VF%d failed.\n", vf_id);
0322 return;
0323 }
0324 memcpy((uint8_t *)fwd + sizeof(struct mbox_msghdr),
0325 (uint8_t *)msg + sizeof(struct mbox_msghdr), size);
0326 fwd->id = msg->id;
0327 fwd->pcifunc = msg->pcifunc;
0328 fwd->sig = msg->sig;
0329 fwd->ver = msg->ver;
0330 fwd->rc = msg->rc;
0331 }
0332
0333
0334 void otx2_cptpf_afpf_mbox_handler(struct work_struct *work)
0335 {
0336 struct otx2_cptpf_dev *cptpf;
0337 struct otx2_mbox *afpf_mbox;
0338 struct otx2_mbox_dev *mdev;
0339 struct mbox_hdr *rsp_hdr;
0340 struct mbox_msghdr *msg;
0341 int offset, vf_id, i;
0342
0343 cptpf = container_of(work, struct otx2_cptpf_dev, afpf_mbox_work);
0344 afpf_mbox = &cptpf->afpf_mbox;
0345 mdev = &afpf_mbox->dev[0];
0346
0347 smp_wmb();
0348
0349 rsp_hdr = (struct mbox_hdr *)(mdev->mbase + afpf_mbox->rx_start);
0350 offset = ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
0351
0352 for (i = 0; i < rsp_hdr->num_msgs; i++) {
0353 msg = (struct mbox_msghdr *)(mdev->mbase + afpf_mbox->rx_start +
0354 offset);
0355 vf_id = (msg->pcifunc >> RVU_PFVF_FUNC_SHIFT) &
0356 RVU_PFVF_FUNC_MASK;
0357 if (vf_id > 0)
0358 forward_to_vf(cptpf, msg, vf_id,
0359 msg->next_msgoff - offset);
0360 else
0361 process_afpf_mbox_msg(cptpf, msg);
0362
0363 offset = msg->next_msgoff;
0364
0365 smp_wmb();
0366 mdev->msgs_acked++;
0367 }
0368 otx2_mbox_reset(afpf_mbox, 0);
0369 }