common/cnxk: add VF support to base device class
Add VF specific handling such as BAR4 setup, forwarding VF mbox messages to AF and vice-versa, VF FLR handling etc. Signed-off-by: Jerin Jacob <jerinj@marvell.com> Acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
This commit is contained in:
parent
665ff1ccc2
commit
585bb3e538
@ -17,6 +17,337 @@
|
||||
/* Single Root I/O Virtualization */
|
||||
#define ROC_PCI_SRIOV_TOTAL_VF 0x0e /* Total VFs */
|
||||
|
||||
static void *
|
||||
mbox_mem_map(off_t off, size_t size)
|
||||
{
|
||||
void *va = MAP_FAILED;
|
||||
int mem_fd;
|
||||
|
||||
if (size <= 0 || !off) {
|
||||
plt_err("Invalid mbox area off 0x%lx size %lu", off, size);
|
||||
goto error;
|
||||
}
|
||||
|
||||
mem_fd = open("/dev/mem", O_RDWR);
|
||||
if (mem_fd < 0)
|
||||
goto error;
|
||||
|
||||
va = plt_mmap(NULL, size, PLT_PROT_READ | PLT_PROT_WRITE,
|
||||
PLT_MAP_SHARED, mem_fd, off);
|
||||
close(mem_fd);
|
||||
|
||||
if (va == MAP_FAILED)
|
||||
plt_err("Failed to mmap sz=0x%zx, fd=%d, off=%jd", size, mem_fd,
|
||||
(intmax_t)off);
|
||||
error:
|
||||
return va;
|
||||
}
|
||||
|
||||
static void
|
||||
mbox_mem_unmap(void *va, size_t size)
|
||||
{
|
||||
if (va)
|
||||
munmap(va, size);
|
||||
}
|
||||
|
||||
static int
|
||||
pf_af_sync_msg(struct dev *dev, struct mbox_msghdr **rsp)
|
||||
{
|
||||
uint32_t timeout = 0, sleep = 1;
|
||||
struct mbox *mbox = dev->mbox;
|
||||
struct mbox_dev *mdev = &mbox->dev[0];
|
||||
|
||||
volatile uint64_t int_status;
|
||||
struct mbox_msghdr *msghdr;
|
||||
uint64_t off;
|
||||
int rc = 0;
|
||||
|
||||
/* We need to disable PF interrupts. We are in timer interrupt */
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1C);
|
||||
|
||||
/* Send message */
|
||||
mbox_msg_send(mbox, 0);
|
||||
|
||||
do {
|
||||
plt_delay_ms(sleep);
|
||||
timeout += sleep;
|
||||
if (timeout >= mbox->rsp_tmo) {
|
||||
plt_err("Message timeout: %dms", mbox->rsp_tmo);
|
||||
rc = -EIO;
|
||||
break;
|
||||
}
|
||||
int_status = plt_read64(dev->bar2 + RVU_PF_INT);
|
||||
} while ((int_status & 0x1) != 0x1);
|
||||
|
||||
/* Clear */
|
||||
plt_write64(int_status, dev->bar2 + RVU_PF_INT);
|
||||
|
||||
/* Enable interrupts */
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1S);
|
||||
|
||||
if (rc == 0) {
|
||||
/* Get message */
|
||||
off = mbox->rx_start +
|
||||
PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
|
||||
msghdr = (struct mbox_msghdr *)((uintptr_t)mdev->mbase + off);
|
||||
if (rsp)
|
||||
*rsp = msghdr;
|
||||
rc = msghdr->rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
af_pf_wait_msg(struct dev *dev, uint16_t vf, int num_msg)
|
||||
{
|
||||
uint32_t timeout = 0, sleep = 1;
|
||||
struct mbox *mbox = dev->mbox;
|
||||
struct mbox_dev *mdev = &mbox->dev[0];
|
||||
volatile uint64_t int_status;
|
||||
struct mbox_hdr *req_hdr;
|
||||
struct mbox_msghdr *msg;
|
||||
struct mbox_msghdr *rsp;
|
||||
uint64_t offset;
|
||||
size_t size;
|
||||
int i;
|
||||
|
||||
/* We need to disable PF interrupts. We are in timer interrupt */
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1C);
|
||||
|
||||
/* Send message */
|
||||
mbox_msg_send(mbox, 0);
|
||||
|
||||
do {
|
||||
plt_delay_ms(sleep);
|
||||
timeout++;
|
||||
if (timeout >= mbox->rsp_tmo) {
|
||||
plt_err("Routed messages %d timeout: %dms", num_msg,
|
||||
mbox->rsp_tmo);
|
||||
break;
|
||||
}
|
||||
int_status = plt_read64(dev->bar2 + RVU_PF_INT);
|
||||
} while ((int_status & 0x1) != 0x1);
|
||||
|
||||
/* Clear */
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT);
|
||||
|
||||
/* Enable interrupts */
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1S);
|
||||
|
||||
plt_spinlock_lock(&mdev->mbox_lock);
|
||||
|
||||
req_hdr = (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->rx_start);
|
||||
if (req_hdr->num_msgs != num_msg)
|
||||
plt_err("Routed messages: %d received: %d", num_msg,
|
||||
req_hdr->num_msgs);
|
||||
|
||||
/* Get messages from mbox */
|
||||
offset = mbox->rx_start +
|
||||
PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
|
||||
for (i = 0; i < req_hdr->num_msgs; i++) {
|
||||
msg = (struct mbox_msghdr *)((uintptr_t)mdev->mbase + offset);
|
||||
size = mbox->rx_start + msg->next_msgoff - offset;
|
||||
|
||||
/* Reserve PF/VF mbox message */
|
||||
size = PLT_ALIGN(size, MBOX_MSG_ALIGN);
|
||||
rsp = mbox_alloc_msg(&dev->mbox_vfpf, vf, size);
|
||||
mbox_rsp_init(msg->id, rsp);
|
||||
|
||||
/* Copy message from AF<->PF mbox to PF<->VF mbox */
|
||||
mbox_memcpy((uint8_t *)rsp + sizeof(struct mbox_msghdr),
|
||||
(uint8_t *)msg + sizeof(struct mbox_msghdr),
|
||||
size - sizeof(struct mbox_msghdr));
|
||||
|
||||
/* Set status and sender pf_func data */
|
||||
rsp->rc = msg->rc;
|
||||
rsp->pcifunc = msg->pcifunc;
|
||||
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
}
|
||||
plt_spinlock_unlock(&mdev->mbox_lock);
|
||||
|
||||
return req_hdr->num_msgs;
|
||||
}
|
||||
|
||||
static int
|
||||
vf_pf_process_msgs(struct dev *dev, uint16_t vf)
|
||||
{
|
||||
struct mbox *mbox = &dev->mbox_vfpf;
|
||||
struct mbox_dev *mdev = &mbox->dev[vf];
|
||||
struct mbox_hdr *req_hdr;
|
||||
struct mbox_msghdr *msg;
|
||||
int offset, routed = 0;
|
||||
size_t size;
|
||||
uint16_t i;
|
||||
|
||||
req_hdr = (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->rx_start);
|
||||
if (!req_hdr->num_msgs)
|
||||
return 0;
|
||||
|
||||
offset = mbox->rx_start + PLT_ALIGN(sizeof(*req_hdr), MBOX_MSG_ALIGN);
|
||||
|
||||
for (i = 0; i < req_hdr->num_msgs; i++) {
|
||||
msg = (struct mbox_msghdr *)((uintptr_t)mdev->mbase + offset);
|
||||
size = mbox->rx_start + msg->next_msgoff - offset;
|
||||
|
||||
/* RVU_PF_FUNC_S */
|
||||
msg->pcifunc = dev_pf_func(dev->pf, vf);
|
||||
|
||||
if (msg->id == MBOX_MSG_READY) {
|
||||
struct ready_msg_rsp *rsp;
|
||||
uint16_t max_bits = sizeof(dev->active_vfs[0]) * 8;
|
||||
|
||||
/* Handle READY message in PF */
|
||||
dev->active_vfs[vf / max_bits] |=
|
||||
BIT_ULL(vf % max_bits);
|
||||
rsp = (struct ready_msg_rsp *)mbox_alloc_msg(
|
||||
mbox, vf, sizeof(*rsp));
|
||||
mbox_rsp_init(msg->id, rsp);
|
||||
|
||||
/* PF/VF function ID */
|
||||
rsp->hdr.pcifunc = msg->pcifunc;
|
||||
rsp->hdr.rc = 0;
|
||||
} else {
|
||||
struct mbox_msghdr *af_req;
|
||||
/* Reserve AF/PF mbox message */
|
||||
size = PLT_ALIGN(size, MBOX_MSG_ALIGN);
|
||||
af_req = mbox_alloc_msg(dev->mbox, 0, size);
|
||||
if (af_req == NULL)
|
||||
return -ENOSPC;
|
||||
mbox_req_init(msg->id, af_req);
|
||||
|
||||
/* Copy message from VF<->PF mbox to PF<->AF mbox */
|
||||
mbox_memcpy((uint8_t *)af_req +
|
||||
sizeof(struct mbox_msghdr),
|
||||
(uint8_t *)msg + sizeof(struct mbox_msghdr),
|
||||
size - sizeof(struct mbox_msghdr));
|
||||
af_req->pcifunc = msg->pcifunc;
|
||||
routed++;
|
||||
}
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
}
|
||||
|
||||
if (routed > 0) {
|
||||
plt_base_dbg("pf:%d routed %d messages from vf:%d to AF",
|
||||
dev->pf, routed, vf);
|
||||
af_pf_wait_msg(dev, vf, routed);
|
||||
mbox_reset(dev->mbox, 0);
|
||||
}
|
||||
|
||||
/* Send mbox responses to VF */
|
||||
if (mdev->num_msgs) {
|
||||
plt_base_dbg("pf:%d reply %d messages to vf:%d", dev->pf,
|
||||
mdev->num_msgs, vf);
|
||||
mbox_msg_send(mbox, vf);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
vf_pf_process_up_msgs(struct dev *dev, uint16_t vf)
|
||||
{
|
||||
struct mbox *mbox = &dev->mbox_vfpf_up;
|
||||
struct mbox_dev *mdev = &mbox->dev[vf];
|
||||
struct mbox_hdr *req_hdr;
|
||||
struct mbox_msghdr *msg;
|
||||
int msgs_acked = 0;
|
||||
int offset;
|
||||
uint16_t i;
|
||||
|
||||
req_hdr = (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->rx_start);
|
||||
if (req_hdr->num_msgs == 0)
|
||||
return 0;
|
||||
|
||||
offset = mbox->rx_start + PLT_ALIGN(sizeof(*req_hdr), MBOX_MSG_ALIGN);
|
||||
|
||||
for (i = 0; i < req_hdr->num_msgs; i++) {
|
||||
msg = (struct mbox_msghdr *)((uintptr_t)mdev->mbase + offset);
|
||||
|
||||
msgs_acked++;
|
||||
/* RVU_PF_FUNC_S */
|
||||
msg->pcifunc = dev_pf_func(dev->pf, vf);
|
||||
|
||||
switch (msg->id) {
|
||||
case MBOX_MSG_CGX_LINK_EVENT:
|
||||
plt_base_dbg("PF: Msg 0x%x (%s) fn:0x%x (pf:%d,vf:%d)",
|
||||
msg->id, mbox_id2name(msg->id),
|
||||
msg->pcifunc, dev_get_pf(msg->pcifunc),
|
||||
dev_get_vf(msg->pcifunc));
|
||||
break;
|
||||
case MBOX_MSG_CGX_PTP_RX_INFO:
|
||||
plt_base_dbg("PF: Msg 0x%x (%s) fn:0x%x (pf:%d,vf:%d)",
|
||||
msg->id, mbox_id2name(msg->id),
|
||||
msg->pcifunc, dev_get_pf(msg->pcifunc),
|
||||
dev_get_vf(msg->pcifunc));
|
||||
break;
|
||||
default:
|
||||
plt_err("Not handled UP msg 0x%x (%s) func:0x%x",
|
||||
msg->id, mbox_id2name(msg->id), msg->pcifunc);
|
||||
}
|
||||
offset = mbox->rx_start + msg->next_msgoff;
|
||||
}
|
||||
mbox_reset(mbox, vf);
|
||||
mdev->msgs_acked = msgs_acked;
|
||||
plt_wmb();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
roc_vf_pf_mbox_handle_msg(void *param)
|
||||
{
|
||||
uint16_t vf, max_vf, max_bits;
|
||||
struct dev *dev = param;
|
||||
|
||||
max_bits = sizeof(dev->intr.bits[0]) * sizeof(uint64_t);
|
||||
max_vf = max_bits * MAX_VFPF_DWORD_BITS;
|
||||
|
||||
for (vf = 0; vf < max_vf; vf++) {
|
||||
if (dev->intr.bits[vf / max_bits] & BIT_ULL(vf % max_bits)) {
|
||||
plt_base_dbg("Process vf:%d request (pf:%d, vf:%d)", vf,
|
||||
dev->pf, dev->vf);
|
||||
vf_pf_process_msgs(dev, vf);
|
||||
/* UP messages */
|
||||
vf_pf_process_up_msgs(dev, vf);
|
||||
dev->intr.bits[vf / max_bits] &=
|
||||
~(BIT_ULL(vf % max_bits));
|
||||
}
|
||||
}
|
||||
dev->timer_set = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
roc_vf_pf_mbox_irq(void *param)
|
||||
{
|
||||
struct dev *dev = param;
|
||||
bool alarm_set = false;
|
||||
uint64_t intr;
|
||||
int vfpf;
|
||||
|
||||
for (vfpf = 0; vfpf < MAX_VFPF_DWORD_BITS; ++vfpf) {
|
||||
intr = plt_read64(dev->bar2 + RVU_PF_VFPF_MBOX_INTX(vfpf));
|
||||
if (!intr)
|
||||
continue;
|
||||
|
||||
plt_base_dbg("vfpf: %d intr: 0x%" PRIx64 " (pf:%d, vf:%d)",
|
||||
vfpf, intr, dev->pf, dev->vf);
|
||||
|
||||
/* Save and clear intr bits */
|
||||
dev->intr.bits[vfpf] |= intr;
|
||||
plt_write64(intr, dev->bar2 + RVU_PF_VFPF_MBOX_INTX(vfpf));
|
||||
alarm_set = true;
|
||||
}
|
||||
|
||||
if (!dev->timer_set && alarm_set) {
|
||||
dev->timer_set = 1;
|
||||
/* Start timer to handle messages */
|
||||
plt_alarm_set(VF_PF_MBOX_TIMER_MS, roc_vf_pf_mbox_handle_msg,
|
||||
dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_msgs(struct dev *dev, struct mbox *mbox)
|
||||
{
|
||||
@ -62,6 +393,112 @@ process_msgs(struct dev *dev, struct mbox *mbox)
|
||||
plt_wmb();
|
||||
}
|
||||
|
||||
/* Copies the message received from AF and sends it to VF */
|
||||
static void
|
||||
pf_vf_mbox_send_up_msg(struct dev *dev, void *rec_msg)
|
||||
{
|
||||
uint16_t max_bits = sizeof(dev->active_vfs[0]) * sizeof(uint64_t);
|
||||
struct mbox *vf_mbox = &dev->mbox_vfpf_up;
|
||||
struct msg_req *msg = rec_msg;
|
||||
struct mbox_msghdr *vf_msg;
|
||||
uint16_t vf;
|
||||
size_t size;
|
||||
|
||||
size = PLT_ALIGN(mbox_id2size(msg->hdr.id), MBOX_MSG_ALIGN);
|
||||
/* Send UP message to all VF's */
|
||||
for (vf = 0; vf < vf_mbox->ndevs; vf++) {
|
||||
/* VF active */
|
||||
if (!(dev->active_vfs[vf / max_bits] & (BIT_ULL(vf))))
|
||||
continue;
|
||||
|
||||
plt_base_dbg("(%s) size: %zx to VF: %d",
|
||||
mbox_id2name(msg->hdr.id), size, vf);
|
||||
|
||||
/* Reserve PF/VF mbox message */
|
||||
vf_msg = mbox_alloc_msg(vf_mbox, vf, size);
|
||||
if (!vf_msg) {
|
||||
plt_err("Failed to alloc VF%d UP message", vf);
|
||||
continue;
|
||||
}
|
||||
mbox_req_init(msg->hdr.id, vf_msg);
|
||||
|
||||
/*
|
||||
* Copy message from AF<->PF UP mbox
|
||||
* to PF<->VF UP mbox
|
||||
*/
|
||||
mbox_memcpy((uint8_t *)vf_msg + sizeof(struct mbox_msghdr),
|
||||
(uint8_t *)msg + sizeof(struct mbox_msghdr),
|
||||
size - sizeof(struct mbox_msghdr));
|
||||
|
||||
vf_msg->rc = msg->hdr.rc;
|
||||
/* Set PF to be a sender */
|
||||
vf_msg->pcifunc = dev->pf_func;
|
||||
|
||||
/* Send to VF */
|
||||
mbox_msg_send(vf_mbox, vf);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
mbox_up_handler_cgx_link_event(struct dev *dev, struct cgx_link_info_msg *msg,
|
||||
struct msg_rsp *rsp)
|
||||
{
|
||||
struct cgx_link_user_info *linfo = &msg->link_info;
|
||||
void *roc_nix = dev->roc_nix;
|
||||
|
||||
plt_base_dbg("pf:%d/vf:%d NIC Link %s --> 0x%x (%s) from: pf:%d/vf:%d",
|
||||
dev_get_pf(dev->pf_func), dev_get_vf(dev->pf_func),
|
||||
linfo->link_up ? "UP" : "DOWN", msg->hdr.id,
|
||||
mbox_id2name(msg->hdr.id), dev_get_pf(msg->hdr.pcifunc),
|
||||
dev_get_vf(msg->hdr.pcifunc));
|
||||
|
||||
/* PF gets link notification from AF */
|
||||
if (dev_get_pf(msg->hdr.pcifunc) == 0) {
|
||||
if (dev->ops && dev->ops->link_status_update)
|
||||
dev->ops->link_status_update(roc_nix, linfo);
|
||||
|
||||
/* Forward the same message as received from AF to VF */
|
||||
pf_vf_mbox_send_up_msg(dev, msg);
|
||||
} else {
|
||||
/* VF gets link up notification */
|
||||
if (dev->ops && dev->ops->link_status_update)
|
||||
dev->ops->link_status_update(roc_nix, linfo);
|
||||
}
|
||||
|
||||
rsp->hdr.rc = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mbox_up_handler_cgx_ptp_rx_info(struct dev *dev,
|
||||
struct cgx_ptp_rx_info_msg *msg,
|
||||
struct msg_rsp *rsp)
|
||||
{
|
||||
void *roc_nix = dev->roc_nix;
|
||||
|
||||
plt_base_dbg("pf:%d/vf:%d PTP mode %s --> 0x%x (%s) from: pf:%d/vf:%d",
|
||||
dev_get_pf(dev->pf_func), dev_get_vf(dev->pf_func),
|
||||
msg->ptp_en ? "ENABLED" : "DISABLED", msg->hdr.id,
|
||||
mbox_id2name(msg->hdr.id), dev_get_pf(msg->hdr.pcifunc),
|
||||
dev_get_vf(msg->hdr.pcifunc));
|
||||
|
||||
/* PF gets PTP notification from AF */
|
||||
if (dev_get_pf(msg->hdr.pcifunc) == 0) {
|
||||
if (dev->ops && dev->ops->ptp_info_update)
|
||||
dev->ops->ptp_info_update(roc_nix, msg->ptp_en);
|
||||
|
||||
/* Forward the same message as received from AF to VF */
|
||||
pf_vf_mbox_send_up_msg(dev, msg);
|
||||
} else {
|
||||
/* VF gets PTP notification */
|
||||
if (dev->ops && dev->ops->ptp_info_update)
|
||||
dev->ops->ptp_info_update(roc_nix, msg->ptp_en);
|
||||
}
|
||||
|
||||
rsp->hdr.rc = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mbox_process_msgs_up(struct dev *dev, struct mbox_msghdr *req)
|
||||
{
|
||||
@ -73,6 +510,24 @@ mbox_process_msgs_up(struct dev *dev, struct mbox_msghdr *req)
|
||||
default:
|
||||
reply_invalid_msg(&dev->mbox_up, 0, 0, req->id);
|
||||
break;
|
||||
#define M(_name, _id, _fn_name, _req_type, _rsp_type) \
|
||||
case _id: { \
|
||||
struct _rsp_type *rsp; \
|
||||
int err; \
|
||||
rsp = (struct _rsp_type *)mbox_alloc_msg( \
|
||||
&dev->mbox_up, 0, sizeof(struct _rsp_type)); \
|
||||
if (!rsp) \
|
||||
return -ENOMEM; \
|
||||
rsp->hdr.id = _id; \
|
||||
rsp->hdr.sig = MBOX_RSP_SIG; \
|
||||
rsp->hdr.pcifunc = dev->pf_func; \
|
||||
rsp->hdr.rc = 0; \
|
||||
err = mbox_up_handler_##_fn_name(dev, (struct _req_type *)req, \
|
||||
rsp); \
|
||||
return err; \
|
||||
}
|
||||
MBOX_UP_CGX_MESSAGES
|
||||
#undef M
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
@ -110,6 +565,26 @@ process_msgs_up(struct dev *dev, struct mbox *mbox)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
roc_pf_vf_mbox_irq(void *param)
|
||||
{
|
||||
struct dev *dev = param;
|
||||
uint64_t intr;
|
||||
|
||||
intr = plt_read64(dev->bar2 + RVU_VF_INT);
|
||||
if (intr == 0)
|
||||
plt_base_dbg("Proceeding to check mbox UP messages if any");
|
||||
|
||||
plt_write64(intr, dev->bar2 + RVU_VF_INT);
|
||||
plt_base_dbg("Irq 0x%" PRIx64 "(pf:%d,vf:%d)", intr, dev->pf, dev->vf);
|
||||
|
||||
/* First process all configuration messages */
|
||||
process_msgs(dev, dev->mbox);
|
||||
|
||||
/* Process Uplink messages */
|
||||
process_msgs_up(dev, &dev->mbox_up);
|
||||
}
|
||||
|
||||
static void
|
||||
roc_af_pf_mbox_irq(void *param)
|
||||
{
|
||||
@ -121,7 +596,7 @@ roc_af_pf_mbox_irq(void *param)
|
||||
plt_base_dbg("Proceeding to check mbox UP messages if any");
|
||||
|
||||
plt_write64(intr, dev->bar2 + RVU_PF_INT);
|
||||
plt_base_dbg("Irq 0x%" PRIx64 "(pf:%d)", intr, dev->pf);
|
||||
plt_base_dbg("Irq 0x%" PRIx64 "(pf:%d,vf:%d)", intr, dev->pf, dev->vf);
|
||||
|
||||
/* First process all configuration messages */
|
||||
process_msgs(dev, dev->mbox);
|
||||
@ -134,10 +609,33 @@ static int
|
||||
mbox_register_pf_irq(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
struct plt_intr_handle *intr_handle = &pci_dev->intr_handle;
|
||||
int rc;
|
||||
int i, rc;
|
||||
|
||||
/* HW clear irq */
|
||||
for (i = 0; i < MAX_VFPF_DWORD_BITS; ++i)
|
||||
plt_write64(~0ull,
|
||||
dev->bar2 + RVU_PF_VFPF_MBOX_INT_ENA_W1CX(i));
|
||||
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1C);
|
||||
|
||||
dev->timer_set = 0;
|
||||
|
||||
/* MBOX interrupt for VF(0...63) <-> PF */
|
||||
rc = dev_irq_register(intr_handle, roc_vf_pf_mbox_irq, dev,
|
||||
RVU_PF_INT_VEC_VFPF_MBOX0);
|
||||
|
||||
if (rc) {
|
||||
plt_err("Fail to register PF(VF0-63) mbox irq");
|
||||
return rc;
|
||||
}
|
||||
/* MBOX interrupt for VF(64...128) <-> PF */
|
||||
rc = dev_irq_register(intr_handle, roc_vf_pf_mbox_irq, dev,
|
||||
RVU_PF_INT_VEC_VFPF_MBOX1);
|
||||
|
||||
if (rc) {
|
||||
plt_err("Fail to register PF(VF64-128) mbox irq");
|
||||
return rc;
|
||||
}
|
||||
/* MBOX interrupt AF <-> PF */
|
||||
rc = dev_irq_register(intr_handle, roc_af_pf_mbox_irq, dev,
|
||||
RVU_PF_INT_VEC_AFPF_MBOX);
|
||||
@ -146,15 +644,47 @@ mbox_register_pf_irq(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* HW enable intr */
|
||||
for (i = 0; i < MAX_VFPF_DWORD_BITS; ++i)
|
||||
plt_write64(~0ull,
|
||||
dev->bar2 + RVU_PF_VFPF_MBOX_INT_ENA_W1SX(i));
|
||||
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT);
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1S);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
mbox_register_vf_irq(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
struct plt_intr_handle *intr_handle = &pci_dev->intr_handle;
|
||||
int rc;
|
||||
|
||||
/* Clear irq */
|
||||
plt_write64(~0ull, dev->bar2 + RVU_VF_INT_ENA_W1C);
|
||||
|
||||
/* MBOX interrupt PF <-> VF */
|
||||
rc = dev_irq_register(intr_handle, roc_pf_vf_mbox_irq, dev,
|
||||
RVU_VF_INT_VEC_MBOX);
|
||||
if (rc) {
|
||||
plt_err("Fail to register PF<->VF mbox irq");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* HW enable intr */
|
||||
plt_write64(~0ull, dev->bar2 + RVU_VF_INT);
|
||||
plt_write64(~0ull, dev->bar2 + RVU_VF_INT_ENA_W1S);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
mbox_register_irq(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
if (dev_is_vf(dev))
|
||||
return mbox_register_vf_irq(pci_dev, dev);
|
||||
else
|
||||
return mbox_register_pf_irq(pci_dev, dev);
|
||||
}
|
||||
|
||||
@ -162,20 +692,229 @@ static void
|
||||
mbox_unregister_pf_irq(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
struct plt_intr_handle *intr_handle = &pci_dev->intr_handle;
|
||||
int i;
|
||||
|
||||
/* HW clear irq */
|
||||
for (i = 0; i < MAX_VFPF_DWORD_BITS; ++i)
|
||||
plt_write64(~0ull,
|
||||
dev->bar2 + RVU_PF_VFPF_MBOX_INT_ENA_W1CX(i));
|
||||
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1C);
|
||||
|
||||
dev->timer_set = 0;
|
||||
|
||||
plt_alarm_cancel(roc_vf_pf_mbox_handle_msg, dev);
|
||||
|
||||
/* Unregister the interrupt handler for each vectors */
|
||||
/* MBOX interrupt for VF(0...63) <-> PF */
|
||||
dev_irq_unregister(intr_handle, roc_vf_pf_mbox_irq, dev,
|
||||
RVU_PF_INT_VEC_VFPF_MBOX0);
|
||||
|
||||
/* MBOX interrupt for VF(64...128) <-> PF */
|
||||
dev_irq_unregister(intr_handle, roc_vf_pf_mbox_irq, dev,
|
||||
RVU_PF_INT_VEC_VFPF_MBOX1);
|
||||
|
||||
/* MBOX interrupt AF <-> PF */
|
||||
dev_irq_unregister(intr_handle, roc_af_pf_mbox_irq, dev,
|
||||
RVU_PF_INT_VEC_AFPF_MBOX);
|
||||
}
|
||||
|
||||
static void
|
||||
mbox_unregister_vf_irq(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
struct plt_intr_handle *intr_handle = &pci_dev->intr_handle;
|
||||
|
||||
/* Clear irq */
|
||||
plt_write64(~0ull, dev->bar2 + RVU_VF_INT_ENA_W1C);
|
||||
|
||||
/* Unregister the interrupt handler */
|
||||
dev_irq_unregister(intr_handle, roc_pf_vf_mbox_irq, dev,
|
||||
RVU_VF_INT_VEC_MBOX);
|
||||
}
|
||||
|
||||
static void
|
||||
mbox_unregister_irq(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
if (dev_is_vf(dev))
|
||||
mbox_unregister_vf_irq(pci_dev, dev);
|
||||
else
|
||||
mbox_unregister_pf_irq(pci_dev, dev);
|
||||
}
|
||||
|
||||
static int
|
||||
vf_flr_send_msg(struct dev *dev, uint16_t vf)
|
||||
{
|
||||
struct mbox *mbox = dev->mbox;
|
||||
struct msg_req *req;
|
||||
int rc;
|
||||
|
||||
req = mbox_alloc_msg_vf_flr(mbox);
|
||||
if (req == NULL)
|
||||
return -ENOSPC;
|
||||
/* Overwrite pcifunc to indicate VF */
|
||||
req->hdr.pcifunc = dev_pf_func(dev->pf, vf);
|
||||
|
||||
/* Sync message in interrupt context */
|
||||
rc = pf_af_sync_msg(dev, NULL);
|
||||
if (rc)
|
||||
plt_err("Failed to send VF FLR mbox msg, rc=%d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
roc_pf_vf_flr_irq(void *param)
|
||||
{
|
||||
struct dev *dev = (struct dev *)param;
|
||||
uint16_t max_vf = 64, vf;
|
||||
uintptr_t bar2;
|
||||
uint64_t intr;
|
||||
int i;
|
||||
|
||||
max_vf = (dev->maxvf > 0) ? dev->maxvf : 64;
|
||||
bar2 = dev->bar2;
|
||||
|
||||
plt_base_dbg("FLR VF interrupt: max_vf: %d", max_vf);
|
||||
|
||||
for (i = 0; i < MAX_VFPF_DWORD_BITS; ++i) {
|
||||
intr = plt_read64(bar2 + RVU_PF_VFFLR_INTX(i));
|
||||
if (!intr)
|
||||
continue;
|
||||
|
||||
for (vf = 0; vf < max_vf; vf++) {
|
||||
if (!(intr & (1ULL << vf)))
|
||||
continue;
|
||||
|
||||
plt_base_dbg("FLR: i :%d intr: 0x%" PRIx64 ", vf-%d", i,
|
||||
intr, (64 * i + vf));
|
||||
/* Clear interrupt */
|
||||
plt_write64(BIT_ULL(vf), bar2 + RVU_PF_VFFLR_INTX(i));
|
||||
/* Disable the interrupt */
|
||||
plt_write64(BIT_ULL(vf),
|
||||
bar2 + RVU_PF_VFFLR_INT_ENA_W1CX(i));
|
||||
/* Inform AF about VF reset */
|
||||
vf_flr_send_msg(dev, vf);
|
||||
|
||||
/* Signal FLR finish */
|
||||
plt_write64(BIT_ULL(vf), bar2 + RVU_PF_VFTRPENDX(i));
|
||||
/* Enable interrupt */
|
||||
plt_write64(~0ull, bar2 + RVU_PF_VFFLR_INT_ENA_W1SX(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vf_flr_unregister_irqs(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
struct plt_intr_handle *intr_handle = &pci_dev->intr_handle;
|
||||
int i;
|
||||
|
||||
plt_base_dbg("Unregister VF FLR interrupts for %s", pci_dev->name);
|
||||
|
||||
/* HW clear irq */
|
||||
for (i = 0; i < MAX_VFPF_DWORD_BITS; i++)
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_VFFLR_INT_ENA_W1CX(i));
|
||||
|
||||
dev_irq_unregister(intr_handle, roc_pf_vf_flr_irq, dev,
|
||||
RVU_PF_INT_VEC_VFFLR0);
|
||||
|
||||
dev_irq_unregister(intr_handle, roc_pf_vf_flr_irq, dev,
|
||||
RVU_PF_INT_VEC_VFFLR1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vf_flr_register_irqs(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
struct plt_intr_handle *handle = &pci_dev->intr_handle;
|
||||
int i, rc;
|
||||
|
||||
plt_base_dbg("Register VF FLR interrupts for %s", pci_dev->name);
|
||||
|
||||
rc = dev_irq_register(handle, roc_pf_vf_flr_irq, dev,
|
||||
RVU_PF_INT_VEC_VFFLR0);
|
||||
if (rc)
|
||||
plt_err("Failed to init RVU_PF_INT_VEC_VFFLR0 rc=%d", rc);
|
||||
|
||||
rc = dev_irq_register(handle, roc_pf_vf_flr_irq, dev,
|
||||
RVU_PF_INT_VEC_VFFLR1);
|
||||
if (rc)
|
||||
plt_err("Failed to init RVU_PF_INT_VEC_VFFLR1 rc=%d", rc);
|
||||
|
||||
/* Enable HW interrupt */
|
||||
for (i = 0; i < MAX_VFPF_DWORD_BITS; ++i) {
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_VFFLR_INTX(i));
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_VFTRPENDX(i));
|
||||
plt_write64(~0ull, dev->bar2 + RVU_PF_VFFLR_INT_ENA_W1SX(i));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dev_active_vfs(struct dev *dev)
|
||||
{
|
||||
int i, count = 0;
|
||||
|
||||
for (i = 0; i < MAX_VFPF_DWORD_BITS; i++)
|
||||
count += __builtin_popcount(dev->active_vfs[i]);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
dev_vf_hwcap_update(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
switch (pci_dev->id.device_id) {
|
||||
case PCI_DEVID_CNXK_RVU_PF:
|
||||
break;
|
||||
case PCI_DEVID_CNXK_RVU_SSO_TIM_VF:
|
||||
case PCI_DEVID_CNXK_RVU_NPA_VF:
|
||||
case PCI_DEVID_CNXK_RVU_AF_VF:
|
||||
case PCI_DEVID_CNXK_RVU_VF:
|
||||
case PCI_DEVID_CNXK_RVU_SDP_VF:
|
||||
dev->hwcap |= DEV_HWCAP_F_VF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uintptr_t
|
||||
dev_vf_mbase_get(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
void *vf_mbase = NULL;
|
||||
uintptr_t pa;
|
||||
|
||||
if (dev_is_vf(dev))
|
||||
return 0;
|
||||
|
||||
/* For CN10K onwards, it is just after PF MBOX */
|
||||
if (!roc_model_is_cn9k())
|
||||
return dev->bar4 + MBOX_SIZE;
|
||||
|
||||
pa = plt_read64(dev->bar2 + RVU_PF_VF_BAR4_ADDR);
|
||||
if (!pa) {
|
||||
plt_err("Invalid VF mbox base pa");
|
||||
return pa;
|
||||
}
|
||||
|
||||
vf_mbase = mbox_mem_map(pa, MBOX_SIZE * pci_dev->max_vfs);
|
||||
if (vf_mbase == MAP_FAILED) {
|
||||
plt_err("Failed to mmap vf mbase at pa 0x%lx, rc=%d", pa,
|
||||
errno);
|
||||
return 0;
|
||||
}
|
||||
return (uintptr_t)vf_mbase;
|
||||
}
|
||||
|
||||
static void
|
||||
dev_vf_mbase_put(struct plt_pci_device *pci_dev, uintptr_t vf_mbase)
|
||||
{
|
||||
if (!vf_mbase || !pci_dev->max_vfs || !roc_model_is_cn9k())
|
||||
return;
|
||||
|
||||
mbox_mem_unmap((void *)vf_mbase, MBOX_SIZE * pci_dev->max_vfs);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
dev_pf_total_vfs(struct plt_pci_device *pci_dev)
|
||||
{
|
||||
@ -213,7 +952,6 @@ dev_setup_shared_lmt_region(struct mbox *mbox)
|
||||
static int
|
||||
dev_lmt_setup(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
{
|
||||
uint64_t bar4_mbox_sz = MBOX_SIZE;
|
||||
struct idev_cfg *idev;
|
||||
int rc;
|
||||
|
||||
@ -237,6 +975,20 @@ dev_lmt_setup(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
dev->pf_func, rc);
|
||||
}
|
||||
|
||||
if (dev_is_vf(dev)) {
|
||||
/* VF BAR4 should always be sufficient enough to
|
||||
* hold LMT lines.
|
||||
*/
|
||||
if (pci_dev->mem_resource[4].len <
|
||||
(RVU_LMT_LINE_MAX * RVU_LMT_SZ)) {
|
||||
plt_err("Not enough bar4 space for lmt lines");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
dev->lmt_base = dev->bar4;
|
||||
} else {
|
||||
uint64_t bar4_mbox_sz = MBOX_SIZE;
|
||||
|
||||
/* PF BAR4 should always be sufficient enough to
|
||||
* hold PF-AF MBOX + PF-VF MBOX + LMT lines.
|
||||
*/
|
||||
@ -249,6 +1001,7 @@ dev_lmt_setup(struct plt_pci_device *pci_dev, struct dev *dev)
|
||||
/* LMT base is just after total VF MBOX area */
|
||||
bar4_mbox_sz += (MBOX_SIZE * dev_pf_total_vfs(pci_dev));
|
||||
dev->lmt_base = dev->bar4 + bar4_mbox_sz;
|
||||
}
|
||||
|
||||
/* Base LMT address should be chosen from only those pci funcs which
|
||||
* participate in LMT shared mode.
|
||||
@ -270,6 +1023,7 @@ dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
|
||||
{
|
||||
int direction, up_direction, rc;
|
||||
uintptr_t bar2, bar4, mbox;
|
||||
uintptr_t vf_mbase = 0;
|
||||
uint64_t intr_offset;
|
||||
|
||||
bar2 = (uintptr_t)pci_dev->mem_resource[2].addr;
|
||||
@ -293,13 +1047,23 @@ dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev->maxvf = pci_dev->max_vfs;
|
||||
dev->bar2 = bar2;
|
||||
dev->bar4 = bar4;
|
||||
dev_vf_hwcap_update(pci_dev, dev);
|
||||
|
||||
if (dev_is_vf(dev)) {
|
||||
mbox = (roc_model_is_cn9k() ?
|
||||
bar4 : (bar2 + RVU_VF_MBOX_REGION));
|
||||
direction = MBOX_DIR_VFPF;
|
||||
up_direction = MBOX_DIR_VFPF_UP;
|
||||
intr_offset = RVU_VF_INT;
|
||||
} else {
|
||||
mbox = bar4;
|
||||
direction = MBOX_DIR_PFAF;
|
||||
up_direction = MBOX_DIR_PFAF_UP;
|
||||
intr_offset = RVU_PF_INT;
|
||||
}
|
||||
|
||||
/* Initialize the local mbox */
|
||||
rc = mbox_init(&dev->mbox_local, mbox, bar2, direction, 1, intr_offset);
|
||||
@ -322,7 +1086,43 @@ dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
|
||||
goto mbox_unregister;
|
||||
|
||||
dev->pf = dev_get_pf(dev->pf_func);
|
||||
dev->vf = dev_get_vf(dev->pf_func);
|
||||
memset(&dev->active_vfs, 0, sizeof(dev->active_vfs));
|
||||
|
||||
/* Allocate memory for device ops */
|
||||
dev->ops = plt_zmalloc(sizeof(struct dev_ops), 0);
|
||||
if (dev->ops == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto mbox_unregister;
|
||||
}
|
||||
|
||||
/* Found VF devices in a PF device */
|
||||
if (pci_dev->max_vfs > 0) {
|
||||
/* Remap mbox area for all vf's */
|
||||
vf_mbase = dev_vf_mbase_get(pci_dev, dev);
|
||||
if (!vf_mbase) {
|
||||
rc = -ENODEV;
|
||||
goto mbox_unregister;
|
||||
}
|
||||
/* Init mbox object */
|
||||
rc = mbox_init(&dev->mbox_vfpf, vf_mbase, bar2, MBOX_DIR_PFVF,
|
||||
pci_dev->max_vfs, intr_offset);
|
||||
if (rc)
|
||||
goto iounmap;
|
||||
|
||||
/* PF -> VF UP messages */
|
||||
rc = mbox_init(&dev->mbox_vfpf_up, vf_mbase, bar2,
|
||||
MBOX_DIR_PFVF_UP, pci_dev->max_vfs, intr_offset);
|
||||
if (rc)
|
||||
goto iounmap;
|
||||
}
|
||||
|
||||
/* Register VF-FLR irq handlers */
|
||||
if (!dev_is_vf(dev)) {
|
||||
rc = vf_flr_register_irqs(pci_dev, dev);
|
||||
if (rc)
|
||||
goto iounmap;
|
||||
}
|
||||
dev->mbox_active = 1;
|
||||
|
||||
/* Setup LMT line base */
|
||||
@ -332,8 +1132,11 @@ dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
|
||||
|
||||
return rc;
|
||||
iounmap:
|
||||
dev_vf_mbase_put(pci_dev, vf_mbase);
|
||||
mbox_unregister:
|
||||
mbox_unregister_irq(pci_dev, dev);
|
||||
if (dev->ops)
|
||||
plt_free(dev->ops);
|
||||
mbox_fini:
|
||||
mbox_fini(dev->mbox);
|
||||
mbox_fini(&dev->mbox_up);
|
||||
@ -349,6 +1152,20 @@ dev_fini(struct dev *dev, struct plt_pci_device *pci_dev)
|
||||
|
||||
mbox_unregister_irq(pci_dev, dev);
|
||||
|
||||
if (!dev_is_vf(dev))
|
||||
vf_flr_unregister_irqs(pci_dev, dev);
|
||||
/* Release PF - VF */
|
||||
mbox = &dev->mbox_vfpf;
|
||||
if (mbox->hwbase && mbox->dev)
|
||||
dev_vf_mbase_put(pci_dev, mbox->hwbase);
|
||||
|
||||
if (dev->ops)
|
||||
plt_free(dev->ops);
|
||||
|
||||
mbox_fini(mbox);
|
||||
mbox = &dev->mbox_vfpf_up;
|
||||
mbox_fini(mbox);
|
||||
|
||||
/* Release PF - AF */
|
||||
mbox = dev->mbox;
|
||||
mbox_fini(mbox);
|
||||
|
@ -5,12 +5,38 @@
|
||||
#ifndef _ROC_DEV_PRIV_H
|
||||
#define _ROC_DEV_PRIV_H
|
||||
|
||||
#define DEV_HWCAP_F_VF BIT_ULL(0) /* VF device */
|
||||
|
||||
#define RVU_PFVF_PF_SHIFT 10
|
||||
#define RVU_PFVF_PF_MASK 0x3F
|
||||
#define RVU_PFVF_FUNC_SHIFT 0
|
||||
#define RVU_PFVF_FUNC_MASK 0x3FF
|
||||
#define RVU_MAX_VF 64 /* RVU_PF_VFPF_MBOX_INT(0..1) */
|
||||
#define RVU_MAX_INT_RETRY 3
|
||||
|
||||
/* PF/VF message handling timer */
|
||||
#define VF_PF_MBOX_TIMER_MS (20 * 1000)
|
||||
|
||||
typedef struct {
|
||||
/* 128 devices translate to two 64 bits dwords */
|
||||
#define MAX_VFPF_DWORD_BITS 2
|
||||
uint64_t bits[MAX_VFPF_DWORD_BITS];
|
||||
} dev_intr_t;
|
||||
|
||||
/* Link status update callback */
|
||||
typedef void (*link_info_t)(void *roc_nix,
|
||||
struct cgx_link_user_info *link);
|
||||
|
||||
/* PTP info callback */
|
||||
typedef int (*ptp_info_t)(void *roc_nix, bool enable);
|
||||
|
||||
struct dev_ops {
|
||||
link_info_t link_status_update;
|
||||
ptp_info_t ptp_info_update;
|
||||
};
|
||||
|
||||
#define dev_is_vf(dev) ((dev)->hwcap & DEV_HWCAP_F_VF)
|
||||
|
||||
static inline int
|
||||
dev_get_vf(uint16_t pf_func)
|
||||
{
|
||||
@ -29,18 +55,33 @@ dev_pf_func(int pf, int vf)
|
||||
return (pf << RVU_PFVF_PF_SHIFT) | ((vf << RVU_PFVF_FUNC_SHIFT) + 1);
|
||||
}
|
||||
|
||||
static inline int
|
||||
dev_is_afvf(uint16_t pf_func)
|
||||
{
|
||||
return !(pf_func & ~RVU_PFVF_FUNC_MASK);
|
||||
}
|
||||
|
||||
struct dev {
|
||||
uint16_t pf;
|
||||
int16_t vf;
|
||||
uint16_t pf_func;
|
||||
uint8_t mbox_active;
|
||||
bool drv_inited;
|
||||
uint64_t active_vfs[MAX_VFPF_DWORD_BITS];
|
||||
uintptr_t bar2;
|
||||
uintptr_t bar4;
|
||||
uintptr_t lmt_base;
|
||||
struct mbox mbox_local;
|
||||
struct mbox mbox_up;
|
||||
struct mbox mbox_vfpf;
|
||||
struct mbox mbox_vfpf_up;
|
||||
dev_intr_t intr;
|
||||
int timer_set; /* ~0 : no alarm handling */
|
||||
uint64_t hwcap;
|
||||
struct mbox *mbox;
|
||||
uint16_t maxvf;
|
||||
struct dev_ops *ops;
|
||||
void *roc_nix;
|
||||
bool disable_shared_lmt; /* false(default): shared lmt mode enabled */
|
||||
} __plt_cache_aligned;
|
||||
|
||||
@ -49,6 +90,7 @@ extern uint16_t dev_sclk_freq;
|
||||
|
||||
int dev_init(struct dev *dev, struct plt_pci_device *pci_dev);
|
||||
int dev_fini(struct dev *dev, struct plt_pci_device *pci_dev);
|
||||
int dev_active_vfs(struct dev *dev);
|
||||
|
||||
int dev_irq_register(struct plt_intr_handle *intr_handle,
|
||||
plt_intr_callback_fn cb, void *data, unsigned int vec);
|
||||
|
Loading…
x
Reference in New Issue
Block a user