1 /***********************license start*************** 2 * Author: Cavium Networks 3 * 4 * Contact: support@caviumnetworks.com 5 * This file is part of the OCTEON SDK 6 * 7 * Copyright (c) 2003-2008 Cavium Networks 8 * 9 * This file is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License, Version 2, as 11 * published by the Free Software Foundation. 12 * 13 * This file is distributed in the hope that it will be useful, but 14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 16 * NONINFRINGEMENT. See the GNU General Public License for more 17 * details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this file; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * or visit http://www.gnu.org/licenses/. 23 * 24 * This file may also be available under a different license from Cavium. 25 * Contact Cavium Networks for more information 26 ***********************license end**************************************/ 27 28 /** 29 * Interface to the hardware Packet Order / Work unit. 30 * 31 * New, starting with SDK 1.7.0, cvmx-pow supports a number of 32 * extended consistency checks. The define 33 * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW 34 * internal state checks to find common programming errors. If 35 * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default 36 * enabled. For example, cvmx-pow will check for the following 37 * program errors or POW state inconsistency. 38 * - Requesting a POW operation with an active tag switch in 39 * progress. 40 * - Waiting for a tag switch to complete for an excessively 41 * long period. This is normally a sign of an error in locking 42 * causing deadlock. 43 * - Illegal tag switches from NULL_NULL. 44 * - Illegal tag switches from NULL. 45 * - Illegal deschedule request. 46 * - WQE pointer not matching the one attached to the core by 47 * the POW. 48 * 49 */ 50 51 #ifndef __CVMX_POW_H__ 52 #define __CVMX_POW_H__ 53 54 #include <asm/octeon/cvmx-pow-defs.h> 55 56 #include <asm/octeon/cvmx-scratch.h> 57 #include <asm/octeon/cvmx-wqe.h> 58 59 /* Default to having all POW constancy checks turned on */ 60 #ifndef CVMX_ENABLE_POW_CHECKS 61 #define CVMX_ENABLE_POW_CHECKS 1 62 #endif 63 64 enum cvmx_pow_tag_type { 65 /* Tag ordering is maintained */ 66 CVMX_POW_TAG_TYPE_ORDERED = 0L, 67 /* Tag ordering is maintained, and at most one PP has the tag */ 68 CVMX_POW_TAG_TYPE_ATOMIC = 1L, 69 /* 70 * The work queue entry from the order - NEVER tag switch from 71 * NULL to NULL 72 */ 73 CVMX_POW_TAG_TYPE_NULL = 2L, 74 /* A tag switch to NULL, and there is no space reserved in POW 75 * - NEVER tag switch to NULL_NULL 76 * - NEVER tag switch from NULL_NULL 77 * - NULL_NULL is entered at the beginning of time and on a deschedule. 78 * - NULL_NULL can be exited by a new work request. A NULL_SWITCH 79 * load can also switch the state to NULL 80 */ 81 CVMX_POW_TAG_TYPE_NULL_NULL = 3L 82 }; 83 84 /** 85 * Wait flag values for pow functions. 86 */ 87 typedef enum { 88 CVMX_POW_WAIT = 1, 89 CVMX_POW_NO_WAIT = 0, 90 } cvmx_pow_wait_t; 91 92 /** 93 * POW tag operations. These are used in the data stored to the POW. 94 */ 95 typedef enum { 96 /* 97 * switch the tag (only) for this PP 98 * - the previous tag should be non-NULL in this case 99 * - tag switch response required 100 * - fields used: op, type, tag 101 */ 102 CVMX_POW_TAG_OP_SWTAG = 0L, 103 /* 104 * switch the tag for this PP, with full information 105 * - this should be used when the previous tag is NULL 106 * - tag switch response required 107 * - fields used: address, op, grp, type, tag 108 */ 109 CVMX_POW_TAG_OP_SWTAG_FULL = 1L, 110 /* 111 * switch the tag (and/or group) for this PP and de-schedule 112 * - OK to keep the tag the same and only change the group 113 * - fields used: op, no_sched, grp, type, tag 114 */ 115 CVMX_POW_TAG_OP_SWTAG_DESCH = 2L, 116 /* 117 * just de-schedule 118 * - fields used: op, no_sched 119 */ 120 CVMX_POW_TAG_OP_DESCH = 3L, 121 /* 122 * create an entirely new work queue entry 123 * - fields used: address, op, qos, grp, type, tag 124 */ 125 CVMX_POW_TAG_OP_ADDWQ = 4L, 126 /* 127 * just update the work queue pointer and grp for this PP 128 * - fields used: address, op, grp 129 */ 130 CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L, 131 /* 132 * set the no_sched bit on the de-schedule list 133 * 134 * - does nothing if the selected entry is not on the 135 * de-schedule list 136 * 137 * - does nothing if the stored work queue pointer does not 138 * match the address field 139 * 140 * - fields used: address, index, op 141 * 142 * Before issuing a *_NSCHED operation, SW must guarantee 143 * that all prior deschedules and set/clr NSCHED operations 144 * are complete and all prior switches are complete. The 145 * hardware provides the opsdone bit and swdone bit for SW 146 * polling. After issuing a *_NSCHED operation, SW must 147 * guarantee that the set/clr NSCHED is complete before any 148 * subsequent operations. 149 */ 150 CVMX_POW_TAG_OP_SET_NSCHED = 6L, 151 /* 152 * clears the no_sched bit on the de-schedule list 153 * 154 * - does nothing if the selected entry is not on the 155 * de-schedule list 156 * 157 * - does nothing if the stored work queue pointer does not 158 * match the address field 159 * 160 * - fields used: address, index, op 161 * 162 * Before issuing a *_NSCHED operation, SW must guarantee that 163 * all prior deschedules and set/clr NSCHED operations are 164 * complete and all prior switches are complete. The hardware 165 * provides the opsdone bit and swdone bit for SW 166 * polling. After issuing a *_NSCHED operation, SW must 167 * guarantee that the set/clr NSCHED is complete before any 168 * subsequent operations. 169 */ 170 CVMX_POW_TAG_OP_CLR_NSCHED = 7L, 171 /* do nothing */ 172 CVMX_POW_TAG_OP_NOP = 15L 173 } cvmx_pow_tag_op_t; 174 175 /** 176 * This structure defines the store data on a store to POW 177 */ 178 typedef union { 179 uint64_t u64; 180 struct { 181 /* 182 * Don't reschedule this entry. no_sched is used for 183 * CVMX_POW_TAG_OP_SWTAG_DESCH and 184 * CVMX_POW_TAG_OP_DESCH 185 */ 186 uint64_t no_sched:1; 187 uint64_t unused:2; 188 /* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */ 189 uint64_t index:13; 190 /* The operation to perform */ 191 cvmx_pow_tag_op_t op:4; 192 uint64_t unused2:2; 193 /* 194 * The QOS level for the packet. qos is only used for 195 * CVMX_POW_TAG_OP_ADDWQ 196 */ 197 uint64_t qos:3; 198 /* 199 * The group that the work queue entry will be 200 * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ, 201 * CVMX_POW_TAG_OP_SWTAG_FULL, 202 * CVMX_POW_TAG_OP_SWTAG_DESCH, and 203 * CVMX_POW_TAG_OP_UPDATE_WQP_GRP 204 */ 205 uint64_t grp:4; 206 /* 207 * The type of the tag. type is used for everything 208 * except CVMX_POW_TAG_OP_DESCH, 209 * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and 210 * CVMX_POW_TAG_OP_*_NSCHED 211 */ 212 uint64_t type:3; 213 /* 214 * The actual tag. tag is used for everything except 215 * CVMX_POW_TAG_OP_DESCH, 216 * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and 217 * CVMX_POW_TAG_OP_*_NSCHED 218 */ 219 uint64_t tag:32; 220 } s; 221 } cvmx_pow_tag_req_t; 222 223 /** 224 * This structure describes the address to load stuff from POW 225 */ 226 typedef union { 227 uint64_t u64; 228 229 /** 230 * Address for new work request loads (did<2:0> == 0) 231 */ 232 struct { 233 /* Mips64 address region. Should be CVMX_IO_SEG */ 234 uint64_t mem_region:2; 235 /* Must be zero */ 236 uint64_t reserved_49_61:13; 237 /* Must be one */ 238 uint64_t is_io:1; 239 /* the ID of POW -- did<2:0> == 0 in this case */ 240 uint64_t did:8; 241 /* Must be zero */ 242 uint64_t reserved_4_39:36; 243 /* 244 * If set, don't return load response until work is 245 * available. 246 */ 247 uint64_t wait:1; 248 /* Must be zero */ 249 uint64_t reserved_0_2:3; 250 } swork; 251 252 /** 253 * Address for loads to get POW internal status 254 */ 255 struct { 256 /* Mips64 address region. Should be CVMX_IO_SEG */ 257 uint64_t mem_region:2; 258 /* Must be zero */ 259 uint64_t reserved_49_61:13; 260 /* Must be one */ 261 uint64_t is_io:1; 262 /* the ID of POW -- did<2:0> == 1 in this case */ 263 uint64_t did:8; 264 /* Must be zero */ 265 uint64_t reserved_10_39:30; 266 /* The core id to get status for */ 267 uint64_t coreid:4; 268 /* 269 * If set and get_cur is set, return reverse tag-list 270 * pointer rather than forward tag-list pointer. 271 */ 272 uint64_t get_rev:1; 273 /* 274 * If set, return current status rather than pending 275 * status. 276 */ 277 uint64_t get_cur:1; 278 /* 279 * If set, get the work-queue pointer rather than 280 * tag/type. 281 */ 282 uint64_t get_wqp:1; 283 /* Must be zero */ 284 uint64_t reserved_0_2:3; 285 } sstatus; 286 287 /** 288 * Address for memory loads to get POW internal state 289 */ 290 struct { 291 /* Mips64 address region. Should be CVMX_IO_SEG */ 292 uint64_t mem_region:2; 293 /* Must be zero */ 294 uint64_t reserved_49_61:13; 295 /* Must be one */ 296 uint64_t is_io:1; 297 /* the ID of POW -- did<2:0> == 2 in this case */ 298 uint64_t did:8; 299 /* Must be zero */ 300 uint64_t reserved_16_39:24; 301 /* POW memory index */ 302 uint64_t index:11; 303 /* 304 * If set, return deschedule information rather than 305 * the standard response for work-queue index (invalid 306 * if the work-queue entry is not on the deschedule 307 * list). 308 */ 309 uint64_t get_des:1; 310 /* 311 * If set, get the work-queue pointer rather than 312 * tag/type (no effect when get_des set). 313 */ 314 uint64_t get_wqp:1; 315 /* Must be zero */ 316 uint64_t reserved_0_2:3; 317 } smemload; 318 319 /** 320 * Address for index/pointer loads 321 */ 322 struct { 323 /* Mips64 address region. Should be CVMX_IO_SEG */ 324 uint64_t mem_region:2; 325 /* Must be zero */ 326 uint64_t reserved_49_61:13; 327 /* Must be one */ 328 uint64_t is_io:1; 329 /* the ID of POW -- did<2:0> == 3 in this case */ 330 uint64_t did:8; 331 /* Must be zero */ 332 uint64_t reserved_9_39:31; 333 /* 334 * when {get_rmt ==0 AND get_des_get_tail == 0}, this 335 * field selects one of eight POW internal-input 336 * queues (0-7), one per QOS level; values 8-15 are 337 * illegal in this case; when {get_rmt ==0 AND 338 * get_des_get_tail == 1}, this field selects one of 339 * 16 deschedule lists (per group); when get_rmt ==1, 340 * this field selects one of 16 memory-input queue 341 * lists. The two memory-input queue lists associated 342 * with each QOS level are: 343 * 344 * - qosgrp = 0, qosgrp = 8: QOS0 345 * - qosgrp = 1, qosgrp = 9: QOS1 346 * - qosgrp = 2, qosgrp = 10: QOS2 347 * - qosgrp = 3, qosgrp = 11: QOS3 348 * - qosgrp = 4, qosgrp = 12: QOS4 349 * - qosgrp = 5, qosgrp = 13: QOS5 350 * - qosgrp = 6, qosgrp = 14: QOS6 351 * - qosgrp = 7, qosgrp = 15: QOS7 352 */ 353 uint64_t qosgrp:4; 354 /* 355 * If set and get_rmt is clear, return deschedule list 356 * indexes rather than indexes for the specified qos 357 * level; if set and get_rmt is set, return the tail 358 * pointer rather than the head pointer for the 359 * specified qos level. 360 */ 361 uint64_t get_des_get_tail:1; 362 /* 363 * If set, return remote pointers rather than the 364 * local indexes for the specified qos level. 365 */ 366 uint64_t get_rmt:1; 367 /* Must be zero */ 368 uint64_t reserved_0_2:3; 369 } sindexload; 370 371 /** 372 * address for NULL_RD request (did<2:0> == 4) when this is read, 373 * HW attempts to change the state to NULL if it is NULL_NULL (the 374 * hardware cannot switch from NULL_NULL to NULL if a POW entry is 375 * not available - software may need to recover by finishing 376 * another piece of work before a POW entry can ever become 377 * available.) 378 */ 379 struct { 380 /* Mips64 address region. Should be CVMX_IO_SEG */ 381 uint64_t mem_region:2; 382 /* Must be zero */ 383 uint64_t reserved_49_61:13; 384 /* Must be one */ 385 uint64_t is_io:1; 386 /* the ID of POW -- did<2:0> == 4 in this case */ 387 uint64_t did:8; 388 /* Must be zero */ 389 uint64_t reserved_0_39:40; 390 } snull_rd; 391 } cvmx_pow_load_addr_t; 392 393 /** 394 * This structure defines the response to a load/SENDSINGLE to POW 395 * (except CSR reads) 396 */ 397 typedef union { 398 uint64_t u64; 399 400 /** 401 * Response to new work request loads 402 */ 403 struct { 404 /* 405 * Set when no new work queue entry was returned. * 406 * If there was de-scheduled work, the HW will 407 * definitely return it. When this bit is set, it 408 * could mean either mean: 409 * 410 * - There was no work, or 411 * 412 * - There was no work that the HW could find. This 413 * case can happen, regardless of the wait bit value 414 * in the original request, when there is work in 415 * the IQ's that is too deep down the list. 416 */ 417 uint64_t no_work:1; 418 /* Must be zero */ 419 uint64_t reserved_40_62:23; 420 /* 36 in O1 -- the work queue pointer */ 421 uint64_t addr:40; 422 } s_work; 423 424 /** 425 * Result for a POW Status Load (when get_cur==0 and get_wqp==0) 426 */ 427 struct { 428 uint64_t reserved_62_63:2; 429 /* Set when there is a pending non-NULL SWTAG or 430 * SWTAG_FULL, and the POW entry has not left the list 431 * for the original tag. */ 432 uint64_t pend_switch:1; 433 /* Set when SWTAG_FULL and pend_switch is set. */ 434 uint64_t pend_switch_full:1; 435 /* 436 * Set when there is a pending NULL SWTAG, or an 437 * implicit switch to NULL. 438 */ 439 uint64_t pend_switch_null:1; 440 /* Set when there is a pending DESCHED or SWTAG_DESCHED. */ 441 uint64_t pend_desched:1; 442 /* 443 * Set when there is a pending SWTAG_DESCHED and 444 * pend_desched is set. 445 */ 446 uint64_t pend_desched_switch:1; 447 /* Set when nosched is desired and pend_desched is set. */ 448 uint64_t pend_nosched:1; 449 /* Set when there is a pending GET_WORK. */ 450 uint64_t pend_new_work:1; 451 /* 452 * When pend_new_work is set, this bit indicates that 453 * the wait bit was set. 454 */ 455 uint64_t pend_new_work_wait:1; 456 /* Set when there is a pending NULL_RD. */ 457 uint64_t pend_null_rd:1; 458 /* Set when there is a pending CLR_NSCHED. */ 459 uint64_t pend_nosched_clr:1; 460 uint64_t reserved_51:1; 461 /* This is the index when pend_nosched_clr is set. */ 462 uint64_t pend_index:11; 463 /* 464 * This is the new_grp when (pend_desched AND 465 * pend_desched_switch) is set. 466 */ 467 uint64_t pend_grp:4; 468 uint64_t reserved_34_35:2; 469 /* 470 * This is the tag type when pend_switch or 471 * (pend_desched AND pend_desched_switch) are set. 472 */ 473 uint64_t pend_type:2; 474 /* 475 * - this is the tag when pend_switch or (pend_desched 476 * AND pend_desched_switch) are set. 477 */ 478 uint64_t pend_tag:32; 479 } s_sstatus0; 480 481 /** 482 * Result for a POW Status Load (when get_cur==0 and get_wqp==1) 483 */ 484 struct { 485 uint64_t reserved_62_63:2; 486 /* 487 * Set when there is a pending non-NULL SWTAG or 488 * SWTAG_FULL, and the POW entry has not left the list 489 * for the original tag. 490 */ 491 uint64_t pend_switch:1; 492 /* Set when SWTAG_FULL and pend_switch is set. */ 493 uint64_t pend_switch_full:1; 494 /* 495 * Set when there is a pending NULL SWTAG, or an 496 * implicit switch to NULL. 497 */ 498 uint64_t pend_switch_null:1; 499 /* 500 * Set when there is a pending DESCHED or 501 * SWTAG_DESCHED. 502 */ 503 uint64_t pend_desched:1; 504 /* 505 * Set when there is a pending SWTAG_DESCHED and 506 * pend_desched is set. 507 */ 508 uint64_t pend_desched_switch:1; 509 /* Set when nosched is desired and pend_desched is set. */ 510 uint64_t pend_nosched:1; 511 /* Set when there is a pending GET_WORK. */ 512 uint64_t pend_new_work:1; 513 /* 514 * When pend_new_work is set, this bit indicates that 515 * the wait bit was set. 516 */ 517 uint64_t pend_new_work_wait:1; 518 /* Set when there is a pending NULL_RD. */ 519 uint64_t pend_null_rd:1; 520 /* Set when there is a pending CLR_NSCHED. */ 521 uint64_t pend_nosched_clr:1; 522 uint64_t reserved_51:1; 523 /* This is the index when pend_nosched_clr is set. */ 524 uint64_t pend_index:11; 525 /* 526 * This is the new_grp when (pend_desched AND 527 * pend_desched_switch) is set. 528 */ 529 uint64_t pend_grp:4; 530 /* This is the wqp when pend_nosched_clr is set. */ 531 uint64_t pend_wqp:36; 532 } s_sstatus1; 533 534 /** 535 * Result for a POW Status Load (when get_cur==1, get_wqp==0, and 536 * get_rev==0) 537 */ 538 struct { 539 uint64_t reserved_62_63:2; 540 /* 541 * Points to the next POW entry in the tag list when 542 * tail == 0 (and tag_type is not NULL or NULL_NULL). 543 */ 544 uint64_t link_index:11; 545 /* The POW entry attached to the core. */ 546 uint64_t index:11; 547 /* 548 * The group attached to the core (updated when new 549 * tag list entered on SWTAG_FULL). 550 */ 551 uint64_t grp:4; 552 /* 553 * Set when this POW entry is at the head of its tag 554 * list (also set when in the NULL or NULL_NULL 555 * state). 556 */ 557 uint64_t head:1; 558 /* 559 * Set when this POW entry is at the tail of its tag 560 * list (also set when in the NULL or NULL_NULL 561 * state). 562 */ 563 uint64_t tail:1; 564 /* 565 * The tag type attached to the core (updated when new 566 * tag list entered on SWTAG, SWTAG_FULL, or 567 * SWTAG_DESCHED). 568 */ 569 uint64_t tag_type:2; 570 /* 571 * The tag attached to the core (updated when new tag 572 * list entered on SWTAG, SWTAG_FULL, or 573 * SWTAG_DESCHED). 574 */ 575 uint64_t tag:32; 576 } s_sstatus2; 577 578 /** 579 * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1) 580 */ 581 struct { 582 uint64_t reserved_62_63:2; 583 /* 584 * Points to the prior POW entry in the tag list when 585 * head == 0 (and tag_type is not NULL or 586 * NULL_NULL). This field is unpredictable when the 587 * core's state is NULL or NULL_NULL. 588 */ 589 uint64_t revlink_index:11; 590 /* The POW entry attached to the core. */ 591 uint64_t index:11; 592 /* 593 * The group attached to the core (updated when new 594 * tag list entered on SWTAG_FULL). 595 */ 596 uint64_t grp:4; 597 /* Set when this POW entry is at the head of its tag 598 * list (also set when in the NULL or NULL_NULL 599 * state). 600 */ 601 uint64_t head:1; 602 /* 603 * Set when this POW entry is at the tail of its tag 604 * list (also set when in the NULL or NULL_NULL 605 * state). 606 */ 607 uint64_t tail:1; 608 /* 609 * The tag type attached to the core (updated when new 610 * tag list entered on SWTAG, SWTAG_FULL, or 611 * SWTAG_DESCHED). 612 */ 613 uint64_t tag_type:2; 614 /* 615 * The tag attached to the core (updated when new tag 616 * list entered on SWTAG, SWTAG_FULL, or 617 * SWTAG_DESCHED). 618 */ 619 uint64_t tag:32; 620 } s_sstatus3; 621 622 /** 623 * Result for a POW Status Load (when get_cur==1, get_wqp==1, and 624 * get_rev==0) 625 */ 626 struct { 627 uint64_t reserved_62_63:2; 628 /* 629 * Points to the next POW entry in the tag list when 630 * tail == 0 (and tag_type is not NULL or NULL_NULL). 631 */ 632 uint64_t link_index:11; 633 /* The POW entry attached to the core. */ 634 uint64_t index:11; 635 /* 636 * The group attached to the core (updated when new 637 * tag list entered on SWTAG_FULL). 638 */ 639 uint64_t grp:4; 640 /* 641 * The wqp attached to the core (updated when new tag 642 * list entered on SWTAG_FULL). 643 */ 644 uint64_t wqp:36; 645 } s_sstatus4; 646 647 /** 648 * Result for a POW Status Load (when get_cur==1, get_wqp==1, and 649 * get_rev==1) 650 */ 651 struct { 652 uint64_t reserved_62_63:2; 653 /* 654 * Points to the prior POW entry in the tag list when 655 * head == 0 (and tag_type is not NULL or 656 * NULL_NULL). This field is unpredictable when the 657 * core's state is NULL or NULL_NULL. 658 */ 659 uint64_t revlink_index:11; 660 /* The POW entry attached to the core. */ 661 uint64_t index:11; 662 /* 663 * The group attached to the core (updated when new 664 * tag list entered on SWTAG_FULL). 665 */ 666 uint64_t grp:4; 667 /* 668 * The wqp attached to the core (updated when new tag 669 * list entered on SWTAG_FULL). 670 */ 671 uint64_t wqp:36; 672 } s_sstatus5; 673 674 /** 675 * Result For POW Memory Load (get_des == 0 and get_wqp == 0) 676 */ 677 struct { 678 uint64_t reserved_51_63:13; 679 /* 680 * The next entry in the input, free, descheduled_head 681 * list (unpredictable if entry is the tail of the 682 * list). 683 */ 684 uint64_t next_index:11; 685 /* The group of the POW entry. */ 686 uint64_t grp:4; 687 uint64_t reserved_35:1; 688 /* 689 * Set when this POW entry is at the tail of its tag 690 * list (also set when in the NULL or NULL_NULL 691 * state). 692 */ 693 uint64_t tail:1; 694 /* The tag type of the POW entry. */ 695 uint64_t tag_type:2; 696 /* The tag of the POW entry. */ 697 uint64_t tag:32; 698 } s_smemload0; 699 700 /** 701 * Result For POW Memory Load (get_des == 0 and get_wqp == 1) 702 */ 703 struct { 704 uint64_t reserved_51_63:13; 705 /* 706 * The next entry in the input, free, descheduled_head 707 * list (unpredictable if entry is the tail of the 708 * list). 709 */ 710 uint64_t next_index:11; 711 /* The group of the POW entry. */ 712 uint64_t grp:4; 713 /* The WQP held in the POW entry. */ 714 uint64_t wqp:36; 715 } s_smemload1; 716 717 /** 718 * Result For POW Memory Load (get_des == 1) 719 */ 720 struct { 721 uint64_t reserved_51_63:13; 722 /* 723 * The next entry in the tag list connected to the 724 * descheduled head. 725 */ 726 uint64_t fwd_index:11; 727 /* The group of the POW entry. */ 728 uint64_t grp:4; 729 /* The nosched bit for the POW entry. */ 730 uint64_t nosched:1; 731 /* There is a pending tag switch */ 732 uint64_t pend_switch:1; 733 /* 734 * The next tag type for the new tag list when 735 * pend_switch is set. 736 */ 737 uint64_t pend_type:2; 738 /* 739 * The next tag for the new tag list when pend_switch 740 * is set. 741 */ 742 uint64_t pend_tag:32; 743 } s_smemload2; 744 745 /** 746 * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0) 747 */ 748 struct { 749 uint64_t reserved_52_63:12; 750 /* 751 * set when there is one or more POW entries on the 752 * free list. 753 */ 754 uint64_t free_val:1; 755 /* 756 * set when there is exactly one POW entry on the free 757 * list. 758 */ 759 uint64_t free_one:1; 760 uint64_t reserved_49:1; 761 /* 762 * when free_val is set, indicates the first entry on 763 * the free list. 764 */ 765 uint64_t free_head:11; 766 uint64_t reserved_37:1; 767 /* 768 * when free_val is set, indicates the last entry on 769 * the free list. 770 */ 771 uint64_t free_tail:11; 772 /* 773 * set when there is one or more POW entries on the 774 * input Q list selected by qosgrp. 775 */ 776 uint64_t loc_val:1; 777 /* 778 * set when there is exactly one POW entry on the 779 * input Q list selected by qosgrp. 780 */ 781 uint64_t loc_one:1; 782 uint64_t reserved_23:1; 783 /* 784 * when loc_val is set, indicates the first entry on 785 * the input Q list selected by qosgrp. 786 */ 787 uint64_t loc_head:11; 788 uint64_t reserved_11:1; 789 /* 790 * when loc_val is set, indicates the last entry on 791 * the input Q list selected by qosgrp. 792 */ 793 uint64_t loc_tail:11; 794 } sindexload0; 795 796 /** 797 * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1) 798 */ 799 struct { 800 uint64_t reserved_52_63:12; 801 /* 802 * set when there is one or more POW entries on the 803 * nosched list. 804 */ 805 uint64_t nosched_val:1; 806 /* 807 * set when there is exactly one POW entry on the 808 * nosched list. 809 */ 810 uint64_t nosched_one:1; 811 uint64_t reserved_49:1; 812 /* 813 * when nosched_val is set, indicates the first entry 814 * on the nosched list. 815 */ 816 uint64_t nosched_head:11; 817 uint64_t reserved_37:1; 818 /* 819 * when nosched_val is set, indicates the last entry 820 * on the nosched list. 821 */ 822 uint64_t nosched_tail:11; 823 /* 824 * set when there is one or more descheduled heads on 825 * the descheduled list selected by qosgrp. 826 */ 827 uint64_t des_val:1; 828 /* 829 * set when there is exactly one descheduled head on 830 * the descheduled list selected by qosgrp. 831 */ 832 uint64_t des_one:1; 833 uint64_t reserved_23:1; 834 /* 835 * when des_val is set, indicates the first 836 * descheduled head on the descheduled list selected 837 * by qosgrp. 838 */ 839 uint64_t des_head:11; 840 uint64_t reserved_11:1; 841 /* 842 * when des_val is set, indicates the last descheduled 843 * head on the descheduled list selected by qosgrp. 844 */ 845 uint64_t des_tail:11; 846 } sindexload1; 847 848 /** 849 * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0) 850 */ 851 struct { 852 uint64_t reserved_39_63:25; 853 /* 854 * Set when this DRAM list is the current head 855 * (i.e. is the next to be reloaded when the POW 856 * hardware reloads a POW entry from DRAM). The POW 857 * hardware alternates between the two DRAM lists 858 * associated with a QOS level when it reloads work 859 * from DRAM into the POW unit. 860 */ 861 uint64_t rmt_is_head:1; 862 /* 863 * Set when the DRAM portion of the input Q list 864 * selected by qosgrp contains one or more pieces of 865 * work. 866 */ 867 uint64_t rmt_val:1; 868 /* 869 * Set when the DRAM portion of the input Q list 870 * selected by qosgrp contains exactly one piece of 871 * work. 872 */ 873 uint64_t rmt_one:1; 874 /* 875 * When rmt_val is set, indicates the first piece of 876 * work on the DRAM input Q list selected by 877 * qosgrp. 878 */ 879 uint64_t rmt_head:36; 880 } sindexload2; 881 882 /** 883 * Result For POW Index/Pointer Load (get_rmt == 884 * 1/get_des_get_tail == 1) 885 */ 886 struct { 887 uint64_t reserved_39_63:25; 888 /* 889 * set when this DRAM list is the current head 890 * (i.e. is the next to be reloaded when the POW 891 * hardware reloads a POW entry from DRAM). The POW 892 * hardware alternates between the two DRAM lists 893 * associated with a QOS level when it reloads work 894 * from DRAM into the POW unit. 895 */ 896 uint64_t rmt_is_head:1; 897 /* 898 * set when the DRAM portion of the input Q list 899 * selected by qosgrp contains one or more pieces of 900 * work. 901 */ 902 uint64_t rmt_val:1; 903 /* 904 * set when the DRAM portion of the input Q list 905 * selected by qosgrp contains exactly one piece of 906 * work. 907 */ 908 uint64_t rmt_one:1; 909 /* 910 * when rmt_val is set, indicates the last piece of 911 * work on the DRAM input Q list selected by 912 * qosgrp. 913 */ 914 uint64_t rmt_tail:36; 915 } sindexload3; 916 917 /** 918 * Response to NULL_RD request loads 919 */ 920 struct { 921 uint64_t unused:62; 922 /* of type cvmx_pow_tag_type_t. state is one of the 923 * following: 924 * 925 * - CVMX_POW_TAG_TYPE_ORDERED 926 * - CVMX_POW_TAG_TYPE_ATOMIC 927 * - CVMX_POW_TAG_TYPE_NULL 928 * - CVMX_POW_TAG_TYPE_NULL_NULL 929 */ 930 uint64_t state:2; 931 } s_null_rd; 932 933 } cvmx_pow_tag_load_resp_t; 934 935 /** 936 * This structure describes the address used for stores to the POW. 937 * The store address is meaningful on stores to the POW. The 938 * hardware assumes that an aligned 64-bit store was used for all 939 * these stores. Note the assumption that the work queue entry is 940 * aligned on an 8-byte boundary (since the low-order 3 address bits 941 * must be zero). Note that not all fields are used by all 942 * operations. 943 * 944 * NOTE: The following is the behavior of the pending switch bit at the PP 945 * for POW stores (i.e. when did<7:3> == 0xc) 946 * - did<2:0> == 0 => pending switch bit is set 947 * - did<2:0> == 1 => no affect on the pending switch bit 948 * - did<2:0> == 3 => pending switch bit is cleared 949 * - did<2:0> == 7 => no affect on the pending switch bit 950 * - did<2:0> == others => must not be used 951 * - No other loads/stores have an affect on the pending switch bit 952 * - The switch bus from POW can clear the pending switch bit 953 * 954 * NOTE: did<2:0> == 2 is used by the HW for a special single-cycle 955 * ADDWQ command that only contains the pointer). SW must never use 956 * did<2:0> == 2. 957 */ 958 typedef union { 959 /** 960 * Unsigned 64 bit integer representation of store address 961 */ 962 uint64_t u64; 963 964 struct { 965 /* Memory region. Should be CVMX_IO_SEG in most cases */ 966 uint64_t mem_reg:2; 967 uint64_t reserved_49_61:13; /* Must be zero */ 968 uint64_t is_io:1; /* Must be one */ 969 /* Device ID of POW. Note that different sub-dids are used. */ 970 uint64_t did:8; 971 uint64_t reserved_36_39:4; /* Must be zero */ 972 /* Address field. addr<2:0> must be zero */ 973 uint64_t addr:36; 974 } stag; 975 } cvmx_pow_tag_store_addr_t; 976 977 /** 978 * decode of the store data when an IOBDMA SENDSINGLE is sent to POW 979 */ 980 typedef union { 981 uint64_t u64; 982 983 struct { 984 /* 985 * the (64-bit word) location in scratchpad to write 986 * to (if len != 0) 987 */ 988 uint64_t scraddr:8; 989 /* the number of words in the response (0 => no response) */ 990 uint64_t len:8; 991 /* the ID of the device on the non-coherent bus */ 992 uint64_t did:8; 993 uint64_t unused:36; 994 /* if set, don't return load response until work is available */ 995 uint64_t wait:1; 996 uint64_t unused2:3; 997 } s; 998 999 } cvmx_pow_iobdma_store_t; 1000 1001 /* CSR typedefs have been moved to cvmx-csr-*.h */ 1002 1003 /** 1004 * Get the POW tag for this core. This returns the current 1005 * tag type, tag, group, and POW entry index associated with 1006 * this core. Index is only valid if the tag type isn't NULL_NULL. 1007 * If a tag switch is pending this routine returns the tag before 1008 * the tag switch, not after. 1009 * 1010 * Returns Current tag 1011 */ 1012 static inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void) 1013 { 1014 cvmx_pow_load_addr_t load_addr; 1015 cvmx_pow_tag_load_resp_t load_resp; 1016 cvmx_pow_tag_req_t result; 1017 1018 load_addr.u64 = 0; 1019 load_addr.sstatus.mem_region = CVMX_IO_SEG; 1020 load_addr.sstatus.is_io = 1; 1021 load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1; 1022 load_addr.sstatus.coreid = cvmx_get_core_num(); 1023 load_addr.sstatus.get_cur = 1; 1024 load_resp.u64 = cvmx_read_csr(load_addr.u64); 1025 result.u64 = 0; 1026 result.s.grp = load_resp.s_sstatus2.grp; 1027 result.s.index = load_resp.s_sstatus2.index; 1028 result.s.type = load_resp.s_sstatus2.tag_type; 1029 result.s.tag = load_resp.s_sstatus2.tag; 1030 return result; 1031 } 1032 1033 /** 1034 * Get the POW WQE for this core. This returns the work queue 1035 * entry currently associated with this core. 1036 * 1037 * Returns WQE pointer 1038 */ 1039 static inline cvmx_wqe_t *cvmx_pow_get_current_wqp(void) 1040 { 1041 cvmx_pow_load_addr_t load_addr; 1042 cvmx_pow_tag_load_resp_t load_resp; 1043 1044 load_addr.u64 = 0; 1045 load_addr.sstatus.mem_region = CVMX_IO_SEG; 1046 load_addr.sstatus.is_io = 1; 1047 load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1; 1048 load_addr.sstatus.coreid = cvmx_get_core_num(); 1049 load_addr.sstatus.get_cur = 1; 1050 load_addr.sstatus.get_wqp = 1; 1051 load_resp.u64 = cvmx_read_csr(load_addr.u64); 1052 return (cvmx_wqe_t *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp); 1053 } 1054 1055 #ifndef CVMX_MF_CHORD 1056 #define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30) 1057 #endif 1058 1059 /** 1060 * Print a warning if a tag switch is pending for this core 1061 * 1062 * @function: Function name checking for a pending tag switch 1063 */ 1064 static inline void __cvmx_pow_warn_if_pending_switch(const char *function) 1065 { 1066 uint64_t switch_complete; 1067 CVMX_MF_CHORD(switch_complete); 1068 if (!switch_complete) 1069 pr_warn("%s called with tag switch in progress\n", function); 1070 } 1071 1072 /** 1073 * Waits for a tag switch to complete by polling the completion bit. 1074 * Note that switches to NULL complete immediately and do not need 1075 * to be waited for. 1076 */ 1077 static inline void cvmx_pow_tag_sw_wait(void) 1078 { 1079 const uint64_t MAX_CYCLES = 1ull << 31; 1080 uint64_t switch_complete; 1081 uint64_t start_cycle = cvmx_get_cycle(); 1082 while (1) { 1083 CVMX_MF_CHORD(switch_complete); 1084 if (unlikely(switch_complete)) 1085 break; 1086 if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { 1087 pr_warn("Tag switch is taking a long time, possible deadlock\n"); 1088 start_cycle = -MAX_CYCLES - 1; 1089 } 1090 } 1091 } 1092 1093 /** 1094 * Synchronous work request. Requests work from the POW. 1095 * This function does NOT wait for previous tag switches to complete, 1096 * so the caller must ensure that there is not a pending tag switch. 1097 * 1098 * @wait: When set, call stalls until work becomes avaiable, or times out. 1099 * If not set, returns immediately. 1100 * 1101 * Returns Returns the WQE pointer from POW. Returns NULL if no work 1102 * was available. 1103 */ 1104 static inline cvmx_wqe_t *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t 1105 wait) 1106 { 1107 cvmx_pow_load_addr_t ptr; 1108 cvmx_pow_tag_load_resp_t result; 1109 1110 if (CVMX_ENABLE_POW_CHECKS) 1111 __cvmx_pow_warn_if_pending_switch(__func__); 1112 1113 ptr.u64 = 0; 1114 ptr.swork.mem_region = CVMX_IO_SEG; 1115 ptr.swork.is_io = 1; 1116 ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG; 1117 ptr.swork.wait = wait; 1118 1119 result.u64 = cvmx_read_csr(ptr.u64); 1120 1121 if (result.s_work.no_work) 1122 return NULL; 1123 else 1124 return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr); 1125 } 1126 1127 /** 1128 * Synchronous work request. Requests work from the POW. 1129 * This function waits for any previous tag switch to complete before 1130 * requesting the new work. 1131 * 1132 * @wait: When set, call stalls until work becomes avaiable, or times out. 1133 * If not set, returns immediately. 1134 * 1135 * Returns Returns the WQE pointer from POW. Returns NULL if no work 1136 * was available. 1137 */ 1138 static inline cvmx_wqe_t *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait) 1139 { 1140 if (CVMX_ENABLE_POW_CHECKS) 1141 __cvmx_pow_warn_if_pending_switch(__func__); 1142 1143 /* Must not have a switch pending when requesting work */ 1144 cvmx_pow_tag_sw_wait(); 1145 return cvmx_pow_work_request_sync_nocheck(wait); 1146 1147 } 1148 1149 /** 1150 * Synchronous null_rd request. Requests a switch out of NULL_NULL POW state. 1151 * This function waits for any previous tag switch to complete before 1152 * requesting the null_rd. 1153 * 1154 * Returns Returns the POW state of type cvmx_pow_tag_type_t. 1155 */ 1156 static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void) 1157 { 1158 cvmx_pow_load_addr_t ptr; 1159 cvmx_pow_tag_load_resp_t result; 1160 1161 if (CVMX_ENABLE_POW_CHECKS) 1162 __cvmx_pow_warn_if_pending_switch(__func__); 1163 1164 /* Must not have a switch pending when requesting work */ 1165 cvmx_pow_tag_sw_wait(); 1166 1167 ptr.u64 = 0; 1168 ptr.snull_rd.mem_region = CVMX_IO_SEG; 1169 ptr.snull_rd.is_io = 1; 1170 ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD; 1171 1172 result.u64 = cvmx_read_csr(ptr.u64); 1173 1174 return (enum cvmx_pow_tag_type) result.s_null_rd.state; 1175 } 1176 1177 /** 1178 * Asynchronous work request. Work is requested from the POW unit, 1179 * and should later be checked with function 1180 * cvmx_pow_work_response_async. This function does NOT wait for 1181 * previous tag switches to complete, so the caller must ensure that 1182 * there is not a pending tag switch. 1183 * 1184 * @scr_addr: Scratch memory address that response will be returned 1185 * to, which is either a valid WQE, or a response with the 1186 * invalid bit set. Byte address, must be 8 byte aligned. 1187 * 1188 * @wait: 1 to cause response to wait for work to become available (or 1189 * timeout), 0 to cause response to return immediately 1190 */ 1191 static inline void cvmx_pow_work_request_async_nocheck(int scr_addr, 1192 cvmx_pow_wait_t wait) 1193 { 1194 cvmx_pow_iobdma_store_t data; 1195 1196 if (CVMX_ENABLE_POW_CHECKS) 1197 __cvmx_pow_warn_if_pending_switch(__func__); 1198 1199 /* scr_addr must be 8 byte aligned */ 1200 data.s.scraddr = scr_addr >> 3; 1201 data.s.len = 1; 1202 data.s.did = CVMX_OCT_DID_TAG_SWTAG; 1203 data.s.wait = wait; 1204 cvmx_send_single(data.u64); 1205 } 1206 1207 /** 1208 * Asynchronous work request. Work is requested from the POW unit, 1209 * and should later be checked with function 1210 * cvmx_pow_work_response_async. This function waits for any previous 1211 * tag switch to complete before requesting the new work. 1212 * 1213 * @scr_addr: Scratch memory address that response will be returned 1214 * to, which is either a valid WQE, or a response with the 1215 * invalid bit set. Byte address, must be 8 byte aligned. 1216 * 1217 * @wait: 1 to cause response to wait for work to become available (or 1218 * timeout), 0 to cause response to return immediately 1219 */ 1220 static inline void cvmx_pow_work_request_async(int scr_addr, 1221 cvmx_pow_wait_t wait) 1222 { 1223 if (CVMX_ENABLE_POW_CHECKS) 1224 __cvmx_pow_warn_if_pending_switch(__func__); 1225 1226 /* Must not have a switch pending when requesting work */ 1227 cvmx_pow_tag_sw_wait(); 1228 cvmx_pow_work_request_async_nocheck(scr_addr, wait); 1229 } 1230 1231 /** 1232 * Gets result of asynchronous work request. Performs a IOBDMA sync 1233 * to wait for the response. 1234 * 1235 * @scr_addr: Scratch memory address to get result from Byte address, 1236 * must be 8 byte aligned. 1237 * 1238 * Returns Returns the WQE from the scratch register, or NULL if no 1239 * work was available. 1240 */ 1241 static inline cvmx_wqe_t *cvmx_pow_work_response_async(int scr_addr) 1242 { 1243 cvmx_pow_tag_load_resp_t result; 1244 1245 CVMX_SYNCIOBDMA; 1246 result.u64 = cvmx_scratch_read64(scr_addr); 1247 1248 if (result.s_work.no_work) 1249 return NULL; 1250 else 1251 return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr); 1252 } 1253 1254 /** 1255 * Checks if a work queue entry pointer returned by a work 1256 * request is valid. It may be invalid due to no work 1257 * being available or due to a timeout. 1258 * 1259 * @wqe_ptr: pointer to a work queue entry returned by the POW 1260 * 1261 * Returns 0 if pointer is valid 1262 * 1 if invalid (no work was returned) 1263 */ 1264 static inline uint64_t cvmx_pow_work_invalid(cvmx_wqe_t *wqe_ptr) 1265 { 1266 return wqe_ptr == NULL; 1267 } 1268 1269 /** 1270 * Starts a tag switch to the provided tag value and tag type. 1271 * Completion for the tag switch must be checked for separately. This 1272 * function does NOT update the work queue entry in dram to match tag 1273 * value and type, so the application must keep track of these if they 1274 * are important to the application. This tag switch command must not 1275 * be used for switches to NULL, as the tag switch pending bit will be 1276 * set by the switch request, but never cleared by the hardware. 1277 * 1278 * NOTE: This should not be used when switching from a NULL tag. Use 1279 * cvmx_pow_tag_sw_full() instead. 1280 * 1281 * This function does no checks, so the caller must ensure that any 1282 * previous tag switch has completed. 1283 * 1284 * @tag: new tag value 1285 * @tag_type: new tag type (ordered or atomic) 1286 */ 1287 static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag, 1288 enum cvmx_pow_tag_type tag_type) 1289 { 1290 cvmx_addr_t ptr; 1291 cvmx_pow_tag_req_t tag_req; 1292 1293 if (CVMX_ENABLE_POW_CHECKS) { 1294 cvmx_pow_tag_req_t current_tag; 1295 __cvmx_pow_warn_if_pending_switch(__func__); 1296 current_tag = cvmx_pow_get_current_tag(); 1297 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1298 pr_warn("%s called with NULL_NULL tag\n", __func__); 1299 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1300 pr_warn("%s called with NULL tag\n", __func__); 1301 if ((current_tag.s.type == tag_type) 1302 && (current_tag.s.tag == tag)) 1303 pr_warn("%s called to perform a tag switch to the same tag\n", 1304 __func__); 1305 if (tag_type == CVMX_POW_TAG_TYPE_NULL) 1306 pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", 1307 __func__); 1308 } 1309 1310 /* 1311 * Note that WQE in DRAM is not updated here, as the POW does 1312 * not read from DRAM once the WQE is in flight. See hardware 1313 * manual for complete details. It is the application's 1314 * responsibility to keep track of the current tag value if 1315 * that is important. 1316 */ 1317 1318 tag_req.u64 = 0; 1319 tag_req.s.op = CVMX_POW_TAG_OP_SWTAG; 1320 tag_req.s.tag = tag; 1321 tag_req.s.type = tag_type; 1322 1323 ptr.u64 = 0; 1324 ptr.sio.mem_region = CVMX_IO_SEG; 1325 ptr.sio.is_io = 1; 1326 ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG; 1327 1328 /* once this store arrives at POW, it will attempt the switch 1329 software must wait for the switch to complete separately */ 1330 cvmx_write_io(ptr.u64, tag_req.u64); 1331 } 1332 1333 /** 1334 * Starts a tag switch to the provided tag value and tag type. 1335 * Completion for the tag switch must be checked for separately. This 1336 * function does NOT update the work queue entry in dram to match tag 1337 * value and type, so the application must keep track of these if they 1338 * are important to the application. This tag switch command must not 1339 * be used for switches to NULL, as the tag switch pending bit will be 1340 * set by the switch request, but never cleared by the hardware. 1341 * 1342 * NOTE: This should not be used when switching from a NULL tag. Use 1343 * cvmx_pow_tag_sw_full() instead. 1344 * 1345 * This function waits for any previous tag switch to complete, and also 1346 * displays an error on tag switches to NULL. 1347 * 1348 * @tag: new tag value 1349 * @tag_type: new tag type (ordered or atomic) 1350 */ 1351 static inline void cvmx_pow_tag_sw(uint32_t tag, 1352 enum cvmx_pow_tag_type tag_type) 1353 { 1354 if (CVMX_ENABLE_POW_CHECKS) 1355 __cvmx_pow_warn_if_pending_switch(__func__); 1356 1357 /* 1358 * Note that WQE in DRAM is not updated here, as the POW does 1359 * not read from DRAM once the WQE is in flight. See hardware 1360 * manual for complete details. It is the application's 1361 * responsibility to keep track of the current tag value if 1362 * that is important. 1363 */ 1364 1365 /* 1366 * Ensure that there is not a pending tag switch, as a tag 1367 * switch cannot be started if a previous switch is still 1368 * pending. 1369 */ 1370 cvmx_pow_tag_sw_wait(); 1371 cvmx_pow_tag_sw_nocheck(tag, tag_type); 1372 } 1373 1374 /** 1375 * Starts a tag switch to the provided tag value and tag type. 1376 * Completion for the tag switch must be checked for separately. This 1377 * function does NOT update the work queue entry in dram to match tag 1378 * value and type, so the application must keep track of these if they 1379 * are important to the application. This tag switch command must not 1380 * be used for switches to NULL, as the tag switch pending bit will be 1381 * set by the switch request, but never cleared by the hardware. 1382 * 1383 * This function must be used for tag switches from NULL. 1384 * 1385 * This function does no checks, so the caller must ensure that any 1386 * previous tag switch has completed. 1387 * 1388 * @wqp: pointer to work queue entry to submit. This entry is 1389 * updated to match the other parameters 1390 * @tag: tag value to be assigned to work queue entry 1391 * @tag_type: type of tag 1392 * @group: group value for the work queue entry. 1393 */ 1394 static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag, 1395 enum cvmx_pow_tag_type tag_type, 1396 uint64_t group) 1397 { 1398 cvmx_addr_t ptr; 1399 cvmx_pow_tag_req_t tag_req; 1400 1401 if (CVMX_ENABLE_POW_CHECKS) { 1402 cvmx_pow_tag_req_t current_tag; 1403 __cvmx_pow_warn_if_pending_switch(__func__); 1404 current_tag = cvmx_pow_get_current_tag(); 1405 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1406 pr_warn("%s called with NULL_NULL tag\n", __func__); 1407 if ((current_tag.s.type == tag_type) 1408 && (current_tag.s.tag == tag)) 1409 pr_warn("%s called to perform a tag switch to the same tag\n", 1410 __func__); 1411 if (tag_type == CVMX_POW_TAG_TYPE_NULL) 1412 pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", 1413 __func__); 1414 if (wqp != cvmx_phys_to_ptr(0x80)) 1415 if (wqp != cvmx_pow_get_current_wqp()) 1416 pr_warn("%s passed WQE(%p) doesn't match the address in the POW(%p)\n", 1417 __func__, wqp, 1418 cvmx_pow_get_current_wqp()); 1419 } 1420 1421 /* 1422 * Note that WQE in DRAM is not updated here, as the POW does 1423 * not read from DRAM once the WQE is in flight. See hardware 1424 * manual for complete details. It is the application's 1425 * responsibility to keep track of the current tag value if 1426 * that is important. 1427 */ 1428 1429 tag_req.u64 = 0; 1430 tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL; 1431 tag_req.s.tag = tag; 1432 tag_req.s.type = tag_type; 1433 tag_req.s.grp = group; 1434 1435 ptr.u64 = 0; 1436 ptr.sio.mem_region = CVMX_IO_SEG; 1437 ptr.sio.is_io = 1; 1438 ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG; 1439 ptr.sio.offset = CAST64(wqp); 1440 1441 /* 1442 * once this store arrives at POW, it will attempt the switch 1443 * software must wait for the switch to complete separately. 1444 */ 1445 cvmx_write_io(ptr.u64, tag_req.u64); 1446 } 1447 1448 /** 1449 * Starts a tag switch to the provided tag value and tag type. 1450 * Completion for the tag switch must be checked for separately. This 1451 * function does NOT update the work queue entry in dram to match tag 1452 * value and type, so the application must keep track of these if they 1453 * are important to the application. This tag switch command must not 1454 * be used for switches to NULL, as the tag switch pending bit will be 1455 * set by the switch request, but never cleared by the hardware. 1456 * 1457 * This function must be used for tag switches from NULL. 1458 * 1459 * This function waits for any pending tag switches to complete 1460 * before requesting the tag switch. 1461 * 1462 * @wqp: pointer to work queue entry to submit. This entry is updated 1463 * to match the other parameters 1464 * @tag: tag value to be assigned to work queue entry 1465 * @tag_type: type of tag 1466 * @group: group value for the work queue entry. 1467 */ 1468 static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag, 1469 enum cvmx_pow_tag_type tag_type, 1470 uint64_t group) 1471 { 1472 if (CVMX_ENABLE_POW_CHECKS) 1473 __cvmx_pow_warn_if_pending_switch(__func__); 1474 1475 /* 1476 * Ensure that there is not a pending tag switch, as a tag 1477 * switch cannot be started if a previous switch is still 1478 * pending. 1479 */ 1480 cvmx_pow_tag_sw_wait(); 1481 cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group); 1482 } 1483 1484 /** 1485 * Switch to a NULL tag, which ends any ordering or 1486 * synchronization provided by the POW for the current 1487 * work queue entry. This operation completes immediately, 1488 * so completion should not be waited for. 1489 * This function does NOT wait for previous tag switches to complete, 1490 * so the caller must ensure that any previous tag switches have completed. 1491 */ 1492 static inline void cvmx_pow_tag_sw_null_nocheck(void) 1493 { 1494 cvmx_addr_t ptr; 1495 cvmx_pow_tag_req_t tag_req; 1496 1497 if (CVMX_ENABLE_POW_CHECKS) { 1498 cvmx_pow_tag_req_t current_tag; 1499 __cvmx_pow_warn_if_pending_switch(__func__); 1500 current_tag = cvmx_pow_get_current_tag(); 1501 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1502 pr_warn("%s called with NULL_NULL tag\n", __func__); 1503 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1504 pr_warn("%s called when we already have a NULL tag\n", 1505 __func__); 1506 } 1507 1508 tag_req.u64 = 0; 1509 tag_req.s.op = CVMX_POW_TAG_OP_SWTAG; 1510 tag_req.s.type = CVMX_POW_TAG_TYPE_NULL; 1511 1512 ptr.u64 = 0; 1513 ptr.sio.mem_region = CVMX_IO_SEG; 1514 ptr.sio.is_io = 1; 1515 ptr.sio.did = CVMX_OCT_DID_TAG_TAG1; 1516 1517 cvmx_write_io(ptr.u64, tag_req.u64); 1518 1519 /* switch to NULL completes immediately */ 1520 } 1521 1522 /** 1523 * Switch to a NULL tag, which ends any ordering or 1524 * synchronization provided by the POW for the current 1525 * work queue entry. This operation completes immediately, 1526 * so completion should not be waited for. 1527 * This function waits for any pending tag switches to complete 1528 * before requesting the switch to NULL. 1529 */ 1530 static inline void cvmx_pow_tag_sw_null(void) 1531 { 1532 if (CVMX_ENABLE_POW_CHECKS) 1533 __cvmx_pow_warn_if_pending_switch(__func__); 1534 1535 /* 1536 * Ensure that there is not a pending tag switch, as a tag 1537 * switch cannot be started if a previous switch is still 1538 * pending. 1539 */ 1540 cvmx_pow_tag_sw_wait(); 1541 cvmx_pow_tag_sw_null_nocheck(); 1542 1543 /* switch to NULL completes immediately */ 1544 } 1545 1546 /** 1547 * Submits work to an input queue. This function updates the work 1548 * queue entry in DRAM to match the arguments given. Note that the 1549 * tag provided is for the work queue entry submitted, and is 1550 * unrelated to the tag that the core currently holds. 1551 * 1552 * @wqp: pointer to work queue entry to submit. This entry is 1553 * updated to match the other parameters 1554 * @tag: tag value to be assigned to work queue entry 1555 * @tag_type: type of tag 1556 * @qos: Input queue to add to. 1557 * @grp: group value for the work queue entry. 1558 */ 1559 static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag, 1560 enum cvmx_pow_tag_type tag_type, 1561 uint64_t qos, uint64_t grp) 1562 { 1563 cvmx_addr_t ptr; 1564 cvmx_pow_tag_req_t tag_req; 1565 1566 wqp->qos = qos; 1567 wqp->tag = tag; 1568 wqp->tag_type = tag_type; 1569 wqp->grp = grp; 1570 1571 tag_req.u64 = 0; 1572 tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ; 1573 tag_req.s.type = tag_type; 1574 tag_req.s.tag = tag; 1575 tag_req.s.qos = qos; 1576 tag_req.s.grp = grp; 1577 1578 ptr.u64 = 0; 1579 ptr.sio.mem_region = CVMX_IO_SEG; 1580 ptr.sio.is_io = 1; 1581 ptr.sio.did = CVMX_OCT_DID_TAG_TAG1; 1582 ptr.sio.offset = cvmx_ptr_to_phys(wqp); 1583 1584 /* 1585 * SYNC write to memory before the work submit. This is 1586 * necessary as POW may read values from DRAM at this time. 1587 */ 1588 CVMX_SYNCWS; 1589 cvmx_write_io(ptr.u64, tag_req.u64); 1590 } 1591 1592 /** 1593 * This function sets the group mask for a core. The group mask 1594 * indicates which groups each core will accept work from. There are 1595 * 16 groups. 1596 * 1597 * @core_num: core to apply mask to 1598 * @mask: Group mask. There are 16 groups, so only bits 0-15 are valid, 1599 * representing groups 0-15. 1600 * Each 1 bit in the mask enables the core to accept work from 1601 * the corresponding group. 1602 */ 1603 static inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask) 1604 { 1605 union cvmx_pow_pp_grp_mskx grp_msk; 1606 1607 grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num)); 1608 grp_msk.s.grp_msk = mask; 1609 cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64); 1610 } 1611 1612 /** 1613 * This function sets POW static priorities for a core. Each input queue has 1614 * an associated priority value. 1615 * 1616 * @core_num: core to apply priorities to 1617 * @priority: Vector of 8 priorities, one per POW Input Queue (0-7). 1618 * Highest priority is 0 and lowest is 7. A priority value 1619 * of 0xF instructs POW to skip the Input Queue when 1620 * scheduling to this specific core. 1621 * NOTE: priorities should not have gaps in values, meaning 1622 * {0,1,1,1,1,1,1,1} is a valid configuration while 1623 * {0,2,2,2,2,2,2,2} is not. 1624 */ 1625 static inline void cvmx_pow_set_priority(uint64_t core_num, 1626 const uint8_t priority[]) 1627 { 1628 /* POW priorities are supported on CN5xxx and later */ 1629 if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) { 1630 union cvmx_pow_pp_grp_mskx grp_msk; 1631 1632 grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num)); 1633 grp_msk.s.qos0_pri = priority[0]; 1634 grp_msk.s.qos1_pri = priority[1]; 1635 grp_msk.s.qos2_pri = priority[2]; 1636 grp_msk.s.qos3_pri = priority[3]; 1637 grp_msk.s.qos4_pri = priority[4]; 1638 grp_msk.s.qos5_pri = priority[5]; 1639 grp_msk.s.qos6_pri = priority[6]; 1640 grp_msk.s.qos7_pri = priority[7]; 1641 1642 /* Detect gaps between priorities and flag error */ 1643 { 1644 int i; 1645 uint32_t prio_mask = 0; 1646 1647 for (i = 0; i < 8; i++) 1648 if (priority[i] != 0xF) 1649 prio_mask |= 1 << priority[i]; 1650 1651 if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) { 1652 pr_err("POW static priorities should be " 1653 "contiguous (0x%llx)\n", 1654 (unsigned long long)prio_mask); 1655 return; 1656 } 1657 } 1658 1659 cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64); 1660 } 1661 } 1662 1663 /** 1664 * Performs a tag switch and then an immediate deschedule. This completes 1665 * immediately, so completion must not be waited for. This function does NOT 1666 * update the wqe in DRAM to match arguments. 1667 * 1668 * This function does NOT wait for any prior tag switches to complete, so the 1669 * calling code must do this. 1670 * 1671 * Note the following CAVEAT of the Octeon HW behavior when 1672 * re-scheduling DE-SCHEDULEd items whose (next) state is 1673 * ORDERED: 1674 * - If there are no switches pending at the time that the 1675 * HW executes the de-schedule, the HW will only re-schedule 1676 * the head of the FIFO associated with the given tag. This 1677 * means that in many respects, the HW treats this ORDERED 1678 * tag as an ATOMIC tag. Note that in the SWTAG_DESCH 1679 * case (to an ORDERED tag), the HW will do the switch 1680 * before the deschedule whenever it is possible to do 1681 * the switch immediately, so it may often look like 1682 * this case. 1683 * - If there is a pending switch to ORDERED at the time 1684 * the HW executes the de-schedule, the HW will perform 1685 * the switch at the time it re-schedules, and will be 1686 * able to reschedule any/all of the entries with the 1687 * same tag. 1688 * Due to this behavior, the RECOMMENDATION to software is 1689 * that they have a (next) state of ATOMIC when they 1690 * DE-SCHEDULE. If an ORDERED tag is what was really desired, 1691 * SW can choose to immediately switch to an ORDERED tag 1692 * after the work (that has an ATOMIC tag) is re-scheduled. 1693 * Note that since there are never any tag switches pending 1694 * when the HW re-schedules, this switch can be IMMEDIATE upon 1695 * the reception of the pointer during the re-schedule. 1696 * 1697 * @tag: New tag value 1698 * @tag_type: New tag type 1699 * @group: New group value 1700 * @no_sched: Control whether this work queue entry will be rescheduled. 1701 * - 1 : don't schedule this work 1702 * - 0 : allow this work to be scheduled. 1703 */ 1704 static inline void cvmx_pow_tag_sw_desched_nocheck( 1705 uint32_t tag, 1706 enum cvmx_pow_tag_type tag_type, 1707 uint64_t group, 1708 uint64_t no_sched) 1709 { 1710 cvmx_addr_t ptr; 1711 cvmx_pow_tag_req_t tag_req; 1712 1713 if (CVMX_ENABLE_POW_CHECKS) { 1714 cvmx_pow_tag_req_t current_tag; 1715 __cvmx_pow_warn_if_pending_switch(__func__); 1716 current_tag = cvmx_pow_get_current_tag(); 1717 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1718 pr_warn("%s called with NULL_NULL tag\n", __func__); 1719 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1720 pr_warn("%s called with NULL tag. Deschedule not allowed from NULL state\n", 1721 __func__); 1722 if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) 1723 && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) 1724 pr_warn("%s called where neither the before or after tag is ATOMIC\n", 1725 __func__); 1726 } 1727 1728 tag_req.u64 = 0; 1729 tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH; 1730 tag_req.s.tag = tag; 1731 tag_req.s.type = tag_type; 1732 tag_req.s.grp = group; 1733 tag_req.s.no_sched = no_sched; 1734 1735 ptr.u64 = 0; 1736 ptr.sio.mem_region = CVMX_IO_SEG; 1737 ptr.sio.is_io = 1; 1738 ptr.sio.did = CVMX_OCT_DID_TAG_TAG3; 1739 /* 1740 * since TAG3 is used, this store will clear the local pending 1741 * switch bit. 1742 */ 1743 cvmx_write_io(ptr.u64, tag_req.u64); 1744 } 1745 1746 /** 1747 * Performs a tag switch and then an immediate deschedule. This completes 1748 * immediately, so completion must not be waited for. This function does NOT 1749 * update the wqe in DRAM to match arguments. 1750 * 1751 * This function waits for any prior tag switches to complete, so the 1752 * calling code may call this function with a pending tag switch. 1753 * 1754 * Note the following CAVEAT of the Octeon HW behavior when 1755 * re-scheduling DE-SCHEDULEd items whose (next) state is 1756 * ORDERED: 1757 * - If there are no switches pending at the time that the 1758 * HW executes the de-schedule, the HW will only re-schedule 1759 * the head of the FIFO associated with the given tag. This 1760 * means that in many respects, the HW treats this ORDERED 1761 * tag as an ATOMIC tag. Note that in the SWTAG_DESCH 1762 * case (to an ORDERED tag), the HW will do the switch 1763 * before the deschedule whenever it is possible to do 1764 * the switch immediately, so it may often look like 1765 * this case. 1766 * - If there is a pending switch to ORDERED at the time 1767 * the HW executes the de-schedule, the HW will perform 1768 * the switch at the time it re-schedules, and will be 1769 * able to reschedule any/all of the entries with the 1770 * same tag. 1771 * Due to this behavior, the RECOMMENDATION to software is 1772 * that they have a (next) state of ATOMIC when they 1773 * DE-SCHEDULE. If an ORDERED tag is what was really desired, 1774 * SW can choose to immediately switch to an ORDERED tag 1775 * after the work (that has an ATOMIC tag) is re-scheduled. 1776 * Note that since there are never any tag switches pending 1777 * when the HW re-schedules, this switch can be IMMEDIATE upon 1778 * the reception of the pointer during the re-schedule. 1779 * 1780 * @tag: New tag value 1781 * @tag_type: New tag type 1782 * @group: New group value 1783 * @no_sched: Control whether this work queue entry will be rescheduled. 1784 * - 1 : don't schedule this work 1785 * - 0 : allow this work to be scheduled. 1786 */ 1787 static inline void cvmx_pow_tag_sw_desched(uint32_t tag, 1788 enum cvmx_pow_tag_type tag_type, 1789 uint64_t group, uint64_t no_sched) 1790 { 1791 if (CVMX_ENABLE_POW_CHECKS) 1792 __cvmx_pow_warn_if_pending_switch(__func__); 1793 1794 /* Need to make sure any writes to the work queue entry are complete */ 1795 CVMX_SYNCWS; 1796 /* 1797 * Ensure that there is not a pending tag switch, as a tag 1798 * switch cannot be started if a previous switch is still 1799 * pending. 1800 */ 1801 cvmx_pow_tag_sw_wait(); 1802 cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched); 1803 } 1804 1805 /** 1806 * Descchedules the current work queue entry. 1807 * 1808 * @no_sched: no schedule flag value to be set on the work queue 1809 * entry. If this is set the entry will not be 1810 * rescheduled. 1811 */ 1812 static inline void cvmx_pow_desched(uint64_t no_sched) 1813 { 1814 cvmx_addr_t ptr; 1815 cvmx_pow_tag_req_t tag_req; 1816 1817 if (CVMX_ENABLE_POW_CHECKS) { 1818 cvmx_pow_tag_req_t current_tag; 1819 __cvmx_pow_warn_if_pending_switch(__func__); 1820 current_tag = cvmx_pow_get_current_tag(); 1821 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1822 pr_warn("%s called with NULL_NULL tag\n", __func__); 1823 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1824 pr_warn("%s called with NULL tag. Deschedule not expected from NULL state\n", 1825 __func__); 1826 } 1827 1828 /* Need to make sure any writes to the work queue entry are complete */ 1829 CVMX_SYNCWS; 1830 1831 tag_req.u64 = 0; 1832 tag_req.s.op = CVMX_POW_TAG_OP_DESCH; 1833 tag_req.s.no_sched = no_sched; 1834 1835 ptr.u64 = 0; 1836 ptr.sio.mem_region = CVMX_IO_SEG; 1837 ptr.sio.is_io = 1; 1838 ptr.sio.did = CVMX_OCT_DID_TAG_TAG3; 1839 /* 1840 * since TAG3 is used, this store will clear the local pending 1841 * switch bit. 1842 */ 1843 cvmx_write_io(ptr.u64, tag_req.u64); 1844 } 1845 1846 /**************************************************** 1847 * Define usage of bits within the 32 bit tag values. 1848 *****************************************************/ 1849 1850 /* 1851 * Number of bits of the tag used by software. The SW bits are always 1852 * a contiguous block of the high starting at bit 31. The hardware 1853 * bits are always the low bits. By default, the top 8 bits of the 1854 * tag are reserved for software, and the low 24 are set by the IPD 1855 * unit. 1856 */ 1857 #define CVMX_TAG_SW_BITS (8) 1858 #define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS) 1859 1860 /* Below is the list of values for the top 8 bits of the tag. */ 1861 /* 1862 * Tag values with top byte of this value are reserved for internal 1863 * executive uses. 1864 */ 1865 #define CVMX_TAG_SW_BITS_INTERNAL 0x1 1866 /* The executive divides the remaining 24 bits as follows: 1867 * - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup 1868 * 1869 * - the lower 16 bits (bits 15 - 0 of the tag) define are the value 1870 * with the subgroup 1871 * 1872 * Note that this section describes the format of tags generated by 1873 * software - refer to the hardware documentation for a description of 1874 * the tags values generated by the packet input hardware. Subgroups 1875 * are defined here. 1876 */ 1877 /* Mask for the value portion of the tag */ 1878 #define CVMX_TAG_SUBGROUP_MASK 0xFFFF 1879 #define CVMX_TAG_SUBGROUP_SHIFT 16 1880 #define CVMX_TAG_SUBGROUP_PKO 0x1 1881 1882 /* End of executive tag subgroup definitions */ 1883 1884 /* 1885 * The remaining values software bit values 0x2 - 0xff are available 1886 * for application use. 1887 */ 1888 1889 /** 1890 * This function creates a 32 bit tag value from the two values provided. 1891 * 1892 * @sw_bits: The upper bits (number depends on configuration) are set 1893 * to this value. The remainder of bits are set by the 1894 * hw_bits parameter. 1895 * 1896 * @hw_bits: The lower bits (number depends on configuration) are set 1897 * to this value. The remainder of bits are set by the 1898 * sw_bits parameter. 1899 * 1900 * Returns 32 bit value of the combined hw and sw bits. 1901 */ 1902 static inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits) 1903 { 1904 return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) << 1905 CVMX_TAG_SW_SHIFT) | 1906 (hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS)); 1907 } 1908 1909 /** 1910 * Extracts the bits allocated for software use from the tag 1911 * 1912 * @tag: 32 bit tag value 1913 * 1914 * Returns N bit software tag value, where N is configurable with the 1915 * CVMX_TAG_SW_BITS define 1916 */ 1917 static inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag) 1918 { 1919 return (tag >> (32 - CVMX_TAG_SW_BITS)) & 1920 cvmx_build_mask(CVMX_TAG_SW_BITS); 1921 } 1922 1923 /** 1924 * 1925 * Extracts the bits allocated for hardware use from the tag 1926 * 1927 * @tag: 32 bit tag value 1928 * 1929 * Returns (32 - N) bit software tag value, where N is configurable 1930 * with the CVMX_TAG_SW_BITS define 1931 */ 1932 static inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag) 1933 { 1934 return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS); 1935 } 1936 1937 /** 1938 * Store the current POW internal state into the supplied 1939 * buffer. It is recommended that you pass a buffer of at least 1940 * 128KB. The format of the capture may change based on SDK 1941 * version and Octeon chip. 1942 * 1943 * @buffer: Buffer to store capture into 1944 * @buffer_size: 1945 * The size of the supplied buffer 1946 * 1947 * Returns Zero on success, negative on failure 1948 */ 1949 extern int cvmx_pow_capture(void *buffer, int buffer_size); 1950 1951 /** 1952 * Dump a POW capture to the console in a human readable format. 1953 * 1954 * @buffer: POW capture from cvmx_pow_capture() 1955 * @buffer_size: 1956 * Size of the buffer 1957 */ 1958 extern void cvmx_pow_display(void *buffer, int buffer_size); 1959 1960 /** 1961 * Return the number of POW entries supported by this chip 1962 * 1963 * Returns Number of POW entries 1964 */ 1965 extern int cvmx_pow_get_num_entries(void); 1966 1967 #endif /* __CVMX_POW_H__ */ 1968