]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
octeontx2: Detect the mbox up or down message via register
[thirdparty/linux.git] / drivers / net / ethernet / marvell / octeontx2 / nic / otx2_vf.c
index 35e06048356f4d545298b4bfc34ae848168734f1..ced456cec8baf037445eb061d792c4855156f59d 100644 (file)
@@ -89,16 +89,20 @@ static void otx2vf_vfaf_mbox_handler(struct work_struct *work)
        struct otx2_mbox *mbox;
        struct mbox *af_mbox;
        int offset, id;
+       u16 num_msgs;
 
        af_mbox = container_of(work, struct mbox, mbox_wrk);
        mbox = &af_mbox->mbox;
        mdev = &mbox->dev[0];
        rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-       if (af_mbox->num_msgs == 0)
+       num_msgs = rsp_hdr->num_msgs;
+
+       if (num_msgs == 0)
                return;
+
        offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 
-       for (id = 0; id < af_mbox->num_msgs; id++) {
+       for (id = 0; id < num_msgs; id++) {
                msg = (struct mbox_msghdr *)(mdev->mbase + offset);
                otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg);
                offset = mbox->rx_start + msg->next_msgoff;
@@ -151,6 +155,7 @@ static void otx2vf_vfaf_mbox_up_handler(struct work_struct *work)
        struct mbox *vf_mbox;
        struct otx2_nic *vf;
        int offset, id;
+       u16 num_msgs;
 
        vf_mbox = container_of(work, struct mbox, mbox_up_wrk);
        vf = vf_mbox->pfvf;
@@ -158,12 +163,14 @@ static void otx2vf_vfaf_mbox_up_handler(struct work_struct *work)
        mdev = &mbox->dev[0];
 
        rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-       if (vf_mbox->up_num_msgs == 0)
+       num_msgs = rsp_hdr->num_msgs;
+
+       if (num_msgs == 0)
                return;
 
        offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 
-       for (id = 0; id < vf_mbox->up_num_msgs; id++) {
+       for (id = 0; id < num_msgs; id++) {
                msg = (struct mbox_msghdr *)(mdev->mbase + offset);
                otx2vf_process_mbox_msg_up(vf, msg);
                offset = mbox->rx_start + msg->next_msgoff;
@@ -178,40 +185,48 @@ static irqreturn_t otx2vf_vfaf_mbox_intr_handler(int irq, void *vf_irq)
        struct otx2_mbox_dev *mdev;
        struct otx2_mbox *mbox;
        struct mbox_hdr *hdr;
+       u64 mbox_data;
 
        /* Clear the IRQ */
        otx2_write64(vf, RVU_VF_INT, BIT_ULL(0));
 
+       mbox_data = otx2_read64(vf, RVU_VF_VFPF_MBOX0);
+
        /* Read latest mbox data */
        smp_rmb();
 
-       /* Check for PF => VF response messages */
-       mbox = &vf->mbox.mbox;
-       mdev = &mbox->dev[0];
-       otx2_sync_mbox_bbuf(mbox, 0);
+       if (mbox_data & MBOX_DOWN_MSG) {
+               mbox_data &= ~MBOX_DOWN_MSG;
+               otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data);
+
+               /* Check for PF => VF response messages */
+               mbox = &vf->mbox.mbox;
+               mdev = &mbox->dev[0];
+               otx2_sync_mbox_bbuf(mbox, 0);
 
-       trace_otx2_msg_interrupt(mbox->pdev, "PF to VF", BIT_ULL(0));
+               hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+               if (hdr->num_msgs)
+                       queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
 
-       hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-       if (hdr->num_msgs) {
-               vf->mbox.num_msgs = hdr->num_msgs;
-               hdr->num_msgs = 0;
-               memset(mbox->hwbase + mbox->rx_start, 0,
-                      ALIGN(sizeof(struct mbox_hdr), sizeof(u64)));
-               queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
+               trace_otx2_msg_interrupt(mbox->pdev, "DOWN reply from PF to VF",
+                                        BIT_ULL(0));
        }
-       /* Check for PF => VF notification messages */
-       mbox = &vf->mbox.mbox_up;
-       mdev = &mbox->dev[0];
-       otx2_sync_mbox_bbuf(mbox, 0);
-
-       hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-       if (hdr->num_msgs) {
-               vf->mbox.up_num_msgs = hdr->num_msgs;
-               hdr->num_msgs = 0;
-               memset(mbox->hwbase + mbox->rx_start, 0,
-                      ALIGN(sizeof(struct mbox_hdr), sizeof(u64)));
-               queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
+
+       if (mbox_data & MBOX_UP_MSG) {
+               mbox_data &= ~MBOX_UP_MSG;
+               otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data);
+
+               /* Check for PF => VF notification messages */
+               mbox = &vf->mbox.mbox_up;
+               mdev = &mbox->dev[0];
+               otx2_sync_mbox_bbuf(mbox, 0);
+
+               hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+               if (hdr->num_msgs)
+                       queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
+
+               trace_otx2_msg_interrupt(mbox->pdev, "UP message from PF to VF",
+                                        BIT_ULL(0));
        }
 
        return IRQ_HANDLED;