common/cnxk: support precolor table setup
[dpdk.git] / drivers / common / cnxk / roc_dev.c
index adff779..ce6980c 100644 (file)
@@ -163,6 +163,39 @@ af_pf_wait_msg(struct dev *dev, uint16_t vf, int num_msg)
                rsp->rc = msg->rc;
                rsp->pcifunc = msg->pcifunc;
 
+               /* Whenever a PF comes up, AF sends the link status to it but
+                * when VF comes up no such event is sent to respective VF.
+                * Using MBOX_MSG_NIX_LF_START_RX response from AF for the
+                * purpose and send the link status of PF to VF.
+                */
+               if (msg->id == MBOX_MSG_NIX_LF_START_RX) {
+                       /* Send link status to VF */
+                       struct cgx_link_user_info linfo;
+                       struct mbox_msghdr *vf_msg;
+                       size_t sz;
+
+                       /* Get the link status */
+                       memset(&linfo, 0, sizeof(struct cgx_link_user_info));
+                       if (dev->ops && dev->ops->link_status_get)
+                               dev->ops->link_status_get(dev->roc_nix, &linfo);
+
+                       sz = PLT_ALIGN(mbox_id2size(MBOX_MSG_CGX_LINK_EVENT),
+                                      MBOX_MSG_ALIGN);
+                       /* Prepare the message to be sent */
+                       vf_msg = mbox_alloc_msg(&dev->mbox_vfpf_up, vf, sz);
+                       if (vf_msg) {
+                               mbox_req_init(MBOX_MSG_CGX_LINK_EVENT, vf_msg);
+                               memcpy((uint8_t *)vf_msg +
+                                      sizeof(struct mbox_msghdr), &linfo,
+                                      sizeof(struct cgx_link_user_info));
+
+                               vf_msg->rc = msg->rc;
+                               vf_msg->pcifunc = msg->pcifunc;
+                               /* Send to VF */
+                               mbox_msg_send(&dev->mbox_vfpf_up, vf);
+                       }
+               }
+
                offset = mbox->rx_start + msg->next_msgoff;
        }
        plt_spinlock_unlock(&mdev->mbox_lock);
@@ -851,6 +884,38 @@ vf_flr_register_irqs(struct plt_pci_device *pci_dev, struct dev *dev)
        return 0;
 }
 
+static void
+clear_rvum_interrupts(struct dev *dev)
+{
+       uint64_t intr;
+       int i;
+
+       if (dev_is_vf(dev)) {
+               /* Clear VF mbox interrupt */
+               intr = plt_read64(dev->bar2 + RVU_VF_INT);
+               if (intr)
+                       plt_write64(intr, dev->bar2 + RVU_VF_INT);
+       } else {
+               /* Clear AF PF interrupt line */
+               intr = plt_read64(dev->bar2 + RVU_PF_INT);
+               if (intr)
+                       plt_write64(intr, dev->bar2 + RVU_PF_INT);
+               for (i = 0; i < MAX_VFPF_DWORD_BITS; ++i) {
+                       /* Clear MBOX interrupts */
+                       intr = plt_read64(dev->bar2 + RVU_PF_VFPF_MBOX_INTX(i));
+                       if (intr)
+                               plt_write64(intr,
+                                           dev->bar2 +
+                                                   RVU_PF_VFPF_MBOX_INTX(i));
+                       /* Clear VF FLR interrupts */
+                       intr = plt_read64(dev->bar2 + RVU_PF_VFFLR_INTX(i));
+                       if (intr)
+                               plt_write64(intr,
+                                           dev->bar2 + RVU_PF_VFFLR_INTX(i));
+               }
+       }
+}
+
 int
 dev_active_vfs(struct dev *dev)
 {
@@ -870,6 +935,8 @@ dev_vf_hwcap_update(struct plt_pci_device *pci_dev, struct dev *dev)
                break;
        case PCI_DEVID_CNXK_RVU_SSO_TIM_VF:
        case PCI_DEVID_CNXK_RVU_NPA_VF:
+       case PCI_DEVID_CN10K_RVU_CPT_VF:
+       case PCI_DEVID_CN9K_RVU_CPT_VF:
        case PCI_DEVID_CNXK_RVU_AF_VF:
        case PCI_DEVID_CNXK_RVU_VF:
        case PCI_DEVID_CNXK_RVU_SDP_VF:
@@ -1055,6 +1122,9 @@ dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
                intr_offset = RVU_PF_INT;
        }
 
+       /* Clear all RVUM interrupts */
+       clear_rvum_interrupts(dev);
+
        /* Initialize the local mbox */
        rc = mbox_init(&dev->mbox_local, mbox, bar2, direction, 1, intr_offset);
        if (rc)