Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2025 Yunsilicon Technology Co., Ltd.
3 : : */
4 : :
5 : : #include <rte_bitmap.h>
6 : : #include <rte_malloc.h>
7 : :
8 : : #include "xsc_log.h"
9 : : #include "xsc_defs.h"
10 : : #include "xsc_np.h"
11 : : #include "xsc_cmd.h"
12 : : #include "xsc_dev.h"
13 : :
14 : : #define XSC_RSS_HASH_FUNC_TOPELIZ 0x1
15 : : #define XSC_LOGIC_PORT_MASK 0x07FF
16 : :
17 : : #define XSC_DEV_DEF_PCT_IDX_MIN 128
18 : : #define XSC_DEV_DEF_PCT_IDX_MAX 138
19 : :
20 : : /* Each board has a PCT manager*/
21 : : static struct xsc_dev_pct_mgr xsc_pct_mgr;
22 : :
23 : : enum xsc_np_type {
24 : : XSC_NP_IPAT = 0,
25 : : XSC_NP_PCT_V4 = 4,
26 : : XSC_NP_EPAT = 19,
27 : : XSC_NP_VFOS = 31,
28 : : XSC_NP_PG_QP_SET_ID = 41,
29 : : XSC_NP_MAX
30 : : };
31 : :
32 : : enum xsc_np_opcode {
33 : : XSC_NP_OP_ADD,
34 : : XSC_NP_OP_DEL,
35 : : XSC_NP_OP_GET,
36 : : XSC_NP_OP_CLR,
37 : : XSC_NP_OP_MOD,
38 : : XSC_NP_OP_MAX
39 : : };
40 : :
41 : : struct xsc_np_mbox_in {
42 : : struct xsc_cmd_inbox_hdr hdr;
43 : : rte_be16_t len;
44 : : rte_be16_t rsvd;
45 : : uint8_t data[];
46 : : };
47 : :
48 : : struct xsc_np_mbox_out {
49 : : struct xsc_cmd_outbox_hdr hdr;
50 : : rte_be32_t error;
51 : : rte_be16_t len;
52 : : rte_be16_t rsvd;
53 : : uint8_t data[];
54 : : };
55 : :
56 : : struct xsc_np_data_tl {
57 : : uint16_t table;
58 : : uint16_t opmod;
59 : : uint16_t length;
60 : : uint16_t rsvd;
61 : : };
62 : :
63 : : enum xsc_hash_tmpl {
64 : : XSC_HASH_TMPL_IDX_IP_PORTS_IP6_PORTS = 0,
65 : : XSC_HASH_TMPL_IDX_IP_IP6,
66 : : XSC_HASH_TMPL_IDX_IP_PORTS_IP6,
67 : : XSC_HASH_TMPL_IDX_IP_IP6_PORTS,
68 : : XSC_HASH_TMPL_IDX_MAX,
69 : : };
70 : :
71 : : static const int xsc_rss_hash_tmplate[XSC_HASH_TMPL_IDX_MAX] = {
72 : : XSC_RSS_HASH_BIT_IPV4_SIP | XSC_RSS_HASH_BIT_IPV4_DIP |
73 : : XSC_RSS_HASH_BIT_IPV6_SIP | XSC_RSS_HASH_BIT_IPV6_DIP |
74 : : XSC_RSS_HASH_BIT_IPV4_SPORT | XSC_RSS_HASH_BIT_IPV4_DPORT |
75 : : XSC_RSS_HASH_BIT_IPV6_SPORT | XSC_RSS_HASH_BIT_IPV6_DPORT,
76 : :
77 : : XSC_RSS_HASH_BIT_IPV4_SIP | XSC_RSS_HASH_BIT_IPV4_DIP |
78 : : XSC_RSS_HASH_BIT_IPV6_SIP | XSC_RSS_HASH_BIT_IPV6_DIP,
79 : :
80 : : XSC_RSS_HASH_BIT_IPV4_SIP | XSC_RSS_HASH_BIT_IPV4_DIP |
81 : : XSC_RSS_HASH_BIT_IPV6_SIP | XSC_RSS_HASH_BIT_IPV6_DIP |
82 : : XSC_RSS_HASH_BIT_IPV4_SPORT | XSC_RSS_HASH_BIT_IPV4_DPORT,
83 : :
84 : : XSC_RSS_HASH_BIT_IPV4_SIP | XSC_RSS_HASH_BIT_IPV4_DIP |
85 : : XSC_RSS_HASH_BIT_IPV6_SIP | XSC_RSS_HASH_BIT_IPV6_DIP |
86 : : XSC_RSS_HASH_BIT_IPV6_SPORT | XSC_RSS_HASH_BIT_IPV6_DPORT,
87 : : };
88 : :
89 : : static uint8_t
90 : 0 : xsc_rss_hash_template_get(struct rte_eth_rss_conf *rss_conf)
91 : : {
92 : : int rss_hf = 0;
93 : : int i = 0;
94 : : uint8_t idx = 0;
95 : : uint8_t outer = 1;
96 : :
97 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_IP) {
98 : : rss_hf |= XSC_RSS_HASH_BIT_IPV4_SIP;
99 : : rss_hf |= XSC_RSS_HASH_BIT_IPV4_DIP;
100 : : rss_hf |= XSC_RSS_HASH_BIT_IPV6_SIP;
101 : : rss_hf |= XSC_RSS_HASH_BIT_IPV6_DIP;
102 : : }
103 : :
104 [ # # ]: 0 : if ((rss_conf->rss_hf & RTE_ETH_RSS_UDP) ||
105 : : (rss_conf->rss_hf & RTE_ETH_RSS_TCP)) {
106 : : rss_hf |= XSC_RSS_HASH_BIT_IPV4_SPORT;
107 : : rss_hf |= XSC_RSS_HASH_BIT_IPV4_DPORT;
108 : : rss_hf |= XSC_RSS_HASH_BIT_IPV6_SPORT;
109 : 0 : rss_hf |= XSC_RSS_HASH_BIT_IPV6_DPORT;
110 : : }
111 : :
112 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_L3_SRC_ONLY) {
113 : : rss_hf |= XSC_RSS_HASH_BIT_IPV4_SIP;
114 : : rss_hf |= XSC_RSS_HASH_BIT_IPV6_SIP;
115 : : rss_hf &= ~XSC_RSS_HASH_BIT_IPV4_DIP;
116 : 0 : rss_hf &= ~XSC_RSS_HASH_BIT_IPV6_DIP;
117 : : }
118 : :
119 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_L3_DST_ONLY) {
120 : : rss_hf |= XSC_RSS_HASH_BIT_IPV4_DIP;
121 : : rss_hf |= XSC_RSS_HASH_BIT_IPV6_DIP;
122 : : rss_hf &= ~XSC_RSS_HASH_BIT_IPV4_SIP;
123 : 0 : rss_hf &= ~XSC_RSS_HASH_BIT_IPV6_SIP;
124 : : }
125 : :
126 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_L4_SRC_ONLY) {
127 : : rss_hf |= XSC_RSS_HASH_BIT_IPV4_SPORT;
128 : : rss_hf |= XSC_RSS_HASH_BIT_IPV6_SPORT;
129 : : rss_hf &= ~XSC_RSS_HASH_BIT_IPV4_DPORT;
130 : 0 : rss_hf &= ~XSC_RSS_HASH_BIT_IPV6_DPORT;
131 : : }
132 : :
133 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_L4_DST_ONLY) {
134 : : rss_hf |= XSC_RSS_HASH_BIT_IPV4_DPORT;
135 : : rss_hf |= XSC_RSS_HASH_BIT_IPV6_DPORT;
136 : : rss_hf &= ~XSC_RSS_HASH_BIT_IPV4_SPORT;
137 : 0 : rss_hf &= ~XSC_RSS_HASH_BIT_IPV6_SPORT;
138 : : }
139 : :
140 : : if ((rss_conf->rss_hf & RTE_ETH_RSS_LEVEL_PMD_DEFAULT) ||
141 : : (rss_conf->rss_hf & RTE_ETH_RSS_LEVEL_OUTERMOST))
142 : : outer = 1;
143 : :
144 [ # # ]: 0 : if (rss_conf->rss_hf & RTE_ETH_RSS_LEVEL_INNERMOST)
145 : : outer = 0;
146 : :
147 [ # # ]: 0 : for (i = 0; i < XSC_HASH_TMPL_IDX_MAX; i++) {
148 [ # # ]: 0 : if (xsc_rss_hash_tmplate[i] == rss_hf) {
149 : 0 : idx = i;
150 : 0 : break;
151 : : }
152 : : }
153 : :
154 : 0 : idx = (idx << 1) | outer;
155 : 0 : return idx;
156 : : }
157 : :
158 : : static int
159 : 0 : xsc_dev_np_exec(struct xsc_dev *xdev, void *cmd, int len, int table, int opmod)
160 : : {
161 : : struct xsc_np_data_tl *tl;
162 : : struct xsc_np_mbox_in *in;
163 : : struct xsc_np_mbox_out *out;
164 : : int in_len;
165 : : int out_len;
166 : : int data_len;
167 : : int cmd_len;
168 : : int ret;
169 : :
170 : 0 : data_len = sizeof(struct xsc_np_data_tl) + len;
171 : 0 : in_len = sizeof(struct xsc_np_mbox_in) + data_len;
172 : 0 : out_len = sizeof(struct xsc_np_mbox_out) + data_len;
173 : 0 : cmd_len = RTE_MAX(in_len, out_len);
174 [ # # ]: 0 : in = malloc(cmd_len);
175 : : memset(in, 0, cmd_len);
176 : : if (in == NULL) {
177 : : rte_errno = ENOMEM;
178 : : PMD_DRV_LOG(ERR, "Failed to alloc np cmd memory");
179 : : return -rte_errno;
180 : : }
181 : :
182 : 0 : in->hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_EXEC_NP);
183 [ # # ]: 0 : in->len = rte_cpu_to_be_16(data_len);
184 : :
185 : : tl = (struct xsc_np_data_tl *)in->data;
186 : 0 : tl->length = len;
187 : 0 : tl->table = table;
188 : 0 : tl->opmod = opmod;
189 [ # # ]: 0 : if (cmd && len)
190 : 0 : memcpy(tl + 1, cmd, len);
191 : :
192 : : out = (struct xsc_np_mbox_out *)in;
193 : 0 : ret = xsc_dev_mailbox_exec(xdev, in, in_len, out, out_len);
194 : :
195 : 0 : free(in);
196 : : return ret;
197 : : }
198 : :
199 : : int
200 : 0 : xsc_dev_create_pct(struct xsc_dev *xdev, int repr_id,
201 : : uint16_t logical_in_port, uint16_t dst_info)
202 : : {
203 : : int ret;
204 : : struct xsc_np_pct_v4_add add;
205 : 0 : struct xsc_repr_port *repr = &xdev->repr_ports[repr_id];
206 : 0 : struct xsc_dev_pct_list *pct_list = &repr->def_pct_list;
207 : :
208 : : memset(&add, 0, sizeof(add));
209 : 0 : add.key.logical_in_port = logical_in_port & XSC_LOGIC_PORT_MASK;
210 : 0 : add.mask.logical_in_port = XSC_LOGIC_PORT_MASK;
211 : 0 : add.action.dst_info = dst_info;
212 : 0 : add.pct_idx = xsc_dev_pct_idx_alloc();
213 [ # # ]: 0 : if (add.pct_idx == XSC_DEV_PCT_IDX_INVALID)
214 : : return -1;
215 : :
216 : 0 : ret = xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_PCT_V4, XSC_NP_OP_ADD);
217 [ # # ]: 0 : if (unlikely(ret != 0)) {
218 : 0 : xsc_dev_pct_idx_free(add.pct_idx);
219 : 0 : return -1;
220 : : }
221 : :
222 : 0 : xsc_dev_pct_entry_insert(pct_list, add.key.logical_in_port, add.pct_idx);
223 : 0 : return 0;
224 : : }
225 : :
226 : : int
227 : 0 : xsc_dev_destroy_pct(struct xsc_dev *xdev, uint16_t logical_in_port, uint32_t pct_idx)
228 : : {
229 : : struct xsc_np_pct_v4_del del;
230 : :
231 : : memset(&del, 0, sizeof(del));
232 : 0 : del.key.logical_in_port = logical_in_port & XSC_LOGIC_PORT_MASK;
233 : 0 : del.mask.logical_in_port = XSC_LOGIC_PORT_MASK;
234 : 0 : del.pct_idx = pct_idx;
235 : 0 : return xsc_dev_np_exec(xdev, &del, sizeof(del), XSC_NP_PCT_V4, XSC_NP_OP_DEL);
236 : : }
237 : :
238 : : void
239 : 0 : xsc_dev_clear_pct(struct xsc_dev *xdev, int repr_id)
240 : : {
241 : : struct xsc_repr_port *repr;
242 : : struct xsc_dev_pct_entry *pct_entry;
243 : : struct xsc_dev_pct_list *pct_list;
244 : :
245 [ # # ]: 0 : if (repr_id == XSC_DEV_REPR_ID_INVALID)
246 : : return;
247 : :
248 : 0 : repr = &xdev->repr_ports[repr_id];
249 : 0 : pct_list = &repr->def_pct_list;
250 : :
251 [ # # ]: 0 : while ((pct_entry = xsc_dev_pct_first_get(pct_list)) != NULL) {
252 : 0 : xsc_dev_destroy_pct(xdev, pct_entry->logic_port, pct_entry->pct_idx);
253 : 0 : xsc_dev_pct_entry_remove(pct_entry);
254 : : }
255 : : }
256 : :
257 : : int
258 : 0 : xsc_dev_create_ipat(struct xsc_dev *xdev, uint16_t logic_in_port, uint16_t dst_info)
259 : : {
260 : : struct xsc_np_ipat add;
261 : :
262 : : memset(&add, 0, sizeof(add));
263 : 0 : add.key.logical_in_port = logic_in_port;
264 : 0 : add.action.dst_info = dst_info;
265 : 0 : add.action.vld = 1;
266 : 0 : return xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_IPAT, XSC_NP_OP_ADD);
267 : : }
268 : :
269 : : int
270 : 0 : xsc_dev_get_ipat_vld(struct xsc_dev *xdev, uint16_t logic_in_port)
271 : : {
272 : : int ret;
273 : : struct xsc_np_ipat get;
274 : :
275 : : memset(&get, 0, sizeof(get));
276 : 0 : get.key.logical_in_port = logic_in_port;
277 : :
278 : 0 : ret = xsc_dev_np_exec(xdev, &get, sizeof(get), XSC_NP_IPAT, XSC_NP_OP_GET);
279 [ # # ]: 0 : if (ret != 0)
280 : 0 : PMD_DRV_LOG(ERR, "Get ipat vld failed, logic in port=%u", logic_in_port);
281 : :
282 : 0 : return get.action.vld;
283 : : }
284 : :
285 : : int
286 : 0 : xsc_dev_destroy_ipat(struct xsc_dev *xdev, uint16_t logic_in_port)
287 : : {
288 : : struct xsc_ipat_key del;
289 : :
290 : : memset(&del, 0, sizeof(del));
291 : 0 : del.logical_in_port = logic_in_port;
292 : 0 : return xsc_dev_np_exec(xdev, &del, sizeof(del), XSC_NP_IPAT, XSC_NP_OP_DEL);
293 : : }
294 : :
295 : : int
296 : 0 : xsc_dev_create_epat(struct xsc_dev *xdev, uint16_t dst_info, uint8_t dst_port,
297 : : uint16_t qpn_ofst, uint8_t qp_num, struct rte_eth_rss_conf *rss_conf)
298 : : {
299 : : struct xsc_np_epat_add add;
300 : :
301 : : memset(&add, 0, sizeof(add));
302 : 0 : add.key.dst_info = dst_info;
303 : 0 : add.action.dst_port = dst_port;
304 : 0 : add.action.vld = 1;
305 : 0 : add.action.rx_qp_id_ofst = qpn_ofst;
306 : 0 : add.action.qp_num = qp_num - 1;
307 : 0 : add.action.rss_en = 1;
308 : 0 : add.action.rss_hash_func = XSC_RSS_HASH_FUNC_TOPELIZ;
309 : 0 : add.action.rss_hash_template = xsc_rss_hash_template_get(rss_conf);
310 : :
311 : 0 : return xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_EPAT, XSC_NP_OP_ADD);
312 : : }
313 : :
314 : : int
315 : 0 : xsc_dev_vf_modify_epat(struct xsc_dev *xdev, uint16_t dst_info, uint16_t qpn_ofst,
316 : : uint8_t qp_num, struct rte_eth_rss_conf *rss_conf)
317 : : {
318 : : struct xsc_np_epat_mod mod;
319 : :
320 : : memset(&mod, 0, sizeof(mod));
321 : 0 : mod.flags = XSC_EPAT_VLD_FLAG | XSC_EPAT_RX_QP_ID_OFST_FLAG |
322 : : XSC_EPAT_QP_NUM_FLAG | XSC_EPAT_HAS_PPH_FLAG |
323 : : XSC_EPAT_RSS_EN_FLAG | XSC_EPAT_RSS_HASH_TEMPLATE_FLAG |
324 : : XSC_EPAT_RSS_HASH_FUNC_FLAG;
325 : :
326 : 0 : mod.key.dst_info = dst_info;
327 : 0 : mod.action.vld = 1;
328 : 0 : mod.action.rx_qp_id_ofst = qpn_ofst;
329 : 0 : mod.action.qp_num = qp_num - 1;
330 : 0 : mod.action.rss_en = 1;
331 : 0 : mod.action.rss_hash_func = XSC_RSS_HASH_FUNC_TOPELIZ;
332 : 0 : mod.action.rss_hash_template = xsc_rss_hash_template_get(rss_conf);
333 : :
334 : 0 : return xsc_dev_np_exec(xdev, &mod, sizeof(mod), XSC_NP_EPAT, XSC_NP_OP_MOD);
335 : : }
336 : :
337 : : int
338 : 0 : xsc_dev_set_qpsetid(struct xsc_dev *xdev, uint32_t txqpn, uint16_t qp_set_id)
339 : : {
340 : : int ret;
341 : : struct xsc_pg_set_id add;
342 : 0 : uint16_t qp_id_base = xdev->hwinfo.raw_qp_id_base;
343 : :
344 : : memset(&add, 0, sizeof(add));
345 : 0 : add.key.qp_id = txqpn - qp_id_base;
346 : 0 : add.action.qp_set_id = qp_set_id;
347 : :
348 : 0 : ret = xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_PG_QP_SET_ID, XSC_NP_OP_ADD);
349 [ # # ]: 0 : if (ret != 0)
350 : 0 : PMD_DRV_LOG(ERR, "Failed to set qp %u setid %u", txqpn, qp_set_id);
351 : :
352 : 0 : return ret;
353 : : }
354 : :
355 : : int
356 : 0 : xsc_dev_destroy_epat(struct xsc_dev *xdev, uint16_t dst_info)
357 : : {
358 : : struct xsc_epat_key del;
359 : :
360 : : memset(&del, 0, sizeof(del));
361 : :
362 : 0 : del.dst_info = dst_info;
363 : 0 : return xsc_dev_np_exec(xdev, &del, sizeof(del), XSC_NP_EPAT, XSC_NP_OP_DEL);
364 : : }
365 : :
366 : : int
367 : 0 : xsc_dev_create_vfos_baselp(struct xsc_dev *xdev)
368 : : {
369 : : int ret;
370 : : struct xsc_np_vfso add;
371 : :
372 : : memset(&add, 0, sizeof(add));
373 : 0 : add.key.src_port = xdev->vfrep_offset;
374 : 0 : add.action.ofst = xdev->vfos_logical_in_port;
375 : :
376 : 0 : ret = xsc_dev_np_exec(xdev, &add, sizeof(add), XSC_NP_VFOS, XSC_NP_OP_ADD);
377 [ # # ]: 0 : if (ret != 0)
378 : 0 : PMD_DRV_LOG(ERR, "Failed to set vfos, port=%u, offset=%u",
379 : : add.key.src_port, add.action.ofst);
380 : :
381 : 0 : return ret;
382 : : }
383 : :
384 : : void
385 : 0 : xsc_dev_pct_uninit(void)
386 : : {
387 : : rte_bitmap_free(xsc_pct_mgr.bmp_pct);
388 : 0 : rte_free(xsc_pct_mgr.bmp_mem);
389 : 0 : }
390 : :
391 : : int
392 : 0 : xsc_dev_pct_init(void)
393 : : {
394 : : int ret;
395 : : uint8_t *bmp_mem;
396 : : uint32_t pos, pct_sz, bmp_sz;
397 : :
398 [ # # ]: 0 : if (xsc_pct_mgr.bmp_mem != NULL)
399 : : return 0;
400 : :
401 : : pct_sz = XSC_DEV_DEF_PCT_IDX_MAX - XSC_DEV_DEF_PCT_IDX_MIN + 1;
402 : 0 : bmp_sz = rte_bitmap_get_memory_footprint(pct_sz);
403 : 0 : bmp_mem = rte_zmalloc(NULL, bmp_sz, RTE_CACHE_LINE_SIZE);
404 [ # # ]: 0 : if (bmp_mem == NULL) {
405 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc pct bitmap memory");
406 : : ret = -ENOMEM;
407 : 0 : goto pct_init_fail;
408 : : }
409 : :
410 : 0 : xsc_pct_mgr.bmp_mem = bmp_mem;
411 : 0 : xsc_pct_mgr.bmp_pct = rte_bitmap_init(pct_sz, bmp_mem, bmp_sz);
412 [ # # ]: 0 : if (xsc_pct_mgr.bmp_pct == NULL) {
413 : 0 : PMD_DRV_LOG(ERR, "Failed to init pct bitmap");
414 : : ret = -EINVAL;
415 : 0 : goto pct_init_fail;
416 : : }
417 : :
418 : : /* Mark all pct bitmap available */
419 [ # # ]: 0 : for (pos = 0; pos < pct_sz; pos++)
420 : 0 : rte_bitmap_set(xsc_pct_mgr.bmp_pct, pos);
421 : :
422 : : return 0;
423 : :
424 : 0 : pct_init_fail:
425 : 0 : xsc_dev_pct_uninit();
426 : 0 : return ret;
427 : : }
428 : :
429 : : uint32_t
430 : 0 : xsc_dev_pct_idx_alloc(void)
431 : : {
432 : : int ret;
433 : 0 : uint64_t slab = 0;
434 : 0 : uint32_t pos = 0;
435 : :
436 : 0 : ret = rte_bitmap_scan(xsc_pct_mgr.bmp_pct, &pos, &slab);
437 [ # # ]: 0 : if (ret != 0) {
438 : 0 : pos += rte_bsf64(slab);
439 : 0 : rte_bitmap_clear(xsc_pct_mgr.bmp_pct, pos);
440 : 0 : return (pos + XSC_DEV_DEF_PCT_IDX_MIN);
441 : : }
442 : :
443 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc xsc pct idx");
444 : 0 : return XSC_DEV_PCT_IDX_INVALID;
445 : : }
446 : :
447 : : void
448 : 0 : xsc_dev_pct_idx_free(uint32_t pct_idx)
449 : : {
450 : 0 : rte_bitmap_set(xsc_pct_mgr.bmp_pct, pct_idx - XSC_DEV_DEF_PCT_IDX_MIN);
451 : 0 : }
452 : :
453 : : int
454 : 0 : xsc_dev_pct_entry_insert(struct xsc_dev_pct_list *pct_list,
455 : : uint32_t logic_port, uint32_t pct_idx)
456 : : {
457 : : struct xsc_dev_pct_entry *pct_entry;
458 : :
459 : 0 : pct_entry = rte_zmalloc(NULL, sizeof(struct xsc_dev_pct_entry), RTE_CACHE_LINE_SIZE);
460 [ # # ]: 0 : if (pct_entry == NULL) {
461 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc pct entry memory");
462 : 0 : return -ENOMEM;
463 : : }
464 : :
465 : 0 : pct_entry->logic_port = logic_port;
466 : 0 : pct_entry->pct_idx = pct_idx;
467 [ # # ]: 0 : LIST_INSERT_HEAD(pct_list, pct_entry, next);
468 : :
469 : 0 : return 0;
470 : : }
471 : :
472 : : struct xsc_dev_pct_entry *
473 : 0 : xsc_dev_pct_first_get(struct xsc_dev_pct_list *pct_list)
474 : : {
475 : : struct xsc_dev_pct_entry *pct_entry;
476 : :
477 : 0 : pct_entry = LIST_FIRST(pct_list);
478 : 0 : return pct_entry;
479 : : }
480 : :
481 : : int
482 : 0 : xsc_dev_pct_entry_remove(struct xsc_dev_pct_entry *pct_entry)
483 : : {
484 [ # # ]: 0 : if (pct_entry == NULL)
485 : : return -1;
486 : :
487 : 0 : xsc_dev_pct_idx_free(pct_entry->pct_idx);
488 [ # # ]: 0 : LIST_REMOVE(pct_entry, next);
489 : 0 : rte_free(pct_entry);
490 : :
491 : 0 : return 0;
492 : : }
|