xref: /linux/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c (revision 23313771c7b99b3b8dba169bc71dae619d41ab56)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
3 
4 #include <linux/bitfield.h>
5 #include <linux/device.h>
6 #include <linux/io.h>
7 
8 #include "hinic3_common.h"
9 #include "hinic3_csr.h"
10 #include "hinic3_hwdev.h"
11 #include "hinic3_hwif.h"
12 
13 /* config BAR4/5 4MB, DB & DWQE both 2MB */
14 #define HINIC3_DB_DWQE_SIZE    0x00400000
15 
16 /* db/dwqe page size: 4K */
17 #define HINIC3_DB_PAGE_SIZE    0x00001000
18 #define HINIC3_DWQE_OFFSET     0x00000800
19 #define HINIC3_DB_MAX_AREAS    (HINIC3_DB_DWQE_SIZE / HINIC3_DB_PAGE_SIZE)
20 
21 #define HINIC3_GET_REG_ADDR(reg)  ((reg) & (HINIC3_REGS_FLAG_MASK))
22 
23 static void __iomem *hinic3_reg_addr(struct hinic3_hwif *hwif, u32 reg)
24 {
25 	return hwif->cfg_regs_base + HINIC3_GET_REG_ADDR(reg);
26 }
27 
28 u32 hinic3_hwif_read_reg(struct hinic3_hwif *hwif, u32 reg)
29 {
30 	void __iomem *addr = hinic3_reg_addr(hwif, reg);
31 
32 	return ioread32be(addr);
33 }
34 
35 void hinic3_hwif_write_reg(struct hinic3_hwif *hwif, u32 reg, u32 val)
36 {
37 	void __iomem *addr = hinic3_reg_addr(hwif, reg);
38 
39 	iowrite32be(val, addr);
40 }
41 
42 static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
43 {
44 	struct hinic3_db_area *db_area = &hwif->db_area;
45 	u32 pg_idx;
46 
47 	spin_lock(&db_area->idx_lock);
48 	pg_idx = find_first_zero_bit(db_area->db_bitmap_array,
49 				     db_area->db_max_areas);
50 	if (pg_idx == db_area->db_max_areas) {
51 		spin_unlock(&db_area->idx_lock);
52 		return -ENOMEM;
53 	}
54 	set_bit(pg_idx, db_area->db_bitmap_array);
55 	spin_unlock(&db_area->idx_lock);
56 
57 	*idx = pg_idx;
58 
59 	return 0;
60 }
61 
62 static void free_db_idx(struct hinic3_hwif *hwif, u32 idx)
63 {
64 	struct hinic3_db_area *db_area = &hwif->db_area;
65 
66 	spin_lock(&db_area->idx_lock);
67 	clear_bit(idx, db_area->db_bitmap_array);
68 	spin_unlock(&db_area->idx_lock);
69 }
70 
71 void hinic3_free_db_addr(struct hinic3_hwdev *hwdev, const u8 __iomem *db_base)
72 {
73 	struct hinic3_hwif *hwif;
74 	uintptr_t distance;
75 	u32 idx;
76 
77 	hwif = hwdev->hwif;
78 	distance = db_base - hwif->db_base;
79 	idx = distance / HINIC3_DB_PAGE_SIZE;
80 
81 	free_db_idx(hwif, idx);
82 }
83 
84 int hinic3_alloc_db_addr(struct hinic3_hwdev *hwdev, void __iomem **db_base,
85 			 void __iomem **dwqe_base)
86 {
87 	struct hinic3_hwif *hwif;
88 	u8 __iomem *addr;
89 	u32 idx;
90 	int err;
91 
92 	hwif = hwdev->hwif;
93 
94 	err = get_db_idx(hwif, &idx);
95 	if (err)
96 		return err;
97 
98 	addr = hwif->db_base + idx * HINIC3_DB_PAGE_SIZE;
99 	*db_base = addr;
100 
101 	if (dwqe_base)
102 		*dwqe_base = addr + HINIC3_DWQE_OFFSET;
103 
104 	return 0;
105 }
106 
107 void hinic3_set_msix_state(struct hinic3_hwdev *hwdev, u16 msix_idx,
108 			   enum hinic3_msix_state flag)
109 {
110 	struct hinic3_hwif *hwif;
111 	u8 int_msk = 1;
112 	u32 mask_bits;
113 	u32 addr;
114 
115 	hwif = hwdev->hwif;
116 
117 	if (flag)
118 		mask_bits = HINIC3_MSI_CLR_INDIR_SET(int_msk, INT_MSK_SET);
119 	else
120 		mask_bits = HINIC3_MSI_CLR_INDIR_SET(int_msk, INT_MSK_CLR);
121 	mask_bits = mask_bits |
122 		    HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX);
123 
124 	addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
125 	hinic3_hwif_write_reg(hwif, addr, mask_bits);
126 }
127 
128 void hinic3_msix_intr_clear_resend_bit(struct hinic3_hwdev *hwdev, u16 msix_idx,
129 				       u8 clear_resend_en)
130 {
131 	struct hinic3_hwif *hwif;
132 	u32 msix_ctrl, addr;
133 
134 	hwif = hwdev->hwif;
135 
136 	msix_ctrl = HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX) |
137 		    HINIC3_MSI_CLR_INDIR_SET(clear_resend_en, RESEND_TIMER_CLR);
138 
139 	addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
140 	hinic3_hwif_write_reg(hwif, addr, msix_ctrl);
141 }
142 
143 void hinic3_set_msix_auto_mask_state(struct hinic3_hwdev *hwdev, u16 msix_idx,
144 				     enum hinic3_msix_auto_mask flag)
145 {
146 	struct hinic3_hwif *hwif;
147 	u32 mask_bits;
148 	u32 addr;
149 
150 	hwif = hwdev->hwif;
151 
152 	if (flag)
153 		mask_bits = HINIC3_MSI_CLR_INDIR_SET(1, AUTO_MSK_SET);
154 	else
155 		mask_bits = HINIC3_MSI_CLR_INDIR_SET(1, AUTO_MSK_CLR);
156 
157 	mask_bits = mask_bits |
158 		    HINIC3_MSI_CLR_INDIR_SET(msix_idx, SIMPLE_INDIR_IDX);
159 
160 	addr = HINIC3_CSR_FUNC_MSI_CLR_WR_ADDR;
161 	hinic3_hwif_write_reg(hwif, addr, mask_bits);
162 }
163 
164 u16 hinic3_global_func_id(struct hinic3_hwdev *hwdev)
165 {
166 	return hwdev->hwif->attr.func_global_idx;
167 }
168