common/cnxk: improve MCAM entries management
[dpdk.git] / drivers / common / cnxk / roc_cpt.c
index 6ddbaa2..74ada6e 100644 (file)
@@ -370,7 +370,7 @@ cpt_available_lfs_get(struct dev *dev, uint16_t *nb_lf)
        if (rc)
                return -EIO;
 
-       *nb_lf = rsp->cpt;
+       *nb_lf = PLT_MAX((uint16_t)rsp->cpt, (uint16_t)rsp->cpt1);
        return 0;
 }
 
@@ -405,7 +405,7 @@ cpt_lfs_free(struct dev *dev)
 }
 
 static int
-cpt_hardware_caps_get(struct dev *dev, union cpt_eng_caps *hw_caps)
+cpt_hardware_caps_get(struct dev *dev, struct roc_cpt *roc_cpt)
 {
        struct cpt_caps_rsp_msg *rsp;
        int ret;
@@ -416,7 +416,8 @@ cpt_hardware_caps_get(struct dev *dev, union cpt_eng_caps *hw_caps)
        if (ret)
                return -EIO;
 
-       mbox_memcpy(hw_caps, rsp->eng_caps,
+       roc_cpt->cpt_revision = rsp->cpt_revision;
+       mbox_memcpy(roc_cpt->hw_caps, rsp->eng_caps,
                    sizeof(union cpt_eng_caps) * CPT_MAX_ENG_TYPES);
 
        return 0;
@@ -437,8 +438,10 @@ cpt_lf_iq_mem_calc(uint32_t nb_desc)
        len += CPT_IQ_FC_LEN;
 
        /* For instruction queues */
-       len += CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc) * CPT_IQ_NB_DESC_MULTIPLIER *
-              sizeof(struct cpt_inst_s);
+       len += PLT_ALIGN(CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc) *
+                                CPT_IQ_NB_DESC_MULTIPLIER *
+                                sizeof(struct cpt_inst_s),
+                        ROC_ALIGN);
 
        return len;
 }
@@ -476,21 +479,40 @@ int
 roc_cpt_dev_configure(struct roc_cpt *roc_cpt, int nb_lf)
 {
        struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
-       uint8_t blkaddr = RVU_BLOCK_ADDR_CPT0;
+       uint8_t blkaddr[ROC_CPT_MAX_BLKS];
        struct msix_offset_rsp *rsp;
        uint8_t eng_grpmsk;
+       int blknum = 0;
        int rc, i;
 
+       blkaddr[0] = RVU_BLOCK_ADDR_CPT0;
+       blkaddr[1] = RVU_BLOCK_ADDR_CPT1;
+
+       if ((roc_cpt->cpt_revision == ROC_CPT_REVISION_ID_98XX) &&
+           (cpt->dev.pf_func & 0x1))
+               blknum = (blknum + 1) % ROC_CPT_MAX_BLKS;
+
        /* Request LF resources */
-       rc = cpt_lfs_attach(&cpt->dev, blkaddr, true, nb_lf);
-       if (rc)
+       rc = cpt_lfs_attach(&cpt->dev, blkaddr[blknum], true, nb_lf);
+
+       /* Request LFs from another block if current block has less LFs */
+       if (roc_cpt->cpt_revision == ROC_CPT_REVISION_ID_98XX && rc == ENOSPC) {
+               blknum = (blknum + 1) % ROC_CPT_MAX_BLKS;
+               rc = cpt_lfs_attach(&cpt->dev, blkaddr[blknum], true, nb_lf);
+       }
+       if (rc) {
+               plt_err("Could not attach LFs");
                return rc;
+       }
+
+       for (i = 0; i < nb_lf; i++)
+               cpt->lf_blkaddr[i] = blkaddr[blknum];
 
        eng_grpmsk = (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_AE]) |
                     (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_SE]) |
                     (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_IE]);
 
-       rc = cpt_lfs_alloc(&cpt->dev, eng_grpmsk, blkaddr, false);
+       rc = cpt_lfs_alloc(&cpt->dev, eng_grpmsk, blkaddr[blknum], false);
        if (rc)
                goto lfs_detach;
 
