common/cnxk: update NIX and NPA dump functions
[dpdk.git] / drivers / common / cnxk / roc_nix_ops.c
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 static inline struct mbox *
9 get_mbox(struct roc_nix *roc_nix)
10 {
11         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
12         struct dev *dev = &nix->dev;
13
14         return dev->mbox;
15 }
16
17 static void
18 nix_lso_tcp(struct nix_lso_format_cfg *req, bool v4)
19 {
20         __io struct nix_lso_format *field;
21
22         /* Format works only with TCP packet marked by OL3/OL4 */
23         field = (__io struct nix_lso_format *)&req->fields[0];
24         req->field_mask = NIX_LSO_FIELD_MASK;
25         /* Outer IPv4/IPv6 */
26         field->layer = NIX_TXLAYER_OL3;
27         field->offset = v4 ? 2 : 4;
28         field->sizem1 = 1; /* 2B */
29         field->alg = NIX_LSOALG_ADD_PAYLEN;
30         field++;
31         if (v4) {
32                 /* IPID field */
33                 field->layer = NIX_TXLAYER_OL3;
34                 field->offset = 4;
35                 field->sizem1 = 1;
36                 /* Incremented linearly per segment */
37                 field->alg = NIX_LSOALG_ADD_SEGNUM;
38                 field++;
39         }
40
41         /* TCP sequence number update */
42         field->layer = NIX_TXLAYER_OL4;
43         field->offset = 4;
44         field->sizem1 = 3; /* 4 bytes */
45         field->alg = NIX_LSOALG_ADD_OFFSET;
46         field++;
47         /* TCP flags field */
48         field->layer = NIX_TXLAYER_OL4;
49         field->offset = 12;
50         field->sizem1 = 1;
51         field->alg = NIX_LSOALG_TCP_FLAGS;
52         field++;
53 }
54
55 static void
56 nix_lso_udp_tun_tcp(struct nix_lso_format_cfg *req, bool outer_v4,
57                     bool inner_v4)
58 {
59         __io struct nix_lso_format *field;
60
61         field = (__io struct nix_lso_format *)&req->fields[0];
62         req->field_mask = NIX_LSO_FIELD_MASK;
63         /* Outer IPv4/IPv6 len */
64         field->layer = NIX_TXLAYER_OL3;
65         field->offset = outer_v4 ? 2 : 4;
66         field->sizem1 = 1; /* 2B */
67         field->alg = NIX_LSOALG_ADD_PAYLEN;
68         field++;
69         if (outer_v4) {
70                 /* IPID */
71                 field->layer = NIX_TXLAYER_OL3;
72                 field->offset = 4;
73                 field->sizem1 = 1;
74                 /* Incremented linearly per segment */
75                 field->alg = NIX_LSOALG_ADD_SEGNUM;
76                 field++;
77         }
78
79         /* Outer UDP length */
80         field->layer = NIX_TXLAYER_OL4;
81         field->offset = 4;
82         field->sizem1 = 1;
83         field->alg = NIX_LSOALG_ADD_PAYLEN;
84         field++;
85
86         /* Inner IPv4/IPv6 */
87         field->layer = NIX_TXLAYER_IL3;
88         field->offset = inner_v4 ? 2 : 4;
89         field->sizem1 = 1; /* 2B */
90         field->alg = NIX_LSOALG_ADD_PAYLEN;
91         field++;
92         if (inner_v4) {
93                 /* IPID field */
94                 field->layer = NIX_TXLAYER_IL3;
95                 field->offset = 4;
96                 field->sizem1 = 1;
97                 /* Incremented linearly per segment */
98                 field->alg = NIX_LSOALG_ADD_SEGNUM;
99                 field++;
100         }
101
102         /* TCP sequence number update */
103         field->layer = NIX_TXLAYER_IL4;
104         field->offset = 4;
105         field->sizem1 = 3; /* 4 bytes */
106         field->alg = NIX_LSOALG_ADD_OFFSET;
107         field++;
108
109         /* TCP flags field */
110         field->layer = NIX_TXLAYER_IL4;
111         field->offset = 12;
112         field->sizem1 = 1;
113         field->alg = NIX_LSOALG_TCP_FLAGS;
114         field++;
115 }
116
117 static void
118 nix_lso_tun_tcp(struct nix_lso_format_cfg *req, bool outer_v4, bool inner_v4)
119 {
120         __io struct nix_lso_format *field;
121
122         field = (__io struct nix_lso_format *)&req->fields[0];
123         req->field_mask = NIX_LSO_FIELD_MASK;
124         /* Outer IPv4/IPv6 len */
125         field->layer = NIX_TXLAYER_OL3;
126         field->offset = outer_v4 ? 2 : 4;
127         field->sizem1 = 1; /* 2B */
128         field->alg = NIX_LSOALG_ADD_PAYLEN;
129         field++;
130         if (outer_v4) {
131                 /* IPID */
132                 field->layer = NIX_TXLAYER_OL3;
133                 field->offset = 4;
134                 field->sizem1 = 1;
135                 /* Incremented linearly per segment */
136                 field->alg = NIX_LSOALG_ADD_SEGNUM;
137                 field++;
138         }
139
140         /* Inner IPv4/IPv6 */
141         field->layer = NIX_TXLAYER_IL3;
142         field->offset = inner_v4 ? 2 : 4;
143         field->sizem1 = 1; /* 2B */
144         field->alg = NIX_LSOALG_ADD_PAYLEN;
145         field++;
146         if (inner_v4) {
147                 /* IPID field */
148                 field->layer = NIX_TXLAYER_IL3;
149                 field->offset = 4;
150                 field->sizem1 = 1;
151                 /* Incremented linearly per segment */
152                 field->alg = NIX_LSOALG_ADD_SEGNUM;
153                 field++;
154         }
155
156         /* TCP sequence number update */
157         field->layer = NIX_TXLAYER_IL4;
158         field->offset = 4;
159         field->sizem1 = 3; /* 4 bytes */
160         field->alg = NIX_LSOALG_ADD_OFFSET;
161         field++;
162
163         /* TCP flags field */
164         field->layer = NIX_TXLAYER_IL4;
165         field->offset = 12;
166         field->sizem1 = 1;
167         field->alg = NIX_LSOALG_TCP_FLAGS;
168         field++;
169 }
170
171 int
172 roc_nix_lso_custom_fmt_setup(struct roc_nix *roc_nix,
173                              struct nix_lso_format *fields, uint16_t nb_fields)
174 {
175         struct mbox *mbox = get_mbox(roc_nix);
176         struct nix_lso_format_cfg_rsp *rsp;
177         struct nix_lso_format_cfg *req;
178         int rc = -ENOSPC;
179
180         if (nb_fields > NIX_LSO_FIELD_MAX)
181                 return -EINVAL;
182
183         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
184         if (req == NULL)
185                 return rc;
186
187         req->field_mask = NIX_LSO_FIELD_MASK;
188         mbox_memcpy(req->fields, fields,
189                     sizeof(struct nix_lso_format) * nb_fields);
190
191         rc = mbox_process_msg(mbox, (void *)&rsp);
192         if (rc)
193                 return rc;
194
195         plt_nix_dbg("Setup custom format %u", rsp->lso_format_idx);
196         return rsp->lso_format_idx;
197 }
198
199 int
200 roc_nix_lso_fmt_setup(struct roc_nix *roc_nix)
201 {
202         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
203         struct mbox *mbox = get_mbox(roc_nix);
204         struct nix_lso_format_cfg_rsp *rsp;
205         struct nix_lso_format_cfg *req;
206         int rc = -ENOSPC;
207
208         /*
209          * IPv4/TCP LSO
210          */
211         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
212         if (req == NULL)
213                 return rc;
214         nix_lso_tcp(req, true);
215         rc = mbox_process_msg(mbox, (void *)&rsp);
216         if (rc)
217                 return rc;
218
219         if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV4)
220                 return NIX_ERR_INTERNAL;
221
222         plt_nix_dbg("tcpv4 lso fmt=%u\n", rsp->lso_format_idx);
223
224         /*
225          * IPv6/TCP LSO
226          */
227         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
228         if (req == NULL)
229                 return -ENOSPC;
230         nix_lso_tcp(req, false);
231         rc = mbox_process_msg(mbox, (void *)&rsp);
232         if (rc)
233                 return rc;
234
235         if (rsp->lso_format_idx != NIX_LSO_FORMAT_IDX_TSOV6)
236                 return NIX_ERR_INTERNAL;
237
238         plt_nix_dbg("tcpv6 lso fmt=%u\n", rsp->lso_format_idx);
239
240         /*
241          * IPv4/UDP/TUN HDR/IPv4/TCP LSO
242          */
243         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
244         if (req == NULL)
245                 return -ENOSPC;
246         nix_lso_udp_tun_tcp(req, true, true);
247         rc = mbox_process_msg(mbox, (void *)&rsp);
248         if (rc)
249                 return rc;
250
251         nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V4V4] = rsp->lso_format_idx;
252         plt_nix_dbg("udp tun v4v4 fmt=%u\n", rsp->lso_format_idx);
253
254         /*
255          * IPv4/UDP/TUN HDR/IPv6/TCP LSO
256          */
257         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
258         if (req == NULL)
259                 return -ENOSPC;
260         nix_lso_udp_tun_tcp(req, true, false);
261         rc = mbox_process_msg(mbox, (void *)&rsp);
262         if (rc)
263                 return rc;
264
265         nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V4V6] = rsp->lso_format_idx;
266         plt_nix_dbg("udp tun v4v6 fmt=%u\n", rsp->lso_format_idx);
267
268         /*
269          * IPv6/UDP/TUN HDR/IPv4/TCP LSO
270          */
271         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
272         if (req == NULL)
273                 return -ENOSPC;
274         nix_lso_udp_tun_tcp(req, false, true);
275         rc = mbox_process_msg(mbox, (void *)&rsp);
276         if (rc)
277                 return rc;
278
279         nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V6V4] = rsp->lso_format_idx;
280         plt_nix_dbg("udp tun v6v4 fmt=%u\n", rsp->lso_format_idx);
281
282         /*
283          * IPv6/UDP/TUN HDR/IPv6/TCP LSO
284          */
285         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
286         if (req == NULL)
287                 return -ENOSPC;
288         nix_lso_udp_tun_tcp(req, false, false);
289         rc = mbox_process_msg(mbox, (void *)&rsp);
290         if (rc)
291                 return rc;
292
293         nix->lso_udp_tun_idx[ROC_NIX_LSO_TUN_V6V6] = rsp->lso_format_idx;
294         plt_nix_dbg("udp tun v6v6 fmt=%u\n", rsp->lso_format_idx);
295
296         /*
297          * IPv4/TUN HDR/IPv4/TCP LSO
298          */
299         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
300         if (req == NULL)
301                 return -ENOSPC;
302         nix_lso_tun_tcp(req, true, true);
303         rc = mbox_process_msg(mbox, (void *)&rsp);
304         if (rc)
305                 return rc;
306
307         nix->lso_tun_idx[ROC_NIX_LSO_TUN_V4V4] = rsp->lso_format_idx;
308         plt_nix_dbg("tun v4v4 fmt=%u\n", rsp->lso_format_idx);
309
310         /*
311          * IPv4/TUN HDR/IPv6/TCP LSO
312          */
313         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
314         if (req == NULL)
315                 return -ENOSPC;
316         nix_lso_tun_tcp(req, true, false);
317         rc = mbox_process_msg(mbox, (void *)&rsp);
318         if (rc)
319                 return rc;
320
321         nix->lso_tun_idx[ROC_NIX_LSO_TUN_V4V6] = rsp->lso_format_idx;
322         plt_nix_dbg("tun v4v6 fmt=%u\n", rsp->lso_format_idx);
323
324         /*
325          * IPv6/TUN HDR/IPv4/TCP LSO
326          */
327         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
328         if (req == NULL)
329                 return -ENOSPC;
330         nix_lso_tun_tcp(req, false, true);
331         rc = mbox_process_msg(mbox, (void *)&rsp);
332         if (rc)
333                 return rc;
334
335         nix->lso_tun_idx[ROC_NIX_LSO_TUN_V6V4] = rsp->lso_format_idx;
336         plt_nix_dbg("tun v6v4 fmt=%u\n", rsp->lso_format_idx);
337
338         /*
339          * IPv6/TUN HDR/IPv6/TCP LSO
340          */
341         req = mbox_alloc_msg_nix_lso_format_cfg(mbox);
342         if (req == NULL)
343                 return -ENOSPC;
344         nix_lso_tun_tcp(req, false, false);
345         rc = mbox_process_msg(mbox, (void *)&rsp);
346         if (rc)
347                 return rc;
348
349         nix->lso_tun_idx[ROC_NIX_LSO_TUN_V6V6] = rsp->lso_format_idx;
350         plt_nix_dbg("tun v6v6 fmt=%u\n", rsp->lso_format_idx);
351         return 0;
352 }
353
354 int
355 roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
356                     uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
357                     uint8_t tun[ROC_NIX_LSO_TUN_MAX])
358 {
359         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
360
361         memcpy(udp_tun, nix->lso_udp_tun_idx, ROC_NIX_LSO_TUN_MAX);
362         memcpy(tun, nix->lso_tun_idx, ROC_NIX_LSO_TUN_MAX);
363         return 0;
364 }
365
366 int
367 roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
368                        uint8_t pre_l2_size_offset,
369                        uint8_t pre_l2_size_offset_mask,
370                        uint8_t pre_l2_size_shift_dir)
371 {
372         struct mbox *mbox = get_mbox(roc_nix);
373         struct npc_set_pkind *req;
374         struct msg_resp *rsp;
375         int rc = -ENOSPC;
376
377         if (switch_header_type == 0)
378                 switch_header_type = ROC_PRIV_FLAGS_DEFAULT;
379
380         if (switch_header_type != ROC_PRIV_FLAGS_DEFAULT &&
381             switch_header_type != ROC_PRIV_FLAGS_EDSA &&
382             switch_header_type != ROC_PRIV_FLAGS_HIGIG &&
383             switch_header_type != ROC_PRIV_FLAGS_LEN_90B &&
384             switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
385             switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
386             switch_header_type != ROC_PRIV_FLAGS_PRE_L2 &&
387             switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
388                 plt_err("switch header type is not supported");
389                 return NIX_ERR_PARAM;
390         }
391
392         if (switch_header_type == ROC_PRIV_FLAGS_LEN_90B &&
393             !roc_nix_is_sdp(roc_nix)) {
394                 plt_err("chlen90b is not supported on non-SDP device");
395                 return NIX_ERR_PARAM;
396         }
397
398         if (switch_header_type == ROC_PRIV_FLAGS_HIGIG &&
399             roc_nix_is_vf_or_sdp(roc_nix)) {
400                 plt_err("higig2 is supported on PF devices only");
401                 return NIX_ERR_PARAM;
402         }
403
404         req = mbox_alloc_msg_npc_set_pkind(mbox);
405         if (req == NULL)
406                 return rc;
407         req->mode = switch_header_type;
408
409         if (switch_header_type == ROC_PRIV_FLAGS_LEN_90B) {
410                 req->mode = ROC_PRIV_FLAGS_CUSTOM;
411                 req->pkind = NPC_RX_CHLEN90B_PKIND;
412         } else if (switch_header_type == ROC_PRIV_FLAGS_EXDSA) {
413                 req->mode = ROC_PRIV_FLAGS_CUSTOM;
414                 req->pkind = NPC_RX_EXDSA_PKIND;
415         } else if (switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
416                 req->mode = ROC_PRIV_FLAGS_CUSTOM;
417                 req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
418         } else if (switch_header_type == ROC_PRIV_FLAGS_PRE_L2) {
419                 req->mode = ROC_PRIV_FLAGS_CUSTOM;
420                 req->pkind = NPC_RX_CUSTOM_PRE_L2_PKIND;
421                 req->var_len_off = pre_l2_size_offset;
422                 req->var_len_off_mask = pre_l2_size_offset_mask;
423                 req->shift_dir = pre_l2_size_shift_dir;
424         }
425
426         req->dir = PKIND_RX;
427         rc = mbox_process_msg(mbox, (void *)&rsp);
428         if (rc)
429                 return rc;
430
431         req = mbox_alloc_msg_npc_set_pkind(mbox);
432         if (req == NULL)
433                 return -ENOSPC;
434         req->mode = switch_header_type;
435         req->dir = PKIND_TX;
436         return mbox_process_msg(mbox, (void *)&rsp);
437 }
438
439 int
440 roc_nix_eeprom_info_get(struct roc_nix *roc_nix,
441                         struct roc_nix_eeprom_info *info)
442 {
443         struct mbox *mbox = get_mbox(roc_nix);
444         struct cgx_fw_data *rsp = NULL;
445         int rc;
446
447         if (!info) {
448                 plt_err("Input buffer is NULL");
449                 return NIX_ERR_PARAM;
450         }
451
452         mbox_alloc_msg_cgx_get_aux_link_info(mbox);
453         rc = mbox_process_msg(mbox, (void *)&rsp);
454         if (rc) {
455                 plt_err("Failed to get fw data: %d", rc);
456                 return rc;
457         }
458
459         info->sff_id = rsp->fwdata.sfp_eeprom.sff_id;
460         mbox_memcpy(info->buf, rsp->fwdata.sfp_eeprom.buf, SFP_EEPROM_SIZE);
461         return 0;
462 }
463
464 int
465 roc_nix_rx_drop_re_set(struct roc_nix *roc_nix, bool ena)
466 {
467         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
468         struct mbox *mbox = get_mbox(roc_nix);
469         struct nix_rx_cfg *req;
470         int rc = -EIO;
471
472         /* No-op if no change */
473         if (ena == !!(nix->rx_cfg & ROC_NIX_LF_RX_CFG_DROP_RE))
474                 return 0;
475
476         req = mbox_alloc_msg_nix_set_rx_cfg(mbox);
477         if (req == NULL)
478                 return rc;
479
480         if (ena)
481                 req->len_verify |= NIX_RX_DROP_RE;
482         /* Keep other flags intact */
483         if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_LEN_OL3)
484                 req->len_verify |= NIX_RX_OL3_VERIFY;
485
486         if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_LEN_OL4)
487                 req->len_verify |= NIX_RX_OL4_VERIFY;
488
489         if (nix->rx_cfg & ROC_NIX_LF_RX_CFG_CSUM_OL4)
490                 req->csum_verify |= NIX_RX_CSUM_OL4_VERIFY;
491
492         rc = mbox_process(mbox);
493         if (rc)
494                 return rc;
495
496         if (ena)
497                 nix->rx_cfg |= ROC_NIX_LF_RX_CFG_DROP_RE;
498         else
499                 nix->rx_cfg &= ~ROC_NIX_LF_RX_CFG_DROP_RE;
500         return 0;
501 }