1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2015 Freescale Semiconductor, Inc. 3 * Copyright 2018-2020 NXP 4 */ 5 6 #include "compat.h" 7 #include <fsl_qbman_debug.h> 8 #include "qbman_portal.h" 9 10 /* QBMan portal management command code */ 11 #define QBMAN_BP_QUERY 0x32 12 #define QBMAN_FQ_QUERY 0x44 13 #define QBMAN_FQ_QUERY_NP 0x45 14 #define QBMAN_WQ_QUERY 0x47 15 #define QBMAN_CGR_QUERY 0x51 16 #define QBMAN_WRED_QUERY 0x54 17 #define QBMAN_CGR_STAT_QUERY 0x55 18 #define QBMAN_CGR_STAT_QUERY_CLR 0x56 19 20 struct qbman_bp_query_desc { 21 uint8_t verb; 22 uint8_t reserved; 23 uint16_t bpid; 24 uint8_t reserved2[60]; 25 }; 26 27 #define QB_BP_STATE_SHIFT 24 28 #define QB_BP_VA_SHIFT 1 29 #define QB_BP_VA_MASK 0x2 30 #define QB_BP_WAE_SHIFT 2 31 #define QB_BP_WAE_MASK 0x4 32 #define QB_BP_PL_SHIFT 15 33 #define QB_BP_PL_MASK 0x8000 34 #define QB_BP_ICID_MASK 0x7FFF 35 36 int qbman_bp_query(struct qbman_swp *s, uint32_t bpid, 37 struct qbman_bp_query_rslt *r) 38 { 39 struct qbman_bp_query_desc *p; 40 41 /* Start the management command */ 42 p = (struct qbman_bp_query_desc *)qbman_swp_mc_start(s); 43 if (!p) 44 return -EBUSY; 45 46 /* Encode the caller-provided attributes */ 47 p->bpid = bpid; 48 49 /* Complete the management command */ 50 *r = *(struct qbman_bp_query_rslt *)qbman_swp_mc_complete(s, p, 51 QBMAN_BP_QUERY); 52 if (!r) { 53 pr_err("qbman: Query BPID %d failed, no response\n", 54 bpid); 55 return -EIO; 56 } 57 58 /* Decode the outcome */ 59 QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_BP_QUERY); 60 61 /* Determine success or failure */ 62 if (r->rslt != QBMAN_MC_RSLT_OK) { 63 pr_err("Query of BPID 0x%x failed, code=0x%02x\n", bpid, 64 r->rslt); 65 return -EIO; 66 } 67 68 return 0; 69 } 70 71 int qbman_bp_get_bdi(struct qbman_bp_query_rslt *r) 72 { 73 return r->bdi & 1; 74 } 75 76 int qbman_bp_get_va(struct qbman_bp_query_rslt *r) 77 { 78 return (r->bdi & QB_BP_VA_MASK) >> QB_BP_VA_MASK; 79 } 80 81 int qbman_bp_get_wae(struct qbman_bp_query_rslt *r) 82 { 83 return (r->bdi & QB_BP_WAE_MASK) >> QB_BP_WAE_SHIFT; 84 } 85 86 static uint16_t qbman_bp_thresh_to_value(uint16_t val) 87 { 88 return (val & 0xff) << ((val & 0xf00) >> 8); 89 } 90 91 uint16_t qbman_bp_get_swdet(struct qbman_bp_query_rslt *r) 92 { 93 94 return qbman_bp_thresh_to_value(r->swdet); 95 } 96 97 uint16_t qbman_bp_get_swdxt(struct qbman_bp_query_rslt *r) 98 { 99 return qbman_bp_thresh_to_value(r->swdxt); 100 } 101 102 uint16_t qbman_bp_get_hwdet(struct qbman_bp_query_rslt *r) 103 { 104 return qbman_bp_thresh_to_value(r->hwdet); 105 } 106 107 uint16_t qbman_bp_get_hwdxt(struct qbman_bp_query_rslt *r) 108 { 109 return qbman_bp_thresh_to_value(r->hwdxt); 110 } 111 112 uint16_t qbman_bp_get_swset(struct qbman_bp_query_rslt *r) 113 { 114 return qbman_bp_thresh_to_value(r->swset); 115 } 116 117 uint16_t qbman_bp_get_swsxt(struct qbman_bp_query_rslt *r) 118 { 119 120 return qbman_bp_thresh_to_value(r->swsxt); 121 } 122 123 uint16_t qbman_bp_get_vbpid(struct qbman_bp_query_rslt *r) 124 { 125 return r->vbpid; 126 } 127 128 uint16_t qbman_bp_get_icid(struct qbman_bp_query_rslt *r) 129 { 130 return r->icid & QB_BP_ICID_MASK; 131 } 132 133 int qbman_bp_get_pl(struct qbman_bp_query_rslt *r) 134 { 135 return (r->icid & QB_BP_PL_MASK) >> QB_BP_PL_SHIFT; 136 } 137 138 uint64_t qbman_bp_get_bpscn_addr(struct qbman_bp_query_rslt *r) 139 { 140 return r->bpscn_addr; 141 } 142 143 uint64_t qbman_bp_get_bpscn_ctx(struct qbman_bp_query_rslt *r) 144 { 145 return r->bpscn_ctx; 146 } 147 148 uint16_t qbman_bp_get_hw_targ(struct qbman_bp_query_rslt *r) 149 { 150 return r->hw_targ; 151 } 152 153 int qbman_bp_has_free_bufs(struct qbman_bp_query_rslt *r) 154 { 155 return !(int)(r->state & 0x1); 156 } 157 158 int qbman_bp_is_depleted(struct qbman_bp_query_rslt *r) 159 { 160 return (int)((r->state & 0x2) >> 1); 161 } 162 163 int qbman_bp_is_surplus(struct qbman_bp_query_rslt *r) 164 { 165 return (int)((r->state & 0x4) >> 2); 166 } 167 168 uint32_t qbman_bp_num_free_bufs(struct qbman_bp_query_rslt *r) 169 { 170 return r->fill; 171 } 172 173 uint32_t qbman_bp_get_hdptr(struct qbman_bp_query_rslt *r) 174 { 175 return r->hdptr; 176 } 177 178 uint32_t qbman_bp_get_sdcnt(struct qbman_bp_query_rslt *r) 179 { 180 return r->sdcnt; 181 } 182 183 uint32_t qbman_bp_get_hdcnt(struct qbman_bp_query_rslt *r) 184 { 185 return r->hdcnt; 186 } 187 188 uint32_t qbman_bp_get_sscnt(struct qbman_bp_query_rslt *r) 189 { 190 return r->sscnt; 191 } 192 193 struct qbman_fq_query_desc { 194 uint8_t verb; 195 uint8_t reserved[3]; 196 uint32_t fqid; 197 uint8_t reserved2[56]; 198 }; 199 200 /* FQ query function for programmable fields */ 201 int qbman_fq_query(struct qbman_swp *s, uint32_t fqid, 202 struct qbman_fq_query_rslt *r) 203 { 204 struct qbman_fq_query_desc *p; 205 206 p = (struct qbman_fq_query_desc *)qbman_swp_mc_start(s); 207 if (!p) 208 return -EBUSY; 209 210 p->fqid = fqid; 211 *r = *(struct qbman_fq_query_rslt *)qbman_swp_mc_complete(s, p, 212 QBMAN_FQ_QUERY); 213 if (!r) { 214 pr_err("qbman: Query FQID %d failed, no response\n", 215 fqid); 216 return -EIO; 217 } 218 219 /* Decode the outcome */ 220 QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_FQ_QUERY); 221 222 /* Determine success or failure */ 223 if (r->rslt != QBMAN_MC_RSLT_OK) { 224 pr_err("Query of FQID 0x%x failed, code=0x%02x\n", 225 fqid, r->rslt); 226 return -EIO; 227 } 228 229 return 0; 230 } 231 232 uint8_t qbman_fq_attr_get_fqctrl(struct qbman_fq_query_rslt *r) 233 { 234 return r->fq_ctrl; 235 } 236 237 uint16_t qbman_fq_attr_get_cgrid(struct qbman_fq_query_rslt *r) 238 { 239 return r->cgid; 240 } 241 242 uint16_t qbman_fq_attr_get_destwq(struct qbman_fq_query_rslt *r) 243 { 244 return r->dest_wq; 245 } 246 247 static uint16_t qbman_thresh_to_value(uint16_t val) 248 { 249 return ((val & 0x1FE0) >> 5) << (val & 0x1F); 250 } 251 252 uint16_t qbman_fq_attr_get_tdthresh(struct qbman_fq_query_rslt *r) 253 { 254 return qbman_thresh_to_value(r->td_thresh); 255 } 256 257 int qbman_fq_attr_get_oa_ics(struct qbman_fq_query_rslt *r) 258 { 259 return (int)(r->oal_oac >> 14) & 0x1; 260 } 261 262 int qbman_fq_attr_get_oa_cgr(struct qbman_fq_query_rslt *r) 263 { 264 return (int)(r->oal_oac >> 15); 265 } 266 267 uint16_t qbman_fq_attr_get_oal(struct qbman_fq_query_rslt *r) 268 { 269 return (r->oal_oac & 0x0FFF); 270 } 271 272 int qbman_fq_attr_get_bdi(struct qbman_fq_query_rslt *r) 273 { 274 return (r->mctl & 0x1); 275 } 276 277 int qbman_fq_attr_get_ff(struct qbman_fq_query_rslt *r) 278 { 279 return (r->mctl & 0x2) >> 1; 280 } 281 282 int qbman_fq_attr_get_va(struct qbman_fq_query_rslt *r) 283 { 284 return (r->mctl & 0x4) >> 2; 285 } 286 287 int qbman_fq_attr_get_ps(struct qbman_fq_query_rslt *r) 288 { 289 return (r->mctl & 0x8) >> 3; 290 } 291 292 int qbman_fq_attr_get_pps(struct qbman_fq_query_rslt *r) 293 { 294 return (r->mctl & 0x30) >> 4; 295 } 296 297 uint16_t qbman_fq_attr_get_icid(struct qbman_fq_query_rslt *r) 298 { 299 return r->icid & 0x7FFF; 300 } 301 302 int qbman_fq_attr_get_pl(struct qbman_fq_query_rslt *r) 303 { 304 return (int)((r->icid & 0x8000) >> 15); 305 } 306 307 uint32_t qbman_fq_attr_get_vfqid(struct qbman_fq_query_rslt *r) 308 { 309 return r->vfqid & 0x00FFFFFF; 310 } 311 312 uint32_t qbman_fq_attr_get_erfqid(struct qbman_fq_query_rslt *r) 313 { 314 return r->fqid_er & 0x00FFFFFF; 315 } 316 317 uint16_t qbman_fq_attr_get_opridsz(struct qbman_fq_query_rslt *r) 318 { 319 return r->opridsz; 320 } 321 322 int qbman_fq_query_state(struct qbman_swp *s, uint32_t fqid, 323 struct qbman_fq_query_np_rslt *r) 324 { 325 struct qbman_fq_query_desc *p; 326 struct qbman_fq_query_np_rslt *var; 327 328 p = (struct qbman_fq_query_desc *)qbman_swp_mc_start(s); 329 if (!p) 330 return -EBUSY; 331 332 p->fqid = fqid; 333 var = qbman_swp_mc_complete(s, p, QBMAN_FQ_QUERY_NP); 334 if (!var) { 335 pr_err("qbman: Query FQID %d NP fields failed, no response\n", 336 fqid); 337 return -EIO; 338 } 339 *r = *var; 340 341 /* Decode the outcome */ 342 QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_FQ_QUERY_NP); 343 344 /* Determine success or failure */ 345 if (r->rslt != QBMAN_MC_RSLT_OK) { 346 pr_err("Query NP fields of FQID 0x%x failed, code=0x%02x\n", 347 fqid, r->rslt); 348 return -EIO; 349 } 350 351 return 0; 352 } 353 354 uint8_t qbman_fq_state_schedstate(const struct qbman_fq_query_np_rslt *r) 355 { 356 return r->st1 & 0x7; 357 } 358 359 int qbman_fq_state_force_eligible(const struct qbman_fq_query_np_rslt *r) 360 { 361 return (int)((r->st1 & 0x8) >> 3); 362 } 363 364 int qbman_fq_state_xoff(const struct qbman_fq_query_np_rslt *r) 365 { 366 return (int)((r->st1 & 0x10) >> 4); 367 } 368 369 int qbman_fq_state_retirement_pending(const struct qbman_fq_query_np_rslt *r) 370 { 371 return (int)((r->st1 & 0x20) >> 5); 372 } 373 374 int qbman_fq_state_overflow_error(const struct qbman_fq_query_np_rslt *r) 375 { 376 return (int)((r->st1 & 0x40) >> 6); 377 } 378 379 uint32_t qbman_fq_state_frame_count(const struct qbman_fq_query_np_rslt *r) 380 { 381 return (r->frm_cnt & 0x00FFFFFF); 382 } 383 384 uint32_t qbman_fq_state_byte_count(const struct qbman_fq_query_np_rslt *r) 385 { 386 return r->byte_cnt; 387 } 388 389 /* Query CGR */ 390 struct qbman_cgr_query_desc { 391 uint8_t verb; 392 uint8_t reserved; 393 uint16_t cgid; 394 uint8_t reserved2[60]; 395 }; 396 397 int qbman_cgr_query(struct qbman_swp *s, uint32_t cgid, 398 struct qbman_cgr_query_rslt *r) 399 { 400 struct qbman_cgr_query_desc *p; 401 402 p = (struct qbman_cgr_query_desc *)qbman_swp_mc_start(s); 403 if (!p) 404 return -EBUSY; 405 406 p->cgid = cgid; 407 *r = *(struct qbman_cgr_query_rslt *)qbman_swp_mc_complete(s, p, 408 QBMAN_CGR_QUERY); 409 if (!r) { 410 pr_err("qbman: Query CGID %d failed, no response\n", 411 cgid); 412 return -EIO; 413 } 414 415 /* Decode the outcome */ 416 QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_CGR_QUERY); 417 418 /* Determine success or failure */ 419 if (r->rslt != QBMAN_MC_RSLT_OK) { 420 pr_err("Query CGID 0x%x failed,code=0x%02x\n", cgid, r->rslt); 421 return -EIO; 422 } 423 424 return 0; 425 } 426 427 int qbman_cgr_get_cscn_wq_en_enter(struct qbman_cgr_query_rslt *r) 428 { 429 return (int)(r->ctl1 & 0x1); 430 } 431 432 int qbman_cgr_get_cscn_wq_en_exit(struct qbman_cgr_query_rslt *r) 433 { 434 return (int)((r->ctl1 & 0x2) >> 1); 435 } 436 437 int qbman_cgr_get_cscn_wq_icd(struct qbman_cgr_query_rslt *r) 438 { 439 return (int)((r->ctl1 & 0x4) >> 2); 440 } 441 442 uint8_t qbman_cgr_get_mode(struct qbman_cgr_query_rslt *r) 443 { 444 return r->mode & 0x3; 445 } 446 447 int qbman_cgr_get_rej_cnt_mode(struct qbman_cgr_query_rslt *r) 448 { 449 return (int)((r->mode & 0x4) >> 2); 450 } 451 452 int qbman_cgr_get_cscn_bdi(struct qbman_cgr_query_rslt *r) 453 { 454 return (int)((r->mode & 0x8) >> 3); 455 } 456 457 uint16_t qbman_cgr_attr_get_cs_thres(struct qbman_cgr_query_rslt *r) 458 { 459 return qbman_thresh_to_value(r->cs_thres); 460 } 461 462 uint16_t qbman_cgr_attr_get_cs_thres_x(struct qbman_cgr_query_rslt *r) 463 { 464 return qbman_thresh_to_value(r->cs_thres_x); 465 } 466 467 uint16_t qbman_cgr_attr_get_td_thres(struct qbman_cgr_query_rslt *r) 468 { 469 return qbman_thresh_to_value(r->td_thres); 470 } 471 472 int qbman_cgr_wred_query(struct qbman_swp *s, uint32_t cgid, 473 struct qbman_wred_query_rslt *r) 474 { 475 struct qbman_cgr_query_desc *p; 476 477 p = (struct qbman_cgr_query_desc *)qbman_swp_mc_start(s); 478 if (!p) 479 return -EBUSY; 480 481 p->cgid = cgid; 482 *r = *(struct qbman_wred_query_rslt *)qbman_swp_mc_complete(s, p, 483 QBMAN_WRED_QUERY); 484 if (!r) { 485 pr_err("qbman: Query CGID WRED %d failed, no response\n", 486 cgid); 487 return -EIO; 488 } 489 490 /* Decode the outcome */ 491 QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_WRED_QUERY); 492 493 /* Determine success or failure */ 494 if (r->rslt != QBMAN_MC_RSLT_OK) { 495 pr_err("Query CGID WRED 0x%x failed,code=0x%02x\n", 496 cgid, r->rslt); 497 return -EIO; 498 } 499 500 return 0; 501 } 502 503 int qbman_cgr_attr_wred_get_edp(struct qbman_wred_query_rslt *r, uint32_t idx) 504 { 505 return (int)(r->edp[idx] & 1); 506 } 507 508 uint32_t qbman_cgr_attr_wred_get_parm_dp(struct qbman_wred_query_rslt *r, 509 uint32_t idx) 510 { 511 return r->wred_parm_dp[idx]; 512 } 513 514 void qbman_cgr_attr_wred_dp_decompose(uint32_t dp, uint64_t *minth, 515 uint64_t *maxth, uint8_t *maxp) 516 { 517 uint8_t ma, mn, step_i, step_s, pn; 518 519 ma = (uint8_t)(dp >> 24); 520 mn = (uint8_t)(dp >> 19) & 0x1f; 521 step_i = (uint8_t)(dp >> 11); 522 step_s = (uint8_t)(dp >> 6) & 0x1f; 523 pn = (uint8_t)dp & 0x3f; 524 525 *maxp = (uint8_t)(((pn<<2) * 100)/256); 526 527 if (mn == 0) 528 *maxth = ma; 529 else 530 *maxth = ((ma+256) * (1<<(mn-1))); 531 532 if (step_s == 0) 533 *minth = *maxth - step_i; 534 else 535 *minth = *maxth - (256 + step_i) * (1<<(step_s - 1)); 536 } 537 538 /* Query CGR/CCGR/CQ statistics */ 539 struct qbman_cgr_statistics_query_desc { 540 uint8_t verb; 541 uint8_t reserved; 542 uint16_t cgid; 543 uint8_t reserved1; 544 uint8_t ct; 545 uint8_t reserved2[58]; 546 }; 547 548 struct qbman_cgr_statistics_query_rslt { 549 uint8_t verb; 550 uint8_t rslt; 551 uint8_t reserved[14]; 552 uint64_t frm_cnt; 553 uint64_t byte_cnt; 554 uint32_t reserved2[8]; 555 }; 556 557 static int qbman_cgr_statistics_query(struct qbman_swp *s, uint32_t cgid, 558 int clear, uint32_t command_type, 559 uint64_t *frame_cnt, uint64_t *byte_cnt) 560 { 561 struct qbman_cgr_statistics_query_desc *p; 562 struct qbman_cgr_statistics_query_rslt *r; 563 uint32_t query_verb; 564 565 p = (struct qbman_cgr_statistics_query_desc *)qbman_swp_mc_start(s); 566 if (!p) 567 return -EBUSY; 568 569 p->cgid = cgid; 570 if (command_type < 2) 571 p->ct = command_type; 572 query_verb = clear ? 573 QBMAN_CGR_STAT_QUERY_CLR : QBMAN_CGR_STAT_QUERY; 574 r = (struct qbman_cgr_statistics_query_rslt *)qbman_swp_mc_complete(s, 575 p, query_verb); 576 if (!r) { 577 pr_err("qbman: Query CGID %d statistics failed, no response\n", 578 cgid); 579 return -EIO; 580 } 581 582 /* Decode the outcome */ 583 QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != query_verb); 584 585 /* Determine success or failure */ 586 if (r->rslt != QBMAN_MC_RSLT_OK) { 587 pr_err("Query statistics of CGID 0x%x failed, code=0x%02x\n", 588 cgid, r->rslt); 589 return -EIO; 590 } 591 592 if (*frame_cnt) 593 *frame_cnt = r->frm_cnt & 0xFFFFFFFFFFllu; 594 if (*byte_cnt) 595 *byte_cnt = r->byte_cnt & 0xFFFFFFFFFFllu; 596 597 return 0; 598 } 599 600 int qbman_cgr_reject_statistics(struct qbman_swp *s, uint32_t cgid, int clear, 601 uint64_t *frame_cnt, uint64_t *byte_cnt) 602 { 603 return qbman_cgr_statistics_query(s, cgid, clear, 0xff, 604 frame_cnt, byte_cnt); 605 } 606 607 int qbman_ccgr_reject_statistics(struct qbman_swp *s, uint32_t cgid, int clear, 608 uint64_t *frame_cnt, uint64_t *byte_cnt) 609 { 610 return qbman_cgr_statistics_query(s, cgid, clear, 1, 611 frame_cnt, byte_cnt); 612 } 613 614 int qbman_cq_dequeue_statistics(struct qbman_swp *s, uint32_t cgid, int clear, 615 uint64_t *frame_cnt, uint64_t *byte_cnt) 616 { 617 return qbman_cgr_statistics_query(s, cgid, clear, 0, 618 frame_cnt, byte_cnt); 619 } 620 621 /* WQ Chan Query */ 622 struct qbman_wqchan_query_desc { 623 uint8_t verb; 624 uint8_t reserved; 625 uint16_t chid; 626 uint8_t reserved2[60]; 627 }; 628 629 int qbman_wqchan_query(struct qbman_swp *s, uint16_t chanid, 630 struct qbman_wqchan_query_rslt *r) 631 { 632 struct qbman_wqchan_query_desc *p; 633 634 /* Start the management command */ 635 p = (struct qbman_wqchan_query_desc *)qbman_swp_mc_start(s); 636 if (!p) 637 return -EBUSY; 638 639 /* Encode the caller-provided attributes */ 640 p->chid = chanid; 641 642 /* Complete the management command */ 643 *r = *(struct qbman_wqchan_query_rslt *)qbman_swp_mc_complete(s, p, 644 QBMAN_WQ_QUERY); 645 if (!r) { 646 pr_err("qbman: Query WQ Channel %d failed, no response\n", 647 chanid); 648 return -EIO; 649 } 650 651 /* Decode the outcome */ 652 QBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_WQ_QUERY); 653 654 /* Determine success or failure */ 655 if (r->rslt != QBMAN_MC_RSLT_OK) { 656 pr_err("Query of WQCHAN 0x%x failed, code=0x%02x\n", 657 chanid, r->rslt); 658 return -EIO; 659 } 660 661 return 0; 662 } 663 664 uint32_t qbman_wqchan_attr_get_wqlen(struct qbman_wqchan_query_rslt *r, int wq) 665 { 666 return r->wq_len[wq] & 0x00FFFFFF; 667 } 668 669 uint64_t qbman_wqchan_attr_get_cdan_ctx(struct qbman_wqchan_query_rslt *r) 670 { 671 return r->cdan_ctx; 672 } 673 674 uint16_t qbman_wqchan_attr_get_cdan_wqid(struct qbman_wqchan_query_rslt *r) 675 { 676 return r->cdan_wqid; 677 } 678 679 uint8_t qbman_wqchan_attr_get_ctrl(struct qbman_wqchan_query_rslt *r) 680 { 681 return r->ctrl; 682 } 683 684 uint16_t qbman_wqchan_attr_get_chanid(struct qbman_wqchan_query_rslt *r) 685 { 686 return r->chid; 687 } 688