* Copyright (c) 2025 HiSilicon Technologies Co., Ltd. All rights reserved.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include "cdma_u_log.h"
#include "cdma_u_common.h"
void *cdma_u_alloc_buf(uint32_t buf_size)
{
void *buf;
int ret;
buf = mmap(NULL, buf_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (buf == MAP_FAILED) {
CDMA_LOG_ERR("mmap buf failed\n");
return NULL;
}
ret = madvise(buf, buf_size, MADV_DONTFORK);
if (ret) {
(void)munmap(buf, buf_size);
CDMA_LOG_ERR("buf madvise failed, ret = %d\n", ret);
return NULL;
}
return buf;
}
int cdma_u_alloc_queue_buf(struct cdma_u_jetty_queue *q, uint32_t max_cnt,
uint32_t entry_size, uint32_t page_size,
bool wrid_en)
{
uint32_t buf_shift;
uint32_t entry_cnt;
entry_cnt = roundup_pow_of_two(max_cnt);
buf_shift = align_power2(roundup_pow_of_two(entry_cnt * entry_size));
q->baseblk_shift = align_power2(roundup_pow_of_two(entry_size));
q->qbuf_size = align((1U << buf_shift), page_size);
q->baseblk_cnt = q->qbuf_size >> q->baseblk_shift;
q->baseblk_mask = q->baseblk_cnt - 1;
if (wrid_en) {
q->wrid = (uintptr_t *)malloc(q->baseblk_cnt * sizeof(uint64_t));
if (!q->wrid) {
CDMA_LOG_ERR("alloc buffer for wrid failed\n");
return -ENOMEM;
}
}
q->qbuf = cdma_u_alloc_buf(q->qbuf_size);
if (!q->qbuf) {
CDMA_LOG_ERR("alloc queue buffer failed\n");
goto err_alloc_buf;
}
q->qbuf_curr = q->qbuf;
return 0;
err_alloc_buf:
if (wrid_en) {
free(q->wrid);
q->wrid = NULL;
}
return -ENOMEM;
}
void cdma_u_free_queue_buf(struct cdma_u_jetty_queue *q)
{
if (q->qbuf) {
cdma_u_free_buf(q->qbuf, q->qbuf_size);
q->qbuf = NULL;
}
if (q->wrid) {
free(q->wrid);
q->wrid = NULL;
}
}