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