Branch data Line data Source code
1 : : /* * SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright 2019-2021 NXP
4 : : *
5 : : */
6 : :
7 : : #include <time.h>
8 : : #include <net/if.h>
9 : :
10 : : #include <rte_mbuf.h>
11 : : #include <ethdev_driver.h>
12 : : #include <rte_malloc.h>
13 : : #include <rte_memcpy.h>
14 : : #include <rte_string_fns.h>
15 : : #include <rte_cycles.h>
16 : : #include <rte_kvargs.h>
17 : : #include <dev_driver.h>
18 : : #include <bus_fslmc_driver.h>
19 : : #include <rte_flow_driver.h>
20 : :
21 : : #include "dpaa2_pmd_logs.h"
22 : : #include <fslmc_vfio.h>
23 : : #include <dpaa2_hw_pvt.h>
24 : : #include <dpaa2_hw_mempool.h>
25 : : #include <dpaa2_hw_dpio.h>
26 : : #include <mc/fsl_dpmng.h>
27 : : #include "dpaa2_ethdev.h"
28 : : #include "dpaa2_sparser.h"
29 : : #include <fsl_qbman_debug.h>
30 : :
31 : : #include <rte_io.h>
32 : : #include <unistd.h>
33 : : #include <sys/mman.h>
34 : :
35 : : #ifndef PAGE_SIZE
36 : : #define PAGE_SIZE (sysconf(_SC_PAGESIZE))
37 : : #endif
38 : : #define PAGE_MASK (~(PAGE_SIZE - 1))
39 : :
40 : : #define LSX_SERDES_LAN_NB 8
41 : : #define LSX_SERDES_REG_BASE 0x1ea0000
42 : : #define LSX_LB_EN_BIT 0x10000000
43 : :
44 : : #define CONFIG_SYS_IMMR 0x01000000
45 : :
46 : : #define CONFIG_SYS_FSL_GUTS_ADDR (CONFIG_SYS_IMMR + 0x00E00000)
47 : : #define CONFIG_SYS_FSL_SERDES_ADDR (CONFIG_SYS_IMMR + 0xEA0000)
48 : :
49 : : #define FSL_LX_SRDS1_PRTCL_SHIFT 16
50 : : #define FSL_LX_SRDS2_PRTCL_SHIFT 21
51 : : #define FSL_LX_SRDS3_PRTCL_SHIFT 26
52 : :
53 : : #define FSL_LS_SRDS1_PRTCL_SHIFT 16
54 : : #define FSL_LS_SRDS2_PRTCL_SHIFT 0
55 : :
56 : : #define FSL_LX_SRDS1_REGSR 29
57 : : #define FSL_LX_SRDS2_REGSR 29
58 : : #define FSL_LX_SRDS3_REGSR 29
59 : :
60 : : #define FSL_LS_SRDS1_REGSR 29
61 : : #define FSL_LS_SRDS2_REGSR 30
62 : :
63 : : #define FSL_LX_SRDS1_PRTCL_MASK 0x001F0000
64 : : #define FSL_LX_SRDS2_PRTCL_MASK 0x03E00000
65 : : #define FSL_LX_SRDS3_PRTCL_MASK 0x7C000000
66 : :
67 : : #define FSL_LS_SRDS1_PRTCL_MASK 0xFFFF0000
68 : : #define FSL_LS_SRDS2_PRTCL_MASK 0x0000FFFF
69 : :
70 : : struct __rte_packed_begin ccsr_lx_serdes_lan {
71 : : uint8_t unused1[0xa0];
72 : : uint32_t lnatcsr0;
73 : : uint8_t unused2[0x100 - 0xa4];
74 : : } __rte_packed_end;
75 : :
76 : : struct __rte_packed_begin ccsr_lx_serdes {
77 : : uint8_t unused0[0x800];
78 : : struct ccsr_lx_serdes_lan lane[LSX_SERDES_LAN_NB];
79 : : } __rte_packed_end;
80 : :
81 : : struct __rte_packed_begin ccsr_ls_serdes {
82 : : uint8_t unused[0x800];
83 : : struct serdes_lane {
84 : : uint32_t gcr0; /* General Control Register 0 */
85 : : uint32_t gcr1; /* General Control Register 1 */
86 : : uint32_t gcr2; /* General Control Register 2 */
87 : : uint32_t ssc0; /* Speed Switch Control 0 */
88 : : uint32_t rec0; /* Receive Equalization Control 0 */
89 : : uint32_t rec1; /* Receive Equalization Control 1 */
90 : : uint32_t tec0; /* Transmit Equalization Control 0 */
91 : : uint32_t ssc1; /* Speed Switch Control 1 */
92 : : uint32_t ttlc;
93 : : uint32_t rev[6];
94 : : uint32_t tsc3;
95 : : } lane[LSX_SERDES_LAN_NB];
96 : : uint8_t res5[0x19fc - 0xa00];
97 : : } __rte_packed_end;
98 : :
99 : : struct __rte_packed_begin ccsr_gur {
100 : : uint32_t porsr1; /* POR status 1 */
101 : : uint32_t porsr2; /* POR status 2 */
102 : : uint8_t res_008[0x20 - 0x8];
103 : : uint32_t gpporcr1; /* General-purpose POR configuration */
104 : : uint32_t gpporcr2; /* General-purpose POR configuration 2 */
105 : : uint32_t gpporcr3;
106 : : uint32_t gpporcr4;
107 : : uint8_t res_030[0x60 - 0x30];
108 : : uint32_t dcfg_fusesr; /* Fuse status register */
109 : : uint8_t res_064[0x70 - 0x64];
110 : : uint32_t devdisr; /* Device disable control 1 */
111 : : uint32_t devdisr2; /* Device disable control 2 */
112 : : uint32_t devdisr3; /* Device disable control 3 */
113 : : uint32_t devdisr4; /* Device disable control 4 */
114 : : uint32_t devdisr5; /* Device disable control 5 */
115 : : uint32_t devdisr6; /* Device disable control 6 */
116 : : uint8_t res_088[0x94 - 0x88];
117 : : uint32_t coredisr; /* Device disable control 7 */
118 : : uint8_t res_098[0xa0 - 0x98];
119 : : uint32_t pvr; /* Processor version */
120 : : uint32_t svr; /* System version */
121 : : uint8_t res_0a8[0x100 - 0xa8];
122 : : uint32_t rcwsr[30]; /* Reset control word status */
123 : :
124 : : uint8_t res_178[0x200 - 0x178];
125 : : uint32_t scratchrw[16]; /* Scratch Read/Write */
126 : : uint8_t res_240[0x300 - 0x240];
127 : : uint32_t scratchw1r[4]; /* Scratch Read (Write once) */
128 : : uint8_t res_310[0x400 - 0x310];
129 : : uint32_t bootlocptrl; /* Boot location pointer low-order addr */
130 : : uint32_t bootlocptrh; /* Boot location pointer high-order addr */
131 : : uint8_t res_408[0x520 - 0x408];
132 : : uint32_t usb1_amqr;
133 : : uint32_t usb2_amqr;
134 : : uint8_t res_528[0x530 - 0x528]; /* add more registers when needed */
135 : : uint32_t sdmm1_amqr;
136 : : uint32_t sdmm2_amqr;
137 : : uint8_t res_538[0x550 - 0x538]; /* add more registers when needed */
138 : : uint32_t sata1_amqr;
139 : : uint32_t sata2_amqr;
140 : : uint32_t sata3_amqr;
141 : : uint32_t sata4_amqr;
142 : : uint8_t res_560[0x570 - 0x560]; /* add more registers when needed */
143 : : uint32_t misc1_amqr;
144 : : uint8_t res_574[0x590 - 0x574]; /* add more registers when needed */
145 : : uint32_t spare1_amqr;
146 : : uint32_t spare2_amqr;
147 : : uint32_t spare3_amqr;
148 : : uint8_t res_59c[0x620 - 0x59c]; /* add more registers when needed */
149 : : uint32_t gencr[7]; /* General Control Registers */
150 : : uint8_t res_63c[0x640 - 0x63c]; /* add more registers when needed */
151 : : uint32_t cgensr1; /* Core General Status Register */
152 : : uint8_t res_644[0x660 - 0x644]; /* add more registers when needed */
153 : : uint32_t cgencr1; /* Core General Control Register */
154 : : uint8_t res_664[0x740 - 0x664]; /* add more registers when needed */
155 : : uint32_t tp_ityp[64]; /* Topology Initiator Type Register */
156 : : struct {
157 : : uint32_t upper;
158 : : uint32_t lower;
159 : : } tp_cluster[4]; /* Core cluster n Topology Register */
160 : : uint8_t res_864[0x920 - 0x864]; /* add more registers when needed */
161 : : uint32_t ioqoscr[8]; /*I/O Quality of Services Register */
162 : : uint32_t uccr;
163 : : uint8_t res_944[0x960 - 0x944]; /* add more registers when needed */
164 : : uint32_t ftmcr;
165 : : uint8_t res_964[0x990 - 0x964]; /* add more registers when needed */
166 : : uint32_t coredisablesr;
167 : : uint8_t res_994[0xa00 - 0x994]; /* add more registers when needed */
168 : : uint32_t sdbgcr; /*Secure Debug Configuration Register */
169 : : uint8_t res_a04[0xbf8 - 0xa04]; /* add more registers when needed */
170 : : uint32_t ipbrr1;
171 : : uint32_t ipbrr2;
172 : : uint8_t res_858[0x1000 - 0xc00];
173 : : } __rte_packed_end;
174 : :
175 : 0 : static void *lsx_ccsr_map_region(uint64_t addr, size_t len)
176 : : {
177 : : int fd;
178 : : void *tmp;
179 : : uint64_t start;
180 : : uint64_t offset;
181 : :
182 : : fd = open("/dev/mem", O_RDWR);
183 [ # # ]: 0 : if (fd < 0) {
184 : 0 : DPAA2_PMD_ERR("Fail to open /dev/mem");
185 : 0 : return NULL;
186 : : }
187 : :
188 : 0 : start = addr & PAGE_MASK;
189 : 0 : offset = addr - start;
190 : 0 : len = len & PAGE_MASK;
191 [ # # ]: 0 : if (len < (size_t)PAGE_SIZE)
192 : 0 : len = PAGE_SIZE;
193 : :
194 : 0 : tmp = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, start);
195 : :
196 : 0 : close(fd);
197 : :
198 [ # # ]: 0 : if (tmp != MAP_FAILED)
199 : 0 : return (uint8_t *)tmp + offset;
200 : : else
201 : : return NULL;
202 : : }
203 : :
204 : : static const uint8_t ls_sd1_prot_idx_map[] = {
205 : : 0x03, 0x05, 0x07, 0x09, 0x0a, 0x0c, 0x0e,
206 : : 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c,
207 : : 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a,
208 : : 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x33, 0x35,
209 : : 0x37, 0x39, 0x3b, 0x4b, 0x4c, 0x4d, 0x58
210 : : };
211 : :
212 : : static const uint8_t ls_sd2_prot_idx_map[] = {
213 : : 0x07, 0x09, 0x0a, 0x0c, 0x0e, 0x10, 0x12,
214 : : 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
215 : : 0x22, 0x24, 0x3d, 0x3f, 0x41, 0x43, 0x45,
216 : : 0x47, 0x49, 0x4f, 0x50, 0x51, 0x52, 0x53,
217 : : 0x54, 0x55, 0x56, 0x57
218 : : };
219 : :
220 : : static const uint8_t ls_sd1_eth_loopback_support[][LSX_SERDES_LAN_NB] = {
221 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x03*/
222 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x05*/
223 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x07*/
224 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x09*/
225 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0a*/
226 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0c*/
227 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0e*/
228 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x10*/
229 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x12*/
230 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x14*/
231 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x16*/
232 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x18*/
233 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1a*/
234 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1c*/
235 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1e*/
236 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x20*/
237 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x22*/
238 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x24*/
239 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x26*/
240 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x28*/
241 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x2a*/
242 : :
243 : : {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2b*/
244 : : {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2d*/
245 : : {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2e*/
246 : : {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x30*/
247 : :
248 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x32*/
249 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x33*/
250 : :
251 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x35*/
252 : : {1, 1, 0, 0, 0, 0, 0, 0}, /* 0x37*/
253 : :
254 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x39*/
255 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x3b*/
256 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x4b*/
257 : : {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x4c*/
258 : : {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x4d*/
259 : : {0, 0, 0, 0, 0, 0, 1, 1} /* 0x58*/
260 : : };
261 : :
262 : : static const uint8_t ls_sd2_eth_loopback_support[][LSX_SERDES_LAN_NB] = {
263 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x07*/
264 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x09*/
265 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0a*/
266 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0c*/
267 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0e*/
268 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x10*/
269 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x12*/
270 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x14*/
271 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x16*/
272 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x18*/
273 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1a*/
274 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1c*/
275 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1e*/
276 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x20*/
277 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x22*/
278 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x24*/
279 : :
280 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x3d*/
281 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x3f*/
282 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x41*/
283 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x43*/
284 : :
285 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x45*/
286 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x47*/
287 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x49*/
288 : :
289 : : {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x4f*/
290 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x50*/
291 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x51*/
292 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x52*/
293 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x53*/
294 : : {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x54*/
295 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x55*/
296 : : {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x56*/
297 : : {0, 0, 0, 0, 0, 0, 1, 1} /* 0x57*/
298 : : };
299 : :
300 : : enum lsx_serdes_id {
301 : : LSX_SERDES_1 = 1,
302 : : LSX_SERDES_2 = 2
303 : : };
304 : :
305 : : static const uint8_t lx_sd1_loopback_support[][LSX_SERDES_LAN_NB] = {
306 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0 prot*/
307 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 1 prot*/
308 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 2 prot*/
309 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 3 prot*/
310 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 4 prot*/
311 : : {0, 0, 0, 0, 1, 1, 1, 1}, /* 5 prot*/
312 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 6 prot*/
313 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 7 prot*/
314 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 8 prot*/
315 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 9 prot*/
316 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 10 prot*/
317 : : {0, 0, 1, 1, 0, 0, 1, 1}, /* 11 prot*/
318 : : {0, 0, 0, 0, 0, 0, 1, 1}, /* 12 prot*/
319 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 13 prot*/
320 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 14 prot*/
321 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 15 prot*/
322 : : {0, 0, 1, 1, 0, 0, 0, 0}, /* 16 prot*/
323 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 17 prot*/
324 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 18 prot*/
325 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 19 prot*/
326 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 20 prot*/
327 : : {1, 1, 1, 1, 0, 0, 1, 1}, /* 21 prot*/
328 : : {1, 1, 1, 1, 0, 0, 1, 1} /* 22 prot*/
329 : : };
330 : :
331 : : static const uint8_t lx_sd2_loopback_support[][LSX_SERDES_LAN_NB] = {
332 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 0 prot*/
333 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 1 prot*/
334 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 2 prot*/
335 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 3 prot*/
336 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 4 prot*/
337 : : {0, 0, 0, 0, 0, 0, 0, 0}, /* 5 prot*/
338 : : {0, 0, 0, 0, 1, 1, 1, 1}, /* 6 prot*/
339 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 7 prot*/
340 : : {0, 0, 0, 0, 0, 0, 1, 1}, /* 8 prot*/
341 : : {1, 1, 1, 1, 1, 1, 1, 1}, /* 9 prot*/
342 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 10 prot*/
343 : : {0, 1, 1, 1, 0, 1, 1, 1}, /* 11 prot*/
344 : : {1, 1, 1, 1, 0, 0, 0, 0}, /* 12 prot*/
345 : : {0, 0, 0, 0, 0, 0, 1, 1}, /* 13 prot*/
346 : : {0, 0, 1, 1, 0, 0, 1, 1} /* 14 prot*/
347 : : };
348 : :
349 : : static inline int
350 : : ls_mac_to_serdes_id(uint8_t mac_id)
351 : : {
352 : 0 : if (mac_id >= 1 && mac_id <= 8)
353 : : return LSX_SERDES_1;
354 [ # # ]: 0 : if (mac_id >= 9 && mac_id <= 16)
355 : : return LSX_SERDES_2;
356 : :
357 : : return -1;
358 : : }
359 : :
360 : : static inline int
361 : : lx_mac_to_serdes_id(uint8_t mac_id)
362 : : {
363 : 0 : if (mac_id >= 1 && mac_id <= 10)
364 : : return LSX_SERDES_1;
365 [ # # ]: 0 : if (mac_id >= 11 && mac_id <= 18)
366 : : return LSX_SERDES_2;
367 : :
368 : : return -1;
369 : : }
370 : :
371 : : static inline int
372 : : ls_serdes_cfg_to_idx(uint8_t sd_cfg, int sd_id)
373 : : {
374 : : int i;
375 : :
376 : 0 : if (sd_id == LSX_SERDES_1) {
377 [ # # ]: 0 : for (i = 0; i < (int)sizeof(ls_sd1_prot_idx_map); i++) {
378 [ # # ]: 0 : if (ls_sd1_prot_idx_map[i] == sd_cfg)
379 : : return i;
380 : : }
381 : : } else if (sd_id == LSX_SERDES_2) {
382 [ # # ]: 0 : for (i = 0; i < (int)sizeof(ls_sd2_prot_idx_map); i++) {
383 [ # # ]: 0 : if (ls_sd2_prot_idx_map[i] == sd_cfg)
384 : : return i;
385 : : }
386 : : }
387 : :
388 : : return -1;
389 : : }
390 : :
391 : : static inline int
392 : : lx_serdes_cfg_to_idx(uint8_t sd_cfg, int sd_id __rte_unused)
393 : : {
394 : : return sd_cfg;
395 : : }
396 : :
397 : : static inline int
398 : 0 : ls_mac_serdes_lpbk_support(uint16_t mac_id,
399 : : uint16_t *serdes_id, uint16_t *lan_id)
400 : : {
401 : : struct ccsr_gur *gur_base =
402 : 0 : lsx_ccsr_map_region(CONFIG_SYS_FSL_GUTS_ADDR,
403 : : sizeof(struct ccsr_gur) / 64 * 64 + 64);
404 : : uint32_t sd_cfg;
405 : : int sd_id, sd_idx;
406 : : uint16_t lan_id_tmp = 0;
407 : : const uint8_t *ls_sd_loopback_support;
408 : :
409 [ # # ]: 0 : sd_id = ls_mac_to_serdes_id(mac_id);
410 : :
411 : : if (sd_id == LSX_SERDES_1) {
412 : : sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LS_SRDS1_REGSR - 1]) &
413 : : FSL_LS_SRDS1_PRTCL_MASK;
414 : : sd_cfg >>= FSL_LS_SRDS1_PRTCL_SHIFT;
415 [ # # ]: 0 : } else if (sd_id == LSX_SERDES_2) {
416 : 0 : sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LS_SRDS2_REGSR - 1]) &
417 : : FSL_LS_SRDS2_PRTCL_MASK;
418 : : sd_cfg >>= FSL_LS_SRDS2_PRTCL_SHIFT;
419 : : } else {
420 : : return false;
421 : : }
422 : 0 : sd_cfg = sd_cfg & 0xff;
423 : :
424 [ # # ]: 0 : sd_idx = ls_serdes_cfg_to_idx(sd_cfg, sd_id);
425 [ # # ]: 0 : if (sd_idx < 0) {
426 : 0 : DPAA2_PMD_ERR("Serdes protocol(0x%02x) does not exist",
427 : : sd_cfg);
428 : 0 : return false;
429 : : }
430 : :
431 [ # # ]: 0 : if (sd_id == LSX_SERDES_1) {
432 : 0 : ls_sd_loopback_support =
433 : : &ls_sd1_eth_loopback_support[sd_idx][0];
434 : : } else {
435 : 0 : ls_sd_loopback_support =
436 : : &ls_sd2_eth_loopback_support[sd_idx][0];
437 : : }
438 : :
439 [ # # ]: 0 : if (sd_id == LSX_SERDES_1)
440 : 0 : lan_id_tmp = (mac_id - 1);
441 : : else
442 : 0 : lan_id_tmp = (mac_id - 9);
443 : :
444 [ # # ]: 0 : if (lan_id_tmp >= LSX_SERDES_LAN_NB) {
445 : 0 : DPAA2_PMD_ERR("Invalid serdes lan(%d).", lan_id_tmp);
446 : 0 : return false;
447 : : }
448 : :
449 [ # # ]: 0 : if (!ls_sd_loopback_support[lan_id_tmp])
450 : : return false;
451 : :
452 [ # # ]: 0 : if (lan_id)
453 : 0 : *lan_id = lan_id_tmp;
454 [ # # ]: 0 : if (serdes_id)
455 : 0 : *serdes_id = sd_id;
456 : :
457 : : return true;
458 : : }
459 : :
460 : : static inline int
461 : 0 : lx_mac_serdes_lpbk_support(uint16_t mac_id,
462 : : uint16_t *serdes_id, uint16_t *lan_id)
463 : : {
464 : : struct ccsr_gur *gur_base =
465 : 0 : lsx_ccsr_map_region(CONFIG_SYS_FSL_GUTS_ADDR,
466 : : sizeof(struct ccsr_gur) / 64 * 64 + 64);
467 : : uint32_t sd_cfg;
468 : : int sd_id, sd_idx;
469 : : uint16_t lan_id_tmp = 0;
470 : : const uint8_t *lx_sd_loopback_support;
471 : :
472 [ # # ]: 0 : sd_id = lx_mac_to_serdes_id(mac_id);
473 : :
474 : : if (sd_id == LSX_SERDES_1) {
475 : : sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LX_SRDS1_REGSR - 1]) &
476 : : FSL_LX_SRDS1_PRTCL_MASK;
477 : 0 : sd_cfg >>= FSL_LX_SRDS1_PRTCL_SHIFT;
478 [ # # ]: 0 : } else if (sd_id == LSX_SERDES_2) {
479 : : sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LX_SRDS2_REGSR - 1]) &
480 : : FSL_LX_SRDS2_PRTCL_MASK;
481 : 0 : sd_cfg >>= FSL_LX_SRDS2_PRTCL_SHIFT;
482 : : } else {
483 : : return false;
484 : : }
485 : : sd_cfg = sd_cfg & 0xff;
486 : :
487 : 0 : sd_idx = lx_serdes_cfg_to_idx(sd_cfg, sd_id);
488 : : if (sd_idx < 0)
489 : : return false;
490 : :
491 [ # # ]: 0 : if (sd_id == LSX_SERDES_1)
492 : 0 : lx_sd_loopback_support = &lx_sd1_loopback_support[sd_idx][0];
493 : : else
494 : 0 : lx_sd_loopback_support = &lx_sd2_loopback_support[sd_idx][0];
495 : :
496 [ # # ]: 0 : if (sd_id == LSX_SERDES_1) {
497 [ # # ]: 0 : if (mac_id == 1)
498 : : lan_id_tmp = 0;
499 [ # # ]: 0 : else if (mac_id == 2)
500 : : lan_id_tmp = 4;
501 : : else
502 : 0 : lan_id_tmp = (mac_id - 3);
503 : : } else {
504 : : if (mac_id == 11)
505 : : lan_id_tmp = 0;
506 : : else if (mac_id == 12)
507 : : lan_id_tmp = 1;
508 : : else if (mac_id == 13)
509 : : lan_id_tmp = 6;
510 : : else if (mac_id == 14)
511 : : lan_id_tmp = 7;
512 : : else if (mac_id == 15)
513 : : lan_id_tmp = 4;
514 : : else if (mac_id == 16)
515 : : lan_id_tmp = 5;
516 : : else if (mac_id == 17)
517 : : lan_id_tmp = 2;
518 : : else if (mac_id == 18)
519 : : lan_id_tmp = 3;
520 : : else
521 : : return false;
522 : : }
523 : :
524 [ # # ]: 0 : if (lan_id_tmp >= LSX_SERDES_LAN_NB)
525 : : return false;
526 : :
527 [ # # ]: 0 : if (!lx_sd_loopback_support[lan_id_tmp])
528 : : return false;
529 : :
530 [ # # ]: 0 : if (lan_id)
531 : 0 : *lan_id = lan_id_tmp;
532 [ # # ]: 0 : if (serdes_id)
533 : 0 : *serdes_id = sd_id;
534 : :
535 : : return true;
536 : : }
537 : :
538 : : static inline int
539 : 0 : ls_serdes_eth_lpbk(uint16_t mac_id, int en)
540 : : {
541 : : uint16_t serdes_id, lan_id;
542 : : int ret;
543 : : uint32_t data;
544 : : struct ccsr_ls_serdes *serdes_base;
545 : : void *reg = 0;
546 : :
547 : 0 : ret = ls_mac_serdes_lpbk_support(mac_id, &serdes_id, &lan_id);
548 [ # # ]: 0 : if (!ret)
549 : : return -ENOTSUP;
550 : :
551 : 0 : serdes_base = lsx_ccsr_map_region(CONFIG_SYS_FSL_SERDES_ADDR +
552 : : (serdes_id - LSX_SERDES_1) * 0x10000,
553 : : sizeof(struct ccsr_ls_serdes) / 64 * 64 + 64);
554 [ # # ]: 0 : if (!serdes_base) {
555 : 0 : DPAA2_PMD_ERR("Serdes register map failed");
556 : 0 : return -ENOMEM;
557 : : }
558 : :
559 [ # # ]: 0 : if (serdes_id == LSX_SERDES_1)
560 : 0 : lan_id = LSX_SERDES_LAN_NB - lan_id - 1;
561 : :
562 : 0 : reg = &serdes_base->lane[lan_id].tsc3;
563 : :
564 : : data = rte_read32(reg);
565 [ # # ]: 0 : if (en)
566 : 0 : rte_write32(data | LSX_LB_EN_BIT, reg);
567 : : else
568 : 0 : rte_write32(data & (~LSX_LB_EN_BIT), reg);
569 : :
570 : : return 0;
571 : : }
572 : :
573 : : static inline int
574 : 0 : lx_serdes_eth_lpbk(uint16_t mac_id, int en)
575 : : {
576 : 0 : uint16_t serdes_id = 0xffff, lan_id = 0xffff;
577 : : int ret;
578 : : uint32_t data;
579 : : struct ccsr_lx_serdes *serdes_base;
580 : : void *reg = 0;
581 : :
582 : 0 : ret = lx_mac_serdes_lpbk_support(mac_id, &serdes_id, &lan_id);
583 [ # # ]: 0 : if (!ret)
584 : : return -ENOTSUP;
585 : :
586 : 0 : serdes_base = lsx_ccsr_map_region(CONFIG_SYS_FSL_SERDES_ADDR +
587 : : (serdes_id - LSX_SERDES_1) * 0x10000,
588 : : sizeof(struct ccsr_lx_serdes) / 64 * 64 + 64);
589 [ # # ]: 0 : if (!serdes_base) {
590 : 0 : DPAA2_PMD_ERR("Serdes register map failed");
591 : 0 : return -ENOMEM;
592 : : }
593 : :
594 [ # # ]: 0 : if (serdes_id == LSX_SERDES_1)
595 : 0 : lan_id = LSX_SERDES_LAN_NB - lan_id - 1;
596 : :
597 : 0 : reg = &serdes_base->lane[lan_id].lnatcsr0;
598 : :
599 : : data = rte_read32(reg);
600 [ # # ]: 0 : if (en)
601 : 0 : rte_write32(data | LSX_LB_EN_BIT, reg);
602 : : else
603 : 0 : rte_write32(data & (~LSX_LB_EN_BIT), reg);
604 : :
605 : : return 0;
606 : : }
607 : :
608 : : /* Configure dpaa2 port as recycle port */
609 : : int
610 : 0 : dpaa2_dev_recycle_config(struct rte_eth_dev *eth_dev)
611 : : {
612 : 0 : struct rte_device *dev = eth_dev->device;
613 : 0 : struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
614 : : struct rte_dpaa2_device *dpaa2_dev =
615 : 0 : container_of(dev, struct rte_dpaa2_device, device);
616 : 0 : struct fsl_mc_io *dpni_dev = eth_dev->process_private;
617 : : struct dpni_port_cfg port_cfg;
618 : : int ret;
619 : :
620 [ # # ]: 0 : if (priv->flags & DPAA2_TX_LOOPBACK_MODE) {
621 : 0 : DPAA2_PMD_INFO("%s has been configured recycle device.",
622 : : eth_dev->data->name);
623 : :
624 : 0 : return 0;
625 : : }
626 : :
627 [ # # ]: 0 : if (dpaa2_dev->ep_dev_type == DPAA2_MAC) {
628 : : /** For dpmac-dpni connection,
629 : : * try setting serdes loopback as recycle device at first.
630 : : */
631 [ # # ]: 0 : if (dpaa2_svr_family == SVR_LS2088A) {
632 : 0 : ret = ls_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 1);
633 [ # # ]: 0 : if (!ret) {
634 : 0 : priv->flags |= DPAA2_TX_SERDES_LOOPBACK_MODE;
635 : 0 : return 0;
636 : : }
637 [ # # ]: 0 : } else if (dpaa2_svr_family == SVR_LX2160A) {
638 : 0 : ret = lx_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 1);
639 [ # # ]: 0 : if (!ret) {
640 : 0 : priv->flags |= DPAA2_TX_SERDES_LOOPBACK_MODE;
641 : 0 : return 0;
642 : : }
643 : : } else {
644 : 0 : DPAA2_PMD_DEBUG("Serdes loopback not support SoC(0x%08x)",
645 : : dpaa2_svr_family);
646 : : }
647 : :
648 : : /** If serdes loopback is not supported for this mac,
649 : : * trying set mac loopback.
650 : : */
651 : :
652 : 0 : port_cfg.loopback_en = 1;
653 : 0 : ret = dpni_set_port_cfg(dpni_dev, CMD_PRI_LOW,
654 : 0 : priv->token,
655 : : DPNI_PORT_CFG_LOOPBACK,
656 : : &port_cfg);
657 [ # # ]: 0 : if (ret) {
658 : 0 : DPAA2_PMD_ERR("Error(%d) to enable loopback", ret);
659 : 0 : return -ENOTSUP;
660 : : }
661 : :
662 : 0 : priv->flags |= DPAA2_TX_MAC_LOOPBACK_MODE;
663 : :
664 : 0 : return 0;
665 : : }
666 : :
667 [ # # ]: 0 : if (dpaa2_dev->ep_dev_type == DPAA2_ETH &&
668 [ # # ]: 0 : dpaa2_dev->object_id == dpaa2_dev->ep_object_id) {
669 : 0 : priv->flags |= DPAA2_TX_DPNI_LOOPBACK_MODE;
670 : :
671 : 0 : return 0;
672 : : }
673 : :
674 : : return -ENOTSUP;
675 : : }
676 : :
677 : : int
678 : 0 : dpaa2_dev_recycle_deconfig(struct rte_eth_dev *eth_dev)
679 : : {
680 : 0 : struct rte_device *dev = eth_dev->device;
681 : 0 : struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
682 : : struct rte_dpaa2_device *dpaa2_dev =
683 : 0 : container_of(dev, struct rte_dpaa2_device, device);
684 : 0 : struct fsl_mc_io *dpni_dev = eth_dev->process_private;
685 : : struct dpni_port_cfg port_cfg;
686 : : int ret = 0;
687 : :
688 [ # # ]: 0 : if (!(priv->flags & DPAA2_TX_LOOPBACK_MODE))
689 : : return 0;
690 : :
691 [ # # ]: 0 : if (priv->flags & DPAA2_TX_SERDES_LOOPBACK_MODE) {
692 [ # # ]: 0 : if (dpaa2_svr_family == SVR_LS2088A) {
693 : 0 : ret = ls_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 0);
694 [ # # ]: 0 : if (ret) {
695 : 0 : DPAA2_PMD_WARN("Error(%d) to disable Serdes loopback",
696 : : ret);
697 : : } else {
698 : 0 : priv->flags &= ~DPAA2_TX_SERDES_LOOPBACK_MODE;
699 : : }
700 [ # # ]: 0 : } else if (dpaa2_svr_family == SVR_LX2160A) {
701 : 0 : ret = lx_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 0);
702 [ # # ]: 0 : if (ret) {
703 : 0 : DPAA2_PMD_WARN("Error(%d) to disable Serdes loopback",
704 : : ret);
705 : : } else {
706 : 0 : priv->flags &= ~DPAA2_TX_SERDES_LOOPBACK_MODE;
707 : : }
708 : : } else {
709 : 0 : DPAA2_PMD_DEBUG("Serdes loopback not support SoC(0x%08x)",
710 : : dpaa2_svr_family);
711 : : }
712 : : }
713 : :
714 [ # # ]: 0 : if (priv->flags & DPAA2_TX_MAC_LOOPBACK_MODE) {
715 : 0 : port_cfg.loopback_en = 0;
716 : 0 : ret = dpni_set_port_cfg(dpni_dev, CMD_PRI_LOW,
717 : 0 : priv->token,
718 : : DPNI_PORT_CFG_LOOPBACK,
719 : : &port_cfg);
720 [ # # ]: 0 : if (ret) {
721 : 0 : DPAA2_PMD_ERR("Error(%d) to disable TX mac loopback",
722 : : ret);
723 : : } else {
724 : 0 : priv->flags &= ~DPAA2_TX_MAC_LOOPBACK_MODE;
725 : : }
726 : : }
727 : :
728 [ # # ]: 0 : if (priv->flags & DPAA2_TX_DPNI_LOOPBACK_MODE)
729 : 0 : priv->flags &= ~DPAA2_TX_DPNI_LOOPBACK_MODE;
730 : :
731 : : return ret;
732 : : }
733 : :
734 : : int
735 : 0 : dpaa2_dev_recycle_qp_setup(struct rte_dpaa2_device *dpaa2_dev,
736 : : uint16_t qidx, uint64_t cntx,
737 : : eth_rx_burst_t tx_lpbk, eth_tx_burst_t rx_lpbk,
738 : : struct dpaa2_queue **txq,
739 : : struct dpaa2_queue **rxq)
740 : : {
741 : : struct rte_eth_dev *dev;
742 : : struct rte_eth_dev_data *data;
743 : : struct dpaa2_queue *txq_tmp;
744 : : struct dpaa2_queue *rxq_tmp;
745 : : struct dpaa2_dev_priv *priv;
746 : :
747 : 0 : dev = dpaa2_dev->eth_dev;
748 : 0 : data = dev->data;
749 : 0 : priv = data->dev_private;
750 : :
751 [ # # ]: 0 : if (!(priv->flags & DPAA2_TX_LOOPBACK_MODE) &&
752 [ # # ]: 0 : (tx_lpbk || rx_lpbk)) {
753 : 0 : DPAA2_PMD_ERR("%s is NOT recycle device!", data->name);
754 : :
755 : 0 : return -EINVAL;
756 : : }
757 : :
758 [ # # # # ]: 0 : if (qidx >= data->nb_rx_queues || qidx >= data->nb_tx_queues)
759 : : return -EINVAL;
760 : :
761 : 0 : rte_spinlock_lock(&priv->lpbk_qp_lock);
762 : :
763 [ # # ]: 0 : if (tx_lpbk)
764 : 0 : dev->tx_pkt_burst = tx_lpbk;
765 : :
766 [ # # ]: 0 : if (rx_lpbk)
767 : 0 : dev->rx_pkt_burst = rx_lpbk;
768 : :
769 : 0 : txq_tmp = data->tx_queues[qidx];
770 : 0 : txq_tmp->lpbk_cntx = cntx;
771 : 0 : rxq_tmp = data->rx_queues[qidx];
772 : 0 : rxq_tmp->lpbk_cntx = cntx;
773 : :
774 [ # # ]: 0 : if (txq)
775 : 0 : *txq = txq_tmp;
776 [ # # ]: 0 : if (rxq)
777 : 0 : *rxq = rxq_tmp;
778 : :
779 : : rte_spinlock_unlock(&priv->lpbk_qp_lock);
780 : :
781 : 0 : return 0;
782 : : }
|