@@ -550,6 +572,7 @@ cpt_lf_init(struct roc_cpt_lf *lf)
        iq_mem = plt_zmalloc(cpt_lf_iq_mem_calc(lf->nb_desc), ROC_ALIGN);
        if (iq_mem == NULL)
                return -ENOMEM;
+       plt_atomic_thread_fence(__ATOMIC_ACQ_REL);
 
        blkaddr = cpt_get_blkaddr(dev);
        lf->rbase = dev->bar2 + ((blkaddr << 20) | (lf->lf_id << 12));
@@ -621,7 +644,7 @@ roc_cpt_dev_init(struct roc_cpt *roc_cpt)
        cpt->pci_dev = pci_dev;
        roc_cpt->lmt_base = dev->lmt_base;
 
-       rc = cpt_hardware_caps_get(dev, roc_cpt->hw_caps);
+       rc = cpt_hardware_caps_get(dev, roc_cpt);
        if (rc) {
                plt_err("Could not determine hardware capabilities");
                goto fail;
@@ -634,7 +657,7 @@ roc_cpt_dev_init(struct roc_cpt *roc_cpt)
        }
 
        /* Reserve 1 CPT LF for inline inbound */
-       nb_lf_avail = PLT_MIN(nb_lf_avail, ROC_CPT_MAX_LFS - 1);
+       nb_lf_avail = PLT_MIN(nb_lf_avail, (uint16_t)(ROC_CPT_MAX_LFS - 1));
 
        roc_cpt->nb_lf_avail = nb_lf_avail;
 
@@ -770,8 +793,10 @@ void
 roc_cpt_iq_disable(struct roc_cpt_lf *lf)
 {
        union cpt_lf_ctl lf_ctl = {.u = 0x0};
+       union cpt_lf_q_grp_ptr grp_ptr;
        union cpt_lf_inprog lf_inprog;
        int timeout = 20;
+       int cnt;
 
        /* Disable instructions enqueuing */
        plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL);
@@ -795,6 +820,27 @@ roc_cpt_iq_disable(struct roc_cpt_lf *lf)
         */
        lf_inprog.s.eena = 0x0;
        plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG);
+
+       /* Wait for instruction queue to become empty */
+       cnt = 0;
+       do {
+               lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
+               if (lf_inprog.s.grb_partial)
+                       cnt = 0;
+               else
+                       cnt++;
+               grp_ptr.u = plt_read64(lf->rbase + CPT_LF_Q_GRP_PTR);
+       } while ((cnt < 10) && (grp_ptr.s.nq_ptr != grp_ptr.s.dq_ptr));
+
+       cnt = 0;
+       do {
+               lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
+               if ((lf_inprog.s.inflight == 0) && (lf_inprog.s.gwb_cnt < 40) &&
+                   ((lf_inprog.s.grb_cnt == 0) || (lf_inprog.s.grb_cnt == 40)))
+                       cnt++;
+               else
+                       cnt = 0;
+       } while (cnt < 10);
 }
 
 void
@@ -806,11 +852,6 @@ roc_cpt_iq_enable(struct roc_cpt_lf *lf)
        /* Disable command queue */
        roc_cpt_iq_disable(lf);
 
-       /* Enable command queue execution */
-       lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
-       lf_inprog.s.eena = 1;
-       plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG);
-
        /* Enable instruction queue enqueuing */
        lf_ctl.u = plt_read64(lf->rbase + CPT_LF_CTL);
        lf_ctl.s.ena = 1;
@@ -819,6 +860,11 @@ roc_cpt_iq_enable(struct roc_cpt_lf *lf)
        lf_ctl.s.fc_hyst_bits = lf->fc_hyst_bits;
        plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL);
 
+       /* Enable command queue execution */
+       lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
+       lf_inprog.s.eena = 1;
+       plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG);
+
        cpt_lf_dump(lf);
 }