LCOV - code coverage report
Current view: top level - drivers/common/cnxk - roc_cpt.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 510 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 43 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 218 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2021 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "roc_api.h"
       6                 :            : #include "roc_priv.h"
       7                 :            : 
       8                 :            : #define CPT_IQ_FC_LEN  128
       9                 :            : #define CPT_IQ_GRP_LEN 16
      10                 :            : 
      11                 :            : #define CPT_IQ_NB_DESC_MULTIPLIER 40
      12                 :            : 
      13                 :            : /* The effective queue size to software is (CPT_LF_Q_SIZE[SIZE_DIV40] - 1 - 8).
      14                 :            :  *
      15                 :            :  * CPT requires 320 free entries (+8). And 40 entries are required for
      16                 :            :  * allowing CPT to discard packet when the queues are full (+1).
      17                 :            :  */
      18                 :            : #define CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc)                                     \
      19                 :            :         (PLT_DIV_CEIL(nb_desc, CPT_IQ_NB_DESC_MULTIPLIER) + 1 + 8)
      20                 :            : 
      21                 :            : #define CPT_IQ_GRP_SIZE(nb_desc)                                               \
      22                 :            :         (CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc) * CPT_IQ_GRP_LEN)
      23                 :            : 
      24                 :            : #define CPT_LF_MAX_NB_DESC      128000
      25                 :            : #define CPT_LF_DEFAULT_NB_DESC  1024
      26                 :            : #define CPT_LF_FC_MIN_THRESHOLD 32
      27                 :            : 
      28                 :            : static struct cpt_int_cb {
      29                 :            :         roc_cpt_int_misc_cb_t cb;
      30                 :            :         void *cb_args;
      31                 :            : } int_cb;
      32                 :            : 
      33                 :            : static void
      34                 :            : cpt_lf_misc_intr_enb_dis(struct roc_cpt_lf *lf, bool enb)
      35                 :            : {
      36                 :            :         /* Enable all cpt lf error irqs except RQ_DISABLED and CQ_DISABLED */
      37                 :            :         if (enb)
      38                 :          0 :                 plt_write64((BIT_ULL(6) | BIT_ULL(5) | BIT_ULL(3) | BIT_ULL(2) |
      39                 :            :                              BIT_ULL(1)),
      40                 :            :                             lf->rbase + CPT_LF_MISC_INT_ENA_W1S);
      41                 :            :         else
      42                 :          0 :                 plt_write64((BIT_ULL(6) | BIT_ULL(5) | BIT_ULL(3) | BIT_ULL(2) |
      43                 :            :                              BIT_ULL(1)),
      44                 :            :                             lf->rbase + CPT_LF_MISC_INT_ENA_W1C);
      45                 :            : }
      46                 :            : 
      47                 :            : static void
      48                 :          0 : cpt_lf_misc_irq(void *param)
      49                 :            : {
      50                 :            :         struct roc_cpt_lf *lf = (struct roc_cpt_lf *)param;
      51                 :          0 :         struct dev *dev = lf->dev;
      52                 :            :         uint64_t intr;
      53                 :            : 
      54         [ #  # ]:          0 :         intr = plt_read64(lf->rbase + CPT_LF_MISC_INT);
      55         [ #  # ]:          0 :         if (intr == 0)
      56                 :            :                 return;
      57                 :            : 
      58                 :          0 :         plt_err("Err_irq=0x%" PRIx64 " pf=%d, vf=%d", intr, dev->pf, dev->vf);
      59                 :            : 
      60                 :            :         /* Dump lf registers */
      61                 :          0 :         cpt_lf_print(lf);
      62                 :            : 
      63                 :            :         /* Clear interrupt */
      64         [ #  # ]:          0 :         plt_write64(intr, lf->rbase + CPT_LF_MISC_INT);
      65                 :            : 
      66         [ #  # ]:          0 :         if (int_cb.cb != NULL) {
      67                 :          0 :                 lf->error_event_pending = 1;
      68                 :          0 :                 int_cb.cb(lf, int_cb.cb_args);
      69                 :            :         }
      70                 :            : }
      71                 :            : 
      72                 :            : static int
      73                 :          0 : cpt_lf_register_misc_irq(struct roc_cpt_lf *lf)
      74                 :            : {
      75                 :          0 :         struct plt_pci_device *pci_dev = lf->pci_dev;
      76                 :            :         struct plt_intr_handle *handle;
      77                 :            :         int rc, vec;
      78                 :            : 
      79                 :          0 :         handle = pci_dev->intr_handle;
      80                 :            : 
      81                 :          0 :         vec = lf->msixoff + CPT_LF_INT_VEC_MISC;
      82                 :            :         /* Clear err interrupt */
      83                 :            :         cpt_lf_misc_intr_enb_dis(lf, false);
      84                 :            :         /* Set used interrupt vectors */
      85                 :          0 :         rc = dev_irq_register(handle, cpt_lf_misc_irq, lf, vec);
      86                 :            :         /* Enable all dev interrupt except for RQ_DISABLED */
      87                 :            :         cpt_lf_misc_intr_enb_dis(lf, true);
      88                 :            : 
      89                 :          0 :         return rc;
      90                 :            : }
      91                 :            : 
      92                 :            : static void
      93                 :          0 : cpt_lf_unregister_misc_irq(struct roc_cpt_lf *lf)
      94                 :            : {
      95                 :          0 :         struct plt_pci_device *pci_dev = lf->pci_dev;
      96                 :            :         struct plt_intr_handle *handle;
      97                 :            :         int vec;
      98                 :            : 
      99                 :          0 :         handle = pci_dev->intr_handle;
     100                 :            : 
     101                 :          0 :         vec = lf->msixoff + CPT_LF_INT_VEC_MISC;
     102                 :            :         /* Clear err interrupt */
     103                 :            :         cpt_lf_misc_intr_enb_dis(lf, false);
     104                 :          0 :         dev_irq_unregister(handle, cpt_lf_misc_irq, lf, vec);
     105                 :          0 : }
     106                 :            : 
     107                 :            : static void
     108                 :            : cpt_lf_done_intr_enb_dis(struct roc_cpt_lf *lf, bool enb)
     109                 :            : {
     110                 :            :         if (enb)
     111                 :          0 :                 plt_write64(0x1, lf->rbase + CPT_LF_DONE_INT_ENA_W1S);
     112                 :            :         else
     113                 :          0 :                 plt_write64(0x1, lf->rbase + CPT_LF_DONE_INT_ENA_W1C);
     114                 :            : }
     115                 :            : 
     116                 :            : static void
     117                 :          0 : cpt_lf_done_irq(void *param)
     118                 :            : {
     119                 :            :         struct roc_cpt_lf *lf = param;
     120                 :            :         uint64_t done_wait;
     121                 :            :         uint64_t intr;
     122                 :            : 
     123                 :            :         /* Read the number of completed requests */
     124         [ #  # ]:          0 :         intr = plt_read64(lf->rbase + CPT_LF_DONE);
     125         [ #  # ]:          0 :         if (intr == 0)
     126                 :            :                 return;
     127                 :            : 
     128                 :          0 :         done_wait = plt_read64(lf->rbase + CPT_LF_DONE_WAIT);
     129                 :            : 
     130                 :            :         /* Acknowledge the number of completed requests */
     131                 :          0 :         plt_write64(intr, lf->rbase + CPT_LF_DONE_ACK);
     132                 :            : 
     133                 :          0 :         plt_write64(done_wait, lf->rbase + CPT_LF_DONE_WAIT);
     134                 :            : }
     135                 :            : 
     136                 :            : static int
     137                 :          0 : cpt_lf_register_done_irq(struct roc_cpt_lf *lf)
     138                 :            : {
     139                 :          0 :         struct plt_pci_device *pci_dev = lf->pci_dev;
     140                 :            :         struct plt_intr_handle *handle;
     141                 :            :         int rc, vec;
     142                 :            : 
     143                 :          0 :         handle = pci_dev->intr_handle;
     144                 :            : 
     145                 :          0 :         vec = lf->msixoff + CPT_LF_INT_VEC_DONE;
     146                 :            : 
     147                 :            :         /* Clear done interrupt */
     148                 :            :         cpt_lf_done_intr_enb_dis(lf, false);
     149                 :            : 
     150                 :            :         /* Set used interrupt vectors */
     151                 :          0 :         rc = dev_irq_register(handle, cpt_lf_done_irq, lf, vec);
     152                 :            : 
     153                 :            :         /* Enable done interrupt */
     154                 :            :         cpt_lf_done_intr_enb_dis(lf, true);
     155                 :            : 
     156                 :          0 :         return rc;
     157                 :            : }
     158                 :            : 
     159                 :            : static void
     160                 :          0 : cpt_lf_unregister_done_irq(struct roc_cpt_lf *lf)
     161                 :            : {
     162                 :          0 :         struct plt_pci_device *pci_dev = lf->pci_dev;
     163                 :            :         struct plt_intr_handle *handle;
     164                 :            :         int vec;
     165                 :            : 
     166                 :          0 :         handle = pci_dev->intr_handle;
     167                 :            : 
     168                 :          0 :         vec = lf->msixoff + CPT_LF_INT_VEC_DONE;
     169                 :            : 
     170                 :            :         /* Clear done interrupt */
     171                 :            :         cpt_lf_done_intr_enb_dis(lf, false);
     172                 :          0 :         dev_irq_unregister(handle, cpt_lf_done_irq, lf, vec);
     173                 :          0 : }
     174                 :            : 
     175                 :            : static int
     176                 :          0 : cpt_lf_register_irqs(struct roc_cpt_lf *lf)
     177                 :            : {
     178                 :            :         int rc;
     179                 :            : 
     180         [ #  # ]:          0 :         if (lf->msixoff == MSIX_VECTOR_INVALID) {
     181                 :          0 :                 plt_err("Invalid CPTLF MSIX vector offset vector: 0x%x",
     182                 :            :                         lf->msixoff);
     183                 :          0 :                 return -EINVAL;
     184                 :            :         }
     185                 :            : 
     186                 :            :         /* Register lf err interrupt */
     187                 :          0 :         rc = cpt_lf_register_misc_irq(lf);
     188         [ #  # ]:          0 :         if (rc)
     189                 :          0 :                 plt_err("Error registering IRQs");
     190                 :            : 
     191                 :          0 :         rc = cpt_lf_register_done_irq(lf);
     192         [ #  # ]:          0 :         if (rc)
     193                 :          0 :                 plt_err("Error registering IRQs");
     194                 :            : 
     195                 :            :         return rc;
     196                 :            : }
     197                 :            : 
     198                 :            : static void
     199                 :            : cpt_lf_unregister_irqs(struct roc_cpt_lf *lf)
     200                 :            : {
     201                 :          0 :         cpt_lf_unregister_misc_irq(lf);
     202                 :          0 :         cpt_lf_unregister_done_irq(lf);
     203                 :            : }
     204                 :            : 
     205                 :            : static void
     206                 :          0 : cpt_lf_dump(struct roc_cpt_lf *lf)
     207                 :            : {
     208                 :          0 :         plt_cpt_dbg("CPT LF");
     209                 :          0 :         plt_cpt_dbg("RBASE: 0x%016" PRIx64, lf->rbase);
     210                 :          0 :         plt_cpt_dbg("LMT_BASE: 0x%016" PRIx64, lf->lmt_base);
     211                 :          0 :         plt_cpt_dbg("MSIXOFF: 0x%x", lf->msixoff);
     212                 :          0 :         plt_cpt_dbg("LF_ID: 0x%x", lf->lf_id);
     213                 :          0 :         plt_cpt_dbg("NB DESC: %d", lf->nb_desc);
     214                 :          0 :         plt_cpt_dbg("FC_ADDR: 0x%016" PRIx64, (uintptr_t)lf->fc_addr);
     215                 :          0 :         plt_cpt_dbg("CQ.VADDR: 0x%016" PRIx64, (uintptr_t)lf->iq_vaddr);
     216                 :            : 
     217                 :          0 :         plt_cpt_dbg("CPT LF REG:");
     218                 :          0 :         plt_cpt_dbg("LF_CTL[0x%016llx]: 0x%016" PRIx64, CPT_LF_CTL,
     219                 :            :                     plt_read64(lf->rbase + CPT_LF_CTL));
     220                 :          0 :         plt_cpt_dbg("LF_INPROG[0x%016llx]: 0x%016" PRIx64, CPT_LF_INPROG,
     221                 :            :                     plt_read64(lf->rbase + CPT_LF_INPROG));
     222                 :            : 
     223                 :          0 :         plt_cpt_dbg("Q_BASE[0x%016llx]: 0x%016" PRIx64, CPT_LF_Q_BASE,
     224                 :            :                     plt_read64(lf->rbase + CPT_LF_Q_BASE));
     225                 :          0 :         plt_cpt_dbg("Q_SIZE[0x%016llx]: 0x%016" PRIx64, CPT_LF_Q_SIZE,
     226                 :            :                     plt_read64(lf->rbase + CPT_LF_Q_SIZE));
     227                 :          0 :         plt_cpt_dbg("Q_INST_PTR[0x%016llx]: 0x%016" PRIx64, CPT_LF_Q_INST_PTR,
     228                 :            :                     plt_read64(lf->rbase + CPT_LF_Q_INST_PTR));
     229                 :          0 :         plt_cpt_dbg("Q_GRP_PTR[0x%016llx]: 0x%016" PRIx64, CPT_LF_Q_GRP_PTR,
     230                 :            :                     plt_read64(lf->rbase + CPT_LF_Q_GRP_PTR));
     231                 :          0 : }
     232                 :            : 
     233                 :            : int
     234                 :          0 : cpt_lf_outb_cfg(struct dev *dev, uint16_t sso_pf_func, uint16_t nix_pf_func,
     235                 :            :                 uint8_t lf_id, bool ena)
     236                 :            : {
     237                 :            :         struct cpt_inline_ipsec_cfg_msg *req;
     238                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     239                 :            :         int rc;
     240                 :            : 
     241                 :          0 :         req = mbox_alloc_msg_cpt_inline_ipsec_cfg(mbox);
     242         [ #  # ]:          0 :         if (req == NULL) {
     243                 :            :                 rc = -ENOSPC;
     244                 :          0 :                 goto exit;
     245                 :            :         }
     246                 :            : 
     247                 :          0 :         req->dir = CPT_INLINE_OUTBOUND;
     248                 :          0 :         req->slot = lf_id;
     249         [ #  # ]:          0 :         if (ena) {
     250                 :          0 :                 req->enable = 1;
     251                 :          0 :                 req->sso_pf_func = sso_pf_func;
     252                 :          0 :                 req->nix_pf_func = nix_pf_func;
     253                 :            :         } else {
     254                 :          0 :                 req->enable = 0;
     255                 :            :         }
     256                 :            : 
     257                 :          0 :         rc = mbox_process(mbox);
     258                 :          0 : exit:
     259                 :            :         mbox_put(mbox);
     260                 :          0 :         return rc;
     261                 :            : }
     262                 :            : 
     263                 :            : int
     264                 :          0 : roc_cpt_inline_ipsec_cfg(struct dev *cpt_dev, uint8_t lf_id,
     265                 :            :                          struct roc_nix *roc_nix)
     266                 :            : {
     267                 :          0 :         bool ena = roc_nix ? true : false;
     268                 :            :         uint16_t nix_pf_func = 0;
     269                 :            :         uint16_t sso_pf_func = 0;
     270                 :            : 
     271         [ #  # ]:          0 :         if (ena) {
     272                 :          0 :                 nix_pf_func = roc_nix_get_pf_func(roc_nix);
     273                 :          0 :                 sso_pf_func = idev_sso_pffunc_get();
     274                 :            :         }
     275                 :            : 
     276                 :          0 :         return cpt_lf_outb_cfg(cpt_dev, sso_pf_func, nix_pf_func, lf_id, ena);
     277                 :            : }
     278                 :            : 
     279                 :            : int
     280                 :          0 : roc_cpt_inline_ipsec_inb_cfg_read(struct roc_cpt *roc_cpt,
     281                 :            :                                   struct roc_cpt_inline_ipsec_inb_cfg *cfg)
     282                 :            : {
     283                 :            :         struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
     284                 :            :         struct nix_inline_ipsec_cfg *inb_cfg;
     285                 :            :         struct dev *dev = &cpt->dev;
     286                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     287                 :            :         struct msg_req *req;
     288                 :            :         int rc;
     289                 :            : 
     290                 :          0 :         req = mbox_alloc_msg_nix_read_inline_ipsec_cfg(mbox);
     291         [ #  # ]:          0 :         if (req == NULL) {
     292                 :            :                 rc = -EIO;
     293                 :          0 :                 goto exit;
     294                 :            :         }
     295                 :            : 
     296                 :            :         rc = mbox_process_msg(mbox, (void *)&inb_cfg);
     297         [ #  # ]:          0 :         if (rc) {
     298                 :            :                 rc = -EIO;
     299                 :          0 :                 goto exit;
     300                 :            :         }
     301                 :          0 :         cfg->cpt_credit = inb_cfg->cpt_credit;
     302                 :          0 :         cfg->egrp = inb_cfg->gen_cfg.egrp;
     303                 :          0 :         cfg->opcode = inb_cfg->gen_cfg.opcode;
     304                 :          0 :         cfg->param1 = inb_cfg->gen_cfg.param1;
     305                 :          0 :         cfg->param2 = inb_cfg->gen_cfg.param2;
     306                 :          0 :         cfg->bpid = inb_cfg->bpid;
     307                 :          0 :         cfg->credit_th = inb_cfg->credit_th;
     308                 :          0 : exit:
     309                 :            :         mbox_put(mbox);
     310                 :          0 :         return rc;
     311                 :            : }
     312                 :            : 
     313                 :            : int
     314                 :          0 : roc_cpt_inline_ipsec_inb_cfg(struct roc_cpt *roc_cpt, struct roc_cpt_inline_ipsec_inb_cfg *cfg)
     315                 :            : {
     316                 :            :         struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
     317                 :            :         struct cpt_rx_inline_lf_cfg_msg *req;
     318                 :            :         struct mbox *mbox;
     319                 :            :         int rc;
     320                 :            : 
     321                 :          0 :         mbox = mbox_get(cpt->dev.mbox);
     322                 :            : 
     323                 :          0 :         req = mbox_alloc_msg_cpt_rx_inline_lf_cfg(mbox);
     324         [ #  # ]:          0 :         if (req == NULL) {
     325                 :            :                 rc = -ENOSPC;
     326                 :          0 :                 goto exit;
     327                 :            :         }
     328                 :            : 
     329                 :          0 :         req->sso_pf_func = idev_sso_pffunc_get();
     330                 :          0 :         req->param1 = cfg->param1;
     331                 :          0 :         req->param2 = cfg->param2;
     332                 :          0 :         req->opcode = cfg->opcode;
     333                 :          0 :         req->bpid = cfg->bpid;
     334                 :          0 :         req->ctx_ilen_valid = cfg->ctx_ilen_valid;
     335                 :          0 :         req->ctx_ilen = cfg->ctx_ilen;
     336                 :            : 
     337                 :          0 :         rc = mbox_process(mbox);
     338                 :          0 : exit:
     339                 :            :         mbox_put(mbox);
     340                 :          0 :         return rc;
     341                 :            : }
     342                 :            : 
     343                 :            : int
     344                 :          0 : roc_cpt_rxc_time_cfg(struct roc_cpt *roc_cpt, struct roc_cpt_rxc_time_cfg *cfg)
     345                 :            : {
     346                 :            :         struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
     347                 :            :         struct cpt_rxc_time_cfg_req *req;
     348                 :            :         struct dev *dev = &cpt->dev;
     349                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     350                 :            :         int rc;
     351                 :            : 
     352                 :          0 :         req = mbox_alloc_msg_cpt_rxc_time_cfg(mbox);
     353         [ #  # ]:          0 :         if (req == NULL) {
     354                 :            :                 rc = -ENOSPC;
     355                 :          0 :                 goto exit;
     356                 :            :         }
     357                 :            : 
     358                 :          0 :         req->blkaddr = 0;
     359                 :            : 
     360                 :            :         /* The step value is in microseconds. */
     361                 :          0 :         req->step = cfg->step;
     362                 :            : 
     363                 :            :         /* The timeout will be: limit * step microseconds */
     364                 :          0 :         req->zombie_limit = cfg->zombie_limit;
     365                 :          0 :         req->zombie_thres = cfg->zombie_thres;
     366                 :            : 
     367                 :            :         /* The timeout will be: limit * step microseconds */
     368                 :          0 :         req->active_limit = cfg->active_limit;
     369                 :          0 :         req->active_thres = cfg->active_thres;
     370                 :            : 
     371                 :          0 :         rc = mbox_process(mbox);
     372                 :          0 : exit:
     373                 :            :         mbox_put(mbox);
     374                 :          0 :         return rc;
     375                 :            : }
     376                 :            : 
     377                 :            : int
     378                 :          0 : cpt_get_msix_offset(struct dev *dev, struct msix_offset_rsp **msix_rsp)
     379                 :            : {
     380                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     381                 :            :         int rc;
     382                 :            : 
     383                 :            :         /* Get MSIX vector offsets */
     384                 :          0 :         mbox_alloc_msg_msix_offset(mbox);
     385                 :            :         rc = mbox_process_msg(mbox, (void *)msix_rsp);
     386                 :            :         mbox_put(mbox);
     387                 :            : 
     388                 :          0 :         return rc;
     389                 :            : }
     390                 :            : 
     391                 :            : int
     392                 :          0 : cpt_lfs_attach(struct dev *dev, uint8_t blkaddr, bool modify, uint16_t nb_lf)
     393                 :            : {
     394                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     395                 :            :         struct rsrc_attach_req *req;
     396                 :            :         int rc;
     397                 :            : 
     398         [ #  # ]:          0 :         if (blkaddr != RVU_BLOCK_ADDR_CPT0 && blkaddr != RVU_BLOCK_ADDR_CPT1) {
     399                 :            :                 rc = -EINVAL;
     400                 :          0 :                 goto exit;
     401                 :            :         }
     402                 :            : 
     403                 :            :         /* Attach CPT(lf) */
     404                 :          0 :         req = mbox_alloc_msg_attach_resources(mbox);
     405         [ #  # ]:          0 :         if (req == NULL) {
     406                 :            :                 rc = -ENOSPC;
     407                 :          0 :                 goto exit;
     408                 :            :         }
     409                 :            : 
     410                 :          0 :         req->cptlfs = nb_lf;
     411                 :          0 :         req->modify = modify;
     412                 :          0 :         req->cpt_blkaddr = blkaddr;
     413                 :            : 
     414                 :          0 :         rc = mbox_process(mbox);
     415                 :          0 : exit:
     416                 :            :         mbox_put(mbox);
     417                 :          0 :         return rc;
     418                 :            : }
     419                 :            : 
     420                 :            : int
     421                 :          0 : cpt_lfs_detach(struct dev *dev)
     422                 :            : {
     423                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     424                 :            :         struct rsrc_detach_req *req;
     425                 :            :         int rc;
     426                 :            : 
     427                 :          0 :         req = mbox_alloc_msg_detach_resources(mbox);
     428         [ #  # ]:          0 :         if (req == NULL) {
     429                 :            :                 rc =  -ENOSPC;
     430                 :          0 :                 goto exit;
     431                 :            :         }
     432                 :            : 
     433                 :          0 :         req->cptlfs = 1;
     434                 :          0 :         req->partial = 1;
     435                 :            : 
     436                 :          0 :         rc = mbox_process(mbox);
     437                 :          0 : exit:
     438                 :            :         mbox_put(mbox);
     439                 :          0 :         return rc;
     440                 :            : }
     441                 :            : 
     442                 :            : static int
     443                 :          0 : cpt_available_lfs_get(struct dev *dev, uint16_t *nb_lf)
     444                 :            : {
     445                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     446                 :            :         struct free_rsrcs_rsp *rsp;
     447                 :            :         int rc;
     448                 :            : 
     449                 :          0 :         mbox_alloc_msg_free_rsrc_cnt(mbox);
     450                 :            : 
     451                 :            :         rc = mbox_process_msg(mbox, (void *)&rsp);
     452         [ #  # ]:          0 :         if (rc) {
     453                 :            :                 rc = -EIO;
     454                 :          0 :                 goto exit;
     455                 :            :         }
     456                 :            : 
     457                 :          0 :         *nb_lf = PLT_MAX((uint16_t)rsp->cpt, (uint16_t)rsp->cpt1);
     458                 :            :         rc = 0;
     459                 :          0 : exit:
     460                 :            :         mbox_put(mbox);
     461                 :          0 :         return rc;
     462                 :            : }
     463                 :            : 
     464                 :            : int
     465                 :          0 : cpt_lfs_alloc(struct dev *dev, uint8_t eng_grpmsk, uint8_t blkaddr, bool inl_dev_sso,
     466                 :            :               bool ctx_ilen_valid, uint8_t ctx_ilen, bool rxc_ena, uint16_t rx_inject_qp)
     467                 :            : {
     468                 :            :         struct cpt_lf_alloc_req_msg *req;
     469                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     470                 :            :         int rc;
     471                 :            : 
     472         [ #  # ]:          0 :         if (blkaddr != RVU_BLOCK_ADDR_CPT0 && blkaddr != RVU_BLOCK_ADDR_CPT1) {
     473                 :            :                 rc = -EINVAL;
     474                 :          0 :                 goto exit;
     475                 :            :         }
     476                 :            : 
     477                 :          0 :         req = mbox_alloc_msg_cpt_lf_alloc(mbox);
     478         [ #  # ]:          0 :         if (!req) {
     479                 :            :                 rc = -ENOSPC;
     480                 :          0 :                 goto exit;
     481                 :            :         }
     482                 :            : 
     483                 :          0 :         req->nix_pf_func = 0;
     484   [ #  #  #  # ]:          0 :         if (inl_dev_sso && nix_inl_dev_pffunc_get())
     485                 :          0 :                 req->sso_pf_func = nix_inl_dev_pffunc_get();
     486                 :            :         else
     487                 :          0 :                 req->sso_pf_func = idev_sso_pffunc_get();
     488                 :          0 :         req->eng_grpmsk = eng_grpmsk;
     489                 :          0 :         req->blkaddr = blkaddr;
     490                 :          0 :         req->ctx_ilen_valid = ctx_ilen_valid;
     491                 :          0 :         req->ctx_ilen = ctx_ilen;
     492         [ #  # ]:          0 :         if (rxc_ena) {
     493                 :          0 :                 req->rxc_ena = 1;
     494                 :          0 :                 req->rxc_ena_lf_id = rx_inject_qp;
     495                 :            :         }
     496                 :            : 
     497                 :          0 :         rc = mbox_process(mbox);
     498                 :          0 : exit:
     499                 :            :         mbox_put(mbox);
     500                 :          0 :         return rc;
     501                 :            : }
     502                 :            : 
     503                 :            : int
     504                 :          0 : cpt_lfs_free(struct dev *dev)
     505                 :            : {
     506                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     507                 :            :         int rc;
     508                 :            : 
     509                 :          0 :         mbox_alloc_msg_cpt_lf_free(mbox);
     510                 :            : 
     511                 :          0 :         rc = mbox_process(mbox);
     512                 :            :         mbox_put(mbox);
     513                 :          0 :         return rc;
     514                 :            : }
     515                 :            : 
     516                 :            : static int
     517                 :          0 : cpt_hardware_caps_get(struct dev *dev, struct roc_cpt *roc_cpt)
     518                 :            : {
     519                 :            :         struct cpt_caps_rsp_msg *rsp;
     520                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     521                 :            :         int ret;
     522                 :            : 
     523                 :          0 :         mbox_alloc_msg_cpt_caps_get(mbox);
     524                 :            : 
     525                 :            :         ret = mbox_process_msg(mbox, (void *)&rsp);
     526         [ #  # ]:          0 :         if (ret) {
     527                 :            :                 ret = -EIO;
     528                 :          0 :                 goto exit;
     529                 :            :         }
     530                 :            : 
     531                 :          0 :         roc_cpt->cpt_revision = rsp->cpt_revision;
     532                 :          0 :         mbox_memcpy(roc_cpt->hw_caps, rsp->eng_caps,
     533                 :            :                     sizeof(union cpt_eng_caps) * CPT_MAX_ENG_TYPES);
     534                 :            : 
     535                 :            :         ret = 0;
     536                 :            : 
     537                 :          0 : exit:
     538                 :            :         mbox_put(mbox);
     539                 :          0 :         return ret;
     540                 :            : }
     541                 :            : 
     542                 :            : static uint32_t
     543                 :            : cpt_lf_iq_mem_calc(uint32_t nb_desc)
     544                 :            : {
     545                 :            :         uint32_t len;
     546                 :            : 
     547                 :            :         /* Space for instruction group memory */
     548                 :          0 :         len = CPT_IQ_GRP_SIZE(nb_desc);
     549                 :            : 
     550                 :            :         /* Align to 128B */
     551                 :          0 :         len = PLT_ALIGN(len, ROC_ALIGN);
     552                 :            : 
     553                 :            :         /* Space for FC */
     554                 :          0 :         len += CPT_IQ_FC_LEN;
     555                 :            : 
     556                 :            :         /* For instruction queues */
     557                 :          0 :         len += PLT_ALIGN(CPT_IQ_NB_DESC_SIZE_DIV40(nb_desc) *
     558                 :            :                                  CPT_IQ_NB_DESC_MULTIPLIER *
     559                 :            :                                  sizeof(struct cpt_inst_s),
     560                 :            :                          ROC_ALIGN);
     561                 :            : 
     562                 :            :         return len;
     563                 :            : }
     564                 :            : 
     565                 :            : static inline void
     566                 :          0 : cpt_iq_init(struct roc_cpt_lf *lf)
     567                 :            : {
     568                 :          0 :         union cpt_lf_q_size lf_q_size = {.u = 0x0};
     569                 :            :         union cpt_lf_q_base lf_q_base = {.u = 0x0};
     570                 :            :         uintptr_t addr;
     571                 :            : 
     572                 :          0 :         lf->io_addr = lf->rbase + CPT_LF_NQX(0);
     573                 :            : 
     574                 :            :         /* Disable command queue */
     575                 :          0 :         roc_cpt_iq_disable(lf);
     576                 :            : 
     577                 :            :         /* Set command queue base address */
     578                 :          0 :         addr = (uintptr_t)lf->iq_vaddr +
     579                 :          0 :                PLT_ALIGN(CPT_IQ_GRP_SIZE(lf->nb_desc), ROC_ALIGN);
     580                 :            : 
     581                 :            :         lf_q_base.u = addr;
     582                 :            : 
     583                 :          0 :         plt_write64(lf_q_base.u, lf->rbase + CPT_LF_Q_BASE);
     584                 :            : 
     585                 :            :         /* Set command queue size */
     586                 :          0 :         lf_q_size.s.size_div40 = CPT_IQ_NB_DESC_SIZE_DIV40(lf->nb_desc);
     587                 :          0 :         plt_write64(lf_q_size.u, lf->rbase + CPT_LF_Q_SIZE);
     588                 :            : 
     589                 :          0 :         lf->fc_addr = (uint64_t *)addr;
     590                 :          0 : }
     591                 :            : 
     592                 :            : int
     593                 :          0 : roc_cpt_dev_configure(struct roc_cpt *roc_cpt, int nb_lf, bool rxc_ena, uint16_t rx_inject_qp)
     594                 :            : {
     595                 :            :         struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
     596                 :            :         uint8_t blkaddr[ROC_CPT_MAX_BLKS];
     597                 :            :         struct msix_offset_rsp *rsp;
     598                 :            :         bool ctx_ilen_valid = false;
     599                 :            :         uint16_t ctx_ilen = 0;
     600                 :            :         uint8_t eng_grpmsk;
     601                 :            :         int blknum = 0;
     602                 :            :         int rc, i;
     603                 :            : 
     604                 :          0 :         blkaddr[0] = RVU_BLOCK_ADDR_CPT0;
     605                 :          0 :         blkaddr[1] = RVU_BLOCK_ADDR_CPT1;
     606                 :            : 
     607         [ #  # ]:          0 :         if ((roc_cpt->cpt_revision == ROC_CPT_REVISION_ID_98XX) &&
     608         [ #  # ]:          0 :             (cpt->dev.pf_func & 0x1))
     609                 :            :                 blknum = (blknum + 1) % ROC_CPT_MAX_BLKS;
     610                 :            : 
     611                 :            :         /* Request LF resources */
     612                 :          0 :         rc = cpt_lfs_attach(&cpt->dev, blkaddr[blknum], true, nb_lf);
     613                 :            : 
     614                 :            :         /* Request LFs from another block if current block has less LFs */
     615   [ #  #  #  # ]:          0 :         if (roc_cpt->cpt_revision == ROC_CPT_REVISION_ID_98XX && rc == ENOSPC) {
     616                 :          0 :                 blknum = (blknum + 1) % ROC_CPT_MAX_BLKS;
     617                 :          0 :                 rc = cpt_lfs_attach(&cpt->dev, blkaddr[blknum], true, nb_lf);
     618                 :            :         }
     619         [ #  # ]:          0 :         if (rc) {
     620                 :          0 :                 plt_err("Could not attach LFs");
     621                 :          0 :                 return rc;
     622                 :            :         }
     623                 :            : 
     624         [ #  # ]:          0 :         for (i = 0; i < nb_lf; i++)
     625                 :          0 :                 cpt->lf_blkaddr[i] = blkaddr[blknum];
     626                 :            : 
     627                 :          0 :         eng_grpmsk = (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_AE]) |
     628                 :          0 :                      (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_SE]) |
     629         [ #  # ]:          0 :                      (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_IE]);
     630                 :            : 
     631         [ #  # ]:          0 :         if (roc_errata_cpt_has_ctx_fetch_issue()) {
     632                 :            :                 ctx_ilen_valid = true;
     633                 :            :                 /* Inbound SA size is max context size */
     634                 :            :                 ctx_ilen = (PLT_ALIGN(ROC_OT_IPSEC_SA_SZ_MAX, ROC_ALIGN) / 128) - 1;
     635                 :            :         }
     636                 :            : 
     637                 :          0 :         rc = cpt_lfs_alloc(&cpt->dev, eng_grpmsk, blkaddr[blknum], false, ctx_ilen_valid, ctx_ilen,
     638                 :            :                            rxc_ena, rx_inject_qp);
     639         [ #  # ]:          0 :         if (rc)
     640                 :          0 :                 goto lfs_detach;
     641                 :            : 
     642                 :          0 :         rc = cpt_get_msix_offset(&cpt->dev, &rsp);
     643         [ #  # ]:          0 :         if (rc)
     644                 :          0 :                 goto lfs_free;
     645                 :            : 
     646         [ #  # ]:          0 :         for (i = 0; i < nb_lf; i++)
     647                 :          0 :                 cpt->lf_msix_off[i] =
     648         [ #  # ]:          0 :                         (cpt->lf_blkaddr[i] == RVU_BLOCK_ADDR_CPT1) ?
     649                 :          0 :                                 rsp->cpt1_lf_msixoff[i] :
     650                 :          0 :                                 rsp->cptlf_msixoff[i];
     651                 :            : 
     652                 :          0 :         roc_cpt->nb_lf = nb_lf;
     653                 :            : 
     654                 :          0 :         return 0;
     655                 :            : 
     656                 :            : lfs_free:
     657                 :          0 :         cpt_lfs_free(&cpt->dev);
     658                 :          0 : lfs_detach:
     659                 :          0 :         cpt_lfs_detach(&cpt->dev);
     660                 :          0 :         return rc;
     661                 :            : }
     662                 :            : 
     663                 :            : uint64_t
     664                 :          0 : cpt_get_blkaddr(struct dev *dev)
     665                 :            : {
     666                 :            :         uint64_t reg;
     667                 :            :         uint64_t off;
     668                 :            : 
     669                 :            :         /* Reading the discovery register to know which CPT is the LF
     670                 :            :          * attached to. Assume CPT LF's of only one block are attached
     671                 :            :          * to a pffunc.
     672                 :            :          */
     673                 :            :         if (dev_is_vf(dev))
     674                 :            :                 off = RVU_VF_BLOCK_ADDRX_DISC(RVU_BLOCK_ADDR_CPT1);
     675                 :            :         else
     676                 :            :                 off = RVU_PF_BLOCK_ADDRX_DISC(RVU_BLOCK_ADDR_CPT1);
     677                 :            : 
     678         [ #  # ]:          0 :         reg = plt_read64(dev->bar2 + off);
     679                 :            : 
     680         [ #  # ]:          0 :         return reg & 0x1FFULL ? RVU_BLOCK_ADDR_CPT1 : RVU_BLOCK_ADDR_CPT0;
     681                 :            : }
     682                 :            : 
     683                 :            : int
     684                 :          0 : cpt_lf_init(struct roc_cpt_lf *lf)
     685                 :            : {
     686                 :          0 :         struct dev *dev = lf->dev;
     687                 :            :         uint64_t blkaddr;
     688                 :            :         void *iq_mem;
     689                 :            :         int rc;
     690                 :            : 
     691         [ #  # ]:          0 :         if (lf->nb_desc == 0 || lf->nb_desc > CPT_LF_MAX_NB_DESC)
     692                 :          0 :                 lf->nb_desc = CPT_LF_DEFAULT_NB_DESC;
     693                 :            : 
     694                 :            :         /* Allocate memory for instruction queue for CPT LF. */
     695                 :          0 :         iq_mem = plt_zmalloc(cpt_lf_iq_mem_calc(lf->nb_desc), ROC_ALIGN);
     696         [ #  # ]:          0 :         if (iq_mem == NULL)
     697                 :            :                 return -ENOMEM;
     698                 :            :         plt_atomic_thread_fence(__ATOMIC_ACQ_REL);
     699                 :            : 
     700                 :          0 :         blkaddr = cpt_get_blkaddr(dev);
     701                 :          0 :         lf->rbase = dev->bar2 + ((blkaddr << 20) | (lf->lf_id << 12));
     702                 :          0 :         lf->iq_vaddr = iq_mem;
     703                 :          0 :         lf->lmt_base = dev->lmt_base;
     704                 :          0 :         lf->pf_func = dev->pf_func;
     705                 :            : 
     706                 :            :         /* Initialize instruction queue */
     707                 :          0 :         cpt_iq_init(lf);
     708                 :            : 
     709                 :          0 :         rc = cpt_lf_register_irqs(lf);
     710         [ #  # ]:          0 :         if (rc)
     711                 :          0 :                 goto disable_iq;
     712                 :            : 
     713                 :            :         return 0;
     714                 :            : 
     715                 :            : disable_iq:
     716                 :          0 :         roc_cpt_iq_disable(lf);
     717                 :          0 :         plt_free(iq_mem);
     718                 :          0 :         return rc;
     719                 :            : }
     720                 :            : 
     721                 :            : int
     722                 :          0 : roc_cpt_lf_init(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf)
     723                 :            : {
     724                 :            :         struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
     725                 :            :         int rc;
     726                 :            : 
     727                 :          0 :         lf->dev = &cpt->dev;
     728                 :          0 :         lf->roc_cpt = roc_cpt;
     729                 :          0 :         lf->msixoff = cpt->lf_msix_off[lf->lf_id];
     730                 :          0 :         lf->pci_dev = cpt->pci_dev;
     731                 :            : 
     732                 :          0 :         rc = cpt_lf_init(lf);
     733         [ #  # ]:          0 :         if (rc)
     734                 :            :                 return rc;
     735                 :            : 
     736                 :            :         /* LF init successful */
     737                 :          0 :         roc_cpt->lf[lf->lf_id] = lf;
     738                 :          0 :         return rc;
     739                 :            : }
     740                 :            : 
     741                 :            : int
     742                 :          0 : roc_cpt_dev_init(struct roc_cpt *roc_cpt)
     743                 :            : {
     744                 :            :         struct plt_pci_device *pci_dev;
     745                 :            :         uint16_t nb_lf_avail;
     746                 :            :         struct dev *dev;
     747                 :            :         struct cpt *cpt;
     748                 :            :         int rc;
     749                 :            : 
     750   [ #  #  #  # ]:          0 :         if (roc_cpt == NULL || roc_cpt->pci_dev == NULL)
     751                 :            :                 return -EINVAL;
     752                 :            : 
     753                 :            :         PLT_STATIC_ASSERT(sizeof(struct cpt) <= ROC_CPT_MEM_SZ);
     754                 :            : 
     755                 :            :         cpt = roc_cpt_to_cpt_priv(roc_cpt);
     756                 :            :         memset(cpt, 0, sizeof(*cpt));
     757                 :            :         pci_dev = roc_cpt->pci_dev;
     758                 :          0 :         dev = &cpt->dev;
     759                 :            : 
     760                 :            :         /* Initialize device  */
     761                 :          0 :         rc = dev_init(dev, pci_dev);
     762         [ #  # ]:          0 :         if (rc) {
     763                 :          0 :                 plt_err("Failed to init roc device");
     764                 :          0 :                 return rc;
     765                 :            :         }
     766                 :            : 
     767                 :          0 :         cpt->pci_dev = pci_dev;
     768                 :          0 :         roc_cpt->lmt_base = dev->lmt_base;
     769                 :            : 
     770                 :          0 :         rc = cpt_hardware_caps_get(dev, roc_cpt);
     771         [ #  # ]:          0 :         if (rc) {
     772                 :          0 :                 plt_err("Could not determine hardware capabilities");
     773                 :          0 :                 goto fail;
     774                 :            :         }
     775                 :            : 
     776                 :          0 :         rc = cpt_available_lfs_get(&cpt->dev, &nb_lf_avail);
     777         [ #  # ]:          0 :         if (rc) {
     778                 :          0 :                 plt_err("Could not get available lfs");
     779                 :          0 :                 goto fail;
     780                 :            :         }
     781                 :            : 
     782                 :            :         /* Reserve 1 CPT LF for inline inbound */
     783                 :          0 :         nb_lf_avail = PLT_MIN(nb_lf_avail, (uint16_t)(ROC_CPT_MAX_LFS - 1));
     784                 :            : 
     785                 :          0 :         roc_cpt->nb_lf_avail = nb_lf_avail;
     786                 :            : 
     787                 :          0 :         dev->roc_cpt = roc_cpt;
     788                 :            : 
     789                 :            :         /* Set it to idev if not already present */
     790         [ #  # ]:          0 :         if (!roc_idev_cpt_get())
     791                 :          0 :                 roc_idev_cpt_set(roc_cpt);
     792                 :            : 
     793                 :            :         return 0;
     794                 :            : 
     795                 :          0 : fail:
     796                 :          0 :         dev_fini(dev, pci_dev);
     797                 :          0 :         return rc;
     798                 :            : }
     799                 :            : 
     800                 :            : int
     801                 :          0 : roc_cpt_lf_ctx_flush(struct roc_cpt_lf *lf, void *cptr, bool inval)
     802                 :            : {
     803                 :            :         union cpt_lf_ctx_flush reg;
     804                 :            :         union cpt_lf_ctx_err err;
     805                 :            : 
     806         [ #  # ]:          0 :         if (lf == NULL) {
     807                 :          0 :                 plt_err("Could not trigger CTX flush");
     808                 :          0 :                 return -ENOTSUP;
     809                 :            :         }
     810                 :            : 
     811                 :          0 :         reg.u = 0;
     812                 :          0 :         reg.s.inval = inval;
     813                 :          0 :         reg.s.cptr = (uintptr_t)cptr >> 7;
     814                 :            : 
     815         [ #  # ]:          0 :         plt_write64(reg.u, lf->rbase + CPT_LF_CTX_FLUSH);
     816                 :            : 
     817                 :            :         plt_atomic_thread_fence(__ATOMIC_ACQ_REL);
     818                 :            : 
     819                 :            :         /* Read a CSR to ensure that the FLUSH operation is complete */
     820         [ #  # ]:          0 :         err.u = plt_read64(lf->rbase + CPT_LF_CTX_ERR);
     821                 :            : 
     822   [ #  #  #  # ]:          0 :         if (err.s.busy_sw_flush && inval) {
     823                 :          0 :                 plt_err("CTX entry could not be invalidated due to active usage.");
     824                 :          0 :                 return -EAGAIN;
     825                 :            :         }
     826                 :            : 
     827         [ #  # ]:          0 :         if (err.s.flush_st_flt) {
     828                 :          0 :                 plt_err("CTX flush could not complete due to store fault");
     829                 :          0 :                 return -EFAULT;
     830                 :            :         }
     831                 :            : 
     832                 :            :         return 0;
     833                 :            : }
     834                 :            : 
     835                 :            : int
     836                 :          0 : roc_cpt_lf_ctx_reload(struct roc_cpt_lf *lf, void *cptr)
     837                 :            : {
     838                 :            :         union cpt_lf_ctx_reload reg;
     839                 :            : 
     840         [ #  # ]:          0 :         if (lf == NULL) {
     841                 :          0 :                 plt_err("Could not trigger CTX reload");
     842                 :          0 :                 return -ENOTSUP;
     843                 :            :         }
     844                 :            : 
     845                 :          0 :         reg.u = 0;
     846                 :          0 :         reg.s.cptr = (uintptr_t)cptr >> 7;
     847                 :            : 
     848                 :          0 :         plt_write64(reg.u, lf->rbase + CPT_LF_CTX_RELOAD);
     849                 :            : 
     850                 :          0 :         return 0;
     851                 :            : }
     852                 :            : 
     853                 :            : static int
     854                 :          0 : cpt_lf_reset(struct roc_cpt_lf *lf)
     855                 :            : {
     856                 :            :         struct cpt_lf_rst_req *req;
     857                 :          0 :         struct dev *dev = lf->dev;
     858                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
     859                 :            :         int rc;
     860                 :            : 
     861                 :          0 :         req = mbox_alloc_msg_cpt_lf_reset(mbox);
     862         [ #  # ]:          0 :         if (req == NULL) {
     863                 :            :                 rc = -EIO;
     864                 :          0 :                 goto exit;
     865                 :            :         }
     866                 :            : 
     867                 :          0 :         req->slot = lf->lf_id;
     868                 :            : 
     869                 :          0 :         rc = mbox_process(mbox);
     870                 :          0 : exit:
     871                 :            :         mbox_put(mbox);
     872                 :          0 :         return rc;
     873                 :            : }
     874                 :            : 
     875                 :            : static void
     876                 :          0 : cpt_9k_lf_rst_lmtst(struct roc_cpt_lf *lf, uint8_t egrp)
     877                 :            : {
     878                 :            :         struct cpt_inst_s inst;
     879                 :            :         uint64_t lmt_status;
     880                 :            : 
     881                 :            :         memset(&inst, 0, sizeof(struct cpt_inst_s));
     882                 :          0 :         inst.w7.s.egrp = egrp;
     883                 :            : 
     884                 :          0 :         plt_io_wmb();
     885                 :            : 
     886                 :            :         do {
     887                 :            :                 /* Copy CPT command to LMTLINE */
     888                 :            :                 roc_lmt_mov64((void *)lf->lmt_base, &inst);
     889                 :            :                 lmt_status = roc_lmt_submit_ldeor(lf->io_addr);
     890                 :            :         } while (lmt_status == 0);
     891                 :            : }
     892                 :            : 
     893                 :            : static void
     894                 :            : cpt_10k_lf_rst_lmtst(struct roc_cpt_lf *lf, uint8_t egrp)
     895                 :            : {
     896                 :            :         uint64_t lmt_base, lmt_arg, io_addr;
     897                 :            :         struct cpt_inst_s *inst;
     898                 :            :         uint16_t lmt_id;
     899                 :            : 
     900                 :          0 :         lmt_base = lf->lmt_base;
     901                 :            :         io_addr = lf->io_addr;
     902                 :            : 
     903                 :            :         io_addr |= ROC_CN10K_CPT_INST_DW_M1 << 4;
     904                 :            :         ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
     905                 :            : 
     906                 :          0 :         inst = (struct cpt_inst_s *)lmt_base;
     907                 :            :         memset(inst, 0, sizeof(struct cpt_inst_s));
     908                 :            :         inst->w7.s.egrp = egrp;
     909                 :            :         lmt_arg = ROC_CN10K_CPT_LMT_ARG | (uint64_t)lmt_id;
     910                 :            :         roc_lmt_submit_steorl(lmt_arg, io_addr);
     911                 :            : }
     912                 :            : 
     913                 :            : static void
     914                 :          0 : roc_cpt_iq_reset(struct roc_cpt_lf *lf)
     915                 :            : {
     916                 :            :         union cpt_lf_inprog lf_inprog = {.u = 0x0};
     917                 :            :         union cpt_lf_ctl lf_ctl = {.u = 0x0};
     918                 :            : 
     919         [ #  # ]:          0 :         lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
     920   [ #  #  #  # ]:          0 :         if (((lf_inprog.s.gwb_cnt & 0x1) == 0x1) &&
     921                 :            :             (lf_inprog.s.grb_partial == 0x0)) {
     922                 :          0 :                 lf_inprog.s.grp_drp = 1;
     923         [ #  # ]:          0 :                 plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG);
     924                 :            : 
     925         [ #  # ]:          0 :                 lf_ctl.u = plt_read64(lf->rbase + CPT_LF_CTL);
     926                 :          0 :                 lf_ctl.s.ena = 1;
     927         [ #  # ]:          0 :                 plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL);
     928                 :            : 
     929         [ #  # ]:          0 :                 if (roc_model_is_cn10k())
     930                 :            :                         cpt_10k_lf_rst_lmtst(lf, ROC_CPT_DFLT_ENG_GRP_SE);
     931                 :            :                 else
     932                 :          0 :                         cpt_9k_lf_rst_lmtst(lf, ROC_CPT_DFLT_ENG_GRP_SE);
     933                 :            : 
     934                 :          0 :                 plt_read64(lf->rbase + CPT_LF_INPROG);
     935                 :          0 :                 plt_delay_us(2);
     936                 :            :         }
     937         [ #  # ]:          0 :         if (cpt_lf_reset(lf))
     938                 :          0 :                 plt_err("Invalid CPT LF to reset");
     939                 :          0 : }
     940                 :            : 
     941                 :            : void
     942                 :          0 : cpt_lf_fini(struct roc_cpt_lf *lf)
     943                 :            : {
     944                 :            :         /* Unregister IRQ's */
     945                 :            :         cpt_lf_unregister_irqs(lf);
     946                 :            : 
     947                 :            :         /* Disable IQ */
     948                 :          0 :         roc_cpt_iq_disable(lf);
     949                 :          0 :         roc_cpt_iq_reset(lf);
     950                 :            : 
     951                 :            :         /* Free memory */
     952                 :          0 :         plt_free(lf->iq_vaddr);
     953                 :          0 :         lf->iq_vaddr = NULL;
     954                 :          0 : }
     955                 :            : 
     956                 :            : void
     957                 :          0 : roc_cpt_lf_reset(struct roc_cpt_lf *lf)
     958                 :            : {
     959         [ #  # ]:          0 :         if (lf == NULL)
     960                 :            :                 return;
     961                 :            : 
     962                 :            :         cpt_lf_misc_intr_enb_dis(lf, false);
     963                 :            :         cpt_lf_done_intr_enb_dis(lf, false);
     964                 :          0 :         roc_cpt_iq_disable(lf);
     965                 :          0 :         roc_cpt_iq_reset(lf);
     966                 :            :         cpt_lf_misc_intr_enb_dis(lf, true);
     967                 :            :         cpt_lf_done_intr_enb_dis(lf, true);
     968                 :            : }
     969                 :            : 
     970                 :            : void
     971                 :          0 : roc_cpt_lf_fini(struct roc_cpt_lf *lf)
     972                 :            : {
     973         [ #  # ]:          0 :         if (lf == NULL)
     974                 :            :                 return;
     975                 :          0 :         lf->roc_cpt->lf[lf->lf_id] = NULL;
     976                 :          0 :         cpt_lf_fini(lf);
     977                 :            : }
     978                 :            : 
     979                 :            : int
     980                 :          0 : roc_cpt_dev_fini(struct roc_cpt *roc_cpt)
     981                 :            : {
     982                 :            :         struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
     983                 :            : 
     984                 :            :         if (cpt == NULL)
     985                 :            :                 return -EINVAL;
     986                 :            : 
     987                 :            :         /* Remove idev references */
     988         [ #  # ]:          0 :         if (roc_idev_cpt_get() == roc_cpt)
     989                 :          0 :                 roc_idev_cpt_set(NULL);
     990                 :            : 
     991                 :          0 :         roc_cpt->nb_lf_avail = 0;
     992                 :            : 
     993                 :          0 :         roc_cpt->lmt_base = 0;
     994                 :            : 
     995                 :          0 :         return dev_fini(&cpt->dev, cpt->pci_dev);
     996                 :            : }
     997                 :            : 
     998                 :            : void
     999                 :          0 : roc_cpt_dev_clear(struct roc_cpt *roc_cpt)
    1000                 :            : {
    1001                 :            :         struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
    1002                 :            :         int i;
    1003                 :            : 
    1004                 :            :         if (cpt == NULL)
    1005                 :            :                 return;
    1006                 :            : 
    1007         [ #  # ]:          0 :         if (roc_cpt->nb_lf == 0)
    1008                 :            :                 return;
    1009                 :            : 
    1010         [ #  # ]:          0 :         for (i = 0; i < roc_cpt->nb_lf; i++)
    1011                 :          0 :                 cpt->lf_msix_off[i] = 0;
    1012                 :            : 
    1013                 :          0 :         roc_cpt->nb_lf = 0;
    1014                 :            : 
    1015                 :          0 :         cpt_lfs_free(&cpt->dev);
    1016                 :            : 
    1017                 :          0 :         cpt_lfs_detach(&cpt->dev);
    1018                 :            : }
    1019                 :            : 
    1020                 :            : int
    1021                 :          0 : roc_cpt_eng_grp_add(struct roc_cpt *roc_cpt, enum cpt_eng_type eng_type)
    1022                 :            : {
    1023                 :            :         struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
    1024                 :            :         struct dev *dev = &cpt->dev;
    1025                 :            :         struct cpt_eng_grp_req *req;
    1026                 :            :         struct cpt_eng_grp_rsp *rsp;
    1027                 :          0 :         struct mbox *mbox = mbox_get(dev->mbox);
    1028                 :            :         int ret;
    1029                 :            : 
    1030                 :          0 :         req = mbox_alloc_msg_cpt_eng_grp_get(mbox);
    1031         [ #  # ]:          0 :         if (req == NULL) {
    1032                 :            :                 ret = -EIO;
    1033                 :          0 :                 goto exit;
    1034                 :            :         }
    1035                 :            : 
    1036         [ #  # ]:          0 :         switch (eng_type) {
    1037                 :            :         case CPT_ENG_TYPE_AE:
    1038                 :            :         case CPT_ENG_TYPE_SE:
    1039                 :            :         case CPT_ENG_TYPE_IE:
    1040                 :            :                 break;
    1041                 :          0 :         default:
    1042                 :            :                 ret = -EINVAL;
    1043                 :          0 :                 goto exit;
    1044                 :            :         }
    1045                 :            : 
    1046                 :          0 :         req->eng_type = eng_type;
    1047                 :          0 :         ret = mbox_process_msg(dev->mbox, (void *)&rsp);
    1048         [ #  # ]:          0 :         if (ret) {
    1049                 :            :                 ret = -EIO;
    1050                 :          0 :                 goto exit;
    1051                 :            :         }
    1052                 :            : 
    1053         [ #  # ]:          0 :         if (rsp->eng_grp_num > 8) {
    1054                 :          0 :                 plt_err("Invalid CPT engine group");
    1055                 :            :                 ret = -ENOTSUP;
    1056                 :          0 :                 goto exit;
    1057                 :            :         }
    1058                 :            : 
    1059                 :          0 :         roc_cpt->eng_grp[eng_type] = rsp->eng_grp_num;
    1060                 :            : 
    1061                 :          0 :         ret = rsp->eng_grp_num;
    1062                 :          0 : exit:
    1063                 :            :         mbox_put(mbox);
    1064                 :          0 :         return ret;
    1065                 :            : }
    1066                 :            : 
    1067                 :            : void
    1068                 :          0 : roc_cpt_iq_disable(struct roc_cpt_lf *lf)
    1069                 :            : {
    1070                 :          0 :         volatile union cpt_lf_q_grp_ptr grp_ptr = {.u = 0x0};
    1071                 :          0 :         volatile union cpt_lf_inprog lf_inprog = {.u = 0x0};
    1072                 :            :         union cpt_lf_ctl lf_ctl = {.u = 0x0};
    1073                 :            :         int timeout = 20;
    1074                 :            :         int cnt;
    1075                 :            : 
    1076                 :            :         /* Disable instructions enqueuing */
    1077                 :          0 :         plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL);
    1078                 :            : 
    1079                 :            :         /* Wait for instruction queue to become empty */
    1080                 :            :         do {
    1081         [ #  # ]:          0 :                 lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
    1082         [ #  # ]:          0 :                 if (!lf_inprog.s.inflight)
    1083                 :            :                         break;
    1084                 :            : 
    1085                 :            :                 plt_delay_ms(20);
    1086         [ #  # ]:          0 :                 if (timeout-- < 0) {
    1087                 :          0 :                         plt_err("CPT LF %d is still busy", lf->lf_id);
    1088                 :          0 :                         break;
    1089                 :            :                 }
    1090                 :            : 
    1091                 :            :         } while (1);
    1092                 :            : 
    1093                 :            :         /* Disable executions in the LF's queue.
    1094                 :            :          * The queue should be empty at this point
    1095                 :            :          */
    1096                 :          0 :         lf_inprog.s.eena = 0x0;
    1097                 :          0 :         plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG);
    1098                 :            : 
    1099                 :            :         /* Wait for instruction queue to become empty */
    1100                 :            :         cnt = 0;
    1101                 :            :         do {
    1102         [ #  # ]:          0 :                 lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
    1103         [ #  # ]:          0 :                 if (lf_inprog.s.grb_partial)
    1104                 :            :                         cnt = 0;
    1105                 :            :                 else
    1106                 :          0 :                         cnt++;
    1107         [ #  # ]:          0 :                 grp_ptr.u = plt_read64(lf->rbase + CPT_LF_Q_GRP_PTR);
    1108   [ #  #  #  # ]:          0 :         } while ((cnt < 10) && (grp_ptr.s.nq_ptr != grp_ptr.s.dq_ptr));
    1109                 :            : 
    1110                 :            :         cnt = 0;
    1111                 :            :         do {
    1112                 :          0 :                 lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
    1113   [ #  #  #  # ]:          0 :                 if ((lf_inprog.s.inflight == 0) && (lf_inprog.s.gwb_cnt < 40) &&
    1114   [ #  #  #  # ]:          0 :                     ((lf_inprog.s.grb_cnt == 0) || (lf_inprog.s.grb_cnt == 40)))
    1115                 :          0 :                         cnt++;
    1116                 :            :                 else
    1117                 :            :                         cnt = 0;
    1118         [ #  # ]:          0 :         } while (cnt < 10);
    1119                 :          0 : }
    1120                 :            : 
    1121                 :            : void
    1122                 :          0 : roc_cpt_iq_enable(struct roc_cpt_lf *lf)
    1123                 :            : {
    1124                 :            :         union cpt_lf_inprog lf_inprog;
    1125                 :            :         union cpt_lf_ctl lf_ctl;
    1126                 :            : 
    1127                 :            :         /* Disable command queue */
    1128                 :          0 :         roc_cpt_iq_disable(lf);
    1129                 :            : 
    1130                 :            :         /* Enable instruction queue enqueuing */
    1131         [ #  # ]:          0 :         lf_ctl.u = plt_read64(lf->rbase + CPT_LF_CTL);
    1132                 :          0 :         lf_ctl.s.ena = 1;
    1133                 :          0 :         lf_ctl.s.fc_ena = 1;
    1134                 :          0 :         lf_ctl.s.fc_up_crossing = 0;
    1135                 :          0 :         lf_ctl.s.fc_hyst_bits = plt_log2_u32(CPT_LF_FC_MIN_THRESHOLD);
    1136         [ #  # ]:          0 :         plt_write64(lf_ctl.u, lf->rbase + CPT_LF_CTL);
    1137                 :            : 
    1138                 :            :         /* Enable command queue execution */
    1139                 :          0 :         lf_inprog.u = plt_read64(lf->rbase + CPT_LF_INPROG);
    1140                 :          0 :         lf_inprog.s.eena = 1;
    1141         [ #  # ]:          0 :         plt_write64(lf_inprog.u, lf->rbase + CPT_LF_INPROG);
    1142                 :            : 
    1143         [ #  # ]:          0 :         if (roc_errata_cpt_has_ctx_fetch_issue()) {
    1144                 :            :                 /* Enable flush on FLR */
    1145                 :          0 :                 plt_write64(1, lf->rbase + CPT_LF_CTX_CTL);
    1146                 :            :         }
    1147                 :            : 
    1148                 :          0 :         cpt_lf_dump(lf);
    1149                 :          0 : }
    1150                 :            : 
    1151                 :            : int
    1152                 :          0 : roc_cpt_lmtline_init(struct roc_cpt *roc_cpt, struct roc_cpt_lmtline *lmtline, int lf_id,
    1153                 :            :                      bool is_dual)
    1154                 :            : {
    1155                 :            :         struct roc_cpt_lf *lf;
    1156                 :            : 
    1157                 :          0 :         lf = roc_cpt->lf[lf_id];
    1158         [ #  # ]:          0 :         if (lf == NULL)
    1159                 :            :                 return -ENOTSUP;
    1160                 :            : 
    1161                 :          0 :         lmtline->io_addr = lf->io_addr;
    1162         [ #  # ]:          0 :         lmtline->fc_thresh = lf->nb_desc - CPT_LF_FC_MIN_THRESHOLD;
    1163                 :            : 
    1164         [ #  # ]:          0 :         if (roc_model_is_cn10k()) {
    1165         [ #  # ]:          0 :                 if (is_dual) {
    1166                 :          0 :                         lmtline->io_addr |= ROC_CN10K_TWO_CPT_INST_DW_M1 << 4;
    1167                 :          0 :                         lmtline->fc_thresh = lf->nb_desc -  2 * CPT_LF_FC_MIN_THRESHOLD;
    1168                 :            :                 } else {
    1169                 :          0 :                         lmtline->io_addr |= ROC_CN10K_CPT_INST_DW_M1 << 4;
    1170                 :            :                 }
    1171                 :            :         }
    1172                 :            : 
    1173                 :          0 :         lmtline->fc_addr = lf->fc_addr;
    1174                 :          0 :         lmtline->lmt_base = lf->lmt_base;
    1175                 :            : 
    1176                 :          0 :         return 0;
    1177                 :            : }
    1178                 :            : 
    1179                 :            : int
    1180                 :          0 : roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
    1181                 :            :                   uint16_t sa_len)
    1182                 :            : {
    1183         [ #  # ]:          0 :         uintptr_t lmt_base = lf->lmt_base;
    1184                 :            :         union cpt_res_s res, *hw_res;
    1185                 :            :         uint64_t lmt_arg, io_addr;
    1186                 :            :         struct cpt_inst_s *inst;
    1187                 :            :         uint16_t lmt_id;
    1188                 :            :         uint64_t *dptr;
    1189                 :            :         int i;
    1190                 :            : 
    1191         [ #  # ]:          0 :         if (!plt_is_aligned(sa_cptr, 128)) {
    1192                 :          0 :                 plt_err("Context pointer should be 128B aligned");
    1193                 :          0 :                 return -EINVAL;
    1194                 :            :         }
    1195                 :            : 
    1196                 :            :         /* Use this lcore's LMT line as no one else is using it */
    1197                 :            :         ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
    1198                 :          0 :         inst = (struct cpt_inst_s *)lmt_base;
    1199                 :            : 
    1200                 :            :         memset(inst, 0, sizeof(struct cpt_inst_s));
    1201                 :            : 
    1202                 :          0 :         hw_res = plt_zmalloc(sizeof(*hw_res), ROC_CPT_RES_ALIGN);
    1203         [ #  # ]:          0 :         if (hw_res == NULL) {
    1204                 :          0 :                 plt_err("Couldn't allocate memory for result address");
    1205                 :          0 :                 return -ENOMEM;
    1206                 :            :         }
    1207                 :            : 
    1208                 :          0 :         dptr = plt_zmalloc(sa_len, 8);
    1209         [ #  # ]:          0 :         if (dptr == NULL) {
    1210                 :          0 :                 plt_err("Couldn't allocate memory for SA dptr");
    1211                 :          0 :                 plt_free(hw_res);
    1212                 :          0 :                 return -ENOMEM;
    1213                 :            :         }
    1214                 :            : 
    1215         [ #  # ]:          0 :         for (i = 0; i < (sa_len / 8); i++)
    1216         [ #  # ]:          0 :                 dptr[i] = plt_cpu_to_be_64(((uint64_t *)sa_dptr)[i]);
    1217                 :            : 
    1218                 :            :         /* Fill CPT_INST_S for WRITE_SA microcode op */
    1219                 :          0 :         hw_res->cn10k.compcode = CPT_COMP_NOT_DONE;
    1220                 :          0 :         inst->res_addr = (uint64_t)hw_res;
    1221                 :          0 :         inst->dptr = (uint64_t)dptr;
    1222                 :          0 :         inst->w4.s.param2 = sa_len >> 3;
    1223                 :          0 :         inst->w4.s.dlen = sa_len;
    1224                 :          0 :         inst->w4.s.opcode_major = ROC_IE_OT_MAJOR_OP_WRITE_SA;
    1225                 :          0 :         inst->w4.s.opcode_minor = ROC_IE_OT_MINOR_OP_WRITE_SA;
    1226                 :          0 :         inst->w7.s.cptr = (uint64_t)sa_cptr;
    1227                 :          0 :         inst->w7.s.ctx_val = 1;
    1228                 :          0 :         inst->w7.s.egrp = ROC_CPT_DFLT_ENG_GRP_SE_IE;
    1229                 :            : 
    1230                 :            :         lmt_arg = ROC_CN10K_CPT_LMT_ARG | (uint64_t)lmt_id;
    1231                 :            :         io_addr = lf->io_addr | ROC_CN10K_CPT_INST_DW_M1 << 4;
    1232                 :            : 
    1233                 :            :         roc_lmt_submit_steorl(lmt_arg, io_addr);
    1234                 :          0 :         plt_io_wmb();
    1235                 :            : 
    1236                 :            :         /* Use 1 min timeout for the poll */
    1237                 :          0 :         const uint64_t timeout = plt_tsc_cycles() + 60 * plt_tsc_hz();
    1238                 :            : 
    1239                 :            :         /* Wait until CPT instruction completes */
    1240                 :            :         do {
    1241                 :          0 :                 res.u64[0] = __atomic_load_n(&hw_res->u64[0], __ATOMIC_RELAXED);
    1242         [ #  # ]:          0 :                 if (unlikely(plt_tsc_cycles() > timeout))
    1243                 :            :                         break;
    1244         [ #  # ]:          0 :         } while (res.cn10k.compcode == CPT_COMP_NOT_DONE);
    1245                 :            : 
    1246                 :          0 :         plt_free(dptr);
    1247                 :          0 :         plt_free(hw_res);
    1248                 :            : 
    1249         [ #  # ]:          0 :         if (res.cn10k.compcode != CPT_COMP_GOOD || res.cn10k.uc_compcode) {
    1250                 :          0 :                 plt_err("Write SA operation timed out");
    1251                 :          0 :                 return -ETIMEDOUT;
    1252                 :            :         }
    1253                 :            : 
    1254                 :            :         return 0;
    1255                 :            : }
    1256                 :            : 
    1257                 :            : void
    1258                 :          0 : roc_cpt_int_misc_cb_register(roc_cpt_int_misc_cb_t cb, void *args)
    1259                 :            : {
    1260         [ #  # ]:          0 :         if (int_cb.cb != NULL)
    1261                 :            :                 return;
    1262                 :            : 
    1263                 :          0 :         int_cb.cb = cb;
    1264                 :          0 :         int_cb.cb_args = args;
    1265                 :            : }
    1266                 :            : 
    1267                 :            : int
    1268                 :          0 : roc_cpt_int_misc_cb_unregister(roc_cpt_int_misc_cb_t cb, void *args)
    1269                 :            : {
    1270         [ #  # ]:          0 :         if (int_cb.cb == NULL)
    1271                 :            :                 return 0;
    1272   [ #  #  #  # ]:          0 :         if (int_cb.cb != cb || int_cb.cb_args != args)
    1273                 :            :                 return -EINVAL;
    1274                 :            : 
    1275                 :          0 :         int_cb.cb = NULL;
    1276                 :          0 :         int_cb.cb_args = NULL;
    1277                 :          0 :         return 0;
    1278                 :            : }

Generated by: LCOV version 1.14