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 : roc_idev_nix_rx_chan_set(roc_nix->port_id, rsp->rx_chan_base); 227 : : 228 : 0 : nix->rqs = plt_zmalloc(sizeof(struct roc_nix_rq *) * nb_rxq, 0); 229 [ # # ]: 0 : if (!nix->rqs) { 230 : : rc = -ENOMEM; 231 : 0 : goto fail; 232 : : } 233 : : 234 : 0 : nix->sqs = plt_zmalloc(sizeof(struct roc_nix_sq *) * nb_txq, 0); 235 [ # # ]: 0 : if (!nix->sqs) { 236 : : rc = -ENOMEM; 237 : 0 : goto fail; 238 : : } 239 : : 240 : 0 : nix_tel_node_add(roc_nix); 241 : 0 : fail: 242 : : mbox_put(mbox); 243 : 0 : return rc; 244 : : } 245 : : 246 : : int 247 : 0 : roc_nix_lf_free(struct roc_nix *roc_nix) 248 : : { 249 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 250 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 251 : : struct nix_lf_free_req *req; 252 : : struct ndc_sync_op *ndc_req; 253 : : int rc = -ENOSPC; 254 : : 255 : 0 : plt_free(nix->rqs); 256 : 0 : plt_free(nix->sqs); 257 : 0 : nix->rqs = NULL; 258 : 0 : nix->sqs = NULL; 259 : : 260 : : /* Sync NDC-NIX for LF */ 261 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox); 262 [ # # ]: 0 : if (ndc_req == NULL) 263 : 0 : goto exit; 264 : 0 : ndc_req->nix_lf_tx_sync = 1; 265 : 0 : ndc_req->nix_lf_rx_sync = 1; 266 : 0 : rc = mbox_process(mbox); 267 [ # # ]: 0 : if (rc) 268 : 0 : plt_err("Error on NDC-NIX-[TX, RX] LF sync, rc %d", rc); 269 : : 270 : 0 : req = mbox_alloc_msg_nix_lf_free(mbox); 271 [ # # ]: 0 : if (req == NULL) { 272 : : rc = -ENOSPC; 273 : 0 : goto exit; 274 : : } 275 : : /* Let AF driver free all this nix lf's 276 : : * NPC entries allocated using NPC MBOX. 277 : : */ 278 : 0 : req->flags = 0; 279 : : 280 : 0 : rc = mbox_process(mbox); 281 : 0 : exit: 282 : : mbox_put(mbox); 283 : 0 : return rc; 284 : : } 285 : : 286 : : static inline int 287 : 0 : nix_lf_attach(struct dev *dev) 288 : : { 289 : 0 : struct mbox *mbox = mbox_get(dev->mbox); 290 : : struct rsrc_attach_req *req; 291 : : int rc = -ENOSPC; 292 : : 293 : : /* Attach NIX(lf) */ 294 : 0 : req = mbox_alloc_msg_attach_resources(mbox); 295 [ # # ]: 0 : if (req == NULL) 296 : 0 : goto exit; 297 : 0 : req->modify = true; 298 : 0 : req->nixlf = true; 299 : : 300 : 0 : rc = mbox_process(mbox); 301 : 0 : exit: 302 : : mbox_put(mbox); 303 : 0 : return rc; 304 : : } 305 : : 306 : : static inline int 307 : 0 : nix_lf_get_msix_offset(struct dev *dev, struct nix *nix) 308 : : { 309 : : struct msix_offset_rsp *msix_rsp; 310 : 0 : struct mbox *mbox = mbox_get(dev->mbox); 311 : : int rc; 312 : : 313 : : /* Get MSIX vector offsets */ 314 : 0 : mbox_alloc_msg_msix_offset(mbox); 315 : : rc = mbox_process_msg(mbox, (void *)&msix_rsp); 316 [ # # ]: 0 : if (rc == 0) 317 : 0 : nix->msixoff = msix_rsp->nix_msixoff; 318 : : 319 : : mbox_put(mbox); 320 : 0 : return rc; 321 : : } 322 : : 323 : : static inline int 324 : 0 : nix_lf_detach(struct nix *nix) 325 : : { 326 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 327 : : struct rsrc_detach_req *req; 328 : : int rc = -ENOSPC; 329 : : 330 : 0 : req = mbox_alloc_msg_detach_resources(mbox); 331 [ # # ]: 0 : if (req == NULL) 332 : 0 : goto exit; 333 : 0 : req->partial = true; 334 : 0 : req->nixlf = true; 335 : : 336 : 0 : rc = mbox_process(mbox); 337 : 0 : exit: 338 : : mbox_put(mbox); 339 : 0 : return rc; 340 : : } 341 : : 342 : : static int 343 : 0 : roc_nix_get_hw_info(struct roc_nix *roc_nix) 344 : : { 345 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 346 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox); 347 : : struct nix_hw_info *hw_info; 348 : : int rc; 349 : : 350 : 0 : mbox_alloc_msg_nix_get_hw_info(mbox); 351 : : rc = mbox_process_msg(mbox, (void *)&hw_info); 352 [ # # ]: 0 : if (rc == 0) { 353 : 0 : nix->vwqe_interval = hw_info->vwqe_delay; 354 [ # # ]: 0 : if (nix->lbk_link) 355 : 0 : roc_nix->dwrr_mtu = hw_info->lbk_dwrr_mtu; 356 [ # # ]: 0 : else if (nix->sdp_link) 357 : 0 : roc_nix->dwrr_mtu = hw_info->sdp_dwrr_mtu; 358 : : else 359 : 0 : roc_nix->dwrr_mtu = hw_info->rpm_dwrr_mtu; 360 : : } 361 : : 362 : : mbox_put(mbox); 363 : 0 : return rc; 364 : : } 365 : : 366 : : static void 367 : : sdp_lbk_id_update(struct plt_pci_device *pci_dev, struct nix *nix) 368 : : { 369 : 0 : nix->sdp_link = false; 370 : 0 : nix->lbk_link = false; 371 : : 372 : : /* Update SDP/LBK link based on PCI device id */ 373 [ # # # ]: 0 : switch (pci_dev->id.device_id) { 374 : 0 : case PCI_DEVID_CNXK_RVU_SDP_PF: 375 : : case PCI_DEVID_CNXK_RVU_SDP_VF: 376 : 0 : nix->sdp_link = true; 377 : 0 : break; 378 : 0 : case PCI_DEVID_CNXK_RVU_AF_VF: 379 : 0 : nix->lbk_link = true; 380 : 0 : break; 381 : : default: 382 : : break; 383 : : } 384 : : } 385 : : 386 : : uint64_t 387 : 0 : nix_get_blkaddr(struct dev *dev) 388 : : { 389 : : uint64_t reg; 390 : : 391 : : /* Reading the discovery register to know which NIX is the LF 392 : : * attached to. 393 : : */ 394 [ # # ]: 0 : reg = plt_read64(dev->bar2 + 395 : : RVU_PF_BLOCK_ADDRX_DISC(RVU_BLOCK_ADDR_NIX0)); 396 : : 397 [ # # ]: 0 : return reg & 0x1FFULL ? RVU_BLOCK_ADDR_NIX0 : RVU_BLOCK_ADDR_NIX1; 398 : : } 399 : : 400 : : int 401 : 0 : roc_nix_dev_init(struct roc_nix *roc_nix) 402 : : { 403 : : enum roc_nix_rss_reta_sz reta_sz; 404 : : struct plt_pci_device *pci_dev; 405 : : struct roc_nix_list *nix_list; 406 : : uint16_t max_sqb_count; 407 : : uint64_t blkaddr; 408 : : struct dev *dev; 409 : : struct nix *nix; 410 : : int rc; 411 : : 412 [ # # # # ]: 0 : if (roc_nix == NULL || roc_nix->pci_dev == NULL) 413 : : return NIX_ERR_PARAM; 414 : : 415 : 0 : reta_sz = roc_nix->reta_sz; 416 [ # # # # ]: 0 : if (reta_sz != 0 && reta_sz != 64 && reta_sz != 128 && reta_sz != 256) 417 : : return NIX_ERR_PARAM; 418 : : 419 [ # # ]: 0 : if (reta_sz == 0) 420 : : reta_sz = ROC_NIX_RSS_RETA_SZ_64; 421 : : 422 : 0 : max_sqb_count = roc_nix->max_sqb_count; 423 : 0 : max_sqb_count = PLT_MIN(max_sqb_count, NIX_MAX_SQB); 424 : 0 : max_sqb_count = PLT_MAX(max_sqb_count, NIX_MIN_SQB); 425 : 0 : roc_nix->max_sqb_count = max_sqb_count; 426 : : 427 : : PLT_STATIC_ASSERT(sizeof(struct nix) <= ROC_NIX_MEM_SZ); 428 : : nix = roc_nix_to_nix_priv(roc_nix); 429 : : pci_dev = roc_nix->pci_dev; 430 : 0 : dev = &nix->dev; 431 : : 432 : 0 : nix_list = roc_idev_nix_list_get(); 433 [ # # ]: 0 : if (nix_list == NULL) 434 : : return -EINVAL; 435 : : 436 : 0 : TAILQ_INSERT_TAIL(nix_list, roc_nix, next); 437 : : 438 [ # # ]: 0 : if (nix->dev.drv_inited) 439 : : return 0; 440 : : 441 [ # # ]: 0 : if (dev->mbox_active) 442 : 0 : goto skip_dev_init; 443 : : 444 : : memset(nix, 0, sizeof(*nix)); 445 : : 446 : : /* Since 0 is a valid BPID, use -1 to represent invalid value. */ 447 : 0 : memset(nix->bpid, -1, sizeof(nix->bpid)); 448 : : 449 : : /* Initialize device */ 450 : 0 : rc = dev_init(dev, pci_dev); 451 [ # # ]: 0 : if (rc) { 452 : 0 : plt_err("Failed to init roc device"); 453 : 0 : goto fail; 454 : : } 455 : : 456 : 0 : skip_dev_init: 457 : 0 : dev->roc_nix = roc_nix; 458 : : 459 : 0 : nix->lmt_base = dev->lmt_base; 460 : : /* Expose base LMT line address for 461 : : * "Per Core LMT line" mode. 462 : : */ 463 : 0 : roc_nix->lmt_base = dev->lmt_base; 464 : : 465 : : /* Attach NIX LF */ 466 : 0 : rc = nix_lf_attach(dev); 467 [ # # ]: 0 : if (rc) 468 : 0 : goto dev_fini; 469 : : 470 : 0 : blkaddr = nix_get_blkaddr(dev); 471 : 0 : nix->is_nix1 = (blkaddr == RVU_BLOCK_ADDR_NIX1); 472 : : 473 : : /* Calculating base address based on which NIX block LF 474 : : * is attached to. 475 : : */ 476 : 0 : nix->base = dev->bar2 + (blkaddr << 20); 477 : : 478 : : /* Get NIX MSIX offset */ 479 : 0 : rc = nix_lf_get_msix_offset(dev, nix); 480 [ # # ]: 0 : if (rc) 481 : 0 : goto lf_detach; 482 : : 483 : : /* Update nix context */ 484 : : sdp_lbk_id_update(pci_dev, nix); 485 : 0 : nix->pci_dev = pci_dev; 486 : 0 : nix->reta_sz = reta_sz; 487 : 0 : nix->mtu = ROC_NIX_DEFAULT_HW_FRS; 488 : 0 : nix->dmac_flt_idx = -1; 489 : : 490 : : /* Register error and ras interrupts */ 491 : 0 : rc = nix_register_irqs(nix); 492 [ # # ]: 0 : if (rc) 493 : 0 : goto lf_detach; 494 : : 495 : 0 : rc = nix_tm_conf_init(roc_nix); 496 [ # # ]: 0 : if (rc) 497 : 0 : goto unregister_irqs; 498 : : 499 : : /* Get NIX HW info */ 500 : 0 : roc_nix_get_hw_info(roc_nix); 501 : 0 : nix->dev.drv_inited = true; 502 : : 503 : 0 : return 0; 504 : : unregister_irqs: 505 : 0 : nix_unregister_irqs(nix); 506 : 0 : lf_detach: 507 : 0 : nix_lf_detach(nix); 508 : 0 : dev_fini: 509 : 0 : rc |= dev_fini(dev, pci_dev); 510 : 0 : fail: 511 : 0 : nix_tel_node_del(roc_nix); 512 : 0 : return rc; 513 : : } 514 : : 515 : : int 516 [ # # ]: 0 : roc_nix_dev_fini(struct roc_nix *roc_nix) 517 : : { 518 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix); 519 : : int rc = 0; 520 : : 521 : : if (nix == NULL) 522 : : return NIX_ERR_PARAM; 523 : : 524 [ # # ]: 0 : if (!nix->dev.drv_inited) 525 : 0 : goto fini; 526 : : 527 : 0 : nix_tm_conf_fini(roc_nix); 528 : 0 : nix_unregister_irqs(nix); 529 : : 530 : 0 : rc = nix_lf_detach(nix); 531 : 0 : nix->dev.drv_inited = false; 532 : 0 : fini: 533 : 0 : rc |= dev_fini(&nix->dev, nix->pci_dev); 534 : : return rc; 535 : : }