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 : : bool 9 : 0 : roc_nix_is_lbk(struct roc_nix *roc_nix) 10 : : { 11 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 12 : : 13 : 0 : return nix->lbk_link; 14 : : } 15 : : 16 : : int 17 : 0 : roc_nix_get_base_chan(struct roc_nix *roc_nix) 18 : : { 19 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 20 : : 21 : 0 : return nix->rx_chan_base; 22 : : } 23 : : 24 : : uint8_t 25 : 0 : roc_nix_get_rx_chan_cnt(struct roc_nix *roc_nix) 26 : : { 27 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 28 : : 29 : 0 : return nix->rx_chan_cnt; 30 : : } 31 : : 32 : : uint16_t 33 : 0 : roc_nix_get_vwqe_interval(struct roc_nix *roc_nix) 34 : : { 35 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 36 : : 37 : 0 : return nix->vwqe_interval; 38 : : } 39 : : 40 : : bool 41 : 0 : roc_nix_is_sdp(struct roc_nix *roc_nix) 42 : : { 43 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 44 : : 45 : 0 : return nix->sdp_link; 46 : : } 47 : : 48 : : bool 49 : 0 : roc_nix_is_pf(struct roc_nix *roc_nix) 50 : : { 51 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 52 : : 53 : 0 : return !dev_is_vf(&nix->dev); 54 : : } 55 : : 56 : : int 57 : 0 : roc_nix_get_pf(struct roc_nix *roc_nix) 58 : : { 59 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 60 : : struct dev *dev = &nix->dev; 61 : : 62 : 0 : return dev_get_pf(dev->pf_func); 63 : : } 64 : : 65 : : int 66 : 0 : roc_nix_get_vf(struct roc_nix *roc_nix) 67 : : { 68 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 69 : : struct dev *dev = &nix->dev; 70 : : 71 : 0 : return dev_get_vf(dev->pf_func); 72 : : } 73 : : 74 : : bool 75 : 0 : roc_nix_is_vf_or_sdp(struct roc_nix *roc_nix) 76 : : { 77 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 78 : : 79 [ # # # # ]: 0 : return (dev_is_vf(&nix->dev) != 0) || roc_nix_is_sdp(roc_nix); 80 : : } 81 : : 82 : : uint16_t 83 : 0 : roc_nix_get_pf_func(struct roc_nix *roc_nix) 84 : : { 85 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 86 : : struct dev *dev = &nix->dev; 87 : : 88 : 0 : return dev->pf_func; 89 : : } 90 : : 91 : : int 92 : 0 : roc_nix_lf_inl_ipsec_cfg(struct roc_nix *roc_nix, struct roc_nix_ipsec_cfg *cfg, 93 : : bool enb) 94 : : { 95 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 96 : : struct nix_inline_ipsec_lf_cfg *lf_cfg; 97 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 98 : : int rc; 99 : : 100 : 0 : lf_cfg = mbox_alloc_msg_nix_inline_ipsec_lf_cfg(mbox); 101 [ # # ]: 0 : if (lf_cfg == NULL) { 102 : : rc = -ENOSPC; 103 : 0 : goto exit; 104 : : } 105 : : 106 [ # # ]: 0 : if (enb) { 107 : 0 : lf_cfg->enable = 1; 108 : 0 : lf_cfg->sa_base_addr = cfg->iova; 109 [ # # ]: 0 : lf_cfg->ipsec_cfg1.sa_idx_w = plt_log2_u32(cfg->max_sa); 110 : 0 : lf_cfg->ipsec_cfg0.lenm1_max = roc_nix_max_pkt_len(roc_nix) - 1; 111 : 0 : lf_cfg->ipsec_cfg1.sa_idx_max = cfg->max_sa - 1; 112 [ # # ]: 0 : lf_cfg->ipsec_cfg0.sa_pow2_size = plt_log2_u32(cfg->sa_size); 113 : 0 : lf_cfg->ipsec_cfg0.tag_const = cfg->tag_const; 114 : 0 : lf_cfg->ipsec_cfg0.tt = cfg->tt; 115 : : } else { 116 : 0 : lf_cfg->enable = 0; 117 : : } 118 : : 119 : 0 : rc = mbox_process(mbox); 120 : 0 : exit: 121 : : mbox_put(mbox); 122 : 0 : return rc; 123 : : } 124 : : 125 : : int 126 : 0 : roc_nix_cpt_ctx_cache_sync(struct roc_nix *roc_nix) 127 : : { 128 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 129 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 130 : : struct msg_req *req; 131 : : int rc; 132 : : 133 : 0 : req = mbox_alloc_msg_cpt_ctx_cache_sync(mbox); 134 [ # # ]: 0 : if (req == NULL) { 135 : : rc = -ENOSPC; 136 : 0 : goto exit; 137 : : } 138 : : 139 : 0 : rc = mbox_process(mbox); 140 : 0 : exit: 141 : : mbox_put(mbox); 142 : 0 : return rc; 143 : : } 144 : : 145 : : int 146 : 0 : roc_nix_max_pkt_len(struct roc_nix *roc_nix) 147 : : { 148 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 149 : : 150 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix)) { 151 [ # # ]: 0 : if (roc_errata_nix_sdp_send_has_mtu_size_16k()) 152 : : return NIX_SDP_16K_HW_FRS; 153 : 0 : return NIX_SDP_MAX_HW_FRS; 154 : : } 155 : : 156 [ # # ]: 0 : if (roc_model_is_cn9k()) 157 : : return NIX_CN9K_MAX_HW_FRS; 158 : : 159 [ # # ]: 0 : if (nix->lbk_link) 160 : 0 : return NIX_LBK_MAX_HW_FRS; 161 : : 162 : : return NIX_RPM_MAX_HW_FRS; 163 : : } 164 : : 165 : : int 166 : 0 : roc_nix_lf_alloc(struct roc_nix *roc_nix, uint32_t nb_rxq, uint32_t nb_txq, 167 : : uint64_t rx_cfg) 168 : : { 169 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 170 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 171 : : struct nix_lf_alloc_req *req; 172 : : struct nix_lf_alloc_rsp *rsp; 173 : : int rc = -ENOSPC; 174 : : 175 : 0 : req = mbox_alloc_msg_nix_lf_alloc(mbox); 176 [ # # ]: 0 : if (req == NULL) 177 : 0 : goto fail; 178 : 0 : req->rq_cnt = nb_rxq; 179 : 0 : req->sq_cnt = nb_txq; 180 [ # # ]: 0 : if (roc_nix->tx_compl_ena) 181 : 0 : req->cq_cnt = nb_rxq + nb_txq; 182 : : else 183 : 0 : req->cq_cnt = nb_rxq; 184 : : /* XQESZ can be W64 or W16 */ 185 : 0 : req->xqe_sz = NIX_XQESZ_W16; 186 : 0 : req->rss_sz = nix->reta_sz; 187 : 0 : req->rss_grps = ROC_NIX_RSS_GRPS; 188 : 0 : req->npa_func = idev_npa_pffunc_get(); 189 : 0 : req->sso_func = idev_sso_pffunc_get(); 190 : 0 : req->rx_cfg = rx_cfg; 191 [ # # # # : 0 : if (roc_nix_is_lbk(roc_nix) && roc_nix->enable_loop && # # ] 192 : : roc_model_is_cn98xx()) 193 : 0 : req->flags = NIX_LF_LBK_BLK_SEL; 194 : : 195 [ # # ]: 0 : if (!roc_nix->rss_tag_as_xor) 196 : 0 : req->flags |= NIX_LF_RSS_TAG_LSB_AS_ADDER; 197 : : 198 : : rc = mbox_process_msg(mbox, (void *)&rsp); 199 [ # # ]: 0 : if (rc) 200 : 0 : goto fail; 201 : : 202 : 0 : nix->rx_cfg = rx_cfg; 203 : 0 : nix->sqb_size = rsp->sqb_size; 204 : 0 : nix->tx_chan_base = rsp->tx_chan_base; 205 : 0 : nix->rx_chan_base = rsp->rx_chan_base; 206 [ # # # # ]: 0 : if (roc_nix_is_lbk(roc_nix) && roc_nix->enable_loop) 207 : 0 : nix->tx_chan_base = rsp->rx_chan_base; 208 : 0 : nix->rx_chan_cnt = rsp->rx_chan_cnt; 209 : 0 : nix->tx_chan_cnt = rsp->tx_chan_cnt; 210 : 0 : nix->lso_tsov4_idx = rsp->lso_tsov4_idx; 211 : 0 : nix->lso_tsov6_idx = rsp->lso_tsov6_idx; 212 : 0 : nix->lf_tx_stats = rsp->lf_tx_stats; 213 : 0 : nix->lf_rx_stats = rsp->lf_rx_stats; 214 : 0 : nix->cints = rsp->cints; 215 : 0 : roc_nix->cints = rsp->cints; 216 : 0 : nix->qints = rsp->qints; 217 : 0 : nix->ptp_en = rsp->hw_rx_tstamp_en; 218 : 0 : roc_nix->rx_ptp_ena = rsp->hw_rx_tstamp_en; 219 : 0 : nix->cgx_links = rsp->cgx_links; 220 : 0 : nix->lbk_links = rsp->lbk_links; 221 : 0 : nix->sdp_links = rsp->sdp_links; 222 : 0 : nix->tx_link = rsp->tx_link; 223 : 0 : nix->nb_rx_queues = nb_rxq; 224 : 0 : nix->nb_tx_queues = nb_txq; 225 : : 226 : 0 : nix->rqs = plt_zmalloc(sizeof(struct roc_nix_rq *) * nb_rxq, 0); 227 [ # # ]: 0 : if (!nix->rqs) { 228 : : rc = -ENOMEM; 229 : 0 : goto fail; 230 : : } 231 : : 232 : 0 : nix->sqs = plt_zmalloc(sizeof(struct roc_nix_sq *) * nb_txq, 0); 233 [ # # ]: 0 : if (!nix->sqs) { 234 : : rc = -ENOMEM; 235 : 0 : goto fail; 236 : : } 237 : : 238 : 0 : nix_tel_node_add(roc_nix); 239 : 0 : fail: 240 : : mbox_put(mbox); 241 : 0 : return rc; 242 : : } 243 : : 244 : : int 245 : 0 : roc_nix_lf_free(struct roc_nix *roc_nix) 246 : : { 247 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 248 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 249 : : struct nix_lf_free_req *req; 250 : : struct ndc_sync_op *ndc_req; 251 : : int rc = -ENOSPC; 252 : : 253 : 0 : plt_free(nix->rqs); 254 : 0 : plt_free(nix->sqs); 255 : 0 : nix->rqs = NULL; 256 : 0 : nix->sqs = NULL; 257 : : 258 : : /* Sync NDC-NIX for LF */ 259 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox); 260 [ # # ]: 0 : if (ndc_req == NULL) 261 : 0 : goto exit; 262 : 0 : ndc_req->nix_lf_tx_sync = 1; 263 : 0 : ndc_req->nix_lf_rx_sync = 1; 264 : 0 : rc = mbox_process(mbox); 265 [ # # ]: 0 : if (rc) 266 : 0 : plt_err("Error on NDC-NIX-[TX, RX] LF sync, rc %d", rc); 267 : : 268 : 0 : req = mbox_alloc_msg_nix_lf_free(mbox); 269 [ # # ]: 0 : if (req == NULL) { 270 : : rc = -ENOSPC; 271 : 0 : goto exit; 272 : : } 273 : : /* Let AF driver free all this nix lf's 274 : : * NPC entries allocated using NPC MBOX. 275 : : */ 276 : 0 : req->flags = 0; 277 : : 278 : 0 : rc = mbox_process(mbox); 279 : 0 : exit: 280 : : mbox_put(mbox); 281 : 0 : return rc; 282 : : } 283 : : 284 : : static inline int 285 : 0 : nix_lf_attach(struct dev *dev) 286 : : { 287 : 0 : struct mbox *mbox = mbox_get(dev->mbox); 288 : : struct rsrc_attach_req *req; 289 : : int rc = -ENOSPC; 290 : : 291 : : /* Attach NIX(lf) */ 292 : 0 : req = mbox_alloc_msg_attach_resources(mbox); 293 [ # # ]: 0 : if (req == NULL) 294 : 0 : goto exit; 295 : 0 : req->modify = true; 296 : 0 : req->nixlf = true; 297 : : 298 : 0 : rc = mbox_process(mbox); 299 : 0 : exit: 300 : : mbox_put(mbox); 301 : 0 : return rc; 302 : : } 303 : : 304 : : static inline int 305 : 0 : nix_lf_get_msix_offset(struct dev *dev, struct nix *nix) 306 : : { 307 : : struct msix_offset_rsp *msix_rsp; 308 : 0 : struct mbox *mbox = mbox_get(dev->mbox); 309 : : int rc; 310 : : 311 : : /* Get MSIX vector offsets */ 312 : 0 : mbox_alloc_msg_msix_offset(mbox); 313 : : rc = mbox_process_msg(mbox, (void *)&msix_rsp); 314 [ # # ]: 0 : if (rc == 0) 315 : 0 : nix->msixoff = msix_rsp->nix_msixoff; 316 : : 317 : : mbox_put(mbox); 318 : 0 : return rc; 319 : : } 320 : : 321 : : static inline int 322 : 0 : nix_lf_detach(struct nix *nix) 323 : : { 324 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 325 : : struct rsrc_detach_req *req; 326 : : int rc = -ENOSPC; 327 : : 328 : 0 : req = mbox_alloc_msg_detach_resources(mbox); 329 [ # # ]: 0 : if (req == NULL) 330 : 0 : goto exit; 331 : 0 : req->partial = true; 332 : 0 : req->nixlf = true; 333 : : 334 : 0 : rc = mbox_process(mbox); 335 : 0 : exit: 336 : : mbox_put(mbox); 337 : 0 : return rc; 338 : : } 339 : : 340 : : static int 341 : 0 : roc_nix_get_hw_info(struct roc_nix *roc_nix) 342 : : { 343 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 344 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 345 : : struct nix_hw_info *hw_info; 346 : : int rc; 347 : : 348 : 0 : mbox_alloc_msg_nix_get_hw_info(mbox); 349 : : rc = mbox_process_msg(mbox, (void *)&hw_info); 350 [ # # ]: 0 : if (rc == 0) { 351 : 0 : nix->vwqe_interval = hw_info->vwqe_delay; 352 [ # # ]: 0 : if (nix->lbk_link) 353 : 0 : roc_nix->dwrr_mtu = hw_info->lbk_dwrr_mtu; 354 [ # # ]: 0 : else if (nix->sdp_link) 355 : 0 : roc_nix->dwrr_mtu = hw_info->sdp_dwrr_mtu; 356 : : else 357 : 0 : roc_nix->dwrr_mtu = hw_info->rpm_dwrr_mtu; 358 : : } 359 : : 360 : : mbox_put(mbox); 361 : 0 : return rc; 362 : : } 363 : : 364 : : static void 365 : : sdp_lbk_id_update(struct plt_pci_device *pci_dev, struct nix *nix) 366 : : { 367 : 0 : nix->sdp_link = false; 368 : 0 : nix->lbk_link = false; 369 : : 370 : : /* Update SDP/LBK link based on PCI device id */ 371 [ # # # ]: 0 : switch (pci_dev->id.device_id) { 372 : 0 : case PCI_DEVID_CNXK_RVU_SDP_PF: 373 : : case PCI_DEVID_CNXK_RVU_SDP_VF: 374 : 0 : nix->sdp_link = true; 375 : 0 : break; 376 : 0 : case PCI_DEVID_CNXK_RVU_AF_VF: 377 : 0 : nix->lbk_link = true; 378 : 0 : break; 379 : : default: 380 : : break; 381 : : } 382 : : } 383 : : 384 : : uint64_t 385 : 0 : nix_get_blkaddr(struct dev *dev) 386 : : { 387 : : uint64_t reg; 388 : : 389 : : /* Reading the discovery register to know which NIX is the LF 390 : : * attached to. 391 : : */ 392 [ # # ]: 0 : reg = plt_read64(dev->bar2 + 393 : : RVU_PF_BLOCK_ADDRX_DISC(RVU_BLOCK_ADDR_NIX0)); 394 : : 395 [ # # ]: 0 : return reg & 0x1FFULL ? RVU_BLOCK_ADDR_NIX0 : RVU_BLOCK_ADDR_NIX1; 396 : : } 397 : : 398 : : int 399 : 0 : roc_nix_dev_init(struct roc_nix *roc_nix) 400 : : { 401 : : enum roc_nix_rss_reta_sz reta_sz; 402 : : struct plt_pci_device *pci_dev; 403 : : struct roc_nix_list *nix_list; 404 : : uint16_t max_sqb_count; 405 : : uint64_t blkaddr; 406 : : struct dev *dev; 407 : : struct nix *nix; 408 : : int rc; 409 : : 410 [ # # # # ]: 0 : if (roc_nix == NULL || roc_nix->pci_dev == NULL) 411 : : return NIX_ERR_PARAM; 412 : : 413 : 0 : reta_sz = roc_nix->reta_sz; 414 [ # # # # ]: 0 : if (reta_sz != 0 && reta_sz != 64 && reta_sz != 128 && reta_sz != 256) 415 : : return NIX_ERR_PARAM; 416 : : 417 [ # # ]: 0 : if (reta_sz == 0) 418 : : reta_sz = ROC_NIX_RSS_RETA_SZ_64; 419 : : 420 : 0 : max_sqb_count = roc_nix->max_sqb_count; 421 : 0 : max_sqb_count = PLT_MIN(max_sqb_count, NIX_MAX_SQB); 422 : 0 : max_sqb_count = PLT_MAX(max_sqb_count, NIX_MIN_SQB); 423 : 0 : roc_nix->max_sqb_count = max_sqb_count; 424 : : 425 : : PLT_STATIC_ASSERT(sizeof(struct nix) <= ROC_NIX_MEM_SZ); 426 : : nix = roc_nix_to_nix_priv(roc_nix); 427 : : pci_dev = roc_nix->pci_dev; 428 : 0 : dev = &nix->dev; 429 : : 430 : 0 : nix_list = roc_idev_nix_list_get(); 431 [ # # ]: 0 : if (nix_list == NULL) 432 : : return -EINVAL; 433 : : 434 : 0 : TAILQ_INSERT_TAIL(nix_list, roc_nix, next); 435 : : 436 [ # # ]: 0 : if (nix->dev.drv_inited) 437 : : return 0; 438 : : 439 [ # # ]: 0 : if (dev->mbox_active) 440 : 0 : goto skip_dev_init; 441 : : 442 : : memset(nix, 0, sizeof(*nix)); 443 : : 444 : : /* Since 0 is a valid BPID, use -1 to represent invalid value. */ 445 : 0 : memset(nix->bpid, -1, sizeof(nix->bpid)); 446 : : 447 : : /* Initialize device */ 448 : 0 : rc = dev_init(dev, pci_dev); 449 [ # # ]: 0 : if (rc) { 450 : 0 : plt_err("Failed to init roc device"); 451 : 0 : goto fail; 452 : : } 453 : : 454 : 0 : skip_dev_init: 455 : 0 : dev->roc_nix = roc_nix; 456 : : 457 : 0 : nix->lmt_base = dev->lmt_base; 458 : : /* Expose base LMT line address for 459 : : * "Per Core LMT line" mode. 460 : : */ 461 : 0 : roc_nix->lmt_base = dev->lmt_base; 462 : : 463 : : /* Attach NIX LF */ 464 : 0 : rc = nix_lf_attach(dev); 465 [ # # ]: 0 : if (rc) 466 : 0 : goto dev_fini; 467 : : 468 : 0 : blkaddr = nix_get_blkaddr(dev); 469 : 0 : nix->is_nix1 = (blkaddr == RVU_BLOCK_ADDR_NIX1); 470 : : 471 : : /* Calculating base address based on which NIX block LF 472 : : * is attached to. 473 : : */ 474 : 0 : nix->base = dev->bar2 + (blkaddr << 20); 475 : : 476 : : /* Get NIX MSIX offset */ 477 : 0 : rc = nix_lf_get_msix_offset(dev, nix); 478 [ # # ]: 0 : if (rc) 479 : 0 : goto lf_detach; 480 : : 481 : : /* Update nix context */ 482 : : sdp_lbk_id_update(pci_dev, nix); 483 : 0 : nix->pci_dev = pci_dev; 484 : 0 : nix->reta_sz = reta_sz; 485 : 0 : nix->mtu = ROC_NIX_DEFAULT_HW_FRS; 486 : 0 : nix->dmac_flt_idx = -1; 487 : : 488 : : /* Register error and ras interrupts */ 489 : 0 : rc = nix_register_irqs(nix); 490 [ # # ]: 0 : if (rc) 491 : 0 : goto lf_detach; 492 : : 493 : 0 : rc = nix_tm_conf_init(roc_nix); 494 [ # # ]: 0 : if (rc) 495 : 0 : goto unregister_irqs; 496 : : 497 : : /* Get NIX HW info */ 498 : 0 : roc_nix_get_hw_info(roc_nix); 499 : 0 : nix->dev.drv_inited = true; 500 : : 501 : 0 : return 0; 502 : : unregister_irqs: 503 : 0 : nix_unregister_irqs(nix); 504 : 0 : lf_detach: 505 : 0 : nix_lf_detach(nix); 506 : 0 : dev_fini: 507 : 0 : rc |= dev_fini(dev, pci_dev); 508 : 0 : fail: 509 : 0 : nix_tel_node_del(roc_nix); 510 : 0 : return rc; 511 : : } 512 : : 513 : : int 514 [ # # ]: 0 : roc_nix_dev_fini(struct roc_nix *roc_nix) 515 : : { 516 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 517 : : int rc = 0; 518 : : 519 : : if (nix == NULL) 520 : : return NIX_ERR_PARAM; 521 : : 522 [ # # ]: 0 : if (!nix->dev.drv_inited) 523 : 0 : goto fini; 524 : : 525 : 0 : nix_tm_conf_fini(roc_nix); 526 : 0 : nix_unregister_irqs(nix); 527 : : 528 : 0 : rc = nix_lf_detach(nix); 529 : 0 : nix->dev.drv_inited = false; 530 : 0 : fini: 531 : 0 : rc |= dev_fini(&nix->dev, nix->pci_dev); 532 : : return rc; 533 : : }