forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
4.6 KiB
204 lines
4.6 KiB
// SPDX-License-Identifier: GPL-2.0-only |
|
/* Copyright (C) 2020 Marvell. */ |
|
|
|
#include "otx2_cpt_common.h" |
|
#include "otx2_cptlf.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); |
|
} |
|
|
|
int otx2_cpt_send_af_reg_requests(struct otx2_mbox *mbox, struct pci_dev *pdev) |
|
{ |
|
return otx2_cpt_send_mbox_msg(mbox, pdev); |
|
} |
|
|
|
int otx2_cpt_add_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, |
|
u64 reg, u64 *val, int blkaddr) |
|
{ |
|
struct cpt_rd_wr_reg_msg *reg_msg; |
|
|
|
reg_msg = (struct cpt_rd_wr_reg_msg *) |
|
otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg), |
|
sizeof(*reg_msg)); |
|
if (reg_msg == NULL) { |
|
dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); |
|
return -EFAULT; |
|
} |
|
|
|
reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER; |
|
reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG; |
|
reg_msg->hdr.pcifunc = 0; |
|
|
|
reg_msg->is_write = 0; |
|
reg_msg->reg_offset = reg; |
|
reg_msg->ret_val = val; |
|
reg_msg->blkaddr = blkaddr; |
|
|
|
return 0; |
|
} |
|
|
|
int otx2_cpt_add_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, |
|
u64 reg, u64 val, int blkaddr) |
|
{ |
|
struct cpt_rd_wr_reg_msg *reg_msg; |
|
|
|
reg_msg = (struct cpt_rd_wr_reg_msg *) |
|
otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*reg_msg), |
|
sizeof(*reg_msg)); |
|
if (reg_msg == NULL) { |
|
dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); |
|
return -EFAULT; |
|
} |
|
|
|
reg_msg->hdr.id = MBOX_MSG_CPT_RD_WR_REGISTER; |
|
reg_msg->hdr.sig = OTX2_MBOX_REQ_SIG; |
|
reg_msg->hdr.pcifunc = 0; |
|
|
|
reg_msg->is_write = 1; |
|
reg_msg->reg_offset = reg; |
|
reg_msg->val = val; |
|
reg_msg->blkaddr = blkaddr; |
|
|
|
return 0; |
|
} |
|
|
|
int otx2_cpt_read_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, |
|
u64 reg, u64 *val, int blkaddr) |
|
{ |
|
int ret; |
|
|
|
ret = otx2_cpt_add_read_af_reg(mbox, pdev, reg, val, blkaddr); |
|
if (ret) |
|
return ret; |
|
|
|
return otx2_cpt_send_mbox_msg(mbox, pdev); |
|
} |
|
|
|
int otx2_cpt_write_af_reg(struct otx2_mbox *mbox, struct pci_dev *pdev, |
|
u64 reg, u64 val, int blkaddr) |
|
{ |
|
int ret; |
|
|
|
ret = otx2_cpt_add_write_af_reg(mbox, pdev, reg, val, blkaddr); |
|
if (ret) |
|
return ret; |
|
|
|
return otx2_cpt_send_mbox_msg(mbox, pdev); |
|
} |
|
|
|
int otx2_cpt_attach_rscrs_msg(struct otx2_cptlfs_info *lfs) |
|
{ |
|
struct otx2_mbox *mbox = lfs->mbox; |
|
struct rsrc_attach *req; |
|
int ret; |
|
|
|
req = (struct rsrc_attach *) |
|
otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), |
|
sizeof(struct msg_rsp)); |
|
if (req == NULL) { |
|
dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n"); |
|
return -EFAULT; |
|
} |
|
|
|
req->hdr.id = MBOX_MSG_ATTACH_RESOURCES; |
|
req->hdr.sig = OTX2_MBOX_REQ_SIG; |
|
req->hdr.pcifunc = 0; |
|
req->cptlfs = lfs->lfs_num; |
|
ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev); |
|
if (ret) |
|
return ret; |
|
|
|
if (!lfs->are_lfs_attached) |
|
ret = -EINVAL; |
|
|
|
return ret; |
|
} |
|
|
|
int otx2_cpt_detach_rsrcs_msg(struct otx2_cptlfs_info *lfs) |
|
{ |
|
struct otx2_mbox *mbox = lfs->mbox; |
|
struct rsrc_detach *req; |
|
int ret; |
|
|
|
req = (struct rsrc_detach *) |
|
otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), |
|
sizeof(struct msg_rsp)); |
|
if (req == NULL) { |
|
dev_err(&lfs->pdev->dev, "RVU MBOX failed to get message.\n"); |
|
return -EFAULT; |
|
} |
|
|
|
req->hdr.id = MBOX_MSG_DETACH_RESOURCES; |
|
req->hdr.sig = OTX2_MBOX_REQ_SIG; |
|
req->hdr.pcifunc = 0; |
|
ret = otx2_cpt_send_mbox_msg(mbox, lfs->pdev); |
|
if (ret) |
|
return ret; |
|
|
|
if (lfs->are_lfs_attached) |
|
ret = -EINVAL; |
|
|
|
return ret; |
|
} |
|
|
|
int otx2_cpt_msix_offset_msg(struct otx2_cptlfs_info *lfs) |
|
{ |
|
struct otx2_mbox *mbox = lfs->mbox; |
|
struct pci_dev *pdev = lfs->pdev; |
|
struct mbox_msghdr *req; |
|
int ret, i; |
|
|
|
req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), |
|
sizeof(struct msix_offset_rsp)); |
|
if (req == NULL) { |
|
dev_err(&pdev->dev, "RVU MBOX failed to get message.\n"); |
|
return -EFAULT; |
|
} |
|
|
|
req->id = MBOX_MSG_MSIX_OFFSET; |
|
req->sig = OTX2_MBOX_REQ_SIG; |
|
req->pcifunc = 0; |
|
ret = otx2_cpt_send_mbox_msg(mbox, pdev); |
|
if (ret) |
|
return ret; |
|
|
|
for (i = 0; i < lfs->lfs_num; i++) { |
|
if (lfs->lf[i].msix_offset == MSIX_VECTOR_INVALID) { |
|
dev_err(&pdev->dev, |
|
"Invalid msix offset %d for LF %d\n", |
|
lfs->lf[i].msix_offset, i); |
|
return -EINVAL; |
|
} |
|
} |
|
return ret; |
|
}
|
|
|