diff options
Diffstat (limited to 'drivers/net/ethernet/marvell')
-rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/mbox.c | 47 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/mbox.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 2 |
4 files changed, 70 insertions, 12 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c index d6f9ed8ea966..81c83d27a424 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c @@ -236,8 +236,10 @@ struct mbox_msghdr *otx2_mbox_get_rsp(struct otx2_mbox *mbox, int devid, struct otx2_mbox_dev *mdev = &mbox->dev[devid]; u16 msgs; + spin_lock(&mdev->mbox_lock); + if (mdev->num_msgs != mdev->msgs_acked) - return ERR_PTR(-ENODEV); + goto error; for (msgs = 0; msgs < mdev->msgs_acked; msgs++) { struct mbox_msghdr *pmsg = mdev->mbase + imsg; @@ -245,18 +247,55 @@ struct mbox_msghdr *otx2_mbox_get_rsp(struct otx2_mbox *mbox, int devid, if (msg == pmsg) { if (pmsg->id != prsp->id) - return ERR_PTR(-ENODEV); + goto error; + spin_unlock(&mdev->mbox_lock); return prsp; } - imsg = pmsg->next_msgoff; - irsp = prsp->next_msgoff; + imsg = mbox->tx_start + pmsg->next_msgoff; + irsp = mbox->rx_start + prsp->next_msgoff; } +error: + spin_unlock(&mdev->mbox_lock); return ERR_PTR(-ENODEV); } EXPORT_SYMBOL(otx2_mbox_get_rsp); +int otx2_mbox_check_rsp_msgs(struct otx2_mbox *mbox, int devid) +{ + unsigned long ireq = mbox->tx_start + msgs_offset; + unsigned long irsp = mbox->rx_start + msgs_offset; + struct otx2_mbox_dev *mdev = &mbox->dev[devid]; + int rc = -ENODEV; + u16 msgs; + + spin_lock(&mdev->mbox_lock); + + if (mdev->num_msgs != mdev->msgs_acked) + goto exit; + + for (msgs = 0; msgs < mdev->msgs_acked; msgs++) { + struct mbox_msghdr *preq = mdev->mbase + ireq; + struct mbox_msghdr *prsp = mdev->mbase + irsp; + + if (preq->id != prsp->id) + goto exit; + if (prsp->rc) { + rc = prsp->rc; + goto exit; + } + + ireq = mbox->tx_start + preq->next_msgoff; + irsp = mbox->rx_start + prsp->next_msgoff; + } + rc = 0; +exit: + spin_unlock(&mdev->mbox_lock); + return rc; +} +EXPORT_SYMBOL(otx2_mbox_check_rsp_msgs); + int otx2_reply_invalid_msg(struct otx2_mbox *mbox, int devid, u16 pcifunc, u16 id) { diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index 76a4575d18ff..25f0e6f7fb39 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -103,6 +103,7 @@ struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid, int size, int size_rsp); struct mbox_msghdr *otx2_mbox_get_rsp(struct otx2_mbox *mbox, int devid, struct mbox_msghdr *msg); +int otx2_mbox_check_rsp_msgs(struct otx2_mbox *mbox, int devid); int otx2_reply_invalid_msg(struct otx2_mbox *mbox, int devid, u16 pcifunc, u16 id); bool otx2_mbox_nonempty(struct otx2_mbox *mbox, int devid); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index cf8741db1549..f5e6acaa865e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -1440,12 +1440,12 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type) /* Process received mbox messages */ req_hdr = mdev->mbase + mbox->rx_start; - if (req_hdr->num_msgs == 0) + if (mw->mbox_wrk[devid].num_msgs == 0) return; offset = mbox->rx_start + ALIGN(sizeof(*req_hdr), MBOX_MSG_ALIGN); - for (id = 0; id < req_hdr->num_msgs; id++) { + for (id = 0; id < mw->mbox_wrk[devid].num_msgs; id++) { msg = mdev->mbase + offset; /* Set which PF/VF sent this message based on mbox IRQ */ @@ -1471,13 +1471,14 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type) if (msg->pcifunc & RVU_PFVF_FUNC_MASK) dev_warn(rvu->dev, "Error %d when processing message %s (0x%x) from PF%d:VF%d\n", err, otx2_mbox_id2name(msg->id), - msg->id, devid, + msg->id, rvu_get_pf(msg->pcifunc), (msg->pcifunc & RVU_PFVF_FUNC_MASK) - 1); else dev_warn(rvu->dev, "Error %d when processing message %s (0x%x) from PF%d\n", err, otx2_mbox_id2name(msg->id), msg->id, devid); } + mw->mbox_wrk[devid].num_msgs = 0; /* Send mbox responses to VF/PF */ otx2_mbox_msg_send(mbox, devid); @@ -1523,14 +1524,14 @@ static void __rvu_mbox_up_handler(struct rvu_work *mwork, int type) mdev = &mbox->dev[devid]; rsp_hdr = mdev->mbase + mbox->rx_start; - if (rsp_hdr->num_msgs == 0) { + if (mw->mbox_wrk_up[devid].up_num_msgs == 0) { dev_warn(rvu->dev, "mbox up handler: num_msgs = 0\n"); return; } offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN); - for (id = 0; id < rsp_hdr->num_msgs; id++) { + for (id = 0; id < mw->mbox_wrk_up[devid].up_num_msgs; id++) { msg = mdev->mbase + offset; if (msg->id >= MBOX_MSG_MAX) { @@ -1560,6 +1561,7 @@ end: offset = mbox->rx_start + msg->next_msgoff; mdev->msgs_acked++; } + mw->mbox_wrk_up[devid].up_num_msgs = 0; otx2_mbox_reset(mbox, devid); } @@ -1697,14 +1699,28 @@ static void rvu_queue_work(struct mbox_wq_info *mw, int first, mbox = &mw->mbox; mdev = &mbox->dev[i]; hdr = mdev->mbase + mbox->rx_start; - if (hdr->num_msgs) - queue_work(mw->mbox_wq, &mw->mbox_wrk[i].work); + /*The hdr->num_msgs is set to zero immediately in the interrupt + * handler to ensure that it holds a correct value next time + * when the interrupt handler is called. + * pf->mbox.num_msgs holds the data for use in pfaf_mbox_handler + * pf>mbox.up_num_msgs holds the data for use in + * pfaf_mbox_up_handler. + */ + + if (hdr->num_msgs) { + mw->mbox_wrk[i].num_msgs = hdr->num_msgs; + hdr->num_msgs = 0; + queue_work(mw->mbox_wq, &mw->mbox_wrk[i].work); + } mbox = &mw->mbox_up; mdev = &mbox->dev[i]; hdr = mdev->mbase + mbox->rx_start; - if (hdr->num_msgs) + if (hdr->num_msgs) { + mw->mbox_wrk_up[i].up_num_msgs = hdr->num_msgs; + hdr->num_msgs = 0; queue_work(mw->mbox_wq, &mw->mbox_wrk_up[i].work); + } } } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index 63b6bbc60f8f..e81b0ed5a7c2 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -63,6 +63,8 @@ struct rvu_debugfs { struct rvu_work { struct work_struct work; struct rvu *rvu; + int num_msgs; + int up_num_msgs; }; struct rsrc_bmap { |