File Index
Files and directories
Sign in
FILE

hinic3_queue_common.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/huawei/hinic3/hinic3_queue_common.c C
 1// SPDX-License-Identifier: GPL-2.0
 2// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 3
 4#include <linux/device.h>
 5
 6#include "hinic3_hwdev.h"
 7#include "hinic3_queue_common.h"
 8
 9void hinic3_queue_pages_init(struct hinic3_queue_pages *qpages, u32 q_depth,
10			     u32 page_size, u32 elem_size)
11{
12	u32 elem_per_page;
13
14	elem_per_page = min(page_size / elem_size, q_depth);
15
16	qpages->pages = NULL;
17	qpages->page_size = page_size;
18	qpages->num_pages = max(q_depth / elem_per_page, 1);
19	qpages->elem_size_shift = ilog2(elem_size);
20	qpages->elem_per_pg_shift = ilog2(elem_per_page);
21}
22
23static void __queue_pages_free(struct hinic3_hwdev *hwdev,
24			       struct hinic3_queue_pages *qpages, u32 pg_cnt)
25{
26	while (pg_cnt > 0) {
27		pg_cnt--;
28		hinic3_dma_free_coherent_align(hwdev->dev,
29					       qpages->pages + pg_cnt);
30	}
31	kfree(qpages->pages);
32	qpages->pages = NULL;
33}
34
35void hinic3_queue_pages_free(struct hinic3_hwdev *hwdev,
36			     struct hinic3_queue_pages *qpages)
37{
38	__queue_pages_free(hwdev, qpages, qpages->num_pages);
39}
40
41int hinic3_queue_pages_alloc(struct hinic3_hwdev *hwdev,
42			     struct hinic3_queue_pages *qpages, u32 align)
43{
44	u32 pg_idx;
45	int err;
46
47	qpages->pages = kcalloc(qpages->num_pages, sizeof(qpages->pages[0]),
48				GFP_KERNEL);
49	if (!qpages->pages)
50		return -ENOMEM;
51
52	if (align == 0)
53		align = qpages->page_size;
54
55	for (pg_idx = 0; pg_idx < qpages->num_pages; pg_idx++) {
56		err = hinic3_dma_zalloc_coherent_align(hwdev->dev,
57						       qpages->page_size,
58						       align,
59						       GFP_KERNEL,
60						       qpages->pages + pg_idx);
61		if (err) {
62			__queue_pages_free(hwdev, qpages, pg_idx);
63			return err;
64		}
65	}
66
67	return 0;
68}
~/ Read-only file preview.