Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2025 Huawei Technologies Co., Ltd
3 : : */
4 : :
5 : : #ifndef _HINIC3_NIC_IO_H_
6 : : #define _HINIC3_NIC_IO_H_
7 : :
8 : : #include "hinic3_ethdev.h"
9 : : #include "base/hinic3_cmdq.h"
10 : :
11 : : #define HINIC3_SQ_WQEBB_SHIFT 4
12 : : #define HINIC3_RQ_WQEBB_SHIFT 3
13 : :
14 : : #define HINIC3_SQ_WQEBB_SIZE RTE_BIT32(HINIC3_SQ_WQEBB_SHIFT)
15 : : #define HINIC3_CQE_SIZE_SHIFT 4
16 : :
17 : : /* Ci addr should RTE_CACHE_SIZE(64B) alignment for performance. */
18 : : #define HINIC3_CI_Q_ADDR_SIZE 64
19 : :
20 : : #define CI_TABLE_SIZE(num_qps, pg_sz) \
21 : : (RTE_ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
22 : :
23 : : #define HINIC3_CI_VADDR(base_addr, q_id) \
24 : : ((volatile uint8_t *)(base_addr) + (q_id) * HINIC3_CI_Q_ADDR_SIZE)
25 : :
26 : : #define HINIC3_CI_PADDR(base_paddr, q_id) \
27 : : ((base_paddr) + (q_id) * HINIC3_CI_Q_ADDR_SIZE)
28 : :
29 : : #define HINIC3_Q_CTXT_MAX ((uint16_t)(((HINIC3_CMDQ_BUF_SIZE - 8) - RTE_PKTMBUF_HEADROOM) / 64))
30 : :
31 : : enum hinic3_rq_wqe_type {
32 : : HINIC3_COMPACT_RQ_WQE,
33 : : HINIC3_NORMAL_RQ_WQE,
34 : : HINIC3_EXTEND_RQ_WQE
35 : : };
36 : :
37 : : enum hinic3_queue_type {
38 : : HINIC3_SQ,
39 : : HINIC3_RQ,
40 : : HINIC3_MAX_QUEUE_TYPE,
41 : : };
42 : :
43 : : enum hinic3_qp_ctxt_type {
44 : : HINIC3_QP_CTXT_TYPE_SQ,
45 : : HINIC3_QP_CTXT_TYPE_RQ,
46 : : };
47 : :
48 : : /* Prepare cmd to clean tso/lro space */
49 : : typedef uint8_t (*prepare_cmd_buf_clean_tso_lro_space_t)(struct hinic3_nic_dev *nic_dev,
50 : : struct hinic3_cmd_buf *cmd_buf,
51 : : enum hinic3_qp_ctxt_type ctxt_type);
52 : : /* Prepare cmd to store RQ and TQ ctxt */
53 : : typedef uint8_t (*prepare_cmd_buf_qp_context_multi_store_t)(struct hinic3_nic_dev *nic_dev,
54 : : struct hinic3_cmd_buf *cmd_buf,
55 : : enum hinic3_qp_ctxt_type ctxt_type,
56 : : uint16_t start_qid,
57 : : uint16_t max_ctxts);
58 : : /* Prepare cmd to modify vlan tag */
59 : : typedef uint8_t (*prepare_cmd_buf_modify_svlan_t)(struct hinic3_cmd_buf *cmd_buf, uint16_t func_id,
60 : : uint16_t vlan_tag, uint16_t q_id,
61 : : uint8_t vlan_mode);
62 : : /* Prepare cmd to set RSS indir table */
63 : : typedef uint8_t (*prepare_cmd_buf_set_rss_indir_table_t)(struct hinic3_nic_dev *nic_dev,
64 : : const uint32_t *indir_table,
65 : : struct hinic3_cmd_buf *cmd_buf);
66 : : /* Prepare cmd to get RSS indir table */
67 : : typedef uint8_t (*prepare_cmd_buf_get_rss_indir_table_t)(struct hinic3_nic_dev *nic_dev,
68 : : struct hinic3_cmd_buf *cmd_buf);
69 : : /* Configure RSS indir table */
70 : : typedef void (*cmd_buf_to_rss_indir_table_t)(const struct hinic3_cmd_buf *cmd_buf,
71 : : uint32_t *indir_table);
72 : :
73 : : struct hinic3_nic_cmdq_ops {
74 : : prepare_cmd_buf_clean_tso_lro_space_t prepare_cmd_buf_clean_tso_lro_space;
75 : : prepare_cmd_buf_qp_context_multi_store_t prepare_cmd_buf_qp_context_multi_store;
76 : : prepare_cmd_buf_modify_svlan_t prepare_cmd_buf_modify_svlan;
77 : : prepare_cmd_buf_set_rss_indir_table_t prepare_cmd_buf_set_rss_indir_table;
78 : : prepare_cmd_buf_get_rss_indir_table_t prepare_cmd_buf_get_rss_indir_table;
79 : : cmd_buf_to_rss_indir_table_t cmd_buf_to_rss_indir_table;
80 : : };
81 : :
82 : : /* Doorbell info. */
83 : : struct hinic3_db {
84 : : uint32_t db_info;
85 : : uint32_t pi_hi;
86 : : };
87 : :
88 : : struct hinic3_sq_ctxt {
89 : : uint32_t ci_pi;
90 : : uint32_t drop_mode_sp;
91 : : uint32_t wq_pfn_hi_owner;
92 : : uint32_t wq_pfn_lo;
93 : :
94 : : uint32_t rsvd0;
95 : : uint32_t pkt_drop_thd;
96 : : uint32_t global_sq_id;
97 : : uint32_t vlan_ceq_attr;
98 : :
99 : : uint32_t pref_cache;
100 : : uint32_t pref_ci_owner;
101 : : uint32_t pref_wq_pfn_hi_ci;
102 : : uint32_t pref_wq_pfn_lo;
103 : :
104 : : uint32_t rsvd8;
105 : : uint32_t rsvd9;
106 : : uint32_t wq_block_pfn_hi;
107 : : uint32_t wq_block_pfn_lo;
108 : : };
109 : :
110 : : struct hinic3_rq_ctxt {
111 : : uint32_t ci_pi;
112 : : uint32_t ceq_attr;
113 : : uint32_t wq_pfn_hi_type_owner;
114 : : uint32_t wq_pfn_lo;
115 : :
116 : : uint32_t rsvd[3];
117 : : uint32_t cqe_sge_len;
118 : :
119 : : uint32_t pref_cache;
120 : : uint32_t pref_ci_owner;
121 : : uint32_t pref_wq_pfn_hi_ci;
122 : : uint32_t pref_wq_pfn_lo;
123 : :
124 : : uint32_t pi_paddr_hi;
125 : : uint32_t pi_paddr_lo;
126 : : uint32_t wq_block_pfn_hi;
127 : : uint32_t wq_block_pfn_lo;
128 : : };
129 : :
130 : : struct hinic3_rq_cqe_ctx {
131 : : struct mgmt_msg_head msg_head;
132 : :
133 : : uint8_t cqe_type;
134 : : uint8_t rq_id;
135 : : uint8_t threshold_cqe_num;
136 : : uint8_t rsvd1;
137 : :
138 : : uint16_t msix_entry_idx;
139 : : uint16_t rsvd2;
140 : :
141 : : uint32_t ci_addr_hi;
142 : : uint32_t ci_addr_lo;
143 : :
144 : : uint16_t timer_loop;
145 : : uint16_t rsvd3;
146 : : };
147 : :
148 : : struct hinic3_rq_enable {
149 : : struct mgmt_msg_head msg_head;
150 : :
151 : : uint32_t rq_id;
152 : : uint8_t rq_enable;
153 : : uint8_t rsvd[3];
154 : : };
155 : :
156 : : #define DB_INFO_QID_SHIFT 0
157 : : #define DB_INFO_NON_FILTER_SHIFT 22
158 : : #define DB_INFO_CFLAG_SHIFT 23
159 : : #define DB_INFO_COS_SHIFT 24
160 : : #define DB_INFO_TYPE_SHIFT 27
161 : :
162 : : #define DB_INFO_QID_MASK 0x1FFFU
163 : : #define DB_INFO_NON_FILTER_MASK 0x1U
164 : : #define DB_INFO_CFLAG_MASK 0x1U
165 : : #define DB_INFO_COS_MASK 0x7U
166 : : #define DB_INFO_TYPE_MASK 0x1FU
167 : : #define DB_INFO_SET(val, member) \
168 : : (((uint32_t)(val) & DB_INFO_##member##_MASK) << DB_INFO_##member##_SHIFT)
169 : :
170 : : #define DB_PI_LOW_MASK 0xFFU
171 : : #define DB_PI_HIGH_MASK 0xFFU
172 : : #define DB_PI_LOW(pi) ((pi) & DB_PI_LOW_MASK)
173 : : #define DB_PI_HI_SHIFT 8
174 : : #define DB_PI_HIGH(pi) (((pi) >> DB_PI_HI_SHIFT) & DB_PI_HIGH_MASK)
175 : : #define DB_INFO_UPPER_32(val) (((uint64_t)(val)) << 32)
176 : :
177 : : #define DB_ADDR(db_addr, pi) ((uint64_t *)(db_addr) + DB_PI_LOW(pi))
178 : : #define SRC_TYPE 1
179 : :
180 : : /* Cflag data path. */
181 : : #define SQ_CFLAG_DP 0
182 : : #define RQ_CFLAG_DP 1
183 : :
184 : : #define MASKED_QUEUE_IDX(queue, idx) ((idx) & (queue)->q_mask)
185 : :
186 : : #define NIC_WQE_ADDR(queue, idx) \
187 : : ({ \
188 : : typeof(queue) __queue = (queue); \
189 : : (void *)((uint64_t)(__queue->queue_buf_vaddr) + \
190 : : ((idx) << __queue->wqebb_shift)); \
191 : : })
192 : :
193 : : /**
194 : : * Write send queue doorbell.
195 : : *
196 : : * @param[in] db_addr
197 : : * Doorbell address.
198 : : * @param[in] q_id
199 : : * Send queue id.
200 : : * @param[in] cos
201 : : * Send queue cos.
202 : : * @param[in] cflag
203 : : * Cflag data path.
204 : : * @param[in] pi
205 : : * Send queue pi.
206 : : */
207 : : static inline void
208 : 0 : hinic3_write_db(void *db_addr, uint16_t q_id, int cos, uint8_t cflag, uint16_t pi)
209 : : {
210 : 0 : uint64_t db = DB_PI_HIGH(pi);
211 : :
212 : 0 : db = DB_INFO_UPPER_32(db) | DB_INFO_SET(SRC_TYPE, TYPE) |
213 : 0 : DB_INFO_SET(cflag, CFLAG) | DB_INFO_SET(cos, COS) |
214 : 0 : DB_INFO_SET(q_id, QID);
215 : :
216 : : rte_atomic_thread_fence(rte_memory_order_release); /**< Write all before the doorbell. */
217 : : /* Hardware will do endianness converting. */
218 : 0 : rte_write64(db, DB_ADDR(db_addr, pi));
219 : 0 : }
220 : :
221 : : /**
222 : : * Get minimum RX buffer size for device.
223 : : *
224 : : * @param[in] nic_dev
225 : : * Pointer to ethernet device structure.
226 : : */
227 : : void hinic3_get_func_rx_buf_size(struct hinic3_nic_dev *nic_dev);
228 : :
229 : : /**
230 : : * Initialize RQ integrated CQE context
231 : : *
232 : : * @param[in] nic_dev
233 : : * Pointer to ethernet device structure.
234 : : *
235 : : * @return
236 : : * 0 on success, non-zero on failure.
237 : : */
238 : : int hinic3_init_rq_cqe_ctxts(struct hinic3_nic_dev *nic_dev);
239 : :
240 : : /**
241 : : * Set RQ disable or enable
242 : : *
243 : : * @param[in] nic_dev
244 : : * Pointer to ethernet device structure.
245 : : * @param[in] q_id
246 : : * Receive queue id.
247 : : * @param[in] enable
248 : : * 1: enable 0: disable
249 : : * @return
250 : : * 0 on success, non-zero on failure.
251 : : */
252 : : int hinic3_set_rq_enable(struct hinic3_nic_dev *nic_dev, uint16_t q_id, bool enable);
253 : :
254 : : /**
255 : : * Initialize qps contexts, set SQ ci attributes, arm all SQ.
256 : : *
257 : : * Function will perform following steps:
258 : : * - Initialize SQ contexts.
259 : : * - Initialize RQ contexts.
260 : : * - Clean QP offload contexts of SQ and RQ.
261 : : * - Set root context for device.
262 : : * - Configure CI tables for each SQ.
263 : : *
264 : : * @param[in] nic_dev
265 : : * Pointer to ethernet device structure.
266 : : *
267 : : * @return
268 : : * 0 on success, non-zero on failure.
269 : : */
270 : : int hinic3_init_qp_ctxts(struct hinic3_nic_dev *nic_dev);
271 : :
272 : : /**
273 : : * Free queue pair context.
274 : : *
275 : : * @param[in] hwdev
276 : : * Pointer to hardware device structure.
277 : : */
278 : : void hinic3_free_qp_ctxts(struct hinic3_hwdev *hwdev);
279 : :
280 : : /**
281 : : * Update driver feature capabilities.
282 : : *
283 : : * @param[in] nic_dev
284 : : * Pointer to ethernet device structure.
285 : : * @param[out] s_feature
286 : : * s_feature driver supported.
287 : : */
288 : : void hinic3_update_driver_feature(struct hinic3_nic_dev *nic_dev, uint64_t s_feature);
289 : :
290 : : /**
291 : : * Get driver feature capabilities.
292 : : *
293 : : * @param[in] nic_dev
294 : : * Pointer to ethernet device structure.
295 : : *
296 : : * @return
297 : : * Feature capabilities of driver.
298 : : */
299 : : uint64_t hinic3_get_driver_feature(struct hinic3_nic_dev *nic_dev);
300 : :
301 : : /**
302 : : * Initialize context structure for specified TXQ by configuring various queue
303 : : * parameters (e.g., ci, pi, work queue page addresses).
304 : : *
305 : : * @param[in] sq
306 : : * Pointer to TXQ structure.
307 : : * @param[in] sq_id
308 : : * ID of TXQ being configured.
309 : : * @param[out] sq_ctxt
310 : : * Pointer to structure that will hold TXQ context.
311 : : */
312 : : void hinic3_sq_prepare_ctxt(struct hinic3_txq *sq, uint16_t sq_id,
313 : : struct hinic3_sq_ctxt *sq_ctxt);
314 : :
315 : : /**
316 : : * Initialize context structure for specified RXQ by configuring various queue
317 : : * parameters (e.g., ci, pi, work queue page addresses).
318 : : *
319 : : * @param[in] rq
320 : : * Pointer to RXQ structure.
321 : : * @param[out] rq_ctxt
322 : : * Pointer to structure that will hold RXQ context.
323 : : */
324 : : void hinic3_rq_prepare_ctxt(struct hinic3_rxq *rq, struct hinic3_rq_ctxt *rq_ctxt);
325 : :
326 : : #endif /* _HINIC3_NIC_IO_H_ */
|