7e8fedd818825473d84082b3a8594a15ec623be1
[dpdk.git] / drivers / net / dpaa2 / dpaa2_sparser.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2018-2019 NXP
3  */
4
5 #include <rte_mbuf.h>
6 #include <rte_ethdev.h>
7 #include <rte_malloc.h>
8 #include <rte_memcpy.h>
9 #include <rte_string_fns.h>
10 #include <rte_dev.h>
11
12 #include <fslmc_logs.h>
13 #include <fslmc_vfio.h>
14 #include <dpaa2_hw_pvt.h>
15 #include <dpaa2_hw_dpio.h>
16 #include <dpaa2_hw_mempool.h>
17 #include <dpaa2_pmd_logs.h>
18
19 #include "dpaa2_ethdev.h"
20 #include "dpaa2_sparser.h"
21 #include "base/dpaa2_hw_dpni_annot.h"
22 #define __STDC_FORMAT_MACROS
23 #include <stdint.h>
24 #include <inttypes.h>
25
26 uint8_t wriop_bytecode[] = {
27         0x00, 0x04, 0x29, 0x42, 0x03, 0xe0, 0x12, 0x00, 0x29, 0x02,
28         0x18, 0x00, 0x87, 0x3c, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00
29 };
30
31 struct frame_attr frame_attr_arr[] = {
32         /* Frame Attribute Flags 1 */
33         /* 000 */ {"Routing header present in IPv6 header 2 ", 0, 0x80000000},
34         /* 001 */ {"GTP Primed was detected                 ", 0, 0x40000000},
35         /* 002 */ {"VLAN with VID = 0 was detected          ", 0, 0x20000000},
36         /* 003 */ {"A PTP frame was detected                ", 0, 0x10000000},
37         /* 004 */ {"VXLAN was parsed                        ", 0, 0x08000000},
38         /* 005 */ {"A VXLAN HXS parsing error was detected  ", 0, 0x04000000},
39         /* 006 */ {"Ethernet control protocol was detected  ", 0, 0x02000000},
40         /* 007 */ {"IKE was detected at UDP port 4500       ", 0, 0x01000000},
41         /* 008 */ {"Shim Shell Soft Parsing Error           ", 0, 0x00800000},
42         /* 009 */ {"Parsing Error                           ", 0, 0x00400000},
43         /* 010 */ {"Ethernet MAC Present                    ", 0, 0x00200000},
44         /* 011 */ {"Ethernet Unicast                        ", 0, 0x00100000},
45         /* 012 */ {"Ethernet Multicast                      ", 0, 0x00080000},
46         /* 013 */ {"Ethernet Broadcast                      ", 0, 0x00040000},
47         /* 014 */ {"BPDU frame (MAC DA is 01:80:C2:00:00:00)", 0, 0x00020000},
48         /* 015 */ {"FCoE detected (Ether type is 0x8906)    ", 0, 0x00010000},
49         /* 016 */ {"FIP detected (Ether type is 0x8914)     ", 0, 0x00008000},
50         /* 017 */ {"Ethernet Parsing Error                  ", 0, 0x00004000},
51         /* 018 */ {"LLC+SNAP Present                        ", 0, 0x00002000},
52         /* 019 */ {"Unknown LLC/OUI                         ", 0, 0x00001000},
53         /* 020 */ {"LLC+SNAP Error                          ", 0, 0x00000800},
54         /* 021 */ {"VLAN 1 Present                          ", 0, 0x00000400},
55         /* 022 */ {"VLAN n Present                          ", 0, 0x00000200},
56         /* 023 */ {"CFI bit in a \"8100\" VLAN tag is set   ", 0, 0x00000100},
57         /* 024 */ {"VLAN Parsing Error                      ", 0, 0x00000080},
58         /* 025 */ {"PPPoE+PPP Present                       ", 0, 0x00000040},
59         /* 026 */ {"PPPoE+PPP Parsing Error                 ", 0, 0x00000020},
60         /* 027 */ {"MPLS 1 Present                          ", 0, 0x00000010},
61         /* 028 */ {"MPLS n Present                          ", 0, 0x00000008},
62         /* 029 */ {"MPLS Parsing Error                      ", 0, 0x00000004},
63         /* 030 */ {"ARP frame Present (Ethertype 0x0806)    ", 0, 0x00000002},
64         /* 031 */ {"ARP Parsing Error                       ", 0, 0x00000001},
65         /* Frame Attribute Flags 2 */
66         /* 032 */ {"L2 Unknown Protocol                     ", 1, 0x80000000},
67         /* 033 */ {"L2 Soft Parsing Error                   ", 1, 0x40000000},
68         /* 034 */ {"IPv4 1 Present                          ", 1, 0x20000000},
69         /* 035 */ {"IPv4 1 Unicast                          ", 1, 0x10000000},
70         /* 036 */ {"IPv4 1 Multicast                        ", 1, 0x08000000},
71         /* 037 */ {"IPv4 1 Broadcast                        ", 1, 0x04000000},
72         /* 038 */ {"IPv4 n Present                          ", 1, 0x02000000},
73         /* 039 */ {"IPv4 n Unicast                          ", 1, 0x01000000},
74         /* 040 */ {"IPv4 n Multicast                        ", 1, 0x00800000},
75         /* 041 */ {"IPv4 n Broadcast                        ", 1, 0x00400000},
76         /* 042 */ {"IPv6 1 Present                          ", 1, 0x00200000},
77         /* 043 */ {"IPv6 1 Unicast                          ", 1, 0x00100000},
78         /* 044 */ {"IPv6 1 Multicast                        ", 1, 0x00080000},
79         /* 045 */ {"IPv6 n Present                          ", 1, 0x00040000},
80         /* 046 */ {"IPv6 n Unicast                          ", 1, 0x00020000},
81         /* 047 */ {"IPv6 n Multicast                        ", 1, 0x00010000},
82         /* 048 */ {"IP 1 option present                     ", 1, 0x00008000},
83         /* 049 */ {"IP 1 Unknown Protocol                   ", 1, 0x00004000},
84         /* 050 */ {"IP 1 Packet is a fragment               ", 1, 0x00002000},
85         /* 051 */ {"IP 1 Packet is an initial fragment      ", 1, 0x00001000},
86         /* 052 */ {"IP 1 Parsing Error                      ", 1, 0x00000800},
87         /* 053 */ {"IP n option present                     ", 1, 0x00000400},
88         /* 054 */ {"IP n Unknown Protocol                   ", 1, 0x00000200},
89         /* 055 */ {"IP n Packet is a fragment               ", 1, 0x00000100},
90         /* 056 */ {"IP n Packet is an initial fragment      ", 1, 0x00000080},
91         /* 057 */ {"ICMP detected (IP proto is 1)           ", 1, 0x00000040},
92         /* 058 */ {"IGMP detected (IP proto is 2)           ", 1, 0x00000020},
93         /* 059 */ {"ICMPv6 detected (IP proto is 3a)        ", 1, 0x00000010},
94         /* 060 */ {"UDP Light detected (IP proto is 136)    ", 1, 0x00000008},
95         /* 061 */ {"IP n Parsing Error                      ", 1, 0x00000004},
96         /* 062 */ {"Min. Encap Present                      ", 1, 0x00000002},
97         /* 063 */ {"Min. Encap S flag set                   ", 1, 0x00000001},
98         /* Frame Attribute Flags 3 */
99         /* 064 */ {"Min. Encap Parsing Error                ", 2, 0x80000000},
100         /* 065 */ {"GRE Present                             ", 2, 0x40000000},
101         /* 066 */ {"GRE R bit set                           ", 2, 0x20000000},
102         /* 067 */ {"GRE Parsing Error                       ", 2, 0x10000000},
103         /* 068 */ {"L3 Unknown Protocol                     ", 2, 0x08000000},
104         /* 069 */ {"L3 Soft Parsing Error                   ", 2, 0x04000000},
105         /* 070 */ {"UDP Present                             ", 2, 0x02000000},
106         /* 071 */ {"UDP Parsing Error                       ", 2, 0x01000000},
107         /* 072 */ {"TCP Present                             ", 2, 0x00800000},
108         /* 073 */ {"TCP options present                     ", 2, 0x00400000},
109         /* 074 */ {"TCP Control bits 6-11 set               ", 2, 0x00200000},
110         /* 075 */ {"TCP Control bits 3-5 set                ", 2, 0x00100000},
111         /* 076 */ {"TCP Parsing Error                       ", 2, 0x00080000},
112         /* 077 */ {"IPSec Present                           ", 2, 0x00040000},
113         /* 078 */ {"IPSec ESP found                         ", 2, 0x00020000},
114         /* 079 */ {"IPSec AH found                          ", 2, 0x00010000},
115         /* 080 */ {"IPSec Parsing Error                     ", 2, 0x00008000},
116         /* 081 */ {"SCTP Present                            ", 2, 0x00004000},
117         /* 082 */ {"SCTP Parsing Error                      ", 2, 0x00002000},
118         /* 083 */ {"DCCP Present                            ", 2, 0x00001000},
119         /* 084 */ {"DCCP Parsing Error                      ", 2, 0x00000800},
120         /* 085 */ {"L4 Unknown Protocol                     ", 2, 0x00000400},
121         /* 086 */ {"L4 Soft Parsing Error                   ", 2, 0x00000200},
122         /* 087 */ {"GTP Present                             ", 2, 0x00000100},
123         /* 088 */ {"GTP Parsing Error                       ", 2, 0x00000080},
124         /* 089 */ {"ESP Present                             ", 2, 0x00000040},
125         /* 090 */ {"ESP Parsing Error                       ", 2, 0x00000020},
126         /* 091 */ {"iSCSI detected (Port# 860)              ", 2, 0x00000010},
127         /* 092 */ {"Capwap-control detected (Port# 5246)    ", 2, 0x00000008},
128         /* 093 */ {"Capwap-data detected (Port# 5247)       ", 2, 0x00000004},
129         /* 094 */ {"L5 Soft Parsing Error                   ", 2, 0x00000002},
130         /* 095 */ {"IPv6 Route hdr1 present                 ", 2, 0x00000001},
131         /* 096 */ {NULL,                                       0, 0x00000000}
132 };
133
134 struct frame_attr_ext frame_attr_ext_arr[] = {
135         /* Frame Attribute Flags Extension */
136         /* 096 */ {"User defined soft parser bit #0         ", 0, 0x8000},
137         /* 096 */ {"User defined soft parser bit #1         ", 0, 0x4000},
138         /* 096 */ {"User defined soft parser bit #2         ", 0, 0x2000},
139         /* 096 */ {"User defined soft parser bit #3         ", 0, 0x1000},
140         /* 096 */ {"User defined soft parser bit #4         ", 0, 0x0800},
141         /* 096 */ {"User defined soft parser bit #5         ", 0, 0x0400},
142         /* 096 */ {"User defined soft parser bit #6         ", 0, 0x0200},
143         /* 096 */ {"User defined soft parser bit #7         ", 0, 0x0100},
144         /* 097 */ {"Reserved                                ", 0, 0x00ff},
145         /* 112 */ {NULL,                                       0, 0x0000}
146 };
147
148 #define SWAP_WORD(pr)                                           \
149 do {                                                            \
150         for (int i = 0; i < 4 ; i++) {                          \
151                 pr[i] = pr[i] ^ pr[6 - i + 1];                  \
152                 pr[6 - i + 1] = pr[6 - i + 1] ^ pr[i];          \
153                 pr[i] = pr[i] ^ pr[6 - i + 1];                  \
154         }                                                       \
155 } while (0)
156
157 #define fa_print_sb()                                           \
158 do {                                                            \
159         if (rte_cpu_to_be_32(*pdw) & frm_attr->fld_mask)        \
160                 DPAA2_PMD_DP_DEBUG("t %s : Yes", frm_attr->fld_name);   \
161 } while (0)
162
163 #define fa_print_sb_ext()                                       \
164 do {                                                            \
165         if (rte_cpu_to_be_16(*pw) & frm_attr_ext->fld_mask)     \
166                 DPAA2_PMD_DP_DEBUG("\t %s : Yes",                       \
167                           frm_attr_ext->fld_name);              \
168 } while (0)
169
170 #define fa_print_mb_ext()                                       \
171 do {                                                            \
172         if (rte_cpu_to_be_16(*pw) & frm_attr_ext->fld_mask)     \
173                 DPAA2_PMD_DP_DEBUG("\t %s : 0x%02x",                    \
174                           frm_attr_ext->fld_name,               \
175                           rte_cpu_to_be_16(*pw) & frm_attr_ext->fld_mask);\
176 } while (0)
177
178 int dpaa2_eth_load_wriop_soft_parser(struct dpaa2_dev_priv *priv,
179                                      enum dpni_soft_sequence_dest dest)
180 {
181         struct fsl_mc_io *dpni = priv->hw;
182         struct dpni_load_ss_cfg     cfg;
183         struct dpni_drv_sparser_param   sp_param;
184         uint8_t *addr;
185         int ret;
186
187         memset(&sp_param, 0, sizeof(sp_param));
188         sp_param.start_pc = priv->ss_offset;
189         sp_param.byte_code = &wriop_bytecode[0];
190         sp_param.size = sizeof(wriop_bytecode);
191
192         cfg.dest = dest;
193         cfg.ss_offset = sp_param.start_pc;
194         cfg.ss_size = sp_param.size;
195
196         addr = rte_malloc(NULL, sp_param.size, 64);
197         if (!addr) {
198                 DPAA2_PMD_ERR("Memory unavailable for soft parser param\n");
199                 return -1;
200         }
201
202         memcpy(addr, sp_param.byte_code, sp_param.size);
203         cfg.ss_iova = (uint64_t)(DPAA2_VADDR_TO_IOVA(addr));
204
205         ret = dpni_load_sw_sequence(dpni, CMD_PRI_LOW, priv->token, &cfg);
206         if (ret) {
207                 DPAA2_PMD_ERR("dpni_load_sw_sequence failed\n");
208                 rte_free(addr);
209                 return ret;
210         }
211
212         priv->ss_iova = (uint64_t)(DPAA2_VADDR_TO_IOVA(addr));
213         priv->ss_offset += sp_param.size;
214         RTE_LOG(INFO, PMD, "Soft parser loaded for dpni@%d\n", priv->hw_id);
215
216         rte_free(addr);
217         return 0;
218 }
219
220 int dpaa2_eth_enable_wriop_soft_parser(struct dpaa2_dev_priv *priv,
221                                        enum dpni_soft_sequence_dest dest)
222 {
223         struct fsl_mc_io *dpni = priv->hw;
224         struct dpni_enable_ss_cfg cfg;
225         uint8_t pa[3];
226         struct dpni_drv_sparser_param sp_param;
227         uint8_t *param_addr = NULL;
228         int ret;
229
230         memset(&sp_param, 0, sizeof(sp_param));
231         pa[0] = 32;     /* Custom Header Length in bytes */
232         sp_param.custom_header_first = 1;
233         sp_param.param_offset = 32;
234         sp_param.param_size = 1;
235         sp_param.start_pc = priv->ss_offset;
236         sp_param.param_array = (uint8_t *)&pa[0];
237
238         cfg.dest = dest;
239         cfg.ss_offset = sp_param.start_pc;
240         cfg.set_start = sp_param.custom_header_first;
241         cfg.hxs = (uint16_t)sp_param.link_to_hard_hxs;
242         cfg.param_offset = sp_param.param_offset;
243         cfg.param_size = sp_param.param_size;
244         if (cfg.param_size) {
245                 param_addr = rte_malloc(NULL, cfg.param_size, 64);
246                 if (!param_addr) {
247                         DPAA2_PMD_ERR("Memory unavailable for soft parser param\n");
248                         return -1;
249                 }
250
251                 memcpy(param_addr, sp_param.param_array, cfg.param_size);
252                 cfg.param_iova = (uint64_t)(DPAA2_VADDR_TO_IOVA(param_addr));
253                 priv->ss_param_iova = cfg.param_iova;
254         } else {
255                 cfg.param_iova = 0;
256         }
257
258         ret = dpni_enable_sw_sequence(dpni, CMD_PRI_LOW, priv->token, &cfg);
259         if (ret) {
260                 DPAA2_PMD_ERR("dpni_enable_sw_sequence failed for dpni%d\n",
261                         priv->hw_id);
262                 rte_free(param_addr);
263                 return ret;
264         }
265
266         rte_free(param_addr);
267         RTE_LOG(INFO, PMD, "Soft parser enabled for dpni@%d\n", priv->hw_id);
268         return 0;
269 }