dpdk/drivers/common/cnxk/roc_sso.c
<<
>>
Prefs
   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/* Private functions. */
   9static int
  10sso_lf_alloc(struct roc_sso *roc_sso, enum sso_lf_type lf_type, uint16_t nb_lf,
  11             void **rsp)
  12{
  13        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
  14        int rc = -ENOSPC;
  15
  16        switch (lf_type) {
  17        case SSO_LF_TYPE_HWS: {
  18                struct ssow_lf_alloc_req *req;
  19
  20                req = mbox_alloc_msg_ssow_lf_alloc(dev->mbox);
  21                if (req == NULL)
  22                        return rc;
  23                req->hws = nb_lf;
  24        } break;
  25        case SSO_LF_TYPE_HWGRP: {
  26                struct sso_lf_alloc_req *req;
  27
  28                req = mbox_alloc_msg_sso_lf_alloc(dev->mbox);
  29                if (req == NULL)
  30                        return rc;
  31                req->hwgrps = nb_lf;
  32        } break;
  33        default:
  34                break;
  35        }
  36
  37        rc = mbox_process_msg(dev->mbox, rsp);
  38        if (rc < 0)
  39                return rc;
  40
  41        return 0;
  42}
  43
  44static int
  45sso_lf_free(struct roc_sso *roc_sso, enum sso_lf_type lf_type, uint16_t nb_lf)
  46{
  47        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
  48        int rc = -ENOSPC;
  49
  50        switch (lf_type) {
  51        case SSO_LF_TYPE_HWS: {
  52                struct ssow_lf_free_req *req;
  53
  54                req = mbox_alloc_msg_ssow_lf_free(dev->mbox);
  55                if (req == NULL)
  56                        return rc;
  57                req->hws = nb_lf;
  58        } break;
  59        case SSO_LF_TYPE_HWGRP: {
  60                struct sso_lf_free_req *req;
  61
  62                req = mbox_alloc_msg_sso_lf_free(dev->mbox);
  63                if (req == NULL)
  64                        return rc;
  65                req->hwgrps = nb_lf;
  66        } break;
  67        default:
  68                break;
  69        }
  70
  71        rc = mbox_process(dev->mbox);
  72        if (rc < 0)
  73                return rc;
  74
  75        return 0;
  76}
  77
  78static int
  79sso_rsrc_attach(struct roc_sso *roc_sso, enum sso_lf_type lf_type,
  80                uint16_t nb_lf)
  81{
  82        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
  83        struct rsrc_attach_req *req;
  84        int rc = -ENOSPC;
  85
  86        req = mbox_alloc_msg_attach_resources(dev->mbox);
  87        if (req == NULL)
  88                return rc;
  89        switch (lf_type) {
  90        case SSO_LF_TYPE_HWS:
  91                req->ssow = nb_lf;
  92                break;
  93        case SSO_LF_TYPE_HWGRP:
  94                req->sso = nb_lf;
  95                break;
  96        default:
  97                return SSO_ERR_PARAM;
  98        }
  99
 100        req->modify = true;
 101        if (mbox_process(dev->mbox) < 0)
 102                return -EIO;
 103
 104        return 0;
 105}
 106
 107static int
 108sso_rsrc_detach(struct roc_sso *roc_sso, enum sso_lf_type lf_type)
 109{
 110        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 111        struct rsrc_detach_req *req;
 112        int rc = -ENOSPC;
 113
 114        req = mbox_alloc_msg_detach_resources(dev->mbox);
 115        if (req == NULL)
 116                return rc;
 117        switch (lf_type) {
 118        case SSO_LF_TYPE_HWS:
 119                req->ssow = true;
 120                break;
 121        case SSO_LF_TYPE_HWGRP:
 122                req->sso = true;
 123                break;
 124        default:
 125                return SSO_ERR_PARAM;
 126        }
 127
 128        req->partial = true;
 129        if (mbox_process(dev->mbox) < 0)
 130                return -EIO;
 131
 132        return 0;
 133}
 134
 135static int
 136sso_rsrc_get(struct roc_sso *roc_sso)
 137{
 138        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 139        struct free_rsrcs_rsp *rsrc_cnt;
 140        int rc;
 141
 142        mbox_alloc_msg_free_rsrc_cnt(dev->mbox);
 143        rc = mbox_process_msg(dev->mbox, (void **)&rsrc_cnt);
 144        if (rc < 0) {
 145                plt_err("Failed to get free resource count\n");
 146                return rc;
 147        }
 148
 149        roc_sso->max_hwgrp = rsrc_cnt->sso;
 150        roc_sso->max_hws = rsrc_cnt->ssow;
 151
 152        return 0;
 153}
 154
 155static void
 156sso_hws_link_modify(uint8_t hws, uintptr_t base, struct plt_bitmap *bmp,
 157                    uint16_t hwgrp[], uint16_t n, uint16_t enable)
 158{
 159        uint64_t reg;
 160        int i, j, k;
 161
 162        i = 0;
 163        while (n) {
 164                uint64_t mask[4] = {
 165                        0x8000,
 166                        0x8000,
 167                        0x8000,
 168                        0x8000,
 169                };
 170
 171                k = n % 4;
 172                k = k ? k : 4;
 173                for (j = 0; j < k; j++) {
 174                        mask[j] = hwgrp[i + j] | enable << 14;
 175                        enable ? plt_bitmap_set(bmp, hwgrp[i + j]) :
 176                                 plt_bitmap_clear(bmp, hwgrp[i + j]);
 177                        plt_sso_dbg("HWS %d Linked to HWGRP %d", hws,
 178                                    hwgrp[i + j]);
 179                }
 180
 181                n -= j;
 182                i += j;
 183                reg = mask[0] | mask[1] << 16 | mask[2] << 32 | mask[3] << 48;
 184                plt_write64(reg, base + SSOW_LF_GWS_GRPMSK_CHG);
 185        }
 186}
 187
 188static int
 189sso_msix_fill(struct roc_sso *roc_sso, uint16_t nb_hws, uint16_t nb_hwgrp)
 190{
 191        struct sso *sso = roc_sso_to_sso_priv(roc_sso);
 192        struct msix_offset_rsp *rsp;
 193        struct dev *dev = &sso->dev;
 194        int i, rc;
 195
 196        mbox_alloc_msg_msix_offset(dev->mbox);
 197        rc = mbox_process_msg(dev->mbox, (void **)&rsp);
 198        if (rc < 0)
 199                return rc;
 200
 201        for (i = 0; i < nb_hws; i++)
 202                sso->hws_msix_offset[i] = rsp->ssow_msixoff[i];
 203        for (i = 0; i < nb_hwgrp; i++)
 204                sso->hwgrp_msix_offset[i] = rsp->sso_msixoff[i];
 205
 206        return 0;
 207}
 208
 209/* Public Functions. */
 210uintptr_t
 211roc_sso_hws_base_get(struct roc_sso *roc_sso, uint8_t hws)
 212{
 213        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 214
 215        return dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12);
 216}
 217
 218uintptr_t
 219roc_sso_hwgrp_base_get(struct roc_sso *roc_sso, uint16_t hwgrp)
 220{
 221        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 222
 223        return dev->bar2 + (RVU_BLOCK_ADDR_SSO << 20 | hwgrp << 12);
 224}
 225
 226uint64_t
 227roc_sso_ns_to_gw(struct roc_sso *roc_sso, uint64_t ns)
 228{
 229        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 230        uint64_t current_us, current_ns, new_ns;
 231        uintptr_t base;
 232
 233        base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20);
 234        current_us = plt_read64(base + SSOW_LF_GWS_NW_TIM);
 235        /* From HRM, table 14-19:
 236         * The SSOW_LF_GWS_NW_TIM[NW_TIM] period is specified in n-1 notation.
 237         */
 238        current_us += 1;
 239
 240        /* From HRM, table 14-1:
 241         * SSOW_LF_GWS_NW_TIM[NW_TIM] specifies the minimum timeout. The SSO
 242         * hardware times out a GET_WORK request within 2 usec of the minimum
 243         * timeout specified by SSOW_LF_GWS_NW_TIM[NW_TIM].
 244         */
 245        current_us += 2;
 246        current_ns = current_us * 1E3;
 247        new_ns = (ns - PLT_MIN(ns, current_ns));
 248        new_ns = !new_ns ? 1 : new_ns;
 249        return (new_ns * plt_tsc_hz()) / 1E9;
 250}
 251
 252int
 253roc_sso_hws_link(struct roc_sso *roc_sso, uint8_t hws, uint16_t hwgrp[],
 254                 uint16_t nb_hwgrp)
 255{
 256        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 257        struct sso *sso;
 258        uintptr_t base;
 259
 260        sso = roc_sso_to_sso_priv(roc_sso);
 261        base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12);
 262        sso_hws_link_modify(hws, base, sso->link_map[hws], hwgrp, nb_hwgrp, 1);
 263
 264        return nb_hwgrp;
 265}
 266
 267int
 268roc_sso_hws_unlink(struct roc_sso *roc_sso, uint8_t hws, uint16_t hwgrp[],
 269                   uint16_t nb_hwgrp)
 270{
 271        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 272        struct sso *sso;
 273        uintptr_t base;
 274
 275        sso = roc_sso_to_sso_priv(roc_sso);
 276        base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12);
 277        sso_hws_link_modify(hws, base, sso->link_map[hws], hwgrp, nb_hwgrp, 0);
 278
 279        return nb_hwgrp;
 280}
 281
 282int
 283roc_sso_hws_stats_get(struct roc_sso *roc_sso, uint8_t hws,
 284                      struct roc_sso_hws_stats *stats)
 285{
 286        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 287        struct sso_hws_stats *req_rsp;
 288        int rc;
 289
 290        req_rsp = (struct sso_hws_stats *)mbox_alloc_msg_sso_hws_get_stats(
 291                dev->mbox);
 292        if (req_rsp == NULL) {
 293                rc = mbox_process(dev->mbox);
 294                if (rc < 0)
 295                        return rc;
 296                req_rsp = (struct sso_hws_stats *)
 297                        mbox_alloc_msg_sso_hws_get_stats(dev->mbox);
 298                if (req_rsp == NULL)
 299                        return -ENOSPC;
 300        }
 301        req_rsp->hws = hws;
 302        rc = mbox_process_msg(dev->mbox, (void **)&req_rsp);
 303        if (rc)
 304                return rc;
 305
 306        stats->arbitration = req_rsp->arbitration;
 307        return 0;
 308}
 309
 310int
 311roc_sso_hwgrp_stats_get(struct roc_sso *roc_sso, uint8_t hwgrp,
 312                        struct roc_sso_hwgrp_stats *stats)
 313{
 314        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 315        struct sso_grp_stats *req_rsp;
 316        int rc;
 317
 318        req_rsp = (struct sso_grp_stats *)mbox_alloc_msg_sso_grp_get_stats(
 319                dev->mbox);
 320        if (req_rsp == NULL) {
 321                rc = mbox_process(dev->mbox);
 322                if (rc < 0)
 323                        return rc;
 324                req_rsp = (struct sso_grp_stats *)
 325                        mbox_alloc_msg_sso_grp_get_stats(dev->mbox);
 326                if (req_rsp == NULL)
 327                        return -ENOSPC;
 328        }
 329        req_rsp->grp = hwgrp;
 330        rc = mbox_process_msg(dev->mbox, (void **)&req_rsp);
 331        if (rc)
 332                return rc;
 333
 334        stats->aw_status = req_rsp->aw_status;
 335        stats->dq_pc = req_rsp->dq_pc;
 336        stats->ds_pc = req_rsp->ds_pc;
 337        stats->ext_pc = req_rsp->ext_pc;
 338        stats->page_cnt = req_rsp->page_cnt;
 339        stats->ts_pc = req_rsp->ts_pc;
 340        stats->wa_pc = req_rsp->wa_pc;
 341        stats->ws_pc = req_rsp->ws_pc;
 342        return 0;
 343}
 344
 345int
 346roc_sso_hwgrp_hws_link_status(struct roc_sso *roc_sso, uint8_t hws,
 347                              uint16_t hwgrp)
 348{
 349        struct sso *sso;
 350
 351        sso = roc_sso_to_sso_priv(roc_sso);
 352        return plt_bitmap_get(sso->link_map[hws], hwgrp);
 353}
 354
 355int
 356roc_sso_hwgrp_qos_config(struct roc_sso *roc_sso, struct roc_sso_hwgrp_qos *qos,
 357                         uint8_t nb_qos, uint32_t nb_xaq)
 358{
 359        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 360        struct sso_grp_qos_cfg *req;
 361        int i, rc;
 362
 363        for (i = 0; i < nb_qos; i++) {
 364                uint8_t xaq_prcnt = qos[i].xaq_prcnt;
 365                uint8_t iaq_prcnt = qos[i].iaq_prcnt;
 366                uint8_t taq_prcnt = qos[i].taq_prcnt;
 367
 368                req = mbox_alloc_msg_sso_grp_qos_config(dev->mbox);
 369                if (req == NULL) {
 370                        rc = mbox_process(dev->mbox);
 371                        if (rc < 0)
 372                                return rc;
 373                        req = mbox_alloc_msg_sso_grp_qos_config(dev->mbox);
 374                        if (req == NULL)
 375                                return -ENOSPC;
 376                }
 377                req->grp = qos[i].hwgrp;
 378                req->xaq_limit = (nb_xaq * (xaq_prcnt ? xaq_prcnt : 100)) / 100;
 379                req->taq_thr = (SSO_HWGRP_IAQ_MAX_THR_MASK *
 380                                (iaq_prcnt ? iaq_prcnt : 100)) /
 381                               100;
 382                req->iaq_thr = (SSO_HWGRP_TAQ_MAX_THR_MASK *
 383                                (taq_prcnt ? taq_prcnt : 100)) /
 384                               100;
 385        }
 386
 387        return mbox_process(dev->mbox);
 388}
 389
 390int
 391roc_sso_hwgrp_alloc_xaq(struct roc_sso *roc_sso, uint32_t npa_aura_id,
 392                        uint16_t hwgrps)
 393{
 394        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 395        struct sso_hw_setconfig *req;
 396        int rc = -ENOSPC;
 397
 398        req = mbox_alloc_msg_sso_hw_setconfig(dev->mbox);
 399        if (req == NULL)
 400                return rc;
 401        req->npa_pf_func = idev_npa_pffunc_get();
 402        req->npa_aura_id = npa_aura_id;
 403        req->hwgrps = hwgrps;
 404
 405        return mbox_process(dev->mbox);
 406}
 407
 408int
 409roc_sso_hwgrp_release_xaq(struct roc_sso *roc_sso, uint16_t hwgrps)
 410{
 411        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 412        struct sso_hw_xaq_release *req;
 413
 414        req = mbox_alloc_msg_sso_hw_release_xaq_aura(dev->mbox);
 415        if (req == NULL)
 416                return -EINVAL;
 417        req->hwgrps = hwgrps;
 418
 419        return mbox_process(dev->mbox);
 420}
 421
 422int
 423roc_sso_hwgrp_set_priority(struct roc_sso *roc_sso, uint16_t hwgrp,
 424                           uint8_t weight, uint8_t affinity, uint8_t priority)
 425{
 426        struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
 427        struct sso_grp_priority *req;
 428        int rc = -ENOSPC;
 429
 430        req = mbox_alloc_msg_sso_grp_set_priority(dev->mbox);
 431        if (req == NULL)
 432                return rc;
 433        req->grp = hwgrp;
 434        req->weight = weight;
 435        req->affinity = affinity;
 436        req->priority = priority;
 437
 438        rc = mbox_process(dev->mbox);
 439        if (rc < 0)
 440                return rc;
 441        plt_sso_dbg("HWGRP %d weight %d affinity %d priority %d", hwgrp, weight,
 442                    affinity, priority);
 443
 444        return 0;
 445}
 446
 447int
 448roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws, uint16_t nb_hwgrp)
 449{
 450        struct sso *sso = roc_sso_to_sso_priv(roc_sso);
 451        struct sso_lf_alloc_rsp *rsp_hwgrp;
 452        int rc;
 453
 454        if (roc_sso->max_hwgrp < nb_hwgrp)
 455                return -ENOENT;
 456        if (roc_sso->max_hws < nb_hws)
 457                return -ENOENT;
 458
 459        rc = sso_rsrc_attach(roc_sso, SSO_LF_TYPE_HWS, nb_hws);
 460        if (rc < 0) {
 461                plt_err("Unable to attach SSO HWS LFs");
 462                return rc;
 463        }
 464
 465        rc = sso_rsrc_attach(roc_sso, SSO_LF_TYPE_HWGRP, nb_hwgrp);
 466        if (rc < 0) {
 467                plt_err("Unable to attach SSO HWGRP LFs");
 468                goto hwgrp_atch_fail;
 469        }
 470
 471        rc = sso_lf_alloc(roc_sso, SSO_LF_TYPE_HWS, nb_hws, NULL);
 472        if (rc < 0) {
 473                plt_err("Unable to alloc SSO HWS LFs");
 474                goto hws_alloc_fail;
 475        }
 476
 477        rc = sso_lf_alloc(roc_sso, SSO_LF_TYPE_HWGRP, nb_hwgrp,
 478                          (void **)&rsp_hwgrp);
 479        if (rc < 0) {
 480                plt_err("Unable to alloc SSO HWGRP Lfs");
 481                goto hwgrp_alloc_fail;
 482        }
 483
 484        roc_sso->xaq_buf_size = rsp_hwgrp->xaq_buf_size;
 485        roc_sso->xae_waes = rsp_hwgrp->xaq_wq_entries;
 486        roc_sso->iue = rsp_hwgrp->in_unit_entries;
 487
 488        rc = sso_msix_fill(roc_sso, nb_hws, nb_hwgrp);
 489        if (rc < 0) {
 490                plt_err("Unable to get MSIX offsets for SSO LFs");
 491                goto sso_msix_fail;
 492        }
 493
 494        rc = sso_register_irqs_priv(roc_sso, &sso->pci_dev->intr_handle, nb_hws,
 495                                    nb_hwgrp);
 496        if (rc < 0) {
 497                plt_err("Failed to register SSO LF IRQs");
 498                goto sso_msix_fail;
 499        }
 500
 501        roc_sso->nb_hwgrp = nb_hwgrp;
 502        roc_sso->nb_hws = nb_hws;
 503
 504        return 0;
 505sso_msix_fail:
 506        sso_lf_free(roc_sso, SSO_LF_TYPE_HWGRP, nb_hwgrp);
 507hwgrp_alloc_fail:
 508        sso_lf_free(roc_sso, SSO_LF_TYPE_HWS, nb_hws);
 509hws_alloc_fail:
 510        sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWGRP);
 511hwgrp_atch_fail:
 512        sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWS);
 513        return rc;
 514}
 515
 516void
 517roc_sso_rsrc_fini(struct roc_sso *roc_sso)
 518{
 519        struct sso *sso = roc_sso_to_sso_priv(roc_sso);
 520
 521        if (!roc_sso->nb_hws && !roc_sso->nb_hwgrp)
 522                return;
 523
 524        sso_unregister_irqs_priv(roc_sso, &sso->pci_dev->intr_handle,
 525                                 roc_sso->nb_hws, roc_sso->nb_hwgrp);
 526        sso_lf_free(roc_sso, SSO_LF_TYPE_HWS, roc_sso->nb_hws);
 527        sso_lf_free(roc_sso, SSO_LF_TYPE_HWGRP, roc_sso->nb_hwgrp);
 528
 529        sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWS);
 530        sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWGRP);
 531
 532        roc_sso->nb_hwgrp = 0;
 533        roc_sso->nb_hws = 0;
 534}
 535
 536int
 537roc_sso_dev_init(struct roc_sso *roc_sso)
 538{
 539        struct plt_pci_device *pci_dev;
 540        uint32_t link_map_sz;
 541        struct sso *sso;
 542        void *link_mem;
 543        int i, rc;
 544
 545        if (roc_sso == NULL || roc_sso->pci_dev == NULL)
 546                return SSO_ERR_PARAM;
 547
 548        PLT_STATIC_ASSERT(sizeof(struct sso) <= ROC_SSO_MEM_SZ);
 549        sso = roc_sso_to_sso_priv(roc_sso);
 550        memset(sso, 0, sizeof(*sso));
 551        pci_dev = roc_sso->pci_dev;
 552
 553        rc = dev_init(&sso->dev, pci_dev);
 554        if (rc < 0) {
 555                plt_err("Failed to init roc device");
 556                goto fail;
 557        }
 558
 559        rc = sso_rsrc_get(roc_sso);
 560        if (rc < 0) {
 561                plt_err("Failed to get SSO resources");
 562                goto rsrc_fail;
 563        }
 564        rc = -ENOMEM;
 565
 566        sso->link_map =
 567                plt_zmalloc(sizeof(struct plt_bitmap *) * roc_sso->max_hws, 0);
 568        if (sso->link_map == NULL) {
 569                plt_err("Failed to allocate memory for link_map array");
 570                goto rsrc_fail;
 571        }
 572
 573        link_map_sz = plt_bitmap_get_memory_footprint(roc_sso->max_hwgrp);
 574        sso->link_map_mem = plt_zmalloc(link_map_sz * roc_sso->max_hws, 0);
 575        if (sso->link_map_mem == NULL) {
 576                plt_err("Failed to get link_map memory");
 577                goto rsrc_fail;
 578        }
 579
 580        link_mem = sso->link_map_mem;
 581        for (i = 0; i < roc_sso->max_hws; i++) {
 582                sso->link_map[i] = plt_bitmap_init(roc_sso->max_hwgrp, link_mem,
 583                                                   link_map_sz);
 584                if (sso->link_map[i] == NULL) {
 585                        plt_err("Failed to allocate link map");
 586                        goto link_mem_free;
 587                }
 588                link_mem = PLT_PTR_ADD(link_mem, link_map_sz);
 589        }
 590        idev_sso_pffunc_set(sso->dev.pf_func);
 591        sso->pci_dev = pci_dev;
 592        sso->dev.drv_inited = true;
 593        roc_sso->lmt_base = sso->dev.lmt_base;
 594
 595        return 0;
 596link_mem_free:
 597        plt_free(sso->link_map_mem);
 598rsrc_fail:
 599        rc |= dev_fini(&sso->dev, pci_dev);
 600fail:
 601        return rc;
 602}
 603
 604int
 605roc_sso_dev_fini(struct roc_sso *roc_sso)
 606{
 607        struct sso *sso;
 608
 609        sso = roc_sso_to_sso_priv(roc_sso);
 610        sso->dev.drv_inited = false;
 611
 612        return dev_fini(&sso->dev, sso->pci_dev);
 613}
 614