| 556 | } |
| 557 | |
| 558 | static int |
| 559 | ionic_qcq_alloc(struct ionic_lif *lif, |
| 560 | uint8_t type, |
| 561 | size_t struct_size, |
| 562 | uint32_t socket_id, |
| 563 | uint32_t index, |
| 564 | const char *type_name, |
| 565 | uint16_t flags, |
| 566 | uint16_t num_descs, |
| 567 | uint16_t num_segs, |
| 568 | uint16_t desc_size, |
| 569 | uint16_t cq_desc_size, |
| 570 | uint16_t sg_desc_size, |
| 571 | struct ionic_qcq **qcq) |
| 572 | { |
| 573 | struct ionic_qcq *new; |
| 574 | uint32_t q_size, cq_size, sg_size, total_size; |
| 575 | void *q_base, *cq_base, *sg_base; |
| 576 | rte_iova_t q_base_pa = 0; |
| 577 | rte_iova_t cq_base_pa = 0; |
| 578 | rte_iova_t sg_base_pa = 0; |
| 579 | size_t page_size = rte_mem_page_size(); |
| 580 | int err; |
| 581 | |
| 582 | *qcq = NULL; |
| 583 | |
| 584 | q_size = num_descs * desc_size; |
| 585 | cq_size = num_descs * cq_desc_size; |
| 586 | sg_size = num_descs * sg_desc_size; |
| 587 | |
| 588 | total_size = RTE_ALIGN(q_size, page_size) + |
| 589 | RTE_ALIGN(cq_size, page_size); |
| 590 | /* |
| 591 | * Note: aligning q_size/cq_size is not enough due to cq_base address |
| 592 | * aligning as q_base could be not aligned to the page. |
| 593 | * Adding page_size. |
| 594 | */ |
| 595 | total_size += page_size; |
| 596 | |
| 597 | if (flags & IONIC_QCQ_F_SG) { |
| 598 | total_size += RTE_ALIGN(sg_size, page_size); |
| 599 | total_size += page_size; |
| 600 | } |
| 601 | |
| 602 | new = rte_zmalloc_socket("ionic", struct_size, |
| 603 | RTE_CACHE_LINE_SIZE, socket_id); |
| 604 | if (!new) { |
| 605 | IONIC_PRINT(ERR, "Cannot allocate queue structure"); |
| 606 | return -ENOMEM; |
| 607 | } |
| 608 | |
| 609 | new->lif = lif; |
| 610 | |
| 611 | /* Most queue types will store 1 ptr per descriptor */ |
| 612 | new->q.info = rte_calloc_socket("ionic", |
| 613 | (uint64_t)num_descs * num_segs, |
| 614 | sizeof(void *), page_size, socket_id); |
| 615 | if (!new->q.info) { |
no test coverage detected