Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include "roc_api.h"
6 : : #include "roc_priv.h"
7 : :
8 : : #define NIX_LSO_FRMT_IPV4_OFFSET_SHFT 3
9 : :
10 : : static void
11 : : nix_lso_tcp(struct nix_lso_format_cfg *req, bool v4)
12 : : {
13 : : __io struct nix_lso_format *field;
14 : :
15 : : /* Format works only with TCP packet marked by OL3/OL4 */
16 : : field = (__io struct nix_lso_format *)&req->fields[0];
17 : 0 : req->field_mask = NIX_LSO_FIELD_MASK;
18 : : /* Outer IPv4/IPv6 */
19 : 0 : field->layer = NIX_TXLAYER_OL3;
20 : 0 : field->offset = v4 ? 2 : 4;
21 : 0 : field->sizem1 = 1; /* 2B */
22 : 0 : field->alg = NIX_LSOALG_ADD_PAYLEN;
23 : : field++;
24 : : if (v4) {
25 : : /* IPID field */
26 : 0 : field->layer = NIX_TXLAYER_OL3;
27 : 0 : field->offset = 4;
28 : 0 : field->sizem1 = 1;
29 : : /* Incremented linearly per segment */
30 : 0 : field->alg = NIX_LSOALG_ADD_SEGNUM;
31 : : field++;
32 : : }
33 : :
34 : : /* TCP sequence number update */
35 : 0 : field->layer = NIX_TXLAYER_OL4;
36 : 0 : field->offset = 4;
37 : 0 : field->sizem1 = 3; /* 4 bytes */
38 : 0 : field->alg = NIX_LSOALG_ADD_OFFSET;
39 : : field++;
40 : : /* TCP flags field */
41 : 0 : field->layer = NIX_TXLAYER_OL4;
42 : 0 : field->offset = 12;
43 : 0 : field->sizem1 = 1;
44 : 0 : field->alg = NIX_LSOALG_TCP_FLAGS;
45 : : field++;
46 : : }
47 : :
48 : : static void
49 : 0 : nix_lso_udp_tun_tcp(struct nix_lso_format_cfg *req, bool outer_v4,
50 : : bool inner_v4)
51 : : {
52 : : __io struct nix_lso_format *field;
53 : :
54 : : field = (__io struct nix_lso_format *)&req->fields[0];
55 : 0 : req->field_mask = NIX_LSO_FIELD_MASK;
56 : : /* Outer IPv4/IPv6 len */
57 : 0 : field->layer = NIX_TXLAYER_OL3;
58 [ # # ]: 0 : field->offset = outer_v4 ? 2 : 4;
59 : 0 : field->sizem1 = 1; /* 2B */
60 : 0 : field->alg = NIX_LSOALG_ADD_PAYLEN;
61 : 0 : field++;
62 [ # # ]: 0 : if (outer_v4) {
63 : : /* IPID */
64 : 0 : field->layer = NIX_TXLAYER_OL3;
65 : 0 : field->offset = 4;
66 : 0 : field->sizem1 = 1;
67 : : /* Incremented linearly per segment */
68 : 0 : field->alg = NIX_LSOALG_ADD_SEGNUM;
69 : 0 : field++;
70 : : }
71 : :
72 : : /* Outer UDP length */
73 : 0 : field->layer = NIX_TXLAYER_OL4;
74 : 0 : field->offset = 4;
75 : 0 : field->sizem1 = 1;
76 : 0 : field->alg = NIX_LSOALG_ADD_PAYLEN;
77 : : field++;
78 : :
79 : : /* Inner IPv4/IPv6 */
80 : 0 : field->layer = NIX_TXLAYER_IL3;
81 [ # # ]: 0 : field->offset = inner_v4 ? 2 : 4;
82 : 0 : field->sizem1 = 1; /* 2B */
83 : 0 : field->alg = NIX_LSOALG_ADD_PAYLEN;
84 : 0 : field++;
85 [ # # ]: 0 : if (inner_v4) {
86 : : /* IPID field */
87 : 0 : field->layer = NIX_TXLAYER_IL3;
88 : 0 : field->offset = 4;
89 : 0 : field->sizem1 = 1;
90 : : /* Incremented linearly per segment */
91 : 0 : field->alg = NIX_LSOALG_ADD_SEGNUM;
92 : 0 : field++;
93 : : }
94 : :
95 : : /* TCP sequence number update */
96 : 0 : field->layer = NIX_TXLAYER_IL4;
97 : 0 : field->offset = 4;
98 : 0 : field->sizem1 = 3; /* 4 bytes */
99 : 0 : field->alg = NIX_LSOALG_ADD_OFFSET;
100 : : field++;
101 : :
102 : : /* TCP flags field */
103 : 0 : field->layer = NIX_TXLAYER_IL4;
104 : 0 : field->offset = 12;
105 : 0 : field->sizem1 = 1;
106 : 0 : field->alg = NIX_LSOALG_TCP_FLAGS;
107 : : field++;
108 : 0 : }
109 : :
110 : : static void
111 : 0 : nix_lso_tun_tcp(struct nix_lso_format_cfg *req, bool outer_v4, bool inner_v4)
112 : : {
113 : : __io struct nix_lso_format *field;
114 : :
115 : : field = (__io struct nix_lso_format *)&req->fields[0];
116 : 0 : req->field_mask = NIX_LSO_FIELD_MASK;
117 : : /* Outer IPv4/IPv6 len */
118 : 0 : field->layer = NIX_TXLAYER_OL3;
119 [ # # ]: 0 : field->offset = outer_v4 ? 2 : 4;
120 : 0 : field->sizem1 = 1; /* 2B */
121 : 0 : field->alg = NIX_LSOALG_ADD_PAYLEN;
122 : 0 : field++;
123 [ # # ]: 0 : if (outer_v4) {
124 : : /* IPID */
125 : 0 : field->layer = NIX_TXLAYER_OL3;
126 : 0 : field->offset = 4;
127 : 0 : field->sizem1 = 1;
128 : : /* Incremented linearly per segment */
129 : 0 : field->alg = NIX_LSOALG_ADD_SEGNUM;
130 : 0 : field++;
131 : : }
132 : :
133 : : /* Inner IPv4/IPv6 */
134 : 0 : field->layer = NIX_TXLAYER_IL3;
135 [ # # ]: 0 : field->offset = inner_v4 ? 2 : 4;
136 : 0 : field->sizem1 = 1; /* 2B */
137 : 0 : field->alg = NIX_LSOALG_ADD_PAYLEN;
138 : 0 : field++;
139 [ # # ]: 0 : if (inner_v4) {
140 : : /* IPID field */
141 : 0 : field->layer = NIX_TXLAYER_IL3;
142 : 0 : field->offset = 4;
143 : 0 : field->sizem1 = 1;
144 : : /* Incremented linearly per segment */
145 : 0 : field->alg = NIX_LSOALG_ADD_SEGNUM;
146 : 0 : field++;
147 : : }
148 : :
149 : : /* TCP sequence number update */
150 : 0 : field->layer = NIX_TXLAYER_IL4;
151 : 0 : field->offset = 4;
152 : 0 : field->sizem1 = 3; /* 4 bytes */
153 : 0 : field->alg = NIX_LSOALG_ADD_OFFSET;
154 : : field++;
155 : :
156 : : /* TCP flags field */
157 : 0 : field->layer = NIX_TXLAYER_IL4;
158 : 0 : field->offset = 12;
159 : 0 : field->sizem1 = 1;
160 : 0 : field->alg = NIX_LSOALG_TCP_FLAGS;
161 : : field++;
162 : 0 : }
163 : :
164 : : int
165 : 0 : roc_nix_lso_alt_flags_profile_setup(struct roc_nix *roc_nix, nix_lso_alt_flg_format_t *fmt)
166 : : {
167 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
168 : : struct dev *dev = &nix->dev;
169 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
170 : : struct nix_lso_alt_flags_cfg_rsp *rsp;
171 : : struct nix_lso_alt_flags_cfg_req *req;
172 : : int rc = -ENOSPC;
173 : :
174 : 0 : req = mbox_alloc_msg_nix_lso_alt_flags_cfg(mbox);
175 [ # # ]: 0 : if (req == NULL)
176 : 0 : goto exit;
177 : :
178 : 0 : req->cfg = fmt->u[0];
179 : 0 : req->cfg1 = fmt->u[1];
180 : :
181 : : rc = mbox_process_msg(mbox, (void *)&rsp);
182 [ # # ]: 0 : if (rc)
183 : 0 : goto exit;
184 : :
185 : 0 : plt_nix_dbg("Setup alt flags format %u", rsp->lso_alt_flags_idx);
186 : 0 : rc = rsp->lso_alt_flags_idx;
187 : 0 : exit:
188 : : mbox_put(mbox);
189 : 0 : return rc;
190 : : }
191 : :
192 : : int
193 : 0 : roc_nix_lso_custom_fmt_setup(struct roc_nix *roc_nix,
194 : : struct nix_lso_format *fields, uint16_t nb_fields)
195 : : {
196 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
197 : : struct dev *dev = &nix->dev;
198 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
199 : : struct nix_lso_format_cfg_rsp *rsp;
200 : : struct nix_lso_format_cfg *req;
201 : : int rc = -ENOSPC;
202 : :
203 [ # # ]: 0 : if (nb_fields > NIX_LSO_FIELD_MAX) {
204 : : rc = -EINVAL;
205 : 0 : goto exit;
206 : : }
207 : :
208 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
209 [ # # ]: 0 : if (req == NULL)
210 : 0 : goto exit;
211 : :
212 : 0 : req->field_mask = NIX_LSO_FIELD_MASK;
213 [ # # ]: 0 : mbox_memcpy(req->fields, fields,
214 : : sizeof(struct nix_lso_format) * nb_fields);
215 : :
216 : : rc = mbox_process_msg(mbox, (void *)&rsp);
217 [ # # ]: 0 : if (rc)
218 : 0 : goto exit;
219 : :
220 : 0 : plt_nix_dbg("Setup custom format %u", rsp->lso_format_idx);
221 : 0 : rc = rsp->lso_format_idx;
222 : 0 : exit:
223 : : mbox_put(mbox);
224 : 0 : return rc;
225 : : }
226 : :
227 : : static int
228 : 0 : nix_lso_ipv4(struct roc_nix *roc_nix)
229 : : {
230 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
231 : : struct nix_lso_format_cfg_rsp *rsp;
232 : : nix_lso_alt_flg_format_t alt_flags;
233 : :
234 : : __io struct nix_lso_format *field;
235 : : struct nix_lso_format_cfg *req;
236 : : int flag_idx = 0, rc = -ENOSPC;
237 : : struct dev *dev = &nix->dev;
238 : : struct mbox *mbox;
239 : :
240 : : /* First get flags profile to update v4 flags */
241 : : memset(&alt_flags, 0, sizeof(alt_flags));
242 : : alt_flags.s.alt_ssf_set = 0;
243 : 0 : alt_flags.s.alt_ssf_mask = 0xFFFF;
244 : 0 : alt_flags.s.alt_fsf_set = 0x2000;
245 : 0 : alt_flags.s.alt_fsf_mask = 0x5FFF;
246 : 0 : alt_flags.s.alt_msf_set = 0x2000;
247 : 0 : alt_flags.s.alt_msf_mask = 0x5FFF;
248 : : alt_flags.s.alt_lsf_set = 0x0000;
249 : 0 : alt_flags.s.alt_lsf_mask = 0x5FFF;
250 : 0 : flag_idx = roc_nix_lso_alt_flags_profile_setup(roc_nix, &alt_flags);
251 [ # # ]: 0 : if (flag_idx < 0)
252 : : return rc;
253 : :
254 : 0 : mbox = mbox_get(dev->mbox);
255 : :
256 : : /*
257 : : * IPv4 Fragmentation
258 : : */
259 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
260 [ # # ]: 0 : if (req == NULL) {
261 : : rc = -ENOSPC;
262 : 0 : goto exit;
263 : : }
264 : :
265 : : /* Format works only with TCP packet marked by OL3/OL4 */
266 : : field = (__io struct nix_lso_format *)&req->fields[0];
267 : 0 : req->field_mask = NIX_LSO_FIELD_MASK;
268 : : /* Update Payload Length */
269 : 0 : field->layer = NIX_TXLAYER_OL3;
270 : 0 : field->offset = 2;
271 : 0 : field->sizem1 = 1; /* 2B */
272 : 0 : field->alg = NIX_LSOALG_ADD_PAYLEN;
273 : : field++;
274 : :
275 : : /* Update fragment offset and flags */
276 : 0 : field->layer = NIX_TXLAYER_OL3;
277 : 0 : field->offset = 6;
278 : 0 : field->sizem1 = 1;
279 : 0 : field->shift = NIX_LSO_FRMT_IPV4_OFFSET_SHFT;
280 : 0 : field->alt_flags_index = flag_idx;
281 : 0 : field->alt_flags = 1;
282 : : /* Cumulative length of previous segments */
283 : 0 : field->alg = NIX_LSOALG_ADD_OFFSET;
284 : : field++;
285 : : rc = mbox_process_msg(mbox, (void *)&rsp);
286 [ # # ]: 0 : if (rc)
287 : 0 : goto exit;
288 : :
289 : : /* IPv4 fragment offset shifted by 3 bits, store this value in profile ID */
290 : 0 : nix->lso_ipv4_idx = (NIX_LSO_FRMT_IPV4_OFFSET_SHFT << 8) | (rsp->lso_format_idx & 0x1F);
291 : 0 : plt_nix_dbg("ipv4 fmt=%u", rsp->lso_format_idx);
292 : 0 : exit:
293 : : mbox_put(mbox);
294 : 0 : return rc;
295 : : }
296 : :
297 : : int
298 : 0 : roc_nix_lso_fmt_setup(struct roc_nix *roc_nix)
299 : : {
300 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
301 : : struct dev *dev = &nix->dev;
302 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
303 : : struct nix_lso_format_cfg_rsp *rsp;
304 : : struct nix_lso_format_cfg *req;
305 : : int rc = -ENOSPC;
306 : :
307 : : /*
308 : : * IPv4/TCP LSO
309 : : */
310 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
311 [ # # ]: 0 : if (req == NULL)
312 : 0 : goto exit;
313 : : nix_lso_tcp(req, true);
314 : : rc = mbox_process_msg(mbox, (void *)&rsp);
315 [ # # ]: 0 : if (rc)
316 : 0 : goto exit;
317 : :
318 [ # # ]: 0 : if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV4) {
319 : : rc = NIX_ERR_INTERNAL;
320 : 0 : goto exit;
321 : : }
322 : :
323 : 0 : plt_nix_dbg("tcpv4 lso fmt=%u", rsp->lso_format_idx);
324 : :
325 : : /*
326 : : * IPv6/TCP LSO
327 : : */
328 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
329 [ # # ]: 0 : if (req == NULL) {
330 : : rc = -ENOSPC;
331 : 0 : goto exit;
332 : : }
333 : : nix_lso_tcp(req, false);
334 : : rc = mbox_process_msg(mbox, (void *)&rsp);
335 [ # # ]: 0 : if (rc)
336 : 0 : goto exit;
337 : :
338 [ # # ]: 0 : if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV6) {
339 : : rc = NIX_ERR_INTERNAL;
340 : 0 : goto exit;
341 : : }
342 : :
343 : 0 : plt_nix_dbg("tcpv6 lso fmt=%u", rsp->lso_format_idx);
344 : :
345 : : /*
346 : : * IPv4/UDP/TUN HDR/IPv4/TCP LSO
347 : : */
348 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
349 [ # # ]: 0 : if (req == NULL) {
350 : : rc = -ENOSPC;
351 : 0 : goto exit;
352 : : }
353 : 0 : nix_lso_udp_tun_tcp(req, true, true);
354 : : rc = mbox_process_msg(mbox, (void *)&rsp);
355 [ # # ]: 0 : if (rc)
356 : 0 : goto exit;
357 : :
358 : 0 : nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V4V4] = rsp->lso_format_idx;
359 : 0 : plt_nix_dbg("udp tun v4v4 fmt=%u", rsp->lso_format_idx);
360 : :
361 : : /*
362 : : * IPv4/UDP/TUN HDR/IPv6/TCP LSO
363 : : */
364 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
365 [ # # ]: 0 : if (req == NULL) {
366 : : rc = -ENOSPC;
367 : 0 : goto exit;
368 : : }
369 : 0 : nix_lso_udp_tun_tcp(req, true, false);
370 : : rc = mbox_process_msg(mbox, (void *)&rsp);
371 [ # # ]: 0 : if (rc)
372 : 0 : goto exit;
373 : :
374 : 0 : nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V4V6] = rsp->lso_format_idx;
375 : 0 : plt_nix_dbg("udp tun v4v6 fmt=%u", rsp->lso_format_idx);
376 : :
377 : : /*
378 : : * IPv6/UDP/TUN HDR/IPv4/TCP LSO
379 : : */
380 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
381 [ # # ]: 0 : if (req == NULL) {
382 : : rc = -ENOSPC;
383 : 0 : goto exit;
384 : : }
385 : 0 : nix_lso_udp_tun_tcp(req, false, true);
386 : : rc = mbox_process_msg(mbox, (void *)&rsp);
387 [ # # ]: 0 : if (rc)
388 : 0 : goto exit;
389 : :
390 : 0 : nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V6V4] = rsp->lso_format_idx;
391 : 0 : plt_nix_dbg("udp tun v6v4 fmt=%u", rsp->lso_format_idx);
392 : :
393 : : /*
394 : : * IPv6/UDP/TUN HDR/IPv6/TCP LSO
395 : : */
396 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
397 [ # # ]: 0 : if (req == NULL) {
398 : : rc = -ENOSPC;
399 : 0 : goto exit;
400 : : }
401 : 0 : nix_lso_udp_tun_tcp(req, false, false);
402 : : rc = mbox_process_msg(mbox, (void *)&rsp);
403 [ # # ]: 0 : if (rc)
404 : 0 : goto exit;
405 : :
406 : 0 : nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V6V6] = rsp->lso_format_idx;
407 : 0 : plt_nix_dbg("udp tun v6v6 fmt=%u", rsp->lso_format_idx);
408 : :
409 : : /*
410 : : * IPv4/TUN HDR/IPv4/TCP LSO
411 : : */
412 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
413 [ # # ]: 0 : if (req == NULL) {
414 : : rc = -ENOSPC;
415 : 0 : goto exit;
416 : : }
417 : 0 : nix_lso_tun_tcp(req, true, true);
418 : : rc = mbox_process_msg(mbox, (void *)&rsp);
419 [ # # ]: 0 : if (rc)
420 : 0 : goto exit;
421 : :
422 : 0 : nix->lso_tun_idx[ROC_NIX_LSO_TUN_V4V4] = rsp->lso_format_idx;
423 : 0 : plt_nix_dbg("tun v4v4 fmt=%u", rsp->lso_format_idx);
424 : :
425 : : /*
426 : : * IPv4/TUN HDR/IPv6/TCP LSO
427 : : */
428 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
429 [ # # ]: 0 : if (req == NULL) {
430 : : rc = -ENOSPC;
431 : 0 : goto exit;
432 : : }
433 : 0 : nix_lso_tun_tcp(req, true, false);
434 : : rc = mbox_process_msg(mbox, (void *)&rsp);
435 [ # # ]: 0 : if (rc)
436 : 0 : goto exit;
437 : :
438 : 0 : nix->lso_tun_idx[ROC_NIX_LSO_TUN_V4V6] = rsp->lso_format_idx;
439 : 0 : plt_nix_dbg("tun v4v6 fmt=%u", rsp->lso_format_idx);
440 : :
441 : : /*
442 : : * IPv6/TUN HDR/IPv4/TCP LSO
443 : : */
444 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
445 [ # # ]: 0 : if (req == NULL) {
446 : : rc = -ENOSPC;
447 : 0 : goto exit;
448 : : }
449 : 0 : nix_lso_tun_tcp(req, false, true);
450 : : rc = mbox_process_msg(mbox, (void *)&rsp);
451 [ # # ]: 0 : if (rc)
452 : 0 : goto exit;
453 : :
454 : 0 : nix->lso_tun_idx[ROC_NIX_LSO_TUN_V6V4] = rsp->lso_format_idx;
455 : 0 : plt_nix_dbg("tun v6v4 fmt=%u", rsp->lso_format_idx);
456 : :
457 : : /*
458 : : * IPv6/TUN HDR/IPv6/TCP LSO
459 : : */
460 : 0 : req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
461 [ # # ]: 0 : if (req == NULL) {
462 : : rc = -ENOSPC;
463 : 0 : goto exit;
464 : : }
465 : :
466 : 0 : nix_lso_tun_tcp(req, false, false);
467 : : rc = mbox_process_msg(mbox, (void *)&rsp);
468 [ # # ]: 0 : if (rc)
469 : 0 : goto exit;
470 : :
471 : 0 : nix->lso_tun_idx[ROC_NIX_LSO_TUN_V6V6] = rsp->lso_format_idx;
472 : 0 : plt_nix_dbg("tun v6v6 fmt=%u", rsp->lso_format_idx);
473 : :
474 : 0 : exit:
475 : : mbox_put(mbox);
476 : :
477 : 0 : nix->lso_ipv4_idx = 0; /* IPv4 fragmentation not supported */
478 [ # # # # ]: 0 : if (!rc && roc_model_is_cn20k())
479 : 0 : return nix_lso_ipv4(roc_nix);
480 : :
481 : : return rc;
482 : : }
483 : :
484 : : int
485 : 0 : roc_nix_lso_fmt_ipv4_frag_get(struct roc_nix *roc_nix)
486 : : {
487 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
488 : :
489 : 0 : return nix->lso_ipv4_idx;
490 : : }
491 : :
492 : : int
493 : 0 : roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
494 : : uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
495 : : uint8_t tun[ROC_NIX_LSO_TUN_MAX])
496 : : {
497 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
498 : :
499 : 0 : memcpy(udp_tun, nix->lso_udp_tun_idx, ROC_NIX_LSO_TUN_MAX);
500 : 0 : memcpy(tun, nix->lso_tun_idx, ROC_NIX_LSO_TUN_MAX);
501 : 0 : return 0;
502 : : }
503 : :
504 : : static int
505 : 0 : skip_size_pkind_get(uint8_t skip_size, uint8_t *pkind)
506 : : {
507 : : struct skip_size_pkind_cfg *cfg;
508 : : const struct plt_memzone *mz;
509 : : int i;
510 : :
511 : 0 : mz = plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE);
512 [ # # ]: 0 : if (!mz)
513 : : return -ENOMEM;
514 : 0 : cfg = mz->addr;
515 : :
516 [ # # ]: 0 : for (i = 0; i < cfg->count; i++) {
517 [ # # ]: 0 : if (cfg->entries[i].skip_size == skip_size) {
518 : 0 : *pkind = cfg->entries[i].pkind;
519 : 0 : return 0;
520 : : }
521 : : }
522 : :
523 [ # # ]: 0 : if (cfg->count >= NPC_SKIP_SIZE_PKIND_MAX) {
524 : 0 : plt_err("skip_size PKIND limit (%d) reached", NPC_SKIP_SIZE_PKIND_MAX);
525 : 0 : return -ENOSPC;
526 : : }
527 : :
528 : : i = cfg->count;
529 : 0 : cfg->entries[i].skip_size = skip_size;
530 : 0 : cfg->entries[i].pkind = NPC_RX_SKIP_SIZE_PKIND + i;
531 : 0 : *pkind = cfg->entries[i].pkind;
532 : 0 : cfg->count++;
533 : 0 : return 0;
534 : : }
535 : :
536 : : int
537 : 0 : roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
538 : : uint8_t pre_l2_size_offset, uint8_t pre_l2_size_offset_mask,
539 : : uint8_t pre_l2_size_shift_dir, uint8_t skip_size)
540 : : {
541 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
542 : : struct dev *dev = &nix->dev;
543 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
544 : : struct npc_set_pkind *req;
545 : : struct msg_resp *rsp;
546 : 0 : uint8_t pkind = 0;
547 : : int rc = -ENOSPC;
548 : :
549 : : if (switch_header_type == 0)
550 : : switch_header_type = ROC_PRIV_FLAGS_DEFAULT;
551 : :
552 : 0 : if (switch_header_type != ROC_PRIV_FLAGS_DEFAULT &&
553 : 0 : switch_header_type != ROC_PRIV_FLAGS_EDSA &&
554 [ # # ]: 0 : switch_header_type != ROC_PRIV_FLAGS_HIGIG &&
555 : 0 : switch_header_type != ROC_PRIV_FLAGS_LEN_90B &&
556 [ # # ]: 0 : switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
557 : 0 : switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
558 [ # # ]: 0 : switch_header_type != ROC_PRIV_FLAGS_PRE_L2 &&
559 : 0 : switch_header_type != ROC_PRIV_FLAGS_SKIP_SIZE &&
560 [ # # ]: 0 : switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
561 : 0 : plt_err("switch header type is not supported");
562 : : rc = NIX_ERR_PARAM;
563 : 0 : goto exit;
564 : : }
565 : :
566 [ # # # # ]: 0 : if (switch_header_type == ROC_PRIV_FLAGS_LEN_90B &&
567 : 0 : !roc_nix_is_sdp(roc_nix)) {
568 : 0 : plt_err("chlen90b is not supported on non-SDP device");
569 : : rc = NIX_ERR_PARAM;
570 : 0 : goto exit;
571 : : }
572 : :
573 [ # # # # ]: 0 : if (switch_header_type == ROC_PRIV_FLAGS_HIGIG &&
574 : 0 : roc_nix_is_vf_or_sdp(roc_nix)) {
575 : 0 : plt_err("higig2 is supported on PF devices only");
576 : : rc = NIX_ERR_PARAM;
577 : 0 : goto exit;
578 : : }
579 : :
580 : 0 : req = mbox_alloc_msg_npc_set_pkind(mbox);
581 [ # # ]: 0 : if (req == NULL)
582 : 0 : goto exit;
583 : 0 : req->mode = switch_header_type;
584 : :
585 [ # # ]: 0 : if (switch_header_type == ROC_PRIV_FLAGS_LEN_90B) {
586 : 0 : req->mode = ROC_PRIV_FLAGS_CUSTOM;
587 : 0 : req->pkind = NPC_RX_CHLEN90B_PKIND;
588 [ # # ]: 0 : } else if (switch_header_type == ROC_PRIV_FLAGS_EXDSA) {
589 : 0 : req->mode = ROC_PRIV_FLAGS_CUSTOM;
590 : 0 : req->pkind = NPC_RX_EXDSA_PKIND;
591 [ # # ]: 0 : } else if (switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
592 : 0 : req->mode = ROC_PRIV_FLAGS_CUSTOM;
593 : 0 : req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
594 [ # # ]: 0 : } else if (switch_header_type == ROC_PRIV_FLAGS_PRE_L2) {
595 : 0 : req->mode = ROC_PRIV_FLAGS_CUSTOM;
596 : 0 : req->pkind = NPC_RX_CUSTOM_PRE_L2_PKIND;
597 : 0 : req->var_len_off = pre_l2_size_offset;
598 : 0 : req->var_len_off_mask = pre_l2_size_offset_mask;
599 : 0 : req->shift_dir = pre_l2_size_shift_dir;
600 [ # # ]: 0 : } else if (switch_header_type == ROC_PRIV_FLAGS_SKIP_SIZE) {
601 : 0 : rc = skip_size_pkind_get(skip_size, &pkind);
602 [ # # ]: 0 : if (rc)
603 : 0 : goto exit;
604 : 0 : req->mode = ROC_PRIV_FLAGS_CUSTOM;
605 : 0 : req->pkind = pkind;
606 : 0 : req->skip_size = skip_size;
607 : : }
608 : :
609 : 0 : req->dir = PKIND_RX;
610 : : rc = mbox_process_msg(mbox, (void *)&rsp);
611 [ # # ]: 0 : if (rc)
612 : 0 : goto exit;
613 : :
614 : 0 : req = mbox_alloc_msg_npc_set_pkind(mbox);
615 [ # # ]: 0 : if (req == NULL) {
616 : : rc = -ENOSPC;
617 : 0 : goto exit;
618 : : }
619 : 0 : req->mode = switch_header_type;
620 : 0 : req->dir = PKIND_TX;
621 : : rc = mbox_process_msg(mbox, (void *)&rsp);
622 : 0 : exit:
623 : : mbox_put(mbox);
624 : 0 : return rc;
625 : : }
626 : :
627 : : int
628 : 0 : roc_nix_eeprom_info_get(struct roc_nix *roc_nix,
629 : : struct roc_nix_eeprom_info *info)
630 : : {
631 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
632 : : struct dev *dev = &nix->dev;
633 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
634 : 0 : struct cgx_fw_data *rsp = NULL;
635 : : int rc;
636 : :
637 [ # # ]: 0 : if (!info) {
638 : 0 : plt_err("Input buffer is NULL");
639 : : rc = NIX_ERR_PARAM;
640 : 0 : goto exit;
641 : : }
642 : :
643 : 0 : mbox_alloc_msg_cgx_get_aux_link_info(mbox);
644 : : rc = mbox_process_msg(mbox, (void *)&rsp);
645 [ # # ]: 0 : if (rc) {
646 : 0 : plt_err("Failed to get fw data: %d", rc);
647 : 0 : goto exit;
648 : : }
649 : :
650 : 0 : info->sff_id = rsp->fwdata.sfp_eeprom.sff_id;
651 : 0 : mbox_memcpy(info->buf, rsp->fwdata.sfp_eeprom.buf, SFP_EEPROM_SIZE);
652 : : rc = 0;
653 : 0 : exit:
654 : : mbox_put(mbox);
655 : 0 : return rc;
656 : : }
657 : :
658 : : int
659 : 0 : roc_nix_rx_drop_re_set(struct roc_nix *roc_nix, bool ena)
660 : : {
661 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
662 : : struct dev *dev = &nix->dev;
663 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
664 : : struct nix_rx_cfg *req;
665 : : int rc = -EIO;
666 : :
667 : : /* No-op if no change */
668 [ # # ]: 0 : if (ena == !!(nix->rx_cfg & ROC_NIX_LF_RX_CFG_DROP_RE)) {
669 : : rc = 0;
670 : 0 : goto exit;
671 : : }
672 : :
673 : 0 : req = mbox_alloc_msg_nix_set_rx_cfg(mbox);
674 [ # # ]: 0 : if (req == NULL)
675 : 0 : goto exit;
676 : :
677 [ # # ]: 0 : if (ena)
678 : 0 : req->len_verify |= NIX_RX_DROP_RE;
679 : : /* Keep other flags intact */
680 [ # # ]: 0 : if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_LEN_OL3)
681 : 0 : req->len_verify |= NIX_RX_OL3_VERIFY;
682 : :
683 [ # # ]: 0 : if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_LEN_OL4)
684 : 0 : req->len_verify |= NIX_RX_OL4_VERIFY;
685 : :
686 [ # # ]: 0 : if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_CSUM_OL4)
687 : 0 : req->csum_verify |= NIX_RX_CSUM_OL4_VERIFY;
688 : :
689 : 0 : rc = mbox_process(mbox);
690 [ # # ]: 0 : if (rc)
691 : 0 : goto exit;
692 : :
693 [ # # ]: 0 : if (ena)
694 : 0 : nix->rx_cfg |= ROC_NIX_LF_RX_CFG_DROP_RE;
695 : : else
696 : 0 : nix->rx_cfg &= ~ROC_NIX_LF_RX_CFG_DROP_RE;
697 : : rc = 0;
698 : 0 : exit:
699 : : mbox_put(mbox);
700 : 0 : return rc;
701 : : }
|