dec15866b0460d906f0e05c45bdbecf8d637fbca
[openwrt/staging/wigyori.git] / target / linux / octeon / patches / 011-octeon_ethernet_driver.patch
1 The octeon-ethernet driver supports the sgmii, rgmii, spi, and xaui
2 ports present on the Cavium OCTEON family of SOCs. These SOCs are
3 multi-core mips64 processors with existing support over in arch/mips.
4
5 The driver files can be categorized into three basic groups:
6
7 1) Register definitions, these are named cvmx-*-defs.h
8
9 2) Main driver code, these have names that don't start cvmx-.
10
11 3) Interface specific functions and other utility code, names starting
12 with cvmx-
13
14 Signed-off-by: David Daney <ddaney@caviumnetworks.com>
15 ---
16 drivers/staging/octeon/Kconfig | 12 +
17 drivers/staging/octeon/Makefile | 30 +
18 drivers/staging/octeon/cvmx-address.h | 274 +++
19 drivers/staging/octeon/cvmx-asxx-defs.h | 475 +++++
20 drivers/staging/octeon/cvmx-cmd-queue.c | 306 +++
21 drivers/staging/octeon/cvmx-cmd-queue.h | 617 ++++++
22 drivers/staging/octeon/cvmx-config.h | 169 ++
23 drivers/staging/octeon/cvmx-dbg-defs.h | 72 +
24 drivers/staging/octeon/cvmx-fau.h | 597 ++++++
25 drivers/staging/octeon/cvmx-fpa-defs.h | 403 ++++
26 drivers/staging/octeon/cvmx-fpa.c | 183 ++
27 drivers/staging/octeon/cvmx-fpa.h | 299 +++
28 drivers/staging/octeon/cvmx-gmxx-defs.h | 2529 +++++++++++++++++++++++
29 drivers/staging/octeon/cvmx-helper-board.c | 706 +++++++
30 drivers/staging/octeon/cvmx-helper-board.h | 180 ++
31 drivers/staging/octeon/cvmx-helper-fpa.c | 243 +++
32 drivers/staging/octeon/cvmx-helper-fpa.h | 64 +
33 drivers/staging/octeon/cvmx-helper-loop.c | 85 +
34 drivers/staging/octeon/cvmx-helper-loop.h | 59 +
35 drivers/staging/octeon/cvmx-helper-npi.c | 113 +
36 drivers/staging/octeon/cvmx-helper-npi.h | 60 +
37 drivers/staging/octeon/cvmx-helper-rgmii.c | 525 +++++
38 drivers/staging/octeon/cvmx-helper-rgmii.h | 110 +
39 drivers/staging/octeon/cvmx-helper-sgmii.c | 550 +++++
40 drivers/staging/octeon/cvmx-helper-sgmii.h | 104 +
41 drivers/staging/octeon/cvmx-helper-spi.c | 195 ++
42 drivers/staging/octeon/cvmx-helper-spi.h | 84 +
43 drivers/staging/octeon/cvmx-helper-util.c | 433 ++++
44 drivers/staging/octeon/cvmx-helper-util.h | 215 ++
45 drivers/staging/octeon/cvmx-helper-xaui.c | 348 ++++
46 drivers/staging/octeon/cvmx-helper-xaui.h | 103 +
47 drivers/staging/octeon/cvmx-helper.c | 1058 ++++++++++
48 drivers/staging/octeon/cvmx-helper.h | 227 ++
49 drivers/staging/octeon/cvmx-interrupt-decodes.c | 371 ++++
50 drivers/staging/octeon/cvmx-interrupt-rsl.c | 140 ++
51 drivers/staging/octeon/cvmx-ipd.h | 338 +++
52 drivers/staging/octeon/cvmx-mdio.h | 506 +++++
53 drivers/staging/octeon/cvmx-packet.h | 65 +
54 drivers/staging/octeon/cvmx-pcsx-defs.h | 370 ++++
55 drivers/staging/octeon/cvmx-pcsxx-defs.h | 316 +++
56 drivers/staging/octeon/cvmx-pip-defs.h | 1267 ++++++++++++
57 drivers/staging/octeon/cvmx-pip.h | 524 +++++
58 drivers/staging/octeon/cvmx-pko-defs.h | 1133 ++++++++++
59 drivers/staging/octeon/cvmx-pko.c | 506 +++++
60 drivers/staging/octeon/cvmx-pko.h | 610 ++++++
61 drivers/staging/octeon/cvmx-pow.h | 1982 ++++++++++++++++++
62 drivers/staging/octeon/cvmx-scratch.h | 139 ++
63 drivers/staging/octeon/cvmx-smix-defs.h | 178 ++
64 drivers/staging/octeon/cvmx-spi.c | 667 ++++++
65 drivers/staging/octeon/cvmx-spi.h | 269 +++
66 drivers/staging/octeon/cvmx-spxx-defs.h | 347 ++++
67 drivers/staging/octeon/cvmx-srxx-defs.h | 126 ++
68 drivers/staging/octeon/cvmx-stxx-defs.h | 292 +++
69 drivers/staging/octeon/cvmx-wqe.h | 397 ++++
70 drivers/staging/octeon/ethernet-common.c | 328 +++
71 drivers/staging/octeon/ethernet-common.h | 29 +
72 drivers/staging/octeon/ethernet-defines.h | 134 ++
73 drivers/staging/octeon/ethernet-mdio.c | 231 +++
74 drivers/staging/octeon/ethernet-mdio.h | 46 +
75 drivers/staging/octeon/ethernet-mem.c | 198 ++
76 drivers/staging/octeon/ethernet-mem.h | 29 +
77 drivers/staging/octeon/ethernet-proc.c | 256 +++
78 drivers/staging/octeon/ethernet-proc.h | 29 +
79 drivers/staging/octeon/ethernet-rgmii.c | 397 ++++
80 drivers/staging/octeon/ethernet-rx.c | 505 +++++
81 drivers/staging/octeon/ethernet-rx.h | 33 +
82 drivers/staging/octeon/ethernet-sgmii.c | 129 ++
83 drivers/staging/octeon/ethernet-spi.c | 323 +++
84 drivers/staging/octeon/ethernet-tx.c | 634 ++++++
85 drivers/staging/octeon/ethernet-tx.h | 32 +
86 drivers/staging/octeon/ethernet-util.h | 81 +
87 drivers/staging/octeon/ethernet-xaui.c | 127 ++
88 drivers/staging/octeon/ethernet.c | 507 +++++
89 drivers/staging/octeon/octeon-ethernet.h | 127 ++
90 74 files changed, 26146 insertions(+), 0 deletions(-)
91 create mode 100644 drivers/staging/octeon/Kconfig
92 create mode 100644 drivers/staging/octeon/Makefile
93 create mode 100644 drivers/staging/octeon/cvmx-address.h
94 create mode 100644 drivers/staging/octeon/cvmx-asxx-defs.h
95 create mode 100644 drivers/staging/octeon/cvmx-cmd-queue.c
96 create mode 100644 drivers/staging/octeon/cvmx-cmd-queue.h
97 create mode 100644 drivers/staging/octeon/cvmx-config.h
98 create mode 100644 drivers/staging/octeon/cvmx-dbg-defs.h
99 create mode 100644 drivers/staging/octeon/cvmx-fau.h
100 create mode 100644 drivers/staging/octeon/cvmx-fpa-defs.h
101 create mode 100644 drivers/staging/octeon/cvmx-fpa.c
102 create mode 100644 drivers/staging/octeon/cvmx-fpa.h
103 create mode 100644 drivers/staging/octeon/cvmx-gmxx-defs.h
104 create mode 100644 drivers/staging/octeon/cvmx-helper-board.c
105 create mode 100644 drivers/staging/octeon/cvmx-helper-board.h
106 create mode 100644 drivers/staging/octeon/cvmx-helper-fpa.c
107 create mode 100644 drivers/staging/octeon/cvmx-helper-fpa.h
108 create mode 100644 drivers/staging/octeon/cvmx-helper-loop.c
109 create mode 100644 drivers/staging/octeon/cvmx-helper-loop.h
110 create mode 100644 drivers/staging/octeon/cvmx-helper-npi.c
111 create mode 100644 drivers/staging/octeon/cvmx-helper-npi.h
112 create mode 100644 drivers/staging/octeon/cvmx-helper-rgmii.c
113 create mode 100644 drivers/staging/octeon/cvmx-helper-rgmii.h
114 create mode 100644 drivers/staging/octeon/cvmx-helper-sgmii.c
115 create mode 100644 drivers/staging/octeon/cvmx-helper-sgmii.h
116 create mode 100644 drivers/staging/octeon/cvmx-helper-spi.c
117 create mode 100644 drivers/staging/octeon/cvmx-helper-spi.h
118 create mode 100644 drivers/staging/octeon/cvmx-helper-util.c
119 create mode 100644 drivers/staging/octeon/cvmx-helper-util.h
120 create mode 100644 drivers/staging/octeon/cvmx-helper-xaui.c
121 create mode 100644 drivers/staging/octeon/cvmx-helper-xaui.h
122 create mode 100644 drivers/staging/octeon/cvmx-helper.c
123 create mode 100644 drivers/staging/octeon/cvmx-helper.h
124 create mode 100644 drivers/staging/octeon/cvmx-interrupt-decodes.c
125 create mode 100644 drivers/staging/octeon/cvmx-interrupt-rsl.c
126 create mode 100644 drivers/staging/octeon/cvmx-ipd.h
127 create mode 100644 drivers/staging/octeon/cvmx-mdio.h
128 create mode 100644 drivers/staging/octeon/cvmx-packet.h
129 create mode 100644 drivers/staging/octeon/cvmx-pcsx-defs.h
130 create mode 100644 drivers/staging/octeon/cvmx-pcsxx-defs.h
131 create mode 100644 drivers/staging/octeon/cvmx-pip-defs.h
132 create mode 100644 drivers/staging/octeon/cvmx-pip.h
133 create mode 100644 drivers/staging/octeon/cvmx-pko-defs.h
134 create mode 100644 drivers/staging/octeon/cvmx-pko.c
135 create mode 100644 drivers/staging/octeon/cvmx-pko.h
136 create mode 100644 drivers/staging/octeon/cvmx-pow.h
137 create mode 100644 drivers/staging/octeon/cvmx-scratch.h
138 create mode 100644 drivers/staging/octeon/cvmx-smix-defs.h
139 create mode 100644 drivers/staging/octeon/cvmx-spi.c
140 create mode 100644 drivers/staging/octeon/cvmx-spi.h
141 create mode 100644 drivers/staging/octeon/cvmx-spxx-defs.h
142 create mode 100644 drivers/staging/octeon/cvmx-srxx-defs.h
143 create mode 100644 drivers/staging/octeon/cvmx-stxx-defs.h
144 create mode 100644 drivers/staging/octeon/cvmx-wqe.h
145 create mode 100644 drivers/staging/octeon/ethernet-common.c
146 create mode 100644 drivers/staging/octeon/ethernet-common.h
147 create mode 100644 drivers/staging/octeon/ethernet-defines.h
148 create mode 100644 drivers/staging/octeon/ethernet-mdio.c
149 create mode 100644 drivers/staging/octeon/ethernet-mdio.h
150 create mode 100644 drivers/staging/octeon/ethernet-mem.c
151 create mode 100644 drivers/staging/octeon/ethernet-mem.h
152 create mode 100644 drivers/staging/octeon/ethernet-proc.c
153 create mode 100644 drivers/staging/octeon/ethernet-proc.h
154 create mode 100644 drivers/staging/octeon/ethernet-rgmii.c
155 create mode 100644 drivers/staging/octeon/ethernet-rx.c
156 create mode 100644 drivers/staging/octeon/ethernet-rx.h
157 create mode 100644 drivers/staging/octeon/ethernet-sgmii.c
158 create mode 100644 drivers/staging/octeon/ethernet-spi.c
159 create mode 100644 drivers/staging/octeon/ethernet-tx.c
160 create mode 100644 drivers/staging/octeon/ethernet-tx.h
161 create mode 100644 drivers/staging/octeon/ethernet-util.h
162 create mode 100644 drivers/staging/octeon/ethernet-xaui.c
163 create mode 100644 drivers/staging/octeon/ethernet.c
164 create mode 100644 drivers/staging/octeon/octeon-ethernet.h
165
166 --- /dev/null
167 +++ b/drivers/staging/octeon/Kconfig
168 @@ -0,0 +1,12 @@
169 +config OCTEON_ETHERNET
170 + tristate "Cavium Networks Octeon Ethernet support"
171 + depends on CPU_CAVIUM_OCTEON
172 + select MII
173 + help
174 + This driver supports the builtin ethernet ports on Cavium
175 + Networks' products in the Octeon family. This driver supports the
176 + CN3XXX and CN5XXX Octeon processors.
177 +
178 + To compile this driver as a module, choose M here. The module
179 + will be called octeon-ethernet.
180 +
181 --- /dev/null
182 +++ b/drivers/staging/octeon/Makefile
183 @@ -0,0 +1,30 @@
184 +# This file is subject to the terms and conditions of the GNU General Public
185 +# License. See the file "COPYING" in the main directory of this archive
186 +# for more details.
187 +#
188 +# Copyright (C) 2005-2009 Cavium Networks
189 +#
190 +
191 +#
192 +# Makefile for Cavium OCTEON on-board ethernet driver
193 +#
194 +
195 +obj-${CONFIG_OCTEON_ETHERNET} := octeon-ethernet.o
196 +
197 +octeon-ethernet-objs := ethernet.o
198 +octeon-ethernet-objs += ethernet-common.o
199 +octeon-ethernet-objs += ethernet-mdio.o
200 +octeon-ethernet-objs += ethernet-mem.o
201 +octeon-ethernet-objs += ethernet-proc.o
202 +octeon-ethernet-objs += ethernet-rgmii.o
203 +octeon-ethernet-objs += ethernet-rx.o
204 +octeon-ethernet-objs += ethernet-sgmii.o
205 +octeon-ethernet-objs += ethernet-spi.o
206 +octeon-ethernet-objs += ethernet-tx.o
207 +octeon-ethernet-objs += ethernet-xaui.o
208 +octeon-ethernet-objs += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \
209 + cvmx-helper-board.o cvmx-helper.o cvmx-helper-xaui.o \
210 + cvmx-helper-rgmii.o cvmx-helper-sgmii.o cvmx-helper-npi.o \
211 + cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \
212 + cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o
213 +
214 --- /dev/null
215 +++ b/drivers/staging/octeon/cvmx-address.h
216 @@ -0,0 +1,274 @@
217 +/***********************license start***************
218 + * Author: Cavium Networks
219 + *
220 + * Contact: support@caviumnetworks.com
221 + * This file is part of the OCTEON SDK
222 + *
223 + * Copyright (c) 2003-2009 Cavium Networks
224 + *
225 + * This file is free software; you can redistribute it and/or modify
226 + * it under the terms of the GNU General Public License, Version 2, as
227 + * published by the Free Software Foundation.
228 + *
229 + * This file is distributed in the hope that it will be useful, but
230 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
231 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
232 + * NONINFRINGEMENT. See the GNU General Public License for more
233 + * details.
234 + *
235 + * You should have received a copy of the GNU General Public License
236 + * along with this file; if not, write to the Free Software
237 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
238 + * or visit http://www.gnu.org/licenses/.
239 + *
240 + * This file may also be available under a different license from Cavium.
241 + * Contact Cavium Networks for more information
242 + ***********************license end**************************************/
243 +
244 +/**
245 + * Typedefs and defines for working with Octeon physical addresses.
246 + *
247 + */
248 +#ifndef __CVMX_ADDRESS_H__
249 +#define __CVMX_ADDRESS_H__
250 +
251 +#if 0
252 +typedef enum {
253 + CVMX_MIPS_SPACE_XKSEG = 3LL,
254 + CVMX_MIPS_SPACE_XKPHYS = 2LL,
255 + CVMX_MIPS_SPACE_XSSEG = 1LL,
256 + CVMX_MIPS_SPACE_XUSEG = 0LL
257 +} cvmx_mips_space_t;
258 +#endif
259 +
260 +typedef enum {
261 + CVMX_MIPS_XKSEG_SPACE_KSEG0 = 0LL,
262 + CVMX_MIPS_XKSEG_SPACE_KSEG1 = 1LL,
263 + CVMX_MIPS_XKSEG_SPACE_SSEG = 2LL,
264 + CVMX_MIPS_XKSEG_SPACE_KSEG3 = 3LL
265 +} cvmx_mips_xkseg_space_t;
266 +
267 +/* decodes <14:13> of a kseg3 window address */
268 +typedef enum {
269 + CVMX_ADD_WIN_SCR = 0L,
270 + /* see cvmx_add_win_dma_dec_t for further decode */
271 + CVMX_ADD_WIN_DMA = 1L,
272 + CVMX_ADD_WIN_UNUSED = 2L,
273 + CVMX_ADD_WIN_UNUSED2 = 3L
274 +} cvmx_add_win_dec_t;
275 +
276 +/* decode within DMA space */
277 +typedef enum {
278 + /*
279 + * Add store data to the write buffer entry, allocating it if
280 + * necessary.
281 + */
282 + CVMX_ADD_WIN_DMA_ADD = 0L,
283 + /* send out the write buffer entry to DRAM */
284 + CVMX_ADD_WIN_DMA_SENDMEM = 1L,
285 + /* store data must be normal DRAM memory space address in this case */
286 + /* send out the write buffer entry as an IOBDMA command */
287 + CVMX_ADD_WIN_DMA_SENDDMA = 2L,
288 + /* see CVMX_ADD_WIN_DMA_SEND_DEC for data contents */
289 + /* send out the write buffer entry as an IO write */
290 + CVMX_ADD_WIN_DMA_SENDIO = 3L,
291 + /* store data must be normal IO space address in this case */
292 + /* send out a single-tick command on the NCB bus */
293 + CVMX_ADD_WIN_DMA_SENDSINGLE = 4L,
294 + /* no write buffer data needed/used */
295 +} cvmx_add_win_dma_dec_t;
296 +
297 +/*
298 + * Physical Address Decode
299 + *
300 + * Octeon-I HW never interprets this X (<39:36> reserved
301 + * for future expansion), software should set to 0.
302 + *
303 + * - 0x0 XXX0 0000 0000 to DRAM Cached
304 + * - 0x0 XXX0 0FFF FFFF
305 + *
306 + * - 0x0 XXX0 1000 0000 to Boot Bus Uncached (Converted to 0x1 00X0 1000 0000
307 + * - 0x0 XXX0 1FFF FFFF + EJTAG to 0x1 00X0 1FFF FFFF)
308 + *
309 + * - 0x0 XXX0 2000 0000 to DRAM Cached
310 + * - 0x0 XXXF FFFF FFFF
311 + *
312 + * - 0x1 00X0 0000 0000 to Boot Bus Uncached
313 + * - 0x1 00XF FFFF FFFF
314 + *
315 + * - 0x1 01X0 0000 0000 to Other NCB Uncached
316 + * - 0x1 FFXF FFFF FFFF devices
317 + *
318 + * Decode of all Octeon addresses
319 + */
320 +typedef union {
321 +
322 + uint64_t u64;
323 + /* mapped or unmapped virtual address */
324 + struct {
325 + uint64_t R:2;
326 + uint64_t offset:62;
327 + } sva;
328 +
329 + /* mapped USEG virtual addresses (typically) */
330 + struct {
331 + uint64_t zeroes:33;
332 + uint64_t offset:31;
333 + } suseg;
334 +
335 + /* mapped or unmapped virtual address */
336 + struct {
337 + uint64_t ones:33;
338 + uint64_t sp:2;
339 + uint64_t offset:29;
340 + } sxkseg;
341 +
342 + /*
343 + * physical address accessed through xkphys unmapped virtual
344 + * address.
345 + */
346 + struct {
347 + uint64_t R:2; /* CVMX_MIPS_SPACE_XKPHYS in this case */
348 + uint64_t cca:3; /* ignored by octeon */
349 + uint64_t mbz:10;
350 + uint64_t pa:49; /* physical address */
351 + } sxkphys;
352 +
353 + /* physical address */
354 + struct {
355 + uint64_t mbz:15;
356 + /* if set, the address is uncached and resides on MCB bus */
357 + uint64_t is_io:1;
358 + /*
359 + * the hardware ignores this field when is_io==0, else
360 + * device ID.
361 + */
362 + uint64_t did:8;
363 + /* the hardware ignores <39:36> in Octeon I */
364 + uint64_t unaddr:4;
365 + uint64_t offset:36;
366 + } sphys;
367 +
368 + /* physical mem address */
369 + struct {
370 + /* techically, <47:40> are dont-cares */
371 + uint64_t zeroes:24;
372 + /* the hardware ignores <39:36> in Octeon I */
373 + uint64_t unaddr:4;
374 + uint64_t offset:36;
375 + } smem;
376 +
377 + /* physical IO address */
378 + struct {
379 + uint64_t mem_region:2;
380 + uint64_t mbz:13;
381 + /* 1 in this case */
382 + uint64_t is_io:1;
383 + /*
384 + * The hardware ignores this field when is_io==0, else
385 + * device ID.
386 + */
387 + uint64_t did:8;
388 + /* the hardware ignores <39:36> in Octeon I */
389 + uint64_t unaddr:4;
390 + uint64_t offset:36;
391 + } sio;
392 +
393 + /*
394 + * Scratchpad virtual address - accessed through a window at
395 + * the end of kseg3
396 + */
397 + struct {
398 + uint64_t ones:49;
399 + /* CVMX_ADD_WIN_SCR (0) in this case */
400 + cvmx_add_win_dec_t csrdec:2;
401 + uint64_t addr:13;
402 + } sscr;
403 +
404 + /* there should only be stores to IOBDMA space, no loads */
405 + /*
406 + * IOBDMA virtual address - accessed through a window at the
407 + * end of kseg3
408 + */
409 + struct {
410 + uint64_t ones:49;
411 + uint64_t csrdec:2; /* CVMX_ADD_WIN_DMA (1) in this case */
412 + uint64_t unused2:3;
413 + uint64_t type:3;
414 + uint64_t addr:7;
415 + } sdma;
416 +
417 + struct {
418 + uint64_t didspace:24;
419 + uint64_t unused:40;
420 + } sfilldidspace;
421 +
422 +} cvmx_addr_t;
423 +
424 +/* These macros for used by 32 bit applications */
425 +
426 +#define CVMX_MIPS32_SPACE_KSEG0 1l
427 +#define CVMX_ADD_SEG32(segment, add) \
428 + (((int32_t)segment << 31) | (int32_t)(add))
429 +
430 +/*
431 + * Currently all IOs are performed using XKPHYS addressing. Linux uses
432 + * the CvmMemCtl register to enable XKPHYS addressing to IO space from
433 + * user mode. Future OSes may need to change the upper bits of IO
434 + * addresses. The following define controls the upper two bits for all
435 + * IO addresses generated by the simple executive library.
436 + */
437 +#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
438 +
439 +/* These macros simplify the process of creating common IO addresses */
440 +#define CVMX_ADD_SEG(segment, add) ((((uint64_t)segment) << 62) | (add))
441 +#ifndef CVMX_ADD_IO_SEG
442 +#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
443 +#endif
444 +#define CVMX_ADDR_DIDSPACE(did) (((CVMX_IO_SEG) << 22) | ((1ULL) << 8) | (did))
445 +#define CVMX_ADDR_DID(did) (CVMX_ADDR_DIDSPACE(did) << 40)
446 +#define CVMX_FULL_DID(did, subdid) (((did) << 3) | (subdid))
447 +
448 + /* from include/ncb_rsl_id.v */
449 +#define CVMX_OCT_DID_MIS 0ULL /* misc stuff */
450 +#define CVMX_OCT_DID_GMX0 1ULL
451 +#define CVMX_OCT_DID_GMX1 2ULL
452 +#define CVMX_OCT_DID_PCI 3ULL
453 +#define CVMX_OCT_DID_KEY 4ULL
454 +#define CVMX_OCT_DID_FPA 5ULL
455 +#define CVMX_OCT_DID_DFA 6ULL
456 +#define CVMX_OCT_DID_ZIP 7ULL
457 +#define CVMX_OCT_DID_RNG 8ULL
458 +#define CVMX_OCT_DID_IPD 9ULL
459 +#define CVMX_OCT_DID_PKT 10ULL
460 +#define CVMX_OCT_DID_TIM 11ULL
461 +#define CVMX_OCT_DID_TAG 12ULL
462 + /* the rest are not on the IO bus */
463 +#define CVMX_OCT_DID_L2C 16ULL
464 +#define CVMX_OCT_DID_LMC 17ULL
465 +#define CVMX_OCT_DID_SPX0 18ULL
466 +#define CVMX_OCT_DID_SPX1 19ULL
467 +#define CVMX_OCT_DID_PIP 20ULL
468 +#define CVMX_OCT_DID_ASX0 22ULL
469 +#define CVMX_OCT_DID_ASX1 23ULL
470 +#define CVMX_OCT_DID_IOB 30ULL
471 +
472 +#define CVMX_OCT_DID_PKT_SEND CVMX_FULL_DID(CVMX_OCT_DID_PKT, 2ULL)
473 +#define CVMX_OCT_DID_TAG_SWTAG CVMX_FULL_DID(CVMX_OCT_DID_TAG, 0ULL)
474 +#define CVMX_OCT_DID_TAG_TAG1 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 1ULL)
475 +#define CVMX_OCT_DID_TAG_TAG2 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 2ULL)
476 +#define CVMX_OCT_DID_TAG_TAG3 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 3ULL)
477 +#define CVMX_OCT_DID_TAG_NULL_RD CVMX_FULL_DID(CVMX_OCT_DID_TAG, 4ULL)
478 +#define CVMX_OCT_DID_TAG_CSR CVMX_FULL_DID(CVMX_OCT_DID_TAG, 7ULL)
479 +#define CVMX_OCT_DID_FAU_FAI CVMX_FULL_DID(CVMX_OCT_DID_IOB, 0ULL)
480 +#define CVMX_OCT_DID_TIM_CSR CVMX_FULL_DID(CVMX_OCT_DID_TIM, 0ULL)
481 +#define CVMX_OCT_DID_KEY_RW CVMX_FULL_DID(CVMX_OCT_DID_KEY, 0ULL)
482 +#define CVMX_OCT_DID_PCI_6 CVMX_FULL_DID(CVMX_OCT_DID_PCI, 6ULL)
483 +#define CVMX_OCT_DID_MIS_BOO CVMX_FULL_DID(CVMX_OCT_DID_MIS, 0ULL)
484 +#define CVMX_OCT_DID_PCI_RML CVMX_FULL_DID(CVMX_OCT_DID_PCI, 0ULL)
485 +#define CVMX_OCT_DID_IPD_CSR CVMX_FULL_DID(CVMX_OCT_DID_IPD, 7ULL)
486 +#define CVMX_OCT_DID_DFA_CSR CVMX_FULL_DID(CVMX_OCT_DID_DFA, 7ULL)
487 +#define CVMX_OCT_DID_MIS_CSR CVMX_FULL_DID(CVMX_OCT_DID_MIS, 7ULL)
488 +#define CVMX_OCT_DID_ZIP_CSR CVMX_FULL_DID(CVMX_OCT_DID_ZIP, 0ULL)
489 +
490 +#endif /* __CVMX_ADDRESS_H__ */
491 --- /dev/null
492 +++ b/drivers/staging/octeon/cvmx-asxx-defs.h
493 @@ -0,0 +1,475 @@
494 +/***********************license start***************
495 + * Author: Cavium Networks
496 + *
497 + * Contact: support@caviumnetworks.com
498 + * This file is part of the OCTEON SDK
499 + *
500 + * Copyright (c) 2003-2008 Cavium Networks
501 + *
502 + * This file is free software; you can redistribute it and/or modify
503 + * it under the terms of the GNU General Public License, Version 2, as
504 + * published by the Free Software Foundation.
505 + *
506 + * This file is distributed in the hope that it will be useful, but
507 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
508 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
509 + * NONINFRINGEMENT. See the GNU General Public License for more
510 + * details.
511 + *
512 + * You should have received a copy of the GNU General Public License
513 + * along with this file; if not, write to the Free Software
514 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
515 + * or visit http://www.gnu.org/licenses/.
516 + *
517 + * This file may also be available under a different license from Cavium.
518 + * Contact Cavium Networks for more information
519 + ***********************license end**************************************/
520 +
521 +#ifndef __CVMX_ASXX_DEFS_H__
522 +#define __CVMX_ASXX_DEFS_H__
523 +
524 +#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) \
525 + CVMX_ADD_IO_SEG(0x00011800B0000180ull + (((block_id) & 0) * 0x8000000ull))
526 +#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) \
527 + CVMX_ADD_IO_SEG(0x00011800B0000188ull + (((block_id) & 0) * 0x8000000ull))
528 +#define CVMX_ASXX_INT_EN(block_id) \
529 + CVMX_ADD_IO_SEG(0x00011800B0000018ull + (((block_id) & 1) * 0x8000000ull))
530 +#define CVMX_ASXX_INT_REG(block_id) \
531 + CVMX_ADD_IO_SEG(0x00011800B0000010ull + (((block_id) & 1) * 0x8000000ull))
532 +#define CVMX_ASXX_MII_RX_DAT_SET(block_id) \
533 + CVMX_ADD_IO_SEG(0x00011800B0000190ull + (((block_id) & 0) * 0x8000000ull))
534 +#define CVMX_ASXX_PRT_LOOP(block_id) \
535 + CVMX_ADD_IO_SEG(0x00011800B0000040ull + (((block_id) & 1) * 0x8000000ull))
536 +#define CVMX_ASXX_RLD_BYPASS(block_id) \
537 + CVMX_ADD_IO_SEG(0x00011800B0000248ull + (((block_id) & 1) * 0x8000000ull))
538 +#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) \
539 + CVMX_ADD_IO_SEG(0x00011800B0000250ull + (((block_id) & 1) * 0x8000000ull))
540 +#define CVMX_ASXX_RLD_COMP(block_id) \
541 + CVMX_ADD_IO_SEG(0x00011800B0000220ull + (((block_id) & 1) * 0x8000000ull))
542 +#define CVMX_ASXX_RLD_DATA_DRV(block_id) \
543 + CVMX_ADD_IO_SEG(0x00011800B0000218ull + (((block_id) & 1) * 0x8000000ull))
544 +#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) \
545 + CVMX_ADD_IO_SEG(0x00011800B0000210ull + (((block_id) & 1) * 0x8000000ull))
546 +#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) \
547 + CVMX_ADD_IO_SEG(0x00011800B0000230ull + (((block_id) & 1) * 0x8000000ull))
548 +#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) \
549 + CVMX_ADD_IO_SEG(0x00011800B0000240ull + (((block_id) & 1) * 0x8000000ull))
550 +#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) \
551 + CVMX_ADD_IO_SEG(0x00011800B0000228ull + (((block_id) & 1) * 0x8000000ull))
552 +#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) \
553 + CVMX_ADD_IO_SEG(0x00011800B0000238ull + (((block_id) & 1) * 0x8000000ull))
554 +#define CVMX_ASXX_RLD_SETTING(block_id) \
555 + CVMX_ADD_IO_SEG(0x00011800B0000258ull + (((block_id) & 1) * 0x8000000ull))
556 +#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) \
557 + CVMX_ADD_IO_SEG(0x00011800B0000020ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
558 +#define CVMX_ASXX_RX_PRT_EN(block_id) \
559 + CVMX_ADD_IO_SEG(0x00011800B0000000ull + (((block_id) & 1) * 0x8000000ull))
560 +#define CVMX_ASXX_RX_WOL(block_id) \
561 + CVMX_ADD_IO_SEG(0x00011800B0000100ull + (((block_id) & 1) * 0x8000000ull))
562 +#define CVMX_ASXX_RX_WOL_MSK(block_id) \
563 + CVMX_ADD_IO_SEG(0x00011800B0000108ull + (((block_id) & 1) * 0x8000000ull))
564 +#define CVMX_ASXX_RX_WOL_POWOK(block_id) \
565 + CVMX_ADD_IO_SEG(0x00011800B0000118ull + (((block_id) & 1) * 0x8000000ull))
566 +#define CVMX_ASXX_RX_WOL_SIG(block_id) \
567 + CVMX_ADD_IO_SEG(0x00011800B0000110ull + (((block_id) & 1) * 0x8000000ull))
568 +#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) \
569 + CVMX_ADD_IO_SEG(0x00011800B0000048ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
570 +#define CVMX_ASXX_TX_COMP_BYP(block_id) \
571 + CVMX_ADD_IO_SEG(0x00011800B0000068ull + (((block_id) & 1) * 0x8000000ull))
572 +#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) \
573 + CVMX_ADD_IO_SEG(0x00011800B0000080ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
574 +#define CVMX_ASXX_TX_PRT_EN(block_id) \
575 + CVMX_ADD_IO_SEG(0x00011800B0000008ull + (((block_id) & 1) * 0x8000000ull))
576 +
577 +union cvmx_asxx_gmii_rx_clk_set {
578 + uint64_t u64;
579 + struct cvmx_asxx_gmii_rx_clk_set_s {
580 + uint64_t reserved_5_63:59;
581 + uint64_t setting:5;
582 + } s;
583 + struct cvmx_asxx_gmii_rx_clk_set_s cn30xx;
584 + struct cvmx_asxx_gmii_rx_clk_set_s cn31xx;
585 + struct cvmx_asxx_gmii_rx_clk_set_s cn50xx;
586 +};
587 +
588 +union cvmx_asxx_gmii_rx_dat_set {
589 + uint64_t u64;
590 + struct cvmx_asxx_gmii_rx_dat_set_s {
591 + uint64_t reserved_5_63:59;
592 + uint64_t setting:5;
593 + } s;
594 + struct cvmx_asxx_gmii_rx_dat_set_s cn30xx;
595 + struct cvmx_asxx_gmii_rx_dat_set_s cn31xx;
596 + struct cvmx_asxx_gmii_rx_dat_set_s cn50xx;
597 +};
598 +
599 +union cvmx_asxx_int_en {
600 + uint64_t u64;
601 + struct cvmx_asxx_int_en_s {
602 + uint64_t reserved_12_63:52;
603 + uint64_t txpsh:4;
604 + uint64_t txpop:4;
605 + uint64_t ovrflw:4;
606 + } s;
607 + struct cvmx_asxx_int_en_cn30xx {
608 + uint64_t reserved_11_63:53;
609 + uint64_t txpsh:3;
610 + uint64_t reserved_7_7:1;
611 + uint64_t txpop:3;
612 + uint64_t reserved_3_3:1;
613 + uint64_t ovrflw:3;
614 + } cn30xx;
615 + struct cvmx_asxx_int_en_cn30xx cn31xx;
616 + struct cvmx_asxx_int_en_s cn38xx;
617 + struct cvmx_asxx_int_en_s cn38xxp2;
618 + struct cvmx_asxx_int_en_cn30xx cn50xx;
619 + struct cvmx_asxx_int_en_s cn58xx;
620 + struct cvmx_asxx_int_en_s cn58xxp1;
621 +};
622 +
623 +union cvmx_asxx_int_reg {
624 + uint64_t u64;
625 + struct cvmx_asxx_int_reg_s {
626 + uint64_t reserved_12_63:52;
627 + uint64_t txpsh:4;
628 + uint64_t txpop:4;
629 + uint64_t ovrflw:4;
630 + } s;
631 + struct cvmx_asxx_int_reg_cn30xx {
632 + uint64_t reserved_11_63:53;
633 + uint64_t txpsh:3;
634 + uint64_t reserved_7_7:1;
635 + uint64_t txpop:3;
636 + uint64_t reserved_3_3:1;
637 + uint64_t ovrflw:3;
638 + } cn30xx;
639 + struct cvmx_asxx_int_reg_cn30xx cn31xx;
640 + struct cvmx_asxx_int_reg_s cn38xx;
641 + struct cvmx_asxx_int_reg_s cn38xxp2;
642 + struct cvmx_asxx_int_reg_cn30xx cn50xx;
643 + struct cvmx_asxx_int_reg_s cn58xx;
644 + struct cvmx_asxx_int_reg_s cn58xxp1;
645 +};
646 +
647 +union cvmx_asxx_mii_rx_dat_set {
648 + uint64_t u64;
649 + struct cvmx_asxx_mii_rx_dat_set_s {
650 + uint64_t reserved_5_63:59;
651 + uint64_t setting:5;
652 + } s;
653 + struct cvmx_asxx_mii_rx_dat_set_s cn30xx;
654 + struct cvmx_asxx_mii_rx_dat_set_s cn50xx;
655 +};
656 +
657 +union cvmx_asxx_prt_loop {
658 + uint64_t u64;
659 + struct cvmx_asxx_prt_loop_s {
660 + uint64_t reserved_8_63:56;
661 + uint64_t ext_loop:4;
662 + uint64_t int_loop:4;
663 + } s;
664 + struct cvmx_asxx_prt_loop_cn30xx {
665 + uint64_t reserved_7_63:57;
666 + uint64_t ext_loop:3;
667 + uint64_t reserved_3_3:1;
668 + uint64_t int_loop:3;
669 + } cn30xx;
670 + struct cvmx_asxx_prt_loop_cn30xx cn31xx;
671 + struct cvmx_asxx_prt_loop_s cn38xx;
672 + struct cvmx_asxx_prt_loop_s cn38xxp2;
673 + struct cvmx_asxx_prt_loop_cn30xx cn50xx;
674 + struct cvmx_asxx_prt_loop_s cn58xx;
675 + struct cvmx_asxx_prt_loop_s cn58xxp1;
676 +};
677 +
678 +union cvmx_asxx_rld_bypass {
679 + uint64_t u64;
680 + struct cvmx_asxx_rld_bypass_s {
681 + uint64_t reserved_1_63:63;
682 + uint64_t bypass:1;
683 + } s;
684 + struct cvmx_asxx_rld_bypass_s cn38xx;
685 + struct cvmx_asxx_rld_bypass_s cn38xxp2;
686 + struct cvmx_asxx_rld_bypass_s cn58xx;
687 + struct cvmx_asxx_rld_bypass_s cn58xxp1;
688 +};
689 +
690 +union cvmx_asxx_rld_bypass_setting {
691 + uint64_t u64;
692 + struct cvmx_asxx_rld_bypass_setting_s {
693 + uint64_t reserved_5_63:59;
694 + uint64_t setting:5;
695 + } s;
696 + struct cvmx_asxx_rld_bypass_setting_s cn38xx;
697 + struct cvmx_asxx_rld_bypass_setting_s cn38xxp2;
698 + struct cvmx_asxx_rld_bypass_setting_s cn58xx;
699 + struct cvmx_asxx_rld_bypass_setting_s cn58xxp1;
700 +};
701 +
702 +union cvmx_asxx_rld_comp {
703 + uint64_t u64;
704 + struct cvmx_asxx_rld_comp_s {
705 + uint64_t reserved_9_63:55;
706 + uint64_t pctl:5;
707 + uint64_t nctl:4;
708 + } s;
709 + struct cvmx_asxx_rld_comp_cn38xx {
710 + uint64_t reserved_8_63:56;
711 + uint64_t pctl:4;
712 + uint64_t nctl:4;
713 + } cn38xx;
714 + struct cvmx_asxx_rld_comp_cn38xx cn38xxp2;
715 + struct cvmx_asxx_rld_comp_s cn58xx;
716 + struct cvmx_asxx_rld_comp_s cn58xxp1;
717 +};
718 +
719 +union cvmx_asxx_rld_data_drv {
720 + uint64_t u64;
721 + struct cvmx_asxx_rld_data_drv_s {
722 + uint64_t reserved_8_63:56;
723 + uint64_t pctl:4;
724 + uint64_t nctl:4;
725 + } s;
726 + struct cvmx_asxx_rld_data_drv_s cn38xx;
727 + struct cvmx_asxx_rld_data_drv_s cn38xxp2;
728 + struct cvmx_asxx_rld_data_drv_s cn58xx;
729 + struct cvmx_asxx_rld_data_drv_s cn58xxp1;
730 +};
731 +
732 +union cvmx_asxx_rld_fcram_mode {
733 + uint64_t u64;
734 + struct cvmx_asxx_rld_fcram_mode_s {
735 + uint64_t reserved_1_63:63;
736 + uint64_t mode:1;
737 + } s;
738 + struct cvmx_asxx_rld_fcram_mode_s cn38xx;
739 + struct cvmx_asxx_rld_fcram_mode_s cn38xxp2;
740 +};
741 +
742 +union cvmx_asxx_rld_nctl_strong {
743 + uint64_t u64;
744 + struct cvmx_asxx_rld_nctl_strong_s {
745 + uint64_t reserved_5_63:59;
746 + uint64_t nctl:5;
747 + } s;
748 + struct cvmx_asxx_rld_nctl_strong_s cn38xx;
749 + struct cvmx_asxx_rld_nctl_strong_s cn38xxp2;
750 + struct cvmx_asxx_rld_nctl_strong_s cn58xx;
751 + struct cvmx_asxx_rld_nctl_strong_s cn58xxp1;
752 +};
753 +
754 +union cvmx_asxx_rld_nctl_weak {
755 + uint64_t u64;
756 + struct cvmx_asxx_rld_nctl_weak_s {
757 + uint64_t reserved_5_63:59;
758 + uint64_t nctl:5;
759 + } s;
760 + struct cvmx_asxx_rld_nctl_weak_s cn38xx;
761 + struct cvmx_asxx_rld_nctl_weak_s cn38xxp2;
762 + struct cvmx_asxx_rld_nctl_weak_s cn58xx;
763 + struct cvmx_asxx_rld_nctl_weak_s cn58xxp1;
764 +};
765 +
766 +union cvmx_asxx_rld_pctl_strong {
767 + uint64_t u64;
768 + struct cvmx_asxx_rld_pctl_strong_s {
769 + uint64_t reserved_5_63:59;
770 + uint64_t pctl:5;
771 + } s;
772 + struct cvmx_asxx_rld_pctl_strong_s cn38xx;
773 + struct cvmx_asxx_rld_pctl_strong_s cn38xxp2;
774 + struct cvmx_asxx_rld_pctl_strong_s cn58xx;
775 + struct cvmx_asxx_rld_pctl_strong_s cn58xxp1;
776 +};
777 +
778 +union cvmx_asxx_rld_pctl_weak {
779 + uint64_t u64;
780 + struct cvmx_asxx_rld_pctl_weak_s {
781 + uint64_t reserved_5_63:59;
782 + uint64_t pctl:5;
783 + } s;
784 + struct cvmx_asxx_rld_pctl_weak_s cn38xx;
785 + struct cvmx_asxx_rld_pctl_weak_s cn38xxp2;
786 + struct cvmx_asxx_rld_pctl_weak_s cn58xx;
787 + struct cvmx_asxx_rld_pctl_weak_s cn58xxp1;
788 +};
789 +
790 +union cvmx_asxx_rld_setting {
791 + uint64_t u64;
792 + struct cvmx_asxx_rld_setting_s {
793 + uint64_t reserved_13_63:51;
794 + uint64_t dfaset:5;
795 + uint64_t dfalag:1;
796 + uint64_t dfalead:1;
797 + uint64_t dfalock:1;
798 + uint64_t setting:5;
799 + } s;
800 + struct cvmx_asxx_rld_setting_cn38xx {
801 + uint64_t reserved_5_63:59;
802 + uint64_t setting:5;
803 + } cn38xx;
804 + struct cvmx_asxx_rld_setting_cn38xx cn38xxp2;
805 + struct cvmx_asxx_rld_setting_s cn58xx;
806 + struct cvmx_asxx_rld_setting_s cn58xxp1;
807 +};
808 +
809 +union cvmx_asxx_rx_clk_setx {
810 + uint64_t u64;
811 + struct cvmx_asxx_rx_clk_setx_s {
812 + uint64_t reserved_5_63:59;
813 + uint64_t setting:5;
814 + } s;
815 + struct cvmx_asxx_rx_clk_setx_s cn30xx;
816 + struct cvmx_asxx_rx_clk_setx_s cn31xx;
817 + struct cvmx_asxx_rx_clk_setx_s cn38xx;
818 + struct cvmx_asxx_rx_clk_setx_s cn38xxp2;
819 + struct cvmx_asxx_rx_clk_setx_s cn50xx;
820 + struct cvmx_asxx_rx_clk_setx_s cn58xx;
821 + struct cvmx_asxx_rx_clk_setx_s cn58xxp1;
822 +};
823 +
824 +union cvmx_asxx_rx_prt_en {
825 + uint64_t u64;
826 + struct cvmx_asxx_rx_prt_en_s {
827 + uint64_t reserved_4_63:60;
828 + uint64_t prt_en:4;
829 + } s;
830 + struct cvmx_asxx_rx_prt_en_cn30xx {
831 + uint64_t reserved_3_63:61;
832 + uint64_t prt_en:3;
833 + } cn30xx;
834 + struct cvmx_asxx_rx_prt_en_cn30xx cn31xx;
835 + struct cvmx_asxx_rx_prt_en_s cn38xx;
836 + struct cvmx_asxx_rx_prt_en_s cn38xxp2;
837 + struct cvmx_asxx_rx_prt_en_cn30xx cn50xx;
838 + struct cvmx_asxx_rx_prt_en_s cn58xx;
839 + struct cvmx_asxx_rx_prt_en_s cn58xxp1;
840 +};
841 +
842 +union cvmx_asxx_rx_wol {
843 + uint64_t u64;
844 + struct cvmx_asxx_rx_wol_s {
845 + uint64_t reserved_2_63:62;
846 + uint64_t status:1;
847 + uint64_t enable:1;
848 + } s;
849 + struct cvmx_asxx_rx_wol_s cn38xx;
850 + struct cvmx_asxx_rx_wol_s cn38xxp2;
851 +};
852 +
853 +union cvmx_asxx_rx_wol_msk {
854 + uint64_t u64;
855 + struct cvmx_asxx_rx_wol_msk_s {
856 + uint64_t msk:64;
857 + } s;
858 + struct cvmx_asxx_rx_wol_msk_s cn38xx;
859 + struct cvmx_asxx_rx_wol_msk_s cn38xxp2;
860 +};
861 +
862 +union cvmx_asxx_rx_wol_powok {
863 + uint64_t u64;
864 + struct cvmx_asxx_rx_wol_powok_s {
865 + uint64_t reserved_1_63:63;
866 + uint64_t powerok:1;
867 + } s;
868 + struct cvmx_asxx_rx_wol_powok_s cn38xx;
869 + struct cvmx_asxx_rx_wol_powok_s cn38xxp2;
870 +};
871 +
872 +union cvmx_asxx_rx_wol_sig {
873 + uint64_t u64;
874 + struct cvmx_asxx_rx_wol_sig_s {
875 + uint64_t reserved_32_63:32;
876 + uint64_t sig:32;
877 + } s;
878 + struct cvmx_asxx_rx_wol_sig_s cn38xx;
879 + struct cvmx_asxx_rx_wol_sig_s cn38xxp2;
880 +};
881 +
882 +union cvmx_asxx_tx_clk_setx {
883 + uint64_t u64;
884 + struct cvmx_asxx_tx_clk_setx_s {
885 + uint64_t reserved_5_63:59;
886 + uint64_t setting:5;
887 + } s;
888 + struct cvmx_asxx_tx_clk_setx_s cn30xx;
889 + struct cvmx_asxx_tx_clk_setx_s cn31xx;
890 + struct cvmx_asxx_tx_clk_setx_s cn38xx;
891 + struct cvmx_asxx_tx_clk_setx_s cn38xxp2;
892 + struct cvmx_asxx_tx_clk_setx_s cn50xx;
893 + struct cvmx_asxx_tx_clk_setx_s cn58xx;
894 + struct cvmx_asxx_tx_clk_setx_s cn58xxp1;
895 +};
896 +
897 +union cvmx_asxx_tx_comp_byp {
898 + uint64_t u64;
899 + struct cvmx_asxx_tx_comp_byp_s {
900 + uint64_t reserved_0_63:64;
901 + } s;
902 + struct cvmx_asxx_tx_comp_byp_cn30xx {
903 + uint64_t reserved_9_63:55;
904 + uint64_t bypass:1;
905 + uint64_t pctl:4;
906 + uint64_t nctl:4;
907 + } cn30xx;
908 + struct cvmx_asxx_tx_comp_byp_cn30xx cn31xx;
909 + struct cvmx_asxx_tx_comp_byp_cn38xx {
910 + uint64_t reserved_8_63:56;
911 + uint64_t pctl:4;
912 + uint64_t nctl:4;
913 + } cn38xx;
914 + struct cvmx_asxx_tx_comp_byp_cn38xx cn38xxp2;
915 + struct cvmx_asxx_tx_comp_byp_cn50xx {
916 + uint64_t reserved_17_63:47;
917 + uint64_t bypass:1;
918 + uint64_t reserved_13_15:3;
919 + uint64_t pctl:5;
920 + uint64_t reserved_5_7:3;
921 + uint64_t nctl:5;
922 + } cn50xx;
923 + struct cvmx_asxx_tx_comp_byp_cn58xx {
924 + uint64_t reserved_13_63:51;
925 + uint64_t pctl:5;
926 + uint64_t reserved_5_7:3;
927 + uint64_t nctl:5;
928 + } cn58xx;
929 + struct cvmx_asxx_tx_comp_byp_cn58xx cn58xxp1;
930 +};
931 +
932 +union cvmx_asxx_tx_hi_waterx {
933 + uint64_t u64;
934 + struct cvmx_asxx_tx_hi_waterx_s {
935 + uint64_t reserved_4_63:60;
936 + uint64_t mark:4;
937 + } s;
938 + struct cvmx_asxx_tx_hi_waterx_cn30xx {
939 + uint64_t reserved_3_63:61;
940 + uint64_t mark:3;
941 + } cn30xx;
942 + struct cvmx_asxx_tx_hi_waterx_cn30xx cn31xx;
943 + struct cvmx_asxx_tx_hi_waterx_s cn38xx;
944 + struct cvmx_asxx_tx_hi_waterx_s cn38xxp2;
945 + struct cvmx_asxx_tx_hi_waterx_cn30xx cn50xx;
946 + struct cvmx_asxx_tx_hi_waterx_s cn58xx;
947 + struct cvmx_asxx_tx_hi_waterx_s cn58xxp1;
948 +};
949 +
950 +union cvmx_asxx_tx_prt_en {
951 + uint64_t u64;
952 + struct cvmx_asxx_tx_prt_en_s {
953 + uint64_t reserved_4_63:60;
954 + uint64_t prt_en:4;
955 + } s;
956 + struct cvmx_asxx_tx_prt_en_cn30xx {
957 + uint64_t reserved_3_63:61;
958 + uint64_t prt_en:3;
959 + } cn30xx;
960 + struct cvmx_asxx_tx_prt_en_cn30xx cn31xx;
961 + struct cvmx_asxx_tx_prt_en_s cn38xx;
962 + struct cvmx_asxx_tx_prt_en_s cn38xxp2;
963 + struct cvmx_asxx_tx_prt_en_cn30xx cn50xx;
964 + struct cvmx_asxx_tx_prt_en_s cn58xx;
965 + struct cvmx_asxx_tx_prt_en_s cn58xxp1;
966 +};
967 +
968 +#endif
969 --- /dev/null
970 +++ b/drivers/staging/octeon/cvmx-cmd-queue.c
971 @@ -0,0 +1,306 @@
972 +/***********************license start***************
973 + * Author: Cavium Networks
974 + *
975 + * Contact: support@caviumnetworks.com
976 + * This file is part of the OCTEON SDK
977 + *
978 + * Copyright (c) 2003-2008 Cavium Networks
979 + *
980 + * This file is free software; you can redistribute it and/or modify
981 + * it under the terms of the GNU General Public License, Version 2, as
982 + * published by the Free Software Foundation.
983 + *
984 + * This file is distributed in the hope that it will be useful, but
985 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
986 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
987 + * NONINFRINGEMENT. See the GNU General Public License for more
988 + * details.
989 + *
990 + * You should have received a copy of the GNU General Public License
991 + * along with this file; if not, write to the Free Software
992 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
993 + * or visit http://www.gnu.org/licenses/.
994 + *
995 + * This file may also be available under a different license from Cavium.
996 + * Contact Cavium Networks for more information
997 + ***********************license end**************************************/
998 +
999 +/*
1000 + * Support functions for managing command queues used for
1001 + * various hardware blocks.
1002 + */
1003 +
1004 +#include <linux/kernel.h>
1005 +
1006 +#include <asm/octeon/octeon.h>
1007 +
1008 +#include "cvmx-config.h"
1009 +#include "cvmx-fpa.h"
1010 +#include "cvmx-cmd-queue.h"
1011 +
1012 +#include <asm/octeon/cvmx-npei-defs.h>
1013 +#include <asm/octeon/cvmx-pexp-defs.h>
1014 +#include "cvmx-pko-defs.h"
1015 +
1016 +/**
1017 + * This application uses this pointer to access the global queue
1018 + * state. It points to a bootmem named block.
1019 + */
1020 +__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr;
1021 +
1022 +/**
1023 + * Initialize the Global queue state pointer.
1024 + *
1025 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1026 + */
1027 +static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void)
1028 +{
1029 + char *alloc_name = "cvmx_cmd_queues";
1030 +#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
1031 + extern uint64_t octeon_reserve32_memory;
1032 +#endif
1033 +
1034 + if (likely(__cvmx_cmd_queue_state_ptr))
1035 + return CVMX_CMD_QUEUE_SUCCESS;
1036 +
1037 +#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
1038 + if (octeon_reserve32_memory)
1039 + __cvmx_cmd_queue_state_ptr =
1040 + cvmx_bootmem_alloc_named_range(sizeof(*__cvmx_cmd_queue_state_ptr),
1041 + octeon_reserve32_memory,
1042 + octeon_reserve32_memory +
1043 + (CONFIG_CAVIUM_RESERVE32 <<
1044 + 20) - 1, 128, alloc_name);
1045 + else
1046 +#endif
1047 + __cvmx_cmd_queue_state_ptr =
1048 + cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr),
1049 + 128,
1050 + alloc_name);
1051 + if (__cvmx_cmd_queue_state_ptr)
1052 + memset(__cvmx_cmd_queue_state_ptr, 0,
1053 + sizeof(*__cvmx_cmd_queue_state_ptr));
1054 + else {
1055 + struct cvmx_bootmem_named_block_desc *block_desc =
1056 + cvmx_bootmem_find_named_block(alloc_name);
1057 + if (block_desc)
1058 + __cvmx_cmd_queue_state_ptr =
1059 + cvmx_phys_to_ptr(block_desc->base_addr);
1060 + else {
1061 + cvmx_dprintf
1062 + ("ERROR: cvmx_cmd_queue_initialize: Unable to get named block %s.\n",
1063 + alloc_name);
1064 + return CVMX_CMD_QUEUE_NO_MEMORY;
1065 + }
1066 + }
1067 + return CVMX_CMD_QUEUE_SUCCESS;
1068 +}
1069 +
1070 +/**
1071 + * Initialize a command queue for use. The initial FPA buffer is
1072 + * allocated and the hardware unit is configured to point to the
1073 + * new command queue.
1074 + *
1075 + * @queue_id: Hardware command queue to initialize.
1076 + * @max_depth: Maximum outstanding commands that can be queued.
1077 + * @fpa_pool: FPA pool the command queues should come from.
1078 + * @pool_size: Size of each buffer in the FPA pool (bytes)
1079 + *
1080 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1081 + */
1082 +cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
1083 + int max_depth, int fpa_pool,
1084 + int pool_size)
1085 +{
1086 + __cvmx_cmd_queue_state_t *qstate;
1087 + cvmx_cmd_queue_result_t result = __cvmx_cmd_queue_init_state_ptr();
1088 + if (result != CVMX_CMD_QUEUE_SUCCESS)
1089 + return result;
1090 +
1091 + qstate = __cvmx_cmd_queue_get_state(queue_id);
1092 + if (qstate == NULL)
1093 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1094 +
1095 + /*
1096 + * We artificially limit max_depth to 1<<20 words. It is an
1097 + * arbitrary limit.
1098 + */
1099 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH) {
1100 + if ((max_depth < 0) || (max_depth > 1 << 20))
1101 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1102 + } else if (max_depth != 0)
1103 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1104 +
1105 + if ((fpa_pool < 0) || (fpa_pool > 7))
1106 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1107 + if ((pool_size < 128) || (pool_size > 65536))
1108 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1109 +
1110 + /* See if someone else has already initialized the queue */
1111 + if (qstate->base_ptr_div128) {
1112 + if (max_depth != (int)qstate->max_depth) {
1113 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1114 + "Queue already initalized with different "
1115 + "max_depth (%d).\n",
1116 + (int)qstate->max_depth);
1117 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1118 + }
1119 + if (fpa_pool != qstate->fpa_pool) {
1120 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1121 + "Queue already initalized with different "
1122 + "FPA pool (%u).\n",
1123 + qstate->fpa_pool);
1124 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1125 + }
1126 + if ((pool_size >> 3) - 1 != qstate->pool_size_m1) {
1127 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1128 + "Queue already initalized with different "
1129 + "FPA pool size (%u).\n",
1130 + (qstate->pool_size_m1 + 1) << 3);
1131 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1132 + }
1133 + CVMX_SYNCWS;
1134 + return CVMX_CMD_QUEUE_ALREADY_SETUP;
1135 + } else {
1136 + union cvmx_fpa_ctl_status status;
1137 + void *buffer;
1138 +
1139 + status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
1140 + if (!status.s.enb) {
1141 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1142 + "FPA is not enabled.\n");
1143 + return CVMX_CMD_QUEUE_NO_MEMORY;
1144 + }
1145 + buffer = cvmx_fpa_alloc(fpa_pool);
1146 + if (buffer == NULL) {
1147 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1148 + "Unable to allocate initial buffer.\n");
1149 + return CVMX_CMD_QUEUE_NO_MEMORY;
1150 + }
1151 +
1152 + memset(qstate, 0, sizeof(*qstate));
1153 + qstate->max_depth = max_depth;
1154 + qstate->fpa_pool = fpa_pool;
1155 + qstate->pool_size_m1 = (pool_size >> 3) - 1;
1156 + qstate->base_ptr_div128 = cvmx_ptr_to_phys(buffer) / 128;
1157 + /*
1158 + * We zeroed the now serving field so we need to also
1159 + * zero the ticket.
1160 + */
1161 + __cvmx_cmd_queue_state_ptr->
1162 + ticket[__cvmx_cmd_queue_get_index(queue_id)] = 0;
1163 + CVMX_SYNCWS;
1164 + return CVMX_CMD_QUEUE_SUCCESS;
1165 + }
1166 +}
1167 +
1168 +/**
1169 + * Shutdown a queue a free it's command buffers to the FPA. The
1170 + * hardware connected to the queue must be stopped before this
1171 + * function is called.
1172 + *
1173 + * @queue_id: Queue to shutdown
1174 + *
1175 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1176 + */
1177 +cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id)
1178 +{
1179 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1180 + if (qptr == NULL) {
1181 + cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Unable to "
1182 + "get queue information.\n");
1183 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1184 + }
1185 +
1186 + if (cvmx_cmd_queue_length(queue_id) > 0) {
1187 + cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Queue still "
1188 + "has data in it.\n");
1189 + return CVMX_CMD_QUEUE_FULL;
1190 + }
1191 +
1192 + __cvmx_cmd_queue_lock(queue_id, qptr);
1193 + if (qptr->base_ptr_div128) {
1194 + cvmx_fpa_free(cvmx_phys_to_ptr
1195 + ((uint64_t) qptr->base_ptr_div128 << 7),
1196 + qptr->fpa_pool, 0);
1197 + qptr->base_ptr_div128 = 0;
1198 + }
1199 + __cvmx_cmd_queue_unlock(qptr);
1200 +
1201 + return CVMX_CMD_QUEUE_SUCCESS;
1202 +}
1203 +
1204 +/**
1205 + * Return the number of command words pending in the queue. This
1206 + * function may be relatively slow for some hardware units.
1207 + *
1208 + * @queue_id: Hardware command queue to query
1209 + *
1210 + * Returns Number of outstanding commands
1211 + */
1212 +int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id)
1213 +{
1214 + if (CVMX_ENABLE_PARAMETER_CHECKING) {
1215 + if (__cvmx_cmd_queue_get_state(queue_id) == NULL)
1216 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1217 + }
1218 +
1219 + /*
1220 + * The cast is here so gcc with check that all values in the
1221 + * cvmx_cmd_queue_id_t enumeration are here.
1222 + */
1223 + switch ((cvmx_cmd_queue_id_t) (queue_id & 0xff0000)) {
1224 + case CVMX_CMD_QUEUE_PKO_BASE:
1225 + /*
1226 + * FIXME: Need atomic lock on
1227 + * CVMX_PKO_REG_READ_IDX. Right now we are normally
1228 + * called with the queue lock, so that is a SLIGHT
1229 + * amount of protection.
1230 + */
1231 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue_id & 0xffff);
1232 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
1233 + union cvmx_pko_mem_debug9 debug9;
1234 + debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
1235 + return debug9.cn38xx.doorbell;
1236 + } else {
1237 + union cvmx_pko_mem_debug8 debug8;
1238 + debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
1239 + return debug8.cn58xx.doorbell;
1240 + }
1241 + case CVMX_CMD_QUEUE_ZIP:
1242 + case CVMX_CMD_QUEUE_DFA:
1243 + case CVMX_CMD_QUEUE_RAID:
1244 + /* FIXME: Implement other lengths */
1245 + return 0;
1246 + case CVMX_CMD_QUEUE_DMA_BASE:
1247 + {
1248 + union cvmx_npei_dmax_counts dmax_counts;
1249 + dmax_counts.u64 =
1250 + cvmx_read_csr(CVMX_PEXP_NPEI_DMAX_COUNTS
1251 + (queue_id & 0x7));
1252 + return dmax_counts.s.dbell;
1253 + }
1254 + case CVMX_CMD_QUEUE_END:
1255 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1256 + }
1257 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1258 +}
1259 +
1260 +/**
1261 + * Return the command buffer to be written to. The purpose of this
1262 + * function is to allow CVMX routine access t othe low level buffer
1263 + * for initial hardware setup. User applications should not call this
1264 + * function directly.
1265 + *
1266 + * @queue_id: Command queue to query
1267 + *
1268 + * Returns Command buffer or NULL on failure
1269 + */
1270 +void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id)
1271 +{
1272 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1273 + if (qptr && qptr->base_ptr_div128)
1274 + return cvmx_phys_to_ptr((uint64_t) qptr->base_ptr_div128 << 7);
1275 + else
1276 + return NULL;
1277 +}
1278 --- /dev/null
1279 +++ b/drivers/staging/octeon/cvmx-cmd-queue.h
1280 @@ -0,0 +1,617 @@
1281 +/***********************license start***************
1282 + * Author: Cavium Networks
1283 + *
1284 + * Contact: support@caviumnetworks.com
1285 + * This file is part of the OCTEON SDK
1286 + *
1287 + * Copyright (c) 2003-2008 Cavium Networks
1288 + *
1289 + * This file is free software; you can redistribute it and/or modify
1290 + * it under the terms of the GNU General Public License, Version 2, as
1291 + * published by the Free Software Foundation.
1292 + *
1293 + * This file is distributed in the hope that it will be useful, but
1294 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
1295 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
1296 + * NONINFRINGEMENT. See the GNU General Public License for more
1297 + * details.
1298 + *
1299 + * You should have received a copy of the GNU General Public License
1300 + * along with this file; if not, write to the Free Software
1301 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1302 + * or visit http://www.gnu.org/licenses/.
1303 + *
1304 + * This file may also be available under a different license from Cavium.
1305 + * Contact Cavium Networks for more information
1306 + ***********************license end**************************************/
1307 +
1308 +/*
1309 + *
1310 + * Support functions for managing command queues used for
1311 + * various hardware blocks.
1312 + *
1313 + * The common command queue infrastructure abstracts out the
1314 + * software necessary for adding to Octeon's chained queue
1315 + * structures. These structures are used for commands to the
1316 + * PKO, ZIP, DFA, RAID, and DMA engine blocks. Although each
1317 + * hardware unit takes commands and CSRs of different types,
1318 + * they all use basic linked command buffers to store the
1319 + * pending request. In general, users of the CVMX API don't
1320 + * call cvmx-cmd-queue functions directly. Instead the hardware
1321 + * unit specific wrapper should be used. The wrappers perform
1322 + * unit specific validation and CSR writes to submit the
1323 + * commands.
1324 + *
1325 + * Even though most software will never directly interact with
1326 + * cvmx-cmd-queue, knowledge of its internal working can help
1327 + * in diagnosing performance problems and help with debugging.
1328 + *
1329 + * Command queue pointers are stored in a global named block
1330 + * called "cvmx_cmd_queues". Except for the PKO queues, each
1331 + * hardware queue is stored in its own cache line to reduce SMP
1332 + * contention on spin locks. The PKO queues are stored such that
1333 + * every 16th queue is next to each other in memory. This scheme
1334 + * allows for queues being in separate cache lines when there
1335 + * are low number of queues per port. With 16 queues per port,
1336 + * the first queue for each port is in the same cache area. The
1337 + * second queues for each port are in another area, etc. This
1338 + * allows software to implement very efficient lockless PKO with
1339 + * 16 queues per port using a minimum of cache lines per core.
1340 + * All queues for a given core will be isolated in the same
1341 + * cache area.
1342 + *
1343 + * In addition to the memory pointer layout, cvmx-cmd-queue
1344 + * provides an optimized fair ll/sc locking mechanism for the
1345 + * queues. The lock uses a "ticket / now serving" model to
1346 + * maintain fair order on contended locks. In addition, it uses
1347 + * predicted locking time to limit cache contention. When a core
1348 + * know it must wait in line for a lock, it spins on the
1349 + * internal cycle counter to completely eliminate any causes of
1350 + * bus traffic.
1351 + *
1352 + */
1353 +
1354 +#ifndef __CVMX_CMD_QUEUE_H__
1355 +#define __CVMX_CMD_QUEUE_H__
1356 +
1357 +#include <linux/prefetch.h>
1358 +
1359 +#include "cvmx-fpa.h"
1360 +/**
1361 + * By default we disable the max depth support. Most programs
1362 + * don't use it and it slows down the command queue processing
1363 + * significantly.
1364 + */
1365 +#ifndef CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH
1366 +#define CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH 0
1367 +#endif
1368 +
1369 +/**
1370 + * Enumeration representing all hardware blocks that use command
1371 + * queues. Each hardware block has up to 65536 sub identifiers for
1372 + * multiple command queues. Not all chips support all hardware
1373 + * units.
1374 + */
1375 +typedef enum {
1376 + CVMX_CMD_QUEUE_PKO_BASE = 0x00000,
1377 +
1378 +#define CVMX_CMD_QUEUE_PKO(queue) \
1379 + ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_PKO_BASE + (0xffff&(queue))))
1380 +
1381 + CVMX_CMD_QUEUE_ZIP = 0x10000,
1382 + CVMX_CMD_QUEUE_DFA = 0x20000,
1383 + CVMX_CMD_QUEUE_RAID = 0x30000,
1384 + CVMX_CMD_QUEUE_DMA_BASE = 0x40000,
1385 +
1386 +#define CVMX_CMD_QUEUE_DMA(queue) \
1387 + ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_DMA_BASE + (0xffff&(queue))))
1388 +
1389 + CVMX_CMD_QUEUE_END = 0x50000,
1390 +} cvmx_cmd_queue_id_t;
1391 +
1392 +/**
1393 + * Command write operations can fail if the comamnd queue needs
1394 + * a new buffer and the associated FPA pool is empty. It can also
1395 + * fail if the number of queued command words reaches the maximum
1396 + * set at initialization.
1397 + */
1398 +typedef enum {
1399 + CVMX_CMD_QUEUE_SUCCESS = 0,
1400 + CVMX_CMD_QUEUE_NO_MEMORY = -1,
1401 + CVMX_CMD_QUEUE_FULL = -2,
1402 + CVMX_CMD_QUEUE_INVALID_PARAM = -3,
1403 + CVMX_CMD_QUEUE_ALREADY_SETUP = -4,
1404 +} cvmx_cmd_queue_result_t;
1405 +
1406 +typedef struct {
1407 + /* You have lock when this is your ticket */
1408 + uint8_t now_serving;
1409 + uint64_t unused1:24;
1410 + /* Maximum outstanding command words */
1411 + uint32_t max_depth;
1412 + /* FPA pool buffers come from */
1413 + uint64_t fpa_pool:3;
1414 + /* Top of command buffer pointer shifted 7 */
1415 + uint64_t base_ptr_div128:29;
1416 + uint64_t unused2:6;
1417 + /* FPA buffer size in 64bit words minus 1 */
1418 + uint64_t pool_size_m1:13;
1419 + /* Number of comamnds already used in buffer */
1420 + uint64_t index:13;
1421 +} __cvmx_cmd_queue_state_t;
1422 +
1423 +/**
1424 + * This structure contains the global state of all comamnd queues.
1425 + * It is stored in a bootmem named block and shared by all
1426 + * applications running on Octeon. Tickets are stored in a differnet
1427 + * cahce line that queue information to reduce the contention on the
1428 + * ll/sc used to get a ticket. If this is not the case, the update
1429 + * of queue state causes the ll/sc to fail quite often.
1430 + */
1431 +typedef struct {
1432 + uint64_t ticket[(CVMX_CMD_QUEUE_END >> 16) * 256];
1433 + __cvmx_cmd_queue_state_t state[(CVMX_CMD_QUEUE_END >> 16) * 256];
1434 +} __cvmx_cmd_queue_all_state_t;
1435 +
1436 +/**
1437 + * Initialize a command queue for use. The initial FPA buffer is
1438 + * allocated and the hardware unit is configured to point to the
1439 + * new command queue.
1440 + *
1441 + * @queue_id: Hardware command queue to initialize.
1442 + * @max_depth: Maximum outstanding commands that can be queued.
1443 + * @fpa_pool: FPA pool the command queues should come from.
1444 + * @pool_size: Size of each buffer in the FPA pool (bytes)
1445 + *
1446 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1447 + */
1448 +cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
1449 + int max_depth, int fpa_pool,
1450 + int pool_size);
1451 +
1452 +/**
1453 + * Shutdown a queue a free it's command buffers to the FPA. The
1454 + * hardware connected to the queue must be stopped before this
1455 + * function is called.
1456 + *
1457 + * @queue_id: Queue to shutdown
1458 + *
1459 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1460 + */
1461 +cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id);
1462 +
1463 +/**
1464 + * Return the number of command words pending in the queue. This
1465 + * function may be relatively slow for some hardware units.
1466 + *
1467 + * @queue_id: Hardware command queue to query
1468 + *
1469 + * Returns Number of outstanding commands
1470 + */
1471 +int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id);
1472 +
1473 +/**
1474 + * Return the command buffer to be written to. The purpose of this
1475 + * function is to allow CVMX routine access t othe low level buffer
1476 + * for initial hardware setup. User applications should not call this
1477 + * function directly.
1478 + *
1479 + * @queue_id: Command queue to query
1480 + *
1481 + * Returns Command buffer or NULL on failure
1482 + */
1483 +void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id);
1484 +
1485 +/**
1486 + * Get the index into the state arrays for the supplied queue id.
1487 + *
1488 + * @queue_id: Queue ID to get an index for
1489 + *
1490 + * Returns Index into the state arrays
1491 + */
1492 +static inline int __cvmx_cmd_queue_get_index(cvmx_cmd_queue_id_t queue_id)
1493 +{
1494 + /*
1495 + * Warning: This code currently only works with devices that
1496 + * have 256 queues or less. Devices with more than 16 queues
1497 + * are layed out in memory to allow cores quick access to
1498 + * every 16th queue. This reduces cache thrashing when you are
1499 + * running 16 queues per port to support lockless operation.
1500 + */
1501 + int unit = queue_id >> 16;
1502 + int q = (queue_id >> 4) & 0xf;
1503 + int core = queue_id & 0xf;
1504 + return unit * 256 + core * 16 + q;
1505 +}
1506 +
1507 +/**
1508 + * Lock the supplied queue so nobody else is updating it at the same
1509 + * time as us.
1510 + *
1511 + * @queue_id: Queue ID to lock
1512 + * @qptr: Pointer to the queue's global state
1513 + */
1514 +static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id,
1515 + __cvmx_cmd_queue_state_t *qptr)
1516 +{
1517 + extern __cvmx_cmd_queue_all_state_t
1518 + *__cvmx_cmd_queue_state_ptr;
1519 + int tmp;
1520 + int my_ticket;
1521 + prefetch(qptr);
1522 + asm volatile (
1523 + ".set push\n"
1524 + ".set noreorder\n"
1525 + "1:\n"
1526 + /* Atomic add one to ticket_ptr */
1527 + "ll %[my_ticket], %[ticket_ptr]\n"
1528 + /* and store the original value */
1529 + "li %[ticket], 1\n"
1530 + /* in my_ticket */
1531 + "baddu %[ticket], %[my_ticket]\n"
1532 + "sc %[ticket], %[ticket_ptr]\n"
1533 + "beqz %[ticket], 1b\n"
1534 + " nop\n"
1535 + /* Load the current now_serving ticket */
1536 + "lbu %[ticket], %[now_serving]\n"
1537 + "2:\n"
1538 + /* Jump out if now_serving == my_ticket */
1539 + "beq %[ticket], %[my_ticket], 4f\n"
1540 + /* Find out how many tickets are in front of me */
1541 + " subu %[ticket], %[my_ticket], %[ticket]\n"
1542 + /* Use tickets in front of me minus one to delay */
1543 + "subu %[ticket], 1\n"
1544 + /* Delay will be ((tickets in front)-1)*32 loops */
1545 + "cins %[ticket], %[ticket], 5, 7\n"
1546 + "3:\n"
1547 + /* Loop here until our ticket might be up */
1548 + "bnez %[ticket], 3b\n"
1549 + " subu %[ticket], 1\n"
1550 + /* Jump back up to check out ticket again */
1551 + "b 2b\n"
1552 + /* Load the current now_serving ticket */
1553 + " lbu %[ticket], %[now_serving]\n"
1554 + "4:\n"
1555 + ".set pop\n" :
1556 + [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]),
1557 + [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp),
1558 + [my_ticket] "=r"(my_ticket)
1559 + );
1560 +}
1561 +
1562 +/**
1563 + * Unlock the queue, flushing all writes.
1564 + *
1565 + * @qptr: Queue to unlock
1566 + */
1567 +static inline void __cvmx_cmd_queue_unlock(__cvmx_cmd_queue_state_t *qptr)
1568 +{
1569 + qptr->now_serving++;
1570 + CVMX_SYNCWS;
1571 +}
1572 +
1573 +/**
1574 + * Get the queue state structure for the given queue id
1575 + *
1576 + * @queue_id: Queue id to get
1577 + *
1578 + * Returns Queue structure or NULL on failure
1579 + */
1580 +static inline __cvmx_cmd_queue_state_t
1581 + *__cvmx_cmd_queue_get_state(cvmx_cmd_queue_id_t queue_id)
1582 +{
1583 + extern __cvmx_cmd_queue_all_state_t
1584 + *__cvmx_cmd_queue_state_ptr;
1585 + return &__cvmx_cmd_queue_state_ptr->
1586 + state[__cvmx_cmd_queue_get_index(queue_id)];
1587 +}
1588 +
1589 +/**
1590 + * Write an arbitrary number of command words to a command queue.
1591 + * This is a generic function; the fixed number of comamnd word
1592 + * functions yield higher performance.
1593 + *
1594 + * @queue_id: Hardware command queue to write to
1595 + * @use_locking:
1596 + * Use internal locking to ensure exclusive access for queue
1597 + * updates. If you don't use this locking you must ensure
1598 + * exclusivity some other way. Locking is strongly recommended.
1599 + * @cmd_count: Number of command words to write
1600 + * @cmds: Array of comamnds to write
1601 + *
1602 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1603 + */
1604 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write(cvmx_cmd_queue_id_t
1605 + queue_id,
1606 + int use_locking,
1607 + int cmd_count,
1608 + uint64_t *cmds)
1609 +{
1610 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1611 +
1612 + /* Make sure nobody else is updating the same queue */
1613 + if (likely(use_locking))
1614 + __cvmx_cmd_queue_lock(queue_id, qptr);
1615 +
1616 + /*
1617 + * If a max queue length was specified then make sure we don't
1618 + * exceed it. If any part of the command would be below the
1619 + * limit we allow it.
1620 + */
1621 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1622 + if (unlikely
1623 + (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1624 + if (likely(use_locking))
1625 + __cvmx_cmd_queue_unlock(qptr);
1626 + return CVMX_CMD_QUEUE_FULL;
1627 + }
1628 + }
1629 +
1630 + /*
1631 + * Normally there is plenty of room in the current buffer for
1632 + * the command.
1633 + */
1634 + if (likely(qptr->index + cmd_count < qptr->pool_size_m1)) {
1635 + uint64_t *ptr =
1636 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1637 + base_ptr_div128 << 7);
1638 + ptr += qptr->index;
1639 + qptr->index += cmd_count;
1640 + while (cmd_count--)
1641 + *ptr++ = *cmds++;
1642 + } else {
1643 + uint64_t *ptr;
1644 + int count;
1645 + /*
1646 + * We need a new comamnd buffer. Fail if there isn't
1647 + * one available.
1648 + */
1649 + uint64_t *new_buffer =
1650 + (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1651 + if (unlikely(new_buffer == NULL)) {
1652 + if (likely(use_locking))
1653 + __cvmx_cmd_queue_unlock(qptr);
1654 + return CVMX_CMD_QUEUE_NO_MEMORY;
1655 + }
1656 + ptr =
1657 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1658 + base_ptr_div128 << 7);
1659 + /*
1660 + * Figure out how many command words will fit in this
1661 + * buffer. One location will be needed for the next
1662 + * buffer pointer.
1663 + */
1664 + count = qptr->pool_size_m1 - qptr->index;
1665 + ptr += qptr->index;
1666 + cmd_count -= count;
1667 + while (count--)
1668 + *ptr++ = *cmds++;
1669 + *ptr = cvmx_ptr_to_phys(new_buffer);
1670 + /*
1671 + * The current buffer is full and has a link to the
1672 + * next buffer. Time to write the rest of the commands
1673 + * into the new buffer.
1674 + */
1675 + qptr->base_ptr_div128 = *ptr >> 7;
1676 + qptr->index = cmd_count;
1677 + ptr = new_buffer;
1678 + while (cmd_count--)
1679 + *ptr++ = *cmds++;
1680 + }
1681 +
1682 + /* All updates are complete. Release the lock and return */
1683 + if (likely(use_locking))
1684 + __cvmx_cmd_queue_unlock(qptr);
1685 + return CVMX_CMD_QUEUE_SUCCESS;
1686 +}
1687 +
1688 +/**
1689 + * Simple function to write two command words to a command
1690 + * queue.
1691 + *
1692 + * @queue_id: Hardware command queue to write to
1693 + * @use_locking:
1694 + * Use internal locking to ensure exclusive access for queue
1695 + * updates. If you don't use this locking you must ensure
1696 + * exclusivity some other way. Locking is strongly recommended.
1697 + * @cmd1: Command
1698 + * @cmd2: Command
1699 + *
1700 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1701 + */
1702 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write2(cvmx_cmd_queue_id_t
1703 + queue_id,
1704 + int use_locking,
1705 + uint64_t cmd1,
1706 + uint64_t cmd2)
1707 +{
1708 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1709 +
1710 + /* Make sure nobody else is updating the same queue */
1711 + if (likely(use_locking))
1712 + __cvmx_cmd_queue_lock(queue_id, qptr);
1713 +
1714 + /*
1715 + * If a max queue length was specified then make sure we don't
1716 + * exceed it. If any part of the command would be below the
1717 + * limit we allow it.
1718 + */
1719 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1720 + if (unlikely
1721 + (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1722 + if (likely(use_locking))
1723 + __cvmx_cmd_queue_unlock(qptr);
1724 + return CVMX_CMD_QUEUE_FULL;
1725 + }
1726 + }
1727 +
1728 + /*
1729 + * Normally there is plenty of room in the current buffer for
1730 + * the command.
1731 + */
1732 + if (likely(qptr->index + 2 < qptr->pool_size_m1)) {
1733 + uint64_t *ptr =
1734 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1735 + base_ptr_div128 << 7);
1736 + ptr += qptr->index;
1737 + qptr->index += 2;
1738 + ptr[0] = cmd1;
1739 + ptr[1] = cmd2;
1740 + } else {
1741 + uint64_t *ptr;
1742 + /*
1743 + * Figure out how many command words will fit in this
1744 + * buffer. One location will be needed for the next
1745 + * buffer pointer.
1746 + */
1747 + int count = qptr->pool_size_m1 - qptr->index;
1748 + /*
1749 + * We need a new comamnd buffer. Fail if there isn't
1750 + * one available.
1751 + */
1752 + uint64_t *new_buffer =
1753 + (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1754 + if (unlikely(new_buffer == NULL)) {
1755 + if (likely(use_locking))
1756 + __cvmx_cmd_queue_unlock(qptr);
1757 + return CVMX_CMD_QUEUE_NO_MEMORY;
1758 + }
1759 + count--;
1760 + ptr =
1761 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1762 + base_ptr_div128 << 7);
1763 + ptr += qptr->index;
1764 + *ptr++ = cmd1;
1765 + if (likely(count))
1766 + *ptr++ = cmd2;
1767 + *ptr = cvmx_ptr_to_phys(new_buffer);
1768 + /*
1769 + * The current buffer is full and has a link to the
1770 + * next buffer. Time to write the rest of the commands
1771 + * into the new buffer.
1772 + */
1773 + qptr->base_ptr_div128 = *ptr >> 7;
1774 + qptr->index = 0;
1775 + if (unlikely(count == 0)) {
1776 + qptr->index = 1;
1777 + new_buffer[0] = cmd2;
1778 + }
1779 + }
1780 +
1781 + /* All updates are complete. Release the lock and return */
1782 + if (likely(use_locking))
1783 + __cvmx_cmd_queue_unlock(qptr);
1784 + return CVMX_CMD_QUEUE_SUCCESS;
1785 +}
1786 +
1787 +/**
1788 + * Simple function to write three command words to a command
1789 + * queue.
1790 + *
1791 + * @queue_id: Hardware command queue to write to
1792 + * @use_locking:
1793 + * Use internal locking to ensure exclusive access for queue
1794 + * updates. If you don't use this locking you must ensure
1795 + * exclusivity some other way. Locking is strongly recommended.
1796 + * @cmd1: Command
1797 + * @cmd2: Command
1798 + * @cmd3: Command
1799 + *
1800 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1801 + */
1802 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write3(cvmx_cmd_queue_id_t
1803 + queue_id,
1804 + int use_locking,
1805 + uint64_t cmd1,
1806 + uint64_t cmd2,
1807 + uint64_t cmd3)
1808 +{
1809 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1810 +
1811 + /* Make sure nobody else is updating the same queue */
1812 + if (likely(use_locking))
1813 + __cvmx_cmd_queue_lock(queue_id, qptr);
1814 +
1815 + /*
1816 + * If a max queue length was specified then make sure we don't
1817 + * exceed it. If any part of the command would be below the
1818 + * limit we allow it.
1819 + */
1820 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1821 + if (unlikely
1822 + (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1823 + if (likely(use_locking))
1824 + __cvmx_cmd_queue_unlock(qptr);
1825 + return CVMX_CMD_QUEUE_FULL;
1826 + }
1827 + }
1828 +
1829 + /*
1830 + * Normally there is plenty of room in the current buffer for
1831 + * the command.
1832 + */
1833 + if (likely(qptr->index + 3 < qptr->pool_size_m1)) {
1834 + uint64_t *ptr =
1835 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1836 + base_ptr_div128 << 7);
1837 + ptr += qptr->index;
1838 + qptr->index += 3;
1839 + ptr[0] = cmd1;
1840 + ptr[1] = cmd2;
1841 + ptr[2] = cmd3;
1842 + } else {
1843 + uint64_t *ptr;
1844 + /*
1845 + * Figure out how many command words will fit in this
1846 + * buffer. One location will be needed for the next
1847 + * buffer pointer
1848 + */
1849 + int count = qptr->pool_size_m1 - qptr->index;
1850 + /*
1851 + * We need a new comamnd buffer. Fail if there isn't
1852 + * one available
1853 + */
1854 + uint64_t *new_buffer =
1855 + (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1856 + if (unlikely(new_buffer == NULL)) {
1857 + if (likely(use_locking))
1858 + __cvmx_cmd_queue_unlock(qptr);
1859 + return CVMX_CMD_QUEUE_NO_MEMORY;
1860 + }
1861 + count--;
1862 + ptr =
1863 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1864 + base_ptr_div128 << 7);
1865 + ptr += qptr->index;
1866 + *ptr++ = cmd1;
1867 + if (count) {
1868 + *ptr++ = cmd2;
1869 + if (count > 1)
1870 + *ptr++ = cmd3;
1871 + }
1872 + *ptr = cvmx_ptr_to_phys(new_buffer);
1873 + /*
1874 + * The current buffer is full and has a link to the
1875 + * next buffer. Time to write the rest of the commands
1876 + * into the new buffer.
1877 + */
1878 + qptr->base_ptr_div128 = *ptr >> 7;
1879 + qptr->index = 0;
1880 + ptr = new_buffer;
1881 + if (count == 0) {
1882 + *ptr++ = cmd2;
1883 + qptr->index++;
1884 + }
1885 + if (count < 2) {
1886 + *ptr++ = cmd3;
1887 + qptr->index++;
1888 + }
1889 + }
1890 +
1891 + /* All updates are complete. Release the lock and return */
1892 + if (likely(use_locking))
1893 + __cvmx_cmd_queue_unlock(qptr);
1894 + return CVMX_CMD_QUEUE_SUCCESS;
1895 +}
1896 +
1897 +#endif /* __CVMX_CMD_QUEUE_H__ */
1898 --- /dev/null
1899 +++ b/drivers/staging/octeon/cvmx-config.h
1900 @@ -0,0 +1,169 @@
1901 +#ifndef __CVMX_CONFIG_H__
1902 +#define __CVMX_CONFIG_H__
1903 +
1904 +/************************* Config Specific Defines ************************/
1905 +#define CVMX_LLM_NUM_PORTS 1
1906 +#define CVMX_NULL_POINTER_PROTECT 1
1907 +#define CVMX_ENABLE_DEBUG_PRINTS 1
1908 +/* PKO queues per port for interface 0 (ports 0-15) */
1909 +#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 1
1910 +/* PKO queues per port for interface 1 (ports 16-31) */
1911 +#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 1
1912 +/* Limit on the number of PKO ports enabled for interface 0 */
1913 +#define CVMX_PKO_MAX_PORTS_INTERFACE0 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
1914 +/* Limit on the number of PKO ports enabled for interface 1 */
1915 +#define CVMX_PKO_MAX_PORTS_INTERFACE1 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
1916 +/* PKO queues per port for PCI (ports 32-35) */
1917 +#define CVMX_PKO_QUEUES_PER_PORT_PCI 1
1918 +/* PKO queues per port for Loop devices (ports 36-39) */
1919 +#define CVMX_PKO_QUEUES_PER_PORT_LOOP 1
1920 +
1921 +/************************* FPA allocation *********************************/
1922 +/* Pool sizes in bytes, must be multiple of a cache line */
1923 +#define CVMX_FPA_POOL_0_SIZE (16 * CVMX_CACHE_LINE_SIZE)
1924 +#define CVMX_FPA_POOL_1_SIZE (1 * CVMX_CACHE_LINE_SIZE)
1925 +#define CVMX_FPA_POOL_2_SIZE (8 * CVMX_CACHE_LINE_SIZE)
1926 +#define CVMX_FPA_POOL_3_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1927 +#define CVMX_FPA_POOL_4_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1928 +#define CVMX_FPA_POOL_5_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1929 +#define CVMX_FPA_POOL_6_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1930 +#define CVMX_FPA_POOL_7_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1931 +
1932 +/* Pools in use */
1933 +/* Packet buffers */
1934 +#define CVMX_FPA_PACKET_POOL (0)
1935 +#define CVMX_FPA_PACKET_POOL_SIZE CVMX_FPA_POOL_0_SIZE
1936 +/* Work queue entrys */
1937 +#define CVMX_FPA_WQE_POOL (1)
1938 +#define CVMX_FPA_WQE_POOL_SIZE CVMX_FPA_POOL_1_SIZE
1939 +/* PKO queue command buffers */
1940 +#define CVMX_FPA_OUTPUT_BUFFER_POOL (2)
1941 +#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE CVMX_FPA_POOL_2_SIZE
1942 +
1943 +/************************* FAU allocation ********************************/
1944 +/* The fetch and add registers are allocated here. They are arranged
1945 + * in order of descending size so that all alignment constraints are
1946 + * automatically met. The enums are linked so that the following enum
1947 + * continues allocating where the previous one left off, so the
1948 + * numbering within each enum always starts with zero. The macros
1949 + * take care of the address increment size, so the values entered
1950 + * always increase by 1. FAU registers are accessed with byte
1951 + * addresses.
1952 + */
1953 +
1954 +#define CVMX_FAU_REG_64_ADDR(x) ((x << 3) + CVMX_FAU_REG_64_START)
1955 +typedef enum {
1956 + CVMX_FAU_REG_64_START = 0,
1957 + CVMX_FAU_REG_64_END = CVMX_FAU_REG_64_ADDR(0),
1958 +} cvmx_fau_reg_64_t;
1959 +
1960 +#define CVMX_FAU_REG_32_ADDR(x) ((x << 2) + CVMX_FAU_REG_32_START)
1961 +typedef enum {
1962 + CVMX_FAU_REG_32_START = CVMX_FAU_REG_64_END,
1963 + CVMX_FAU_REG_32_END = CVMX_FAU_REG_32_ADDR(0),
1964 +} cvmx_fau_reg_32_t;
1965 +
1966 +#define CVMX_FAU_REG_16_ADDR(x) ((x << 1) + CVMX_FAU_REG_16_START)
1967 +typedef enum {
1968 + CVMX_FAU_REG_16_START = CVMX_FAU_REG_32_END,
1969 + CVMX_FAU_REG_16_END = CVMX_FAU_REG_16_ADDR(0),
1970 +} cvmx_fau_reg_16_t;
1971 +
1972 +#define CVMX_FAU_REG_8_ADDR(x) ((x) + CVMX_FAU_REG_8_START)
1973 +typedef enum {
1974 + CVMX_FAU_REG_8_START = CVMX_FAU_REG_16_END,
1975 + CVMX_FAU_REG_8_END = CVMX_FAU_REG_8_ADDR(0),
1976 +} cvmx_fau_reg_8_t;
1977 +
1978 +/*
1979 + * The name CVMX_FAU_REG_AVAIL_BASE is provided to indicate the first
1980 + * available FAU address that is not allocated in cvmx-config.h. This
1981 + * is 64 bit aligned.
1982 + */
1983 +#define CVMX_FAU_REG_AVAIL_BASE ((CVMX_FAU_REG_8_END + 0x7) & (~0x7ULL))
1984 +#define CVMX_FAU_REG_END (2048)
1985 +
1986 +/********************** scratch memory allocation *************************/
1987 +/* Scratchpad memory allocation. Note that these are byte memory
1988 + * addresses. Some uses of scratchpad (IOBDMA for example) require
1989 + * the use of 8-byte aligned addresses, so proper alignment needs to
1990 + * be taken into account.
1991 + */
1992 +/* Generic scratch iobdma area */
1993 +#define CVMX_SCR_SCRATCH (0)
1994 +/* First location available after cvmx-config.h allocated region. */
1995 +#define CVMX_SCR_REG_AVAIL_BASE (8)
1996 +
1997 +/*
1998 + * CVMX_HELPER_FIRST_MBUFF_SKIP is the number of bytes to reserve
1999 + * before the beginning of the packet. If necessary, override the
2000 + * default here. See the IPD section of the hardware manual for MBUFF
2001 + * SKIP details.
2002 + */
2003 +#define CVMX_HELPER_FIRST_MBUFF_SKIP 184
2004 +
2005 +/*
2006 + * CVMX_HELPER_NOT_FIRST_MBUFF_SKIP is the number of bytes to reserve
2007 + * in each chained packet element. If necessary, override the default
2008 + * here.
2009 + */
2010 +#define CVMX_HELPER_NOT_FIRST_MBUFF_SKIP 0
2011 +
2012 +/*
2013 + * CVMX_HELPER_ENABLE_BACK_PRESSURE controls whether back pressure is
2014 + * enabled for all input ports. This controls if IPD sends
2015 + * backpressure to all ports if Octeon's FPA pools don't have enough
2016 + * packet or work queue entries. Even when this is off, it is still
2017 + * possible to get backpressure from individual hardware ports. When
2018 + * configuring backpressure, also check
2019 + * CVMX_HELPER_DISABLE_*_BACKPRESSURE below. If necessary, override
2020 + * the default here.
2021 + */
2022 +#define CVMX_HELPER_ENABLE_BACK_PRESSURE 1
2023 +
2024 +/*
2025 + * CVMX_HELPER_ENABLE_IPD controls if the IPD is enabled in the helper
2026 + * function. Once it is enabled the hardware starts accepting
2027 + * packets. You might want to skip the IPD enable if configuration
2028 + * changes are need from the default helper setup. If necessary,
2029 + * override the default here.
2030 + */
2031 +#define CVMX_HELPER_ENABLE_IPD 0
2032 +
2033 +/*
2034 + * CVMX_HELPER_INPUT_TAG_TYPE selects the type of tag that the IPD assigns
2035 + * to incoming packets.
2036 + */
2037 +#define CVMX_HELPER_INPUT_TAG_TYPE CVMX_POW_TAG_TYPE_ORDERED
2038 +
2039 +#define CVMX_ENABLE_PARAMETER_CHECKING 0
2040 +
2041 +/*
2042 + * The following select which fields are used by the PIP to generate
2043 + * the tag on INPUT
2044 + * 0: don't include
2045 + * 1: include
2046 + */
2047 +#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP 0
2048 +#define CVMX_HELPER_INPUT_TAG_IPV6_DST_IP 0
2049 +#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT 0
2050 +#define CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT 0
2051 +#define CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER 0
2052 +#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP 0
2053 +#define CVMX_HELPER_INPUT_TAG_IPV4_DST_IP 0
2054 +#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT 0
2055 +#define CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT 0
2056 +#define CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL 0
2057 +#define CVMX_HELPER_INPUT_TAG_INPUT_PORT 1
2058 +
2059 +/* Select skip mode for input ports */
2060 +#define CVMX_HELPER_INPUT_PORT_SKIP_MODE CVMX_PIP_PORT_CFG_MODE_SKIPL2
2061 +
2062 +/*
2063 + * Force backpressure to be disabled. This overrides all other
2064 + * backpressure configuration.
2065 + */
2066 +#define CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 0
2067 +
2068 +#endif /* __CVMX_CONFIG_H__ */
2069 +
2070 --- /dev/null
2071 +++ b/drivers/staging/octeon/cvmx-dbg-defs.h
2072 @@ -0,0 +1,72 @@
2073 +/***********************license start***************
2074 + * Author: Cavium Networks
2075 + *
2076 + * Contact: support@caviumnetworks.com
2077 + * This file is part of the OCTEON SDK
2078 + *
2079 + * Copyright (c) 2003-2008 Cavium Networks
2080 + *
2081 + * This file is free software; you can redistribute it and/or modify
2082 + * it under the terms of the GNU General Public License, Version 2, as
2083 + * published by the Free Software Foundation.
2084 + *
2085 + * This file is distributed in the hope that it will be useful, but
2086 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2087 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2088 + * NONINFRINGEMENT. See the GNU General Public License for more
2089 + * details.
2090 + *
2091 + * You should have received a copy of the GNU General Public License
2092 + * along with this file; if not, write to the Free Software
2093 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2094 + * or visit http://www.gnu.org/licenses/.
2095 + *
2096 + * This file may also be available under a different license from Cavium.
2097 + * Contact Cavium Networks for more information
2098 + ***********************license end**************************************/
2099 +
2100 +#ifndef __CVMX_DBG_DEFS_H__
2101 +#define __CVMX_DBG_DEFS_H__
2102 +
2103 +#define CVMX_DBG_DATA \
2104 + CVMX_ADD_IO_SEG(0x00011F00000001E8ull)
2105 +
2106 +union cvmx_dbg_data {
2107 + uint64_t u64;
2108 + struct cvmx_dbg_data_s {
2109 + uint64_t reserved_23_63:41;
2110 + uint64_t c_mul:5;
2111 + uint64_t dsel_ext:1;
2112 + uint64_t data:17;
2113 + } s;
2114 + struct cvmx_dbg_data_cn30xx {
2115 + uint64_t reserved_31_63:33;
2116 + uint64_t pll_mul:3;
2117 + uint64_t reserved_23_27:5;
2118 + uint64_t c_mul:5;
2119 + uint64_t dsel_ext:1;
2120 + uint64_t data:17;
2121 + } cn30xx;
2122 + struct cvmx_dbg_data_cn30xx cn31xx;
2123 + struct cvmx_dbg_data_cn38xx {
2124 + uint64_t reserved_29_63:35;
2125 + uint64_t d_mul:4;
2126 + uint64_t dclk_mul2:1;
2127 + uint64_t cclk_div2:1;
2128 + uint64_t c_mul:5;
2129 + uint64_t dsel_ext:1;
2130 + uint64_t data:17;
2131 + } cn38xx;
2132 + struct cvmx_dbg_data_cn38xx cn38xxp2;
2133 + struct cvmx_dbg_data_cn30xx cn50xx;
2134 + struct cvmx_dbg_data_cn58xx {
2135 + uint64_t reserved_29_63:35;
2136 + uint64_t rem:6;
2137 + uint64_t c_mul:5;
2138 + uint64_t dsel_ext:1;
2139 + uint64_t data:17;
2140 + } cn58xx;
2141 + struct cvmx_dbg_data_cn58xx cn58xxp1;
2142 +};
2143 +
2144 +#endif
2145 --- /dev/null
2146 +++ b/drivers/staging/octeon/cvmx-fau.h
2147 @@ -0,0 +1,597 @@
2148 +/***********************license start***************
2149 + * Author: Cavium Networks
2150 + *
2151 + * Contact: support@caviumnetworks.com
2152 + * This file is part of the OCTEON SDK
2153 + *
2154 + * Copyright (c) 2003-2008 Cavium Networks
2155 + *
2156 + * This file is free software; you can redistribute it and/or modify
2157 + * it under the terms of the GNU General Public License, Version 2, as
2158 + * published by the Free Software Foundation.
2159 + *
2160 + * This file is distributed in the hope that it will be useful, but
2161 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2162 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2163 + * NONINFRINGEMENT. See the GNU General Public License for more
2164 + * details.
2165 + *
2166 + * You should have received a copy of the GNU General Public License
2167 + * along with this file; if not, write to the Free Software
2168 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2169 + * or visit http://www.gnu.org/licenses/.
2170 + *
2171 + * This file may also be available under a different license from Cavium.
2172 + * Contact Cavium Networks for more information
2173 + ***********************license end**************************************/
2174 +
2175 +/*
2176 + * Interface to the hardware Fetch and Add Unit.
2177 + */
2178 +
2179 +#ifndef __CVMX_FAU_H__
2180 +#define __CVMX_FAU_H__
2181 +
2182 +/*
2183 + * Octeon Fetch and Add Unit (FAU)
2184 + */
2185 +
2186 +#define CVMX_FAU_LOAD_IO_ADDRESS cvmx_build_io_address(0x1e, 0)
2187 +#define CVMX_FAU_BITS_SCRADDR 63, 56
2188 +#define CVMX_FAU_BITS_LEN 55, 48
2189 +#define CVMX_FAU_BITS_INEVAL 35, 14
2190 +#define CVMX_FAU_BITS_TAGWAIT 13, 13
2191 +#define CVMX_FAU_BITS_NOADD 13, 13
2192 +#define CVMX_FAU_BITS_SIZE 12, 11
2193 +#define CVMX_FAU_BITS_REGISTER 10, 0
2194 +
2195 +typedef enum {
2196 + CVMX_FAU_OP_SIZE_8 = 0,
2197 + CVMX_FAU_OP_SIZE_16 = 1,
2198 + CVMX_FAU_OP_SIZE_32 = 2,
2199 + CVMX_FAU_OP_SIZE_64 = 3
2200 +} cvmx_fau_op_size_t;
2201 +
2202 +/**
2203 + * Tagwait return definition. If a timeout occurs, the error
2204 + * bit will be set. Otherwise the value of the register before
2205 + * the update will be returned.
2206 + */
2207 +typedef struct {
2208 + uint64_t error:1;
2209 + int64_t value:63;
2210 +} cvmx_fau_tagwait64_t;
2211 +
2212 +/**
2213 + * Tagwait return definition. If a timeout occurs, the error
2214 + * bit will be set. Otherwise the value of the register before
2215 + * the update will be returned.
2216 + */
2217 +typedef struct {
2218 + uint64_t error:1;
2219 + int32_t value:31;
2220 +} cvmx_fau_tagwait32_t;
2221 +
2222 +/**
2223 + * Tagwait return definition. If a timeout occurs, the error
2224 + * bit will be set. Otherwise the value of the register before
2225 + * the update will be returned.
2226 + */
2227 +typedef struct {
2228 + uint64_t error:1;
2229 + int16_t value:15;
2230 +} cvmx_fau_tagwait16_t;
2231 +
2232 +/**
2233 + * Tagwait return definition. If a timeout occurs, the error
2234 + * bit will be set. Otherwise the value of the register before
2235 + * the update will be returned.
2236 + */
2237 +typedef struct {
2238 + uint64_t error:1;
2239 + int8_t value:7;
2240 +} cvmx_fau_tagwait8_t;
2241 +
2242 +/**
2243 + * Asynchronous tagwait return definition. If a timeout occurs,
2244 + * the error bit will be set. Otherwise the value of the
2245 + * register before the update will be returned.
2246 + */
2247 +typedef union {
2248 + uint64_t u64;
2249 + struct {
2250 + uint64_t invalid:1;
2251 + uint64_t data:63; /* unpredictable if invalid is set */
2252 + } s;
2253 +} cvmx_fau_async_tagwait_result_t;
2254 +
2255 +/**
2256 + * Builds a store I/O address for writing to the FAU
2257 + *
2258 + * @noadd: 0 = Store value is atomically added to the current value
2259 + * 1 = Store value is atomically written over the current value
2260 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2261 + * - Step by 2 for 16 bit access.
2262 + * - Step by 4 for 32 bit access.
2263 + * - Step by 8 for 64 bit access.
2264 + * Returns Address to store for atomic update
2265 + */
2266 +static inline uint64_t __cvmx_fau_store_address(uint64_t noadd, uint64_t reg)
2267 +{
2268 + return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
2269 + cvmx_build_bits(CVMX_FAU_BITS_NOADD, noadd) |
2270 + cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2271 +}
2272 +
2273 +/**
2274 + * Builds a I/O address for accessing the FAU
2275 + *
2276 + * @tagwait: Should the atomic add wait for the current tag switch
2277 + * operation to complete.
2278 + * - 0 = Don't wait
2279 + * - 1 = Wait for tag switch to complete
2280 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2281 + * - Step by 2 for 16 bit access.
2282 + * - Step by 4 for 32 bit access.
2283 + * - Step by 8 for 64 bit access.
2284 + * @value: Signed value to add.
2285 + * Note: When performing 32 and 64 bit access, only the low
2286 + * 22 bits are available.
2287 + * Returns Address to read from for atomic update
2288 + */
2289 +static inline uint64_t __cvmx_fau_atomic_address(uint64_t tagwait, uint64_t reg,
2290 + int64_t value)
2291 +{
2292 + return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
2293 + cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
2294 + cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
2295 + cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2296 +}
2297 +
2298 +/**
2299 + * Perform an atomic 64 bit add
2300 + *
2301 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2302 + * - Step by 8 for 64 bit access.
2303 + * @value: Signed value to add.
2304 + * Note: Only the low 22 bits are available.
2305 + * Returns Value of the register before the update
2306 + */
2307 +static inline int64_t cvmx_fau_fetch_and_add64(cvmx_fau_reg_64_t reg,
2308 + int64_t value)
2309 +{
2310 + return cvmx_read64_int64(__cvmx_fau_atomic_address(0, reg, value));
2311 +}
2312 +
2313 +/**
2314 + * Perform an atomic 32 bit add
2315 + *
2316 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2317 + * - Step by 4 for 32 bit access.
2318 + * @value: Signed value to add.
2319 + * Note: Only the low 22 bits are available.
2320 + * Returns Value of the register before the update
2321 + */
2322 +static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg_32_t reg,
2323 + int32_t value)
2324 +{
2325 + return cvmx_read64_int32(__cvmx_fau_atomic_address(0, reg, value));
2326 +}
2327 +
2328 +/**
2329 + * Perform an atomic 16 bit add
2330 + *
2331 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2332 + * - Step by 2 for 16 bit access.
2333 + * @value: Signed value to add.
2334 + * Returns Value of the register before the update
2335 + */
2336 +static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg_16_t reg,
2337 + int16_t value)
2338 +{
2339 + return cvmx_read64_int16(__cvmx_fau_atomic_address(0, reg, value));
2340 +}
2341 +
2342 +/**
2343 + * Perform an atomic 8 bit add
2344 + *
2345 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2346 + * @value: Signed value to add.
2347 + * Returns Value of the register before the update
2348 + */
2349 +static inline int8_t cvmx_fau_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
2350 +{
2351 + return cvmx_read64_int8(__cvmx_fau_atomic_address(0, reg, value));
2352 +}
2353 +
2354 +/**
2355 + * Perform an atomic 64 bit add after the current tag switch
2356 + * completes
2357 + *
2358 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2359 + * - Step by 8 for 64 bit access.
2360 + * @value: Signed value to add.
2361 + * Note: Only the low 22 bits are available.
2362 + * Returns If a timeout occurs, the error bit will be set. Otherwise
2363 + * the value of the register before the update will be
2364 + * returned
2365 + */
2366 +static inline cvmx_fau_tagwait64_t
2367 +cvmx_fau_tagwait_fetch_and_add64(cvmx_fau_reg_64_t reg, int64_t value)
2368 +{
2369 + union {
2370 + uint64_t i64;
2371 + cvmx_fau_tagwait64_t t;
2372 + } result;
2373 + result.i64 =
2374 + cvmx_read64_int64(__cvmx_fau_atomic_address(1, reg, value));
2375 + return result.t;
2376 +}
2377 +
2378 +/**
2379 + * Perform an atomic 32 bit add after the current tag switch
2380 + * completes
2381 + *
2382 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2383 + * - Step by 4 for 32 bit access.
2384 + * @value: Signed value to add.
2385 + * Note: Only the low 22 bits are available.
2386 + * Returns If a timeout occurs, the error bit will be set. Otherwise
2387 + * the value of the register before the update will be
2388 + * returned
2389 + */
2390 +static inline cvmx_fau_tagwait32_t
2391 +cvmx_fau_tagwait_fetch_and_add32(cvmx_fau_reg_32_t reg, int32_t value)
2392 +{
2393 + union {
2394 + uint64_t i32;
2395 + cvmx_fau_tagwait32_t t;
2396 + } result;
2397 + result.i32 =
2398 + cvmx_read64_int32(__cvmx_fau_atomic_address(1, reg, value));
2399 + return result.t;
2400 +}
2401 +
2402 +/**
2403 + * Perform an atomic 16 bit add after the current tag switch
2404 + * completes
2405 + *
2406 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2407 + * - Step by 2 for 16 bit access.
2408 + * @value: Signed value to add.
2409 + * Returns If a timeout occurs, the error bit will be set. Otherwise
2410 + * the value of the register before the update will be
2411 + * returned
2412 + */
2413 +static inline cvmx_fau_tagwait16_t
2414 +cvmx_fau_tagwait_fetch_and_add16(cvmx_fau_reg_16_t reg, int16_t value)
2415 +{
2416 + union {
2417 + uint64_t i16;
2418 + cvmx_fau_tagwait16_t t;
2419 + } result;
2420 + result.i16 =
2421 + cvmx_read64_int16(__cvmx_fau_atomic_address(1, reg, value));
2422 + return result.t;
2423 +}
2424 +
2425 +/**
2426 + * Perform an atomic 8 bit add after the current tag switch
2427 + * completes
2428 + *
2429 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2430 + * @value: Signed value to add.
2431 + * Returns If a timeout occurs, the error bit will be set. Otherwise
2432 + * the value of the register before the update will be
2433 + * returned
2434 + */
2435 +static inline cvmx_fau_tagwait8_t
2436 +cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
2437 +{
2438 + union {
2439 + uint64_t i8;
2440 + cvmx_fau_tagwait8_t t;
2441 + } result;
2442 + result.i8 = cvmx_read64_int8(__cvmx_fau_atomic_address(1, reg, value));
2443 + return result.t;
2444 +}
2445 +
2446 +/**
2447 + * Builds I/O data for async operations
2448 + *
2449 + * @scraddr: Scratch pad byte addres to write to. Must be 8 byte aligned
2450 + * @value: Signed value to add.
2451 + * Note: When performing 32 and 64 bit access, only the low
2452 + * 22 bits are available.
2453 + * @tagwait: Should the atomic add wait for the current tag switch
2454 + * operation to complete.
2455 + * - 0 = Don't wait
2456 + * - 1 = Wait for tag switch to complete
2457 + * @size: The size of the operation:
2458 + * - CVMX_FAU_OP_SIZE_8 (0) = 8 bits
2459 + * - CVMX_FAU_OP_SIZE_16 (1) = 16 bits
2460 + * - CVMX_FAU_OP_SIZE_32 (2) = 32 bits
2461 + * - CVMX_FAU_OP_SIZE_64 (3) = 64 bits
2462 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2463 + * - Step by 2 for 16 bit access.
2464 + * - Step by 4 for 32 bit access.
2465 + * - Step by 8 for 64 bit access.
2466 + * Returns Data to write using cvmx_send_single
2467 + */
2468 +static inline uint64_t __cvmx_fau_iobdma_data(uint64_t scraddr, int64_t value,
2469 + uint64_t tagwait,
2470 + cvmx_fau_op_size_t size,
2471 + uint64_t reg)
2472 +{
2473 + return CVMX_FAU_LOAD_IO_ADDRESS |
2474 + cvmx_build_bits(CVMX_FAU_BITS_SCRADDR, scraddr >> 3) |
2475 + cvmx_build_bits(CVMX_FAU_BITS_LEN, 1) |
2476 + cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
2477 + cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
2478 + cvmx_build_bits(CVMX_FAU_BITS_SIZE, size) |
2479 + cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2480 +}
2481 +
2482 +/**
2483 + * Perform an async atomic 64 bit add. The old value is
2484 + * placed in the scratch memory at byte address scraddr.
2485 + *
2486 + * @scraddr: Scratch memory byte address to put response in.
2487 + * Must be 8 byte aligned.
2488 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2489 + * - Step by 8 for 64 bit access.
2490 + * @value: Signed value to add.
2491 + * Note: Only the low 22 bits are available.
2492 + * Returns Placed in the scratch pad register
2493 + */
2494 +static inline void cvmx_fau_async_fetch_and_add64(uint64_t scraddr,
2495 + cvmx_fau_reg_64_t reg,
2496 + int64_t value)
2497 +{
2498 + cvmx_send_single(__cvmx_fau_iobdma_data
2499 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_64, reg));
2500 +}
2501 +
2502 +/**
2503 + * Perform an async atomic 32 bit add. The old value is
2504 + * placed in the scratch memory at byte address scraddr.
2505 + *
2506 + * @scraddr: Scratch memory byte address to put response in.
2507 + * Must be 8 byte aligned.
2508 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2509 + * - Step by 4 for 32 bit access.
2510 + * @value: Signed value to add.
2511 + * Note: Only the low 22 bits are available.
2512 + * Returns Placed in the scratch pad register
2513 + */
2514 +static inline void cvmx_fau_async_fetch_and_add32(uint64_t scraddr,
2515 + cvmx_fau_reg_32_t reg,
2516 + int32_t value)
2517 +{
2518 + cvmx_send_single(__cvmx_fau_iobdma_data
2519 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_32, reg));
2520 +}
2521 +
2522 +/**
2523 + * Perform an async atomic 16 bit add. The old value is
2524 + * placed in the scratch memory at byte address scraddr.
2525 + *
2526 + * @scraddr: Scratch memory byte address to put response in.
2527 + * Must be 8 byte aligned.
2528 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2529 + * - Step by 2 for 16 bit access.
2530 + * @value: Signed value to add.
2531 + * Returns Placed in the scratch pad register
2532 + */
2533 +static inline void cvmx_fau_async_fetch_and_add16(uint64_t scraddr,
2534 + cvmx_fau_reg_16_t reg,
2535 + int16_t value)
2536 +{
2537 + cvmx_send_single(__cvmx_fau_iobdma_data
2538 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_16, reg));
2539 +}
2540 +
2541 +/**
2542 + * Perform an async atomic 8 bit add. The old value is
2543 + * placed in the scratch memory at byte address scraddr.
2544 + *
2545 + * @scraddr: Scratch memory byte address to put response in.
2546 + * Must be 8 byte aligned.
2547 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2548 + * @value: Signed value to add.
2549 + * Returns Placed in the scratch pad register
2550 + */
2551 +static inline void cvmx_fau_async_fetch_and_add8(uint64_t scraddr,
2552 + cvmx_fau_reg_8_t reg,
2553 + int8_t value)
2554 +{
2555 + cvmx_send_single(__cvmx_fau_iobdma_data
2556 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_8, reg));
2557 +}
2558 +
2559 +/**
2560 + * Perform an async atomic 64 bit add after the current tag
2561 + * switch completes.
2562 + *
2563 + * @scraddr: Scratch memory byte address to put response in. Must be
2564 + * 8 byte aligned. If a timeout occurs, the error bit (63)
2565 + * will be set. Otherwise the value of the register before
2566 + * the update will be returned
2567 + *
2568 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2569 + * - Step by 8 for 64 bit access.
2570 + * @value: Signed value to add.
2571 + * Note: Only the low 22 bits are available.
2572 + * Returns Placed in the scratch pad register
2573 + */
2574 +static inline void cvmx_fau_async_tagwait_fetch_and_add64(uint64_t scraddr,
2575 + cvmx_fau_reg_64_t reg,
2576 + int64_t value)
2577 +{
2578 + cvmx_send_single(__cvmx_fau_iobdma_data
2579 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_64, reg));
2580 +}
2581 +
2582 +/**
2583 + * Perform an async atomic 32 bit add after the current tag
2584 + * switch completes.
2585 + *
2586 + * @scraddr: Scratch memory byte address to put response in. Must be
2587 + * 8 byte aligned. If a timeout occurs, the error bit (63)
2588 + * will be set. Otherwise the value of the register before
2589 + * the update will be returned
2590 + *
2591 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2592 + * - Step by 4 for 32 bit access.
2593 + * @value: Signed value to add.
2594 + * Note: Only the low 22 bits are available.
2595 + * Returns Placed in the scratch pad register
2596 + */
2597 +static inline void cvmx_fau_async_tagwait_fetch_and_add32(uint64_t scraddr,
2598 + cvmx_fau_reg_32_t reg,
2599 + int32_t value)
2600 +{
2601 + cvmx_send_single(__cvmx_fau_iobdma_data
2602 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_32, reg));
2603 +}
2604 +
2605 +/**
2606 + * Perform an async atomic 16 bit add after the current tag
2607 + * switch completes.
2608 + *
2609 + * @scraddr: Scratch memory byte address to put response in. Must be
2610 + * 8 byte aligned. If a timeout occurs, the error bit (63)
2611 + * will be set. Otherwise the value of the register before
2612 + * the update will be returned
2613 + *
2614 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2615 + * - Step by 2 for 16 bit access.
2616 + * @value: Signed value to add.
2617 + *
2618 + * Returns Placed in the scratch pad register
2619 + */
2620 +static inline void cvmx_fau_async_tagwait_fetch_and_add16(uint64_t scraddr,
2621 + cvmx_fau_reg_16_t reg,
2622 + int16_t value)
2623 +{
2624 + cvmx_send_single(__cvmx_fau_iobdma_data
2625 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_16, reg));
2626 +}
2627 +
2628 +/**
2629 + * Perform an async atomic 8 bit add after the current tag
2630 + * switch completes.
2631 + *
2632 + * @scraddr: Scratch memory byte address to put response in. Must be
2633 + * 8 byte aligned. If a timeout occurs, the error bit (63)
2634 + * will be set. Otherwise the value of the register before
2635 + * the update will be returned
2636 + *
2637 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2638 + * @value: Signed value to add.
2639 + *
2640 + * Returns Placed in the scratch pad register
2641 + */
2642 +static inline void cvmx_fau_async_tagwait_fetch_and_add8(uint64_t scraddr,
2643 + cvmx_fau_reg_8_t reg,
2644 + int8_t value)
2645 +{
2646 + cvmx_send_single(__cvmx_fau_iobdma_data
2647 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_8, reg));
2648 +}
2649 +
2650 +/**
2651 + * Perform an atomic 64 bit add
2652 + *
2653 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2654 + * - Step by 8 for 64 bit access.
2655 + * @value: Signed value to add.
2656 + */
2657 +static inline void cvmx_fau_atomic_add64(cvmx_fau_reg_64_t reg, int64_t value)
2658 +{
2659 + cvmx_write64_int64(__cvmx_fau_store_address(0, reg), value);
2660 +}
2661 +
2662 +/**
2663 + * Perform an atomic 32 bit add
2664 + *
2665 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2666 + * - Step by 4 for 32 bit access.
2667 + * @value: Signed value to add.
2668 + */
2669 +static inline void cvmx_fau_atomic_add32(cvmx_fau_reg_32_t reg, int32_t value)
2670 +{
2671 + cvmx_write64_int32(__cvmx_fau_store_address(0, reg), value);
2672 +}
2673 +
2674 +/**
2675 + * Perform an atomic 16 bit add
2676 + *
2677 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2678 + * - Step by 2 for 16 bit access.
2679 + * @value: Signed value to add.
2680 + */
2681 +static inline void cvmx_fau_atomic_add16(cvmx_fau_reg_16_t reg, int16_t value)
2682 +{
2683 + cvmx_write64_int16(__cvmx_fau_store_address(0, reg), value);
2684 +}
2685 +
2686 +/**
2687 + * Perform an atomic 8 bit add
2688 + *
2689 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2690 + * @value: Signed value to add.
2691 + */
2692 +static inline void cvmx_fau_atomic_add8(cvmx_fau_reg_8_t reg, int8_t value)
2693 +{
2694 + cvmx_write64_int8(__cvmx_fau_store_address(0, reg), value);
2695 +}
2696 +
2697 +/**
2698 + * Perform an atomic 64 bit write
2699 + *
2700 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2701 + * - Step by 8 for 64 bit access.
2702 + * @value: Signed value to write.
2703 + */
2704 +static inline void cvmx_fau_atomic_write64(cvmx_fau_reg_64_t reg, int64_t value)
2705 +{
2706 + cvmx_write64_int64(__cvmx_fau_store_address(1, reg), value);
2707 +}
2708 +
2709 +/**
2710 + * Perform an atomic 32 bit write
2711 + *
2712 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2713 + * - Step by 4 for 32 bit access.
2714 + * @value: Signed value to write.
2715 + */
2716 +static inline void cvmx_fau_atomic_write32(cvmx_fau_reg_32_t reg, int32_t value)
2717 +{
2718 + cvmx_write64_int32(__cvmx_fau_store_address(1, reg), value);
2719 +}
2720 +
2721 +/**
2722 + * Perform an atomic 16 bit write
2723 + *
2724 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2725 + * - Step by 2 for 16 bit access.
2726 + * @value: Signed value to write.
2727 + */
2728 +static inline void cvmx_fau_atomic_write16(cvmx_fau_reg_16_t reg, int16_t value)
2729 +{
2730 + cvmx_write64_int16(__cvmx_fau_store_address(1, reg), value);
2731 +}
2732 +
2733 +/**
2734 + * Perform an atomic 8 bit write
2735 + *
2736 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2737 + * @value: Signed value to write.
2738 + */
2739 +static inline void cvmx_fau_atomic_write8(cvmx_fau_reg_8_t reg, int8_t value)
2740 +{
2741 + cvmx_write64_int8(__cvmx_fau_store_address(1, reg), value);
2742 +}
2743 +
2744 +#endif /* __CVMX_FAU_H__ */
2745 --- /dev/null
2746 +++ b/drivers/staging/octeon/cvmx-fpa-defs.h
2747 @@ -0,0 +1,403 @@
2748 +/***********************license start***************
2749 + * Author: Cavium Networks
2750 + *
2751 + * Contact: support@caviumnetworks.com
2752 + * This file is part of the OCTEON SDK
2753 + *
2754 + * Copyright (c) 2003-2008 Cavium Networks
2755 + *
2756 + * This file is free software; you can redistribute it and/or modify
2757 + * it under the terms of the GNU General Public License, Version 2, as
2758 + * published by the Free Software Foundation.
2759 + *
2760 + * This file is distributed in the hope that it will be useful, but
2761 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2762 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2763 + * NONINFRINGEMENT. See the GNU General Public License for more
2764 + * details.
2765 + *
2766 + * You should have received a copy of the GNU General Public License
2767 + * along with this file; if not, write to the Free Software
2768 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2769 + * or visit http://www.gnu.org/licenses/.
2770 + *
2771 + * This file may also be available under a different license from Cavium.
2772 + * Contact Cavium Networks for more information
2773 + ***********************license end**************************************/
2774 +
2775 +#ifndef __CVMX_FPA_DEFS_H__
2776 +#define __CVMX_FPA_DEFS_H__
2777 +
2778 +#define CVMX_FPA_BIST_STATUS \
2779 + CVMX_ADD_IO_SEG(0x00011800280000E8ull)
2780 +#define CVMX_FPA_CTL_STATUS \
2781 + CVMX_ADD_IO_SEG(0x0001180028000050ull)
2782 +#define CVMX_FPA_FPF0_MARKS \
2783 + CVMX_ADD_IO_SEG(0x0001180028000000ull)
2784 +#define CVMX_FPA_FPF0_SIZE \
2785 + CVMX_ADD_IO_SEG(0x0001180028000058ull)
2786 +#define CVMX_FPA_FPF1_MARKS \
2787 + CVMX_ADD_IO_SEG(0x0001180028000008ull)
2788 +#define CVMX_FPA_FPF2_MARKS \
2789 + CVMX_ADD_IO_SEG(0x0001180028000010ull)
2790 +#define CVMX_FPA_FPF3_MARKS \
2791 + CVMX_ADD_IO_SEG(0x0001180028000018ull)
2792 +#define CVMX_FPA_FPF4_MARKS \
2793 + CVMX_ADD_IO_SEG(0x0001180028000020ull)
2794 +#define CVMX_FPA_FPF5_MARKS \
2795 + CVMX_ADD_IO_SEG(0x0001180028000028ull)
2796 +#define CVMX_FPA_FPF6_MARKS \
2797 + CVMX_ADD_IO_SEG(0x0001180028000030ull)
2798 +#define CVMX_FPA_FPF7_MARKS \
2799 + CVMX_ADD_IO_SEG(0x0001180028000038ull)
2800 +#define CVMX_FPA_FPFX_MARKS(offset) \
2801 + CVMX_ADD_IO_SEG(0x0001180028000008ull + (((offset) & 7) * 8) - 8 * 1)
2802 +#define CVMX_FPA_FPFX_SIZE(offset) \
2803 + CVMX_ADD_IO_SEG(0x0001180028000060ull + (((offset) & 7) * 8) - 8 * 1)
2804 +#define CVMX_FPA_INT_ENB \
2805 + CVMX_ADD_IO_SEG(0x0001180028000048ull)
2806 +#define CVMX_FPA_INT_SUM \
2807 + CVMX_ADD_IO_SEG(0x0001180028000040ull)
2808 +#define CVMX_FPA_QUE0_PAGE_INDEX \
2809 + CVMX_ADD_IO_SEG(0x00011800280000F0ull)
2810 +#define CVMX_FPA_QUE1_PAGE_INDEX \
2811 + CVMX_ADD_IO_SEG(0x00011800280000F8ull)
2812 +#define CVMX_FPA_QUE2_PAGE_INDEX \
2813 + CVMX_ADD_IO_SEG(0x0001180028000100ull)
2814 +#define CVMX_FPA_QUE3_PAGE_INDEX \
2815 + CVMX_ADD_IO_SEG(0x0001180028000108ull)
2816 +#define CVMX_FPA_QUE4_PAGE_INDEX \
2817 + CVMX_ADD_IO_SEG(0x0001180028000110ull)
2818 +#define CVMX_FPA_QUE5_PAGE_INDEX \
2819 + CVMX_ADD_IO_SEG(0x0001180028000118ull)
2820 +#define CVMX_FPA_QUE6_PAGE_INDEX \
2821 + CVMX_ADD_IO_SEG(0x0001180028000120ull)
2822 +#define CVMX_FPA_QUE7_PAGE_INDEX \
2823 + CVMX_ADD_IO_SEG(0x0001180028000128ull)
2824 +#define CVMX_FPA_QUEX_AVAILABLE(offset) \
2825 + CVMX_ADD_IO_SEG(0x0001180028000098ull + (((offset) & 7) * 8))
2826 +#define CVMX_FPA_QUEX_PAGE_INDEX(offset) \
2827 + CVMX_ADD_IO_SEG(0x00011800280000F0ull + (((offset) & 7) * 8))
2828 +#define CVMX_FPA_QUE_ACT \
2829 + CVMX_ADD_IO_SEG(0x0001180028000138ull)
2830 +#define CVMX_FPA_QUE_EXP \
2831 + CVMX_ADD_IO_SEG(0x0001180028000130ull)
2832 +#define CVMX_FPA_WART_CTL \
2833 + CVMX_ADD_IO_SEG(0x00011800280000D8ull)
2834 +#define CVMX_FPA_WART_STATUS \
2835 + CVMX_ADD_IO_SEG(0x00011800280000E0ull)
2836 +
2837 +union cvmx_fpa_bist_status {
2838 + uint64_t u64;
2839 + struct cvmx_fpa_bist_status_s {
2840 + uint64_t reserved_5_63:59;
2841 + uint64_t frd:1;
2842 + uint64_t fpf0:1;
2843 + uint64_t fpf1:1;
2844 + uint64_t ffr:1;
2845 + uint64_t fdr:1;
2846 + } s;
2847 + struct cvmx_fpa_bist_status_s cn30xx;
2848 + struct cvmx_fpa_bist_status_s cn31xx;
2849 + struct cvmx_fpa_bist_status_s cn38xx;
2850 + struct cvmx_fpa_bist_status_s cn38xxp2;
2851 + struct cvmx_fpa_bist_status_s cn50xx;
2852 + struct cvmx_fpa_bist_status_s cn52xx;
2853 + struct cvmx_fpa_bist_status_s cn52xxp1;
2854 + struct cvmx_fpa_bist_status_s cn56xx;
2855 + struct cvmx_fpa_bist_status_s cn56xxp1;
2856 + struct cvmx_fpa_bist_status_s cn58xx;
2857 + struct cvmx_fpa_bist_status_s cn58xxp1;
2858 +};
2859 +
2860 +union cvmx_fpa_ctl_status {
2861 + uint64_t u64;
2862 + struct cvmx_fpa_ctl_status_s {
2863 + uint64_t reserved_18_63:46;
2864 + uint64_t reset:1;
2865 + uint64_t use_ldt:1;
2866 + uint64_t use_stt:1;
2867 + uint64_t enb:1;
2868 + uint64_t mem1_err:7;
2869 + uint64_t mem0_err:7;
2870 + } s;
2871 + struct cvmx_fpa_ctl_status_s cn30xx;
2872 + struct cvmx_fpa_ctl_status_s cn31xx;
2873 + struct cvmx_fpa_ctl_status_s cn38xx;
2874 + struct cvmx_fpa_ctl_status_s cn38xxp2;
2875 + struct cvmx_fpa_ctl_status_s cn50xx;
2876 + struct cvmx_fpa_ctl_status_s cn52xx;
2877 + struct cvmx_fpa_ctl_status_s cn52xxp1;
2878 + struct cvmx_fpa_ctl_status_s cn56xx;
2879 + struct cvmx_fpa_ctl_status_s cn56xxp1;
2880 + struct cvmx_fpa_ctl_status_s cn58xx;
2881 + struct cvmx_fpa_ctl_status_s cn58xxp1;
2882 +};
2883 +
2884 +union cvmx_fpa_fpfx_marks {
2885 + uint64_t u64;
2886 + struct cvmx_fpa_fpfx_marks_s {
2887 + uint64_t reserved_22_63:42;
2888 + uint64_t fpf_wr:11;
2889 + uint64_t fpf_rd:11;
2890 + } s;
2891 + struct cvmx_fpa_fpfx_marks_s cn38xx;
2892 + struct cvmx_fpa_fpfx_marks_s cn38xxp2;
2893 + struct cvmx_fpa_fpfx_marks_s cn56xx;
2894 + struct cvmx_fpa_fpfx_marks_s cn56xxp1;
2895 + struct cvmx_fpa_fpfx_marks_s cn58xx;
2896 + struct cvmx_fpa_fpfx_marks_s cn58xxp1;
2897 +};
2898 +
2899 +union cvmx_fpa_fpfx_size {
2900 + uint64_t u64;
2901 + struct cvmx_fpa_fpfx_size_s {
2902 + uint64_t reserved_11_63:53;
2903 + uint64_t fpf_siz:11;
2904 + } s;
2905 + struct cvmx_fpa_fpfx_size_s cn38xx;
2906 + struct cvmx_fpa_fpfx_size_s cn38xxp2;
2907 + struct cvmx_fpa_fpfx_size_s cn56xx;
2908 + struct cvmx_fpa_fpfx_size_s cn56xxp1;
2909 + struct cvmx_fpa_fpfx_size_s cn58xx;
2910 + struct cvmx_fpa_fpfx_size_s cn58xxp1;
2911 +};
2912 +
2913 +union cvmx_fpa_fpf0_marks {
2914 + uint64_t u64;
2915 + struct cvmx_fpa_fpf0_marks_s {
2916 + uint64_t reserved_24_63:40;
2917 + uint64_t fpf_wr:12;
2918 + uint64_t fpf_rd:12;
2919 + } s;
2920 + struct cvmx_fpa_fpf0_marks_s cn38xx;
2921 + struct cvmx_fpa_fpf0_marks_s cn38xxp2;
2922 + struct cvmx_fpa_fpf0_marks_s cn56xx;
2923 + struct cvmx_fpa_fpf0_marks_s cn56xxp1;
2924 + struct cvmx_fpa_fpf0_marks_s cn58xx;
2925 + struct cvmx_fpa_fpf0_marks_s cn58xxp1;
2926 +};
2927 +
2928 +union cvmx_fpa_fpf0_size {
2929 + uint64_t u64;
2930 + struct cvmx_fpa_fpf0_size_s {
2931 + uint64_t reserved_12_63:52;
2932 + uint64_t fpf_siz:12;
2933 + } s;
2934 + struct cvmx_fpa_fpf0_size_s cn38xx;
2935 + struct cvmx_fpa_fpf0_size_s cn38xxp2;
2936 + struct cvmx_fpa_fpf0_size_s cn56xx;
2937 + struct cvmx_fpa_fpf0_size_s cn56xxp1;
2938 + struct cvmx_fpa_fpf0_size_s cn58xx;
2939 + struct cvmx_fpa_fpf0_size_s cn58xxp1;
2940 +};
2941 +
2942 +union cvmx_fpa_int_enb {
2943 + uint64_t u64;
2944 + struct cvmx_fpa_int_enb_s {
2945 + uint64_t reserved_28_63:36;
2946 + uint64_t q7_perr:1;
2947 + uint64_t q7_coff:1;
2948 + uint64_t q7_und:1;
2949 + uint64_t q6_perr:1;
2950 + uint64_t q6_coff:1;
2951 + uint64_t q6_und:1;
2952 + uint64_t q5_perr:1;
2953 + uint64_t q5_coff:1;
2954 + uint64_t q5_und:1;
2955 + uint64_t q4_perr:1;
2956 + uint64_t q4_coff:1;
2957 + uint64_t q4_und:1;
2958 + uint64_t q3_perr:1;
2959 + uint64_t q3_coff:1;
2960 + uint64_t q3_und:1;
2961 + uint64_t q2_perr:1;
2962 + uint64_t q2_coff:1;
2963 + uint64_t q2_und:1;
2964 + uint64_t q1_perr:1;
2965 + uint64_t q1_coff:1;
2966 + uint64_t q1_und:1;
2967 + uint64_t q0_perr:1;
2968 + uint64_t q0_coff:1;
2969 + uint64_t q0_und:1;
2970 + uint64_t fed1_dbe:1;
2971 + uint64_t fed1_sbe:1;
2972 + uint64_t fed0_dbe:1;
2973 + uint64_t fed0_sbe:1;
2974 + } s;
2975 + struct cvmx_fpa_int_enb_s cn30xx;
2976 + struct cvmx_fpa_int_enb_s cn31xx;
2977 + struct cvmx_fpa_int_enb_s cn38xx;
2978 + struct cvmx_fpa_int_enb_s cn38xxp2;
2979 + struct cvmx_fpa_int_enb_s cn50xx;
2980 + struct cvmx_fpa_int_enb_s cn52xx;
2981 + struct cvmx_fpa_int_enb_s cn52xxp1;
2982 + struct cvmx_fpa_int_enb_s cn56xx;
2983 + struct cvmx_fpa_int_enb_s cn56xxp1;
2984 + struct cvmx_fpa_int_enb_s cn58xx;
2985 + struct cvmx_fpa_int_enb_s cn58xxp1;
2986 +};
2987 +
2988 +union cvmx_fpa_int_sum {
2989 + uint64_t u64;
2990 + struct cvmx_fpa_int_sum_s {
2991 + uint64_t reserved_28_63:36;
2992 + uint64_t q7_perr:1;
2993 + uint64_t q7_coff:1;
2994 + uint64_t q7_und:1;
2995 + uint64_t q6_perr:1;
2996 + uint64_t q6_coff:1;
2997 + uint64_t q6_und:1;
2998 + uint64_t q5_perr:1;
2999 + uint64_t q5_coff:1;
3000 + uint64_t q5_und:1;
3001 + uint64_t q4_perr:1;
3002 + uint64_t q4_coff:1;
3003 + uint64_t q4_und:1;
3004 + uint64_t q3_perr:1;
3005 + uint64_t q3_coff:1;
3006 + uint64_t q3_und:1;
3007 + uint64_t q2_perr:1;
3008 + uint64_t q2_coff:1;
3009 + uint64_t q2_und:1;
3010 + uint64_t q1_perr:1;
3011 + uint64_t q1_coff:1;
3012 + uint64_t q1_und:1;
3013 + uint64_t q0_perr:1;
3014 + uint64_t q0_coff:1;
3015 + uint64_t q0_und:1;
3016 + uint64_t fed1_dbe:1;
3017 + uint64_t fed1_sbe:1;
3018 + uint64_t fed0_dbe:1;
3019 + uint64_t fed0_sbe:1;
3020 + } s;
3021 + struct cvmx_fpa_int_sum_s cn30xx;
3022 + struct cvmx_fpa_int_sum_s cn31xx;
3023 + struct cvmx_fpa_int_sum_s cn38xx;
3024 + struct cvmx_fpa_int_sum_s cn38xxp2;
3025 + struct cvmx_fpa_int_sum_s cn50xx;
3026 + struct cvmx_fpa_int_sum_s cn52xx;
3027 + struct cvmx_fpa_int_sum_s cn52xxp1;
3028 + struct cvmx_fpa_int_sum_s cn56xx;
3029 + struct cvmx_fpa_int_sum_s cn56xxp1;
3030 + struct cvmx_fpa_int_sum_s cn58xx;
3031 + struct cvmx_fpa_int_sum_s cn58xxp1;
3032 +};
3033 +
3034 +union cvmx_fpa_quex_available {
3035 + uint64_t u64;
3036 + struct cvmx_fpa_quex_available_s {
3037 + uint64_t reserved_29_63:35;
3038 + uint64_t que_siz:29;
3039 + } s;
3040 + struct cvmx_fpa_quex_available_s cn30xx;
3041 + struct cvmx_fpa_quex_available_s cn31xx;
3042 + struct cvmx_fpa_quex_available_s cn38xx;
3043 + struct cvmx_fpa_quex_available_s cn38xxp2;
3044 + struct cvmx_fpa_quex_available_s cn50xx;
3045 + struct cvmx_fpa_quex_available_s cn52xx;
3046 + struct cvmx_fpa_quex_available_s cn52xxp1;
3047 + struct cvmx_fpa_quex_available_s cn56xx;
3048 + struct cvmx_fpa_quex_available_s cn56xxp1;
3049 + struct cvmx_fpa_quex_available_s cn58xx;
3050 + struct cvmx_fpa_quex_available_s cn58xxp1;
3051 +};
3052 +
3053 +union cvmx_fpa_quex_page_index {
3054 + uint64_t u64;
3055 + struct cvmx_fpa_quex_page_index_s {
3056 + uint64_t reserved_25_63:39;
3057 + uint64_t pg_num:25;
3058 + } s;
3059 + struct cvmx_fpa_quex_page_index_s cn30xx;
3060 + struct cvmx_fpa_quex_page_index_s cn31xx;
3061 + struct cvmx_fpa_quex_page_index_s cn38xx;
3062 + struct cvmx_fpa_quex_page_index_s cn38xxp2;
3063 + struct cvmx_fpa_quex_page_index_s cn50xx;
3064 + struct cvmx_fpa_quex_page_index_s cn52xx;
3065 + struct cvmx_fpa_quex_page_index_s cn52xxp1;
3066 + struct cvmx_fpa_quex_page_index_s cn56xx;
3067 + struct cvmx_fpa_quex_page_index_s cn56xxp1;
3068 + struct cvmx_fpa_quex_page_index_s cn58xx;
3069 + struct cvmx_fpa_quex_page_index_s cn58xxp1;
3070 +};
3071 +
3072 +union cvmx_fpa_que_act {
3073 + uint64_t u64;
3074 + struct cvmx_fpa_que_act_s {
3075 + uint64_t reserved_29_63:35;
3076 + uint64_t act_que:3;
3077 + uint64_t act_indx:26;
3078 + } s;
3079 + struct cvmx_fpa_que_act_s cn30xx;
3080 + struct cvmx_fpa_que_act_s cn31xx;
3081 + struct cvmx_fpa_que_act_s cn38xx;
3082 + struct cvmx_fpa_que_act_s cn38xxp2;
3083 + struct cvmx_fpa_que_act_s cn50xx;
3084 + struct cvmx_fpa_que_act_s cn52xx;
3085 + struct cvmx_fpa_que_act_s cn52xxp1;
3086 + struct cvmx_fpa_que_act_s cn56xx;
3087 + struct cvmx_fpa_que_act_s cn56xxp1;
3088 + struct cvmx_fpa_que_act_s cn58xx;
3089 + struct cvmx_fpa_que_act_s cn58xxp1;
3090 +};
3091 +
3092 +union cvmx_fpa_que_exp {
3093 + uint64_t u64;
3094 + struct cvmx_fpa_que_exp_s {
3095 + uint64_t reserved_29_63:35;
3096 + uint64_t exp_que:3;
3097 + uint64_t exp_indx:26;
3098 + } s;
3099 + struct cvmx_fpa_que_exp_s cn30xx;
3100 + struct cvmx_fpa_que_exp_s cn31xx;
3101 + struct cvmx_fpa_que_exp_s cn38xx;
3102 + struct cvmx_fpa_que_exp_s cn38xxp2;
3103 + struct cvmx_fpa_que_exp_s cn50xx;
3104 + struct cvmx_fpa_que_exp_s cn52xx;
3105 + struct cvmx_fpa_que_exp_s cn52xxp1;
3106 + struct cvmx_fpa_que_exp_s cn56xx;
3107 + struct cvmx_fpa_que_exp_s cn56xxp1;
3108 + struct cvmx_fpa_que_exp_s cn58xx;
3109 + struct cvmx_fpa_que_exp_s cn58xxp1;
3110 +};
3111 +
3112 +union cvmx_fpa_wart_ctl {
3113 + uint64_t u64;
3114 + struct cvmx_fpa_wart_ctl_s {
3115 + uint64_t reserved_16_63:48;
3116 + uint64_t ctl:16;
3117 + } s;
3118 + struct cvmx_fpa_wart_ctl_s cn30xx;
3119 + struct cvmx_fpa_wart_ctl_s cn31xx;
3120 + struct cvmx_fpa_wart_ctl_s cn38xx;
3121 + struct cvmx_fpa_wart_ctl_s cn38xxp2;
3122 + struct cvmx_fpa_wart_ctl_s cn50xx;
3123 + struct cvmx_fpa_wart_ctl_s cn52xx;
3124 + struct cvmx_fpa_wart_ctl_s cn52xxp1;
3125 + struct cvmx_fpa_wart_ctl_s cn56xx;
3126 + struct cvmx_fpa_wart_ctl_s cn56xxp1;
3127 + struct cvmx_fpa_wart_ctl_s cn58xx;
3128 + struct cvmx_fpa_wart_ctl_s cn58xxp1;
3129 +};
3130 +
3131 +union cvmx_fpa_wart_status {
3132 + uint64_t u64;
3133 + struct cvmx_fpa_wart_status_s {
3134 + uint64_t reserved_32_63:32;
3135 + uint64_t status:32;
3136 + } s;
3137 + struct cvmx_fpa_wart_status_s cn30xx;
3138 + struct cvmx_fpa_wart_status_s cn31xx;
3139 + struct cvmx_fpa_wart_status_s cn38xx;
3140 + struct cvmx_fpa_wart_status_s cn38xxp2;
3141 + struct cvmx_fpa_wart_status_s cn50xx;
3142 + struct cvmx_fpa_wart_status_s cn52xx;
3143 + struct cvmx_fpa_wart_status_s cn52xxp1;
3144 + struct cvmx_fpa_wart_status_s cn56xx;
3145 + struct cvmx_fpa_wart_status_s cn56xxp1;
3146 + struct cvmx_fpa_wart_status_s cn58xx;
3147 + struct cvmx_fpa_wart_status_s cn58xxp1;
3148 +};
3149 +
3150 +#endif
3151 --- /dev/null
3152 +++ b/drivers/staging/octeon/cvmx-fpa.c
3153 @@ -0,0 +1,183 @@
3154 +/***********************license start***************
3155 + * Author: Cavium Networks
3156 + *
3157 + * Contact: support@caviumnetworks.com
3158 + * This file is part of the OCTEON SDK
3159 + *
3160 + * Copyright (c) 2003-2008 Cavium Networks
3161 + *
3162 + * This file is free software; you can redistribute it and/or modify
3163 + * it under the terms of the GNU General Public License, Version 2, as
3164 + * published by the Free Software Foundation.
3165 + *
3166 + * This file is distributed in the hope that it will be useful, but
3167 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3168 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3169 + * NONINFRINGEMENT. See the GNU General Public License for more
3170 + * details.
3171 + *
3172 + * You should have received a copy of the GNU General Public License
3173 + * along with this file; if not, write to the Free Software
3174 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3175 + * or visit http://www.gnu.org/licenses/.
3176 + *
3177 + * This file may also be available under a different license from Cavium.
3178 + * Contact Cavium Networks for more information
3179 + ***********************license end**************************************/
3180 +
3181 +/**
3182 + * @file
3183 + *
3184 + * Support library for the hardware Free Pool Allocator.
3185 + *
3186 + *
3187 + */
3188 +
3189 +#include "cvmx-config.h"
3190 +#include "cvmx.h"
3191 +#include "cvmx-fpa.h"
3192 +#include "cvmx-ipd.h"
3193 +
3194 +/**
3195 + * Current state of all the pools. Use access functions
3196 + * instead of using it directly.
3197 + */
3198 +CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
3199 +
3200 +/**
3201 + * Setup a FPA pool to control a new block of memory. The
3202 + * buffer pointer must be a physical address.
3203 + *
3204 + * @pool: Pool to initialize
3205 + * 0 <= pool < 8
3206 + * @name: Constant character string to name this pool.
3207 + * String is not copied.
3208 + * @buffer: Pointer to the block of memory to use. This must be
3209 + * accessable by all processors and external hardware.
3210 + * @block_size: Size for each block controlled by the FPA
3211 + * @num_blocks: Number of blocks
3212 + *
3213 + * Returns 0 on Success,
3214 + * -1 on failure
3215 + */
3216 +int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
3217 + uint64_t block_size, uint64_t num_blocks)
3218 +{
3219 + char *ptr;
3220 + if (!buffer) {
3221 + cvmx_dprintf
3222 + ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
3223 + return -1;
3224 + }
3225 + if (pool >= CVMX_FPA_NUM_POOLS) {
3226 + cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
3227 + return -1;
3228 + }
3229 +
3230 + if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
3231 + cvmx_dprintf
3232 + ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
3233 + return -1;
3234 + }
3235 +
3236 + if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
3237 + cvmx_dprintf
3238 + ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
3239 + return -1;
3240 + }
3241 +
3242 + cvmx_fpa_pool_info[pool].name = name;
3243 + cvmx_fpa_pool_info[pool].size = block_size;
3244 + cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
3245 + cvmx_fpa_pool_info[pool].base = buffer;
3246 +
3247 + ptr = (char *)buffer;
3248 + while (num_blocks--) {
3249 + cvmx_fpa_free(ptr, pool, 0);
3250 + ptr += block_size;
3251 + }
3252 + return 0;
3253 +}
3254 +
3255 +/**
3256 + * Shutdown a Memory pool and validate that it had all of
3257 + * the buffers originally placed in it.
3258 + *
3259 + * @pool: Pool to shutdown
3260 + * Returns Zero on success
3261 + * - Positive is count of missing buffers
3262 + * - Negative is too many buffers or corrupted pointers
3263 + */
3264 +uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
3265 +{
3266 + uint64_t errors = 0;
3267 + uint64_t count = 0;
3268 + uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
3269 + uint64_t finish =
3270 + base +
3271 + cvmx_fpa_pool_info[pool].size *
3272 + cvmx_fpa_pool_info[pool].starting_element_count;
3273 + void *ptr;
3274 + uint64_t address;
3275 +
3276 + count = 0;
3277 + do {
3278 + ptr = cvmx_fpa_alloc(pool);
3279 + if (ptr)
3280 + address = cvmx_ptr_to_phys(ptr);
3281 + else
3282 + address = 0;
3283 + if (address) {
3284 + if ((address >= base) && (address < finish) &&
3285 + (((address -
3286 + base) % cvmx_fpa_pool_info[pool].size) == 0)) {
3287 + count++;
3288 + } else {
3289 + cvmx_dprintf
3290 + ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
3291 + (unsigned long long)address,
3292 + cvmx_fpa_pool_info[pool].name, (int)pool);
3293 + errors++;
3294 + }
3295 + }
3296 + } while (address);
3297 +
3298 +#ifdef CVMX_ENABLE_PKO_FUNCTIONS
3299 + if (pool == 0)
3300 + cvmx_ipd_free_ptr();
3301 +#endif
3302 +
3303 + if (errors) {
3304 + cvmx_dprintf
3305 + ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n",
3306 + cvmx_fpa_pool_info[pool].name, (int)pool,
3307 + (unsigned long long)base, (unsigned long long)finish,
3308 + (unsigned long long)cvmx_fpa_pool_info[pool].size);
3309 + return -errors;
3310 + } else
3311 + return 0;
3312 +}
3313 +
3314 +uint64_t cvmx_fpa_get_block_size(uint64_t pool)
3315 +{
3316 + switch (pool) {
3317 + case 0:
3318 + return CVMX_FPA_POOL_0_SIZE;
3319 + case 1:
3320 + return CVMX_FPA_POOL_1_SIZE;
3321 + case 2:
3322 + return CVMX_FPA_POOL_2_SIZE;
3323 + case 3:
3324 + return CVMX_FPA_POOL_3_SIZE;
3325 + case 4:
3326 + return CVMX_FPA_POOL_4_SIZE;
3327 + case 5:
3328 + return CVMX_FPA_POOL_5_SIZE;
3329 + case 6:
3330 + return CVMX_FPA_POOL_6_SIZE;
3331 + case 7:
3332 + return CVMX_FPA_POOL_7_SIZE;
3333 + default:
3334 + return 0;
3335 + }
3336 +}
3337 --- /dev/null
3338 +++ b/drivers/staging/octeon/cvmx-fpa.h
3339 @@ -0,0 +1,299 @@
3340 +/***********************license start***************
3341 + * Author: Cavium Networks
3342 + *
3343 + * Contact: support@caviumnetworks.com
3344 + * This file is part of the OCTEON SDK
3345 + *
3346 + * Copyright (c) 2003-2008 Cavium Networks
3347 + *
3348 + * This file is free software; you can redistribute it and/or modify
3349 + * it under the terms of the GNU General Public License, Version 2, as
3350 + * published by the Free Software Foundation.
3351 + *
3352 + * This file is distributed in the hope that it will be useful, but
3353 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3354 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3355 + * NONINFRINGEMENT. See the GNU General Public License for more
3356 + * details.
3357 + *
3358 + * You should have received a copy of the GNU General Public License
3359 + * along with this file; if not, write to the Free Software
3360 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3361 + * or visit http://www.gnu.org/licenses/.
3362 + *
3363 + * This file may also be available under a different license from Cavium.
3364 + * Contact Cavium Networks for more information
3365 + ***********************license end**************************************/
3366 +
3367 +/**
3368 + * @file
3369 + *
3370 + * Interface to the hardware Free Pool Allocator.
3371 + *
3372 + *
3373 + */
3374 +
3375 +#ifndef __CVMX_FPA_H__
3376 +#define __CVMX_FPA_H__
3377 +
3378 +#include "cvmx-address.h"
3379 +#include "cvmx-fpa-defs.h"
3380 +
3381 +#define CVMX_FPA_NUM_POOLS 8
3382 +#define CVMX_FPA_MIN_BLOCK_SIZE 128
3383 +#define CVMX_FPA_ALIGNMENT 128
3384 +
3385 +/**
3386 + * Structure describing the data format used for stores to the FPA.
3387 + */
3388 +typedef union {
3389 + uint64_t u64;
3390 + struct {
3391 + /*
3392 + * the (64-bit word) location in scratchpad to write
3393 + * to (if len != 0)
3394 + */
3395 + uint64_t scraddr:8;
3396 + /* the number of words in the response (0 => no response) */
3397 + uint64_t len:8;
3398 + /* the ID of the device on the non-coherent bus */
3399 + uint64_t did:8;
3400 + /*
3401 + * the address that will appear in the first tick on
3402 + * the NCB bus.
3403 + */
3404 + uint64_t addr:40;
3405 + } s;
3406 +} cvmx_fpa_iobdma_data_t;
3407 +
3408 +/**
3409 + * Structure describing the current state of a FPA pool.
3410 + */
3411 +typedef struct {
3412 + /* Name it was created under */
3413 + const char *name;
3414 + /* Size of each block */
3415 + uint64_t size;
3416 + /* The base memory address of whole block */
3417 + void *base;
3418 + /* The number of elements in the pool at creation */
3419 + uint64_t starting_element_count;
3420 +} cvmx_fpa_pool_info_t;
3421 +
3422 +/**
3423 + * Current state of all the pools. Use access functions
3424 + * instead of using it directly.
3425 + */
3426 +extern cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
3427 +
3428 +/* CSR typedefs have been moved to cvmx-csr-*.h */
3429 +
3430 +/**
3431 + * Return the name of the pool
3432 + *
3433 + * @pool: Pool to get the name of
3434 + * Returns The name
3435 + */
3436 +static inline const char *cvmx_fpa_get_name(uint64_t pool)
3437 +{
3438 + return cvmx_fpa_pool_info[pool].name;
3439 +}
3440 +
3441 +/**
3442 + * Return the base of the pool
3443 + *
3444 + * @pool: Pool to get the base of
3445 + * Returns The base
3446 + */
3447 +static inline void *cvmx_fpa_get_base(uint64_t pool)
3448 +{
3449 + return cvmx_fpa_pool_info[pool].base;
3450 +}
3451 +
3452 +/**
3453 + * Check if a pointer belongs to an FPA pool. Return non-zero
3454 + * if the supplied pointer is inside the memory controlled by
3455 + * an FPA pool.
3456 + *
3457 + * @pool: Pool to check
3458 + * @ptr: Pointer to check
3459 + * Returns Non-zero if pointer is in the pool. Zero if not
3460 + */
3461 +static inline int cvmx_fpa_is_member(uint64_t pool, void *ptr)
3462 +{
3463 + return ((ptr >= cvmx_fpa_pool_info[pool].base) &&
3464 + ((char *)ptr <
3465 + ((char *)(cvmx_fpa_pool_info[pool].base)) +
3466 + cvmx_fpa_pool_info[pool].size *
3467 + cvmx_fpa_pool_info[pool].starting_element_count));
3468 +}
3469 +
3470 +/**
3471 + * Enable the FPA for use. Must be performed after any CSR
3472 + * configuration but before any other FPA functions.
3473 + */
3474 +static inline void cvmx_fpa_enable(void)
3475 +{
3476 + union cvmx_fpa_ctl_status status;
3477 +
3478 + status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
3479 + if (status.s.enb) {
3480 + cvmx_dprintf
3481 + ("Warning: Enabling FPA when FPA already enabled.\n");
3482 + }
3483 +
3484 + /*
3485 + * Do runtime check as we allow pass1 compiled code to run on
3486 + * pass2 chips.
3487 + */
3488 + if (cvmx_octeon_is_pass1()) {
3489 + union cvmx_fpa_fpfx_marks marks;
3490 + int i;
3491 + for (i = 1; i < 8; i++) {
3492 + marks.u64 =
3493 + cvmx_read_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull);
3494 + marks.s.fpf_wr = 0xe0;
3495 + cvmx_write_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull,
3496 + marks.u64);
3497 + }
3498 +
3499 + /* Enforce a 10 cycle delay between config and enable */
3500 + cvmx_wait(10);
3501 + }
3502 +
3503 + /* FIXME: CVMX_FPA_CTL_STATUS read is unmodelled */
3504 + status.u64 = 0;
3505 + status.s.enb = 1;
3506 + cvmx_write_csr(CVMX_FPA_CTL_STATUS, status.u64);
3507 +}
3508 +
3509 +/**
3510 + * Get a new block from the FPA
3511 + *
3512 + * @pool: Pool to get the block from
3513 + * Returns Pointer to the block or NULL on failure
3514 + */
3515 +static inline void *cvmx_fpa_alloc(uint64_t pool)
3516 +{
3517 + uint64_t address =
3518 + cvmx_read_csr(CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool)));
3519 + if (address)
3520 + return cvmx_phys_to_ptr(address);
3521 + else
3522 + return NULL;
3523 +}
3524 +
3525 +/**
3526 + * Asynchronously get a new block from the FPA
3527 + *
3528 + * @scr_addr: Local scratch address to put response in. This is a byte address,
3529 + * but must be 8 byte aligned.
3530 + * @pool: Pool to get the block from
3531 + */
3532 +static inline void cvmx_fpa_async_alloc(uint64_t scr_addr, uint64_t pool)
3533 +{
3534 + cvmx_fpa_iobdma_data_t data;
3535 +
3536 + /*
3537 + * Hardware only uses 64 bit alligned locations, so convert
3538 + * from byte address to 64-bit index
3539 + */
3540 + data.s.scraddr = scr_addr >> 3;
3541 + data.s.len = 1;
3542 + data.s.did = CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool);
3543 + data.s.addr = 0;
3544 + cvmx_send_single(data.u64);
3545 +}
3546 +
3547 +/**
3548 + * Free a block allocated with a FPA pool. Does NOT provide memory
3549 + * ordering in cases where the memory block was modified by the core.
3550 + *
3551 + * @ptr: Block to free
3552 + * @pool: Pool to put it in
3553 + * @num_cache_lines:
3554 + * Cache lines to invalidate
3555 + */
3556 +static inline void cvmx_fpa_free_nosync(void *ptr, uint64_t pool,
3557 + uint64_t num_cache_lines)
3558 +{
3559 + cvmx_addr_t newptr;
3560 + newptr.u64 = cvmx_ptr_to_phys(ptr);
3561 + newptr.sfilldidspace.didspace =
3562 + CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool));
3563 + /* Prevent GCC from reordering around free */
3564 + barrier();
3565 + /* value written is number of cache lines not written back */
3566 + cvmx_write_io(newptr.u64, num_cache_lines);
3567 +}
3568 +
3569 +/**
3570 + * Free a block allocated with a FPA pool. Provides required memory
3571 + * ordering in cases where memory block was modified by core.
3572 + *
3573 + * @ptr: Block to free
3574 + * @pool: Pool to put it in
3575 + * @num_cache_lines:
3576 + * Cache lines to invalidate
3577 + */
3578 +static inline void cvmx_fpa_free(void *ptr, uint64_t pool,
3579 + uint64_t num_cache_lines)
3580 +{
3581 + cvmx_addr_t newptr;
3582 + newptr.u64 = cvmx_ptr_to_phys(ptr);
3583 + newptr.sfilldidspace.didspace =
3584 + CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool));
3585 + /*
3586 + * Make sure that any previous writes to memory go out before
3587 + * we free this buffer. This also serves as a barrier to
3588 + * prevent GCC from reordering operations to after the
3589 + * free.
3590 + */
3591 + CVMX_SYNCWS;
3592 + /* value written is number of cache lines not written back */
3593 + cvmx_write_io(newptr.u64, num_cache_lines);
3594 +}
3595 +
3596 +/**
3597 + * Setup a FPA pool to control a new block of memory.
3598 + * This can only be called once per pool. Make sure proper
3599 + * locking enforces this.
3600 + *
3601 + * @pool: Pool to initialize
3602 + * 0 <= pool < 8
3603 + * @name: Constant character string to name this pool.
3604 + * String is not copied.
3605 + * @buffer: Pointer to the block of memory to use. This must be
3606 + * accessable by all processors and external hardware.
3607 + * @block_size: Size for each block controlled by the FPA
3608 + * @num_blocks: Number of blocks
3609 + *
3610 + * Returns 0 on Success,
3611 + * -1 on failure
3612 + */
3613 +extern int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
3614 + uint64_t block_size, uint64_t num_blocks);
3615 +
3616 +/**
3617 + * Shutdown a Memory pool and validate that it had all of
3618 + * the buffers originally placed in it. This should only be
3619 + * called by one processor after all hardware has finished
3620 + * using the pool.
3621 + *
3622 + * @pool: Pool to shutdown
3623 + * Returns Zero on success
3624 + * - Positive is count of missing buffers
3625 + * - Negative is too many buffers or corrupted pointers
3626 + */
3627 +extern uint64_t cvmx_fpa_shutdown_pool(uint64_t pool);
3628 +
3629 +/**
3630 + * Get the size of blocks controlled by the pool
3631 + * This is resolved to a constant at compile time.
3632 + *
3633 + * @pool: Pool to access
3634 + * Returns Size of the block in bytes
3635 + */
3636 +uint64_t cvmx_fpa_get_block_size(uint64_t pool);
3637 +
3638 +#endif /* __CVM_FPA_H__ */
3639 --- /dev/null
3640 +++ b/drivers/staging/octeon/cvmx-gmxx-defs.h
3641 @@ -0,0 +1,2529 @@
3642 +/***********************license start***************
3643 + * Author: Cavium Networks
3644 + *
3645 + * Contact: support@caviumnetworks.com
3646 + * This file is part of the OCTEON SDK
3647 + *
3648 + * Copyright (c) 2003-2008 Cavium Networks
3649 + *
3650 + * This file is free software; you can redistribute it and/or modify
3651 + * it under the terms of the GNU General Public License, Version 2, as
3652 + * published by the Free Software Foundation.
3653 + *
3654 + * This file is distributed in the hope that it will be useful, but
3655 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3656 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3657 + * NONINFRINGEMENT. See the GNU General Public License for more
3658 + * details.
3659 + *
3660 + * You should have received a copy of the GNU General Public License
3661 + * along with this file; if not, write to the Free Software
3662 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3663 + * or visit http://www.gnu.org/licenses/.
3664 + *
3665 + * This file may also be available under a different license from Cavium.
3666 + * Contact Cavium Networks for more information
3667 + ***********************license end**************************************/
3668 +
3669 +#ifndef __CVMX_GMXX_DEFS_H__
3670 +#define __CVMX_GMXX_DEFS_H__
3671 +
3672 +#define CVMX_GMXX_BAD_REG(block_id) \
3673 + CVMX_ADD_IO_SEG(0x0001180008000518ull + (((block_id) & 1) * 0x8000000ull))
3674 +#define CVMX_GMXX_BIST(block_id) \
3675 + CVMX_ADD_IO_SEG(0x0001180008000400ull + (((block_id) & 1) * 0x8000000ull))
3676 +#define CVMX_GMXX_CLK_EN(block_id) \
3677 + CVMX_ADD_IO_SEG(0x00011800080007F0ull + (((block_id) & 1) * 0x8000000ull))
3678 +#define CVMX_GMXX_HG2_CONTROL(block_id) \
3679 + CVMX_ADD_IO_SEG(0x0001180008000550ull + (((block_id) & 1) * 0x8000000ull))
3680 +#define CVMX_GMXX_INF_MODE(block_id) \
3681 + CVMX_ADD_IO_SEG(0x00011800080007F8ull + (((block_id) & 1) * 0x8000000ull))
3682 +#define CVMX_GMXX_NXA_ADR(block_id) \
3683 + CVMX_ADD_IO_SEG(0x0001180008000510ull + (((block_id) & 1) * 0x8000000ull))
3684 +#define CVMX_GMXX_PRTX_CBFC_CTL(offset, block_id) \
3685 + CVMX_ADD_IO_SEG(0x0001180008000580ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3686 +#define CVMX_GMXX_PRTX_CFG(offset, block_id) \
3687 + CVMX_ADD_IO_SEG(0x0001180008000010ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3688 +#define CVMX_GMXX_RXX_ADR_CAM0(offset, block_id) \
3689 + CVMX_ADD_IO_SEG(0x0001180008000180ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3690 +#define CVMX_GMXX_RXX_ADR_CAM1(offset, block_id) \
3691 + CVMX_ADD_IO_SEG(0x0001180008000188ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3692 +#define CVMX_GMXX_RXX_ADR_CAM2(offset, block_id) \
3693 + CVMX_ADD_IO_SEG(0x0001180008000190ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3694 +#define CVMX_GMXX_RXX_ADR_CAM3(offset, block_id) \
3695 + CVMX_ADD_IO_SEG(0x0001180008000198ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3696 +#define CVMX_GMXX_RXX_ADR_CAM4(offset, block_id) \
3697 + CVMX_ADD_IO_SEG(0x00011800080001A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3698 +#define CVMX_GMXX_RXX_ADR_CAM5(offset, block_id) \
3699 + CVMX_ADD_IO_SEG(0x00011800080001A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3700 +#define CVMX_GMXX_RXX_ADR_CAM_EN(offset, block_id) \
3701 + CVMX_ADD_IO_SEG(0x0001180008000108ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3702 +#define CVMX_GMXX_RXX_ADR_CTL(offset, block_id) \
3703 + CVMX_ADD_IO_SEG(0x0001180008000100ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3704 +#define CVMX_GMXX_RXX_DECISION(offset, block_id) \
3705 + CVMX_ADD_IO_SEG(0x0001180008000040ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3706 +#define CVMX_GMXX_RXX_FRM_CHK(offset, block_id) \
3707 + CVMX_ADD_IO_SEG(0x0001180008000020ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3708 +#define CVMX_GMXX_RXX_FRM_CTL(offset, block_id) \
3709 + CVMX_ADD_IO_SEG(0x0001180008000018ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3710 +#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) \
3711 + CVMX_ADD_IO_SEG(0x0001180008000030ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3712 +#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) \
3713 + CVMX_ADD_IO_SEG(0x0001180008000028ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3714 +#define CVMX_GMXX_RXX_IFG(offset, block_id) \
3715 + CVMX_ADD_IO_SEG(0x0001180008000058ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3716 +#define CVMX_GMXX_RXX_INT_EN(offset, block_id) \
3717 + CVMX_ADD_IO_SEG(0x0001180008000008ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3718 +#define CVMX_GMXX_RXX_INT_REG(offset, block_id) \
3719 + CVMX_ADD_IO_SEG(0x0001180008000000ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3720 +#define CVMX_GMXX_RXX_JABBER(offset, block_id) \
3721 + CVMX_ADD_IO_SEG(0x0001180008000038ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3722 +#define CVMX_GMXX_RXX_PAUSE_DROP_TIME(offset, block_id) \
3723 + CVMX_ADD_IO_SEG(0x0001180008000068ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3724 +#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) \
3725 + CVMX_ADD_IO_SEG(0x0001180008000060ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3726 +#define CVMX_GMXX_RXX_STATS_CTL(offset, block_id) \
3727 + CVMX_ADD_IO_SEG(0x0001180008000050ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3728 +#define CVMX_GMXX_RXX_STATS_OCTS(offset, block_id) \
3729 + CVMX_ADD_IO_SEG(0x0001180008000088ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3730 +#define CVMX_GMXX_RXX_STATS_OCTS_CTL(offset, block_id) \
3731 + CVMX_ADD_IO_SEG(0x0001180008000098ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3732 +#define CVMX_GMXX_RXX_STATS_OCTS_DMAC(offset, block_id) \
3733 + CVMX_ADD_IO_SEG(0x00011800080000A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3734 +#define CVMX_GMXX_RXX_STATS_OCTS_DRP(offset, block_id) \
3735 + CVMX_ADD_IO_SEG(0x00011800080000B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3736 +#define CVMX_GMXX_RXX_STATS_PKTS(offset, block_id) \
3737 + CVMX_ADD_IO_SEG(0x0001180008000080ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3738 +#define CVMX_GMXX_RXX_STATS_PKTS_BAD(offset, block_id) \
3739 + CVMX_ADD_IO_SEG(0x00011800080000C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3740 +#define CVMX_GMXX_RXX_STATS_PKTS_CTL(offset, block_id) \
3741 + CVMX_ADD_IO_SEG(0x0001180008000090ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3742 +#define CVMX_GMXX_RXX_STATS_PKTS_DMAC(offset, block_id) \
3743 + CVMX_ADD_IO_SEG(0x00011800080000A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3744 +#define CVMX_GMXX_RXX_STATS_PKTS_DRP(offset, block_id) \
3745 + CVMX_ADD_IO_SEG(0x00011800080000B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3746 +#define CVMX_GMXX_RXX_UDD_SKP(offset, block_id) \
3747 + CVMX_ADD_IO_SEG(0x0001180008000048ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3748 +#define CVMX_GMXX_RX_BP_DROPX(offset, block_id) \
3749 + CVMX_ADD_IO_SEG(0x0001180008000420ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3750 +#define CVMX_GMXX_RX_BP_OFFX(offset, block_id) \
3751 + CVMX_ADD_IO_SEG(0x0001180008000460ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3752 +#define CVMX_GMXX_RX_BP_ONX(offset, block_id) \
3753 + CVMX_ADD_IO_SEG(0x0001180008000440ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3754 +#define CVMX_GMXX_RX_HG2_STATUS(block_id) \
3755 + CVMX_ADD_IO_SEG(0x0001180008000548ull + (((block_id) & 1) * 0x8000000ull))
3756 +#define CVMX_GMXX_RX_PASS_EN(block_id) \
3757 + CVMX_ADD_IO_SEG(0x00011800080005F8ull + (((block_id) & 1) * 0x8000000ull))
3758 +#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) \
3759 + CVMX_ADD_IO_SEG(0x0001180008000600ull + (((offset) & 15) * 8) + (((block_id) & 1) * 0x8000000ull))
3760 +#define CVMX_GMXX_RX_PRTS(block_id) \
3761 + CVMX_ADD_IO_SEG(0x0001180008000410ull + (((block_id) & 1) * 0x8000000ull))
3762 +#define CVMX_GMXX_RX_PRT_INFO(block_id) \
3763 + CVMX_ADD_IO_SEG(0x00011800080004E8ull + (((block_id) & 1) * 0x8000000ull))
3764 +#define CVMX_GMXX_RX_TX_STATUS(block_id) \
3765 + CVMX_ADD_IO_SEG(0x00011800080007E8ull + (((block_id) & 0) * 0x8000000ull))
3766 +#define CVMX_GMXX_RX_XAUI_BAD_COL(block_id) \
3767 + CVMX_ADD_IO_SEG(0x0001180008000538ull + (((block_id) & 1) * 0x8000000ull))
3768 +#define CVMX_GMXX_RX_XAUI_CTL(block_id) \
3769 + CVMX_ADD_IO_SEG(0x0001180008000530ull + (((block_id) & 1) * 0x8000000ull))
3770 +#define CVMX_GMXX_SMACX(offset, block_id) \
3771 + CVMX_ADD_IO_SEG(0x0001180008000230ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3772 +#define CVMX_GMXX_STAT_BP(block_id) \
3773 + CVMX_ADD_IO_SEG(0x0001180008000520ull + (((block_id) & 1) * 0x8000000ull))
3774 +#define CVMX_GMXX_TXX_APPEND(offset, block_id) \
3775 + CVMX_ADD_IO_SEG(0x0001180008000218ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3776 +#define CVMX_GMXX_TXX_BURST(offset, block_id) \
3777 + CVMX_ADD_IO_SEG(0x0001180008000228ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3778 +#define CVMX_GMXX_TXX_CBFC_XOFF(offset, block_id) \
3779 + CVMX_ADD_IO_SEG(0x00011800080005A0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3780 +#define CVMX_GMXX_TXX_CBFC_XON(offset, block_id) \
3781 + CVMX_ADD_IO_SEG(0x00011800080005C0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3782 +#define CVMX_GMXX_TXX_CLK(offset, block_id) \
3783 + CVMX_ADD_IO_SEG(0x0001180008000208ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3784 +#define CVMX_GMXX_TXX_CTL(offset, block_id) \
3785 + CVMX_ADD_IO_SEG(0x0001180008000270ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3786 +#define CVMX_GMXX_TXX_MIN_PKT(offset, block_id) \
3787 + CVMX_ADD_IO_SEG(0x0001180008000240ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3788 +#define CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(offset, block_id) \
3789 + CVMX_ADD_IO_SEG(0x0001180008000248ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3790 +#define CVMX_GMXX_TXX_PAUSE_PKT_TIME(offset, block_id) \
3791 + CVMX_ADD_IO_SEG(0x0001180008000238ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3792 +#define CVMX_GMXX_TXX_PAUSE_TOGO(offset, block_id) \
3793 + CVMX_ADD_IO_SEG(0x0001180008000258ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3794 +#define CVMX_GMXX_TXX_PAUSE_ZERO(offset, block_id) \
3795 + CVMX_ADD_IO_SEG(0x0001180008000260ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3796 +#define CVMX_GMXX_TXX_SGMII_CTL(offset, block_id) \
3797 + CVMX_ADD_IO_SEG(0x0001180008000300ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3798 +#define CVMX_GMXX_TXX_SLOT(offset, block_id) \
3799 + CVMX_ADD_IO_SEG(0x0001180008000220ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3800 +#define CVMX_GMXX_TXX_SOFT_PAUSE(offset, block_id) \
3801 + CVMX_ADD_IO_SEG(0x0001180008000250ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3802 +#define CVMX_GMXX_TXX_STAT0(offset, block_id) \
3803 + CVMX_ADD_IO_SEG(0x0001180008000280ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3804 +#define CVMX_GMXX_TXX_STAT1(offset, block_id) \
3805 + CVMX_ADD_IO_SEG(0x0001180008000288ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3806 +#define CVMX_GMXX_TXX_STAT2(offset, block_id) \
3807 + CVMX_ADD_IO_SEG(0x0001180008000290ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3808 +#define CVMX_GMXX_TXX_STAT3(offset, block_id) \
3809 + CVMX_ADD_IO_SEG(0x0001180008000298ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3810 +#define CVMX_GMXX_TXX_STAT4(offset, block_id) \
3811 + CVMX_ADD_IO_SEG(0x00011800080002A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3812 +#define CVMX_GMXX_TXX_STAT5(offset, block_id) \
3813 + CVMX_ADD_IO_SEG(0x00011800080002A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3814 +#define CVMX_GMXX_TXX_STAT6(offset, block_id) \
3815 + CVMX_ADD_IO_SEG(0x00011800080002B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3816 +#define CVMX_GMXX_TXX_STAT7(offset, block_id) \
3817 + CVMX_ADD_IO_SEG(0x00011800080002B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3818 +#define CVMX_GMXX_TXX_STAT8(offset, block_id) \
3819 + CVMX_ADD_IO_SEG(0x00011800080002C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3820 +#define CVMX_GMXX_TXX_STAT9(offset, block_id) \
3821 + CVMX_ADD_IO_SEG(0x00011800080002C8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3822 +#define CVMX_GMXX_TXX_STATS_CTL(offset, block_id) \
3823 + CVMX_ADD_IO_SEG(0x0001180008000268ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3824 +#define CVMX_GMXX_TXX_THRESH(offset, block_id) \
3825 + CVMX_ADD_IO_SEG(0x0001180008000210ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3826 +#define CVMX_GMXX_TX_BP(block_id) \
3827 + CVMX_ADD_IO_SEG(0x00011800080004D0ull + (((block_id) & 1) * 0x8000000ull))
3828 +#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) \
3829 + CVMX_ADD_IO_SEG(0x0001180008000780ull + (((offset) & 1) * 8) + (((block_id) & 0) * 0x0ull))
3830 +#define CVMX_GMXX_TX_COL_ATTEMPT(block_id) \
3831 + CVMX_ADD_IO_SEG(0x0001180008000498ull + (((block_id) & 1) * 0x8000000ull))
3832 +#define CVMX_GMXX_TX_CORRUPT(block_id) \
3833 + CVMX_ADD_IO_SEG(0x00011800080004D8ull + (((block_id) & 1) * 0x8000000ull))
3834 +#define CVMX_GMXX_TX_HG2_REG1(block_id) \
3835 + CVMX_ADD_IO_SEG(0x0001180008000558ull + (((block_id) & 1) * 0x8000000ull))
3836 +#define CVMX_GMXX_TX_HG2_REG2(block_id) \
3837 + CVMX_ADD_IO_SEG(0x0001180008000560ull + (((block_id) & 1) * 0x8000000ull))
3838 +#define CVMX_GMXX_TX_IFG(block_id) \
3839 + CVMX_ADD_IO_SEG(0x0001180008000488ull + (((block_id) & 1) * 0x8000000ull))
3840 +#define CVMX_GMXX_TX_INT_EN(block_id) \
3841 + CVMX_ADD_IO_SEG(0x0001180008000508ull + (((block_id) & 1) * 0x8000000ull))
3842 +#define CVMX_GMXX_TX_INT_REG(block_id) \
3843 + CVMX_ADD_IO_SEG(0x0001180008000500ull + (((block_id) & 1) * 0x8000000ull))
3844 +#define CVMX_GMXX_TX_JAM(block_id) \
3845 + CVMX_ADD_IO_SEG(0x0001180008000490ull + (((block_id) & 1) * 0x8000000ull))
3846 +#define CVMX_GMXX_TX_LFSR(block_id) \
3847 + CVMX_ADD_IO_SEG(0x00011800080004F8ull + (((block_id) & 1) * 0x8000000ull))
3848 +#define CVMX_GMXX_TX_OVR_BP(block_id) \
3849 + CVMX_ADD_IO_SEG(0x00011800080004C8ull + (((block_id) & 1) * 0x8000000ull))
3850 +#define CVMX_GMXX_TX_PAUSE_PKT_DMAC(block_id) \
3851 + CVMX_ADD_IO_SEG(0x00011800080004A0ull + (((block_id) & 1) * 0x8000000ull))
3852 +#define CVMX_GMXX_TX_PAUSE_PKT_TYPE(block_id) \
3853 + CVMX_ADD_IO_SEG(0x00011800080004A8ull + (((block_id) & 1) * 0x8000000ull))
3854 +#define CVMX_GMXX_TX_PRTS(block_id) \
3855 + CVMX_ADD_IO_SEG(0x0001180008000480ull + (((block_id) & 1) * 0x8000000ull))
3856 +#define CVMX_GMXX_TX_SPI_CTL(block_id) \
3857 + CVMX_ADD_IO_SEG(0x00011800080004C0ull + (((block_id) & 1) * 0x8000000ull))
3858 +#define CVMX_GMXX_TX_SPI_DRAIN(block_id) \
3859 + CVMX_ADD_IO_SEG(0x00011800080004E0ull + (((block_id) & 1) * 0x8000000ull))
3860 +#define CVMX_GMXX_TX_SPI_MAX(block_id) \
3861 + CVMX_ADD_IO_SEG(0x00011800080004B0ull + (((block_id) & 1) * 0x8000000ull))
3862 +#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) \
3863 + CVMX_ADD_IO_SEG(0x0001180008000680ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
3864 +#define CVMX_GMXX_TX_SPI_THRESH(block_id) \
3865 + CVMX_ADD_IO_SEG(0x00011800080004B8ull + (((block_id) & 1) * 0x8000000ull))
3866 +#define CVMX_GMXX_TX_XAUI_CTL(block_id) \
3867 + CVMX_ADD_IO_SEG(0x0001180008000528ull + (((block_id) & 1) * 0x8000000ull))
3868 +#define CVMX_GMXX_XAUI_EXT_LOOPBACK(block_id) \
3869 + CVMX_ADD_IO_SEG(0x0001180008000540ull + (((block_id) & 1) * 0x8000000ull))
3870 +
3871 +union cvmx_gmxx_bad_reg {
3872 + uint64_t u64;
3873 + struct cvmx_gmxx_bad_reg_s {
3874 + uint64_t reserved_31_63:33;
3875 + uint64_t inb_nxa:4;
3876 + uint64_t statovr:1;
3877 + uint64_t loststat:4;
3878 + uint64_t reserved_18_21:4;
3879 + uint64_t out_ovr:16;
3880 + uint64_t ncb_ovr:1;
3881 + uint64_t out_col:1;
3882 + } s;
3883 + struct cvmx_gmxx_bad_reg_cn30xx {
3884 + uint64_t reserved_31_63:33;
3885 + uint64_t inb_nxa:4;
3886 + uint64_t statovr:1;
3887 + uint64_t reserved_25_25:1;
3888 + uint64_t loststat:3;
3889 + uint64_t reserved_5_21:17;
3890 + uint64_t out_ovr:3;
3891 + uint64_t reserved_0_1:2;
3892 + } cn30xx;
3893 + struct cvmx_gmxx_bad_reg_cn30xx cn31xx;
3894 + struct cvmx_gmxx_bad_reg_s cn38xx;
3895 + struct cvmx_gmxx_bad_reg_s cn38xxp2;
3896 + struct cvmx_gmxx_bad_reg_cn30xx cn50xx;
3897 + struct cvmx_gmxx_bad_reg_cn52xx {
3898 + uint64_t reserved_31_63:33;
3899 + uint64_t inb_nxa:4;
3900 + uint64_t statovr:1;
3901 + uint64_t loststat:4;
3902 + uint64_t reserved_6_21:16;
3903 + uint64_t out_ovr:4;
3904 + uint64_t reserved_0_1:2;
3905 + } cn52xx;
3906 + struct cvmx_gmxx_bad_reg_cn52xx cn52xxp1;
3907 + struct cvmx_gmxx_bad_reg_cn52xx cn56xx;
3908 + struct cvmx_gmxx_bad_reg_cn52xx cn56xxp1;
3909 + struct cvmx_gmxx_bad_reg_s cn58xx;
3910 + struct cvmx_gmxx_bad_reg_s cn58xxp1;
3911 +};
3912 +
3913 +union cvmx_gmxx_bist {
3914 + uint64_t u64;
3915 + struct cvmx_gmxx_bist_s {
3916 + uint64_t reserved_17_63:47;
3917 + uint64_t status:17;
3918 + } s;
3919 + struct cvmx_gmxx_bist_cn30xx {
3920 + uint64_t reserved_10_63:54;
3921 + uint64_t status:10;
3922 + } cn30xx;
3923 + struct cvmx_gmxx_bist_cn30xx cn31xx;
3924 + struct cvmx_gmxx_bist_cn30xx cn38xx;
3925 + struct cvmx_gmxx_bist_cn30xx cn38xxp2;
3926 + struct cvmx_gmxx_bist_cn50xx {
3927 + uint64_t reserved_12_63:52;
3928 + uint64_t status:12;
3929 + } cn50xx;
3930 + struct cvmx_gmxx_bist_cn52xx {
3931 + uint64_t reserved_16_63:48;
3932 + uint64_t status:16;
3933 + } cn52xx;
3934 + struct cvmx_gmxx_bist_cn52xx cn52xxp1;
3935 + struct cvmx_gmxx_bist_cn52xx cn56xx;
3936 + struct cvmx_gmxx_bist_cn52xx cn56xxp1;
3937 + struct cvmx_gmxx_bist_s cn58xx;
3938 + struct cvmx_gmxx_bist_s cn58xxp1;
3939 +};
3940 +
3941 +union cvmx_gmxx_clk_en {
3942 + uint64_t u64;
3943 + struct cvmx_gmxx_clk_en_s {
3944 + uint64_t reserved_1_63:63;
3945 + uint64_t clk_en:1;
3946 + } s;
3947 + struct cvmx_gmxx_clk_en_s cn52xx;
3948 + struct cvmx_gmxx_clk_en_s cn52xxp1;
3949 + struct cvmx_gmxx_clk_en_s cn56xx;
3950 + struct cvmx_gmxx_clk_en_s cn56xxp1;
3951 +};
3952 +
3953 +union cvmx_gmxx_hg2_control {
3954 + uint64_t u64;
3955 + struct cvmx_gmxx_hg2_control_s {
3956 + uint64_t reserved_19_63:45;
3957 + uint64_t hg2tx_en:1;
3958 + uint64_t hg2rx_en:1;
3959 + uint64_t phys_en:1;
3960 + uint64_t logl_en:16;
3961 + } s;
3962 + struct cvmx_gmxx_hg2_control_s cn52xx;
3963 + struct cvmx_gmxx_hg2_control_s cn52xxp1;
3964 + struct cvmx_gmxx_hg2_control_s cn56xx;
3965 +};
3966 +
3967 +union cvmx_gmxx_inf_mode {
3968 + uint64_t u64;
3969 + struct cvmx_gmxx_inf_mode_s {
3970 + uint64_t reserved_10_63:54;
3971 + uint64_t speed:2;
3972 + uint64_t reserved_6_7:2;
3973 + uint64_t mode:2;
3974 + uint64_t reserved_3_3:1;
3975 + uint64_t p0mii:1;
3976 + uint64_t en:1;
3977 + uint64_t type:1;
3978 + } s;
3979 + struct cvmx_gmxx_inf_mode_cn30xx {
3980 + uint64_t reserved_3_63:61;
3981 + uint64_t p0mii:1;
3982 + uint64_t en:1;
3983 + uint64_t type:1;
3984 + } cn30xx;
3985 + struct cvmx_gmxx_inf_mode_cn31xx {
3986 + uint64_t reserved_2_63:62;
3987 + uint64_t en:1;
3988 + uint64_t type:1;
3989 + } cn31xx;
3990 + struct cvmx_gmxx_inf_mode_cn31xx cn38xx;
3991 + struct cvmx_gmxx_inf_mode_cn31xx cn38xxp2;
3992 + struct cvmx_gmxx_inf_mode_cn30xx cn50xx;
3993 + struct cvmx_gmxx_inf_mode_cn52xx {
3994 + uint64_t reserved_10_63:54;
3995 + uint64_t speed:2;
3996 + uint64_t reserved_6_7:2;
3997 + uint64_t mode:2;
3998 + uint64_t reserved_2_3:2;
3999 + uint64_t en:1;
4000 + uint64_t type:1;
4001 + } cn52xx;
4002 + struct cvmx_gmxx_inf_mode_cn52xx cn52xxp1;
4003 + struct cvmx_gmxx_inf_mode_cn52xx cn56xx;
4004 + struct cvmx_gmxx_inf_mode_cn52xx cn56xxp1;
4005 + struct cvmx_gmxx_inf_mode_cn31xx cn58xx;
4006 + struct cvmx_gmxx_inf_mode_cn31xx cn58xxp1;
4007 +};
4008 +
4009 +union cvmx_gmxx_nxa_adr {
4010 + uint64_t u64;
4011 + struct cvmx_gmxx_nxa_adr_s {
4012 + uint64_t reserved_6_63:58;
4013 + uint64_t prt:6;
4014 + } s;
4015 + struct cvmx_gmxx_nxa_adr_s cn30xx;
4016 + struct cvmx_gmxx_nxa_adr_s cn31xx;
4017 + struct cvmx_gmxx_nxa_adr_s cn38xx;
4018 + struct cvmx_gmxx_nxa_adr_s cn38xxp2;
4019 + struct cvmx_gmxx_nxa_adr_s cn50xx;
4020 + struct cvmx_gmxx_nxa_adr_s cn52xx;
4021 + struct cvmx_gmxx_nxa_adr_s cn52xxp1;
4022 + struct cvmx_gmxx_nxa_adr_s cn56xx;
4023 + struct cvmx_gmxx_nxa_adr_s cn56xxp1;
4024 + struct cvmx_gmxx_nxa_adr_s cn58xx;
4025 + struct cvmx_gmxx_nxa_adr_s cn58xxp1;
4026 +};
4027 +
4028 +union cvmx_gmxx_prtx_cbfc_ctl {
4029 + uint64_t u64;
4030 + struct cvmx_gmxx_prtx_cbfc_ctl_s {
4031 + uint64_t phys_en:16;
4032 + uint64_t logl_en:16;
4033 + uint64_t phys_bp:16;
4034 + uint64_t reserved_4_15:12;
4035 + uint64_t bck_en:1;
4036 + uint64_t drp_en:1;
4037 + uint64_t tx_en:1;
4038 + uint64_t rx_en:1;
4039 + } s;
4040 + struct cvmx_gmxx_prtx_cbfc_ctl_s cn52xx;
4041 + struct cvmx_gmxx_prtx_cbfc_ctl_s cn56xx;
4042 +};
4043 +
4044 +union cvmx_gmxx_prtx_cfg {
4045 + uint64_t u64;
4046 + struct cvmx_gmxx_prtx_cfg_s {
4047 + uint64_t reserved_14_63:50;
4048 + uint64_t tx_idle:1;
4049 + uint64_t rx_idle:1;
4050 + uint64_t reserved_9_11:3;
4051 + uint64_t speed_msb:1;
4052 + uint64_t reserved_4_7:4;
4053 + uint64_t slottime:1;
4054 + uint64_t duplex:1;
4055 + uint64_t speed:1;
4056 + uint64_t en:1;
4057 + } s;
4058 + struct cvmx_gmxx_prtx_cfg_cn30xx {
4059 + uint64_t reserved_4_63:60;
4060 + uint64_t slottime:1;
4061 + uint64_t duplex:1;
4062 + uint64_t speed:1;
4063 + uint64_t en:1;
4064 + } cn30xx;
4065 + struct cvmx_gmxx_prtx_cfg_cn30xx cn31xx;
4066 + struct cvmx_gmxx_prtx_cfg_cn30xx cn38xx;
4067 + struct cvmx_gmxx_prtx_cfg_cn30xx cn38xxp2;
4068 + struct cvmx_gmxx_prtx_cfg_cn30xx cn50xx;
4069 + struct cvmx_gmxx_prtx_cfg_s cn52xx;
4070 + struct cvmx_gmxx_prtx_cfg_s cn52xxp1;
4071 + struct cvmx_gmxx_prtx_cfg_s cn56xx;
4072 + struct cvmx_gmxx_prtx_cfg_s cn56xxp1;
4073 + struct cvmx_gmxx_prtx_cfg_cn30xx cn58xx;
4074 + struct cvmx_gmxx_prtx_cfg_cn30xx cn58xxp1;
4075 +};
4076 +
4077 +union cvmx_gmxx_rxx_adr_cam0 {
4078 + uint64_t u64;
4079 + struct cvmx_gmxx_rxx_adr_cam0_s {
4080 + uint64_t adr:64;
4081 + } s;
4082 + struct cvmx_gmxx_rxx_adr_cam0_s cn30xx;
4083 + struct cvmx_gmxx_rxx_adr_cam0_s cn31xx;
4084 + struct cvmx_gmxx_rxx_adr_cam0_s cn38xx;
4085 + struct cvmx_gmxx_rxx_adr_cam0_s cn38xxp2;
4086 + struct cvmx_gmxx_rxx_adr_cam0_s cn50xx;
4087 + struct cvmx_gmxx_rxx_adr_cam0_s cn52xx;
4088 + struct cvmx_gmxx_rxx_adr_cam0_s cn52xxp1;
4089 + struct cvmx_gmxx_rxx_adr_cam0_s cn56xx;
4090 + struct cvmx_gmxx_rxx_adr_cam0_s cn56xxp1;
4091 + struct cvmx_gmxx_rxx_adr_cam0_s cn58xx;
4092 + struct cvmx_gmxx_rxx_adr_cam0_s cn58xxp1;
4093 +};
4094 +
4095 +union cvmx_gmxx_rxx_adr_cam1 {
4096 + uint64_t u64;
4097 + struct cvmx_gmxx_rxx_adr_cam1_s {
4098 + uint64_t adr:64;
4099 + } s;
4100 + struct cvmx_gmxx_rxx_adr_cam1_s cn30xx;
4101 + struct cvmx_gmxx_rxx_adr_cam1_s cn31xx;
4102 + struct cvmx_gmxx_rxx_adr_cam1_s cn38xx;
4103 + struct cvmx_gmxx_rxx_adr_cam1_s cn38xxp2;
4104 + struct cvmx_gmxx_rxx_adr_cam1_s cn50xx;
4105 + struct cvmx_gmxx_rxx_adr_cam1_s cn52xx;
4106 + struct cvmx_gmxx_rxx_adr_cam1_s cn52xxp1;
4107 + struct cvmx_gmxx_rxx_adr_cam1_s cn56xx;
4108 + struct cvmx_gmxx_rxx_adr_cam1_s cn56xxp1;
4109 + struct cvmx_gmxx_rxx_adr_cam1_s cn58xx;
4110 + struct cvmx_gmxx_rxx_adr_cam1_s cn58xxp1;
4111 +};
4112 +
4113 +union cvmx_gmxx_rxx_adr_cam2 {
4114 + uint64_t u64;
4115 + struct cvmx_gmxx_rxx_adr_cam2_s {
4116 + uint64_t adr:64;
4117 + } s;
4118 + struct cvmx_gmxx_rxx_adr_cam2_s cn30xx;
4119 + struct cvmx_gmxx_rxx_adr_cam2_s cn31xx;
4120 + struct cvmx_gmxx_rxx_adr_cam2_s cn38xx;
4121 + struct cvmx_gmxx_rxx_adr_cam2_s cn38xxp2;
4122 + struct cvmx_gmxx_rxx_adr_cam2_s cn50xx;
4123 + struct cvmx_gmxx_rxx_adr_cam2_s cn52xx;
4124 + struct cvmx_gmxx_rxx_adr_cam2_s cn52xxp1;
4125 + struct cvmx_gmxx_rxx_adr_cam2_s cn56xx;
4126 + struct cvmx_gmxx_rxx_adr_cam2_s cn56xxp1;
4127 + struct cvmx_gmxx_rxx_adr_cam2_s cn58xx;
4128 + struct cvmx_gmxx_rxx_adr_cam2_s cn58xxp1;
4129 +};
4130 +
4131 +union cvmx_gmxx_rxx_adr_cam3 {
4132 + uint64_t u64;
4133 + struct cvmx_gmxx_rxx_adr_cam3_s {
4134 + uint64_t adr:64;
4135 + } s;
4136 + struct cvmx_gmxx_rxx_adr_cam3_s cn30xx;
4137 + struct cvmx_gmxx_rxx_adr_cam3_s cn31xx;
4138 + struct cvmx_gmxx_rxx_adr_cam3_s cn38xx;
4139 + struct cvmx_gmxx_rxx_adr_cam3_s cn38xxp2;
4140 + struct cvmx_gmxx_rxx_adr_cam3_s cn50xx;
4141 + struct cvmx_gmxx_rxx_adr_cam3_s cn52xx;
4142 + struct cvmx_gmxx_rxx_adr_cam3_s cn52xxp1;
4143 + struct cvmx_gmxx_rxx_adr_cam3_s cn56xx;
4144 + struct cvmx_gmxx_rxx_adr_cam3_s cn56xxp1;
4145 + struct cvmx_gmxx_rxx_adr_cam3_s cn58xx;
4146 + struct cvmx_gmxx_rxx_adr_cam3_s cn58xxp1;
4147 +};
4148 +
4149 +union cvmx_gmxx_rxx_adr_cam4 {
4150 + uint64_t u64;
4151 + struct cvmx_gmxx_rxx_adr_cam4_s {
4152 + uint64_t adr:64;
4153 + } s;
4154 + struct cvmx_gmxx_rxx_adr_cam4_s cn30xx;
4155 + struct cvmx_gmxx_rxx_adr_cam4_s cn31xx;
4156 + struct cvmx_gmxx_rxx_adr_cam4_s cn38xx;
4157 + struct cvmx_gmxx_rxx_adr_cam4_s cn38xxp2;
4158 + struct cvmx_gmxx_rxx_adr_cam4_s cn50xx;
4159 + struct cvmx_gmxx_rxx_adr_cam4_s cn52xx;
4160 + struct cvmx_gmxx_rxx_adr_cam4_s cn52xxp1;
4161 + struct cvmx_gmxx_rxx_adr_cam4_s cn56xx;
4162 + struct cvmx_gmxx_rxx_adr_cam4_s cn56xxp1;
4163 + struct cvmx_gmxx_rxx_adr_cam4_s cn58xx;
4164 + struct cvmx_gmxx_rxx_adr_cam4_s cn58xxp1;
4165 +};
4166 +
4167 +union cvmx_gmxx_rxx_adr_cam5 {
4168 + uint64_t u64;
4169 + struct cvmx_gmxx_rxx_adr_cam5_s {
4170 + uint64_t adr:64;
4171 + } s;
4172 + struct cvmx_gmxx_rxx_adr_cam5_s cn30xx;
4173 + struct cvmx_gmxx_rxx_adr_cam5_s cn31xx;
4174 + struct cvmx_gmxx_rxx_adr_cam5_s cn38xx;
4175 + struct cvmx_gmxx_rxx_adr_cam5_s cn38xxp2;
4176 + struct cvmx_gmxx_rxx_adr_cam5_s cn50xx;
4177 + struct cvmx_gmxx_rxx_adr_cam5_s cn52xx;
4178 + struct cvmx_gmxx_rxx_adr_cam5_s cn52xxp1;
4179 + struct cvmx_gmxx_rxx_adr_cam5_s cn56xx;
4180 + struct cvmx_gmxx_rxx_adr_cam5_s cn56xxp1;
4181 + struct cvmx_gmxx_rxx_adr_cam5_s cn58xx;
4182 + struct cvmx_gmxx_rxx_adr_cam5_s cn58xxp1;
4183 +};
4184 +
4185 +union cvmx_gmxx_rxx_adr_cam_en {
4186 + uint64_t u64;
4187 + struct cvmx_gmxx_rxx_adr_cam_en_s {
4188 + uint64_t reserved_8_63:56;
4189 + uint64_t en:8;
4190 + } s;
4191 + struct cvmx_gmxx_rxx_adr_cam_en_s cn30xx;
4192 + struct cvmx_gmxx_rxx_adr_cam_en_s cn31xx;
4193 + struct cvmx_gmxx_rxx_adr_cam_en_s cn38xx;
4194 + struct cvmx_gmxx_rxx_adr_cam_en_s cn38xxp2;
4195 + struct cvmx_gmxx_rxx_adr_cam_en_s cn50xx;
4196 + struct cvmx_gmxx_rxx_adr_cam_en_s cn52xx;
4197 + struct cvmx_gmxx_rxx_adr_cam_en_s cn52xxp1;
4198 + struct cvmx_gmxx_rxx_adr_cam_en_s cn56xx;
4199 + struct cvmx_gmxx_rxx_adr_cam_en_s cn56xxp1;
4200 + struct cvmx_gmxx_rxx_adr_cam_en_s cn58xx;
4201 + struct cvmx_gmxx_rxx_adr_cam_en_s cn58xxp1;
4202 +};
4203 +
4204 +union cvmx_gmxx_rxx_adr_ctl {
4205 + uint64_t u64;
4206 + struct cvmx_gmxx_rxx_adr_ctl_s {
4207 + uint64_t reserved_4_63:60;
4208 + uint64_t cam_mode:1;
4209 + uint64_t mcst:2;
4210 + uint64_t bcst:1;
4211 + } s;
4212 + struct cvmx_gmxx_rxx_adr_ctl_s cn30xx;
4213 + struct cvmx_gmxx_rxx_adr_ctl_s cn31xx;
4214 + struct cvmx_gmxx_rxx_adr_ctl_s cn38xx;
4215 + struct cvmx_gmxx_rxx_adr_ctl_s cn38xxp2;
4216 + struct cvmx_gmxx_rxx_adr_ctl_s cn50xx;
4217 + struct cvmx_gmxx_rxx_adr_ctl_s cn52xx;
4218 + struct cvmx_gmxx_rxx_adr_ctl_s cn52xxp1;
4219 + struct cvmx_gmxx_rxx_adr_ctl_s cn56xx;
4220 + struct cvmx_gmxx_rxx_adr_ctl_s cn56xxp1;
4221 + struct cvmx_gmxx_rxx_adr_ctl_s cn58xx;
4222 + struct cvmx_gmxx_rxx_adr_ctl_s cn58xxp1;
4223 +};
4224 +
4225 +union cvmx_gmxx_rxx_decision {
4226 + uint64_t u64;
4227 + struct cvmx_gmxx_rxx_decision_s {
4228 + uint64_t reserved_5_63:59;
4229 + uint64_t cnt:5;
4230 + } s;
4231 + struct cvmx_gmxx_rxx_decision_s cn30xx;
4232 + struct cvmx_gmxx_rxx_decision_s cn31xx;
4233 + struct cvmx_gmxx_rxx_decision_s cn38xx;
4234 + struct cvmx_gmxx_rxx_decision_s cn38xxp2;
4235 + struct cvmx_gmxx_rxx_decision_s cn50xx;
4236 + struct cvmx_gmxx_rxx_decision_s cn52xx;
4237 + struct cvmx_gmxx_rxx_decision_s cn52xxp1;
4238 + struct cvmx_gmxx_rxx_decision_s cn56xx;
4239 + struct cvmx_gmxx_rxx_decision_s cn56xxp1;
4240 + struct cvmx_gmxx_rxx_decision_s cn58xx;
4241 + struct cvmx_gmxx_rxx_decision_s cn58xxp1;
4242 +};
4243 +
4244 +union cvmx_gmxx_rxx_frm_chk {
4245 + uint64_t u64;
4246 + struct cvmx_gmxx_rxx_frm_chk_s {
4247 + uint64_t reserved_10_63:54;
4248 + uint64_t niberr:1;
4249 + uint64_t skperr:1;
4250 + uint64_t rcverr:1;
4251 + uint64_t lenerr:1;
4252 + uint64_t alnerr:1;
4253 + uint64_t fcserr:1;
4254 + uint64_t jabber:1;
4255 + uint64_t maxerr:1;
4256 + uint64_t carext:1;
4257 + uint64_t minerr:1;
4258 + } s;
4259 + struct cvmx_gmxx_rxx_frm_chk_s cn30xx;
4260 + struct cvmx_gmxx_rxx_frm_chk_s cn31xx;
4261 + struct cvmx_gmxx_rxx_frm_chk_s cn38xx;
4262 + struct cvmx_gmxx_rxx_frm_chk_s cn38xxp2;
4263 + struct cvmx_gmxx_rxx_frm_chk_cn50xx {
4264 + uint64_t reserved_10_63:54;
4265 + uint64_t niberr:1;
4266 + uint64_t skperr:1;
4267 + uint64_t rcverr:1;
4268 + uint64_t reserved_6_6:1;
4269 + uint64_t alnerr:1;
4270 + uint64_t fcserr:1;
4271 + uint64_t jabber:1;
4272 + uint64_t reserved_2_2:1;
4273 + uint64_t carext:1;
4274 + uint64_t reserved_0_0:1;
4275 + } cn50xx;
4276 + struct cvmx_gmxx_rxx_frm_chk_cn52xx {
4277 + uint64_t reserved_9_63:55;
4278 + uint64_t skperr:1;
4279 + uint64_t rcverr:1;
4280 + uint64_t reserved_5_6:2;
4281 + uint64_t fcserr:1;
4282 + uint64_t jabber:1;
4283 + uint64_t reserved_2_2:1;
4284 + uint64_t carext:1;
4285 + uint64_t reserved_0_0:1;
4286 + } cn52xx;
4287 + struct cvmx_gmxx_rxx_frm_chk_cn52xx cn52xxp1;
4288 + struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xx;
4289 + struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xxp1;
4290 + struct cvmx_gmxx_rxx_frm_chk_s cn58xx;
4291 + struct cvmx_gmxx_rxx_frm_chk_s cn58xxp1;
4292 +};
4293 +
4294 +union cvmx_gmxx_rxx_frm_ctl {
4295 + uint64_t u64;
4296 + struct cvmx_gmxx_rxx_frm_ctl_s {
4297 + uint64_t reserved_11_63:53;
4298 + uint64_t null_dis:1;
4299 + uint64_t pre_align:1;
4300 + uint64_t pad_len:1;
4301 + uint64_t vlan_len:1;
4302 + uint64_t pre_free:1;
4303 + uint64_t ctl_smac:1;
4304 + uint64_t ctl_mcst:1;
4305 + uint64_t ctl_bck:1;
4306 + uint64_t ctl_drp:1;
4307 + uint64_t pre_strp:1;
4308 + uint64_t pre_chk:1;
4309 + } s;
4310 + struct cvmx_gmxx_rxx_frm_ctl_cn30xx {
4311 + uint64_t reserved_9_63:55;
4312 + uint64_t pad_len:1;
4313 + uint64_t vlan_len:1;
4314 + uint64_t pre_free:1;
4315 + uint64_t ctl_smac:1;
4316 + uint64_t ctl_mcst:1;
4317 + uint64_t ctl_bck:1;
4318 + uint64_t ctl_drp:1;
4319 + uint64_t pre_strp:1;
4320 + uint64_t pre_chk:1;
4321 + } cn30xx;
4322 + struct cvmx_gmxx_rxx_frm_ctl_cn31xx {
4323 + uint64_t reserved_8_63:56;
4324 + uint64_t vlan_len:1;
4325 + uint64_t pre_free:1;
4326 + uint64_t ctl_smac:1;
4327 + uint64_t ctl_mcst:1;
4328 + uint64_t ctl_bck:1;
4329 + uint64_t ctl_drp:1;
4330 + uint64_t pre_strp:1;
4331 + uint64_t pre_chk:1;
4332 + } cn31xx;
4333 + struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn38xx;
4334 + struct cvmx_gmxx_rxx_frm_ctl_cn31xx cn38xxp2;
4335 + struct cvmx_gmxx_rxx_frm_ctl_cn50xx {
4336 + uint64_t reserved_11_63:53;
4337 + uint64_t null_dis:1;
4338 + uint64_t pre_align:1;
4339 + uint64_t reserved_7_8:2;
4340 + uint64_t pre_free:1;
4341 + uint64_t ctl_smac:1;
4342 + uint64_t ctl_mcst:1;
4343 + uint64_t ctl_bck:1;
4344 + uint64_t ctl_drp:1;
4345 + uint64_t pre_strp:1;
4346 + uint64_t pre_chk:1;
4347 + } cn50xx;
4348 + struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xx;
4349 + struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xxp1;
4350 + struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn56xx;
4351 + struct cvmx_gmxx_rxx_frm_ctl_cn56xxp1 {
4352 + uint64_t reserved_10_63:54;
4353 + uint64_t pre_align:1;
4354 + uint64_t reserved_7_8:2;
4355 + uint64_t pre_free:1;
4356 + uint64_t ctl_smac:1;
4357 + uint64_t ctl_mcst:1;
4358 + uint64_t ctl_bck:1;
4359 + uint64_t ctl_drp:1;
4360 + uint64_t pre_strp:1;
4361 + uint64_t pre_chk:1;
4362 + } cn56xxp1;
4363 + struct cvmx_gmxx_rxx_frm_ctl_s cn58xx;
4364 + struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn58xxp1;
4365 +};
4366 +
4367 +union cvmx_gmxx_rxx_frm_max {
4368 + uint64_t u64;
4369 + struct cvmx_gmxx_rxx_frm_max_s {
4370 + uint64_t reserved_16_63:48;
4371 + uint64_t len:16;
4372 + } s;
4373 + struct cvmx_gmxx_rxx_frm_max_s cn30xx;
4374 + struct cvmx_gmxx_rxx_frm_max_s cn31xx;
4375 + struct cvmx_gmxx_rxx_frm_max_s cn38xx;
4376 + struct cvmx_gmxx_rxx_frm_max_s cn38xxp2;
4377 + struct cvmx_gmxx_rxx_frm_max_s cn58xx;
4378 + struct cvmx_gmxx_rxx_frm_max_s cn58xxp1;
4379 +};
4380 +
4381 +union cvmx_gmxx_rxx_frm_min {
4382 + uint64_t u64;
4383 + struct cvmx_gmxx_rxx_frm_min_s {
4384 + uint64_t reserved_16_63:48;
4385 + uint64_t len:16;
4386 + } s;
4387 + struct cvmx_gmxx_rxx_frm_min_s cn30xx;
4388 + struct cvmx_gmxx_rxx_frm_min_s cn31xx;
4389 + struct cvmx_gmxx_rxx_frm_min_s cn38xx;
4390 + struct cvmx_gmxx_rxx_frm_min_s cn38xxp2;
4391 + struct cvmx_gmxx_rxx_frm_min_s cn58xx;
4392 + struct cvmx_gmxx_rxx_frm_min_s cn58xxp1;
4393 +};
4394 +
4395 +union cvmx_gmxx_rxx_ifg {
4396 + uint64_t u64;
4397 + struct cvmx_gmxx_rxx_ifg_s {
4398 + uint64_t reserved_4_63:60;
4399 + uint64_t ifg:4;
4400 + } s;
4401 + struct cvmx_gmxx_rxx_ifg_s cn30xx;
4402 + struct cvmx_gmxx_rxx_ifg_s cn31xx;
4403 + struct cvmx_gmxx_rxx_ifg_s cn38xx;
4404 + struct cvmx_gmxx_rxx_ifg_s cn38xxp2;
4405 + struct cvmx_gmxx_rxx_ifg_s cn50xx;
4406 + struct cvmx_gmxx_rxx_ifg_s cn52xx;
4407 + struct cvmx_gmxx_rxx_ifg_s cn52xxp1;
4408 + struct cvmx_gmxx_rxx_ifg_s cn56xx;
4409 + struct cvmx_gmxx_rxx_ifg_s cn56xxp1;
4410 + struct cvmx_gmxx_rxx_ifg_s cn58xx;
4411 + struct cvmx_gmxx_rxx_ifg_s cn58xxp1;
4412 +};
4413 +
4414 +union cvmx_gmxx_rxx_int_en {
4415 + uint64_t u64;
4416 + struct cvmx_gmxx_rxx_int_en_s {
4417 + uint64_t reserved_29_63:35;
4418 + uint64_t hg2cc:1;
4419 + uint64_t hg2fld:1;
4420 + uint64_t undat:1;
4421 + uint64_t uneop:1;
4422 + uint64_t unsop:1;
4423 + uint64_t bad_term:1;
4424 + uint64_t bad_seq:1;
4425 + uint64_t rem_fault:1;
4426 + uint64_t loc_fault:1;
4427 + uint64_t pause_drp:1;
4428 + uint64_t phy_dupx:1;
4429 + uint64_t phy_spd:1;
4430 + uint64_t phy_link:1;
4431 + uint64_t ifgerr:1;
4432 + uint64_t coldet:1;
4433 + uint64_t falerr:1;
4434 + uint64_t rsverr:1;
4435 + uint64_t pcterr:1;
4436 + uint64_t ovrerr:1;
4437 + uint64_t niberr:1;
4438 + uint64_t skperr:1;
4439 + uint64_t rcverr:1;
4440 + uint64_t lenerr:1;
4441 + uint64_t alnerr:1;
4442 + uint64_t fcserr:1;
4443 + uint64_t jabber:1;
4444 + uint64_t maxerr:1;
4445 + uint64_t carext:1;
4446 + uint64_t minerr:1;
4447 + } s;
4448 + struct cvmx_gmxx_rxx_int_en_cn30xx {
4449 + uint64_t reserved_19_63:45;
4450 + uint64_t phy_dupx:1;
4451 + uint64_t phy_spd:1;
4452 + uint64_t phy_link:1;
4453 + uint64_t ifgerr:1;
4454 + uint64_t coldet:1;
4455 + uint64_t falerr:1;
4456 + uint64_t rsverr:1;
4457 + uint64_t pcterr:1;
4458 + uint64_t ovrerr:1;
4459 + uint64_t niberr:1;
4460 + uint64_t skperr:1;
4461 + uint64_t rcverr:1;
4462 + uint64_t lenerr:1;
4463 + uint64_t alnerr:1;
4464 + uint64_t fcserr:1;
4465 + uint64_t jabber:1;
4466 + uint64_t maxerr:1;
4467 + uint64_t carext:1;
4468 + uint64_t minerr:1;
4469 + } cn30xx;
4470 + struct cvmx_gmxx_rxx_int_en_cn30xx cn31xx;
4471 + struct cvmx_gmxx_rxx_int_en_cn30xx cn38xx;
4472 + struct cvmx_gmxx_rxx_int_en_cn30xx cn38xxp2;
4473 + struct cvmx_gmxx_rxx_int_en_cn50xx {
4474 + uint64_t reserved_20_63:44;
4475 + uint64_t pause_drp:1;
4476 + uint64_t phy_dupx:1;
4477 + uint64_t phy_spd:1;
4478 + uint64_t phy_link:1;
4479 + uint64_t ifgerr:1;
4480 + uint64_t coldet:1;
4481 + uint64_t falerr:1;
4482 + uint64_t rsverr:1;
4483 + uint64_t pcterr:1;
4484 + uint64_t ovrerr:1;
4485 + uint64_t niberr:1;
4486 + uint64_t skperr:1;
4487 + uint64_t rcverr:1;
4488 + uint64_t reserved_6_6:1;
4489 + uint64_t alnerr:1;
4490 + uint64_t fcserr:1;
4491 + uint64_t jabber:1;
4492 + uint64_t reserved_2_2:1;
4493 + uint64_t carext:1;
4494 + uint64_t reserved_0_0:1;
4495 + } cn50xx;
4496 + struct cvmx_gmxx_rxx_int_en_cn52xx {
4497 + uint64_t reserved_29_63:35;
4498 + uint64_t hg2cc:1;
4499 + uint64_t hg2fld:1;
4500 + uint64_t undat:1;
4501 + uint64_t uneop:1;
4502 + uint64_t unsop:1;
4503 + uint64_t bad_term:1;
4504 + uint64_t bad_seq:1;
4505 + uint64_t rem_fault:1;
4506 + uint64_t loc_fault:1;
4507 + uint64_t pause_drp:1;
4508 + uint64_t reserved_16_18:3;
4509 + uint64_t ifgerr:1;
4510 + uint64_t coldet:1;
4511 + uint64_t falerr:1;
4512 + uint64_t rsverr:1;
4513 + uint64_t pcterr:1;
4514 + uint64_t ovrerr:1;
4515 + uint64_t reserved_9_9:1;
4516 + uint64_t skperr:1;
4517 + uint64_t rcverr:1;
4518 + uint64_t reserved_5_6:2;
4519 + uint64_t fcserr:1;
4520 + uint64_t jabber:1;
4521 + uint64_t reserved_2_2:1;
4522 + uint64_t carext:1;
4523 + uint64_t reserved_0_0:1;
4524 + } cn52xx;
4525 + struct cvmx_gmxx_rxx_int_en_cn52xx cn52xxp1;
4526 + struct cvmx_gmxx_rxx_int_en_cn52xx cn56xx;
4527 + struct cvmx_gmxx_rxx_int_en_cn56xxp1 {
4528 + uint64_t reserved_27_63:37;
4529 + uint64_t undat:1;
4530 + uint64_t uneop:1;
4531 + uint64_t unsop:1;
4532 + uint64_t bad_term:1;
4533 + uint64_t bad_seq:1;
4534 + uint64_t rem_fault:1;
4535 + uint64_t loc_fault:1;
4536 + uint64_t pause_drp:1;
4537 + uint64_t reserved_16_18:3;
4538 + uint64_t ifgerr:1;
4539 + uint64_t coldet:1;
4540 + uint64_t falerr:1;
4541 + uint64_t rsverr:1;
4542 + uint64_t pcterr:1;
4543 + uint64_t ovrerr:1;
4544 + uint64_t reserved_9_9:1;
4545 + uint64_t skperr:1;
4546 + uint64_t rcverr:1;
4547 + uint64_t reserved_5_6:2;
4548 + uint64_t fcserr:1;
4549 + uint64_t jabber:1;
4550 + uint64_t reserved_2_2:1;
4551 + uint64_t carext:1;
4552 + uint64_t reserved_0_0:1;
4553 + } cn56xxp1;
4554 + struct cvmx_gmxx_rxx_int_en_cn58xx {
4555 + uint64_t reserved_20_63:44;
4556 + uint64_t pause_drp:1;
4557 + uint64_t phy_dupx:1;
4558 + uint64_t phy_spd:1;
4559 + uint64_t phy_link:1;
4560 + uint64_t ifgerr:1;
4561 + uint64_t coldet:1;
4562 + uint64_t falerr:1;
4563 + uint64_t rsverr:1;
4564 + uint64_t pcterr:1;
4565 + uint64_t ovrerr:1;
4566 + uint64_t niberr:1;
4567 + uint64_t skperr:1;
4568 + uint64_t rcverr:1;
4569 + uint64_t lenerr:1;
4570 + uint64_t alnerr:1;
4571 + uint64_t fcserr:1;
4572 + uint64_t jabber:1;
4573 + uint64_t maxerr:1;
4574 + uint64_t carext:1;
4575 + uint64_t minerr:1;
4576 + } cn58xx;
4577 + struct cvmx_gmxx_rxx_int_en_cn58xx cn58xxp1;
4578 +};
4579 +
4580 +union cvmx_gmxx_rxx_int_reg {
4581 + uint64_t u64;
4582 + struct cvmx_gmxx_rxx_int_reg_s {
4583 + uint64_t reserved_29_63:35;
4584 + uint64_t hg2cc:1;
4585 + uint64_t hg2fld:1;
4586 + uint64_t undat:1;
4587 + uint64_t uneop:1;
4588 + uint64_t unsop:1;
4589 + uint64_t bad_term:1;
4590 + uint64_t bad_seq:1;
4591 + uint64_t rem_fault:1;
4592 + uint64_t loc_fault:1;
4593 + uint64_t pause_drp:1;
4594 + uint64_t phy_dupx:1;
4595 + uint64_t phy_spd:1;
4596 + uint64_t phy_link:1;
4597 + uint64_t ifgerr:1;
4598 + uint64_t coldet:1;
4599 + uint64_t falerr:1;
4600 + uint64_t rsverr:1;
4601 + uint64_t pcterr:1;
4602 + uint64_t ovrerr:1;
4603 + uint64_t niberr:1;
4604 + uint64_t skperr:1;
4605 + uint64_t rcverr:1;
4606 + uint64_t lenerr:1;
4607 + uint64_t alnerr:1;
4608 + uint64_t fcserr:1;
4609 + uint64_t jabber:1;
4610 + uint64_t maxerr:1;
4611 + uint64_t carext:1;
4612 + uint64_t minerr:1;
4613 + } s;
4614 + struct cvmx_gmxx_rxx_int_reg_cn30xx {
4615 + uint64_t reserved_19_63:45;
4616 + uint64_t phy_dupx:1;
4617 + uint64_t phy_spd:1;
4618 + uint64_t phy_link:1;
4619 + uint64_t ifgerr:1;
4620 + uint64_t coldet:1;
4621 + uint64_t falerr:1;
4622 + uint64_t rsverr:1;
4623 + uint64_t pcterr:1;
4624 + uint64_t ovrerr:1;
4625 + uint64_t niberr:1;
4626 + uint64_t skperr:1;
4627 + uint64_t rcverr:1;
4628 + uint64_t lenerr:1;
4629 + uint64_t alnerr:1;
4630 + uint64_t fcserr:1;
4631 + uint64_t jabber:1;
4632 + uint64_t maxerr:1;
4633 + uint64_t carext:1;
4634 + uint64_t minerr:1;
4635 + } cn30xx;
4636 + struct cvmx_gmxx_rxx_int_reg_cn30xx cn31xx;
4637 + struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xx;
4638 + struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xxp2;
4639 + struct cvmx_gmxx_rxx_int_reg_cn50xx {
4640 + uint64_t reserved_20_63:44;
4641 + uint64_t pause_drp:1;
4642 + uint64_t phy_dupx:1;
4643 + uint64_t phy_spd:1;
4644 + uint64_t phy_link:1;
4645 + uint64_t ifgerr:1;
4646 + uint64_t coldet:1;
4647 + uint64_t falerr:1;
4648 + uint64_t rsverr:1;
4649 + uint64_t pcterr:1;
4650 + uint64_t ovrerr:1;
4651 + uint64_t niberr:1;
4652 + uint64_t skperr:1;
4653 + uint64_t rcverr:1;
4654 + uint64_t reserved_6_6:1;
4655 + uint64_t alnerr:1;
4656 + uint64_t fcserr:1;
4657 + uint64_t jabber:1;
4658 + uint64_t reserved_2_2:1;
4659 + uint64_t carext:1;
4660 + uint64_t reserved_0_0:1;
4661 + } cn50xx;
4662 + struct cvmx_gmxx_rxx_int_reg_cn52xx {
4663 + uint64_t reserved_29_63:35;
4664 + uint64_t hg2cc:1;
4665 + uint64_t hg2fld:1;
4666 + uint64_t undat:1;
4667 + uint64_t uneop:1;
4668 + uint64_t unsop:1;
4669 + uint64_t bad_term:1;
4670 + uint64_t bad_seq:1;
4671 + uint64_t rem_fault:1;
4672 + uint64_t loc_fault:1;
4673 + uint64_t pause_drp:1;
4674 + uint64_t reserved_16_18:3;
4675 + uint64_t ifgerr:1;
4676 + uint64_t coldet:1;
4677 + uint64_t falerr:1;
4678 + uint64_t rsverr:1;
4679 + uint64_t pcterr:1;
4680 + uint64_t ovrerr:1;
4681 + uint64_t reserved_9_9:1;
4682 + uint64_t skperr:1;
4683 + uint64_t rcverr:1;
4684 + uint64_t reserved_5_6:2;
4685 + uint64_t fcserr:1;
4686 + uint64_t jabber:1;
4687 + uint64_t reserved_2_2:1;
4688 + uint64_t carext:1;
4689 + uint64_t reserved_0_0:1;
4690 + } cn52xx;
4691 + struct cvmx_gmxx_rxx_int_reg_cn52xx cn52xxp1;
4692 + struct cvmx_gmxx_rxx_int_reg_cn52xx cn56xx;
4693 + struct cvmx_gmxx_rxx_int_reg_cn56xxp1 {
4694 + uint64_t reserved_27_63:37;
4695 + uint64_t undat:1;
4696 + uint64_t uneop:1;
4697 + uint64_t unsop:1;
4698 + uint64_t bad_term:1;
4699 + uint64_t bad_seq:1;
4700 + uint64_t rem_fault:1;
4701 + uint64_t loc_fault:1;
4702 + uint64_t pause_drp:1;
4703 + uint64_t reserved_16_18:3;
4704 + uint64_t ifgerr:1;
4705 + uint64_t coldet:1;
4706 + uint64_t falerr:1;
4707 + uint64_t rsverr:1;
4708 + uint64_t pcterr:1;
4709 + uint64_t ovrerr:1;
4710 + uint64_t reserved_9_9:1;
4711 + uint64_t skperr:1;
4712 + uint64_t rcverr:1;
4713 + uint64_t reserved_5_6:2;
4714 + uint64_t fcserr:1;
4715 + uint64_t jabber:1;
4716 + uint64_t reserved_2_2:1;
4717 + uint64_t carext:1;
4718 + uint64_t reserved_0_0:1;
4719 + } cn56xxp1;
4720 + struct cvmx_gmxx_rxx_int_reg_cn58xx {
4721 + uint64_t reserved_20_63:44;
4722 + uint64_t pause_drp:1;
4723 + uint64_t phy_dupx:1;
4724 + uint64_t phy_spd:1;
4725 + uint64_t phy_link:1;
4726 + uint64_t ifgerr:1;
4727 + uint64_t coldet:1;
4728 + uint64_t falerr:1;
4729 + uint64_t rsverr:1;
4730 + uint64_t pcterr:1;
4731 + uint64_t ovrerr:1;
4732 + uint64_t niberr:1;
4733 + uint64_t skperr:1;
4734 + uint64_t rcverr:1;
4735 + uint64_t lenerr:1;
4736 + uint64_t alnerr:1;
4737 + uint64_t fcserr:1;
4738 + uint64_t jabber:1;
4739 + uint64_t maxerr:1;
4740 + uint64_t carext:1;
4741 + uint64_t minerr:1;
4742 + } cn58xx;
4743 + struct cvmx_gmxx_rxx_int_reg_cn58xx cn58xxp1;
4744 +};
4745 +
4746 +union cvmx_gmxx_rxx_jabber {
4747 + uint64_t u64;
4748 + struct cvmx_gmxx_rxx_jabber_s {
4749 + uint64_t reserved_16_63:48;
4750 + uint64_t cnt:16;
4751 + } s;
4752 + struct cvmx_gmxx_rxx_jabber_s cn30xx;
4753 + struct cvmx_gmxx_rxx_jabber_s cn31xx;
4754 + struct cvmx_gmxx_rxx_jabber_s cn38xx;
4755 + struct cvmx_gmxx_rxx_jabber_s cn38xxp2;
4756 + struct cvmx_gmxx_rxx_jabber_s cn50xx;
4757 + struct cvmx_gmxx_rxx_jabber_s cn52xx;
4758 + struct cvmx_gmxx_rxx_jabber_s cn52xxp1;
4759 + struct cvmx_gmxx_rxx_jabber_s cn56xx;
4760 + struct cvmx_gmxx_rxx_jabber_s cn56xxp1;
4761 + struct cvmx_gmxx_rxx_jabber_s cn58xx;
4762 + struct cvmx_gmxx_rxx_jabber_s cn58xxp1;
4763 +};
4764 +
4765 +union cvmx_gmxx_rxx_pause_drop_time {
4766 + uint64_t u64;
4767 + struct cvmx_gmxx_rxx_pause_drop_time_s {
4768 + uint64_t reserved_16_63:48;
4769 + uint64_t status:16;
4770 + } s;
4771 + struct cvmx_gmxx_rxx_pause_drop_time_s cn50xx;
4772 + struct cvmx_gmxx_rxx_pause_drop_time_s cn52xx;
4773 + struct cvmx_gmxx_rxx_pause_drop_time_s cn52xxp1;
4774 + struct cvmx_gmxx_rxx_pause_drop_time_s cn56xx;
4775 + struct cvmx_gmxx_rxx_pause_drop_time_s cn56xxp1;
4776 + struct cvmx_gmxx_rxx_pause_drop_time_s cn58xx;
4777 + struct cvmx_gmxx_rxx_pause_drop_time_s cn58xxp1;
4778 +};
4779 +
4780 +union cvmx_gmxx_rxx_rx_inbnd {
4781 + uint64_t u64;
4782 + struct cvmx_gmxx_rxx_rx_inbnd_s {
4783 + uint64_t reserved_4_63:60;
4784 + uint64_t duplex:1;
4785 + uint64_t speed:2;
4786 + uint64_t status:1;
4787 + } s;
4788 + struct cvmx_gmxx_rxx_rx_inbnd_s cn30xx;
4789 + struct cvmx_gmxx_rxx_rx_inbnd_s cn31xx;
4790 + struct cvmx_gmxx_rxx_rx_inbnd_s cn38xx;
4791 + struct cvmx_gmxx_rxx_rx_inbnd_s cn38xxp2;
4792 + struct cvmx_gmxx_rxx_rx_inbnd_s cn50xx;
4793 + struct cvmx_gmxx_rxx_rx_inbnd_s cn58xx;
4794 + struct cvmx_gmxx_rxx_rx_inbnd_s cn58xxp1;
4795 +};
4796 +
4797 +union cvmx_gmxx_rxx_stats_ctl {
4798 + uint64_t u64;
4799 + struct cvmx_gmxx_rxx_stats_ctl_s {
4800 + uint64_t reserved_1_63:63;
4801 + uint64_t rd_clr:1;
4802 + } s;
4803 + struct cvmx_gmxx_rxx_stats_ctl_s cn30xx;
4804 + struct cvmx_gmxx_rxx_stats_ctl_s cn31xx;
4805 + struct cvmx_gmxx_rxx_stats_ctl_s cn38xx;
4806 + struct cvmx_gmxx_rxx_stats_ctl_s cn38xxp2;
4807 + struct cvmx_gmxx_rxx_stats_ctl_s cn50xx;
4808 + struct cvmx_gmxx_rxx_stats_ctl_s cn52xx;
4809 + struct cvmx_gmxx_rxx_stats_ctl_s cn52xxp1;
4810 + struct cvmx_gmxx_rxx_stats_ctl_s cn56xx;
4811 + struct cvmx_gmxx_rxx_stats_ctl_s cn56xxp1;
4812 + struct cvmx_gmxx_rxx_stats_ctl_s cn58xx;
4813 + struct cvmx_gmxx_rxx_stats_ctl_s cn58xxp1;
4814 +};
4815 +
4816 +union cvmx_gmxx_rxx_stats_octs {
4817 + uint64_t u64;
4818 + struct cvmx_gmxx_rxx_stats_octs_s {
4819 + uint64_t reserved_48_63:16;
4820 + uint64_t cnt:48;
4821 + } s;
4822 + struct cvmx_gmxx_rxx_stats_octs_s cn30xx;
4823 + struct cvmx_gmxx_rxx_stats_octs_s cn31xx;
4824 + struct cvmx_gmxx_rxx_stats_octs_s cn38xx;
4825 + struct cvmx_gmxx_rxx_stats_octs_s cn38xxp2;
4826 + struct cvmx_gmxx_rxx_stats_octs_s cn50xx;
4827 + struct cvmx_gmxx_rxx_stats_octs_s cn52xx;
4828 + struct cvmx_gmxx_rxx_stats_octs_s cn52xxp1;
4829 + struct cvmx_gmxx_rxx_stats_octs_s cn56xx;
4830 + struct cvmx_gmxx_rxx_stats_octs_s cn56xxp1;
4831 + struct cvmx_gmxx_rxx_stats_octs_s cn58xx;
4832 + struct cvmx_gmxx_rxx_stats_octs_s cn58xxp1;
4833 +};
4834 +
4835 +union cvmx_gmxx_rxx_stats_octs_ctl {
4836 + uint64_t u64;
4837 + struct cvmx_gmxx_rxx_stats_octs_ctl_s {
4838 + uint64_t reserved_48_63:16;
4839 + uint64_t cnt:48;
4840 + } s;
4841 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn30xx;
4842 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn31xx;
4843 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xx;
4844 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xxp2;
4845 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn50xx;
4846 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xx;
4847 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xxp1;
4848 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xx;
4849 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xxp1;
4850 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xx;
4851 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xxp1;
4852 +};
4853 +
4854 +union cvmx_gmxx_rxx_stats_octs_dmac {
4855 + uint64_t u64;
4856 + struct cvmx_gmxx_rxx_stats_octs_dmac_s {
4857 + uint64_t reserved_48_63:16;
4858 + uint64_t cnt:48;
4859 + } s;
4860 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn30xx;
4861 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn31xx;
4862 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xx;
4863 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xxp2;
4864 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn50xx;
4865 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xx;
4866 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xxp1;
4867 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xx;
4868 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xxp1;
4869 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xx;
4870 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xxp1;
4871 +};
4872 +
4873 +union cvmx_gmxx_rxx_stats_octs_drp {
4874 + uint64_t u64;
4875 + struct cvmx_gmxx_rxx_stats_octs_drp_s {
4876 + uint64_t reserved_48_63:16;
4877 + uint64_t cnt:48;
4878 + } s;
4879 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn30xx;
4880 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn31xx;
4881 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xx;
4882 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xxp2;
4883 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn50xx;
4884 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xx;
4885 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xxp1;
4886 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xx;
4887 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xxp1;
4888 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xx;
4889 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xxp1;
4890 +};
4891 +
4892 +union cvmx_gmxx_rxx_stats_pkts {
4893 + uint64_t u64;
4894 + struct cvmx_gmxx_rxx_stats_pkts_s {
4895 + uint64_t reserved_32_63:32;
4896 + uint64_t cnt:32;
4897 + } s;
4898 + struct cvmx_gmxx_rxx_stats_pkts_s cn30xx;
4899 + struct cvmx_gmxx_rxx_stats_pkts_s cn31xx;
4900 + struct cvmx_gmxx_rxx_stats_pkts_s cn38xx;
4901 + struct cvmx_gmxx_rxx_stats_pkts_s cn38xxp2;
4902 + struct cvmx_gmxx_rxx_stats_pkts_s cn50xx;
4903 + struct cvmx_gmxx_rxx_stats_pkts_s cn52xx;
4904 + struct cvmx_gmxx_rxx_stats_pkts_s cn52xxp1;
4905 + struct cvmx_gmxx_rxx_stats_pkts_s cn56xx;
4906 + struct cvmx_gmxx_rxx_stats_pkts_s cn56xxp1;
4907 + struct cvmx_gmxx_rxx_stats_pkts_s cn58xx;
4908 + struct cvmx_gmxx_rxx_stats_pkts_s cn58xxp1;
4909 +};
4910 +
4911 +union cvmx_gmxx_rxx_stats_pkts_bad {
4912 + uint64_t u64;
4913 + struct cvmx_gmxx_rxx_stats_pkts_bad_s {
4914 + uint64_t reserved_32_63:32;
4915 + uint64_t cnt:32;
4916 + } s;
4917 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn30xx;
4918 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn31xx;
4919 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xx;
4920 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xxp2;
4921 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn50xx;
4922 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xx;
4923 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xxp1;
4924 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xx;
4925 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xxp1;
4926 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xx;
4927 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xxp1;
4928 +};
4929 +
4930 +union cvmx_gmxx_rxx_stats_pkts_ctl {
4931 + uint64_t u64;
4932 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s {
4933 + uint64_t reserved_32_63:32;
4934 + uint64_t cnt:32;
4935 + } s;
4936 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn30xx;
4937 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn31xx;
4938 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xx;
4939 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xxp2;
4940 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn50xx;
4941 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xx;
4942 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xxp1;
4943 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xx;
4944 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xxp1;
4945 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xx;
4946 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xxp1;
4947 +};
4948 +
4949 +union cvmx_gmxx_rxx_stats_pkts_dmac {
4950 + uint64_t u64;
4951 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s {
4952 + uint64_t reserved_32_63:32;
4953 + uint64_t cnt:32;
4954 + } s;
4955 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn30xx;
4956 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn31xx;
4957 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xx;
4958 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xxp2;
4959 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn50xx;
4960 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xx;
4961 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xxp1;
4962 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xx;
4963 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xxp1;
4964 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xx;
4965 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xxp1;
4966 +};
4967 +
4968 +union cvmx_gmxx_rxx_stats_pkts_drp {
4969 + uint64_t u64;
4970 + struct cvmx_gmxx_rxx_stats_pkts_drp_s {
4971 + uint64_t reserved_32_63:32;
4972 + uint64_t cnt:32;
4973 + } s;
4974 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn30xx;
4975 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn31xx;
4976 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xx;
4977 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xxp2;
4978 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn50xx;
4979 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xx;
4980 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xxp1;
4981 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xx;
4982 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xxp1;
4983 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xx;
4984 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xxp1;
4985 +};
4986 +
4987 +union cvmx_gmxx_rxx_udd_skp {
4988 + uint64_t u64;
4989 + struct cvmx_gmxx_rxx_udd_skp_s {
4990 + uint64_t reserved_9_63:55;
4991 + uint64_t fcssel:1;
4992 + uint64_t reserved_7_7:1;
4993 + uint64_t len:7;
4994 + } s;
4995 + struct cvmx_gmxx_rxx_udd_skp_s cn30xx;
4996 + struct cvmx_gmxx_rxx_udd_skp_s cn31xx;
4997 + struct cvmx_gmxx_rxx_udd_skp_s cn38xx;
4998 + struct cvmx_gmxx_rxx_udd_skp_s cn38xxp2;
4999 + struct cvmx_gmxx_rxx_udd_skp_s cn50xx;
5000 + struct cvmx_gmxx_rxx_udd_skp_s cn52xx;
5001 + struct cvmx_gmxx_rxx_udd_skp_s cn52xxp1;
5002 + struct cvmx_gmxx_rxx_udd_skp_s cn56xx;
5003 + struct cvmx_gmxx_rxx_udd_skp_s cn56xxp1;
5004 + struct cvmx_gmxx_rxx_udd_skp_s cn58xx;
5005 + struct cvmx_gmxx_rxx_udd_skp_s cn58xxp1;
5006 +};
5007 +
5008 +union cvmx_gmxx_rx_bp_dropx {
5009 + uint64_t u64;
5010 + struct cvmx_gmxx_rx_bp_dropx_s {
5011 + uint64_t reserved_6_63:58;
5012 + uint64_t mark:6;
5013 + } s;
5014 + struct cvmx_gmxx_rx_bp_dropx_s cn30xx;
5015 + struct cvmx_gmxx_rx_bp_dropx_s cn31xx;
5016 + struct cvmx_gmxx_rx_bp_dropx_s cn38xx;
5017 + struct cvmx_gmxx_rx_bp_dropx_s cn38xxp2;
5018 + struct cvmx_gmxx_rx_bp_dropx_s cn50xx;
5019 + struct cvmx_gmxx_rx_bp_dropx_s cn52xx;
5020 + struct cvmx_gmxx_rx_bp_dropx_s cn52xxp1;
5021 + struct cvmx_gmxx_rx_bp_dropx_s cn56xx;
5022 + struct cvmx_gmxx_rx_bp_dropx_s cn56xxp1;
5023 + struct cvmx_gmxx_rx_bp_dropx_s cn58xx;
5024 + struct cvmx_gmxx_rx_bp_dropx_s cn58xxp1;
5025 +};
5026 +
5027 +union cvmx_gmxx_rx_bp_offx {
5028 + uint64_t u64;
5029 + struct cvmx_gmxx_rx_bp_offx_s {
5030 + uint64_t reserved_6_63:58;
5031 + uint64_t mark:6;
5032 + } s;
5033 + struct cvmx_gmxx_rx_bp_offx_s cn30xx;
5034 + struct cvmx_gmxx_rx_bp_offx_s cn31xx;
5035 + struct cvmx_gmxx_rx_bp_offx_s cn38xx;
5036 + struct cvmx_gmxx_rx_bp_offx_s cn38xxp2;
5037 + struct cvmx_gmxx_rx_bp_offx_s cn50xx;
5038 + struct cvmx_gmxx_rx_bp_offx_s cn52xx;
5039 + struct cvmx_gmxx_rx_bp_offx_s cn52xxp1;
5040 + struct cvmx_gmxx_rx_bp_offx_s cn56xx;
5041 + struct cvmx_gmxx_rx_bp_offx_s cn56xxp1;
5042 + struct cvmx_gmxx_rx_bp_offx_s cn58xx;
5043 + struct cvmx_gmxx_rx_bp_offx_s cn58xxp1;
5044 +};
5045 +
5046 +union cvmx_gmxx_rx_bp_onx {
5047 + uint64_t u64;
5048 + struct cvmx_gmxx_rx_bp_onx_s {
5049 + uint64_t reserved_9_63:55;
5050 + uint64_t mark:9;
5051 + } s;
5052 + struct cvmx_gmxx_rx_bp_onx_s cn30xx;
5053 + struct cvmx_gmxx_rx_bp_onx_s cn31xx;
5054 + struct cvmx_gmxx_rx_bp_onx_s cn38xx;
5055 + struct cvmx_gmxx_rx_bp_onx_s cn38xxp2;
5056 + struct cvmx_gmxx_rx_bp_onx_s cn50xx;
5057 + struct cvmx_gmxx_rx_bp_onx_s cn52xx;
5058 + struct cvmx_gmxx_rx_bp_onx_s cn52xxp1;
5059 + struct cvmx_gmxx_rx_bp_onx_s cn56xx;
5060 + struct cvmx_gmxx_rx_bp_onx_s cn56xxp1;
5061 + struct cvmx_gmxx_rx_bp_onx_s cn58xx;
5062 + struct cvmx_gmxx_rx_bp_onx_s cn58xxp1;
5063 +};
5064 +
5065 +union cvmx_gmxx_rx_hg2_status {
5066 + uint64_t u64;
5067 + struct cvmx_gmxx_rx_hg2_status_s {
5068 + uint64_t reserved_48_63:16;
5069 + uint64_t phtim2go:16;
5070 + uint64_t xof:16;
5071 + uint64_t lgtim2go:16;
5072 + } s;
5073 + struct cvmx_gmxx_rx_hg2_status_s cn52xx;
5074 + struct cvmx_gmxx_rx_hg2_status_s cn52xxp1;
5075 + struct cvmx_gmxx_rx_hg2_status_s cn56xx;
5076 +};
5077 +
5078 +union cvmx_gmxx_rx_pass_en {
5079 + uint64_t u64;
5080 + struct cvmx_gmxx_rx_pass_en_s {
5081 + uint64_t reserved_16_63:48;
5082 + uint64_t en:16;
5083 + } s;
5084 + struct cvmx_gmxx_rx_pass_en_s cn38xx;
5085 + struct cvmx_gmxx_rx_pass_en_s cn38xxp2;
5086 + struct cvmx_gmxx_rx_pass_en_s cn58xx;
5087 + struct cvmx_gmxx_rx_pass_en_s cn58xxp1;
5088 +};
5089 +
5090 +union cvmx_gmxx_rx_pass_mapx {
5091 + uint64_t u64;
5092 + struct cvmx_gmxx_rx_pass_mapx_s {
5093 + uint64_t reserved_4_63:60;
5094 + uint64_t dprt:4;
5095 + } s;
5096 + struct cvmx_gmxx_rx_pass_mapx_s cn38xx;
5097 + struct cvmx_gmxx_rx_pass_mapx_s cn38xxp2;
5098 + struct cvmx_gmxx_rx_pass_mapx_s cn58xx;
5099 + struct cvmx_gmxx_rx_pass_mapx_s cn58xxp1;
5100 +};
5101 +
5102 +union cvmx_gmxx_rx_prt_info {
5103 + uint64_t u64;
5104 + struct cvmx_gmxx_rx_prt_info_s {
5105 + uint64_t reserved_32_63:32;
5106 + uint64_t drop:16;
5107 + uint64_t commit:16;
5108 + } s;
5109 + struct cvmx_gmxx_rx_prt_info_cn30xx {
5110 + uint64_t reserved_19_63:45;
5111 + uint64_t drop:3;
5112 + uint64_t reserved_3_15:13;
5113 + uint64_t commit:3;
5114 + } cn30xx;
5115 + struct cvmx_gmxx_rx_prt_info_cn30xx cn31xx;
5116 + struct cvmx_gmxx_rx_prt_info_s cn38xx;
5117 + struct cvmx_gmxx_rx_prt_info_cn30xx cn50xx;
5118 + struct cvmx_gmxx_rx_prt_info_cn52xx {
5119 + uint64_t reserved_20_63:44;
5120 + uint64_t drop:4;
5121 + uint64_t reserved_4_15:12;
5122 + uint64_t commit:4;
5123 + } cn52xx;
5124 + struct cvmx_gmxx_rx_prt_info_cn52xx cn52xxp1;
5125 + struct cvmx_gmxx_rx_prt_info_cn52xx cn56xx;
5126 + struct cvmx_gmxx_rx_prt_info_cn52xx cn56xxp1;
5127 + struct cvmx_gmxx_rx_prt_info_s cn58xx;
5128 + struct cvmx_gmxx_rx_prt_info_s cn58xxp1;
5129 +};
5130 +
5131 +union cvmx_gmxx_rx_prts {
5132 + uint64_t u64;
5133 + struct cvmx_gmxx_rx_prts_s {
5134 + uint64_t reserved_3_63:61;
5135 + uint64_t prts:3;
5136 + } s;
5137 + struct cvmx_gmxx_rx_prts_s cn30xx;
5138 + struct cvmx_gmxx_rx_prts_s cn31xx;
5139 + struct cvmx_gmxx_rx_prts_s cn38xx;
5140 + struct cvmx_gmxx_rx_prts_s cn38xxp2;
5141 + struct cvmx_gmxx_rx_prts_s cn50xx;
5142 + struct cvmx_gmxx_rx_prts_s cn52xx;
5143 + struct cvmx_gmxx_rx_prts_s cn52xxp1;
5144 + struct cvmx_gmxx_rx_prts_s cn56xx;
5145 + struct cvmx_gmxx_rx_prts_s cn56xxp1;
5146 + struct cvmx_gmxx_rx_prts_s cn58xx;
5147 + struct cvmx_gmxx_rx_prts_s cn58xxp1;
5148 +};
5149 +
5150 +union cvmx_gmxx_rx_tx_status {
5151 + uint64_t u64;
5152 + struct cvmx_gmxx_rx_tx_status_s {
5153 + uint64_t reserved_7_63:57;
5154 + uint64_t tx:3;
5155 + uint64_t reserved_3_3:1;
5156 + uint64_t rx:3;
5157 + } s;
5158 + struct cvmx_gmxx_rx_tx_status_s cn30xx;
5159 + struct cvmx_gmxx_rx_tx_status_s cn31xx;
5160 + struct cvmx_gmxx_rx_tx_status_s cn50xx;
5161 +};
5162 +
5163 +union cvmx_gmxx_rx_xaui_bad_col {
5164 + uint64_t u64;
5165 + struct cvmx_gmxx_rx_xaui_bad_col_s {
5166 + uint64_t reserved_40_63:24;
5167 + uint64_t val:1;
5168 + uint64_t state:3;
5169 + uint64_t lane_rxc:4;
5170 + uint64_t lane_rxd:32;
5171 + } s;
5172 + struct cvmx_gmxx_rx_xaui_bad_col_s cn52xx;
5173 + struct cvmx_gmxx_rx_xaui_bad_col_s cn52xxp1;
5174 + struct cvmx_gmxx_rx_xaui_bad_col_s cn56xx;
5175 + struct cvmx_gmxx_rx_xaui_bad_col_s cn56xxp1;
5176 +};
5177 +
5178 +union cvmx_gmxx_rx_xaui_ctl {
5179 + uint64_t u64;
5180 + struct cvmx_gmxx_rx_xaui_ctl_s {
5181 + uint64_t reserved_2_63:62;
5182 + uint64_t status:2;
5183 + } s;
5184 + struct cvmx_gmxx_rx_xaui_ctl_s cn52xx;
5185 + struct cvmx_gmxx_rx_xaui_ctl_s cn52xxp1;
5186 + struct cvmx_gmxx_rx_xaui_ctl_s cn56xx;
5187 + struct cvmx_gmxx_rx_xaui_ctl_s cn56xxp1;
5188 +};
5189 +
5190 +union cvmx_gmxx_smacx {
5191 + uint64_t u64;
5192 + struct cvmx_gmxx_smacx_s {
5193 + uint64_t reserved_48_63:16;
5194 + uint64_t smac:48;
5195 + } s;
5196 + struct cvmx_gmxx_smacx_s cn30xx;
5197 + struct cvmx_gmxx_smacx_s cn31xx;
5198 + struct cvmx_gmxx_smacx_s cn38xx;
5199 + struct cvmx_gmxx_smacx_s cn38xxp2;
5200 + struct cvmx_gmxx_smacx_s cn50xx;
5201 + struct cvmx_gmxx_smacx_s cn52xx;
5202 + struct cvmx_gmxx_smacx_s cn52xxp1;
5203 + struct cvmx_gmxx_smacx_s cn56xx;
5204 + struct cvmx_gmxx_smacx_s cn56xxp1;
5205 + struct cvmx_gmxx_smacx_s cn58xx;
5206 + struct cvmx_gmxx_smacx_s cn58xxp1;
5207 +};
5208 +
5209 +union cvmx_gmxx_stat_bp {
5210 + uint64_t u64;
5211 + struct cvmx_gmxx_stat_bp_s {
5212 + uint64_t reserved_17_63:47;
5213 + uint64_t bp:1;
5214 + uint64_t cnt:16;
5215 + } s;
5216 + struct cvmx_gmxx_stat_bp_s cn30xx;
5217 + struct cvmx_gmxx_stat_bp_s cn31xx;
5218 + struct cvmx_gmxx_stat_bp_s cn38xx;
5219 + struct cvmx_gmxx_stat_bp_s cn38xxp2;
5220 + struct cvmx_gmxx_stat_bp_s cn50xx;
5221 + struct cvmx_gmxx_stat_bp_s cn52xx;
5222 + struct cvmx_gmxx_stat_bp_s cn52xxp1;
5223 + struct cvmx_gmxx_stat_bp_s cn56xx;
5224 + struct cvmx_gmxx_stat_bp_s cn56xxp1;
5225 + struct cvmx_gmxx_stat_bp_s cn58xx;
5226 + struct cvmx_gmxx_stat_bp_s cn58xxp1;
5227 +};
5228 +
5229 +union cvmx_gmxx_txx_append {
5230 + uint64_t u64;
5231 + struct cvmx_gmxx_txx_append_s {
5232 + uint64_t reserved_4_63:60;
5233 + uint64_t force_fcs:1;
5234 + uint64_t fcs:1;
5235 + uint64_t pad:1;
5236 + uint64_t preamble:1;
5237 + } s;
5238 + struct cvmx_gmxx_txx_append_s cn30xx;
5239 + struct cvmx_gmxx_txx_append_s cn31xx;
5240 + struct cvmx_gmxx_txx_append_s cn38xx;
5241 + struct cvmx_gmxx_txx_append_s cn38xxp2;
5242 + struct cvmx_gmxx_txx_append_s cn50xx;
5243 + struct cvmx_gmxx_txx_append_s cn52xx;
5244 + struct cvmx_gmxx_txx_append_s cn52xxp1;
5245 + struct cvmx_gmxx_txx_append_s cn56xx;
5246 + struct cvmx_gmxx_txx_append_s cn56xxp1;
5247 + struct cvmx_gmxx_txx_append_s cn58xx;
5248 + struct cvmx_gmxx_txx_append_s cn58xxp1;
5249 +};
5250 +
5251 +union cvmx_gmxx_txx_burst {
5252 + uint64_t u64;
5253 + struct cvmx_gmxx_txx_burst_s {
5254 + uint64_t reserved_16_63:48;
5255 + uint64_t burst:16;
5256 + } s;
5257 + struct cvmx_gmxx_txx_burst_s cn30xx;
5258 + struct cvmx_gmxx_txx_burst_s cn31xx;
5259 + struct cvmx_gmxx_txx_burst_s cn38xx;
5260 + struct cvmx_gmxx_txx_burst_s cn38xxp2;
5261 + struct cvmx_gmxx_txx_burst_s cn50xx;
5262 + struct cvmx_gmxx_txx_burst_s cn52xx;
5263 + struct cvmx_gmxx_txx_burst_s cn52xxp1;
5264 + struct cvmx_gmxx_txx_burst_s cn56xx;
5265 + struct cvmx_gmxx_txx_burst_s cn56xxp1;
5266 + struct cvmx_gmxx_txx_burst_s cn58xx;
5267 + struct cvmx_gmxx_txx_burst_s cn58xxp1;
5268 +};
5269 +
5270 +union cvmx_gmxx_txx_cbfc_xoff {
5271 + uint64_t u64;
5272 + struct cvmx_gmxx_txx_cbfc_xoff_s {
5273 + uint64_t reserved_16_63:48;
5274 + uint64_t xoff:16;
5275 + } s;
5276 + struct cvmx_gmxx_txx_cbfc_xoff_s cn52xx;
5277 + struct cvmx_gmxx_txx_cbfc_xoff_s cn56xx;
5278 +};
5279 +
5280 +union cvmx_gmxx_txx_cbfc_xon {
5281 + uint64_t u64;
5282 + struct cvmx_gmxx_txx_cbfc_xon_s {
5283 + uint64_t reserved_16_63:48;
5284 + uint64_t xon:16;
5285 + } s;
5286 + struct cvmx_gmxx_txx_cbfc_xon_s cn52xx;
5287 + struct cvmx_gmxx_txx_cbfc_xon_s cn56xx;
5288 +};
5289 +
5290 +union cvmx_gmxx_txx_clk {
5291 + uint64_t u64;
5292 + struct cvmx_gmxx_txx_clk_s {
5293 + uint64_t reserved_6_63:58;
5294 + uint64_t clk_cnt:6;
5295 + } s;
5296 + struct cvmx_gmxx_txx_clk_s cn30xx;
5297 + struct cvmx_gmxx_txx_clk_s cn31xx;
5298 + struct cvmx_gmxx_txx_clk_s cn38xx;
5299 + struct cvmx_gmxx_txx_clk_s cn38xxp2;
5300 + struct cvmx_gmxx_txx_clk_s cn50xx;
5301 + struct cvmx_gmxx_txx_clk_s cn58xx;
5302 + struct cvmx_gmxx_txx_clk_s cn58xxp1;
5303 +};
5304 +
5305 +union cvmx_gmxx_txx_ctl {
5306 + uint64_t u64;
5307 + struct cvmx_gmxx_txx_ctl_s {
5308 + uint64_t reserved_2_63:62;
5309 + uint64_t xsdef_en:1;
5310 + uint64_t xscol_en:1;
5311 + } s;
5312 + struct cvmx_gmxx_txx_ctl_s cn30xx;
5313 + struct cvmx_gmxx_txx_ctl_s cn31xx;
5314 + struct cvmx_gmxx_txx_ctl_s cn38xx;
5315 + struct cvmx_gmxx_txx_ctl_s cn38xxp2;
5316 + struct cvmx_gmxx_txx_ctl_s cn50xx;
5317 + struct cvmx_gmxx_txx_ctl_s cn52xx;
5318 + struct cvmx_gmxx_txx_ctl_s cn52xxp1;
5319 + struct cvmx_gmxx_txx_ctl_s cn56xx;
5320 + struct cvmx_gmxx_txx_ctl_s cn56xxp1;
5321 + struct cvmx_gmxx_txx_ctl_s cn58xx;
5322 + struct cvmx_gmxx_txx_ctl_s cn58xxp1;
5323 +};
5324 +
5325 +union cvmx_gmxx_txx_min_pkt {
5326 + uint64_t u64;
5327 + struct cvmx_gmxx_txx_min_pkt_s {
5328 + uint64_t reserved_8_63:56;
5329 + uint64_t min_size:8;
5330 + } s;
5331 + struct cvmx_gmxx_txx_min_pkt_s cn30xx;
5332 + struct cvmx_gmxx_txx_min_pkt_s cn31xx;
5333 + struct cvmx_gmxx_txx_min_pkt_s cn38xx;
5334 + struct cvmx_gmxx_txx_min_pkt_s cn38xxp2;
5335 + struct cvmx_gmxx_txx_min_pkt_s cn50xx;
5336 + struct cvmx_gmxx_txx_min_pkt_s cn52xx;
5337 + struct cvmx_gmxx_txx_min_pkt_s cn52xxp1;
5338 + struct cvmx_gmxx_txx_min_pkt_s cn56xx;
5339 + struct cvmx_gmxx_txx_min_pkt_s cn56xxp1;
5340 + struct cvmx_gmxx_txx_min_pkt_s cn58xx;
5341 + struct cvmx_gmxx_txx_min_pkt_s cn58xxp1;
5342 +};
5343 +
5344 +union cvmx_gmxx_txx_pause_pkt_interval {
5345 + uint64_t u64;
5346 + struct cvmx_gmxx_txx_pause_pkt_interval_s {
5347 + uint64_t reserved_16_63:48;
5348 + uint64_t interval:16;
5349 + } s;
5350 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn30xx;
5351 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn31xx;
5352 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xx;
5353 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xxp2;
5354 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn50xx;
5355 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xx;
5356 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xxp1;
5357 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xx;
5358 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xxp1;
5359 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xx;
5360 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xxp1;
5361 +};
5362 +
5363 +union cvmx_gmxx_txx_pause_pkt_time {
5364 + uint64_t u64;
5365 + struct cvmx_gmxx_txx_pause_pkt_time_s {
5366 + uint64_t reserved_16_63:48;
5367 + uint64_t time:16;
5368 + } s;
5369 + struct cvmx_gmxx_txx_pause_pkt_time_s cn30xx;
5370 + struct cvmx_gmxx_txx_pause_pkt_time_s cn31xx;
5371 + struct cvmx_gmxx_txx_pause_pkt_time_s cn38xx;
5372 + struct cvmx_gmxx_txx_pause_pkt_time_s cn38xxp2;
5373 + struct cvmx_gmxx_txx_pause_pkt_time_s cn50xx;
5374 + struct cvmx_gmxx_txx_pause_pkt_time_s cn52xx;
5375 + struct cvmx_gmxx_txx_pause_pkt_time_s cn52xxp1;
5376 + struct cvmx_gmxx_txx_pause_pkt_time_s cn56xx;
5377 + struct cvmx_gmxx_txx_pause_pkt_time_s cn56xxp1;
5378 + struct cvmx_gmxx_txx_pause_pkt_time_s cn58xx;
5379 + struct cvmx_gmxx_txx_pause_pkt_time_s cn58xxp1;
5380 +};
5381 +
5382 +union cvmx_gmxx_txx_pause_togo {
5383 + uint64_t u64;
5384 + struct cvmx_gmxx_txx_pause_togo_s {
5385 + uint64_t reserved_32_63:32;
5386 + uint64_t msg_time:16;
5387 + uint64_t time:16;
5388 + } s;
5389 + struct cvmx_gmxx_txx_pause_togo_cn30xx {
5390 + uint64_t reserved_16_63:48;
5391 + uint64_t time:16;
5392 + } cn30xx;
5393 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn31xx;
5394 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xx;
5395 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xxp2;
5396 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn50xx;
5397 + struct cvmx_gmxx_txx_pause_togo_s cn52xx;
5398 + struct cvmx_gmxx_txx_pause_togo_s cn52xxp1;
5399 + struct cvmx_gmxx_txx_pause_togo_s cn56xx;
5400 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn56xxp1;
5401 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xx;
5402 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xxp1;
5403 +};
5404 +
5405 +union cvmx_gmxx_txx_pause_zero {
5406 + uint64_t u64;
5407 + struct cvmx_gmxx_txx_pause_zero_s {
5408 + uint64_t reserved_1_63:63;
5409 + uint64_t send:1;
5410 + } s;
5411 + struct cvmx_gmxx_txx_pause_zero_s cn30xx;
5412 + struct cvmx_gmxx_txx_pause_zero_s cn31xx;
5413 + struct cvmx_gmxx_txx_pause_zero_s cn38xx;
5414 + struct cvmx_gmxx_txx_pause_zero_s cn38xxp2;
5415 + struct cvmx_gmxx_txx_pause_zero_s cn50xx;
5416 + struct cvmx_gmxx_txx_pause_zero_s cn52xx;
5417 + struct cvmx_gmxx_txx_pause_zero_s cn52xxp1;
5418 + struct cvmx_gmxx_txx_pause_zero_s cn56xx;
5419 + struct cvmx_gmxx_txx_pause_zero_s cn56xxp1;
5420 + struct cvmx_gmxx_txx_pause_zero_s cn58xx;
5421 + struct cvmx_gmxx_txx_pause_zero_s cn58xxp1;
5422 +};
5423 +
5424 +union cvmx_gmxx_txx_sgmii_ctl {
5425 + uint64_t u64;
5426 + struct cvmx_gmxx_txx_sgmii_ctl_s {
5427 + uint64_t reserved_1_63:63;
5428 + uint64_t align:1;
5429 + } s;
5430 + struct cvmx_gmxx_txx_sgmii_ctl_s cn52xx;
5431 + struct cvmx_gmxx_txx_sgmii_ctl_s cn52xxp1;
5432 + struct cvmx_gmxx_txx_sgmii_ctl_s cn56xx;
5433 + struct cvmx_gmxx_txx_sgmii_ctl_s cn56xxp1;
5434 +};
5435 +
5436 +union cvmx_gmxx_txx_slot {
5437 + uint64_t u64;
5438 + struct cvmx_gmxx_txx_slot_s {
5439 + uint64_t reserved_10_63:54;
5440 + uint64_t slot:10;
5441 + } s;
5442 + struct cvmx_gmxx_txx_slot_s cn30xx;
5443 + struct cvmx_gmxx_txx_slot_s cn31xx;
5444 + struct cvmx_gmxx_txx_slot_s cn38xx;
5445 + struct cvmx_gmxx_txx_slot_s cn38xxp2;
5446 + struct cvmx_gmxx_txx_slot_s cn50xx;
5447 + struct cvmx_gmxx_txx_slot_s cn52xx;
5448 + struct cvmx_gmxx_txx_slot_s cn52xxp1;
5449 + struct cvmx_gmxx_txx_slot_s cn56xx;
5450 + struct cvmx_gmxx_txx_slot_s cn56xxp1;
5451 + struct cvmx_gmxx_txx_slot_s cn58xx;
5452 + struct cvmx_gmxx_txx_slot_s cn58xxp1;
5453 +};
5454 +
5455 +union cvmx_gmxx_txx_soft_pause {
5456 + uint64_t u64;
5457 + struct cvmx_gmxx_txx_soft_pause_s {
5458 + uint64_t reserved_16_63:48;
5459 + uint64_t time:16;
5460 + } s;
5461 + struct cvmx_gmxx_txx_soft_pause_s cn30xx;
5462 + struct cvmx_gmxx_txx_soft_pause_s cn31xx;
5463 + struct cvmx_gmxx_txx_soft_pause_s cn38xx;
5464 + struct cvmx_gmxx_txx_soft_pause_s cn38xxp2;
5465 + struct cvmx_gmxx_txx_soft_pause_s cn50xx;
5466 + struct cvmx_gmxx_txx_soft_pause_s cn52xx;
5467 + struct cvmx_gmxx_txx_soft_pause_s cn52xxp1;
5468 + struct cvmx_gmxx_txx_soft_pause_s cn56xx;
5469 + struct cvmx_gmxx_txx_soft_pause_s cn56xxp1;
5470 + struct cvmx_gmxx_txx_soft_pause_s cn58xx;
5471 + struct cvmx_gmxx_txx_soft_pause_s cn58xxp1;
5472 +};
5473 +
5474 +union cvmx_gmxx_txx_stat0 {
5475 + uint64_t u64;
5476 + struct cvmx_gmxx_txx_stat0_s {
5477 + uint64_t xsdef:32;
5478 + uint64_t xscol:32;
5479 + } s;
5480 + struct cvmx_gmxx_txx_stat0_s cn30xx;
5481 + struct cvmx_gmxx_txx_stat0_s cn31xx;
5482 + struct cvmx_gmxx_txx_stat0_s cn38xx;
5483 + struct cvmx_gmxx_txx_stat0_s cn38xxp2;
5484 + struct cvmx_gmxx_txx_stat0_s cn50xx;
5485 + struct cvmx_gmxx_txx_stat0_s cn52xx;
5486 + struct cvmx_gmxx_txx_stat0_s cn52xxp1;
5487 + struct cvmx_gmxx_txx_stat0_s cn56xx;
5488 + struct cvmx_gmxx_txx_stat0_s cn56xxp1;
5489 + struct cvmx_gmxx_txx_stat0_s cn58xx;
5490 + struct cvmx_gmxx_txx_stat0_s cn58xxp1;
5491 +};
5492 +
5493 +union cvmx_gmxx_txx_stat1 {
5494 + uint64_t u64;
5495 + struct cvmx_gmxx_txx_stat1_s {
5496 + uint64_t scol:32;
5497 + uint64_t mcol:32;
5498 + } s;
5499 + struct cvmx_gmxx_txx_stat1_s cn30xx;
5500 + struct cvmx_gmxx_txx_stat1_s cn31xx;
5501 + struct cvmx_gmxx_txx_stat1_s cn38xx;
5502 + struct cvmx_gmxx_txx_stat1_s cn38xxp2;
5503 + struct cvmx_gmxx_txx_stat1_s cn50xx;
5504 + struct cvmx_gmxx_txx_stat1_s cn52xx;
5505 + struct cvmx_gmxx_txx_stat1_s cn52xxp1;
5506 + struct cvmx_gmxx_txx_stat1_s cn56xx;
5507 + struct cvmx_gmxx_txx_stat1_s cn56xxp1;
5508 + struct cvmx_gmxx_txx_stat1_s cn58xx;
5509 + struct cvmx_gmxx_txx_stat1_s cn58xxp1;
5510 +};
5511 +
5512 +union cvmx_gmxx_txx_stat2 {
5513 + uint64_t u64;
5514 + struct cvmx_gmxx_txx_stat2_s {
5515 + uint64_t reserved_48_63:16;
5516 + uint64_t octs:48;
5517 + } s;
5518 + struct cvmx_gmxx_txx_stat2_s cn30xx;
5519 + struct cvmx_gmxx_txx_stat2_s cn31xx;
5520 + struct cvmx_gmxx_txx_stat2_s cn38xx;
5521 + struct cvmx_gmxx_txx_stat2_s cn38xxp2;
5522 + struct cvmx_gmxx_txx_stat2_s cn50xx;
5523 + struct cvmx_gmxx_txx_stat2_s cn52xx;
5524 + struct cvmx_gmxx_txx_stat2_s cn52xxp1;
5525 + struct cvmx_gmxx_txx_stat2_s cn56xx;
5526 + struct cvmx_gmxx_txx_stat2_s cn56xxp1;
5527 + struct cvmx_gmxx_txx_stat2_s cn58xx;
5528 + struct cvmx_gmxx_txx_stat2_s cn58xxp1;
5529 +};
5530 +
5531 +union cvmx_gmxx_txx_stat3 {
5532 + uint64_t u64;
5533 + struct cvmx_gmxx_txx_stat3_s {
5534 + uint64_t reserved_32_63:32;
5535 + uint64_t pkts:32;
5536 + } s;
5537 + struct cvmx_gmxx_txx_stat3_s cn30xx;
5538 + struct cvmx_gmxx_txx_stat3_s cn31xx;
5539 + struct cvmx_gmxx_txx_stat3_s cn38xx;
5540 + struct cvmx_gmxx_txx_stat3_s cn38xxp2;
5541 + struct cvmx_gmxx_txx_stat3_s cn50xx;
5542 + struct cvmx_gmxx_txx_stat3_s cn52xx;
5543 + struct cvmx_gmxx_txx_stat3_s cn52xxp1;
5544 + struct cvmx_gmxx_txx_stat3_s cn56xx;
5545 + struct cvmx_gmxx_txx_stat3_s cn56xxp1;
5546 + struct cvmx_gmxx_txx_stat3_s cn58xx;
5547 + struct cvmx_gmxx_txx_stat3_s cn58xxp1;
5548 +};
5549 +
5550 +union cvmx_gmxx_txx_stat4 {
5551 + uint64_t u64;
5552 + struct cvmx_gmxx_txx_stat4_s {
5553 + uint64_t hist1:32;
5554 + uint64_t hist0:32;
5555 + } s;
5556 + struct cvmx_gmxx_txx_stat4_s cn30xx;
5557 + struct cvmx_gmxx_txx_stat4_s cn31xx;
5558 + struct cvmx_gmxx_txx_stat4_s cn38xx;
5559 + struct cvmx_gmxx_txx_stat4_s cn38xxp2;
5560 + struct cvmx_gmxx_txx_stat4_s cn50xx;
5561 + struct cvmx_gmxx_txx_stat4_s cn52xx;
5562 + struct cvmx_gmxx_txx_stat4_s cn52xxp1;
5563 + struct cvmx_gmxx_txx_stat4_s cn56xx;
5564 + struct cvmx_gmxx_txx_stat4_s cn56xxp1;
5565 + struct cvmx_gmxx_txx_stat4_s cn58xx;
5566 + struct cvmx_gmxx_txx_stat4_s cn58xxp1;
5567 +};
5568 +
5569 +union cvmx_gmxx_txx_stat5 {
5570 + uint64_t u64;
5571 + struct cvmx_gmxx_txx_stat5_s {
5572 + uint64_t hist3:32;
5573 + uint64_t hist2:32;
5574 + } s;
5575 + struct cvmx_gmxx_txx_stat5_s cn30xx;
5576 + struct cvmx_gmxx_txx_stat5_s cn31xx;
5577 + struct cvmx_gmxx_txx_stat5_s cn38xx;
5578 + struct cvmx_gmxx_txx_stat5_s cn38xxp2;
5579 + struct cvmx_gmxx_txx_stat5_s cn50xx;
5580 + struct cvmx_gmxx_txx_stat5_s cn52xx;
5581 + struct cvmx_gmxx_txx_stat5_s cn52xxp1;
5582 + struct cvmx_gmxx_txx_stat5_s cn56xx;
5583 + struct cvmx_gmxx_txx_stat5_s cn56xxp1;
5584 + struct cvmx_gmxx_txx_stat5_s cn58xx;
5585 + struct cvmx_gmxx_txx_stat5_s cn58xxp1;
5586 +};
5587 +
5588 +union cvmx_gmxx_txx_stat6 {
5589 + uint64_t u64;
5590 + struct cvmx_gmxx_txx_stat6_s {
5591 + uint64_t hist5:32;
5592 + uint64_t hist4:32;
5593 + } s;
5594 + struct cvmx_gmxx_txx_stat6_s cn30xx;
5595 + struct cvmx_gmxx_txx_stat6_s cn31xx;
5596 + struct cvmx_gmxx_txx_stat6_s cn38xx;
5597 + struct cvmx_gmxx_txx_stat6_s cn38xxp2;
5598 + struct cvmx_gmxx_txx_stat6_s cn50xx;
5599 + struct cvmx_gmxx_txx_stat6_s cn52xx;
5600 + struct cvmx_gmxx_txx_stat6_s cn52xxp1;
5601 + struct cvmx_gmxx_txx_stat6_s cn56xx;
5602 + struct cvmx_gmxx_txx_stat6_s cn56xxp1;
5603 + struct cvmx_gmxx_txx_stat6_s cn58xx;
5604 + struct cvmx_gmxx_txx_stat6_s cn58xxp1;
5605 +};
5606 +
5607 +union cvmx_gmxx_txx_stat7 {
5608 + uint64_t u64;
5609 + struct cvmx_gmxx_txx_stat7_s {
5610 + uint64_t hist7:32;
5611 + uint64_t hist6:32;
5612 + } s;
5613 + struct cvmx_gmxx_txx_stat7_s cn30xx;
5614 + struct cvmx_gmxx_txx_stat7_s cn31xx;
5615 + struct cvmx_gmxx_txx_stat7_s cn38xx;
5616 + struct cvmx_gmxx_txx_stat7_s cn38xxp2;
5617 + struct cvmx_gmxx_txx_stat7_s cn50xx;
5618 + struct cvmx_gmxx_txx_stat7_s cn52xx;
5619 + struct cvmx_gmxx_txx_stat7_s cn52xxp1;
5620 + struct cvmx_gmxx_txx_stat7_s cn56xx;
5621 + struct cvmx_gmxx_txx_stat7_s cn56xxp1;
5622 + struct cvmx_gmxx_txx_stat7_s cn58xx;
5623 + struct cvmx_gmxx_txx_stat7_s cn58xxp1;
5624 +};
5625 +
5626 +union cvmx_gmxx_txx_stat8 {
5627 + uint64_t u64;
5628 + struct cvmx_gmxx_txx_stat8_s {
5629 + uint64_t mcst:32;
5630 + uint64_t bcst:32;
5631 + } s;
5632 + struct cvmx_gmxx_txx_stat8_s cn30xx;
5633 + struct cvmx_gmxx_txx_stat8_s cn31xx;
5634 + struct cvmx_gmxx_txx_stat8_s cn38xx;
5635 + struct cvmx_gmxx_txx_stat8_s cn38xxp2;
5636 + struct cvmx_gmxx_txx_stat8_s cn50xx;
5637 + struct cvmx_gmxx_txx_stat8_s cn52xx;
5638 + struct cvmx_gmxx_txx_stat8_s cn52xxp1;
5639 + struct cvmx_gmxx_txx_stat8_s cn56xx;
5640 + struct cvmx_gmxx_txx_stat8_s cn56xxp1;
5641 + struct cvmx_gmxx_txx_stat8_s cn58xx;
5642 + struct cvmx_gmxx_txx_stat8_s cn58xxp1;
5643 +};
5644 +
5645 +union cvmx_gmxx_txx_stat9 {
5646 + uint64_t u64;
5647 + struct cvmx_gmxx_txx_stat9_s {
5648 + uint64_t undflw:32;
5649 + uint64_t ctl:32;
5650 + } s;
5651 + struct cvmx_gmxx_txx_stat9_s cn30xx;
5652 + struct cvmx_gmxx_txx_stat9_s cn31xx;
5653 + struct cvmx_gmxx_txx_stat9_s cn38xx;
5654 + struct cvmx_gmxx_txx_stat9_s cn38xxp2;
5655 + struct cvmx_gmxx_txx_stat9_s cn50xx;
5656 + struct cvmx_gmxx_txx_stat9_s cn52xx;
5657 + struct cvmx_gmxx_txx_stat9_s cn52xxp1;
5658 + struct cvmx_gmxx_txx_stat9_s cn56xx;
5659 + struct cvmx_gmxx_txx_stat9_s cn56xxp1;
5660 + struct cvmx_gmxx_txx_stat9_s cn58xx;
5661 + struct cvmx_gmxx_txx_stat9_s cn58xxp1;
5662 +};
5663 +
5664 +union cvmx_gmxx_txx_stats_ctl {
5665 + uint64_t u64;
5666 + struct cvmx_gmxx_txx_stats_ctl_s {
5667 + uint64_t reserved_1_63:63;
5668 + uint64_t rd_clr:1;
5669 + } s;
5670 + struct cvmx_gmxx_txx_stats_ctl_s cn30xx;
5671 + struct cvmx_gmxx_txx_stats_ctl_s cn31xx;
5672 + struct cvmx_gmxx_txx_stats_ctl_s cn38xx;
5673 + struct cvmx_gmxx_txx_stats_ctl_s cn38xxp2;
5674 + struct cvmx_gmxx_txx_stats_ctl_s cn50xx;
5675 + struct cvmx_gmxx_txx_stats_ctl_s cn52xx;
5676 + struct cvmx_gmxx_txx_stats_ctl_s cn52xxp1;
5677 + struct cvmx_gmxx_txx_stats_ctl_s cn56xx;
5678 + struct cvmx_gmxx_txx_stats_ctl_s cn56xxp1;
5679 + struct cvmx_gmxx_txx_stats_ctl_s cn58xx;
5680 + struct cvmx_gmxx_txx_stats_ctl_s cn58xxp1;
5681 +};
5682 +
5683 +union cvmx_gmxx_txx_thresh {
5684 + uint64_t u64;
5685 + struct cvmx_gmxx_txx_thresh_s {
5686 + uint64_t reserved_9_63:55;
5687 + uint64_t cnt:9;
5688 + } s;
5689 + struct cvmx_gmxx_txx_thresh_cn30xx {
5690 + uint64_t reserved_7_63:57;
5691 + uint64_t cnt:7;
5692 + } cn30xx;
5693 + struct cvmx_gmxx_txx_thresh_cn30xx cn31xx;
5694 + struct cvmx_gmxx_txx_thresh_s cn38xx;
5695 + struct cvmx_gmxx_txx_thresh_s cn38xxp2;
5696 + struct cvmx_gmxx_txx_thresh_cn30xx cn50xx;
5697 + struct cvmx_gmxx_txx_thresh_s cn52xx;
5698 + struct cvmx_gmxx_txx_thresh_s cn52xxp1;
5699 + struct cvmx_gmxx_txx_thresh_s cn56xx;
5700 + struct cvmx_gmxx_txx_thresh_s cn56xxp1;
5701 + struct cvmx_gmxx_txx_thresh_s cn58xx;
5702 + struct cvmx_gmxx_txx_thresh_s cn58xxp1;
5703 +};
5704 +
5705 +union cvmx_gmxx_tx_bp {
5706 + uint64_t u64;
5707 + struct cvmx_gmxx_tx_bp_s {
5708 + uint64_t reserved_4_63:60;
5709 + uint64_t bp:4;
5710 + } s;
5711 + struct cvmx_gmxx_tx_bp_cn30xx {
5712 + uint64_t reserved_3_63:61;
5713 + uint64_t bp:3;
5714 + } cn30xx;
5715 + struct cvmx_gmxx_tx_bp_cn30xx cn31xx;
5716 + struct cvmx_gmxx_tx_bp_s cn38xx;
5717 + struct cvmx_gmxx_tx_bp_s cn38xxp2;
5718 + struct cvmx_gmxx_tx_bp_cn30xx cn50xx;
5719 + struct cvmx_gmxx_tx_bp_s cn52xx;
5720 + struct cvmx_gmxx_tx_bp_s cn52xxp1;
5721 + struct cvmx_gmxx_tx_bp_s cn56xx;
5722 + struct cvmx_gmxx_tx_bp_s cn56xxp1;
5723 + struct cvmx_gmxx_tx_bp_s cn58xx;
5724 + struct cvmx_gmxx_tx_bp_s cn58xxp1;
5725 +};
5726 +
5727 +union cvmx_gmxx_tx_clk_mskx {
5728 + uint64_t u64;
5729 + struct cvmx_gmxx_tx_clk_mskx_s {
5730 + uint64_t reserved_1_63:63;
5731 + uint64_t msk:1;
5732 + } s;
5733 + struct cvmx_gmxx_tx_clk_mskx_s cn30xx;
5734 + struct cvmx_gmxx_tx_clk_mskx_s cn50xx;
5735 +};
5736 +
5737 +union cvmx_gmxx_tx_col_attempt {
5738 + uint64_t u64;
5739 + struct cvmx_gmxx_tx_col_attempt_s {
5740 + uint64_t reserved_5_63:59;
5741 + uint64_t limit:5;
5742 + } s;
5743 + struct cvmx_gmxx_tx_col_attempt_s cn30xx;
5744 + struct cvmx_gmxx_tx_col_attempt_s cn31xx;
5745 + struct cvmx_gmxx_tx_col_attempt_s cn38xx;
5746 + struct cvmx_gmxx_tx_col_attempt_s cn38xxp2;
5747 + struct cvmx_gmxx_tx_col_attempt_s cn50xx;
5748 + struct cvmx_gmxx_tx_col_attempt_s cn52xx;
5749 + struct cvmx_gmxx_tx_col_attempt_s cn52xxp1;
5750 + struct cvmx_gmxx_tx_col_attempt_s cn56xx;
5751 + struct cvmx_gmxx_tx_col_attempt_s cn56xxp1;
5752 + struct cvmx_gmxx_tx_col_attempt_s cn58xx;
5753 + struct cvmx_gmxx_tx_col_attempt_s cn58xxp1;
5754 +};
5755 +
5756 +union cvmx_gmxx_tx_corrupt {
5757 + uint64_t u64;
5758 + struct cvmx_gmxx_tx_corrupt_s {
5759 + uint64_t reserved_4_63:60;
5760 + uint64_t corrupt:4;
5761 + } s;
5762 + struct cvmx_gmxx_tx_corrupt_cn30xx {
5763 + uint64_t reserved_3_63:61;
5764 + uint64_t corrupt:3;
5765 + } cn30xx;
5766 + struct cvmx_gmxx_tx_corrupt_cn30xx cn31xx;
5767 + struct cvmx_gmxx_tx_corrupt_s cn38xx;
5768 + struct cvmx_gmxx_tx_corrupt_s cn38xxp2;
5769 + struct cvmx_gmxx_tx_corrupt_cn30xx cn50xx;
5770 + struct cvmx_gmxx_tx_corrupt_s cn52xx;
5771 + struct cvmx_gmxx_tx_corrupt_s cn52xxp1;
5772 + struct cvmx_gmxx_tx_corrupt_s cn56xx;
5773 + struct cvmx_gmxx_tx_corrupt_s cn56xxp1;
5774 + struct cvmx_gmxx_tx_corrupt_s cn58xx;
5775 + struct cvmx_gmxx_tx_corrupt_s cn58xxp1;
5776 +};
5777 +
5778 +union cvmx_gmxx_tx_hg2_reg1 {
5779 + uint64_t u64;
5780 + struct cvmx_gmxx_tx_hg2_reg1_s {
5781 + uint64_t reserved_16_63:48;
5782 + uint64_t tx_xof:16;
5783 + } s;
5784 + struct cvmx_gmxx_tx_hg2_reg1_s cn52xx;
5785 + struct cvmx_gmxx_tx_hg2_reg1_s cn52xxp1;
5786 + struct cvmx_gmxx_tx_hg2_reg1_s cn56xx;
5787 +};
5788 +
5789 +union cvmx_gmxx_tx_hg2_reg2 {
5790 + uint64_t u64;
5791 + struct cvmx_gmxx_tx_hg2_reg2_s {
5792 + uint64_t reserved_16_63:48;
5793 + uint64_t tx_xon:16;
5794 + } s;
5795 + struct cvmx_gmxx_tx_hg2_reg2_s cn52xx;
5796 + struct cvmx_gmxx_tx_hg2_reg2_s cn52xxp1;
5797 + struct cvmx_gmxx_tx_hg2_reg2_s cn56xx;
5798 +};
5799 +
5800 +union cvmx_gmxx_tx_ifg {
5801 + uint64_t u64;
5802 + struct cvmx_gmxx_tx_ifg_s {
5803 + uint64_t reserved_8_63:56;
5804 + uint64_t ifg2:4;
5805 + uint64_t ifg1:4;
5806 + } s;
5807 + struct cvmx_gmxx_tx_ifg_s cn30xx;
5808 + struct cvmx_gmxx_tx_ifg_s cn31xx;
5809 + struct cvmx_gmxx_tx_ifg_s cn38xx;
5810 + struct cvmx_gmxx_tx_ifg_s cn38xxp2;
5811 + struct cvmx_gmxx_tx_ifg_s cn50xx;
5812 + struct cvmx_gmxx_tx_ifg_s cn52xx;
5813 + struct cvmx_gmxx_tx_ifg_s cn52xxp1;
5814 + struct cvmx_gmxx_tx_ifg_s cn56xx;
5815 + struct cvmx_gmxx_tx_ifg_s cn56xxp1;
5816 + struct cvmx_gmxx_tx_ifg_s cn58xx;
5817 + struct cvmx_gmxx_tx_ifg_s cn58xxp1;
5818 +};
5819 +
5820 +union cvmx_gmxx_tx_int_en {
5821 + uint64_t u64;
5822 + struct cvmx_gmxx_tx_int_en_s {
5823 + uint64_t reserved_20_63:44;
5824 + uint64_t late_col:4;
5825 + uint64_t xsdef:4;
5826 + uint64_t xscol:4;
5827 + uint64_t reserved_6_7:2;
5828 + uint64_t undflw:4;
5829 + uint64_t ncb_nxa:1;
5830 + uint64_t pko_nxa:1;
5831 + } s;
5832 + struct cvmx_gmxx_tx_int_en_cn30xx {
5833 + uint64_t reserved_19_63:45;
5834 + uint64_t late_col:3;
5835 + uint64_t reserved_15_15:1;
5836 + uint64_t xsdef:3;
5837 + uint64_t reserved_11_11:1;
5838 + uint64_t xscol:3;
5839 + uint64_t reserved_5_7:3;
5840 + uint64_t undflw:3;
5841 + uint64_t reserved_1_1:1;
5842 + uint64_t pko_nxa:1;
5843 + } cn30xx;
5844 + struct cvmx_gmxx_tx_int_en_cn31xx {
5845 + uint64_t reserved_15_63:49;
5846 + uint64_t xsdef:3;
5847 + uint64_t reserved_11_11:1;
5848 + uint64_t xscol:3;
5849 + uint64_t reserved_5_7:3;
5850 + uint64_t undflw:3;
5851 + uint64_t reserved_1_1:1;
5852 + uint64_t pko_nxa:1;
5853 + } cn31xx;
5854 + struct cvmx_gmxx_tx_int_en_s cn38xx;
5855 + struct cvmx_gmxx_tx_int_en_cn38xxp2 {
5856 + uint64_t reserved_16_63:48;
5857 + uint64_t xsdef:4;
5858 + uint64_t xscol:4;
5859 + uint64_t reserved_6_7:2;
5860 + uint64_t undflw:4;
5861 + uint64_t ncb_nxa:1;
5862 + uint64_t pko_nxa:1;
5863 + } cn38xxp2;
5864 + struct cvmx_gmxx_tx_int_en_cn30xx cn50xx;
5865 + struct cvmx_gmxx_tx_int_en_cn52xx {
5866 + uint64_t reserved_20_63:44;
5867 + uint64_t late_col:4;
5868 + uint64_t xsdef:4;
5869 + uint64_t xscol:4;
5870 + uint64_t reserved_6_7:2;
5871 + uint64_t undflw:4;
5872 + uint64_t reserved_1_1:1;
5873 + uint64_t pko_nxa:1;
5874 + } cn52xx;
5875 + struct cvmx_gmxx_tx_int_en_cn52xx cn52xxp1;
5876 + struct cvmx_gmxx_tx_int_en_cn52xx cn56xx;
5877 + struct cvmx_gmxx_tx_int_en_cn52xx cn56xxp1;
5878 + struct cvmx_gmxx_tx_int_en_s cn58xx;
5879 + struct cvmx_gmxx_tx_int_en_s cn58xxp1;
5880 +};
5881 +
5882 +union cvmx_gmxx_tx_int_reg {
5883 + uint64_t u64;
5884 + struct cvmx_gmxx_tx_int_reg_s {
5885 + uint64_t reserved_20_63:44;
5886 + uint64_t late_col:4;
5887 + uint64_t xsdef:4;
5888 + uint64_t xscol:4;
5889 + uint64_t reserved_6_7:2;
5890 + uint64_t undflw:4;
5891 + uint64_t ncb_nxa:1;
5892 + uint64_t pko_nxa:1;
5893 + } s;
5894 + struct cvmx_gmxx_tx_int_reg_cn30xx {
5895 + uint64_t reserved_19_63:45;
5896 + uint64_t late_col:3;
5897 + uint64_t reserved_15_15:1;
5898 + uint64_t xsdef:3;
5899 + uint64_t reserved_11_11:1;
5900 + uint64_t xscol:3;
5901 + uint64_t reserved_5_7:3;
5902 + uint64_t undflw:3;
5903 + uint64_t reserved_1_1:1;
5904 + uint64_t pko_nxa:1;
5905 + } cn30xx;
5906 + struct cvmx_gmxx_tx_int_reg_cn31xx {
5907 + uint64_t reserved_15_63:49;
5908 + uint64_t xsdef:3;
5909 + uint64_t reserved_11_11:1;
5910 + uint64_t xscol:3;
5911 + uint64_t reserved_5_7:3;
5912 + uint64_t undflw:3;
5913 + uint64_t reserved_1_1:1;
5914 + uint64_t pko_nxa:1;
5915 + } cn31xx;
5916 + struct cvmx_gmxx_tx_int_reg_s cn38xx;
5917 + struct cvmx_gmxx_tx_int_reg_cn38xxp2 {
5918 + uint64_t reserved_16_63:48;
5919 + uint64_t xsdef:4;
5920 + uint64_t xscol:4;
5921 + uint64_t reserved_6_7:2;
5922 + uint64_t undflw:4;
5923 + uint64_t ncb_nxa:1;
5924 + uint64_t pko_nxa:1;
5925 + } cn38xxp2;
5926 + struct cvmx_gmxx_tx_int_reg_cn30xx cn50xx;
5927 + struct cvmx_gmxx_tx_int_reg_cn52xx {
5928 + uint64_t reserved_20_63:44;
5929 + uint64_t late_col:4;
5930 + uint64_t xsdef:4;
5931 + uint64_t xscol:4;
5932 + uint64_t reserved_6_7:2;
5933 + uint64_t undflw:4;
5934 + uint64_t reserved_1_1:1;
5935 + uint64_t pko_nxa:1;
5936 + } cn52xx;
5937 + struct cvmx_gmxx_tx_int_reg_cn52xx cn52xxp1;
5938 + struct cvmx_gmxx_tx_int_reg_cn52xx cn56xx;
5939 + struct cvmx_gmxx_tx_int_reg_cn52xx cn56xxp1;
5940 + struct cvmx_gmxx_tx_int_reg_s cn58xx;
5941 + struct cvmx_gmxx_tx_int_reg_s cn58xxp1;
5942 +};
5943 +
5944 +union cvmx_gmxx_tx_jam {
5945 + uint64_t u64;
5946 + struct cvmx_gmxx_tx_jam_s {
5947 + uint64_t reserved_8_63:56;
5948 + uint64_t jam:8;
5949 + } s;
5950 + struct cvmx_gmxx_tx_jam_s cn30xx;
5951 + struct cvmx_gmxx_tx_jam_s cn31xx;
5952 + struct cvmx_gmxx_tx_jam_s cn38xx;
5953 + struct cvmx_gmxx_tx_jam_s cn38xxp2;
5954 + struct cvmx_gmxx_tx_jam_s cn50xx;
5955 + struct cvmx_gmxx_tx_jam_s cn52xx;
5956 + struct cvmx_gmxx_tx_jam_s cn52xxp1;
5957 + struct cvmx_gmxx_tx_jam_s cn56xx;
5958 + struct cvmx_gmxx_tx_jam_s cn56xxp1;
5959 + struct cvmx_gmxx_tx_jam_s cn58xx;
5960 + struct cvmx_gmxx_tx_jam_s cn58xxp1;
5961 +};
5962 +
5963 +union cvmx_gmxx_tx_lfsr {
5964 + uint64_t u64;
5965 + struct cvmx_gmxx_tx_lfsr_s {
5966 + uint64_t reserved_16_63:48;
5967 + uint64_t lfsr:16;
5968 + } s;
5969 + struct cvmx_gmxx_tx_lfsr_s cn30xx;
5970 + struct cvmx_gmxx_tx_lfsr_s cn31xx;
5971 + struct cvmx_gmxx_tx_lfsr_s cn38xx;
5972 + struct cvmx_gmxx_tx_lfsr_s cn38xxp2;
5973 + struct cvmx_gmxx_tx_lfsr_s cn50xx;
5974 + struct cvmx_gmxx_tx_lfsr_s cn52xx;
5975 + struct cvmx_gmxx_tx_lfsr_s cn52xxp1;
5976 + struct cvmx_gmxx_tx_lfsr_s cn56xx;
5977 + struct cvmx_gmxx_tx_lfsr_s cn56xxp1;
5978 + struct cvmx_gmxx_tx_lfsr_s cn58xx;
5979 + struct cvmx_gmxx_tx_lfsr_s cn58xxp1;
5980 +};
5981 +
5982 +union cvmx_gmxx_tx_ovr_bp {
5983 + uint64_t u64;
5984 + struct cvmx_gmxx_tx_ovr_bp_s {
5985 + uint64_t reserved_48_63:16;
5986 + uint64_t tx_prt_bp:16;
5987 + uint64_t reserved_12_31:20;
5988 + uint64_t en:4;
5989 + uint64_t bp:4;
5990 + uint64_t ign_full:4;
5991 + } s;
5992 + struct cvmx_gmxx_tx_ovr_bp_cn30xx {
5993 + uint64_t reserved_11_63:53;
5994 + uint64_t en:3;
5995 + uint64_t reserved_7_7:1;
5996 + uint64_t bp:3;
5997 + uint64_t reserved_3_3:1;
5998 + uint64_t ign_full:3;
5999 + } cn30xx;
6000 + struct cvmx_gmxx_tx_ovr_bp_cn30xx cn31xx;
6001 + struct cvmx_gmxx_tx_ovr_bp_cn38xx {
6002 + uint64_t reserved_12_63:52;
6003 + uint64_t en:4;
6004 + uint64_t bp:4;
6005 + uint64_t ign_full:4;
6006 + } cn38xx;
6007 + struct cvmx_gmxx_tx_ovr_bp_cn38xx cn38xxp2;
6008 + struct cvmx_gmxx_tx_ovr_bp_cn30xx cn50xx;
6009 + struct cvmx_gmxx_tx_ovr_bp_s cn52xx;
6010 + struct cvmx_gmxx_tx_ovr_bp_s cn52xxp1;
6011 + struct cvmx_gmxx_tx_ovr_bp_s cn56xx;
6012 + struct cvmx_gmxx_tx_ovr_bp_s cn56xxp1;
6013 + struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xx;
6014 + struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xxp1;
6015 +};
6016 +
6017 +union cvmx_gmxx_tx_pause_pkt_dmac {
6018 + uint64_t u64;
6019 + struct cvmx_gmxx_tx_pause_pkt_dmac_s {
6020 + uint64_t reserved_48_63:16;
6021 + uint64_t dmac:48;
6022 + } s;
6023 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn30xx;
6024 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn31xx;
6025 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xx;
6026 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xxp2;
6027 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn50xx;
6028 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xx;
6029 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xxp1;
6030 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xx;
6031 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xxp1;
6032 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xx;
6033 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xxp1;
6034 +};
6035 +
6036 +union cvmx_gmxx_tx_pause_pkt_type {
6037 + uint64_t u64;
6038 + struct cvmx_gmxx_tx_pause_pkt_type_s {
6039 + uint64_t reserved_16_63:48;
6040 + uint64_t type:16;
6041 + } s;
6042 + struct cvmx_gmxx_tx_pause_pkt_type_s cn30xx;
6043 + struct cvmx_gmxx_tx_pause_pkt_type_s cn31xx;
6044 + struct cvmx_gmxx_tx_pause_pkt_type_s cn38xx;
6045 + struct cvmx_gmxx_tx_pause_pkt_type_s cn38xxp2;
6046 + struct cvmx_gmxx_tx_pause_pkt_type_s cn50xx;
6047 + struct cvmx_gmxx_tx_pause_pkt_type_s cn52xx;
6048 + struct cvmx_gmxx_tx_pause_pkt_type_s cn52xxp1;
6049 + struct cvmx_gmxx_tx_pause_pkt_type_s cn56xx;
6050 + struct cvmx_gmxx_tx_pause_pkt_type_s cn56xxp1;
6051 + struct cvmx_gmxx_tx_pause_pkt_type_s cn58xx;
6052 + struct cvmx_gmxx_tx_pause_pkt_type_s cn58xxp1;
6053 +};
6054 +
6055 +union cvmx_gmxx_tx_prts {
6056 + uint64_t u64;
6057 + struct cvmx_gmxx_tx_prts_s {
6058 + uint64_t reserved_5_63:59;
6059 + uint64_t prts:5;
6060 + } s;
6061 + struct cvmx_gmxx_tx_prts_s cn30xx;
6062 + struct cvmx_gmxx_tx_prts_s cn31xx;
6063 + struct cvmx_gmxx_tx_prts_s cn38xx;
6064 + struct cvmx_gmxx_tx_prts_s cn38xxp2;
6065 + struct cvmx_gmxx_tx_prts_s cn50xx;
6066 + struct cvmx_gmxx_tx_prts_s cn52xx;
6067 + struct cvmx_gmxx_tx_prts_s cn52xxp1;
6068 + struct cvmx_gmxx_tx_prts_s cn56xx;
6069 + struct cvmx_gmxx_tx_prts_s cn56xxp1;
6070 + struct cvmx_gmxx_tx_prts_s cn58xx;
6071 + struct cvmx_gmxx_tx_prts_s cn58xxp1;
6072 +};
6073 +
6074 +union cvmx_gmxx_tx_spi_ctl {
6075 + uint64_t u64;
6076 + struct cvmx_gmxx_tx_spi_ctl_s {
6077 + uint64_t reserved_2_63:62;
6078 + uint64_t tpa_clr:1;
6079 + uint64_t cont_pkt:1;
6080 + } s;
6081 + struct cvmx_gmxx_tx_spi_ctl_s cn38xx;
6082 + struct cvmx_gmxx_tx_spi_ctl_s cn38xxp2;
6083 + struct cvmx_gmxx_tx_spi_ctl_s cn58xx;
6084 + struct cvmx_gmxx_tx_spi_ctl_s cn58xxp1;
6085 +};
6086 +
6087 +union cvmx_gmxx_tx_spi_drain {
6088 + uint64_t u64;
6089 + struct cvmx_gmxx_tx_spi_drain_s {
6090 + uint64_t reserved_16_63:48;
6091 + uint64_t drain:16;
6092 + } s;
6093 + struct cvmx_gmxx_tx_spi_drain_s cn38xx;
6094 + struct cvmx_gmxx_tx_spi_drain_s cn58xx;
6095 + struct cvmx_gmxx_tx_spi_drain_s cn58xxp1;
6096 +};
6097 +
6098 +union cvmx_gmxx_tx_spi_max {
6099 + uint64_t u64;
6100 + struct cvmx_gmxx_tx_spi_max_s {
6101 + uint64_t reserved_23_63:41;
6102 + uint64_t slice:7;
6103 + uint64_t max2:8;
6104 + uint64_t max1:8;
6105 + } s;
6106 + struct cvmx_gmxx_tx_spi_max_cn38xx {
6107 + uint64_t reserved_16_63:48;
6108 + uint64_t max2:8;
6109 + uint64_t max1:8;
6110 + } cn38xx;
6111 + struct cvmx_gmxx_tx_spi_max_cn38xx cn38xxp2;
6112 + struct cvmx_gmxx_tx_spi_max_s cn58xx;
6113 + struct cvmx_gmxx_tx_spi_max_s cn58xxp1;
6114 +};
6115 +
6116 +union cvmx_gmxx_tx_spi_roundx {
6117 + uint64_t u64;
6118 + struct cvmx_gmxx_tx_spi_roundx_s {
6119 + uint64_t reserved_16_63:48;
6120 + uint64_t round:16;
6121 + } s;
6122 + struct cvmx_gmxx_tx_spi_roundx_s cn58xx;
6123 + struct cvmx_gmxx_tx_spi_roundx_s cn58xxp1;
6124 +};
6125 +
6126 +union cvmx_gmxx_tx_spi_thresh {
6127 + uint64_t u64;
6128 + struct cvmx_gmxx_tx_spi_thresh_s {
6129 + uint64_t reserved_6_63:58;
6130 + uint64_t thresh:6;
6131 + } s;
6132 + struct cvmx_gmxx_tx_spi_thresh_s cn38xx;
6133 + struct cvmx_gmxx_tx_spi_thresh_s cn38xxp2;
6134 + struct cvmx_gmxx_tx_spi_thresh_s cn58xx;
6135 + struct cvmx_gmxx_tx_spi_thresh_s cn58xxp1;
6136 +};
6137 +
6138 +union cvmx_gmxx_tx_xaui_ctl {
6139 + uint64_t u64;
6140 + struct cvmx_gmxx_tx_xaui_ctl_s {
6141 + uint64_t reserved_11_63:53;
6142 + uint64_t hg_pause_hgi:2;
6143 + uint64_t hg_en:1;
6144 + uint64_t reserved_7_7:1;
6145 + uint64_t ls_byp:1;
6146 + uint64_t ls:2;
6147 + uint64_t reserved_2_3:2;
6148 + uint64_t uni_en:1;
6149 + uint64_t dic_en:1;
6150 + } s;
6151 + struct cvmx_gmxx_tx_xaui_ctl_s cn52xx;
6152 + struct cvmx_gmxx_tx_xaui_ctl_s cn52xxp1;
6153 + struct cvmx_gmxx_tx_xaui_ctl_s cn56xx;
6154 + struct cvmx_gmxx_tx_xaui_ctl_s cn56xxp1;
6155 +};
6156 +
6157 +union cvmx_gmxx_xaui_ext_loopback {
6158 + uint64_t u64;
6159 + struct cvmx_gmxx_xaui_ext_loopback_s {
6160 + uint64_t reserved_5_63:59;
6161 + uint64_t en:1;
6162 + uint64_t thresh:4;
6163 + } s;
6164 + struct cvmx_gmxx_xaui_ext_loopback_s cn52xx;
6165 + struct cvmx_gmxx_xaui_ext_loopback_s cn52xxp1;
6166 + struct cvmx_gmxx_xaui_ext_loopback_s cn56xx;
6167 + struct cvmx_gmxx_xaui_ext_loopback_s cn56xxp1;
6168 +};
6169 +
6170 +#endif
6171 --- /dev/null
6172 +++ b/drivers/staging/octeon/cvmx-helper-board.c
6173 @@ -0,0 +1,706 @@
6174 +/***********************license start***************
6175 + * Author: Cavium Networks
6176 + *
6177 + * Contact: support@caviumnetworks.com
6178 + * This file is part of the OCTEON SDK
6179 + *
6180 + * Copyright (c) 2003-2008 Cavium Networks
6181 + *
6182 + * This file is free software; you can redistribute it and/or modify
6183 + * it under the terms of the GNU General Public License, Version 2, as
6184 + * published by the Free Software Foundation.
6185 + *
6186 + * This file is distributed in the hope that it will be useful, but
6187 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
6188 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
6189 + * NONINFRINGEMENT. See the GNU General Public License for more
6190 + * details.
6191 + *
6192 + * You should have received a copy of the GNU General Public License
6193 + * along with this file; if not, write to the Free Software
6194 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6195 + * or visit http://www.gnu.org/licenses/.
6196 + *
6197 + * This file may also be available under a different license from Cavium.
6198 + * Contact Cavium Networks for more information
6199 + ***********************license end**************************************/
6200 +
6201 +/*
6202 + *
6203 + * Helper functions to abstract board specific data about
6204 + * network ports from the rest of the cvmx-helper files.
6205 + */
6206 +
6207 +#include <asm/octeon/octeon.h>
6208 +#include <asm/octeon/cvmx-bootinfo.h>
6209 +
6210 +#include "cvmx-config.h"
6211 +
6212 +#include "cvmx-mdio.h"
6213 +
6214 +#include "cvmx-helper.h"
6215 +#include "cvmx-helper-util.h"
6216 +#include "cvmx-helper-board.h"
6217 +
6218 +#include "cvmx-gmxx-defs.h"
6219 +#include "cvmx-asxx-defs.h"
6220 +
6221 +/**
6222 + * cvmx_override_board_link_get(int ipd_port) is a function
6223 + * pointer. It is meant to allow customization of the process of
6224 + * talking to a PHY to determine link speed. It is called every
6225 + * time a PHY must be polled for link status. Users should set
6226 + * this pointer to a function before calling any cvmx-helper
6227 + * operations.
6228 + */
6229 +cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port) =
6230 + NULL;
6231 +
6232 +/**
6233 + * Return the MII PHY address associated with the given IPD
6234 + * port. A result of -1 means there isn't a MII capable PHY
6235 + * connected to this port. On chips supporting multiple MII
6236 + * busses the bus number is encoded in bits <15:8>.
6237 + *
6238 + * This function must be modified for every new Octeon board.
6239 + * Internally it uses switch statements based on the cvmx_sysinfo
6240 + * data to determine board types and revisions. It replies on the
6241 + * fact that every Octeon board receives a unique board type
6242 + * enumeration from the bootloader.
6243 + *
6244 + * @ipd_port: Octeon IPD port to get the MII address for.
6245 + *
6246 + * Returns MII PHY address and bus number or -1.
6247 + */
6248 +int cvmx_helper_board_get_mii_address(int ipd_port)
6249 +{
6250 + switch (cvmx_sysinfo_get()->board_type) {
6251 + case CVMX_BOARD_TYPE_SIM:
6252 + /* Simulator doesn't have MII */
6253 + return -1;
6254 + case CVMX_BOARD_TYPE_EBT3000:
6255 + case CVMX_BOARD_TYPE_EBT5800:
6256 + case CVMX_BOARD_TYPE_THUNDER:
6257 + case CVMX_BOARD_TYPE_NICPRO2:
6258 + /* Interface 0 is SPI4, interface 1 is RGMII */
6259 + if ((ipd_port >= 16) && (ipd_port < 20))
6260 + return ipd_port - 16;
6261 + else
6262 + return -1;
6263 + case CVMX_BOARD_TYPE_KODAMA:
6264 + case CVMX_BOARD_TYPE_EBH3100:
6265 + case CVMX_BOARD_TYPE_HIKARI:
6266 + case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
6267 + case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6268 + case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
6269 + /*
6270 + * Port 0 is WAN connected to a PHY, Port 1 is GMII
6271 + * connected to a switch
6272 + */
6273 + if (ipd_port == 0)
6274 + return 4;
6275 + else if (ipd_port == 1)
6276 + return 9;
6277 + else
6278 + return -1;
6279 + case CVMX_BOARD_TYPE_NAC38:
6280 + /* Board has 8 RGMII ports PHYs are 0-7 */
6281 + if ((ipd_port >= 0) && (ipd_port < 4))
6282 + return ipd_port;
6283 + else if ((ipd_port >= 16) && (ipd_port < 20))
6284 + return ipd_port - 16 + 4;
6285 + else
6286 + return -1;
6287 + case CVMX_BOARD_TYPE_EBH3000:
6288 + /* Board has dual SPI4 and no PHYs */
6289 + return -1;
6290 + case CVMX_BOARD_TYPE_EBH5200:
6291 + case CVMX_BOARD_TYPE_EBH5201:
6292 + case CVMX_BOARD_TYPE_EBT5200:
6293 + /*
6294 + * Board has 4 SGMII ports. The PHYs start right after the MII
6295 + * ports MII0 = 0, MII1 = 1, SGMII = 2-5.
6296 + */
6297 + if ((ipd_port >= 0) && (ipd_port < 4))
6298 + return ipd_port + 2;
6299 + else
6300 + return -1;
6301 + case CVMX_BOARD_TYPE_EBH5600:
6302 + case CVMX_BOARD_TYPE_EBH5601:
6303 + case CVMX_BOARD_TYPE_EBH5610:
6304 + /*
6305 + * Board has 8 SGMII ports. 4 connect out, two connect
6306 + * to a switch, and 2 loop to each other
6307 + */
6308 + if ((ipd_port >= 0) && (ipd_port < 4))
6309 + return ipd_port + 1;
6310 + else
6311 + return -1;
6312 + case CVMX_BOARD_TYPE_CUST_NB5:
6313 + if (ipd_port == 2)
6314 + return 4;
6315 + else
6316 + return -1;
6317 + case CVMX_BOARD_TYPE_NIC_XLE_4G:
6318 + /* Board has 4 SGMII ports. connected QLM3(interface 1) */
6319 + if ((ipd_port >= 16) && (ipd_port < 20))
6320 + return ipd_port - 16 + 1;
6321 + else
6322 + return -1;
6323 + case CVMX_BOARD_TYPE_BBGW_REF:
6324 + /*
6325 + * No PHYs are connected to Octeon, everything is
6326 + * through switch.
6327 + */
6328 + return -1;
6329 + }
6330 +
6331 + /* Some unknown board. Somebody forgot to update this function... */
6332 + cvmx_dprintf
6333 + ("cvmx_helper_board_get_mii_address: Unknown board type %d\n",
6334 + cvmx_sysinfo_get()->board_type);
6335 + return -1;
6336 +}
6337 +
6338 +/**
6339 + * This function is the board specific method of determining an
6340 + * ethernet ports link speed. Most Octeon boards have Marvell PHYs
6341 + * and are handled by the fall through case. This function must be
6342 + * updated for boards that don't have the normal Marvell PHYs.
6343 + *
6344 + * This function must be modified for every new Octeon board.
6345 + * Internally it uses switch statements based on the cvmx_sysinfo
6346 + * data to determine board types and revisions. It relies on the
6347 + * fact that every Octeon board receives a unique board type
6348 + * enumeration from the bootloader.
6349 + *
6350 + * @ipd_port: IPD input port associated with the port we want to get link
6351 + * status for.
6352 + *
6353 + * Returns The ports link status. If the link isn't fully resolved, this must
6354 + * return zero.
6355 + */
6356 +cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
6357 +{
6358 + cvmx_helper_link_info_t result;
6359 + int phy_addr;
6360 + int is_broadcom_phy = 0;
6361 +
6362 + /* Give the user a chance to override the processing of this function */
6363 + if (cvmx_override_board_link_get)
6364 + return cvmx_override_board_link_get(ipd_port);
6365 +
6366 + /* Unless we fix it later, all links are defaulted to down */
6367 + result.u64 = 0;
6368 +
6369 + /*
6370 + * This switch statement should handle all ports that either don't use
6371 + * Marvell PHYS, or don't support in-band status.
6372 + */
6373 + switch (cvmx_sysinfo_get()->board_type) {
6374 + case CVMX_BOARD_TYPE_SIM:
6375 + /* The simulator gives you a simulated 1Gbps full duplex link */
6376 + result.s.link_up = 1;
6377 + result.s.full_duplex = 1;
6378 + result.s.speed = 1000;
6379 + return result;
6380 + case CVMX_BOARD_TYPE_EBH3100:
6381 + case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
6382 + case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6383 + case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
6384 + /* Port 1 on these boards is always Gigabit */
6385 + if (ipd_port == 1) {
6386 + result.s.link_up = 1;
6387 + result.s.full_duplex = 1;
6388 + result.s.speed = 1000;
6389 + return result;
6390 + }
6391 + /* Fall through to the generic code below */
6392 + break;
6393 + case CVMX_BOARD_TYPE_CUST_NB5:
6394 + /* Port 1 on these boards is always Gigabit */
6395 + if (ipd_port == 1) {
6396 + result.s.link_up = 1;
6397 + result.s.full_duplex = 1;
6398 + result.s.speed = 1000;
6399 + return result;
6400 + } else /* The other port uses a broadcom PHY */
6401 + is_broadcom_phy = 1;
6402 + break;
6403 + case CVMX_BOARD_TYPE_BBGW_REF:
6404 + /* Port 1 on these boards is always Gigabit */
6405 + if (ipd_port == 2) {
6406 + /* Port 2 is not hooked up */
6407 + result.u64 = 0;
6408 + return result;
6409 + } else {
6410 + /* Ports 0 and 1 connect to the switch */
6411 + result.s.link_up = 1;
6412 + result.s.full_duplex = 1;
6413 + result.s.speed = 1000;
6414 + return result;
6415 + }
6416 + break;
6417 + }
6418 +
6419 + phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
6420 + if (phy_addr != -1) {
6421 + if (is_broadcom_phy) {
6422 + /*
6423 + * Below we are going to read SMI/MDIO
6424 + * register 0x19 which works on Broadcom
6425 + * parts
6426 + */
6427 + int phy_status =
6428 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6429 + 0x19);
6430 + switch ((phy_status >> 8) & 0x7) {
6431 + case 0:
6432 + result.u64 = 0;
6433 + break;
6434 + case 1:
6435 + result.s.link_up = 1;
6436 + result.s.full_duplex = 0;
6437 + result.s.speed = 10;
6438 + break;
6439 + case 2:
6440 + result.s.link_up = 1;
6441 + result.s.full_duplex = 1;
6442 + result.s.speed = 10;
6443 + break;
6444 + case 3:
6445 + result.s.link_up = 1;
6446 + result.s.full_duplex = 0;
6447 + result.s.speed = 100;
6448 + break;
6449 + case 4:
6450 + result.s.link_up = 1;
6451 + result.s.full_duplex = 1;
6452 + result.s.speed = 100;
6453 + break;
6454 + case 5:
6455 + result.s.link_up = 1;
6456 + result.s.full_duplex = 1;
6457 + result.s.speed = 100;
6458 + break;
6459 + case 6:
6460 + result.s.link_up = 1;
6461 + result.s.full_duplex = 0;
6462 + result.s.speed = 1000;
6463 + break;
6464 + case 7:
6465 + result.s.link_up = 1;
6466 + result.s.full_duplex = 1;
6467 + result.s.speed = 1000;
6468 + break;
6469 + }
6470 + } else {
6471 + /*
6472 + * This code assumes we are using a Marvell
6473 + * Gigabit PHY. All the speed information can
6474 + * be read from register 17 in one
6475 + * go. Somebody using a different PHY will
6476 + * need to handle it above in the board
6477 + * specific area.
6478 + */
6479 + int phy_status =
6480 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17);
6481 +
6482 + /*
6483 + * If the resolve bit 11 isn't set, see if
6484 + * autoneg is turned off (bit 12, reg 0). The
6485 + * resolve bit doesn't get set properly when
6486 + * autoneg is off, so force it.
6487 + */
6488 + if ((phy_status & (1 << 11)) == 0) {
6489 + int auto_status =
6490 + cvmx_mdio_read(phy_addr >> 8,
6491 + phy_addr & 0xff, 0);
6492 + if ((auto_status & (1 << 12)) == 0)
6493 + phy_status |= 1 << 11;
6494 + }
6495 +
6496 + /*
6497 + * Only return a link if the PHY has finished
6498 + * auto negotiation and set the resolved bit
6499 + * (bit 11)
6500 + */
6501 + if (phy_status & (1 << 11)) {
6502 + result.s.link_up = 1;
6503 + result.s.full_duplex = ((phy_status >> 13) & 1);
6504 + switch ((phy_status >> 14) & 3) {
6505 + case 0: /* 10 Mbps */
6506 + result.s.speed = 10;
6507 + break;
6508 + case 1: /* 100 Mbps */
6509 + result.s.speed = 100;
6510 + break;
6511 + case 2: /* 1 Gbps */
6512 + result.s.speed = 1000;
6513 + break;
6514 + case 3: /* Illegal */
6515 + result.u64 = 0;
6516 + break;
6517 + }
6518 + }
6519 + }
6520 + } else if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
6521 + || OCTEON_IS_MODEL(OCTEON_CN58XX)
6522 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
6523 + /*
6524 + * We don't have a PHY address, so attempt to use
6525 + * in-band status. It is really important that boards
6526 + * not supporting in-band status never get
6527 + * here. Reading broken in-band status tends to do bad
6528 + * things
6529 + */
6530 + union cvmx_gmxx_rxx_rx_inbnd inband_status;
6531 + int interface = cvmx_helper_get_interface_num(ipd_port);
6532 + int index = cvmx_helper_get_interface_index_num(ipd_port);
6533 + inband_status.u64 =
6534 + cvmx_read_csr(CVMX_GMXX_RXX_RX_INBND(index, interface));
6535 +
6536 + result.s.link_up = inband_status.s.status;
6537 + result.s.full_duplex = inband_status.s.duplex;
6538 + switch (inband_status.s.speed) {
6539 + case 0: /* 10 Mbps */
6540 + result.s.speed = 10;
6541 + break;
6542 + case 1: /* 100 Mbps */
6543 + result.s.speed = 100;
6544 + break;
6545 + case 2: /* 1 Gbps */
6546 + result.s.speed = 1000;
6547 + break;
6548 + case 3: /* Illegal */
6549 + result.u64 = 0;
6550 + break;
6551 + }
6552 + } else {
6553 + /*
6554 + * We don't have a PHY address and we don't have
6555 + * in-band status. There is no way to determine the
6556 + * link speed. Return down assuming this port isn't
6557 + * wired
6558 + */
6559 + result.u64 = 0;
6560 + }
6561 +
6562 + /* If link is down, return all fields as zero. */
6563 + if (!result.s.link_up)
6564 + result.u64 = 0;
6565 +
6566 + return result;
6567 +}
6568 +
6569 +/**
6570 + * This function as a board specific method of changing the PHY
6571 + * speed, duplex, and auto-negotiation. This programs the PHY and
6572 + * not Octeon. This can be used to force Octeon's links to
6573 + * specific settings.
6574 + *
6575 + * @phy_addr: The address of the PHY to program
6576 + * @enable_autoneg:
6577 + * Non zero if you want to enable auto-negotiation.
6578 + * @link_info: Link speed to program. If the speed is zero and auto-negotiation
6579 + * is enabled, all possible negotiation speeds are advertised.
6580 + *
6581 + * Returns Zero on success, negative on failure
6582 + */
6583 +int cvmx_helper_board_link_set_phy(int phy_addr,
6584 + cvmx_helper_board_set_phy_link_flags_types_t
6585 + link_flags,
6586 + cvmx_helper_link_info_t link_info)
6587 +{
6588 +
6589 + /* Set the flow control settings based on link_flags */
6590 + if ((link_flags & set_phy_link_flags_flow_control_mask) !=
6591 + set_phy_link_flags_flow_control_dont_touch) {
6592 + cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6593 + reg_autoneg_adver.u16 =
6594 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6595 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6596 + reg_autoneg_adver.s.asymmetric_pause =
6597 + (link_flags & set_phy_link_flags_flow_control_mask) ==
6598 + set_phy_link_flags_flow_control_enable;
6599 + reg_autoneg_adver.s.pause =
6600 + (link_flags & set_phy_link_flags_flow_control_mask) ==
6601 + set_phy_link_flags_flow_control_enable;
6602 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6603 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6604 + reg_autoneg_adver.u16);
6605 + }
6606 +
6607 + /* If speed isn't set and autoneg is on advertise all supported modes */
6608 + if ((link_flags & set_phy_link_flags_autoneg)
6609 + && (link_info.s.speed == 0)) {
6610 + cvmx_mdio_phy_reg_control_t reg_control;
6611 + cvmx_mdio_phy_reg_status_t reg_status;
6612 + cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6613 + cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
6614 + cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
6615 +
6616 + reg_status.u16 =
6617 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6618 + CVMX_MDIO_PHY_REG_STATUS);
6619 + reg_autoneg_adver.u16 =
6620 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6621 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6622 + reg_autoneg_adver.s.advert_100base_t4 =
6623 + reg_status.s.capable_100base_t4;
6624 + reg_autoneg_adver.s.advert_10base_tx_full =
6625 + reg_status.s.capable_10_full;
6626 + reg_autoneg_adver.s.advert_10base_tx_half =
6627 + reg_status.s.capable_10_half;
6628 + reg_autoneg_adver.s.advert_100base_tx_full =
6629 + reg_status.s.capable_100base_x_full;
6630 + reg_autoneg_adver.s.advert_100base_tx_half =
6631 + reg_status.s.capable_100base_x_half;
6632 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6633 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6634 + reg_autoneg_adver.u16);
6635 + if (reg_status.s.capable_extended_status) {
6636 + reg_extended_status.u16 =
6637 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6638 + CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
6639 + reg_control_1000.u16 =
6640 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6641 + CVMX_MDIO_PHY_REG_CONTROL_1000);
6642 + reg_control_1000.s.advert_1000base_t_full =
6643 + reg_extended_status.s.capable_1000base_t_full;
6644 + reg_control_1000.s.advert_1000base_t_half =
6645 + reg_extended_status.s.capable_1000base_t_half;
6646 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6647 + CVMX_MDIO_PHY_REG_CONTROL_1000,
6648 + reg_control_1000.u16);
6649 + }
6650 + reg_control.u16 =
6651 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6652 + CVMX_MDIO_PHY_REG_CONTROL);
6653 + reg_control.s.autoneg_enable = 1;
6654 + reg_control.s.restart_autoneg = 1;
6655 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6656 + CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6657 + } else if ((link_flags & set_phy_link_flags_autoneg)) {
6658 + cvmx_mdio_phy_reg_control_t reg_control;
6659 + cvmx_mdio_phy_reg_status_t reg_status;
6660 + cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6661 + cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
6662 + cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
6663 +
6664 + reg_status.u16 =
6665 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6666 + CVMX_MDIO_PHY_REG_STATUS);
6667 + reg_autoneg_adver.u16 =
6668 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6669 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6670 + reg_autoneg_adver.s.advert_100base_t4 = 0;
6671 + reg_autoneg_adver.s.advert_10base_tx_full = 0;
6672 + reg_autoneg_adver.s.advert_10base_tx_half = 0;
6673 + reg_autoneg_adver.s.advert_100base_tx_full = 0;
6674 + reg_autoneg_adver.s.advert_100base_tx_half = 0;
6675 + if (reg_status.s.capable_extended_status) {
6676 + reg_extended_status.u16 =
6677 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6678 + CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
6679 + reg_control_1000.u16 =
6680 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6681 + CVMX_MDIO_PHY_REG_CONTROL_1000);
6682 + reg_control_1000.s.advert_1000base_t_full = 0;
6683 + reg_control_1000.s.advert_1000base_t_half = 0;
6684 + }
6685 + switch (link_info.s.speed) {
6686 + case 10:
6687 + reg_autoneg_adver.s.advert_10base_tx_full =
6688 + link_info.s.full_duplex;
6689 + reg_autoneg_adver.s.advert_10base_tx_half =
6690 + !link_info.s.full_duplex;
6691 + break;
6692 + case 100:
6693 + reg_autoneg_adver.s.advert_100base_tx_full =
6694 + link_info.s.full_duplex;
6695 + reg_autoneg_adver.s.advert_100base_tx_half =
6696 + !link_info.s.full_duplex;
6697 + break;
6698 + case 1000:
6699 + reg_control_1000.s.advert_1000base_t_full =
6700 + link_info.s.full_duplex;
6701 + reg_control_1000.s.advert_1000base_t_half =
6702 + !link_info.s.full_duplex;
6703 + break;
6704 + }
6705 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6706 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6707 + reg_autoneg_adver.u16);
6708 + if (reg_status.s.capable_extended_status)
6709 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6710 + CVMX_MDIO_PHY_REG_CONTROL_1000,
6711 + reg_control_1000.u16);
6712 + reg_control.u16 =
6713 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6714 + CVMX_MDIO_PHY_REG_CONTROL);
6715 + reg_control.s.autoneg_enable = 1;
6716 + reg_control.s.restart_autoneg = 1;
6717 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6718 + CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6719 + } else {
6720 + cvmx_mdio_phy_reg_control_t reg_control;
6721 + reg_control.u16 =
6722 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6723 + CVMX_MDIO_PHY_REG_CONTROL);
6724 + reg_control.s.autoneg_enable = 0;
6725 + reg_control.s.restart_autoneg = 1;
6726 + reg_control.s.duplex = link_info.s.full_duplex;
6727 + if (link_info.s.speed == 1000) {
6728 + reg_control.s.speed_msb = 1;
6729 + reg_control.s.speed_lsb = 0;
6730 + } else if (link_info.s.speed == 100) {
6731 + reg_control.s.speed_msb = 0;
6732 + reg_control.s.speed_lsb = 1;
6733 + } else if (link_info.s.speed == 10) {
6734 + reg_control.s.speed_msb = 0;
6735 + reg_control.s.speed_lsb = 0;
6736 + }
6737 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6738 + CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6739 + }
6740 + return 0;
6741 +}
6742 +
6743 +/**
6744 + * This function is called by cvmx_helper_interface_probe() after it
6745 + * determines the number of ports Octeon can support on a specific
6746 + * interface. This function is the per board location to override
6747 + * this value. It is called with the number of ports Octeon might
6748 + * support and should return the number of actual ports on the
6749 + * board.
6750 + *
6751 + * This function must be modifed for every new Octeon board.
6752 + * Internally it uses switch statements based on the cvmx_sysinfo
6753 + * data to determine board types and revisions. It relys on the
6754 + * fact that every Octeon board receives a unique board type
6755 + * enumeration from the bootloader.
6756 + *
6757 + * @interface: Interface to probe
6758 + * @supported_ports:
6759 + * Number of ports Octeon supports.
6760 + *
6761 + * Returns Number of ports the actual board supports. Many times this will
6762 + * simple be "support_ports".
6763 + */
6764 +int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
6765 +{
6766 + switch (cvmx_sysinfo_get()->board_type) {
6767 + case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6768 + if (interface == 0)
6769 + return 2;
6770 + break;
6771 + case CVMX_BOARD_TYPE_BBGW_REF:
6772 + if (interface == 0)
6773 + return 2;
6774 + break;
6775 + case CVMX_BOARD_TYPE_NIC_XLE_4G:
6776 + if (interface == 0)
6777 + return 0;
6778 + break;
6779 + /* The 2nd interface on the EBH5600 is connected to the Marvel switch,
6780 + which we don't support. Disable ports connected to it */
6781 + case CVMX_BOARD_TYPE_EBH5600:
6782 + if (interface == 1)
6783 + return 0;
6784 + break;
6785 + }
6786 + return supported_ports;
6787 +}
6788 +
6789 +/**
6790 + * Enable packet input/output from the hardware. This function is
6791 + * called after by cvmx_helper_packet_hardware_enable() to
6792 + * perform board specific initialization. For most boards
6793 + * nothing is needed.
6794 + *
6795 + * @interface: Interface to enable
6796 + *
6797 + * Returns Zero on success, negative on failure
6798 + */
6799 +int __cvmx_helper_board_hardware_enable(int interface)
6800 +{
6801 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5) {
6802 + if (interface == 0) {
6803 + /* Different config for switch port */
6804 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0);
6805 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
6806 + /*
6807 + * Boards with gigabit WAN ports need a
6808 + * different setting that is compatible with
6809 + * 100 Mbit settings
6810 + */
6811 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface),
6812 + 0xc);
6813 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface),
6814 + 0xc);
6815 + }
6816 + } else if (cvmx_sysinfo_get()->board_type ==
6817 + CVMX_BOARD_TYPE_CN3010_EVB_HS5) {
6818 + /*
6819 + * Broadcom PHYs require differnet ASX
6820 + * clocks. Unfortunately many boards don't define a
6821 + * new board Id and simply mangle the
6822 + * CN3010_EVB_HS5
6823 + */
6824 + if (interface == 0) {
6825 + /*
6826 + * Some boards use a hacked up bootloader that
6827 + * identifies them as CN3010_EVB_HS5
6828 + * evaluation boards. This leads to all kinds
6829 + * of configuration problems. Detect one
6830 + * case, and print warning, while trying to do
6831 + * the right thing.
6832 + */
6833 + int phy_addr = cvmx_helper_board_get_mii_address(0);
6834 + if (phy_addr != -1) {
6835 + int phy_identifier =
6836 + cvmx_mdio_read(phy_addr >> 8,
6837 + phy_addr & 0xff, 0x2);
6838 + /* Is it a Broadcom PHY? */
6839 + if (phy_identifier == 0x0143) {
6840 + cvmx_dprintf("\n");
6841 + cvmx_dprintf("ERROR:\n");
6842 + cvmx_dprintf
6843 + ("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n");
6844 + cvmx_dprintf
6845 + ("ERROR: The board type is mis-configured, and software malfunctions are likely.\n");
6846 + cvmx_dprintf
6847 + ("ERROR: All boards require a unique board type to identify them.\n");
6848 + cvmx_dprintf("ERROR:\n");
6849 + cvmx_dprintf("\n");
6850 + cvmx_wait(1000000000);
6851 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX
6852 + (0, interface), 5);
6853 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX
6854 + (0, interface), 5);
6855 + }
6856 + }
6857 + }
6858 + }
6859 + return 0;
6860 +}
6861 +
6862 +cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void)
6863 +{
6864 + switch (cvmx_sysinfo_get()->board_type) {
6865 + case CVMX_BOARD_TYPE_BBGW_REF:
6866 + return USB_CLOCK_TYPE_CRYSTAL_12;
6867 + }
6868 + return USB_CLOCK_TYPE_REF_48;
6869 +}
6870 +
6871 +int __cvmx_helper_board_usb_get_num_ports(int supported_ports)
6872 +{
6873 + switch (cvmx_sysinfo_get()->board_type) {
6874 + case CVMX_BOARD_TYPE_NIC_XLE_4G:
6875 + return 0;
6876 + }
6877 +
6878 + return supported_ports;
6879 +}
6880 --- /dev/null
6881 +++ b/drivers/staging/octeon/cvmx-helper-board.h
6882 @@ -0,0 +1,180 @@
6883 +/***********************license start***************
6884 + * Author: Cavium Networks
6885 + *
6886 + * Contact: support@caviumnetworks.com
6887 + * This file is part of the OCTEON SDK
6888 + *
6889 + * Copyright (c) 2003-2008 Cavium Networks
6890 + *
6891 + * This file is free software; you can redistribute it and/or modify
6892 + * it under the terms of the GNU General Public License, Version 2, as
6893 + * published by the Free Software Foundation.
6894 + *
6895 + * This file is distributed in the hope that it will be useful, but
6896 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
6897 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
6898 + * NONINFRINGEMENT. See the GNU General Public License for more
6899 + * details.
6900 + *
6901 + * You should have received a copy of the GNU General Public License
6902 + * along with this file; if not, write to the Free Software
6903 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6904 + * or visit http://www.gnu.org/licenses/.
6905 + *
6906 + * This file may also be available under a different license from Cavium.
6907 + * Contact Cavium Networks for more information
6908 + ***********************license end**************************************/
6909 +
6910 +/**
6911 + *
6912 + * Helper functions to abstract board specific data about
6913 + * network ports from the rest of the cvmx-helper files.
6914 + *
6915 + */
6916 +#ifndef __CVMX_HELPER_BOARD_H__
6917 +#define __CVMX_HELPER_BOARD_H__
6918 +
6919 +#include "cvmx-helper.h"
6920 +
6921 +typedef enum {
6922 + USB_CLOCK_TYPE_REF_12,
6923 + USB_CLOCK_TYPE_REF_24,
6924 + USB_CLOCK_TYPE_REF_48,
6925 + USB_CLOCK_TYPE_CRYSTAL_12,
6926 +} cvmx_helper_board_usb_clock_types_t;
6927 +
6928 +typedef enum {
6929 + set_phy_link_flags_autoneg = 0x1,
6930 + set_phy_link_flags_flow_control_dont_touch = 0x0 << 1,
6931 + set_phy_link_flags_flow_control_enable = 0x1 << 1,
6932 + set_phy_link_flags_flow_control_disable = 0x2 << 1,
6933 + set_phy_link_flags_flow_control_mask = 0x3 << 1, /* Mask for 2 bit wide flow control field */
6934 +} cvmx_helper_board_set_phy_link_flags_types_t;
6935 +
6936 +/**
6937 + * cvmx_override_board_link_get(int ipd_port) is a function
6938 + * pointer. It is meant to allow customization of the process of
6939 + * talking to a PHY to determine link speed. It is called every
6940 + * time a PHY must be polled for link status. Users should set
6941 + * this pointer to a function before calling any cvmx-helper
6942 + * operations.
6943 + */
6944 +extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port);
6945 +
6946 +/**
6947 + * Return the MII PHY address associated with the given IPD
6948 + * port. A result of -1 means there isn't a MII capable PHY
6949 + * connected to this port. On chips supporting multiple MII
6950 + * busses the bus number is encoded in bits <15:8>.
6951 + *
6952 + * This function must be modifed for every new Octeon board.
6953 + * Internally it uses switch statements based on the cvmx_sysinfo
6954 + * data to determine board types and revisions. It relys on the
6955 + * fact that every Octeon board receives a unique board type
6956 + * enumeration from the bootloader.
6957 + *
6958 + * @ipd_port: Octeon IPD port to get the MII address for.
6959 + *
6960 + * Returns MII PHY address and bus number or -1.
6961 + */
6962 +extern int cvmx_helper_board_get_mii_address(int ipd_port);
6963 +
6964 +/**
6965 + * This function as a board specific method of changing the PHY
6966 + * speed, duplex, and autonegotiation. This programs the PHY and
6967 + * not Octeon. This can be used to force Octeon's links to
6968 + * specific settings.
6969 + *
6970 + * @phy_addr: The address of the PHY to program
6971 + * @link_flags:
6972 + * Flags to control autonegotiation. Bit 0 is autonegotiation
6973 + * enable/disable to maintain backware compatability.
6974 + * @link_info: Link speed to program. If the speed is zero and autonegotiation
6975 + * is enabled, all possible negotiation speeds are advertised.
6976 + *
6977 + * Returns Zero on success, negative on failure
6978 + */
6979 +int cvmx_helper_board_link_set_phy(int phy_addr,
6980 + cvmx_helper_board_set_phy_link_flags_types_t
6981 + link_flags,
6982 + cvmx_helper_link_info_t link_info);
6983 +
6984 +/**
6985 + * This function is the board specific method of determining an
6986 + * ethernet ports link speed. Most Octeon boards have Marvell PHYs
6987 + * and are handled by the fall through case. This function must be
6988 + * updated for boards that don't have the normal Marvell PHYs.
6989 + *
6990 + * This function must be modifed for every new Octeon board.
6991 + * Internally it uses switch statements based on the cvmx_sysinfo
6992 + * data to determine board types and revisions. It relys on the
6993 + * fact that every Octeon board receives a unique board type
6994 + * enumeration from the bootloader.
6995 + *
6996 + * @ipd_port: IPD input port associated with the port we want to get link
6997 + * status for.
6998 + *
6999 + * Returns The ports link status. If the link isn't fully resolved, this must
7000 + * return zero.
7001 + */
7002 +extern cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port);
7003 +
7004 +/**
7005 + * This function is called by cvmx_helper_interface_probe() after it
7006 + * determines the number of ports Octeon can support on a specific
7007 + * interface. This function is the per board location to override
7008 + * this value. It is called with the number of ports Octeon might
7009 + * support and should return the number of actual ports on the
7010 + * board.
7011 + *
7012 + * This function must be modifed for every new Octeon board.
7013 + * Internally it uses switch statements based on the cvmx_sysinfo
7014 + * data to determine board types and revisions. It relys on the
7015 + * fact that every Octeon board receives a unique board type
7016 + * enumeration from the bootloader.
7017 + *
7018 + * @interface: Interface to probe
7019 + * @supported_ports:
7020 + * Number of ports Octeon supports.
7021 + *
7022 + * Returns Number of ports the actual board supports. Many times this will
7023 + * simple be "support_ports".
7024 + */
7025 +extern int __cvmx_helper_board_interface_probe(int interface,
7026 + int supported_ports);
7027 +
7028 +/**
7029 + * Enable packet input/output from the hardware. This function is
7030 + * called after by cvmx_helper_packet_hardware_enable() to
7031 + * perform board specific initialization. For most boards
7032 + * nothing is needed.
7033 + *
7034 + * @interface: Interface to enable
7035 + *
7036 + * Returns Zero on success, negative on failure
7037 + */
7038 +extern int __cvmx_helper_board_hardware_enable(int interface);
7039 +
7040 +/**
7041 + * Gets the clock type used for the USB block based on board type.
7042 + * Used by the USB code for auto configuration of clock type.
7043 + *
7044 + * Returns USB clock type enumeration
7045 + */
7046 +cvmx_helper_board_usb_clock_types_t
7047 +__cvmx_helper_board_usb_get_clock_type(void);
7048 +
7049 +/**
7050 + * Adjusts the number of available USB ports on Octeon based on board
7051 + * specifics.
7052 + *
7053 + * @supported_ports: expected number of ports based on chip type;
7054 + *
7055 + *
7056 + * Returns number of available usb ports, based on board specifics.
7057 + * Return value is supported_ports if function does not
7058 + * override.
7059 + */
7060 +int __cvmx_helper_board_usb_get_num_ports(int supported_ports);
7061 +
7062 +#endif /* __CVMX_HELPER_BOARD_H__ */
7063 --- /dev/null
7064 +++ b/drivers/staging/octeon/cvmx-helper-fpa.c
7065 @@ -0,0 +1,243 @@
7066 +/***********************license start***************
7067 + * Author: Cavium Networks
7068 + *
7069 + * Contact: support@caviumnetworks.com
7070 + * This file is part of the OCTEON SDK
7071 + *
7072 + * Copyright (c) 2003-2008 Cavium Networks
7073 + *
7074 + * This file is free software; you can redistribute it and/or modify
7075 + * it under the terms of the GNU General Public License, Version 2, as
7076 + * published by the Free Software Foundation.
7077 + *
7078 + * This file is distributed in the hope that it will be useful, but
7079 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7080 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7081 + * NONINFRINGEMENT. See the GNU General Public License for more
7082 + * details.
7083 + *
7084 + * You should have received a copy of the GNU General Public License
7085 + * along with this file; if not, write to the Free Software
7086 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7087 + * or visit http://www.gnu.org/licenses/.
7088 + *
7089 + * This file may also be available under a different license from Cavium.
7090 + * Contact Cavium Networks for more information
7091 + ***********************license end**************************************/
7092 +
7093 +/**
7094 + * @file
7095 + *
7096 + * Helper functions for FPA setup.
7097 + *
7098 + */
7099 +#include "executive-config.h"
7100 +#include "cvmx-config.h"
7101 +#include "cvmx.h"
7102 +#include "cvmx-bootmem.h"
7103 +#include "cvmx-fpa.h"
7104 +#include "cvmx-helper-fpa.h"
7105 +
7106 +/**
7107 + * Allocate memory for and initialize a single FPA pool.
7108 + *
7109 + * @pool: Pool to initialize
7110 + * @buffer_size: Size of buffers to allocate in bytes
7111 + * @buffers: Number of buffers to put in the pool. Zero is allowed
7112 + * @name: String name of the pool for debugging purposes
7113 + * Returns Zero on success, non-zero on failure
7114 + */
7115 +static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size,
7116 + uint64_t buffers, const char *name)
7117 +{
7118 + uint64_t current_num;
7119 + void *memory;
7120 + uint64_t align = CVMX_CACHE_LINE_SIZE;
7121 +
7122 + /*
7123 + * Align the allocation so that power of 2 size buffers are
7124 + * naturally aligned.
7125 + */
7126 + while (align < buffer_size)
7127 + align = align << 1;
7128 +
7129 + if (buffers == 0)
7130 + return 0;
7131 +
7132 + current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool));
7133 + if (current_num) {
7134 + cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. "
7135 + "Skipping setup.\n",
7136 + pool, name, (unsigned long long)current_num);
7137 + return 0;
7138 + }
7139 +
7140 + memory = cvmx_bootmem_alloc(buffer_size * buffers, align);
7141 + if (memory == NULL) {
7142 + cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n",
7143 + pool, name);
7144 + return -1;
7145 + }
7146 + cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers);
7147 + return 0;
7148 +}
7149 +
7150 +/**
7151 + * Allocate memory and initialize the FPA pools using memory
7152 + * from cvmx-bootmem. Specifying zero for the number of
7153 + * buffers will cause that FPA pool to not be setup. This is
7154 + * useful if you aren't using some of the hardware and want
7155 + * to save memory. Use cvmx_helper_initialize_fpa instead of
7156 + * this function directly.
7157 + *
7158 + * @pip_pool: Should always be CVMX_FPA_PACKET_POOL
7159 + * @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE
7160 + * @pip_buffers:
7161 + * Number of packet buffers.
7162 + * @wqe_pool: Should always be CVMX_FPA_WQE_POOL
7163 + * @wqe_size: Should always be CVMX_FPA_WQE_POOL_SIZE
7164 + * @wqe_entries:
7165 + * Number of work queue entries
7166 + * @pko_pool: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL
7167 + * @pko_size: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
7168 + * @pko_buffers:
7169 + * PKO Command buffers. You should at minimum have two per
7170 + * each PKO queue.
7171 + * @tim_pool: Should always be CVMX_FPA_TIMER_POOL
7172 + * @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE
7173 + * @tim_buffers:
7174 + * TIM ring buffer command queues. At least two per timer bucket
7175 + * is recommened.
7176 + * @dfa_pool: Should always be CVMX_FPA_DFA_POOL
7177 + * @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE
7178 + * @dfa_buffers:
7179 + * DFA command buffer. A relatively small (32 for example)
7180 + * number should work.
7181 + * Returns Zero on success, non-zero if out of memory
7182 + */
7183 +static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size,
7184 + int pip_buffers, int wqe_pool,
7185 + int wqe_size, int wqe_entries,
7186 + int pko_pool, int pko_size,
7187 + int pko_buffers, int tim_pool,
7188 + int tim_size, int tim_buffers,
7189 + int dfa_pool, int dfa_size,
7190 + int dfa_buffers)
7191 +{
7192 + int status;
7193 +
7194 + cvmx_fpa_enable();
7195 +
7196 + if ((pip_buffers > 0) && (pip_buffers <= 64))
7197 + cvmx_dprintf
7198 + ("Warning: %d packet buffers may not be enough for hardware"
7199 + " prefetch. 65 or more is recommended.\n", pip_buffers);
7200 +
7201 + if (pip_pool >= 0) {
7202 + status =
7203 + __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size,
7204 + pip_buffers,
7205 + "Packet Buffers");
7206 + if (status)
7207 + return status;
7208 + }
7209 +
7210 + if (wqe_pool >= 0) {
7211 + status =
7212 + __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size,
7213 + wqe_entries,
7214 + "Work Queue Entries");
7215 + if (status)
7216 + return status;
7217 + }
7218 +
7219 + if (pko_pool >= 0) {
7220 + status =
7221 + __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size,
7222 + pko_buffers,
7223 + "PKO Command Buffers");
7224 + if (status)
7225 + return status;
7226 + }
7227 +
7228 + if (tim_pool >= 0) {
7229 + status =
7230 + __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size,
7231 + tim_buffers,
7232 + "TIM Command Buffers");
7233 + if (status)
7234 + return status;
7235 + }
7236 +
7237 + if (dfa_pool >= 0) {
7238 + status =
7239 + __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size,
7240 + dfa_buffers,
7241 + "DFA Command Buffers");
7242 + if (status)
7243 + return status;
7244 + }
7245 +
7246 + return 0;
7247 +}
7248 +
7249 +/**
7250 + * Allocate memory and initialize the FPA pools using memory
7251 + * from cvmx-bootmem. Sizes of each element in the pools is
7252 + * controlled by the cvmx-config.h header file. Specifying
7253 + * zero for any parameter will cause that FPA pool to not be
7254 + * setup. This is useful if you aren't using some of the
7255 + * hardware and want to save memory.
7256 + *
7257 + * @packet_buffers:
7258 + * Number of packet buffers to allocate
7259 + * @work_queue_entries:
7260 + * Number of work queue entries
7261 + * @pko_buffers:
7262 + * PKO Command buffers. You should at minimum have two per
7263 + * each PKO queue.
7264 + * @tim_buffers:
7265 + * TIM ring buffer command queues. At least two per timer bucket
7266 + * is recommened.
7267 + * @dfa_buffers:
7268 + * DFA command buffer. A relatively small (32 for example)
7269 + * number should work.
7270 + * Returns Zero on success, non-zero if out of memory
7271 + */
7272 +int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries,
7273 + int pko_buffers, int tim_buffers,
7274 + int dfa_buffers)
7275 +{
7276 +#ifndef CVMX_FPA_PACKET_POOL
7277 +#define CVMX_FPA_PACKET_POOL -1
7278 +#define CVMX_FPA_PACKET_POOL_SIZE 0
7279 +#endif
7280 +#ifndef CVMX_FPA_WQE_POOL
7281 +#define CVMX_FPA_WQE_POOL -1
7282 +#define CVMX_FPA_WQE_POOL_SIZE 0
7283 +#endif
7284 +#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL
7285 +#define CVMX_FPA_OUTPUT_BUFFER_POOL -1
7286 +#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0
7287 +#endif
7288 +#ifndef CVMX_FPA_TIMER_POOL
7289 +#define CVMX_FPA_TIMER_POOL -1
7290 +#define CVMX_FPA_TIMER_POOL_SIZE 0
7291 +#endif
7292 +#ifndef CVMX_FPA_DFA_POOL
7293 +#define CVMX_FPA_DFA_POOL -1
7294 +#define CVMX_FPA_DFA_POOL_SIZE 0
7295 +#endif
7296 + return __cvmx_helper_initialize_fpa(CVMX_FPA_PACKET_POOL,
7297 + CVMX_FPA_PACKET_POOL_SIZE,
7298 + packet_buffers, CVMX_FPA_WQE_POOL,
7299 + CVMX_FPA_WQE_POOL_SIZE,
7300 + work_queue_entries,
7301 + CVMX_FPA_OUTPUT_BUFFER_POOL,
7302 + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
7303 + pko_buffers, CVMX_FPA_TIMER_POOL,
7304 + CVMX_FPA_TIMER_POOL_SIZE,
7305 + tim_buffers, CVMX_FPA_DFA_POOL,
7306 + CVMX_FPA_DFA_POOL_SIZE,
7307 + dfa_buffers);
7308 +}
7309 --- /dev/null
7310 +++ b/drivers/staging/octeon/cvmx-helper-fpa.h
7311 @@ -0,0 +1,64 @@
7312 +/***********************license start***************
7313 + * Author: Cavium Networks
7314 + *
7315 + * Contact: support@caviumnetworks.com
7316 + * This file is part of the OCTEON SDK
7317 + *
7318 + * Copyright (c) 2003-2008 Cavium Networks
7319 + *
7320 + * This file is free software; you can redistribute it and/or modify
7321 + * it under the terms of the GNU General Public License, Version 2, as
7322 + * published by the Free Software Foundation.
7323 + *
7324 + * This file is distributed in the hope that it will be useful, but
7325 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7326 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7327 + * NONINFRINGEMENT. See the GNU General Public License for more
7328 + * details.
7329 + *
7330 + * You should have received a copy of the GNU General Public License
7331 + * along with this file; if not, write to the Free Software
7332 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7333 + * or visit http://www.gnu.org/licenses/.
7334 + *
7335 + * This file may also be available under a different license from Cavium.
7336 + * Contact Cavium Networks for more information
7337 + ***********************license end**************************************/
7338 +
7339 +/**
7340 + * @file
7341 + *
7342 + * Helper functions for FPA setup.
7343 + *
7344 + */
7345 +#ifndef __CVMX_HELPER_H_FPA__
7346 +#define __CVMX_HELPER_H_FPA__
7347 +
7348 +/**
7349 + * Allocate memory and initialize the FPA pools using memory
7350 + * from cvmx-bootmem. Sizes of each element in the pools is
7351 + * controlled by the cvmx-config.h header file. Specifying
7352 + * zero for any parameter will cause that FPA pool to not be
7353 + * setup. This is useful if you aren't using some of the
7354 + * hardware and want to save memory.
7355 + *
7356 + * @packet_buffers:
7357 + * Number of packet buffers to allocate
7358 + * @work_queue_entries:
7359 + * Number of work queue entries
7360 + * @pko_buffers:
7361 + * PKO Command buffers. You should at minimum have two per
7362 + * each PKO queue.
7363 + * @tim_buffers:
7364 + * TIM ring buffer command queues. At least two per timer bucket
7365 + * is recommened.
7366 + * @dfa_buffers:
7367 + * DFA command buffer. A relatively small (32 for example)
7368 + * number should work.
7369 + * Returns Zero on success, non-zero if out of memory
7370 + */
7371 +extern int cvmx_helper_initialize_fpa(int packet_buffers,
7372 + int work_queue_entries, int pko_buffers,
7373 + int tim_buffers, int dfa_buffers);
7374 +
7375 +#endif /* __CVMX_HELPER_H__ */
7376 --- /dev/null
7377 +++ b/drivers/staging/octeon/cvmx-helper-loop.c
7378 @@ -0,0 +1,85 @@
7379 +/***********************license start***************
7380 + * Author: Cavium Networks
7381 + *
7382 + * Contact: support@caviumnetworks.com
7383 + * This file is part of the OCTEON SDK
7384 + *
7385 + * Copyright (c) 2003-2008 Cavium Networks
7386 + *
7387 + * This file is free software; you can redistribute it and/or modify
7388 + * it under the terms of the GNU General Public License, Version 2, as
7389 + * published by the Free Software Foundation.
7390 + *
7391 + * This file is distributed in the hope that it will be useful, but
7392 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7393 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7394 + * NONINFRINGEMENT. See the GNU General Public License for more
7395 + * details.
7396 + *
7397 + * You should have received a copy of the GNU General Public License
7398 + * along with this file; if not, write to the Free Software
7399 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7400 + * or visit http://www.gnu.org/licenses/.
7401 + *
7402 + * This file may also be available under a different license from Cavium.
7403 + * Contact Cavium Networks for more information
7404 + ***********************license end**************************************/
7405 +
7406 +/*
7407 + * Functions for LOOP initialization, configuration,
7408 + * and monitoring.
7409 + */
7410 +#include <asm/octeon/octeon.h>
7411 +
7412 +#include "cvmx-config.h"
7413 +
7414 +#include "cvmx-helper.h"
7415 +#include "cvmx-pip-defs.h"
7416 +
7417 +/**
7418 + * Probe a LOOP interface and determine the number of ports
7419 + * connected to it. The LOOP interface should still be down
7420 + * after this call.
7421 + *
7422 + * @interface: Interface to probe
7423 + *
7424 + * Returns Number of ports on the interface. Zero to disable.
7425 + */
7426 +int __cvmx_helper_loop_probe(int interface)
7427 +{
7428 + union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
7429 + int num_ports = 4;
7430 + int port;
7431 +
7432 + /* We need to disable length checking so packet < 64 bytes and jumbo
7433 + frames don't get errors */
7434 + for (port = 0; port < num_ports; port++) {
7435 + union cvmx_pip_prt_cfgx port_cfg;
7436 + int ipd_port = cvmx_helper_get_ipd_port(interface, port);
7437 + port_cfg.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
7438 + port_cfg.s.maxerr_en = 0;
7439 + port_cfg.s.minerr_en = 0;
7440 + cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_cfg.u64);
7441 + }
7442 +
7443 + /* Disable FCS stripping for loopback ports */
7444 + ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
7445 + ipd_sub_port_fcs.s.port_bit2 = 0;
7446 + cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
7447 + return num_ports;
7448 +}
7449 +
7450 +/**
7451 + * Bringup and enable a LOOP interface. After this call packet
7452 + * I/O should be fully functional. This is called with IPD
7453 + * enabled but PKO disabled.
7454 + *
7455 + * @interface: Interface to bring up
7456 + *
7457 + * Returns Zero on success, negative on failure
7458 + */
7459 +int __cvmx_helper_loop_enable(int interface)
7460 +{
7461 + /* Do nothing. */
7462 + return 0;
7463 +}
7464 --- /dev/null
7465 +++ b/drivers/staging/octeon/cvmx-helper-loop.h
7466 @@ -0,0 +1,59 @@
7467 +/***********************license start***************
7468 + * Author: Cavium Networks
7469 + *
7470 + * Contact: support@caviumnetworks.com
7471 + * This file is part of the OCTEON SDK
7472 + *
7473 + * Copyright (c) 2003-2008 Cavium Networks
7474 + *
7475 + * This file is free software; you can redistribute it and/or modify
7476 + * it under the terms of the GNU General Public License, Version 2, as published by
7477 + * the Free Software Foundation.
7478 + *
7479 + * This file is distributed in the hope that it will be useful,
7480 + * but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
7481 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
7482 + * See the GNU General Public License for more details.
7483 + *
7484 + * You should have received a copy of the GNU General Public License
7485 + * along with this file; if not, write to the Free Software
7486 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7487 + * or visit http://www.gnu.org/licenses/.
7488 + *
7489 + * This file may also be available under a different license from Cavium.
7490 + * Contact Cavium Networks for more information
7491 + ***********************license end**************************************/
7492 +
7493 +/**
7494 + * @file
7495 + *
7496 + * Functions for LOOP initialization, configuration,
7497 + * and monitoring.
7498 + *
7499 + */
7500 +#ifndef __CVMX_HELPER_LOOP_H__
7501 +#define __CVMX_HELPER_LOOP_H__
7502 +
7503 +/**
7504 + * Probe a LOOP interface and determine the number of ports
7505 + * connected to it. The LOOP interface should still be down after
7506 + * this call.
7507 + *
7508 + * @interface: Interface to probe
7509 + *
7510 + * Returns Number of ports on the interface. Zero to disable.
7511 + */
7512 +extern int __cvmx_helper_loop_probe(int interface);
7513 +
7514 +/**
7515 + * Bringup and enable a LOOP interface. After this call packet
7516 + * I/O should be fully functional. This is called with IPD
7517 + * enabled but PKO disabled.
7518 + *
7519 + * @interface: Interface to bring up
7520 + *
7521 + * Returns Zero on success, negative on failure
7522 + */
7523 +extern int __cvmx_helper_loop_enable(int interface);
7524 +
7525 +#endif
7526 --- /dev/null
7527 +++ b/drivers/staging/octeon/cvmx-helper-npi.c
7528 @@ -0,0 +1,113 @@
7529 +/***********************license start***************
7530 + * Author: Cavium Networks
7531 + *
7532 + * Contact: support@caviumnetworks.com
7533 + * This file is part of the OCTEON SDK
7534 + *
7535 + * Copyright (c) 2003-2008 Cavium Networks
7536 + *
7537 + * This file is free software; you can redistribute it and/or modify
7538 + * it under the terms of the GNU General Public License, Version 2, as
7539 + * published by the Free Software Foundation.
7540 + *
7541 + * This file is distributed in the hope that it will be useful, but
7542 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7543 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7544 + * NONINFRINGEMENT. See the GNU General Public License for more
7545 + * details.
7546 + *
7547 + * You should have received a copy of the GNU General Public License
7548 + * along with this file; if not, write to the Free Software
7549 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7550 + * or visit http://www.gnu.org/licenses/.
7551 + *
7552 + * This file may also be available under a different license from Cavium.
7553 + * Contact Cavium Networks for more information
7554 + ***********************license end**************************************/
7555 +
7556 +/*
7557 + * Functions for NPI initialization, configuration,
7558 + * and monitoring.
7559 + */
7560 +#include <asm/octeon/octeon.h>
7561 +
7562 +#include "cvmx-config.h"
7563 +
7564 +#include "cvmx-helper.h"
7565 +
7566 +#include "cvmx-pip-defs.h"
7567 +
7568 +/**
7569 + * Probe a NPI interface and determine the number of ports
7570 + * connected to it. The NPI interface should still be down
7571 + * after this call.
7572 + *
7573 + * @interface: Interface to probe
7574 + *
7575 + * Returns Number of ports on the interface. Zero to disable.
7576 + */
7577 +int __cvmx_helper_npi_probe(int interface)
7578 +{
7579 +#if CVMX_PKO_QUEUES_PER_PORT_PCI > 0
7580 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
7581 + return 4;
7582 + else if (OCTEON_IS_MODEL(OCTEON_CN56XX)
7583 + && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
7584 + /* The packet engines didn't exist before pass 2 */
7585 + return 4;
7586 + else if (OCTEON_IS_MODEL(OCTEON_CN52XX)
7587 + && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X))
7588 + /* The packet engines didn't exist before pass 2 */
7589 + return 4;
7590 +#if 0
7591 + /*
7592 + * Technically CN30XX, CN31XX, and CN50XX contain packet
7593 + * engines, but nobody ever uses them. Since this is the case,
7594 + * we disable them here.
7595 + */
7596 + else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7597 + || OCTEON_IS_MODEL(OCTEON_CN50XX))
7598 + return 2;
7599 + else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
7600 + return 1;
7601 +#endif
7602 +#endif
7603 + return 0;
7604 +}
7605 +
7606 +/**
7607 + * Bringup and enable a NPI interface. After this call packet
7608 + * I/O should be fully functional. This is called with IPD
7609 + * enabled but PKO disabled.
7610 + *
7611 + * @interface: Interface to bring up
7612 + *
7613 + * Returns Zero on success, negative on failure
7614 + */
7615 +int __cvmx_helper_npi_enable(int interface)
7616 +{
7617 + /*
7618 + * On CN50XX, CN52XX, and CN56XX we need to disable length
7619 + * checking so packet < 64 bytes and jumbo frames don't get
7620 + * errors.
7621 + */
7622 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
7623 + !OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7624 + int num_ports = cvmx_helper_ports_on_interface(interface);
7625 + int port;
7626 + for (port = 0; port < num_ports; port++) {
7627 + union cvmx_pip_prt_cfgx port_cfg;
7628 + int ipd_port =
7629 + cvmx_helper_get_ipd_port(interface, port);
7630 + port_cfg.u64 =
7631 + cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
7632 + port_cfg.s.maxerr_en = 0;
7633 + port_cfg.s.minerr_en = 0;
7634 + cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port),
7635 + port_cfg.u64);
7636 + }
7637 + }
7638 +
7639 + /* Enables are controlled by the remote host, so nothing to do here */
7640 + return 0;
7641 +}
7642 --- /dev/null
7643 +++ b/drivers/staging/octeon/cvmx-helper-npi.h
7644 @@ -0,0 +1,60 @@
7645 +/***********************license start***************
7646 + * Author: Cavium Networks
7647 + *
7648 + * Contact: support@caviumnetworks.com
7649 + * This file is part of the OCTEON SDK
7650 + *
7651 + * Copyright (c) 2003-2008 Cavium Networks
7652 + *
7653 + * This file is free software; you can redistribute it and/or modify
7654 + * it under the terms of the GNU General Public License, Version 2, as
7655 + * published by the Free Software Foundation.
7656 + *
7657 + * This file is distributed in the hope that it will be useful, but
7658 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7659 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7660 + * NONINFRINGEMENT. See the GNU General Public License for more
7661 + * details.
7662 + *
7663 + * You should have received a copy of the GNU General Public License
7664 + * along with this file; if not, write to the Free Software
7665 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7666 + * or visit http://www.gnu.org/licenses/.
7667 + *
7668 + * This file may also be available under a different license from Cavium.
7669 + * Contact Cavium Networks for more information
7670 + ***********************license end**************************************/
7671 +
7672 +/**
7673 + * @file
7674 + *
7675 + * Functions for NPI initialization, configuration,
7676 + * and monitoring.
7677 + *
7678 + */
7679 +#ifndef __CVMX_HELPER_NPI_H__
7680 +#define __CVMX_HELPER_NPI_H__
7681 +
7682 +/**
7683 + * Probe a NPI interface and determine the number of ports
7684 + * connected to it. The NPI interface should still be down after
7685 + * this call.
7686 + *
7687 + * @interface: Interface to probe
7688 + *
7689 + * Returns Number of ports on the interface. Zero to disable.
7690 + */
7691 +extern int __cvmx_helper_npi_probe(int interface);
7692 +
7693 +/**
7694 + * Bringup and enable a NPI interface. After this call packet
7695 + * I/O should be fully functional. This is called with IPD
7696 + * enabled but PKO disabled.
7697 + *
7698 + * @interface: Interface to bring up
7699 + *
7700 + * Returns Zero on success, negative on failure
7701 + */
7702 +extern int __cvmx_helper_npi_enable(int interface);
7703 +
7704 +#endif
7705 --- /dev/null
7706 +++ b/drivers/staging/octeon/cvmx-helper-rgmii.c
7707 @@ -0,0 +1,525 @@
7708 +/***********************license start***************
7709 + * Author: Cavium Networks
7710 + *
7711 + * Contact: support@caviumnetworks.com
7712 + * This file is part of the OCTEON SDK
7713 + *
7714 + * Copyright (c) 2003-2008 Cavium Networks
7715 + *
7716 + * This file is free software; you can redistribute it and/or modify
7717 + * it under the terms of the GNU General Public License, Version 2, as
7718 + * published by the Free Software Foundation.
7719 + *
7720 + * This file is distributed in the hope that it will be useful, but
7721 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7722 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7723 + * NONINFRINGEMENT. See the GNU General Public License for more
7724 + * details.
7725 + *
7726 + * You should have received a copy of the GNU General Public License
7727 + * along with this file; if not, write to the Free Software
7728 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7729 + * or visit http://www.gnu.org/licenses/.
7730 + *
7731 + * This file may also be available under a different license from Cavium.
7732 + * Contact Cavium Networks for more information
7733 + ***********************license end**************************************/
7734 +
7735 +/*
7736 + * Functions for RGMII/GMII/MII initialization, configuration,
7737 + * and monitoring.
7738 + */
7739 +#include <asm/octeon/octeon.h>
7740 +
7741 +#include "cvmx-config.h"
7742 +
7743 +
7744 +#include "cvmx-mdio.h"
7745 +#include "cvmx-pko.h"
7746 +#include "cvmx-helper.h"
7747 +#include "cvmx-helper-board.h"
7748 +
7749 +#include <asm/octeon/cvmx-npi-defs.h>
7750 +#include "cvmx-gmxx-defs.h"
7751 +#include "cvmx-asxx-defs.h"
7752 +#include "cvmx-dbg-defs.h"
7753 +
7754 +void __cvmx_interrupt_gmxx_enable(int interface);
7755 +void __cvmx_interrupt_asxx_enable(int block);
7756 +
7757 +/**
7758 + * Probe RGMII ports and determine the number present
7759 + *
7760 + * @interface: Interface to probe
7761 + *
7762 + * Returns Number of RGMII/GMII/MII ports (0-4).
7763 + */
7764 +int __cvmx_helper_rgmii_probe(int interface)
7765 +{
7766 + int num_ports = 0;
7767 + union cvmx_gmxx_inf_mode mode;
7768 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
7769 +
7770 + if (mode.s.type) {
7771 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
7772 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7773 + cvmx_dprintf("ERROR: RGMII initialize called in "
7774 + "SPI interface\n");
7775 + } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7776 + || OCTEON_IS_MODEL(OCTEON_CN30XX)
7777 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7778 + /*
7779 + * On these chips "type" says we're in
7780 + * GMII/MII mode. This limits us to 2 ports
7781 + */
7782 + num_ports = 2;
7783 + } else {
7784 + cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
7785 + __func__);
7786 + }
7787 + } else {
7788 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
7789 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7790 + num_ports = 4;
7791 + } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7792 + || OCTEON_IS_MODEL(OCTEON_CN30XX)
7793 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7794 + num_ports = 3;
7795 + } else {
7796 + cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
7797 + __func__);
7798 + }
7799 + }
7800 + return num_ports;
7801 +}
7802 +
7803 +/**
7804 + * Put an RGMII interface in loopback mode. Internal packets sent
7805 + * out will be received back again on the same port. Externally
7806 + * received packets will echo back out.
7807 + *
7808 + * @port: IPD port number to loop.
7809 + */
7810 +void cvmx_helper_rgmii_internal_loopback(int port)
7811 +{
7812 + int interface = (port >> 4) & 1;
7813 + int index = port & 0xf;
7814 + uint64_t tmp;
7815 +
7816 + union cvmx_gmxx_prtx_cfg gmx_cfg;
7817 + gmx_cfg.u64 = 0;
7818 + gmx_cfg.s.duplex = 1;
7819 + gmx_cfg.s.slottime = 1;
7820 + gmx_cfg.s.speed = 1;
7821 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
7822 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
7823 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
7824 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
7825 + tmp = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
7826 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), (1 << index) | tmp);
7827 + tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface));
7828 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), (1 << index) | tmp);
7829 + tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface));
7830 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), (1 << index) | tmp);
7831 + gmx_cfg.s.en = 1;
7832 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
7833 +}
7834 +
7835 +/**
7836 + * Workaround ASX setup errata with CN38XX pass1
7837 + *
7838 + * @interface: Interface to setup
7839 + * @port: Port to setup (0..3)
7840 + * @cpu_clock_hz:
7841 + * Chip frequency in Hertz
7842 + *
7843 + * Returns Zero on success, negative on failure
7844 + */
7845 +static int __cvmx_helper_errata_asx_pass1(int interface, int port,
7846 + int cpu_clock_hz)
7847 +{
7848 + /* Set hi water mark as per errata GMX-4 */
7849 + if (cpu_clock_hz >= 325000000 && cpu_clock_hz < 375000000)
7850 + cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 12);
7851 + else if (cpu_clock_hz >= 375000000 && cpu_clock_hz < 437000000)
7852 + cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 11);
7853 + else if (cpu_clock_hz >= 437000000 && cpu_clock_hz < 550000000)
7854 + cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 10);
7855 + else if (cpu_clock_hz >= 550000000 && cpu_clock_hz < 687000000)
7856 + cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 9);
7857 + else
7858 + cvmx_dprintf("Illegal clock frequency (%d). "
7859 + "CVMX_ASXX_TX_HI_WATERX not set\n", cpu_clock_hz);
7860 + return 0;
7861 +}
7862 +
7863 +/**
7864 + * Configure all of the ASX, GMX, and PKO regsiters required
7865 + * to get RGMII to function on the supplied interface.
7866 + *
7867 + * @interface: PKO Interface to configure (0 or 1)
7868 + *
7869 + * Returns Zero on success
7870 + */
7871 +int __cvmx_helper_rgmii_enable(int interface)
7872 +{
7873 + int num_ports = cvmx_helper_ports_on_interface(interface);
7874 + int port;
7875 + struct cvmx_sysinfo *sys_info_ptr = cvmx_sysinfo_get();
7876 + union cvmx_gmxx_inf_mode mode;
7877 + union cvmx_asxx_tx_prt_en asx_tx;
7878 + union cvmx_asxx_rx_prt_en asx_rx;
7879 +
7880 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
7881 +
7882 + if (mode.s.en == 0)
7883 + return -1;
7884 + if ((OCTEON_IS_MODEL(OCTEON_CN38XX) ||
7885 + OCTEON_IS_MODEL(OCTEON_CN58XX)) && mode.s.type == 1)
7886 + /* Ignore SPI interfaces */
7887 + return -1;
7888 +
7889 + /* Configure the ASX registers needed to use the RGMII ports */
7890 + asx_tx.u64 = 0;
7891 + asx_tx.s.prt_en = cvmx_build_mask(num_ports);
7892 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), asx_tx.u64);
7893 +
7894 + asx_rx.u64 = 0;
7895 + asx_rx.s.prt_en = cvmx_build_mask(num_ports);
7896 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), asx_rx.u64);
7897 +
7898 + /* Configure the GMX registers needed to use the RGMII ports */
7899 + for (port = 0; port < num_ports; port++) {
7900 + /* Setting of CVMX_GMXX_TXX_THRESH has been moved to
7901 + __cvmx_helper_setup_gmx() */
7902 +
7903 + if (cvmx_octeon_is_pass1())
7904 + __cvmx_helper_errata_asx_pass1(interface, port,
7905 + sys_info_ptr->
7906 + cpu_clock_hz);
7907 + else {
7908 + /*
7909 + * Configure more flexible RGMII preamble
7910 + * checking. Pass 1 doesn't support this
7911 + * feature.
7912 + */
7913 + union cvmx_gmxx_rxx_frm_ctl frm_ctl;
7914 + frm_ctl.u64 =
7915 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
7916 + (port, interface));
7917 + /* New field, so must be compile time */
7918 + frm_ctl.s.pre_free = 1;
7919 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(port, interface),
7920 + frm_ctl.u64);
7921 + }
7922 +
7923 + /*
7924 + * Each pause frame transmitted will ask for about 10M
7925 + * bit times before resume. If buffer space comes
7926 + * available before that time has expired, an XON
7927 + * pause frame (0 time) will be transmitted to restart
7928 + * the flow.
7929 + */
7930 + cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_TIME(port, interface),
7931 + 20000);
7932 + cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL
7933 + (port, interface), 19000);
7934 +
7935 + if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7936 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
7937 + 16);
7938 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
7939 + 16);
7940 + } else {
7941 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
7942 + 24);
7943 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
7944 + 24);
7945 + }
7946 + }
7947 +
7948 + __cvmx_helper_setup_gmx(interface, num_ports);
7949 +
7950 + /* enable the ports now */
7951 + for (port = 0; port < num_ports; port++) {
7952 + union cvmx_gmxx_prtx_cfg gmx_cfg;
7953 + cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port
7954 + (interface, port));
7955 + gmx_cfg.u64 =
7956 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(port, interface));
7957 + gmx_cfg.s.en = 1;
7958 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(port, interface),
7959 + gmx_cfg.u64);
7960 + }
7961 + __cvmx_interrupt_asxx_enable(interface);
7962 + __cvmx_interrupt_gmxx_enable(interface);
7963 +
7964 + return 0;
7965 +}
7966 +
7967 +/**
7968 + * Return the link state of an IPD/PKO port as returned by
7969 + * auto negotiation. The result of this function may not match
7970 + * Octeon's link config if auto negotiation has changed since
7971 + * the last call to cvmx_helper_link_set().
7972 + *
7973 + * @ipd_port: IPD/PKO port to query
7974 + *
7975 + * Returns Link state
7976 + */
7977 +cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port)
7978 +{
7979 + int interface = cvmx_helper_get_interface_num(ipd_port);
7980 + int index = cvmx_helper_get_interface_index_num(ipd_port);
7981 + union cvmx_asxx_prt_loop asxx_prt_loop;
7982 +
7983 + asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
7984 + if (asxx_prt_loop.s.int_loop & (1 << index)) {
7985 + /* Force 1Gbps full duplex on internal loopback */
7986 + cvmx_helper_link_info_t result;
7987 + result.u64 = 0;
7988 + result.s.full_duplex = 1;
7989 + result.s.link_up = 1;
7990 + result.s.speed = 1000;
7991 + return result;
7992 + } else
7993 + return __cvmx_helper_board_link_get(ipd_port);
7994 +}
7995 +
7996 +/**
7997 + * Configure an IPD/PKO port for the specified link state. This
7998 + * function does not influence auto negotiation at the PHY level.
7999 + * The passed link state must always match the link state returned
8000 + * by cvmx_helper_link_get(). It is normally best to use
8001 + * cvmx_helper_link_autoconf() instead.
8002 + *
8003 + * @ipd_port: IPD/PKO port to configure
8004 + * @link_info: The new link state
8005 + *
8006 + * Returns Zero on success, negative on failure
8007 + */
8008 +int __cvmx_helper_rgmii_link_set(int ipd_port,
8009 + cvmx_helper_link_info_t link_info)
8010 +{
8011 + int result = 0;
8012 + int interface = cvmx_helper_get_interface_num(ipd_port);
8013 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8014 + union cvmx_gmxx_prtx_cfg original_gmx_cfg;
8015 + union cvmx_gmxx_prtx_cfg new_gmx_cfg;
8016 + union cvmx_pko_mem_queue_qos pko_mem_queue_qos;
8017 + union cvmx_pko_mem_queue_qos pko_mem_queue_qos_save[16];
8018 + union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp;
8019 + union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp_save;
8020 + int i;
8021 +
8022 + /* Ignore speed sets in the simulator */
8023 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
8024 + return 0;
8025 +
8026 + /* Read the current settings so we know the current enable state */
8027 + original_gmx_cfg.u64 =
8028 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8029 + new_gmx_cfg = original_gmx_cfg;
8030 +
8031 + /* Disable the lowest level RX */
8032 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8033 + cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) &
8034 + ~(1 << index));
8035 +
8036 + /* Disable all queues so that TX should become idle */
8037 + for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
8038 + int queue = cvmx_pko_get_base_queue(ipd_port) + i;
8039 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue);
8040 + pko_mem_queue_qos.u64 = cvmx_read_csr(CVMX_PKO_MEM_QUEUE_QOS);
8041 + pko_mem_queue_qos.s.pid = ipd_port;
8042 + pko_mem_queue_qos.s.qid = queue;
8043 + pko_mem_queue_qos_save[i] = pko_mem_queue_qos;
8044 + pko_mem_queue_qos.s.qos_mask = 0;
8045 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS, pko_mem_queue_qos.u64);
8046 + }
8047 +
8048 + /* Disable backpressure */
8049 + gmx_tx_ovr_bp.u64 = cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface));
8050 + gmx_tx_ovr_bp_save = gmx_tx_ovr_bp;
8051 + gmx_tx_ovr_bp.s.bp &= ~(1 << index);
8052 + gmx_tx_ovr_bp.s.en |= 1 << index;
8053 + cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp.u64);
8054 + cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface));
8055 +
8056 + /*
8057 + * Poll the GMX state machine waiting for it to become
8058 + * idle. Preferably we should only change speed when it is
8059 + * idle. If it doesn't become idle we will still do the speed
8060 + * change, but there is a slight chance that GMX will
8061 + * lockup.
8062 + */
8063 + cvmx_write_csr(CVMX_NPI_DBG_SELECT,
8064 + interface * 0x800 + index * 0x100 + 0x880);
8065 + CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 7,
8066 + ==, 0, 10000);
8067 + CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 0xf,
8068 + ==, 0, 10000);
8069 +
8070 + /* Disable the port before we make any changes */
8071 + new_gmx_cfg.s.en = 0;
8072 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8073 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8074 +
8075 + /* Set full/half duplex */
8076 + if (cvmx_octeon_is_pass1())
8077 + /* Half duplex is broken for 38XX Pass 1 */
8078 + new_gmx_cfg.s.duplex = 1;
8079 + else if (!link_info.s.link_up)
8080 + /* Force full duplex on down links */
8081 + new_gmx_cfg.s.duplex = 1;
8082 + else
8083 + new_gmx_cfg.s.duplex = link_info.s.full_duplex;
8084 +
8085 + /* Set the link speed. Anything unknown is set to 1Gbps */
8086 + if (link_info.s.speed == 10) {
8087 + new_gmx_cfg.s.slottime = 0;
8088 + new_gmx_cfg.s.speed = 0;
8089 + } else if (link_info.s.speed == 100) {
8090 + new_gmx_cfg.s.slottime = 0;
8091 + new_gmx_cfg.s.speed = 0;
8092 + } else {
8093 + new_gmx_cfg.s.slottime = 1;
8094 + new_gmx_cfg.s.speed = 1;
8095 + }
8096 +
8097 + /* Adjust the clocks */
8098 + if (link_info.s.speed == 10) {
8099 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 50);
8100 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40);
8101 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8102 + } else if (link_info.s.speed == 100) {
8103 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 5);
8104 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40);
8105 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8106 + } else {
8107 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
8108 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
8109 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
8110 + }
8111 +
8112 + if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
8113 + if ((link_info.s.speed == 10) || (link_info.s.speed == 100)) {
8114 + union cvmx_gmxx_inf_mode mode;
8115 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
8116 +
8117 + /*
8118 + * Port .en .type .p0mii Configuration
8119 + * ---- --- ----- ------ -----------------------------------------
8120 + * X 0 X X All links are disabled.
8121 + * 0 1 X 0 Port 0 is RGMII
8122 + * 0 1 X 1 Port 0 is MII
8123 + * 1 1 0 X Ports 1 and 2 are configured as RGMII ports.
8124 + * 1 1 1 X Port 1: GMII/MII; Port 2: disabled. GMII or
8125 + * MII port is selected by GMX_PRT1_CFG[SPEED].
8126 + */
8127 +
8128 + /* In MII mode, CLK_CNT = 1. */
8129 + if (((index == 0) && (mode.s.p0mii == 1))
8130 + || ((index != 0) && (mode.s.type == 1))) {
8131 + cvmx_write_csr(CVMX_GMXX_TXX_CLK
8132 + (index, interface), 1);
8133 + }
8134 + }
8135 + }
8136 +
8137 + /* Do a read to make sure all setup stuff is complete */
8138 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8139 +
8140 + /* Save the new GMX setting without enabling the port */
8141 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8142 +
8143 + /* Enable the lowest level RX */
8144 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8145 + cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) | (1 <<
8146 + index));
8147 +
8148 + /* Re-enable the TX path */
8149 + for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
8150 + int queue = cvmx_pko_get_base_queue(ipd_port) + i;
8151 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue);
8152 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS,
8153 + pko_mem_queue_qos_save[i].u64);
8154 + }
8155 +
8156 + /* Restore backpressure */
8157 + cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp_save.u64);
8158 +
8159 + /* Restore the GMX enable state. Port config is complete */
8160 + new_gmx_cfg.s.en = original_gmx_cfg.s.en;
8161 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8162 +
8163 + return result;
8164 +}
8165 +
8166 +/**
8167 + * Configure a port for internal and/or external loopback. Internal loopback
8168 + * causes packets sent by the port to be received by Octeon. External loopback
8169 + * causes packets received from the wire to sent out again.
8170 + *
8171 + * @ipd_port: IPD/PKO port to loopback.
8172 + * @enable_internal:
8173 + * Non zero if you want internal loopback
8174 + * @enable_external:
8175 + * Non zero if you want external loopback
8176 + *
8177 + * Returns Zero on success, negative on failure.
8178 + */
8179 +int __cvmx_helper_rgmii_configure_loopback(int ipd_port, int enable_internal,
8180 + int enable_external)
8181 +{
8182 + int interface = cvmx_helper_get_interface_num(ipd_port);
8183 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8184 + int original_enable;
8185 + union cvmx_gmxx_prtx_cfg gmx_cfg;
8186 + union cvmx_asxx_prt_loop asxx_prt_loop;
8187 +
8188 + /* Read the current enable state and save it */
8189 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8190 + original_enable = gmx_cfg.s.en;
8191 + /* Force port to be disabled */
8192 + gmx_cfg.s.en = 0;
8193 + if (enable_internal) {
8194 + /* Force speed if we're doing internal loopback */
8195 + gmx_cfg.s.duplex = 1;
8196 + gmx_cfg.s.slottime = 1;
8197 + gmx_cfg.s.speed = 1;
8198 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
8199 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
8200 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
8201 + }
8202 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
8203 +
8204 + /* Set the loopback bits */
8205 + asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
8206 + if (enable_internal)
8207 + asxx_prt_loop.s.int_loop |= 1 << index;
8208 + else
8209 + asxx_prt_loop.s.int_loop &= ~(1 << index);
8210 + if (enable_external)
8211 + asxx_prt_loop.s.ext_loop |= 1 << index;
8212 + else
8213 + asxx_prt_loop.s.ext_loop &= ~(1 << index);
8214 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), asxx_prt_loop.u64);
8215 +
8216 + /* Force enables in internal loopback */
8217 + if (enable_internal) {
8218 + uint64_t tmp;
8219 + tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface));
8220 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface),
8221 + (1 << index) | tmp);
8222 + tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface));
8223 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8224 + (1 << index) | tmp);
8225 + original_enable = 1;
8226 + }
8227 +
8228 + /* Restore the enable state */
8229 + gmx_cfg.s.en = original_enable;
8230 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
8231 + return 0;
8232 +}
8233 --- /dev/null
8234 +++ b/drivers/staging/octeon/cvmx-helper-rgmii.h
8235 @@ -0,0 +1,110 @@
8236 +/***********************license start***************
8237 + * Author: Cavium Networks
8238 + *
8239 + * Contact: support@caviumnetworks.com
8240 + * This file is part of the OCTEON SDK
8241 + *
8242 + * Copyright (c) 2003-2008 Cavium Networks
8243 + *
8244 + * This file is free software; you can redistribute it and/or modify
8245 + * it under the terms of the GNU General Public License, Version 2, as
8246 + * published by the Free Software Foundation.
8247 + *
8248 + * This file is distributed in the hope that it will be useful, but
8249 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8250 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8251 + * NONINFRINGEMENT. See the GNU General Public License for more
8252 + * details.
8253 + *
8254 + * You should have received a copy of the GNU General Public License
8255 + * along with this file; if not, write to the Free Software
8256 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8257 + * or visit http://www.gnu.org/licenses/.
8258 + *
8259 + * This file may also be available under a different license from Cavium.
8260 + * Contact Cavium Networks for more information
8261 + ***********************license end**************************************/
8262 +
8263 +/**
8264 + * @file
8265 + *
8266 + * Functions for RGMII/GMII/MII initialization, configuration,
8267 + * and monitoring.
8268 + *
8269 + */
8270 +#ifndef __CVMX_HELPER_RGMII_H__
8271 +#define __CVMX_HELPER_RGMII_H__
8272 +
8273 +/**
8274 + * Probe RGMII ports and determine the number present
8275 + *
8276 + * @interface: Interface to probe
8277 + *
8278 + * Returns Number of RGMII/GMII/MII ports (0-4).
8279 + */
8280 +extern int __cvmx_helper_rgmii_probe(int interface);
8281 +
8282 +/**
8283 + * Put an RGMII interface in loopback mode. Internal packets sent
8284 + * out will be received back again on the same port. Externally
8285 + * received packets will echo back out.
8286 + *
8287 + * @port: IPD port number to loop.
8288 + */
8289 +extern void cvmx_helper_rgmii_internal_loopback(int port);
8290 +
8291 +/**
8292 + * Configure all of the ASX, GMX, and PKO regsiters required
8293 + * to get RGMII to function on the supplied interface.
8294 + *
8295 + * @interface: PKO Interface to configure (0 or 1)
8296 + *
8297 + * Returns Zero on success
8298 + */
8299 +extern int __cvmx_helper_rgmii_enable(int interface);
8300 +
8301 +/**
8302 + * Return the link state of an IPD/PKO port as returned by
8303 + * auto negotiation. The result of this function may not match
8304 + * Octeon's link config if auto negotiation has changed since
8305 + * the last call to cvmx_helper_link_set().
8306 + *
8307 + * @ipd_port: IPD/PKO port to query
8308 + *
8309 + * Returns Link state
8310 + */
8311 +extern cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port);
8312 +
8313 +/**
8314 + * Configure an IPD/PKO port for the specified link state. This
8315 + * function does not influence auto negotiation at the PHY level.
8316 + * The passed link state must always match the link state returned
8317 + * by cvmx_helper_link_get(). It is normally best to use
8318 + * cvmx_helper_link_autoconf() instead.
8319 + *
8320 + * @ipd_port: IPD/PKO port to configure
8321 + * @link_info: The new link state
8322 + *
8323 + * Returns Zero on success, negative on failure
8324 + */
8325 +extern int __cvmx_helper_rgmii_link_set(int ipd_port,
8326 + cvmx_helper_link_info_t link_info);
8327 +
8328 +/**
8329 + * Configure a port for internal and/or external loopback. Internal loopback
8330 + * causes packets sent by the port to be received by Octeon. External loopback
8331 + * causes packets received from the wire to sent out again.
8332 + *
8333 + * @ipd_port: IPD/PKO port to loopback.
8334 + * @enable_internal:
8335 + * Non zero if you want internal loopback
8336 + * @enable_external:
8337 + * Non zero if you want external loopback
8338 + *
8339 + * Returns Zero on success, negative on failure.
8340 + */
8341 +extern int __cvmx_helper_rgmii_configure_loopback(int ipd_port,
8342 + int enable_internal,
8343 + int enable_external);
8344 +
8345 +#endif
8346 --- /dev/null
8347 +++ b/drivers/staging/octeon/cvmx-helper-sgmii.c
8348 @@ -0,0 +1,550 @@
8349 +/***********************license start***************
8350 + * Author: Cavium Networks
8351 + *
8352 + * Contact: support@caviumnetworks.com
8353 + * This file is part of the OCTEON SDK
8354 + *
8355 + * Copyright (c) 2003-2008 Cavium Networks
8356 + *
8357 + * This file is free software; you can redistribute it and/or modify
8358 + * it under the terms of the GNU General Public License, Version 2, as
8359 + * published by the Free Software Foundation.
8360 + *
8361 + * This file is distributed in the hope that it will be useful, but
8362 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8363 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8364 + * NONINFRINGEMENT. See the GNU General Public License for more
8365 + * details.
8366 + *
8367 + * You should have received a copy of the GNU General Public License
8368 + * along with this file; if not, write to the Free Software
8369 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8370 + * or visit http://www.gnu.org/licenses/.
8371 + *
8372 + * This file may also be available under a different license from Cavium.
8373 + * Contact Cavium Networks for more information
8374 + ***********************license end**************************************/
8375 +
8376 +/*
8377 + * Functions for SGMII initialization, configuration,
8378 + * and monitoring.
8379 + */
8380 +
8381 +#include <asm/octeon/octeon.h>
8382 +
8383 +#include "cvmx-config.h"
8384 +
8385 +#include "cvmx-mdio.h"
8386 +#include "cvmx-helper.h"
8387 +#include "cvmx-helper-board.h"
8388 +
8389 +#include "cvmx-gmxx-defs.h"
8390 +#include "cvmx-pcsx-defs.h"
8391 +
8392 +void __cvmx_interrupt_gmxx_enable(int interface);
8393 +void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
8394 +void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
8395 +
8396 +/**
8397 + * Perform initialization required only once for an SGMII port.
8398 + *
8399 + * @interface: Interface to init
8400 + * @index: Index of prot on the interface
8401 + *
8402 + * Returns Zero on success, negative on failure
8403 + */
8404 +static int __cvmx_helper_sgmii_hardware_init_one_time(int interface, int index)
8405 +{
8406 + const uint64_t clock_mhz = cvmx_sysinfo_get()->cpu_clock_hz / 1000000;
8407 + union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
8408 + union cvmx_pcsx_linkx_timer_count_reg pcsx_linkx_timer_count_reg;
8409 + union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8410 +
8411 + /* Disable GMX */
8412 + gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8413 + gmxx_prtx_cfg.s.en = 0;
8414 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8415 +
8416 + /*
8417 + * Write PCS*_LINK*_TIMER_COUNT_REG[COUNT] with the
8418 + * appropriate value. 1000BASE-X specifies a 10ms
8419 + * interval. SGMII specifies a 1.6ms interval.
8420 + */
8421 + pcs_misc_ctl_reg.u64 =
8422 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8423 + pcsx_linkx_timer_count_reg.u64 =
8424 + cvmx_read_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface));
8425 + if (pcs_misc_ctl_reg.s.mode) {
8426 + /* 1000BASE-X */
8427 + pcsx_linkx_timer_count_reg.s.count =
8428 + (10000ull * clock_mhz) >> 10;
8429 + } else {
8430 + /* SGMII */
8431 + pcsx_linkx_timer_count_reg.s.count =
8432 + (1600ull * clock_mhz) >> 10;
8433 + }
8434 + cvmx_write_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface),
8435 + pcsx_linkx_timer_count_reg.u64);
8436 +
8437 + /*
8438 + * Write the advertisement register to be used as the
8439 + * tx_Config_Reg<D15:D0> of the autonegotiation. In
8440 + * 1000BASE-X mode, tx_Config_Reg<D15:D0> is PCS*_AN*_ADV_REG.
8441 + * In SGMII PHY mode, tx_Config_Reg<D15:D0> is
8442 + * PCS*_SGM*_AN_ADV_REG. In SGMII MAC mode,
8443 + * tx_Config_Reg<D15:D0> is the fixed value 0x4001, so this
8444 + * step can be skipped.
8445 + */
8446 + if (pcs_misc_ctl_reg.s.mode) {
8447 + /* 1000BASE-X */
8448 + union cvmx_pcsx_anx_adv_reg pcsx_anx_adv_reg;
8449 + pcsx_anx_adv_reg.u64 =
8450 + cvmx_read_csr(CVMX_PCSX_ANX_ADV_REG(index, interface));
8451 + pcsx_anx_adv_reg.s.rem_flt = 0;
8452 + pcsx_anx_adv_reg.s.pause = 3;
8453 + pcsx_anx_adv_reg.s.hfd = 1;
8454 + pcsx_anx_adv_reg.s.fd = 1;
8455 + cvmx_write_csr(CVMX_PCSX_ANX_ADV_REG(index, interface),
8456 + pcsx_anx_adv_reg.u64);
8457 + } else {
8458 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8459 + pcsx_miscx_ctl_reg.u64 =
8460 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8461 + if (pcsx_miscx_ctl_reg.s.mac_phy) {
8462 + /* PHY Mode */
8463 + union cvmx_pcsx_sgmx_an_adv_reg pcsx_sgmx_an_adv_reg;
8464 + pcsx_sgmx_an_adv_reg.u64 =
8465 + cvmx_read_csr(CVMX_PCSX_SGMX_AN_ADV_REG
8466 + (index, interface));
8467 + pcsx_sgmx_an_adv_reg.s.link = 1;
8468 + pcsx_sgmx_an_adv_reg.s.dup = 1;
8469 + pcsx_sgmx_an_adv_reg.s.speed = 2;
8470 + cvmx_write_csr(CVMX_PCSX_SGMX_AN_ADV_REG
8471 + (index, interface),
8472 + pcsx_sgmx_an_adv_reg.u64);
8473 + } else {
8474 + /* MAC Mode - Nothing to do */
8475 + }
8476 + }
8477 + return 0;
8478 +}
8479 +
8480 +/**
8481 + * Initialize the SERTES link for the first time or after a loss
8482 + * of link.
8483 + *
8484 + * @interface: Interface to init
8485 + * @index: Index of prot on the interface
8486 + *
8487 + * Returns Zero on success, negative on failure
8488 + */
8489 +static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index)
8490 +{
8491 + union cvmx_pcsx_mrx_control_reg control_reg;
8492 +
8493 + /*
8494 + * Take PCS through a reset sequence.
8495 + * PCS*_MR*_CONTROL_REG[PWR_DN] should be cleared to zero.
8496 + * Write PCS*_MR*_CONTROL_REG[RESET]=1 (while not changing the
8497 + * value of the other PCS*_MR*_CONTROL_REG bits). Read
8498 + * PCS*_MR*_CONTROL_REG[RESET] until it changes value to
8499 + * zero.
8500 + */
8501 + control_reg.u64 =
8502 + cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8503 + if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
8504 + control_reg.s.reset = 1;
8505 + cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8506 + control_reg.u64);
8507 + if (CVMX_WAIT_FOR_FIELD64
8508 + (CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8509 + union cvmx_pcsx_mrx_control_reg, reset, ==, 0, 10000)) {
8510 + cvmx_dprintf("SGMII%d: Timeout waiting for port %d "
8511 + "to finish reset\n",
8512 + interface, index);
8513 + return -1;
8514 + }
8515 + }
8516 +
8517 + /*
8518 + * Write PCS*_MR*_CONTROL_REG[RST_AN]=1 to ensure a fresh
8519 + * sgmii negotiation starts.
8520 + */
8521 + control_reg.s.rst_an = 1;
8522 + control_reg.s.an_en = 1;
8523 + control_reg.s.pwr_dn = 0;
8524 + cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8525 + control_reg.u64);
8526 +
8527 + /*
8528 + * Wait for PCS*_MR*_STATUS_REG[AN_CPT] to be set, indicating
8529 + * that sgmii autonegotiation is complete. In MAC mode this
8530 + * isn't an ethernet link, but a link between Octeon and the
8531 + * PHY.
8532 + */
8533 + if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
8534 + CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_STATUS_REG(index, interface),
8535 + union cvmx_pcsx_mrx_status_reg, an_cpt, ==, 1,
8536 + 10000)) {
8537 + /* cvmx_dprintf("SGMII%d: Port %d link timeout\n", interface, index); */
8538 + return -1;
8539 + }
8540 + return 0;
8541 +}
8542 +
8543 +/**
8544 + * Configure an SGMII link to the specified speed after the SERTES
8545 + * link is up.
8546 + *
8547 + * @interface: Interface to init
8548 + * @index: Index of prot on the interface
8549 + * @link_info: Link state to configure
8550 + *
8551 + * Returns Zero on success, negative on failure
8552 + */
8553 +static int __cvmx_helper_sgmii_hardware_init_link_speed(int interface,
8554 + int index,
8555 + cvmx_helper_link_info_t
8556 + link_info)
8557 +{
8558 + int is_enabled;
8559 + union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8560 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8561 +
8562 + /* Disable GMX before we make any changes. Remember the enable state */
8563 + gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8564 + is_enabled = gmxx_prtx_cfg.s.en;
8565 + gmxx_prtx_cfg.s.en = 0;
8566 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8567 +
8568 + /* Wait for GMX to be idle */
8569 + if (CVMX_WAIT_FOR_FIELD64
8570 + (CVMX_GMXX_PRTX_CFG(index, interface), union cvmx_gmxx_prtx_cfg,
8571 + rx_idle, ==, 1, 10000)
8572 + || CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface),
8573 + union cvmx_gmxx_prtx_cfg, tx_idle, ==, 1,
8574 + 10000)) {
8575 + cvmx_dprintf
8576 + ("SGMII%d: Timeout waiting for port %d to be idle\n",
8577 + interface, index);
8578 + return -1;
8579 + }
8580 +
8581 + /* Read GMX CFG again to make sure the disable completed */
8582 + gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8583 +
8584 + /*
8585 + * Get the misc control for PCS. We will need to set the
8586 + * duplication amount.
8587 + */
8588 + pcsx_miscx_ctl_reg.u64 =
8589 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8590 +
8591 + /*
8592 + * Use GMXENO to force the link down if the status we get says
8593 + * it should be down.
8594 + */
8595 + pcsx_miscx_ctl_reg.s.gmxeno = !link_info.s.link_up;
8596 +
8597 + /* Only change the duplex setting if the link is up */
8598 + if (link_info.s.link_up)
8599 + gmxx_prtx_cfg.s.duplex = link_info.s.full_duplex;
8600 +
8601 + /* Do speed based setting for GMX */
8602 + switch (link_info.s.speed) {
8603 + case 10:
8604 + gmxx_prtx_cfg.s.speed = 0;
8605 + gmxx_prtx_cfg.s.speed_msb = 1;
8606 + gmxx_prtx_cfg.s.slottime = 0;
8607 + /* Setting from GMX-603 */
8608 + pcsx_miscx_ctl_reg.s.samp_pt = 25;
8609 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
8610 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8611 + break;
8612 + case 100:
8613 + gmxx_prtx_cfg.s.speed = 0;
8614 + gmxx_prtx_cfg.s.speed_msb = 0;
8615 + gmxx_prtx_cfg.s.slottime = 0;
8616 + pcsx_miscx_ctl_reg.s.samp_pt = 0x5;
8617 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
8618 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8619 + break;
8620 + case 1000:
8621 + gmxx_prtx_cfg.s.speed = 1;
8622 + gmxx_prtx_cfg.s.speed_msb = 0;
8623 + gmxx_prtx_cfg.s.slottime = 1;
8624 + pcsx_miscx_ctl_reg.s.samp_pt = 1;
8625 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 512);
8626 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 8192);
8627 + break;
8628 + default:
8629 + break;
8630 + }
8631 +
8632 + /* Write the new misc control for PCS */
8633 + cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
8634 + pcsx_miscx_ctl_reg.u64);
8635 +
8636 + /* Write the new GMX settings with the port still disabled */
8637 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8638 +
8639 + /* Read GMX CFG again to make sure the config completed */
8640 + gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8641 +
8642 + /* Restore the enabled / disabled state */
8643 + gmxx_prtx_cfg.s.en = is_enabled;
8644 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8645 +
8646 + return 0;
8647 +}
8648 +
8649 +/**
8650 + * Bring up the SGMII interface to be ready for packet I/O but
8651 + * leave I/O disabled using the GMX override. This function
8652 + * follows the bringup documented in 10.6.3 of the manual.
8653 + *
8654 + * @interface: Interface to bringup
8655 + * @num_ports: Number of ports on the interface
8656 + *
8657 + * Returns Zero on success, negative on failure
8658 + */
8659 +static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
8660 +{
8661 + int index;
8662 +
8663 + __cvmx_helper_setup_gmx(interface, num_ports);
8664 +
8665 + for (index = 0; index < num_ports; index++) {
8666 + int ipd_port = cvmx_helper_get_ipd_port(interface, index);
8667 + __cvmx_helper_sgmii_hardware_init_one_time(interface, index);
8668 + __cvmx_helper_sgmii_link_set(ipd_port,
8669 + __cvmx_helper_sgmii_link_get
8670 + (ipd_port));
8671 +
8672 + }
8673 +
8674 + return 0;
8675 +}
8676 +
8677 +/**
8678 + * Probe a SGMII interface and determine the number of ports
8679 + * connected to it. The SGMII interface should still be down after
8680 + * this call.
8681 + *
8682 + * @interface: Interface to probe
8683 + *
8684 + * Returns Number of ports on the interface. Zero to disable.
8685 + */
8686 +int __cvmx_helper_sgmii_probe(int interface)
8687 +{
8688 + union cvmx_gmxx_inf_mode mode;
8689 +
8690 + /*
8691 + * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
8692 + * interface needs to be enabled before IPD otherwise per port
8693 + * backpressure may not work properly
8694 + */
8695 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
8696 + mode.s.en = 1;
8697 + cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
8698 + return 4;
8699 +}
8700 +
8701 +/**
8702 + * Bringup and enable a SGMII interface. After this call packet
8703 + * I/O should be fully functional. This is called with IPD
8704 + * enabled but PKO disabled.
8705 + *
8706 + * @interface: Interface to bring up
8707 + *
8708 + * Returns Zero on success, negative on failure
8709 + */
8710 +int __cvmx_helper_sgmii_enable(int interface)
8711 +{
8712 + int num_ports = cvmx_helper_ports_on_interface(interface);
8713 + int index;
8714 +
8715 + __cvmx_helper_sgmii_hardware_init(interface, num_ports);
8716 +
8717 + for (index = 0; index < num_ports; index++) {
8718 + union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8719 + gmxx_prtx_cfg.u64 =
8720 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8721 + gmxx_prtx_cfg.s.en = 1;
8722 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
8723 + gmxx_prtx_cfg.u64);
8724 + __cvmx_interrupt_pcsx_intx_en_reg_enable(index, interface);
8725 + }
8726 + __cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
8727 + __cvmx_interrupt_gmxx_enable(interface);
8728 + return 0;
8729 +}
8730 +
8731 +/**
8732 + * Return the link state of an IPD/PKO port as returned by
8733 + * auto negotiation. The result of this function may not match
8734 + * Octeon's link config if auto negotiation has changed since
8735 + * the last call to cvmx_helper_link_set().
8736 + *
8737 + * @ipd_port: IPD/PKO port to query
8738 + *
8739 + * Returns Link state
8740 + */
8741 +cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port)
8742 +{
8743 + cvmx_helper_link_info_t result;
8744 + union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
8745 + int interface = cvmx_helper_get_interface_num(ipd_port);
8746 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8747 + union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
8748 +
8749 + result.u64 = 0;
8750 +
8751 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
8752 + /* The simulator gives you a simulated 1Gbps full duplex link */
8753 + result.s.link_up = 1;
8754 + result.s.full_duplex = 1;
8755 + result.s.speed = 1000;
8756 + return result;
8757 + }
8758 +
8759 + pcsx_mrx_control_reg.u64 =
8760 + cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8761 + if (pcsx_mrx_control_reg.s.loopbck1) {
8762 + /* Force 1Gbps full duplex link for internal loopback */
8763 + result.s.link_up = 1;
8764 + result.s.full_duplex = 1;
8765 + result.s.speed = 1000;
8766 + return result;
8767 + }
8768 +
8769 + pcs_misc_ctl_reg.u64 =
8770 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8771 + if (pcs_misc_ctl_reg.s.mode) {
8772 + /* 1000BASE-X */
8773 + /* FIXME */
8774 + } else {
8775 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8776 + pcsx_miscx_ctl_reg.u64 =
8777 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8778 + if (pcsx_miscx_ctl_reg.s.mac_phy) {
8779 + /* PHY Mode */
8780 + union cvmx_pcsx_mrx_status_reg pcsx_mrx_status_reg;
8781 + union cvmx_pcsx_anx_results_reg pcsx_anx_results_reg;
8782 +
8783 + /*
8784 + * Don't bother continuing if the SERTES low
8785 + * level link is down
8786 + */
8787 + pcsx_mrx_status_reg.u64 =
8788 + cvmx_read_csr(CVMX_PCSX_MRX_STATUS_REG
8789 + (index, interface));
8790 + if (pcsx_mrx_status_reg.s.lnk_st == 0) {
8791 + if (__cvmx_helper_sgmii_hardware_init_link
8792 + (interface, index) != 0)
8793 + return result;
8794 + }
8795 +
8796 + /* Read the autoneg results */
8797 + pcsx_anx_results_reg.u64 =
8798 + cvmx_read_csr(CVMX_PCSX_ANX_RESULTS_REG
8799 + (index, interface));
8800 + if (pcsx_anx_results_reg.s.an_cpt) {
8801 + /*
8802 + * Auto negotiation is complete. Set
8803 + * status accordingly.
8804 + */
8805 + result.s.full_duplex =
8806 + pcsx_anx_results_reg.s.dup;
8807 + result.s.link_up =
8808 + pcsx_anx_results_reg.s.link_ok;
8809 + switch (pcsx_anx_results_reg.s.spd) {
8810 + case 0:
8811 + result.s.speed = 10;
8812 + break;
8813 + case 1:
8814 + result.s.speed = 100;
8815 + break;
8816 + case 2:
8817 + result.s.speed = 1000;
8818 + break;
8819 + default:
8820 + result.s.speed = 0;
8821 + result.s.link_up = 0;
8822 + break;
8823 + }
8824 + } else {
8825 + /*
8826 + * Auto negotiation isn't
8827 + * complete. Return link down.
8828 + */
8829 + result.s.speed = 0;
8830 + result.s.link_up = 0;
8831 + }
8832 + } else { /* MAC Mode */
8833 +
8834 + result = __cvmx_helper_board_link_get(ipd_port);
8835 + }
8836 + }
8837 + return result;
8838 +}
8839 +
8840 +/**
8841 + * Configure an IPD/PKO port for the specified link state. This
8842 + * function does not influence auto negotiation at the PHY level.
8843 + * The passed link state must always match the link state returned
8844 + * by cvmx_helper_link_get(). It is normally best to use
8845 + * cvmx_helper_link_autoconf() instead.
8846 + *
8847 + * @ipd_port: IPD/PKO port to configure
8848 + * @link_info: The new link state
8849 + *
8850 + * Returns Zero on success, negative on failure
8851 + */
8852 +int __cvmx_helper_sgmii_link_set(int ipd_port,
8853 + cvmx_helper_link_info_t link_info)
8854 +{
8855 + int interface = cvmx_helper_get_interface_num(ipd_port);
8856 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8857 + __cvmx_helper_sgmii_hardware_init_link(interface, index);
8858 + return __cvmx_helper_sgmii_hardware_init_link_speed(interface, index,
8859 + link_info);
8860 +}
8861 +
8862 +/**
8863 + * Configure a port for internal and/or external loopback. Internal
8864 + * loopback causes packets sent by the port to be received by
8865 + * Octeon. External loopback causes packets received from the wire to
8866 + * sent out again.
8867 + *
8868 + * @ipd_port: IPD/PKO port to loopback.
8869 + * @enable_internal:
8870 + * Non zero if you want internal loopback
8871 + * @enable_external:
8872 + * Non zero if you want external loopback
8873 + *
8874 + * Returns Zero on success, negative on failure.
8875 + */
8876 +int __cvmx_helper_sgmii_configure_loopback(int ipd_port, int enable_internal,
8877 + int enable_external)
8878 +{
8879 + int interface = cvmx_helper_get_interface_num(ipd_port);
8880 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8881 + union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
8882 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8883 +
8884 + pcsx_mrx_control_reg.u64 =
8885 + cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8886 + pcsx_mrx_control_reg.s.loopbck1 = enable_internal;
8887 + cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8888 + pcsx_mrx_control_reg.u64);
8889 +
8890 + pcsx_miscx_ctl_reg.u64 =
8891 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8892 + pcsx_miscx_ctl_reg.s.loopbck2 = enable_external;
8893 + cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
8894 + pcsx_miscx_ctl_reg.u64);
8895 +
8896 + __cvmx_helper_sgmii_hardware_init_link(interface, index);
8897 + return 0;
8898 +}
8899 --- /dev/null
8900 +++ b/drivers/staging/octeon/cvmx-helper-sgmii.h
8901 @@ -0,0 +1,104 @@
8902 +/***********************license start***************
8903 + * Author: Cavium Networks
8904 + *
8905 + * Contact: support@caviumnetworks.com
8906 + * This file is part of the OCTEON SDK
8907 + *
8908 + * Copyright (c) 2003-2008 Cavium Networks
8909 + *
8910 + * This file is free software; you can redistribute it and/or modify
8911 + * it under the terms of the GNU General Public License, Version 2, as
8912 + * published by the Free Software Foundation.
8913 + *
8914 + * This file is distributed in the hope that it will be useful, but
8915 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8916 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8917 + * NONINFRINGEMENT. See the GNU General Public License for more
8918 + * details.
8919 + *
8920 + * You should have received a copy of the GNU General Public License
8921 + * along with this file; if not, write to the Free Software
8922 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8923 + * or visit http://www.gnu.org/licenses/.
8924 + *
8925 + * This file may also be available under a different license from Cavium.
8926 + * Contact Cavium Networks for more information
8927 + ***********************license end**************************************/
8928 +
8929 +/**
8930 + * @file
8931 + *
8932 + * Functions for SGMII initialization, configuration,
8933 + * and monitoring.
8934 + *
8935 + */
8936 +#ifndef __CVMX_HELPER_SGMII_H__
8937 +#define __CVMX_HELPER_SGMII_H__
8938 +
8939 +/**
8940 + * Probe a SGMII interface and determine the number of ports
8941 + * connected to it. The SGMII interface should still be down after
8942 + * this call.
8943 + *
8944 + * @interface: Interface to probe
8945 + *
8946 + * Returns Number of ports on the interface. Zero to disable.
8947 + */
8948 +extern int __cvmx_helper_sgmii_probe(int interface);
8949 +
8950 +/**
8951 + * Bringup and enable a SGMII interface. After this call packet
8952 + * I/O should be fully functional. This is called with IPD
8953 + * enabled but PKO disabled.
8954 + *
8955 + * @interface: Interface to bring up
8956 + *
8957 + * Returns Zero on success, negative on failure
8958 + */
8959 +extern int __cvmx_helper_sgmii_enable(int interface);
8960 +
8961 +/**
8962 + * Return the link state of an IPD/PKO port as returned by
8963 + * auto negotiation. The result of this function may not match
8964 + * Octeon's link config if auto negotiation has changed since
8965 + * the last call to cvmx_helper_link_set().
8966 + *
8967 + * @ipd_port: IPD/PKO port to query
8968 + *
8969 + * Returns Link state
8970 + */
8971 +extern cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port);
8972 +
8973 +/**
8974 + * Configure an IPD/PKO port for the specified link state. This
8975 + * function does not influence auto negotiation at the PHY level.
8976 + * The passed link state must always match the link state returned
8977 + * by cvmx_helper_link_get(). It is normally best to use
8978 + * cvmx_helper_link_autoconf() instead.
8979 + *
8980 + * @ipd_port: IPD/PKO port to configure
8981 + * @link_info: The new link state
8982 + *
8983 + * Returns Zero on success, negative on failure
8984 + */
8985 +extern int __cvmx_helper_sgmii_link_set(int ipd_port,
8986 + cvmx_helper_link_info_t link_info);
8987 +
8988 +/**
8989 + * Configure a port for internal and/or external loopback. Internal loopback
8990 + * causes packets sent by the port to be received by Octeon. External loopback
8991 + * causes packets received from the wire to sent out again.
8992 + *
8993 + * @ipd_port: IPD/PKO port to loopback.
8994 + * @enable_internal:
8995 + * Non zero if you want internal loopback
8996 + * @enable_external:
8997 + * Non zero if you want external loopback
8998 + *
8999 + * Returns Zero on success, negative on failure.
9000 + */
9001 +extern int __cvmx_helper_sgmii_configure_loopback(int ipd_port,
9002 + int enable_internal,
9003 + int enable_external);
9004 +
9005 +#endif
9006 --- /dev/null
9007 +++ b/drivers/staging/octeon/cvmx-helper-spi.c
9008 @@ -0,0 +1,195 @@
9009 +/***********************license start***************
9010 + * Author: Cavium Networks
9011 + *
9012 + * Contact: support@caviumnetworks.com
9013 + * This file is part of the OCTEON SDK
9014 + *
9015 + * Copyright (c) 2003-2008 Cavium Networks
9016 + *
9017 + * This file is free software; you can redistribute it and/or modify
9018 + * it under the terms of the GNU General Public License, Version 2, as
9019 + * published by the Free Software Foundation.
9020 + *
9021 + * This file is distributed in the hope that it will be useful, but
9022 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9023 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9024 + * NONINFRINGEMENT. See the GNU General Public License for more
9025 + * details.
9026 + *
9027 + * You should have received a copy of the GNU General Public License
9028 + * along with this file; if not, write to the Free Software
9029 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9030 + * or visit http://www.gnu.org/licenses/.
9031 + *
9032 + * This file may also be available under a different license from Cavium.
9033 + * Contact Cavium Networks for more information
9034 + ***********************license end**************************************/
9035 +
9036 +void __cvmx_interrupt_gmxx_enable(int interface);
9037 +void __cvmx_interrupt_spxx_int_msk_enable(int index);
9038 +void __cvmx_interrupt_stxx_int_msk_enable(int index);
9039 +
9040 +/*
9041 + * Functions for SPI initialization, configuration,
9042 + * and monitoring.
9043 + */
9044 +#include <asm/octeon/octeon.h>
9045 +
9046 +#include "cvmx-config.h"
9047 +#include "cvmx-spi.h"
9048 +#include "cvmx-helper.h"
9049 +
9050 +#include "cvmx-pip-defs.h"
9051 +#include "cvmx-pko-defs.h"
9052 +
9053 +/*
9054 + * CVMX_HELPER_SPI_TIMEOUT is used to determine how long the SPI
9055 + * initialization routines wait for SPI training. You can override the
9056 + * value using executive-config.h if necessary.
9057 + */
9058 +#ifndef CVMX_HELPER_SPI_TIMEOUT
9059 +#define CVMX_HELPER_SPI_TIMEOUT 10
9060 +#endif
9061 +
9062 +/**
9063 + * Probe a SPI interface and determine the number of ports
9064 + * connected to it. The SPI interface should still be down after
9065 + * this call.
9066 + *
9067 + * @interface: Interface to probe
9068 + *
9069 + * Returns Number of ports on the interface. Zero to disable.
9070 + */
9071 +int __cvmx_helper_spi_probe(int interface)
9072 +{
9073 + int num_ports = 0;
9074 +
9075 + if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
9076 + cvmx_spi4000_is_present(interface)) {
9077 + num_ports = 10;
9078 + } else {
9079 + union cvmx_pko_reg_crc_enable enable;
9080 + num_ports = 16;
9081 + /*
9082 + * Unlike the SPI4000, most SPI devices don't
9083 + * automatically put on the L2 CRC. For everything
9084 + * except for the SPI4000 have PKO append the L2 CRC
9085 + * to the packet.
9086 + */
9087 + enable.u64 = cvmx_read_csr(CVMX_PKO_REG_CRC_ENABLE);
9088 + enable.s.enable |= 0xffff << (interface * 16);
9089 + cvmx_write_csr(CVMX_PKO_REG_CRC_ENABLE, enable.u64);
9090 + }
9091 + __cvmx_helper_setup_gmx(interface, num_ports);
9092 + return num_ports;
9093 +}
9094 +
9095 +/**
9096 + * Bringup and enable a SPI interface. After this call packet I/O
9097 + * should be fully functional. This is called with IPD enabled but
9098 + * PKO disabled.
9099 + *
9100 + * @interface: Interface to bring up
9101 + *
9102 + * Returns Zero on success, negative on failure
9103 + */
9104 +int __cvmx_helper_spi_enable(int interface)
9105 +{
9106 + /*
9107 + * Normally the ethernet L2 CRC is checked and stripped in the
9108 + * GMX block. When you are using SPI, this isn' the case and
9109 + * IPD needs to check the L2 CRC.
9110 + */
9111 + int num_ports = cvmx_helper_ports_on_interface(interface);
9112 + int ipd_port;
9113 + for (ipd_port = interface * 16; ipd_port < interface * 16 + num_ports;
9114 + ipd_port++) {
9115 + union cvmx_pip_prt_cfgx port_config;
9116 + port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
9117 + port_config.s.crc_en = 1;
9118 + cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_config.u64);
9119 + }
9120 +
9121 + if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
9122 + cvmx_spi_start_interface(interface, CVMX_SPI_MODE_DUPLEX,
9123 + CVMX_HELPER_SPI_TIMEOUT, num_ports);
9124 + if (cvmx_spi4000_is_present(interface))
9125 + cvmx_spi4000_initialize(interface);
9126 + }
9127 + __cvmx_interrupt_spxx_int_msk_enable(interface);
9128 + __cvmx_interrupt_stxx_int_msk_enable(interface);
9129 + __cvmx_interrupt_gmxx_enable(interface);
9130 + return 0;
9131 +}
9132 +
9133 +/**
9134 + * Return the link state of an IPD/PKO port as returned by
9135 + * auto negotiation. The result of this function may not match
9136 + * Octeon's link config if auto negotiation has changed since
9137 + * the last call to cvmx_helper_link_set().
9138 + *
9139 + * @ipd_port: IPD/PKO port to query
9140 + *
9141 + * Returns Link state
9142 + */
9143 +cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port)
9144 +{
9145 + cvmx_helper_link_info_t result;
9146 + int interface = cvmx_helper_get_interface_num(ipd_port);
9147 + int index = cvmx_helper_get_interface_index_num(ipd_port);
9148 + result.u64 = 0;
9149 +
9150 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
9151 + /* The simulator gives you a simulated full duplex link */
9152 + result.s.link_up = 1;
9153 + result.s.full_duplex = 1;
9154 + result.s.speed = 10000;
9155 + } else if (cvmx_spi4000_is_present(interface)) {
9156 + union cvmx_gmxx_rxx_rx_inbnd inband =
9157 + cvmx_spi4000_check_speed(interface, index);
9158 + result.s.link_up = inband.s.status;
9159 + result.s.full_duplex = inband.s.duplex;
9160 + switch (inband.s.speed) {
9161 + case 0: /* 10 Mbps */
9162 + result.s.speed = 10;
9163 + break;
9164 + case 1: /* 100 Mbps */
9165 + result.s.speed = 100;
9166 + break;
9167 + case 2: /* 1 Gbps */
9168 + result.s.speed = 1000;
9169 + break;
9170 + case 3: /* Illegal */
9171 + result.s.speed = 0;
9172 + result.s.link_up = 0;
9173 + break;
9174 + }
9175 + } else {
9176 + /* For generic SPI we can't determine the link, just return some
9177 + sane results */
9178 + result.s.link_up = 1;
9179 + result.s.full_duplex = 1;
9180 + result.s.speed = 10000;
9181 + }
9182 + return result;
9183 +}
9184 +
9185 +/**
9186 + * Configure an IPD/PKO port for the specified link state. This
9187 + * function does not influence auto negotiation at the PHY level.
9188 + * The passed link state must always match the link state returned
9189 + * by cvmx_helper_link_get(). It is normally best to use
9190 + * cvmx_helper_link_autoconf() instead.
9191 + *
9192 + * @ipd_port: IPD/PKO port to configure
9193 + * @link_info: The new link state
9194 + *
9195 + * Returns Zero on success, negative on failure
9196 + */
9197 +int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
9198 +{
9199 + /* Nothing to do. If we have a SPI4000 then the setup was already performed
9200 + by cvmx_spi4000_check_speed(). If not then there isn't any link
9201 + info */
9202 + return 0;
9203 +}
9204 --- /dev/null
9205 +++ b/drivers/staging/octeon/cvmx-helper-spi.h
9206 @@ -0,0 +1,84 @@
9207 +/***********************license start***************
9208 + * Author: Cavium Networks
9209 + *
9210 + * Contact: support@caviumnetworks.com
9211 + * This file is part of the OCTEON SDK
9212 + *
9213 + * Copyright (c) 2003-2008 Cavium Networks
9214 + *
9215 + * This file is free software; you can redistribute it and/or modify
9216 + * it under the terms of the GNU General Public License, Version 2, as
9217 + * published by the Free Software Foundation.
9218 + *
9219 + * This file is distributed in the hope that it will be useful, but
9220 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9221 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9222 + * NONINFRINGEMENT. See the GNU General Public License for more
9223 + * details.
9224 + *
9225 + * You should have received a copy of the GNU General Public License
9226 + * along with this file; if not, write to the Free Software
9227 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9228 + * or visit http://www.gnu.org/licenses/.
9229 + *
9230 + * This file may also be available under a different license from Cavium.
9231 + * Contact Cavium Networks for more information
9232 + ***********************license end**************************************/
9233 +
9234 +/*
9235 + * Functions for SPI initialization, configuration,
9236 + * and monitoring.
9237 + */
9238 +#ifndef __CVMX_HELPER_SPI_H__
9239 +#define __CVMX_HELPER_SPI_H__
9240 +
9241 +/**
9242 + * Probe a SPI interface and determine the number of ports
9243 + * connected to it. The SPI interface should still be down after
9244 + * this call.
9245 + *
9246 + * @interface: Interface to probe
9247 + *
9248 + * Returns Number of ports on the interface. Zero to disable.
9249 + */
9250 +extern int __cvmx_helper_spi_probe(int interface);
9251 +
9252 +/**
9253 + * Bringup and enable a SPI interface. After this call packet I/O
9254 + * should be fully functional. This is called with IPD enabled but
9255 + * PKO disabled.
9256 + *
9257 + * @interface: Interface to bring up
9258 + *
9259 + * Returns Zero on success, negative on failure
9260 + */
9261 +extern int __cvmx_helper_spi_enable(int interface);
9262 +
9263 +/**
9264 + * Return the link state of an IPD/PKO port as returned by
9265 + * auto negotiation. The result of this function may not match
9266 + * Octeon's link config if auto negotiation has changed since
9267 + * the last call to cvmx_helper_link_set().
9268 + *
9269 + * @ipd_port: IPD/PKO port to query
9270 + *
9271 + * Returns Link state
9272 + */
9273 +extern cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port);
9274 +
9275 +/**
9276 + * Configure an IPD/PKO port for the specified link state. This
9277 + * function does not influence auto negotiation at the PHY level.
9278 + * The passed link state must always match the link state returned
9279 + * by cvmx_helper_link_get(). It is normally best to use
9280 + * cvmx_helper_link_autoconf() instead.
9281 + *
9282 + * @ipd_port: IPD/PKO port to configure
9283 + * @link_info: The new link state
9284 + *
9285 + * Returns Zero on success, negative on failure
9286 + */
9287 +extern int __cvmx_helper_spi_link_set(int ipd_port,
9288 + cvmx_helper_link_info_t link_info);
9289 +
9290 +#endif
9291 --- /dev/null
9292 +++ b/drivers/staging/octeon/cvmx-helper-util.c
9293 @@ -0,0 +1,433 @@
9294 +/***********************license start***************
9295 + * Author: Cavium Networks
9296 + *
9297 + * Contact: support@caviumnetworks.com
9298 + * This file is part of the OCTEON SDK
9299 + *
9300 + * Copyright (c) 2003-2008 Cavium Networks
9301 + *
9302 + * This file is free software; you can redistribute it and/or modify
9303 + * it under the terms of the GNU General Public License, Version 2, as
9304 + * published by the Free Software Foundation.
9305 + *
9306 + * This file is distributed in the hope that it will be useful, but
9307 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9308 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9309 + * NONINFRINGEMENT. See the GNU General Public License for more
9310 + * details.
9311 + *
9312 + * You should have received a copy of the GNU General Public License
9313 + * along with this file; if not, write to the Free Software
9314 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9315 + * or visit http://www.gnu.org/licenses/.
9316 + *
9317 + * This file may also be available under a different license from Cavium.
9318 + * Contact Cavium Networks for more information
9319 + ***********************license end**************************************/
9320 +
9321 +/*
9322 + * Small helper utilities.
9323 + */
9324 +#include <linux/kernel.h>
9325 +
9326 +#include <asm/octeon/octeon.h>
9327 +
9328 +#include "cvmx-config.h"
9329 +
9330 +#include "cvmx-fpa.h"
9331 +#include "cvmx-pip.h"
9332 +#include "cvmx-pko.h"
9333 +#include "cvmx-ipd.h"
9334 +#include "cvmx-spi.h"
9335 +
9336 +#include "cvmx-helper.h"
9337 +#include "cvmx-helper-util.h"
9338 +
9339 +#include <asm/octeon/cvmx-ipd-defs.h>
9340 +
9341 +/**
9342 + * Convert a interface mode into a human readable string
9343 + *
9344 + * @mode: Mode to convert
9345 + *
9346 + * Returns String
9347 + */
9348 +const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t
9349 + mode)
9350 +{
9351 + switch (mode) {
9352 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
9353 + return "DISABLED";
9354 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
9355 + return "RGMII";
9356 + case CVMX_HELPER_INTERFACE_MODE_GMII:
9357 + return "GMII";
9358 + case CVMX_HELPER_INTERFACE_MODE_SPI:
9359 + return "SPI";
9360 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
9361 + return "PCIE";
9362 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
9363 + return "XAUI";
9364 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
9365 + return "SGMII";
9366 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
9367 + return "PICMG";
9368 + case CVMX_HELPER_INTERFACE_MODE_NPI:
9369 + return "NPI";
9370 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
9371 + return "LOOP";
9372 + }
9373 + return "UNKNOWN";
9374 +}
9375 +
9376 +/**
9377 + * Debug routine to dump the packet structure to the console
9378 + *
9379 + * @work: Work queue entry containing the packet to dump
9380 + * Returns
9381 + */
9382 +int cvmx_helper_dump_packet(cvmx_wqe_t *work)
9383 +{
9384 + uint64_t count;
9385 + uint64_t remaining_bytes;
9386 + union cvmx_buf_ptr buffer_ptr;
9387 + uint64_t start_of_buffer;
9388 + uint8_t *data_address;
9389 + uint8_t *end_of_data;
9390 +
9391 + cvmx_dprintf("Packet Length: %u\n", work->len);
9392 + cvmx_dprintf(" Input Port: %u\n", work->ipprt);
9393 + cvmx_dprintf(" QoS: %u\n", work->qos);
9394 + cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs);
9395 +
9396 + if (work->word2.s.bufs == 0) {
9397 + union cvmx_ipd_wqe_fpa_queue wqe_pool;
9398 + wqe_pool.u64 = cvmx_read_csr(CVMX_IPD_WQE_FPA_QUEUE);
9399 + buffer_ptr.u64 = 0;
9400 + buffer_ptr.s.pool = wqe_pool.s.wqe_pool;
9401 + buffer_ptr.s.size = 128;
9402 + buffer_ptr.s.addr = cvmx_ptr_to_phys(work->packet_data);
9403 + if (likely(!work->word2.s.not_IP)) {
9404 + union cvmx_pip_ip_offset pip_ip_offset;
9405 + pip_ip_offset.u64 = cvmx_read_csr(CVMX_PIP_IP_OFFSET);
9406 + buffer_ptr.s.addr +=
9407 + (pip_ip_offset.s.offset << 3) -
9408 + work->word2.s.ip_offset;
9409 + buffer_ptr.s.addr += (work->word2.s.is_v6 ^ 1) << 2;
9410 + } else {
9411 + /*
9412 + * WARNING: This code assumes that the packet
9413 + * is not RAW. If it was, we would use
9414 + * PIP_GBL_CFG[RAW_SHF] instead of
9415 + * PIP_GBL_CFG[NIP_SHF].
9416 + */
9417 + union cvmx_pip_gbl_cfg pip_gbl_cfg;
9418 + pip_gbl_cfg.u64 = cvmx_read_csr(CVMX_PIP_GBL_CFG);
9419 + buffer_ptr.s.addr += pip_gbl_cfg.s.nip_shf;
9420 + }
9421 + } else
9422 + buffer_ptr = work->packet_ptr;
9423 + remaining_bytes = work->len;
9424 +
9425 + while (remaining_bytes) {
9426 + start_of_buffer =
9427 + ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9428 + cvmx_dprintf(" Buffer Start:%llx\n",
9429 + (unsigned long long)start_of_buffer);
9430 + cvmx_dprintf(" Buffer I : %u\n", buffer_ptr.s.i);
9431 + cvmx_dprintf(" Buffer Back: %u\n", buffer_ptr.s.back);
9432 + cvmx_dprintf(" Buffer Pool: %u\n", buffer_ptr.s.pool);
9433 + cvmx_dprintf(" Buffer Data: %llx\n",
9434 + (unsigned long long)buffer_ptr.s.addr);
9435 + cvmx_dprintf(" Buffer Size: %u\n", buffer_ptr.s.size);
9436 +
9437 + cvmx_dprintf("\t\t");
9438 + data_address = (uint8_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr);
9439 + end_of_data = data_address + buffer_ptr.s.size;
9440 + count = 0;
9441 + while (data_address < end_of_data) {
9442 + if (remaining_bytes == 0)
9443 + break;
9444 + else
9445 + remaining_bytes--;
9446 + cvmx_dprintf("%02x", (unsigned int)*data_address);
9447 + data_address++;
9448 + if (remaining_bytes && (count == 7)) {
9449 + cvmx_dprintf("\n\t\t");
9450 + count = 0;
9451 + } else
9452 + count++;
9453 + }
9454 + cvmx_dprintf("\n");
9455 +
9456 + if (remaining_bytes)
9457 + buffer_ptr = *(union cvmx_buf_ptr *)
9458 + cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9459 + }
9460 + return 0;
9461 +}
9462 +
9463 +/**
9464 + * Setup Random Early Drop on a specific input queue
9465 + *
9466 + * @queue: Input queue to setup RED on (0-7)
9467 + * @pass_thresh:
9468 + * Packets will begin slowly dropping when there are less than
9469 + * this many packet buffers free in FPA 0.
9470 + * @drop_thresh:
9471 + * All incomming packets will be dropped when there are less
9472 + * than this many free packet buffers in FPA 0.
9473 + * Returns Zero on success. Negative on failure
9474 + */
9475 +int cvmx_helper_setup_red_queue(int queue, int pass_thresh, int drop_thresh)
9476 +{
9477 + union cvmx_ipd_qosx_red_marks red_marks;
9478 + union cvmx_ipd_red_quex_param red_param;
9479 +
9480 + /* Set RED to begin dropping packets when there are pass_thresh buffers
9481 + left. It will linearly drop more packets until reaching drop_thresh
9482 + buffers */
9483 + red_marks.u64 = 0;
9484 + red_marks.s.drop = drop_thresh;
9485 + red_marks.s.pass = pass_thresh;
9486 + cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64);
9487 +
9488 + /* Use the actual queue 0 counter, not the average */
9489 + red_param.u64 = 0;
9490 + red_param.s.prb_con =
9491 + (255ul << 24) / (red_marks.s.pass - red_marks.s.drop);
9492 + red_param.s.avg_con = 1;
9493 + red_param.s.new_con = 255;
9494 + red_param.s.use_pcnt = 1;
9495 + cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64);
9496 + return 0;
9497 +}
9498 +
9499 +/**
9500 + * Setup Random Early Drop to automatically begin dropping packets.
9501 + *
9502 + * @pass_thresh:
9503 + * Packets will begin slowly dropping when there are less than
9504 + * this many packet buffers free in FPA 0.
9505 + * @drop_thresh:
9506 + * All incomming packets will be dropped when there are less
9507 + * than this many free packet buffers in FPA 0.
9508 + * Returns Zero on success. Negative on failure
9509 + */
9510 +int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
9511 +{
9512 + union cvmx_ipd_portx_bp_page_cnt page_cnt;
9513 + union cvmx_ipd_bp_prt_red_end ipd_bp_prt_red_end;
9514 + union cvmx_ipd_red_port_enable red_port_enable;
9515 + int queue;
9516 + int interface;
9517 + int port;
9518 +
9519 + /* Disable backpressure based on queued buffers. It needs SW support */
9520 + page_cnt.u64 = 0;
9521 + page_cnt.s.bp_enb = 0;
9522 + page_cnt.s.page_cnt = 100;
9523 + for (interface = 0; interface < 2; interface++) {
9524 + for (port = cvmx_helper_get_first_ipd_port(interface);
9525 + port < cvmx_helper_get_last_ipd_port(interface); port++)
9526 + cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port),
9527 + page_cnt.u64);
9528 + }
9529 +
9530 + for (queue = 0; queue < 8; queue++)
9531 + cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh);
9532 +
9533 + /* Shutoff the dropping based on the per port page count. SW isn't
9534 + decrementing it right now */
9535 + ipd_bp_prt_red_end.u64 = 0;
9536 + ipd_bp_prt_red_end.s.prt_enb = 0;
9537 + cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64);
9538 +
9539 + red_port_enable.u64 = 0;
9540 + red_port_enable.s.prt_enb = 0xfffffffffull;
9541 + red_port_enable.s.avg_dly = 10000;
9542 + red_port_enable.s.prb_dly = 10000;
9543 + cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64);
9544 +
9545 + return 0;
9546 +}
9547 +
9548 +/**
9549 + * Setup the common GMX settings that determine the number of
9550 + * ports. These setting apply to almost all configurations of all
9551 + * chips.
9552 + *
9553 + * @interface: Interface to configure
9554 + * @num_ports: Number of ports on the interface
9555 + *
9556 + * Returns Zero on success, negative on failure
9557 + */
9558 +int __cvmx_helper_setup_gmx(int interface, int num_ports)
9559 +{
9560 + union cvmx_gmxx_tx_prts gmx_tx_prts;
9561 + union cvmx_gmxx_rx_prts gmx_rx_prts;
9562 + union cvmx_pko_reg_gmx_port_mode pko_mode;
9563 + union cvmx_gmxx_txx_thresh gmx_tx_thresh;
9564 + int index;
9565 +
9566 + /* Tell GMX the number of TX ports on this interface */
9567 + gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface));
9568 + gmx_tx_prts.s.prts = num_ports;
9569 + cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64);
9570 +
9571 + /* Tell GMX the number of RX ports on this interface. This only
9572 + ** applies to *GMII and XAUI ports */
9573 + if (cvmx_helper_interface_get_mode(interface) ==
9574 + CVMX_HELPER_INTERFACE_MODE_RGMII
9575 + || cvmx_helper_interface_get_mode(interface) ==
9576 + CVMX_HELPER_INTERFACE_MODE_SGMII
9577 + || cvmx_helper_interface_get_mode(interface) ==
9578 + CVMX_HELPER_INTERFACE_MODE_GMII
9579 + || cvmx_helper_interface_get_mode(interface) ==
9580 + CVMX_HELPER_INTERFACE_MODE_XAUI) {
9581 + if (num_ports > 4) {
9582 + cvmx_dprintf("__cvmx_helper_setup_gmx: Illegal "
9583 + "num_ports\n");
9584 + return -1;
9585 + }
9586 +
9587 + gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface));
9588 + gmx_rx_prts.s.prts = num_ports;
9589 + cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64);
9590 + }
9591 +
9592 + /* Skip setting CVMX_PKO_REG_GMX_PORT_MODE on 30XX, 31XX, and 50XX */
9593 + if (!OCTEON_IS_MODEL(OCTEON_CN30XX) && !OCTEON_IS_MODEL(OCTEON_CN31XX)
9594 + && !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
9595 + /* Tell PKO the number of ports on this interface */
9596 + pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE);
9597 + if (interface == 0) {
9598 + if (num_ports == 1)
9599 + pko_mode.s.mode0 = 4;
9600 + else if (num_ports == 2)
9601 + pko_mode.s.mode0 = 3;
9602 + else if (num_ports <= 4)
9603 + pko_mode.s.mode0 = 2;
9604 + else if (num_ports <= 8)
9605 + pko_mode.s.mode0 = 1;
9606 + else
9607 + pko_mode.s.mode0 = 0;
9608 + } else {
9609 + if (num_ports == 1)
9610 + pko_mode.s.mode1 = 4;
9611 + else if (num_ports == 2)
9612 + pko_mode.s.mode1 = 3;
9613 + else if (num_ports <= 4)
9614 + pko_mode.s.mode1 = 2;
9615 + else if (num_ports <= 8)
9616 + pko_mode.s.mode1 = 1;
9617 + else
9618 + pko_mode.s.mode1 = 0;
9619 + }
9620 + cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64);
9621 + }
9622 +
9623 + /*
9624 + * Set GMX to buffer as much data as possible before starting
9625 + * transmit. This reduces the chances that we have a TX under
9626 + * run due to memory contention. Any packet that fits entirely
9627 + * in the GMX FIFO can never have an under run regardless of
9628 + * memory load.
9629 + */
9630 + gmx_tx_thresh.u64 = cvmx_read_csr(CVMX_GMXX_TXX_THRESH(0, interface));
9631 + if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX)
9632 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
9633 + /* These chips have a fixed max threshold of 0x40 */
9634 + gmx_tx_thresh.s.cnt = 0x40;
9635 + } else {
9636 + /* Choose the max value for the number of ports */
9637 + if (num_ports <= 1)
9638 + gmx_tx_thresh.s.cnt = 0x100 / 1;
9639 + else if (num_ports == 2)
9640 + gmx_tx_thresh.s.cnt = 0x100 / 2;
9641 + else
9642 + gmx_tx_thresh.s.cnt = 0x100 / 4;
9643 + }
9644 + /*
9645 + * SPI and XAUI can have lots of ports but the GMX hardware
9646 + * only ever has a max of 4.
9647 + */
9648 + if (num_ports > 4)
9649 + num_ports = 4;
9650 + for (index = 0; index < num_ports; index++)
9651 + cvmx_write_csr(CVMX_GMXX_TXX_THRESH(index, interface),
9652 + gmx_tx_thresh.u64);
9653 +
9654 + return 0;
9655 +}
9656 +
9657 +/**
9658 + * Returns the IPD/PKO port number for a port on teh given
9659 + * interface.
9660 + *
9661 + * @interface: Interface to use
9662 + * @port: Port on the interface
9663 + *
9664 + * Returns IPD/PKO port number
9665 + */
9666 +int cvmx_helper_get_ipd_port(int interface, int port)
9667 +{
9668 + switch (interface) {
9669 + case 0:
9670 + return port;
9671 + case 1:
9672 + return port + 16;
9673 + case 2:
9674 + return port + 32;
9675 + case 3:
9676 + return port + 36;
9677 + }
9678 + return -1;
9679 +}
9680 +
9681 +/**
9682 + * Returns the interface number for an IPD/PKO port number.
9683 + *
9684 + * @ipd_port: IPD/PKO port number
9685 + *
9686 + * Returns Interface number
9687 + */
9688 +int cvmx_helper_get_interface_num(int ipd_port)
9689 +{
9690 + if (ipd_port < 16)
9691 + return 0;
9692 + else if (ipd_port < 32)
9693 + return 1;
9694 + else if (ipd_port < 36)
9695 + return 2;
9696 + else if (ipd_port < 40)
9697 + return 3;
9698 + else
9699 + cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "
9700 + "port number\n");
9701 +
9702 + return -1;
9703 +}
9704 +
9705 +/**
9706 + * Returns the interface index number for an IPD/PKO port
9707 + * number.
9708 + *
9709 + * @ipd_port: IPD/PKO port number
9710 + *
9711 + * Returns Interface index number
9712 + */
9713 +int cvmx_helper_get_interface_index_num(int ipd_port)
9714 +{
9715 + if (ipd_port < 32)
9716 + return ipd_port & 15;
9717 + else if (ipd_port < 36)
9718 + return ipd_port & 3;
9719 + else if (ipd_port < 40)
9720 + return ipd_port & 3;
9721 + else
9722 + cvmx_dprintf("cvmx_helper_get_interface_index_num: "
9723 + "Illegal IPD port number\n");
9724 +
9725 + return -1;
9726 +}
9727 --- /dev/null
9728 +++ b/drivers/staging/octeon/cvmx-helper-util.h
9729 @@ -0,0 +1,215 @@
9730 +/***********************license start***************
9731 + * Author: Cavium Networks
9732 + *
9733 + * Contact: support@caviumnetworks.com
9734 + * This file is part of the OCTEON SDK
9735 + *
9736 + * Copyright (c) 2003-2008 Cavium Networks
9737 + *
9738 + * This file is free software; you can redistribute it and/or modify
9739 + * it under the terms of the GNU General Public License, Version 2, as
9740 + * published by the Free Software Foundation.
9741 + *
9742 + * This file is distributed in the hope that it will be useful, but
9743 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9744 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9745 + * NONINFRINGEMENT. See the GNU General Public License for more
9746 + * details.
9747 + *
9748 + * You should have received a copy of the GNU General Public License
9749 + * along with this file; if not, write to the Free Software
9750 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9751 + * or visit http://www.gnu.org/licenses/.
9752 + *
9753 + * This file may also be available under a different license from Cavium.
9754 + * Contact Cavium Networks for more information
9755 + ***********************license end**************************************/
9756 +
9757 +/*
9758 + *
9759 + * Small helper utilities.
9760 + *
9761 + */
9762 +
9763 +#ifndef __CVMX_HELPER_UTIL_H__
9764 +#define __CVMX_HELPER_UTIL_H__
9765 +
9766 +/**
9767 + * Convert a interface mode into a human readable string
9768 + *
9769 + * @mode: Mode to convert
9770 + *
9771 + * Returns String
9772 + */
9773 +extern const char
9774 + *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode);
9775 +
9776 +/**
9777 + * Debug routine to dump the packet structure to the console
9778 + *
9779 + * @work: Work queue entry containing the packet to dump
9780 + * Returns
9781 + */
9782 +extern int cvmx_helper_dump_packet(cvmx_wqe_t *work);
9783 +
9784 +/**
9785 + * Setup Random Early Drop on a specific input queue
9786 + *
9787 + * @queue: Input queue to setup RED on (0-7)
9788 + * @pass_thresh:
9789 + * Packets will begin slowly dropping when there are less than
9790 + * this many packet buffers free in FPA 0.
9791 + * @drop_thresh:
9792 + * All incomming packets will be dropped when there are less
9793 + * than this many free packet buffers in FPA 0.
9794 + * Returns Zero on success. Negative on failure
9795 + */
9796 +extern int cvmx_helper_setup_red_queue(int queue, int pass_thresh,
9797 + int drop_thresh);
9798 +
9799 +/**
9800 + * Setup Random Early Drop to automatically begin dropping packets.
9801 + *
9802 + * @pass_thresh:
9803 + * Packets will begin slowly dropping when there are less than
9804 + * this many packet buffers free in FPA 0.
9805 + * @drop_thresh:
9806 + * All incomming packets will be dropped when there are less
9807 + * than this many free packet buffers in FPA 0.
9808 + * Returns Zero on success. Negative on failure
9809 + */
9810 +extern int cvmx_helper_setup_red(int pass_thresh, int drop_thresh);
9811 +
9812 +/**
9813 + * Get the version of the CVMX libraries.
9814 + *
9815 + * Returns Version string. Note this buffer is allocated statically
9816 + * and will be shared by all callers.
9817 + */
9818 +extern const char *cvmx_helper_get_version(void);
9819 +
9820 +/**
9821 + * Setup the common GMX settings that determine the number of
9822 + * ports. These setting apply to almost all configurations of all
9823 + * chips.
9824 + *
9825 + * @interface: Interface to configure
9826 + * @num_ports: Number of ports on the interface
9827 + *
9828 + * Returns Zero on success, negative on failure
9829 + */
9830 +extern int __cvmx_helper_setup_gmx(int interface, int num_ports);
9831 +
9832 +/**
9833 + * Returns the IPD/PKO port number for a port on the given
9834 + * interface.
9835 + *
9836 + * @interface: Interface to use
9837 + * @port: Port on the interface
9838 + *
9839 + * Returns IPD/PKO port number
9840 + */
9841 +extern int cvmx_helper_get_ipd_port(int interface, int port);
9842 +
9843 +/**
9844 + * Returns the IPD/PKO port number for the first port on the given
9845 + * interface.
9846 + *
9847 + * @interface: Interface to use
9848 + *
9849 + * Returns IPD/PKO port number
9850 + */
9851 +static inline int cvmx_helper_get_first_ipd_port(int interface)
9852 +{
9853 + return cvmx_helper_get_ipd_port(interface, 0);
9854 +}
9855 +
9856 +/**
9857 + * Returns the IPD/PKO port number for the last port on the given
9858 + * interface.
9859 + *
9860 + * @interface: Interface to use
9861 + *
9862 + * Returns IPD/PKO port number
9863 + */
9864 +static inline int cvmx_helper_get_last_ipd_port(int interface)
9865 +{
9866 + extern int cvmx_helper_ports_on_interface(int interface);
9867 +
9868 + return cvmx_helper_get_first_ipd_port(interface) +
9869 + cvmx_helper_ports_on_interface(interface) - 1;
9870 +}
9871 +
9872 +/**
9873 + * Free the packet buffers contained in a work queue entry.
9874 + * The work queue entry is not freed.
9875 + *
9876 + * @work: Work queue entry with packet to free
9877 + */
9878 +static inline void cvmx_helper_free_packet_data(cvmx_wqe_t *work)
9879 +{
9880 + uint64_t number_buffers;
9881 + union cvmx_buf_ptr buffer_ptr;
9882 + union cvmx_buf_ptr next_buffer_ptr;
9883 + uint64_t start_of_buffer;
9884 +
9885 + number_buffers = work->word2.s.bufs;
9886 + if (number_buffers == 0)
9887 + return;
9888 + buffer_ptr = work->packet_ptr;
9889 +
9890 + /*
9891 + * Since the number of buffers is not zero, we know this is
9892 + * not a dynamic short packet. We need to check if it is a
9893 + * packet received with IPD_CTL_STATUS[NO_WPTR]. If this is
9894 + * true, we need to free all buffers except for the first
9895 + * one. The caller doesn't expect their WQE pointer to be
9896 + * freed
9897 + */
9898 + start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9899 + if (cvmx_ptr_to_phys(work) == start_of_buffer) {
9900 + next_buffer_ptr =
9901 + *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9902 + buffer_ptr = next_buffer_ptr;
9903 + number_buffers--;
9904 + }
9905 +
9906 + while (number_buffers--) {
9907 + /*
9908 + * Remember the back pointer is in cache lines, not
9909 + * 64bit words
9910 + */
9911 + start_of_buffer =
9912 + ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9913 + /*
9914 + * Read pointer to next buffer before we free the
9915 + * current buffer.
9916 + */
9917 + next_buffer_ptr =
9918 + *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9919 + cvmx_fpa_free(cvmx_phys_to_ptr(start_of_buffer),
9920 + buffer_ptr.s.pool, 0);
9921 + buffer_ptr = next_buffer_ptr;
9922 + }
9923 +}
9924 +
9925 +/**
9926 + * Returns the interface number for an IPD/PKO port number.
9927 + *
9928 + * @ipd_port: IPD/PKO port number
9929 + *
9930 + * Returns Interface number
9931 + */
9932 +extern int cvmx_helper_get_interface_num(int ipd_port);
9933 +
9934 +/**
9935 + * Returns the interface index number for an IPD/PKO port
9936 + * number.
9937 + *
9938 + * @ipd_port: IPD/PKO port number
9939 + *
9940 + * Returns Interface index number
9941 + */
9942 +extern int cvmx_helper_get_interface_index_num(int ipd_port);
9943 +
9944 +#endif /* __CVMX_HELPER_H__ */
9945 --- /dev/null
9946 +++ b/drivers/staging/octeon/cvmx-helper-xaui.c
9947 @@ -0,0 +1,348 @@
9948 +/***********************license start***************
9949 + * Author: Cavium Networks
9950 + *
9951 + * Contact: support@caviumnetworks.com
9952 + * This file is part of the OCTEON SDK
9953 + *
9954 + * Copyright (c) 2003-2008 Cavium Networks
9955 + *
9956 + * This file is free software; you can redistribute it and/or modify
9957 + * it under the terms of the GNU General Public License, Version 2, as
9958 + * published by the Free Software Foundation.
9959 + *
9960 + * This file is distributed in the hope that it will be useful, but
9961 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9962 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9963 + * NONINFRINGEMENT. See the GNU General Public License for more
9964 + * details.
9965 + *
9966 + * You should have received a copy of the GNU General Public License
9967 + * along with this file; if not, write to the Free Software
9968 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9969 + * or visit http://www.gnu.org/licenses/.
9970 + *
9971 + * This file may also be available under a different license from Cavium.
9972 + * Contact Cavium Networks for more information
9973 + ***********************license end**************************************/
9974 +
9975 +/*
9976 + * Functions for XAUI initialization, configuration,
9977 + * and monitoring.
9978 + *
9979 + */
9980 +
9981 +#include <asm/octeon/octeon.h>
9982 +
9983 +#include "cvmx-config.h"
9984 +
9985 +#include "cvmx-helper.h"
9986 +
9987 +#include "cvmx-pko-defs.h"
9988 +#include "cvmx-gmxx-defs.h"
9989 +#include "cvmx-pcsxx-defs.h"
9990 +
9991 +void __cvmx_interrupt_gmxx_enable(int interface);
9992 +void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
9993 +void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
9994 +/**
9995 + * Probe a XAUI interface and determine the number of ports
9996 + * connected to it. The XAUI interface should still be down
9997 + * after this call.
9998 + *
9999 + * @interface: Interface to probe
10000 + *
10001 + * Returns Number of ports on the interface. Zero to disable.
10002 + */
10003 +int __cvmx_helper_xaui_probe(int interface)
10004 +{
10005 + int i;
10006 + union cvmx_gmxx_hg2_control gmx_hg2_control;
10007 + union cvmx_gmxx_inf_mode mode;
10008 +
10009 + /*
10010 + * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
10011 + * interface needs to be enabled before IPD otherwise per port
10012 + * backpressure may not work properly.
10013 + */
10014 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
10015 + mode.s.en = 1;
10016 + cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
10017 +
10018 + __cvmx_helper_setup_gmx(interface, 1);
10019 +
10020 + /*
10021 + * Setup PKO to support 16 ports for HiGig2 virtual
10022 + * ports. We're pointing all of the PKO packet ports for this
10023 + * interface to the XAUI. This allows us to use HiGig2
10024 + * backpressure per port.
10025 + */
10026 + for (i = 0; i < 16; i++) {
10027 + union cvmx_pko_mem_port_ptrs pko_mem_port_ptrs;
10028 + pko_mem_port_ptrs.u64 = 0;
10029 + /*
10030 + * We set each PKO port to have equal priority in a
10031 + * round robin fashion.
10032 + */
10033 + pko_mem_port_ptrs.s.static_p = 0;
10034 + pko_mem_port_ptrs.s.qos_mask = 0xff;
10035 + /* All PKO ports map to the same XAUI hardware port */
10036 + pko_mem_port_ptrs.s.eid = interface * 4;
10037 + pko_mem_port_ptrs.s.pid = interface * 16 + i;
10038 + cvmx_write_csr(CVMX_PKO_MEM_PORT_PTRS, pko_mem_port_ptrs.u64);
10039 + }
10040 +
10041 + /* If HiGig2 is enabled return 16 ports, otherwise return 1 port */
10042 + gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface));
10043 + if (gmx_hg2_control.s.hg2tx_en)
10044 + return 16;
10045 + else
10046 + return 1;
10047 +}
10048 +
10049 +/**
10050 + * Bringup and enable a XAUI interface. After this call packet
10051 + * I/O should be fully functional. This is called with IPD
10052 + * enabled but PKO disabled.
10053 + *
10054 + * @interface: Interface to bring up
10055 + *
10056 + * Returns Zero on success, negative on failure
10057 + */
10058 +int __cvmx_helper_xaui_enable(int interface)
10059 +{
10060 + union cvmx_gmxx_prtx_cfg gmx_cfg;
10061 + union cvmx_pcsxx_control1_reg xauiCtl;
10062 + union cvmx_pcsxx_misc_ctl_reg xauiMiscCtl;
10063 + union cvmx_gmxx_tx_xaui_ctl gmxXauiTxCtl;
10064 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
10065 + union cvmx_gmxx_tx_int_en gmx_tx_int_en;
10066 + union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
10067 +
10068 + /* (1) Interface has already been enabled. */
10069 +
10070 + /* (2) Disable GMX. */
10071 + xauiMiscCtl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface));
10072 + xauiMiscCtl.s.gmxeno = 1;
10073 + cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
10074 +
10075 + /* (3) Disable GMX and PCSX interrupts. */
10076 + gmx_rx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_EN(0, interface));
10077 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
10078 + gmx_tx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_TX_INT_EN(interface));
10079 + cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
10080 + pcsx_int_en_reg.u64 = cvmx_read_csr(CVMX_PCSXX_INT_EN_REG(interface));
10081 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
10082 +
10083 + /* (4) Bring up the PCSX and GMX reconciliation layer. */
10084 + /* (4)a Set polarity and lane swapping. */
10085 + /* (4)b */
10086 + gmxXauiTxCtl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10087 + /* Enable better IFG packing and improves performance */
10088 + gmxXauiTxCtl.s.dic_en = 1;
10089 + gmxXauiTxCtl.s.uni_en = 0;
10090 + cvmx_write_csr(CVMX_GMXX_TX_XAUI_CTL(interface), gmxXauiTxCtl.u64);
10091 +
10092 + /* (4)c Aply reset sequence */
10093 + xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
10094 + xauiCtl.s.lo_pwr = 0;
10095 + xauiCtl.s.reset = 1;
10096 + cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
10097 +
10098 + /* Wait for PCS to come out of reset */
10099 + if (CVMX_WAIT_FOR_FIELD64
10100 + (CVMX_PCSXX_CONTROL1_REG(interface), union cvmx_pcsxx_control1_reg,
10101 + reset, ==, 0, 10000))
10102 + return -1;
10103 + /* Wait for PCS to be aligned */
10104 + if (CVMX_WAIT_FOR_FIELD64
10105 + (CVMX_PCSXX_10GBX_STATUS_REG(interface),
10106 + union cvmx_pcsxx_10gbx_status_reg, alignd, ==, 1, 10000))
10107 + return -1;
10108 + /* Wait for RX to be ready */
10109 + if (CVMX_WAIT_FOR_FIELD64
10110 + (CVMX_GMXX_RX_XAUI_CTL(interface), union cvmx_gmxx_rx_xaui_ctl,
10111 + status, ==, 0, 10000))
10112 + return -1;
10113 +
10114 + /* (6) Configure GMX */
10115 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10116 + gmx_cfg.s.en = 0;
10117 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10118 +
10119 + /* Wait for GMX RX to be idle */
10120 + if (CVMX_WAIT_FOR_FIELD64
10121 + (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
10122 + rx_idle, ==, 1, 10000))
10123 + return -1;
10124 + /* Wait for GMX TX to be idle */
10125 + if (CVMX_WAIT_FOR_FIELD64
10126 + (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
10127 + tx_idle, ==, 1, 10000))
10128 + return -1;
10129 +
10130 + /* GMX configure */
10131 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10132 + gmx_cfg.s.speed = 1;
10133 + gmx_cfg.s.speed_msb = 0;
10134 + gmx_cfg.s.slottime = 1;
10135 + cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), 1);
10136 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(0, interface), 512);
10137 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(0, interface), 8192);
10138 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10139 +
10140 + /* (7) Clear out any error state */
10141 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(0, interface),
10142 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(0, interface)));
10143 + cvmx_write_csr(CVMX_GMXX_TX_INT_REG(interface),
10144 + cvmx_read_csr(CVMX_GMXX_TX_INT_REG(interface)));
10145 + cvmx_write_csr(CVMX_PCSXX_INT_REG(interface),
10146 + cvmx_read_csr(CVMX_PCSXX_INT_REG(interface)));
10147 +
10148 + /* Wait for receive link */
10149 + if (CVMX_WAIT_FOR_FIELD64
10150 + (CVMX_PCSXX_STATUS1_REG(interface), union cvmx_pcsxx_status1_reg,
10151 + rcv_lnk, ==, 1, 10000))
10152 + return -1;
10153 + if (CVMX_WAIT_FOR_FIELD64
10154 + (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
10155 + xmtflt, ==, 0, 10000))
10156 + return -1;
10157 + if (CVMX_WAIT_FOR_FIELD64
10158 + (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
10159 + rcvflt, ==, 0, 10000))
10160 + return -1;
10161 +
10162 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), gmx_rx_int_en.u64);
10163 + cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
10164 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64);
10165 +
10166 + cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port(interface, 0));
10167 +
10168 + /* (8) Enable packet reception */
10169 + xauiMiscCtl.s.gmxeno = 0;
10170 + cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
10171 +
10172 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10173 + gmx_cfg.s.en = 1;
10174 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10175 +
10176 + __cvmx_interrupt_pcsx_intx_en_reg_enable(0, interface);
10177 + __cvmx_interrupt_pcsx_intx_en_reg_enable(1, interface);
10178 + __cvmx_interrupt_pcsx_intx_en_reg_enable(2, interface);
10179 + __cvmx_interrupt_pcsx_intx_en_reg_enable(3, interface);
10180 + __cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
10181 + __cvmx_interrupt_gmxx_enable(interface);
10182 +
10183 + return 0;
10184 +}
10185 +
10186 +/**
10187 + * Return the link state of an IPD/PKO port as returned by
10188 + * auto negotiation. The result of this function may not match
10189 + * Octeon's link config if auto negotiation has changed since
10190 + * the last call to cvmx_helper_link_set().
10191 + *
10192 + * @ipd_port: IPD/PKO port to query
10193 + *
10194 + * Returns Link state
10195 + */
10196 +cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port)
10197 +{
10198 + int interface = cvmx_helper_get_interface_num(ipd_port);
10199 + union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
10200 + union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
10201 + union cvmx_pcsxx_status1_reg pcsxx_status1_reg;
10202 + cvmx_helper_link_info_t result;
10203 +
10204 + gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10205 + gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
10206 + pcsxx_status1_reg.u64 =
10207 + cvmx_read_csr(CVMX_PCSXX_STATUS1_REG(interface));
10208 + result.u64 = 0;
10209 +
10210 + /* Only return a link if both RX and TX are happy */
10211 + if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0) &&
10212 + (pcsxx_status1_reg.s.rcv_lnk == 1)) {
10213 + result.s.link_up = 1;
10214 + result.s.full_duplex = 1;
10215 + result.s.speed = 10000;
10216 + } else {
10217 + /* Disable GMX and PCSX interrupts. */
10218 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
10219 + cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
10220 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
10221 + }
10222 + return result;
10223 +}
10224 +
10225 +/**
10226 + * Configure an IPD/PKO port for the specified link state. This
10227 + * function does not influence auto negotiation at the PHY level.
10228 + * The passed link state must always match the link state returned
10229 + * by cvmx_helper_link_get(). It is normally best to use
10230 + * cvmx_helper_link_autoconf() instead.
10231 + *
10232 + * @ipd_port: IPD/PKO port to configure
10233 + * @link_info: The new link state
10234 + *
10235 + * Returns Zero on success, negative on failure
10236 + */
10237 +int __cvmx_helper_xaui_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
10238 +{
10239 + int interface = cvmx_helper_get_interface_num(ipd_port);
10240 + union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
10241 + union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
10242 +
10243 + gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10244 + gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
10245 +
10246 + /* If the link shouldn't be up, then just return */
10247 + if (!link_info.s.link_up)
10248 + return 0;
10249 +
10250 + /* Do nothing if both RX and TX are happy */
10251 + if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0))
10252 + return 0;
10253 +
10254 + /* Bring the link up */
10255 + return __cvmx_helper_xaui_enable(interface);
10256 +}
10257 +
10258 +/**
10259 + * Configure a port for internal and/or external loopback. Internal loopback
10260 + * causes packets sent by the port to be received by Octeon. External loopback
10261 + * causes packets received from the wire to sent out again.
10262 + *
10263 + * @ipd_port: IPD/PKO port to loopback.
10264 + * @enable_internal:
10265 + * Non zero if you want internal loopback
10266 + * @enable_external:
10267 + * Non zero if you want external loopback
10268 + *
10269 + * Returns Zero on success, negative on failure.
10270 + */
10271 +extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
10272 + int enable_internal,
10273 + int enable_external)
10274 +{
10275 + int interface = cvmx_helper_get_interface_num(ipd_port);
10276 + union cvmx_pcsxx_control1_reg pcsxx_control1_reg;
10277 + union cvmx_gmxx_xaui_ext_loopback gmxx_xaui_ext_loopback;
10278 +
10279 + /* Set the internal loop */
10280 + pcsxx_control1_reg.u64 =
10281 + cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
10282 + pcsxx_control1_reg.s.loopbck1 = enable_internal;
10283 + cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface),
10284 + pcsxx_control1_reg.u64);
10285 +
10286 + /* Set the external loop */
10287 + gmxx_xaui_ext_loopback.u64 =
10288 + cvmx_read_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface));
10289 + gmxx_xaui_ext_loopback.s.en = enable_external;
10290 + cvmx_write_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface),
10291 + gmxx_xaui_ext_loopback.u64);
10292 +
10293 + /* Take the link through a reset */
10294 + return __cvmx_helper_xaui_enable(interface);
10295 +}
10296 --- /dev/null
10297 +++ b/drivers/staging/octeon/cvmx-helper-xaui.h
10298 @@ -0,0 +1,103 @@
10299 +/***********************license start***************
10300 + * Author: Cavium Networks
10301 + *
10302 + * Contact: support@caviumnetworks.com
10303 + * This file is part of the OCTEON SDK
10304 + *
10305 + * Copyright (c) 2003-2008 Cavium Networks
10306 + *
10307 + * This file is free software; you can redistribute it and/or modify
10308 + * it under the terms of the GNU General Public License, Version 2, as
10309 + * published by the Free Software Foundation.
10310 + *
10311 + * This file is distributed in the hope that it will be useful, but
10312 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
10313 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
10314 + * NONINFRINGEMENT. See the GNU General Public License for more
10315 + * details.
10316 + *
10317 + * You should have received a copy of the GNU General Public License
10318 + * along with this file; if not, write to the Free Software
10319 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10320 + * or visit http://www.gnu.org/licenses/.
10321 + *
10322 + * This file may also be available under a different license from Cavium.
10323 + * Contact Cavium Networks for more information
10324 + ***********************license end**************************************/
10325 +
10326 +/**
10327 + * @file
10328 + *
10329 + * Functions for XAUI initialization, configuration,
10330 + * and monitoring.
10331 + *
10332 + */
10333 +#ifndef __CVMX_HELPER_XAUI_H__
10334 +#define __CVMX_HELPER_XAUI_H__
10335 +
10336 +/**
10337 + * Probe a XAUI interface and determine the number of ports
10338 + * connected to it. The XAUI interface should still be down
10339 + * after this call.
10340 + *
10341 + * @interface: Interface to probe
10342 + *
10343 + * Returns Number of ports on the interface. Zero to disable.
10344 + */
10345 +extern int __cvmx_helper_xaui_probe(int interface);
10346 +
10347 +/**
10348 + * Bringup and enable a XAUI interface. After this call packet
10349 + * I/O should be fully functional. This is called with IPD
10350 + * enabled but PKO disabled.
10351 + *
10352 + * @interface: Interface to bring up
10353 + *
10354 + * Returns Zero on success, negative on failure
10355 + */
10356 +extern int __cvmx_helper_xaui_enable(int interface);
10357 +
10358 +/**
10359 + * Return the link state of an IPD/PKO port as returned by
10360 + * auto negotiation. The result of this function may not match
10361 + * Octeon's link config if auto negotiation has changed since
10362 + * the last call to cvmx_helper_link_set().
10363 + *
10364 + * @ipd_port: IPD/PKO port to query
10365 + *
10366 + * Returns Link state
10367 + */
10368 +extern cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port);
10369 +
10370 +/**
10371 + * Configure an IPD/PKO port for the specified link state. This
10372 + * function does not influence auto negotiation at the PHY level.
10373 + * The passed link state must always match the link state returned
10374 + * by cvmx_helper_link_get(). It is normally best to use
10375 + * cvmx_helper_link_autoconf() instead.
10376 + *
10377 + * @ipd_port: IPD/PKO port to configure
10378 + * @link_info: The new link state
10379 + *
10380 + * Returns Zero on success, negative on failure
10381 + */
10382 +extern int __cvmx_helper_xaui_link_set(int ipd_port,
10383 + cvmx_helper_link_info_t link_info);
10384 +
10385 +/**
10386 + * Configure a port for internal and/or external loopback. Internal loopback
10387 + * causes packets sent by the port to be received by Octeon. External loopback
10388 + * causes packets received from the wire to sent out again.
10389 + *
10390 + * @ipd_port: IPD/PKO port to loopback.
10391 + * @enable_internal:
10392 + * Non zero if you want internal loopback
10393 + * @enable_external:
10394 + * Non zero if you want external loopback
10395 + *
10396 + * Returns Zero on success, negative on failure.
10397 + */
10398 +extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
10399 + int enable_internal,
10400 + int enable_external);
10401 +#endif
10402 --- /dev/null
10403 +++ b/drivers/staging/octeon/cvmx-helper.c
10404 @@ -0,0 +1,1058 @@
10405 +/***********************license start***************
10406 + * Author: Cavium Networks
10407 + *
10408 + * Contact: support@caviumnetworks.com
10409 + * This file is part of the OCTEON SDK
10410 + *
10411 + * Copyright (c) 2003-2008 Cavium Networks
10412 + *
10413 + * This file is free software; you can redistribute it and/or modify
10414 + * it under the terms of the GNU General Public License, Version 2, as
10415 + * published by the Free Software Foundation.
10416 + *
10417 + * This file is distributed in the hope that it will be useful, but
10418 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
10419 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
10420 + * NONINFRINGEMENT. See the GNU General Public License for more
10421 + * details.
10422 + *
10423 + * You should have received a copy of the GNU General Public License
10424 + * along with this file; if not, write to the Free Software
10425 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10426 + * or visit http://www.gnu.org/licenses/.
10427 + *
10428 + * This file may also be available under a different license from Cavium.
10429 + * Contact Cavium Networks for more information
10430 + ***********************license end**************************************/
10431 +
10432 +/*
10433 + *
10434 + * Helper functions for common, but complicated tasks.
10435 + *
10436 + */
10437 +#include <asm/octeon/octeon.h>
10438 +
10439 +#include "cvmx-config.h"
10440 +
10441 +#include "cvmx-fpa.h"
10442 +#include "cvmx-pip.h"
10443 +#include "cvmx-pko.h"
10444 +#include "cvmx-ipd.h"
10445 +#include "cvmx-spi.h"
10446 +#include "cvmx-helper.h"
10447 +#include "cvmx-helper-board.h"
10448 +
10449 +#include "cvmx-pip-defs.h"
10450 +#include "cvmx-smix-defs.h"
10451 +#include "cvmx-asxx-defs.h"
10452 +
10453 +/**
10454 + * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
10455 + * priorities[16]) is a function pointer. It is meant to allow
10456 + * customization of the PKO queue priorities based on the port
10457 + * number. Users should set this pointer to a function before
10458 + * calling any cvmx-helper operations.
10459 + */
10460 +void (*cvmx_override_pko_queue_priority) (int pko_port,
10461 + uint64_t priorities[16]);
10462 +
10463 +/**
10464 + * cvmx_override_ipd_port_setup(int ipd_port) is a function
10465 + * pointer. It is meant to allow customization of the IPD port
10466 + * setup before packet input/output comes online. It is called
10467 + * after cvmx-helper does the default IPD configuration, but
10468 + * before IPD is enabled. Users should set this pointer to a
10469 + * function before calling any cvmx-helper operations.
10470 + */
10471 +void (*cvmx_override_ipd_port_setup) (int ipd_port);
10472 +
10473 +/* Port count per interface */
10474 +static int interface_port_count[4] = { 0, 0, 0, 0 };
10475 +
10476 +/* Port last configured link info index by IPD/PKO port */
10477 +static cvmx_helper_link_info_t
10478 + port_link_info[CVMX_PIP_NUM_INPUT_PORTS];
10479 +
10480 +/**
10481 + * Return the number of interfaces the chip has. Each interface
10482 + * may have multiple ports. Most chips support two interfaces,
10483 + * but the CNX0XX and CNX1XX are exceptions. These only support
10484 + * one interface.
10485 + *
10486 + * Returns Number of interfaces on chip
10487 + */
10488 +int cvmx_helper_get_number_of_interfaces(void)
10489 +{
10490 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
10491 + return 4;
10492 + else
10493 + return 3;
10494 +}
10495 +
10496 +/**
10497 + * Return the number of ports on an interface. Depending on the
10498 + * chip and configuration, this can be 1-16. A value of 0
10499 + * specifies that the interface doesn't exist or isn't usable.
10500 + *
10501 + * @interface: Interface to get the port count for
10502 + *
10503 + * Returns Number of ports on interface. Can be Zero.
10504 + */
10505 +int cvmx_helper_ports_on_interface(int interface)
10506 +{
10507 + return interface_port_count[interface];
10508 +}
10509 +
10510 +/**
10511 + * Get the operating mode of an interface. Depending on the Octeon
10512 + * chip and configuration, this function returns an enumeration
10513 + * of the type of packet I/O supported by an interface.
10514 + *
10515 + * @interface: Interface to probe
10516 + *
10517 + * Returns Mode of the interface. Unknown or unsupported interfaces return
10518 + * DISABLED.
10519 + */
10520 +cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
10521 +{
10522 + union cvmx_gmxx_inf_mode mode;
10523 + if (interface == 2)
10524 + return CVMX_HELPER_INTERFACE_MODE_NPI;
10525 +
10526 + if (interface == 3) {
10527 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)
10528 + || OCTEON_IS_MODEL(OCTEON_CN52XX))
10529 + return CVMX_HELPER_INTERFACE_MODE_LOOP;
10530 + else
10531 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10532 + }
10533 +
10534 + if (interface == 0
10535 + && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
10536 + && cvmx_sysinfo_get()->board_rev_major == 1) {
10537 + /*
10538 + * Lie about interface type of CN3005 board. This
10539 + * board has a switch on port 1 like the other
10540 + * evaluation boards, but it is connected over RGMII
10541 + * instead of GMII. Report GMII mode so that the
10542 + * speed is forced to 1 Gbit full duplex. Other than
10543 + * some initial configuration (which does not use the
10544 + * output of this function) there is no difference in
10545 + * setup between GMII and RGMII modes.
10546 + */
10547 + return CVMX_HELPER_INTERFACE_MODE_GMII;
10548 + }
10549 +
10550 + /* Interface 1 is always disabled on CN31XX and CN30XX */
10551 + if ((interface == 1)
10552 + && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
10553 + || OCTEON_IS_MODEL(OCTEON_CN50XX)
10554 + || OCTEON_IS_MODEL(OCTEON_CN52XX)))
10555 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10556 +
10557 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
10558 +
10559 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
10560 + switch (mode.cn56xx.mode) {
10561 + case 0:
10562 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10563 + case 1:
10564 + return CVMX_HELPER_INTERFACE_MODE_XAUI;
10565 + case 2:
10566 + return CVMX_HELPER_INTERFACE_MODE_SGMII;
10567 + case 3:
10568 + return CVMX_HELPER_INTERFACE_MODE_PICMG;
10569 + default:
10570 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10571 + }
10572 + } else {
10573 + if (!mode.s.en)
10574 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10575 +
10576 + if (mode.s.type) {
10577 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
10578 + || OCTEON_IS_MODEL(OCTEON_CN58XX))
10579 + return CVMX_HELPER_INTERFACE_MODE_SPI;
10580 + else
10581 + return CVMX_HELPER_INTERFACE_MODE_GMII;
10582 + } else
10583 + return CVMX_HELPER_INTERFACE_MODE_RGMII;
10584 + }
10585 +}
10586 +
10587 +/**
10588 + * Configure the IPD/PIP tagging and QoS options for a specific
10589 + * port. This function determines the POW work queue entry
10590 + * contents for a port. The setup performed here is controlled by
10591 + * the defines in executive-config.h.
10592 + *
10593 + * @ipd_port: Port to configure. This follows the IPD numbering, not the
10594 + * per interface numbering
10595 + *
10596 + * Returns Zero on success, negative on failure
10597 + */
10598 +static int __cvmx_helper_port_setup_ipd(int ipd_port)
10599 +{
10600 + union cvmx_pip_prt_cfgx port_config;
10601 + union cvmx_pip_prt_tagx tag_config;
10602 +
10603 + port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
10604 + tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
10605 +
10606 + /* Have each port go to a different POW queue */
10607 + port_config.s.qos = ipd_port & 0x7;
10608 +
10609 + /* Process the headers and place the IP header in the work queue */
10610 + port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
10611 +
10612 + tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
10613 + tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
10614 + tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
10615 + tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
10616 + tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
10617 + tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
10618 + tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
10619 + tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
10620 + tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
10621 + tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
10622 + tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
10623 + tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10624 + tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10625 + tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10626 + tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10627 + tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10628 + /* Put all packets in group 0. Other groups can be used by the app */
10629 + tag_config.s.grp = 0;
10630 +
10631 + cvmx_pip_config_port(ipd_port, port_config, tag_config);
10632 +
10633 + /* Give the user a chance to override our setting for each port */
10634 + if (cvmx_override_ipd_port_setup)
10635 + cvmx_override_ipd_port_setup(ipd_port);
10636 +
10637 + return 0;
10638 +}
10639 +
10640 +/**
10641 + * This function probes an interface to determine the actual
10642 + * number of hardware ports connected to it. It doesn't setup the
10643 + * ports or enable them. The main goal here is to set the global
10644 + * interface_port_count[interface] correctly. Hardware setup of the
10645 + * ports will be performed later.
10646 + *
10647 + * @interface: Interface to probe
10648 + *
10649 + * Returns Zero on success, negative on failure
10650 + */
10651 +int cvmx_helper_interface_probe(int interface)
10652 +{
10653 + /* At this stage in the game we don't want packets to be moving yet.
10654 + The following probe calls should perform hardware setup
10655 + needed to determine port counts. Receive must still be disabled */
10656 + switch (cvmx_helper_interface_get_mode(interface)) {
10657 + /* These types don't support ports to IPD/PKO */
10658 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10659 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
10660 + interface_port_count[interface] = 0;
10661 + break;
10662 + /* XAUI is a single high speed port */
10663 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
10664 + interface_port_count[interface] =
10665 + __cvmx_helper_xaui_probe(interface);
10666 + break;
10667 + /*
10668 + * RGMII/GMII/MII are all treated about the same. Most
10669 + * functions refer to these ports as RGMII.
10670 + */
10671 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
10672 + case CVMX_HELPER_INTERFACE_MODE_GMII:
10673 + interface_port_count[interface] =
10674 + __cvmx_helper_rgmii_probe(interface);
10675 + break;
10676 + /*
10677 + * SPI4 can have 1-16 ports depending on the device at
10678 + * the other end.
10679 + */
10680 + case CVMX_HELPER_INTERFACE_MODE_SPI:
10681 + interface_port_count[interface] =
10682 + __cvmx_helper_spi_probe(interface);
10683 + break;
10684 + /*
10685 + * SGMII can have 1-4 ports depending on how many are
10686 + * hooked up.
10687 + */
10688 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
10689 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
10690 + interface_port_count[interface] =
10691 + __cvmx_helper_sgmii_probe(interface);
10692 + break;
10693 + /* PCI target Network Packet Interface */
10694 + case CVMX_HELPER_INTERFACE_MODE_NPI:
10695 + interface_port_count[interface] =
10696 + __cvmx_helper_npi_probe(interface);
10697 + break;
10698 + /*
10699 + * Special loopback only ports. These are not the same
10700 + * as other ports in loopback mode.
10701 + */
10702 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
10703 + interface_port_count[interface] =
10704 + __cvmx_helper_loop_probe(interface);
10705 + break;
10706 + }
10707 +
10708 + interface_port_count[interface] =
10709 + __cvmx_helper_board_interface_probe(interface,
10710 + interface_port_count
10711 + [interface]);
10712 +
10713 + /* Make sure all global variables propagate to other cores */
10714 + CVMX_SYNCWS;
10715 +
10716 + return 0;
10717 +}
10718 +
10719 +/**
10720 + * Setup the IPD/PIP for the ports on an interface. Packet
10721 + * classification and tagging are set for every port on the
10722 + * interface. The number of ports on the interface must already
10723 + * have been probed.
10724 + *
10725 + * @interface: Interface to setup IPD/PIP for
10726 + *
10727 + * Returns Zero on success, negative on failure
10728 + */
10729 +static int __cvmx_helper_interface_setup_ipd(int interface)
10730 +{
10731 + int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
10732 + int num_ports = interface_port_count[interface];
10733 +
10734 + while (num_ports--) {
10735 + __cvmx_helper_port_setup_ipd(ipd_port);
10736 + ipd_port++;
10737 + }
10738 + return 0;
10739 +}
10740 +
10741 +/**
10742 + * Setup global setting for IPD/PIP not related to a specific
10743 + * interface or port. This must be called before IPD is enabled.
10744 + *
10745 + * Returns Zero on success, negative on failure.
10746 + */
10747 +static int __cvmx_helper_global_setup_ipd(void)
10748 +{
10749 + /* Setup the global packet input options */
10750 + cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8,
10751 + CVMX_HELPER_FIRST_MBUFF_SKIP / 8,
10752 + CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8,
10753 + /* The +8 is to account for the next ptr */
10754 + (CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128,
10755 + /* The +8 is to account for the next ptr */
10756 + (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128,
10757 + CVMX_FPA_WQE_POOL,
10758 + CVMX_IPD_OPC_MODE_STT,
10759 + CVMX_HELPER_ENABLE_BACK_PRESSURE);
10760 + return 0;
10761 +}
10762 +
10763 +/**
10764 + * Setup the PKO for the ports on an interface. The number of
10765 + * queues per port and the priority of each PKO output queue
10766 + * is set here. PKO must be disabled when this function is called.
10767 + *
10768 + * @interface: Interface to setup PKO for
10769 + *
10770 + * Returns Zero on success, negative on failure
10771 + */
10772 +static int __cvmx_helper_interface_setup_pko(int interface)
10773 +{
10774 + /*
10775 + * Each packet output queue has an associated priority. The
10776 + * higher the priority, the more often it can send a packet. A
10777 + * priority of 8 means it can send in all 8 rounds of
10778 + * contention. We're going to make each queue one less than
10779 + * the last. The vector of priorities has been extended to
10780 + * support CN5xxx CPUs, where up to 16 queues can be
10781 + * associated to a port. To keep backward compatibility we
10782 + * don't change the initial 8 priorities and replicate them in
10783 + * the second half. With per-core PKO queues (PKO lockless
10784 + * operation) all queues have the same priority.
10785 + */
10786 + uint64_t priorities[16] =
10787 + { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
10788 +
10789 + /*
10790 + * Setup the IPD/PIP and PKO for the ports discovered
10791 + * above. Here packet classification, tagging and output
10792 + * priorities are set.
10793 + */
10794 + int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
10795 + int num_ports = interface_port_count[interface];
10796 + while (num_ports--) {
10797 + /*
10798 + * Give the user a chance to override the per queue
10799 + * priorities.
10800 + */
10801 + if (cvmx_override_pko_queue_priority)
10802 + cvmx_override_pko_queue_priority(ipd_port, priorities);
10803 +
10804 + cvmx_pko_config_port(ipd_port,
10805 + cvmx_pko_get_base_queue_per_core(ipd_port,
10806 + 0),
10807 + cvmx_pko_get_num_queues(ipd_port),
10808 + priorities);
10809 + ipd_port++;
10810 + }
10811 + return 0;
10812 +}
10813 +
10814 +/**
10815 + * Setup global setting for PKO not related to a specific
10816 + * interface or port. This must be called before PKO is enabled.
10817 + *
10818 + * Returns Zero on success, negative on failure.
10819 + */
10820 +static int __cvmx_helper_global_setup_pko(void)
10821 +{
10822 + /*
10823 + * Disable tagwait FAU timeout. This needs to be done before
10824 + * anyone might start packet output using tags.
10825 + */
10826 + union cvmx_iob_fau_timeout fau_to;
10827 + fau_to.u64 = 0;
10828 + fau_to.s.tout_val = 0xfff;
10829 + fau_to.s.tout_enb = 0;
10830 + cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
10831 + return 0;
10832 +}
10833 +
10834 +/**
10835 + * Setup global backpressure setting.
10836 + *
10837 + * Returns Zero on success, negative on failure
10838 + */
10839 +static int __cvmx_helper_global_setup_backpressure(void)
10840 +{
10841 +#if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
10842 + /* Disable backpressure if configured to do so */
10843 + /* Disable backpressure (pause frame) generation */
10844 + int num_interfaces = cvmx_helper_get_number_of_interfaces();
10845 + int interface;
10846 + for (interface = 0; interface < num_interfaces; interface++) {
10847 + switch (cvmx_helper_interface_get_mode(interface)) {
10848 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10849 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
10850 + case CVMX_HELPER_INTERFACE_MODE_NPI:
10851 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
10852 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
10853 + break;
10854 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
10855 + case CVMX_HELPER_INTERFACE_MODE_GMII:
10856 + case CVMX_HELPER_INTERFACE_MODE_SPI:
10857 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
10858 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
10859 + cvmx_gmx_set_backpressure_override(interface, 0xf);
10860 + break;
10861 + }
10862 + }
10863 +#endif
10864 +
10865 + return 0;
10866 +}
10867 +
10868 +/**
10869 + * Enable packet input/output from the hardware. This function is
10870 + * called after all internal setup is complete and IPD is enabled.
10871 + * After this function completes, packets will be accepted from the
10872 + * hardware ports. PKO should still be disabled to make sure packets
10873 + * aren't sent out partially setup hardware.
10874 + *
10875 + * @interface: Interface to enable
10876 + *
10877 + * Returns Zero on success, negative on failure
10878 + */
10879 +static int __cvmx_helper_packet_hardware_enable(int interface)
10880 +{
10881 + int result = 0;
10882 + switch (cvmx_helper_interface_get_mode(interface)) {
10883 + /* These types don't support ports to IPD/PKO */
10884 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10885 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
10886 + /* Nothing to do */
10887 + break;
10888 + /* XAUI is a single high speed port */
10889 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
10890 + result = __cvmx_helper_xaui_enable(interface);
10891 + break;
10892 + /*
10893 + * RGMII/GMII/MII are all treated about the same. Most
10894 + * functions refer to these ports as RGMII
10895 + */
10896 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
10897 + case CVMX_HELPER_INTERFACE_MODE_GMII:
10898 + result = __cvmx_helper_rgmii_enable(interface);
10899 + break;
10900 + /*
10901 + * SPI4 can have 1-16 ports depending on the device at
10902 + * the other end
10903 + */
10904 + case CVMX_HELPER_INTERFACE_MODE_SPI:
10905 + result = __cvmx_helper_spi_enable(interface);
10906 + break;
10907 + /*
10908 + * SGMII can have 1-4 ports depending on how many are
10909 + * hooked up
10910 + */
10911 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
10912 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
10913 + result = __cvmx_helper_sgmii_enable(interface);
10914 + break;
10915 + /* PCI target Network Packet Interface */
10916 + case CVMX_HELPER_INTERFACE_MODE_NPI:
10917 + result = __cvmx_helper_npi_enable(interface);
10918 + break;
10919 + /*
10920 + * Special loopback only ports. These are not the same
10921 + * as other ports in loopback mode
10922 + */
10923 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
10924 + result = __cvmx_helper_loop_enable(interface);
10925 + break;
10926 + }
10927 + result |= __cvmx_helper_board_hardware_enable(interface);
10928 + return result;
10929 +}
10930 +
10931 +/**
10932 + * Function to adjust internal IPD pointer alignments
10933 + *
10934 + * Returns 0 on success
10935 + * !0 on failure
10936 + */
10937 +int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
10938 +{
10939 +#define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
10940 + (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
10941 +#define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
10942 + (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
10943 +#define FIX_IPD_OUTPORT 0
10944 + /* Ports 0-15 are interface 0, 16-31 are interface 1 */
10945 +#define INTERFACE(port) (port >> 4)
10946 +#define INDEX(port) (port & 0xf)
10947 + uint64_t *p64;
10948 + cvmx_pko_command_word0_t pko_command;
10949 + union cvmx_buf_ptr g_buffer, pkt_buffer;
10950 + cvmx_wqe_t *work;
10951 + int size, num_segs = 0, wqe_pcnt, pkt_pcnt;
10952 + union cvmx_gmxx_prtx_cfg gmx_cfg;
10953 + int retry_cnt;
10954 + int retry_loop_cnt;
10955 + int mtu;
10956 + int i;
10957 + cvmx_helper_link_info_t link_info;
10958 +
10959 + /* Save values for restore at end */
10960 + uint64_t prtx_cfg =
10961 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG
10962 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
10963 + uint64_t tx_ptr_en =
10964 + cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
10965 + uint64_t rx_ptr_en =
10966 + cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
10967 + uint64_t rxx_jabber =
10968 + cvmx_read_csr(CVMX_GMXX_RXX_JABBER
10969 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
10970 + uint64_t frame_max =
10971 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
10972 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
10973 +
10974 + /* Configure port to gig FDX as required for loopback mode */
10975 + cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
10976 +
10977 + /*
10978 + * Disable reception on all ports so if traffic is present it
10979 + * will not interfere.
10980 + */
10981 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
10982 +
10983 + cvmx_wait(100000000ull);
10984 +
10985 + for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) {
10986 + retry_cnt = 100000;
10987 + wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
10988 + pkt_pcnt = (wqe_pcnt >> 7) & 0x7f;
10989 + wqe_pcnt &= 0x7f;
10990 +
10991 + num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
10992 +
10993 + if (num_segs == 0)
10994 + goto fix_ipd_exit;
10995 +
10996 + num_segs += 1;
10997 +
10998 + size =
10999 + FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES +
11000 + ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) -
11001 + (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2);
11002 +
11003 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
11004 + 1 << INDEX(FIX_IPD_OUTPORT));
11005 + CVMX_SYNC;
11006 +
11007 + g_buffer.u64 = 0;
11008 + g_buffer.s.addr =
11009 + cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL));
11010 + if (g_buffer.s.addr == 0) {
11011 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11012 + "buffer allocation failure.\n");
11013 + goto fix_ipd_exit;
11014 + }
11015 +
11016 + g_buffer.s.pool = CVMX_FPA_WQE_POOL;
11017 + g_buffer.s.size = num_segs;
11018 +
11019 + pkt_buffer.u64 = 0;
11020 + pkt_buffer.s.addr =
11021 + cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL));
11022 + if (pkt_buffer.s.addr == 0) {
11023 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11024 + "buffer allocation failure.\n");
11025 + goto fix_ipd_exit;
11026 + }
11027 + pkt_buffer.s.i = 1;
11028 + pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL;
11029 + pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES;
11030 +
11031 + p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr);
11032 + p64[0] = 0xffffffffffff0000ull;
11033 + p64[1] = 0x08004510ull;
11034 + p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull;
11035 + p64[3] = 0x3a5fc0a81073c0a8ull;
11036 +
11037 + for (i = 0; i < num_segs; i++) {
11038 + if (i > 0)
11039 + pkt_buffer.s.size =
11040 + FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
11041 +
11042 + if (i == (num_segs - 1))
11043 + pkt_buffer.s.i = 0;
11044 +
11045 + *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
11046 + 8 * i) = pkt_buffer.u64;
11047 + }
11048 +
11049 + /* Build the PKO command */
11050 + pko_command.u64 = 0;
11051 + pko_command.s.segs = num_segs;
11052 + pko_command.s.total_bytes = size;
11053 + pko_command.s.dontfree = 0;
11054 + pko_command.s.gather = 1;
11055 +
11056 + gmx_cfg.u64 =
11057 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG
11058 + (INDEX(FIX_IPD_OUTPORT),
11059 + INTERFACE(FIX_IPD_OUTPORT)));
11060 + gmx_cfg.s.en = 1;
11061 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG
11062 + (INDEX(FIX_IPD_OUTPORT),
11063 + INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64);
11064 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11065 + 1 << INDEX(FIX_IPD_OUTPORT));
11066 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11067 + 1 << INDEX(FIX_IPD_OUTPORT));
11068 +
11069 + mtu =
11070 + cvmx_read_csr(CVMX_GMXX_RXX_JABBER
11071 + (INDEX(FIX_IPD_OUTPORT),
11072 + INTERFACE(FIX_IPD_OUTPORT)));
11073 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER
11074 + (INDEX(FIX_IPD_OUTPORT),
11075 + INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
11076 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
11077 + (INDEX(FIX_IPD_OUTPORT),
11078 + INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
11079 +
11080 + cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT,
11081 + cvmx_pko_get_base_queue
11082 + (FIX_IPD_OUTPORT),
11083 + CVMX_PKO_LOCK_CMD_QUEUE);
11084 + cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT,
11085 + cvmx_pko_get_base_queue
11086 + (FIX_IPD_OUTPORT), pko_command,
11087 + g_buffer, CVMX_PKO_LOCK_CMD_QUEUE);
11088 +
11089 + CVMX_SYNC;
11090 +
11091 + do {
11092 + work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
11093 + retry_cnt--;
11094 + } while ((work == NULL) && (retry_cnt > 0));
11095 +
11096 + if (!retry_cnt)
11097 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11098 + "get_work() timeout occured.\n");
11099 +
11100 + /* Free packet */
11101 + if (work)
11102 + cvmx_helper_free_packet_data(work);
11103 + }
11104 +
11105 +fix_ipd_exit:
11106 +
11107 + /* Return CSR configs to saved values */
11108 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG
11109 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11110 + prtx_cfg);
11111 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11112 + tx_ptr_en);
11113 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11114 + rx_ptr_en);
11115 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER
11116 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11117 + rxx_jabber);
11118 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
11119 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11120 + frame_max);
11121 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0);
11122 + /* Set link to down so autonegotiation will set it up again */
11123 + link_info.u64 = 0;
11124 + cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info);
11125 +
11126 + /*
11127 + * Bring the link back up as autonegotiation is not done in
11128 + * user applications.
11129 + */
11130 + cvmx_helper_link_autoconf(FIX_IPD_OUTPORT);
11131 +
11132 + CVMX_SYNC;
11133 + if (num_segs)
11134 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
11135 +
11136 + return !!num_segs;
11137 +
11138 +}
11139 +
11140 +/**
11141 + * Called after all internal packet IO paths are setup. This
11142 + * function enables IPD/PIP and begins packet input and output.
11143 + *
11144 + * Returns Zero on success, negative on failure
11145 + */
11146 +int cvmx_helper_ipd_and_packet_input_enable(void)
11147 +{
11148 + int num_interfaces;
11149 + int interface;
11150 +
11151 + /* Enable IPD */
11152 + cvmx_ipd_enable();
11153 +
11154 + /*
11155 + * Time to enable hardware ports packet input and output. Note
11156 + * that at this point IPD/PIP must be fully functional and PKO
11157 + * must be disabled
11158 + */
11159 + num_interfaces = cvmx_helper_get_number_of_interfaces();
11160 + for (interface = 0; interface < num_interfaces; interface++) {
11161 + if (cvmx_helper_ports_on_interface(interface) > 0)
11162 + __cvmx_helper_packet_hardware_enable(interface);
11163 + }
11164 +
11165 + /* Finally enable PKO now that the entire path is up and running */
11166 + cvmx_pko_enable();
11167 +
11168 + if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
11169 + || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1))
11170 + && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
11171 + __cvmx_helper_errata_fix_ipd_ptr_alignment();
11172 + return 0;
11173 +}
11174 +
11175 +/**
11176 + * Initialize the PIP, IPD, and PKO hardware to support
11177 + * simple priority based queues for the ethernet ports. Each
11178 + * port is configured with a number of priority queues based
11179 + * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
11180 + * priority than the previous.
11181 + *
11182 + * Returns Zero on success, non-zero on failure
11183 + */
11184 +int cvmx_helper_initialize_packet_io_global(void)
11185 +{
11186 + int result = 0;
11187 + int interface;
11188 + union cvmx_l2c_cfg l2c_cfg;
11189 + union cvmx_smix_en smix_en;
11190 + const int num_interfaces = cvmx_helper_get_number_of_interfaces();
11191 +
11192 + /*
11193 + * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to
11194 + * be disabled.
11195 + */
11196 + if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
11197 + __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
11198 +
11199 + /*
11200 + * Tell L2 to give the IOB statically higher priority compared
11201 + * to the cores. This avoids conditions where IO blocks might
11202 + * be starved under very high L2 loads.
11203 + */
11204 + l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
11205 + l2c_cfg.s.lrf_arb_mode = 0;
11206 + l2c_cfg.s.rfb_arb_mode = 0;
11207 + cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
11208 +
11209 + /* Make sure SMI/MDIO is enabled so we can query PHYs */
11210 + smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
11211 + if (!smix_en.s.en) {
11212 + smix_en.s.en = 1;
11213 + cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
11214 + }
11215 +
11216 + /* Newer chips actually have two SMI/MDIO interfaces */
11217 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
11218 + !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
11219 + !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
11220 + smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
11221 + if (!smix_en.s.en) {
11222 + smix_en.s.en = 1;
11223 + cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
11224 + }
11225 + }
11226 +
11227 + cvmx_pko_initialize_global();
11228 + for (interface = 0; interface < num_interfaces; interface++) {
11229 + result |= cvmx_helper_interface_probe(interface);
11230 + if (cvmx_helper_ports_on_interface(interface) > 0)
11231 + cvmx_dprintf("Interface %d has %d ports (%s)\n",
11232 + interface,
11233 + cvmx_helper_ports_on_interface(interface),
11234 + cvmx_helper_interface_mode_to_string
11235 + (cvmx_helper_interface_get_mode
11236 + (interface)));
11237 + result |= __cvmx_helper_interface_setup_ipd(interface);
11238 + result |= __cvmx_helper_interface_setup_pko(interface);
11239 + }
11240 +
11241 + result |= __cvmx_helper_global_setup_ipd();
11242 + result |= __cvmx_helper_global_setup_pko();
11243 +
11244 + /* Enable any flow control and backpressure */
11245 + result |= __cvmx_helper_global_setup_backpressure();
11246 +
11247 +#if CVMX_HELPER_ENABLE_IPD
11248 + result |= cvmx_helper_ipd_and_packet_input_enable();
11249 +#endif
11250 + return result;
11251 +}
11252 +
11253 +/**
11254 + * Does core local initialization for packet io
11255 + *
11256 + * Returns Zero on success, non-zero on failure
11257 + */
11258 +int cvmx_helper_initialize_packet_io_local(void)
11259 +{
11260 + return cvmx_pko_initialize_local();
11261 +}
11262 +
11263 +/**
11264 + * Auto configure an IPD/PKO port link state and speed. This
11265 + * function basically does the equivalent of:
11266 + * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
11267 + *
11268 + * @ipd_port: IPD/PKO port to auto configure
11269 + *
11270 + * Returns Link state after configure
11271 + */
11272 +cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
11273 +{
11274 + cvmx_helper_link_info_t link_info;
11275 + int interface = cvmx_helper_get_interface_num(ipd_port);
11276 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11277 +
11278 + if (index >= cvmx_helper_ports_on_interface(interface)) {
11279 + link_info.u64 = 0;
11280 + return link_info;
11281 + }
11282 +
11283 + link_info = cvmx_helper_link_get(ipd_port);
11284 + if (link_info.u64 == port_link_info[ipd_port].u64)
11285 + return link_info;
11286 +
11287 + /* If we fail to set the link speed, port_link_info will not change */
11288 + cvmx_helper_link_set(ipd_port, link_info);
11289 +
11290 + /*
11291 + * port_link_info should be the current value, which will be
11292 + * different than expect if cvmx_helper_link_set() failed.
11293 + */
11294 + return port_link_info[ipd_port];
11295 +}
11296 +
11297 +/**
11298 + * Return the link state of an IPD/PKO port as returned by
11299 + * auto negotiation. The result of this function may not match
11300 + * Octeon's link config if auto negotiation has changed since
11301 + * the last call to cvmx_helper_link_set().
11302 + *
11303 + * @ipd_port: IPD/PKO port to query
11304 + *
11305 + * Returns Link state
11306 + */
11307 +cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
11308 +{
11309 + cvmx_helper_link_info_t result;
11310 + int interface = cvmx_helper_get_interface_num(ipd_port);
11311 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11312 +
11313 + /* The default result will be a down link unless the code below
11314 + changes it */
11315 + result.u64 = 0;
11316 +
11317 + if (index >= cvmx_helper_ports_on_interface(interface))
11318 + return result;
11319 +
11320 + switch (cvmx_helper_interface_get_mode(interface)) {
11321 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11322 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
11323 + /* Network links are not supported */
11324 + break;
11325 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11326 + result = __cvmx_helper_xaui_link_get(ipd_port);
11327 + break;
11328 + case CVMX_HELPER_INTERFACE_MODE_GMII:
11329 + if (index == 0)
11330 + result = __cvmx_helper_rgmii_link_get(ipd_port);
11331 + else {
11332 + result.s.full_duplex = 1;
11333 + result.s.link_up = 1;
11334 + result.s.speed = 1000;
11335 + }
11336 + break;
11337 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
11338 + result = __cvmx_helper_rgmii_link_get(ipd_port);
11339 + break;
11340 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11341 + result = __cvmx_helper_spi_link_get(ipd_port);
11342 + break;
11343 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11344 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11345 + result = __cvmx_helper_sgmii_link_get(ipd_port);
11346 + break;
11347 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11348 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
11349 + /* Network links are not supported */
11350 + break;
11351 + }
11352 + return result;
11353 +}
11354 +
11355 +/**
11356 + * Configure an IPD/PKO port for the specified link state. This
11357 + * function does not influence auto negotiation at the PHY level.
11358 + * The passed link state must always match the link state returned
11359 + * by cvmx_helper_link_get(). It is normally best to use
11360 + * cvmx_helper_link_autoconf() instead.
11361 + *
11362 + * @ipd_port: IPD/PKO port to configure
11363 + * @link_info: The new link state
11364 + *
11365 + * Returns Zero on success, negative on failure
11366 + */
11367 +int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
11368 +{
11369 + int result = -1;
11370 + int interface = cvmx_helper_get_interface_num(ipd_port);
11371 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11372 +
11373 + if (index >= cvmx_helper_ports_on_interface(interface))
11374 + return -1;
11375 +
11376 + switch (cvmx_helper_interface_get_mode(interface)) {
11377 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11378 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
11379 + break;
11380 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11381 + result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
11382 + break;
11383 + /*
11384 + * RGMII/GMII/MII are all treated about the same. Most
11385 + * functions refer to these ports as RGMII.
11386 + */
11387 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
11388 + case CVMX_HELPER_INTERFACE_MODE_GMII:
11389 + result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
11390 + break;
11391 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11392 + result = __cvmx_helper_spi_link_set(ipd_port, link_info);
11393 + break;
11394 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11395 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11396 + result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
11397 + break;
11398 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11399 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
11400 + break;
11401 + }
11402 + /* Set the port_link_info here so that the link status is updated
11403 + no matter how cvmx_helper_link_set is called. We don't change
11404 + the value if link_set failed */
11405 + if (result == 0)
11406 + port_link_info[ipd_port].u64 = link_info.u64;
11407 + return result;
11408 +}
11409 +
11410 +/**
11411 + * Configure a port for internal and/or external loopback. Internal loopback
11412 + * causes packets sent by the port to be received by Octeon. External loopback
11413 + * causes packets received from the wire to sent out again.
11414 + *
11415 + * @ipd_port: IPD/PKO port to loopback.
11416 + * @enable_internal:
11417 + * Non zero if you want internal loopback
11418 + * @enable_external:
11419 + * Non zero if you want external loopback
11420 + *
11421 + * Returns Zero on success, negative on failure.
11422 + */
11423 +int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
11424 + int enable_external)
11425 +{
11426 + int result = -1;
11427 + int interface = cvmx_helper_get_interface_num(ipd_port);
11428 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11429 +
11430 + if (index >= cvmx_helper_ports_on_interface(interface))
11431 + return -1;
11432 +
11433 + switch (cvmx_helper_interface_get_mode(interface)) {
11434 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11435 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
11436 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11437 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11438 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
11439 + break;
11440 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11441 + result =
11442 + __cvmx_helper_xaui_configure_loopback(ipd_port,
11443 + enable_internal,
11444 + enable_external);
11445 + break;
11446 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
11447 + case CVMX_HELPER_INTERFACE_MODE_GMII:
11448 + result =
11449 + __cvmx_helper_rgmii_configure_loopback(ipd_port,
11450 + enable_internal,
11451 + enable_external);
11452 + break;
11453 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11454 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11455 + result =
11456 + __cvmx_helper_sgmii_configure_loopback(ipd_port,
11457 + enable_internal,
11458 + enable_external);
11459 + break;
11460 + }
11461 + return result;
11462 +}
11463 --- /dev/null
11464 +++ b/drivers/staging/octeon/cvmx-helper.h
11465 @@ -0,0 +1,227 @@
11466 +/***********************license start***************
11467 + * Author: Cavium Networks
11468 + *
11469 + * Contact: support@caviumnetworks.com
11470 + * This file is part of the OCTEON SDK
11471 + *
11472 + * Copyright (c) 2003-2008 Cavium Networks
11473 + *
11474 + * This file is free software; you can redistribute it and/or modify
11475 + * it under the terms of the GNU General Public License, Version 2, as
11476 + * published by the Free Software Foundation.
11477 + *
11478 + * This file is distributed in the hope that it will be useful, but
11479 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
11480 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
11481 + * NONINFRINGEMENT. See the GNU General Public License for more
11482 + * details.
11483 + *
11484 + * You should have received a copy of the GNU General Public License
11485 + * along with this file; if not, write to the Free Software
11486 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11487 + * or visit http://www.gnu.org/licenses/.
11488 + *
11489 + * This file may also be available under a different license from Cavium.
11490 + * Contact Cavium Networks for more information
11491 + ***********************license end**************************************/
11492 +
11493 +/*
11494 + *
11495 + * Helper functions for common, but complicated tasks.
11496 + *
11497 + */
11498 +
11499 +#ifndef __CVMX_HELPER_H__
11500 +#define __CVMX_HELPER_H__
11501 +
11502 +#include "cvmx-config.h"
11503 +#include "cvmx-fpa.h"
11504 +#include "cvmx-wqe.h"
11505 +
11506 +typedef enum {
11507 + CVMX_HELPER_INTERFACE_MODE_DISABLED,
11508 + CVMX_HELPER_INTERFACE_MODE_RGMII,
11509 + CVMX_HELPER_INTERFACE_MODE_GMII,
11510 + CVMX_HELPER_INTERFACE_MODE_SPI,
11511 + CVMX_HELPER_INTERFACE_MODE_PCIE,
11512 + CVMX_HELPER_INTERFACE_MODE_XAUI,
11513 + CVMX_HELPER_INTERFACE_MODE_SGMII,
11514 + CVMX_HELPER_INTERFACE_MODE_PICMG,
11515 + CVMX_HELPER_INTERFACE_MODE_NPI,
11516 + CVMX_HELPER_INTERFACE_MODE_LOOP,
11517 +} cvmx_helper_interface_mode_t;
11518 +
11519 +typedef union {
11520 + uint64_t u64;
11521 + struct {
11522 + uint64_t reserved_20_63:44;
11523 + uint64_t link_up:1; /**< Is the physical link up? */
11524 + uint64_t full_duplex:1; /**< 1 if the link is full duplex */
11525 + uint64_t speed:18; /**< Speed of the link in Mbps */
11526 + } s;
11527 +} cvmx_helper_link_info_t;
11528 +
11529 +#include "cvmx-helper-fpa.h"
11530 +
11531 +#include <asm/octeon/cvmx-helper-errata.h>
11532 +#include "cvmx-helper-loop.h"
11533 +#include "cvmx-helper-npi.h"
11534 +#include "cvmx-helper-rgmii.h"
11535 +#include "cvmx-helper-sgmii.h"
11536 +#include "cvmx-helper-spi.h"
11537 +#include "cvmx-helper-util.h"
11538 +#include "cvmx-helper-xaui.h"
11539 +
11540 +/**
11541 + * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
11542 + * priorities[16]) is a function pointer. It is meant to allow
11543 + * customization of the PKO queue priorities based on the port
11544 + * number. Users should set this pointer to a function before
11545 + * calling any cvmx-helper operations.
11546 + */
11547 +extern void (*cvmx_override_pko_queue_priority) (int pko_port,
11548 + uint64_t priorities[16]);
11549 +
11550 +/**
11551 + * cvmx_override_ipd_port_setup(int ipd_port) is a function
11552 + * pointer. It is meant to allow customization of the IPD port
11553 + * setup before packet input/output comes online. It is called
11554 + * after cvmx-helper does the default IPD configuration, but
11555 + * before IPD is enabled. Users should set this pointer to a
11556 + * function before calling any cvmx-helper operations.
11557 + */
11558 +extern void (*cvmx_override_ipd_port_setup) (int ipd_port);
11559 +
11560 +/**
11561 + * This function enables the IPD and also enables the packet interfaces.
11562 + * The packet interfaces (RGMII and SPI) must be enabled after the
11563 + * IPD. This should be called by the user program after any additional
11564 + * IPD configuration changes are made if CVMX_HELPER_ENABLE_IPD
11565 + * is not set in the executive-config.h file.
11566 + *
11567 + * Returns 0 on success
11568 + * -1 on failure
11569 + */
11570 +extern int cvmx_helper_ipd_and_packet_input_enable(void);
11571 +
11572 +/**
11573 + * Initialize the PIP, IPD, and PKO hardware to support
11574 + * simple priority based queues for the ethernet ports. Each
11575 + * port is configured with a number of priority queues based
11576 + * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
11577 + * priority than the previous.
11578 + *
11579 + * Returns Zero on success, non-zero on failure
11580 + */
11581 +extern int cvmx_helper_initialize_packet_io_global(void);
11582 +
11583 +/**
11584 + * Does core local initialization for packet io
11585 + *
11586 + * Returns Zero on success, non-zero on failure
11587 + */
11588 +extern int cvmx_helper_initialize_packet_io_local(void);
11589 +
11590 +/**
11591 + * Returns the number of ports on the given interface.
11592 + * The interface must be initialized before the port count
11593 + * can be returned.
11594 + *
11595 + * @interface: Which interface to return port count for.
11596 + *
11597 + * Returns Port count for interface
11598 + * -1 for uninitialized interface
11599 + */
11600 +extern int cvmx_helper_ports_on_interface(int interface);
11601 +
11602 +/**
11603 + * Return the number of interfaces the chip has. Each interface
11604 + * may have multiple ports. Most chips support two interfaces,
11605 + * but the CNX0XX and CNX1XX are exceptions. These only support
11606 + * one interface.
11607 + *
11608 + * Returns Number of interfaces on chip
11609 + */
11610 +extern int cvmx_helper_get_number_of_interfaces(void);
11611 +
11612 +/**
11613 + * Get the operating mode of an interface. Depending on the Octeon
11614 + * chip and configuration, this function returns an enumeration
11615 + * of the type of packet I/O supported by an interface.
11616 + *
11617 + * @interface: Interface to probe
11618 + *
11619 + * Returns Mode of the interface. Unknown or unsupported interfaces return
11620 + * DISABLED.
11621 + */
11622 +extern cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int
11623 + interface);
11624 +
11625 +/**
11626 + * Auto configure an IPD/PKO port link state and speed. This
11627 + * function basically does the equivalent of:
11628 + * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
11629 + *
11630 + * @ipd_port: IPD/PKO port to auto configure
11631 + *
11632 + * Returns Link state after configure
11633 + */
11634 +extern cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port);
11635 +
11636 +/**
11637 + * Return the link state of an IPD/PKO port as returned by
11638 + * auto negotiation. The result of this function may not match
11639 + * Octeon's link config if auto negotiation has changed since
11640 + * the last call to cvmx_helper_link_set().
11641 + *
11642 + * @ipd_port: IPD/PKO port to query
11643 + *
11644 + * Returns Link state
11645 + */
11646 +extern cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port);
11647 +
11648 +/**
11649 + * Configure an IPD/PKO port for the specified link state. This
11650 + * function does not influence auto negotiation at the PHY level.
11651 + * The passed link state must always match the link state returned
11652 + * by cvmx_helper_link_get(). It is normally best to use
11653 + * cvmx_helper_link_autoconf() instead.
11654 + *
11655 + * @ipd_port: IPD/PKO port to configure
11656 + * @link_info: The new link state
11657 + *
11658 + * Returns Zero on success, negative on failure
11659 + */
11660 +extern int cvmx_helper_link_set(int ipd_port,
11661 + cvmx_helper_link_info_t link_info);
11662 +
11663 +/**
11664 + * This function probes an interface to determine the actual
11665 + * number of hardware ports connected to it. It doesn't setup the
11666 + * ports or enable them. The main goal here is to set the global
11667 + * interface_port_count[interface] correctly. Hardware setup of the
11668 + * ports will be performed later.
11669 + *
11670 + * @interface: Interface to probe
11671 + *
11672 + * Returns Zero on success, negative on failure
11673 + */
11674 +extern int cvmx_helper_interface_probe(int interface);
11675 +
11676 +/**
11677 + * Configure a port for internal and/or external loopback. Internal loopback
11678 + * causes packets sent by the port to be received by Octeon. External loopback
11679 + * causes packets received from the wire to sent out again.
11680 + *
11681 + * @ipd_port: IPD/PKO port to loopback.
11682 + * @enable_internal:
11683 + * Non zero if you want internal loopback
11684 + * @enable_external:
11685 + * Non zero if you want external loopback
11686 + *
11687 + * Returns Zero on success, negative on failure.
11688 + */
11689 +extern int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
11690 + int enable_external);
11691 +
11692 +#endif /* __CVMX_HELPER_H__ */
11693 --- /dev/null
11694 +++ b/drivers/staging/octeon/cvmx-interrupt-decodes.c
11695 @@ -0,0 +1,371 @@
11696 +/***********************license start***************
11697 + * Author: Cavium Networks
11698 + *
11699 + * Contact: support@caviumnetworks.com
11700 + * This file is part of the OCTEON SDK
11701 + *
11702 + * Copyright (c) 2003-2009 Cavium Networks
11703 + *
11704 + * This file is free software; you can redistribute it and/or modify
11705 + * it under the terms of the GNU General Public License, Version 2, as
11706 + * published by the Free Software Foundation.
11707 + *
11708 + * This file is distributed in the hope that it will be useful, but
11709 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
11710 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
11711 + * NONINFRINGEMENT. See the GNU General Public License for more
11712 + * details.
11713 + *
11714 + * You should have received a copy of the GNU General Public License
11715 + * along with this file; if not, write to the Free Software
11716 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11717 + * or visit http://www.gnu.org/licenses/.
11718 + *
11719 + * This file may also be available under a different license from Cavium.
11720 + * Contact Cavium Networks for more information
11721 + ***********************license end**************************************/
11722 +
11723 +/*
11724 + *
11725 + * Automatically generated functions useful for enabling
11726 + * and decoding RSL_INT_BLOCKS interrupts.
11727 + *
11728 + */
11729 +
11730 +#include <asm/octeon/octeon.h>
11731 +
11732 +#include "cvmx-gmxx-defs.h"
11733 +#include "cvmx-pcsx-defs.h"
11734 +#include "cvmx-pcsxx-defs.h"
11735 +#include "cvmx-spxx-defs.h"
11736 +#include "cvmx-stxx-defs.h"
11737 +
11738 +#ifndef PRINT_ERROR
11739 +#define PRINT_ERROR(format, ...)
11740 +#endif
11741 +
11742 +
11743 +/**
11744 + * __cvmx_interrupt_gmxx_rxx_int_en_enable enables all interrupt bits in cvmx_gmxx_rxx_int_en_t
11745 + */
11746 +void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block)
11747 +{
11748 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
11749 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, block),
11750 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, block)));
11751 + gmx_rx_int_en.u64 = 0;
11752 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
11753 + /* Skipping gmx_rx_int_en.s.reserved_29_63 */
11754 + gmx_rx_int_en.s.hg2cc = 1;
11755 + gmx_rx_int_en.s.hg2fld = 1;
11756 + gmx_rx_int_en.s.undat = 1;
11757 + gmx_rx_int_en.s.uneop = 1;
11758 + gmx_rx_int_en.s.unsop = 1;
11759 + gmx_rx_int_en.s.bad_term = 1;
11760 + gmx_rx_int_en.s.bad_seq = 1;
11761 + gmx_rx_int_en.s.rem_fault = 1;
11762 + gmx_rx_int_en.s.loc_fault = 1;
11763 + gmx_rx_int_en.s.pause_drp = 1;
11764 + /* Skipping gmx_rx_int_en.s.reserved_16_18 */
11765 + /*gmx_rx_int_en.s.ifgerr = 1; */
11766 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11767 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11768 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11769 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11770 + gmx_rx_int_en.s.ovrerr = 1;
11771 + /* Skipping gmx_rx_int_en.s.reserved_9_9 */
11772 + gmx_rx_int_en.s.skperr = 1;
11773 + gmx_rx_int_en.s.rcverr = 1;
11774 + /* Skipping gmx_rx_int_en.s.reserved_5_6 */
11775 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11776 + gmx_rx_int_en.s.jabber = 1;
11777 + /* Skipping gmx_rx_int_en.s.reserved_2_2 */
11778 + gmx_rx_int_en.s.carext = 1;
11779 + /* Skipping gmx_rx_int_en.s.reserved_0_0 */
11780 + }
11781 + if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
11782 + /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11783 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11784 + /*gmx_rx_int_en.s.phy_spd = 1; */
11785 + /*gmx_rx_int_en.s.phy_link = 1; */
11786 + /*gmx_rx_int_en.s.ifgerr = 1; */
11787 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11788 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11789 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11790 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11791 + gmx_rx_int_en.s.ovrerr = 1;
11792 + gmx_rx_int_en.s.niberr = 1;
11793 + gmx_rx_int_en.s.skperr = 1;
11794 + gmx_rx_int_en.s.rcverr = 1;
11795 + /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11796 + gmx_rx_int_en.s.alnerr = 1;
11797 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11798 + gmx_rx_int_en.s.jabber = 1;
11799 + gmx_rx_int_en.s.maxerr = 1;
11800 + gmx_rx_int_en.s.carext = 1;
11801 + gmx_rx_int_en.s.minerr = 1;
11802 + }
11803 + if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
11804 + /* Skipping gmx_rx_int_en.s.reserved_20_63 */
11805 + gmx_rx_int_en.s.pause_drp = 1;
11806 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11807 + /*gmx_rx_int_en.s.phy_spd = 1; */
11808 + /*gmx_rx_int_en.s.phy_link = 1; */
11809 + /*gmx_rx_int_en.s.ifgerr = 1; */
11810 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11811 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11812 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11813 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11814 + gmx_rx_int_en.s.ovrerr = 1;
11815 + gmx_rx_int_en.s.niberr = 1;
11816 + gmx_rx_int_en.s.skperr = 1;
11817 + gmx_rx_int_en.s.rcverr = 1;
11818 + /* Skipping gmx_rx_int_en.s.reserved_6_6 */
11819 + gmx_rx_int_en.s.alnerr = 1;
11820 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11821 + gmx_rx_int_en.s.jabber = 1;
11822 + /* Skipping gmx_rx_int_en.s.reserved_2_2 */
11823 + gmx_rx_int_en.s.carext = 1;
11824 + /* Skipping gmx_rx_int_en.s.reserved_0_0 */
11825 + }
11826 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
11827 + /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11828 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11829 + /*gmx_rx_int_en.s.phy_spd = 1; */
11830 + /*gmx_rx_int_en.s.phy_link = 1; */
11831 + /*gmx_rx_int_en.s.ifgerr = 1; */
11832 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11833 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11834 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11835 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11836 + gmx_rx_int_en.s.ovrerr = 1;
11837 + gmx_rx_int_en.s.niberr = 1;
11838 + gmx_rx_int_en.s.skperr = 1;
11839 + gmx_rx_int_en.s.rcverr = 1;
11840 + /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11841 + gmx_rx_int_en.s.alnerr = 1;
11842 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11843 + gmx_rx_int_en.s.jabber = 1;
11844 + gmx_rx_int_en.s.maxerr = 1;
11845 + gmx_rx_int_en.s.carext = 1;
11846 + gmx_rx_int_en.s.minerr = 1;
11847 + }
11848 + if (OCTEON_IS_MODEL(OCTEON_CN31XX)) {
11849 + /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11850 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11851 + /*gmx_rx_int_en.s.phy_spd = 1; */
11852 + /*gmx_rx_int_en.s.phy_link = 1; */
11853 + /*gmx_rx_int_en.s.ifgerr = 1; */
11854 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11855 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11856 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11857 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11858 + gmx_rx_int_en.s.ovrerr = 1;
11859 + gmx_rx_int_en.s.niberr = 1;
11860 + gmx_rx_int_en.s.skperr = 1;
11861 + gmx_rx_int_en.s.rcverr = 1;
11862 + /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11863 + gmx_rx_int_en.s.alnerr = 1;
11864 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11865 + gmx_rx_int_en.s.jabber = 1;
11866 + gmx_rx_int_en.s.maxerr = 1;
11867 + gmx_rx_int_en.s.carext = 1;
11868 + gmx_rx_int_en.s.minerr = 1;
11869 + }
11870 + if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
11871 + /* Skipping gmx_rx_int_en.s.reserved_20_63 */
11872 + gmx_rx_int_en.s.pause_drp = 1;
11873 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11874 + /*gmx_rx_int_en.s.phy_spd = 1; */
11875 + /*gmx_rx_int_en.s.phy_link = 1; */
11876 + /*gmx_rx_int_en.s.ifgerr = 1; */
11877 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11878 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11879 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11880 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11881 + gmx_rx_int_en.s.ovrerr = 1;
11882 + gmx_rx_int_en.s.niberr = 1;
11883 + gmx_rx_int_en.s.skperr = 1;
11884 + gmx_rx_int_en.s.rcverr = 1;
11885 + /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11886 + gmx_rx_int_en.s.alnerr = 1;
11887 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11888 + gmx_rx_int_en.s.jabber = 1;
11889 + gmx_rx_int_en.s.maxerr = 1;
11890 + gmx_rx_int_en.s.carext = 1;
11891 + gmx_rx_int_en.s.minerr = 1;
11892 + }
11893 + if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
11894 + /* Skipping gmx_rx_int_en.s.reserved_29_63 */
11895 + gmx_rx_int_en.s.hg2cc = 1;
11896 + gmx_rx_int_en.s.hg2fld = 1;
11897 + gmx_rx_int_en.s.undat = 1;
11898 + gmx_rx_int_en.s.uneop = 1;
11899 + gmx_rx_int_en.s.unsop = 1;
11900 + gmx_rx_int_en.s.bad_term = 1;
11901 + gmx_rx_int_en.s.bad_seq = 0;
11902 + gmx_rx_int_en.s.rem_fault = 1;
11903 + gmx_rx_int_en.s.loc_fault = 0;
11904 + gmx_rx_int_en.s.pause_drp = 1;
11905 + /* Skipping gmx_rx_int_en.s.reserved_16_18 */
11906 + /*gmx_rx_int_en.s.ifgerr = 1; */
11907 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11908 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11909 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11910 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11911 + gmx_rx_int_en.s.ovrerr = 1;
11912 + /* Skipping gmx_rx_int_en.s.reserved_9_9 */
11913 + gmx_rx_int_en.s.skperr = 1;
11914 + gmx_rx_int_en.s.rcverr = 1;
11915 + /* Skipping gmx_rx_int_en.s.reserved_5_6 */
11916 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11917 + gmx_rx_int_en.s.jabber = 1;
11918 + /* Skipping gmx_rx_int_en.s.reserved_2_2 */
11919 + gmx_rx_int_en.s.carext = 1;
11920 + /* Skipping gmx_rx_int_en.s.reserved_0_0 */
11921 + }
11922 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, block), gmx_rx_int_en.u64);
11923 +}
11924 +/**
11925 + * __cvmx_interrupt_pcsx_intx_en_reg_enable enables all interrupt bits in cvmx_pcsx_intx_en_reg_t
11926 + */
11927 +void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block)
11928 +{
11929 + union cvmx_pcsx_intx_en_reg pcs_int_en_reg;
11930 + cvmx_write_csr(CVMX_PCSX_INTX_REG(index, block),
11931 + cvmx_read_csr(CVMX_PCSX_INTX_REG(index, block)));
11932 + pcs_int_en_reg.u64 = 0;
11933 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
11934 + /* Skipping pcs_int_en_reg.s.reserved_12_63 */
11935 + /*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */
11936 + pcs_int_en_reg.s.sync_bad_en = 1;
11937 + pcs_int_en_reg.s.an_bad_en = 1;
11938 + pcs_int_en_reg.s.rxlock_en = 1;
11939 + pcs_int_en_reg.s.rxbad_en = 1;
11940 + /*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */
11941 + pcs_int_en_reg.s.txbad_en = 1;
11942 + pcs_int_en_reg.s.txfifo_en = 1;
11943 + pcs_int_en_reg.s.txfifu_en = 1;
11944 + pcs_int_en_reg.s.an_err_en = 1;
11945 + /*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */
11946 + /*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */
11947 + }
11948 + if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
11949 + /* Skipping pcs_int_en_reg.s.reserved_12_63 */
11950 + /*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */
11951 + pcs_int_en_reg.s.sync_bad_en = 1;
11952 + pcs_int_en_reg.s.an_bad_en = 1;
11953 + pcs_int_en_reg.s.rxlock_en = 1;
11954 + pcs_int_en_reg.s.rxbad_en = 1;
11955 + /*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */
11956 + pcs_int_en_reg.s.txbad_en = 1;
11957 + pcs_int_en_reg.s.txfifo_en = 1;
11958 + pcs_int_en_reg.s.txfifu_en = 1;
11959 + pcs_int_en_reg.s.an_err_en = 1;
11960 + /*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */
11961 + /*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */
11962 + }
11963 + cvmx_write_csr(CVMX_PCSX_INTX_EN_REG(index, block), pcs_int_en_reg.u64);
11964 +}
11965 +/**
11966 + * __cvmx_interrupt_pcsxx_int_en_reg_enable enables all interrupt bits in cvmx_pcsxx_int_en_reg_t
11967 + */
11968 +void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index)
11969 +{
11970 + union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
11971 + cvmx_write_csr(CVMX_PCSXX_INT_REG(index),
11972 + cvmx_read_csr(CVMX_PCSXX_INT_REG(index)));
11973 + pcsx_int_en_reg.u64 = 0;
11974 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
11975 + /* Skipping pcsx_int_en_reg.s.reserved_6_63 */
11976 + pcsx_int_en_reg.s.algnlos_en = 1;
11977 + pcsx_int_en_reg.s.synlos_en = 1;
11978 + pcsx_int_en_reg.s.bitlckls_en = 1;
11979 + pcsx_int_en_reg.s.rxsynbad_en = 1;
11980 + pcsx_int_en_reg.s.rxbad_en = 1;
11981 + pcsx_int_en_reg.s.txflt_en = 1;
11982 + }
11983 + if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
11984 + /* Skipping pcsx_int_en_reg.s.reserved_6_63 */
11985 + pcsx_int_en_reg.s.algnlos_en = 1;
11986 + pcsx_int_en_reg.s.synlos_en = 1;
11987 + pcsx_int_en_reg.s.bitlckls_en = 0; /* Happens if XAUI module is not installed */
11988 + pcsx_int_en_reg.s.rxsynbad_en = 1;
11989 + pcsx_int_en_reg.s.rxbad_en = 1;
11990 + pcsx_int_en_reg.s.txflt_en = 1;
11991 + }
11992 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(index), pcsx_int_en_reg.u64);
11993 +}
11994 +
11995 +/**
11996 + * __cvmx_interrupt_spxx_int_msk_enable enables all interrupt bits in cvmx_spxx_int_msk_t
11997 + */
11998 +void __cvmx_interrupt_spxx_int_msk_enable(int index)
11999 +{
12000 + union cvmx_spxx_int_msk spx_int_msk;
12001 + cvmx_write_csr(CVMX_SPXX_INT_REG(index),
12002 + cvmx_read_csr(CVMX_SPXX_INT_REG(index)));
12003 + spx_int_msk.u64 = 0;
12004 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
12005 + /* Skipping spx_int_msk.s.reserved_12_63 */
12006 + spx_int_msk.s.calerr = 1;
12007 + spx_int_msk.s.syncerr = 1;
12008 + spx_int_msk.s.diperr = 1;
12009 + spx_int_msk.s.tpaovr = 1;
12010 + spx_int_msk.s.rsverr = 1;
12011 + spx_int_msk.s.drwnng = 1;
12012 + spx_int_msk.s.clserr = 1;
12013 + spx_int_msk.s.spiovr = 1;
12014 + /* Skipping spx_int_msk.s.reserved_2_3 */
12015 + spx_int_msk.s.abnorm = 1;
12016 + spx_int_msk.s.prtnxa = 1;
12017 + }
12018 + if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12019 + /* Skipping spx_int_msk.s.reserved_12_63 */
12020 + spx_int_msk.s.calerr = 1;
12021 + spx_int_msk.s.syncerr = 1;
12022 + spx_int_msk.s.diperr = 1;
12023 + spx_int_msk.s.tpaovr = 1;
12024 + spx_int_msk.s.rsverr = 1;
12025 + spx_int_msk.s.drwnng = 1;
12026 + spx_int_msk.s.clserr = 1;
12027 + spx_int_msk.s.spiovr = 1;
12028 + /* Skipping spx_int_msk.s.reserved_2_3 */
12029 + spx_int_msk.s.abnorm = 1;
12030 + spx_int_msk.s.prtnxa = 1;
12031 + }
12032 + cvmx_write_csr(CVMX_SPXX_INT_MSK(index), spx_int_msk.u64);
12033 +}
12034 +/**
12035 + * __cvmx_interrupt_stxx_int_msk_enable enables all interrupt bits in cvmx_stxx_int_msk_t
12036 + */
12037 +void __cvmx_interrupt_stxx_int_msk_enable(int index)
12038 +{
12039 + union cvmx_stxx_int_msk stx_int_msk;
12040 + cvmx_write_csr(CVMX_STXX_INT_REG(index),
12041 + cvmx_read_csr(CVMX_STXX_INT_REG(index)));
12042 + stx_int_msk.u64 = 0;
12043 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
12044 + /* Skipping stx_int_msk.s.reserved_8_63 */
12045 + stx_int_msk.s.frmerr = 1;
12046 + stx_int_msk.s.unxfrm = 1;
12047 + stx_int_msk.s.nosync = 1;
12048 + stx_int_msk.s.diperr = 1;
12049 + stx_int_msk.s.datovr = 1;
12050 + stx_int_msk.s.ovrbst = 1;
12051 + stx_int_msk.s.calpar1 = 1;
12052 + stx_int_msk.s.calpar0 = 1;
12053 + }
12054 + if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12055 + /* Skipping stx_int_msk.s.reserved_8_63 */
12056 + stx_int_msk.s.frmerr = 1;
12057 + stx_int_msk.s.unxfrm = 1;
12058 + stx_int_msk.s.nosync = 1;
12059 + stx_int_msk.s.diperr = 1;
12060 + stx_int_msk.s.datovr = 1;
12061 + stx_int_msk.s.ovrbst = 1;
12062 + stx_int_msk.s.calpar1 = 1;
12063 + stx_int_msk.s.calpar0 = 1;
12064 + }
12065 + cvmx_write_csr(CVMX_STXX_INT_MSK(index), stx_int_msk.u64);
12066 +}
12067 --- /dev/null
12068 +++ b/drivers/staging/octeon/cvmx-interrupt-rsl.c
12069 @@ -0,0 +1,140 @@
12070 +/***********************license start***************
12071 + * Author: Cavium Networks
12072 + *
12073 + * Contact: support@caviumnetworks.com
12074 + * This file is part of the OCTEON SDK
12075 + *
12076 + * Copyright (c) 2003-2008 Cavium Networks
12077 + *
12078 + * This file is free software; you can redistribute it and/or modify
12079 + * it under the terms of the GNU General Public License, Version 2, as
12080 + * published by the Free Software Foundation.
12081 + *
12082 + * This file is distributed in the hope that it will be useful, but
12083 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12084 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12085 + * NONINFRINGEMENT. See the GNU General Public License for more
12086 + * details.
12087 + *
12088 + * You should have received a copy of the GNU General Public License
12089 + * along with this file; if not, write to the Free Software
12090 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12091 + * or visit http://www.gnu.org/licenses/.
12092 + *
12093 + * This file may also be available under a different license from Cavium.
12094 + * Contact Cavium Networks for more information
12095 + ***********************license end**************************************/
12096 +
12097 +/*
12098 + * Utility functions to decode Octeon's RSL_INT_BLOCKS
12099 + * interrupts into error messages.
12100 + */
12101 +
12102 +#include <asm/octeon/octeon.h>
12103 +
12104 +#include "cvmx-asxx-defs.h"
12105 +#include "cvmx-gmxx-defs.h"
12106 +
12107 +#ifndef PRINT_ERROR
12108 +#define PRINT_ERROR(format, ...)
12109 +#endif
12110 +
12111 +void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block);
12112 +
12113 +/**
12114 + * Enable ASX error interrupts that exist on CN3XXX, CN50XX, and
12115 + * CN58XX.
12116 + *
12117 + * @block: Interface to enable 0-1
12118 + */
12119 +void __cvmx_interrupt_asxx_enable(int block)
12120 +{
12121 + int mask;
12122 + union cvmx_asxx_int_en csr;
12123 + /*
12124 + * CN38XX and CN58XX have two interfaces with 4 ports per
12125 + * interface. All other chips have a max of 3 ports on
12126 + * interface 0
12127 + */
12128 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
12129 + mask = 0xf; /* Set enables for 4 ports */
12130 + else
12131 + mask = 0x7; /* Set enables for 3 ports */
12132 +
12133 + /* Enable interface interrupts */
12134 + csr.u64 = cvmx_read_csr(CVMX_ASXX_INT_EN(block));
12135 + csr.s.txpsh = mask;
12136 + csr.s.txpop = mask;
12137 + csr.s.ovrflw = mask;
12138 + cvmx_write_csr(CVMX_ASXX_INT_EN(block), csr.u64);
12139 +}
12140 +/**
12141 + * Enable GMX error reporting for the supplied interface
12142 + *
12143 + * @interface: Interface to enable
12144 + */
12145 +void __cvmx_interrupt_gmxx_enable(int interface)
12146 +{
12147 + union cvmx_gmxx_inf_mode mode;
12148 + union cvmx_gmxx_tx_int_en gmx_tx_int_en;
12149 + int num_ports;
12150 + int index;
12151 +
12152 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
12153 +
12154 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
12155 + if (mode.s.en) {
12156 + switch (mode.cn56xx.mode) {
12157 + case 1: /* XAUI */
12158 + num_ports = 1;
12159 + break;
12160 + case 2: /* SGMII */
12161 + case 3: /* PICMG */
12162 + num_ports = 4;
12163 + break;
12164 + default: /* Disabled */
12165 + num_ports = 0;
12166 + break;
12167 + }
12168 + } else
12169 + num_ports = 0;
12170 + } else {
12171 + if (mode.s.en) {
12172 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
12173 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12174 + /*
12175 + * SPI on CN38XX and CN58XX report all
12176 + * errors through port 0. RGMII needs
12177 + * to check all 4 ports
12178 + */
12179 + if (mode.s.type)
12180 + num_ports = 1;
12181 + else
12182 + num_ports = 4;
12183 + } else {
12184 + /*
12185 + * CN30XX, CN31XX, and CN50XX have two
12186 + * or three ports. GMII and MII has 2,
12187 + * RGMII has three
12188 + */
12189 + if (mode.s.type)
12190 + num_ports = 2;
12191 + else
12192 + num_ports = 3;
12193 + }
12194 + } else
12195 + num_ports = 0;
12196 + }
12197 +
12198 + gmx_tx_int_en.u64 = 0;
12199 + if (num_ports) {
12200 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
12201 + || OCTEON_IS_MODEL(OCTEON_CN58XX))
12202 + gmx_tx_int_en.s.ncb_nxa = 1;
12203 + gmx_tx_int_en.s.pko_nxa = 1;
12204 + }
12205 + gmx_tx_int_en.s.undflw = (1 << num_ports) - 1;
12206 + cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
12207 + for (index = 0; index < num_ports; index++)
12208 + __cvmx_interrupt_gmxx_rxx_int_en_enable(index, interface);
12209 +}
12210 --- /dev/null
12211 +++ b/drivers/staging/octeon/cvmx-ipd.h
12212 @@ -0,0 +1,338 @@
12213 +/***********************license start***************
12214 + * Author: Cavium Networks
12215 + *
12216 + * Contact: support@caviumnetworks.com
12217 + * This file is part of the OCTEON SDK
12218 + *
12219 + * Copyright (c) 2003-2008 Cavium Networks
12220 + *
12221 + * This file is free software; you can redistribute it and/or modify
12222 + * it under the terms of the GNU General Public License, Version 2, as
12223 + * published by the Free Software Foundation.
12224 + *
12225 + * This file is distributed in the hope that it will be useful, but
12226 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12227 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12228 + * NONINFRINGEMENT. See the GNU General Public License for more
12229 + * details.
12230 + *
12231 + * You should have received a copy of the GNU General Public License
12232 + * along with this file; if not, write to the Free Software
12233 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12234 + * or visit http://www.gnu.org/licenses/.
12235 + *
12236 + * This file may also be available under a different license from Cavium.
12237 + * Contact Cavium Networks for more information
12238 + ***********************license end**************************************/
12239 +
12240 +/**
12241 + *
12242 + * Interface to the hardware Input Packet Data unit.
12243 + */
12244 +
12245 +#ifndef __CVMX_IPD_H__
12246 +#define __CVMX_IPD_H__
12247 +
12248 +#include <asm/octeon/octeon-feature.h>
12249 +
12250 +#include <asm/octeon/cvmx-ipd-defs.h>
12251 +
12252 +enum cvmx_ipd_mode {
12253 + CVMX_IPD_OPC_MODE_STT = 0LL, /* All blocks DRAM, not cached in L2 */
12254 + CVMX_IPD_OPC_MODE_STF = 1LL, /* All bloccks into L2 */
12255 + CVMX_IPD_OPC_MODE_STF1_STT = 2LL, /* 1st block L2, rest DRAM */
12256 + CVMX_IPD_OPC_MODE_STF2_STT = 3LL /* 1st, 2nd blocks L2, rest DRAM */
12257 +};
12258 +
12259 +#ifndef CVMX_ENABLE_LEN_M8_FIX
12260 +#define CVMX_ENABLE_LEN_M8_FIX 0
12261 +#endif
12262 +
12263 +/* CSR typedefs have been moved to cvmx-csr-*.h */
12264 +typedef union cvmx_ipd_1st_mbuff_skip cvmx_ipd_mbuff_first_skip_t;
12265 +typedef union cvmx_ipd_1st_next_ptr_back cvmx_ipd_first_next_ptr_back_t;
12266 +
12267 +typedef cvmx_ipd_mbuff_first_skip_t cvmx_ipd_mbuff_not_first_skip_t;
12268 +typedef cvmx_ipd_first_next_ptr_back_t cvmx_ipd_second_next_ptr_back_t;
12269 +
12270 +/**
12271 + * Configure IPD
12272 + *
12273 + * @mbuff_size: Packets buffer size in 8 byte words
12274 + * @first_mbuff_skip:
12275 + * Number of 8 byte words to skip in the first buffer
12276 + * @not_first_mbuff_skip:
12277 + * Number of 8 byte words to skip in each following buffer
12278 + * @first_back: Must be same as first_mbuff_skip / 128
12279 + * @second_back:
12280 + * Must be same as not_first_mbuff_skip / 128
12281 + * @wqe_fpa_pool:
12282 + * FPA pool to get work entries from
12283 + * @cache_mode:
12284 + * @back_pres_enable_flag:
12285 + * Enable or disable port back pressure
12286 + */
12287 +static inline void cvmx_ipd_config(uint64_t mbuff_size,
12288 + uint64_t first_mbuff_skip,
12289 + uint64_t not_first_mbuff_skip,
12290 + uint64_t first_back,
12291 + uint64_t second_back,
12292 + uint64_t wqe_fpa_pool,
12293 + enum cvmx_ipd_mode cache_mode,
12294 + uint64_t back_pres_enable_flag)
12295 +{
12296 + cvmx_ipd_mbuff_first_skip_t first_skip;
12297 + cvmx_ipd_mbuff_not_first_skip_t not_first_skip;
12298 + union cvmx_ipd_packet_mbuff_size size;
12299 + cvmx_ipd_first_next_ptr_back_t first_back_struct;
12300 + cvmx_ipd_second_next_ptr_back_t second_back_struct;
12301 + union cvmx_ipd_wqe_fpa_queue wqe_pool;
12302 + union cvmx_ipd_ctl_status ipd_ctl_reg;
12303 +
12304 + first_skip.u64 = 0;
12305 + first_skip.s.skip_sz = first_mbuff_skip;
12306 + cvmx_write_csr(CVMX_IPD_1ST_MBUFF_SKIP, first_skip.u64);
12307 +
12308 + not_first_skip.u64 = 0;
12309 + not_first_skip.s.skip_sz = not_first_mbuff_skip;
12310 + cvmx_write_csr(CVMX_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.u64);
12311 +
12312 + size.u64 = 0;
12313 + size.s.mb_size = mbuff_size;
12314 + cvmx_write_csr(CVMX_IPD_PACKET_MBUFF_SIZE, size.u64);
12315 +
12316 + first_back_struct.u64 = 0;
12317 + first_back_struct.s.back = first_back;
12318 + cvmx_write_csr(CVMX_IPD_1st_NEXT_PTR_BACK, first_back_struct.u64);
12319 +
12320 + second_back_struct.u64 = 0;
12321 + second_back_struct.s.back = second_back;
12322 + cvmx_write_csr(CVMX_IPD_2nd_NEXT_PTR_BACK, second_back_struct.u64);
12323 +
12324 + wqe_pool.u64 = 0;
12325 + wqe_pool.s.wqe_pool = wqe_fpa_pool;
12326 + cvmx_write_csr(CVMX_IPD_WQE_FPA_QUEUE, wqe_pool.u64);
12327 +
12328 + ipd_ctl_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12329 + ipd_ctl_reg.s.opc_mode = cache_mode;
12330 + ipd_ctl_reg.s.pbp_en = back_pres_enable_flag;
12331 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_reg.u64);
12332 +
12333 + /* Note: the example RED code that used to be here has been moved to
12334 + cvmx_helper_setup_red */
12335 +}
12336 +
12337 +/**
12338 + * Enable IPD
12339 + */
12340 +static inline void cvmx_ipd_enable(void)
12341 +{
12342 + union cvmx_ipd_ctl_status ipd_reg;
12343 + ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12344 + if (ipd_reg.s.ipd_en) {
12345 + cvmx_dprintf
12346 + ("Warning: Enabling IPD when IPD already enabled.\n");
12347 + }
12348 + ipd_reg.s.ipd_en = 1;
12349 +#if CVMX_ENABLE_LEN_M8_FIX
12350 + if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
12351 + ipd_reg.s.len_m8 = TRUE;
12352 +#endif
12353 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
12354 +}
12355 +
12356 +/**
12357 + * Disable IPD
12358 + */
12359 +static inline void cvmx_ipd_disable(void)
12360 +{
12361 + union cvmx_ipd_ctl_status ipd_reg;
12362 + ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12363 + ipd_reg.s.ipd_en = 0;
12364 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
12365 +}
12366 +
12367 +/**
12368 + * Supportive function for cvmx_fpa_shutdown_pool.
12369 + */
12370 +static inline void cvmx_ipd_free_ptr(void)
12371 +{
12372 + /* Only CN38XXp{1,2} cannot read pointer out of the IPD */
12373 + if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)
12374 + && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
12375 + int no_wptr = 0;
12376 + union cvmx_ipd_ptr_count ipd_ptr_count;
12377 + ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
12378 +
12379 + /* Handle Work Queue Entry in cn56xx and cn52xx */
12380 + if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
12381 + union cvmx_ipd_ctl_status ipd_ctl_status;
12382 + ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12383 + if (ipd_ctl_status.s.no_wptr)
12384 + no_wptr = 1;
12385 + }
12386 +
12387 + /* Free the prefetched WQE */
12388 + if (ipd_ptr_count.s.wqev_cnt) {
12389 + union cvmx_ipd_wqe_ptr_valid ipd_wqe_ptr_valid;
12390 + ipd_wqe_ptr_valid.u64 =
12391 + cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID);
12392 + if (no_wptr)
12393 + cvmx_fpa_free(cvmx_phys_to_ptr
12394 + ((uint64_t) ipd_wqe_ptr_valid.s.
12395 + ptr << 7), CVMX_FPA_PACKET_POOL,
12396 + 0);
12397 + else
12398 + cvmx_fpa_free(cvmx_phys_to_ptr
12399 + ((uint64_t) ipd_wqe_ptr_valid.s.
12400 + ptr << 7), CVMX_FPA_WQE_POOL, 0);
12401 + }
12402 +
12403 + /* Free all WQE in the fifo */
12404 + if (ipd_ptr_count.s.wqe_pcnt) {
12405 + int i;
12406 + union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
12407 + ipd_pwp_ptr_fifo_ctl.u64 =
12408 + cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12409 + for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
12410 + ipd_pwp_ptr_fifo_ctl.s.cena = 0;
12411 + ipd_pwp_ptr_fifo_ctl.s.raddr =
12412 + ipd_pwp_ptr_fifo_ctl.s.max_cnts +
12413 + (ipd_pwp_ptr_fifo_ctl.s.wraddr +
12414 + i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
12415 + cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12416 + ipd_pwp_ptr_fifo_ctl.u64);
12417 + ipd_pwp_ptr_fifo_ctl.u64 =
12418 + cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12419 + if (no_wptr)
12420 + cvmx_fpa_free(cvmx_phys_to_ptr
12421 + ((uint64_t)
12422 + ipd_pwp_ptr_fifo_ctl.s.
12423 + ptr << 7),
12424 + CVMX_FPA_PACKET_POOL, 0);
12425 + else
12426 + cvmx_fpa_free(cvmx_phys_to_ptr
12427 + ((uint64_t)
12428 + ipd_pwp_ptr_fifo_ctl.s.
12429 + ptr << 7),
12430 + CVMX_FPA_WQE_POOL, 0);
12431 + }
12432 + ipd_pwp_ptr_fifo_ctl.s.cena = 1;
12433 + cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12434 + ipd_pwp_ptr_fifo_ctl.u64);
12435 + }
12436 +
12437 + /* Free the prefetched packet */
12438 + if (ipd_ptr_count.s.pktv_cnt) {
12439 + union cvmx_ipd_pkt_ptr_valid ipd_pkt_ptr_valid;
12440 + ipd_pkt_ptr_valid.u64 =
12441 + cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID);
12442 + cvmx_fpa_free(cvmx_phys_to_ptr
12443 + (ipd_pkt_ptr_valid.s.ptr << 7),
12444 + CVMX_FPA_PACKET_POOL, 0);
12445 + }
12446 +
12447 + /* Free the per port prefetched packets */
12448 + if (1) {
12449 + int i;
12450 + union cvmx_ipd_prc_port_ptr_fifo_ctl
12451 + ipd_prc_port_ptr_fifo_ctl;
12452 + ipd_prc_port_ptr_fifo_ctl.u64 =
12453 + cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
12454 +
12455 + for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
12456 + i++) {
12457 + ipd_prc_port_ptr_fifo_ctl.s.cena = 0;
12458 + ipd_prc_port_ptr_fifo_ctl.s.raddr =
12459 + i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
12460 + cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
12461 + ipd_prc_port_ptr_fifo_ctl.u64);
12462 + ipd_prc_port_ptr_fifo_ctl.u64 =
12463 + cvmx_read_csr
12464 + (CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
12465 + cvmx_fpa_free(cvmx_phys_to_ptr
12466 + ((uint64_t)
12467 + ipd_prc_port_ptr_fifo_ctl.s.
12468 + ptr << 7), CVMX_FPA_PACKET_POOL,
12469 + 0);
12470 + }
12471 + ipd_prc_port_ptr_fifo_ctl.s.cena = 1;
12472 + cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
12473 + ipd_prc_port_ptr_fifo_ctl.u64);
12474 + }
12475 +
12476 + /* Free all packets in the holding fifo */
12477 + if (ipd_ptr_count.s.pfif_cnt) {
12478 + int i;
12479 + union cvmx_ipd_prc_hold_ptr_fifo_ctl
12480 + ipd_prc_hold_ptr_fifo_ctl;
12481 +
12482 + ipd_prc_hold_ptr_fifo_ctl.u64 =
12483 + cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
12484 +
12485 + for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
12486 + ipd_prc_hold_ptr_fifo_ctl.s.cena = 0;
12487 + ipd_prc_hold_ptr_fifo_ctl.s.raddr =
12488 + (ipd_prc_hold_ptr_fifo_ctl.s.praddr +
12489 + i) % ipd_prc_hold_ptr_fifo_ctl.s.max_pkt;
12490 + cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
12491 + ipd_prc_hold_ptr_fifo_ctl.u64);
12492 + ipd_prc_hold_ptr_fifo_ctl.u64 =
12493 + cvmx_read_csr
12494 + (CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
12495 + cvmx_fpa_free(cvmx_phys_to_ptr
12496 + ((uint64_t)
12497 + ipd_prc_hold_ptr_fifo_ctl.s.
12498 + ptr << 7), CVMX_FPA_PACKET_POOL,
12499 + 0);
12500 + }
12501 + ipd_prc_hold_ptr_fifo_ctl.s.cena = 1;
12502 + cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
12503 + ipd_prc_hold_ptr_fifo_ctl.u64);
12504 + }
12505 +
12506 + /* Free all packets in the fifo */
12507 + if (ipd_ptr_count.s.pkt_pcnt) {
12508 + int i;
12509 + union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
12510 + ipd_pwp_ptr_fifo_ctl.u64 =
12511 + cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12512 +
12513 + for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
12514 + ipd_pwp_ptr_fifo_ctl.s.cena = 0;
12515 + ipd_pwp_ptr_fifo_ctl.s.raddr =
12516 + (ipd_pwp_ptr_fifo_ctl.s.praddr +
12517 + i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
12518 + cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12519 + ipd_pwp_ptr_fifo_ctl.u64);
12520 + ipd_pwp_ptr_fifo_ctl.u64 =
12521 + cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12522 + cvmx_fpa_free(cvmx_phys_to_ptr
12523 + ((uint64_t) ipd_pwp_ptr_fifo_ctl.
12524 + s.ptr << 7),
12525 + CVMX_FPA_PACKET_POOL, 0);
12526 + }
12527 + ipd_pwp_ptr_fifo_ctl.s.cena = 1;
12528 + cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12529 + ipd_pwp_ptr_fifo_ctl.u64);
12530 + }
12531 +
12532 + /* Reset the IPD to get all buffers out of it */
12533 + {
12534 + union cvmx_ipd_ctl_status ipd_ctl_status;
12535 + ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12536 + ipd_ctl_status.s.reset = 1;
12537 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);
12538 + }
12539 +
12540 + /* Reset the PIP */
12541 + {
12542 + union cvmx_pip_sft_rst pip_sft_rst;
12543 + pip_sft_rst.u64 = cvmx_read_csr(CVMX_PIP_SFT_RST);
12544 + pip_sft_rst.s.rst = 1;
12545 + cvmx_write_csr(CVMX_PIP_SFT_RST, pip_sft_rst.u64);
12546 + }
12547 + }
12548 +}
12549 +
12550 +#endif /* __CVMX_IPD_H__ */
12551 --- /dev/null
12552 +++ b/drivers/staging/octeon/cvmx-mdio.h
12553 @@ -0,0 +1,506 @@
12554 +/***********************license start***************
12555 + * Author: Cavium Networks
12556 + *
12557 + * Contact: support@caviumnetworks.com
12558 + * This file is part of the OCTEON SDK
12559 + *
12560 + * Copyright (c) 2003-2008 Cavium Networks
12561 + *
12562 + * This file is free software; you can redistribute it and/or modify
12563 + * it under the terms of the GNU General Public License, Version 2, as
12564 + * published by the Free Software Foundation.
12565 + *
12566 + * This file is distributed in the hope that it will be useful, but
12567 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12568 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12569 + * NONINFRINGEMENT. See the GNU General Public License for more
12570 + * details.
12571 + *
12572 + * You should have received a copy of the GNU General Public License
12573 + * along with this file; if not, write to the Free Software
12574 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12575 + * or visit http://www.gnu.org/licenses/.
12576 + *
12577 + * This file may also be available under a different license from Cavium.
12578 + * Contact Cavium Networks for more information
12579 + ***********************license end**************************************/
12580 +
12581 +/*
12582 + *
12583 + * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3
12584 + * clause 22 and clause 45 operations.
12585 + *
12586 + */
12587 +
12588 +#ifndef __CVMX_MIO_H__
12589 +#define __CVMX_MIO_H__
12590 +
12591 +#include "cvmx-smix-defs.h"
12592 +
12593 +/**
12594 + * PHY register 0 from the 802.3 spec
12595 + */
12596 +#define CVMX_MDIO_PHY_REG_CONTROL 0
12597 +typedef union {
12598 + uint16_t u16;
12599 + struct {
12600 + uint16_t reset:1;
12601 + uint16_t loopback:1;
12602 + uint16_t speed_lsb:1;
12603 + uint16_t autoneg_enable:1;
12604 + uint16_t power_down:1;
12605 + uint16_t isolate:1;
12606 + uint16_t restart_autoneg:1;
12607 + uint16_t duplex:1;
12608 + uint16_t collision_test:1;
12609 + uint16_t speed_msb:1;
12610 + uint16_t unidirectional_enable:1;
12611 + uint16_t reserved_0_4:5;
12612 + } s;
12613 +} cvmx_mdio_phy_reg_control_t;
12614 +
12615 +/**
12616 + * PHY register 1 from the 802.3 spec
12617 + */
12618 +#define CVMX_MDIO_PHY_REG_STATUS 1
12619 +typedef union {
12620 + uint16_t u16;
12621 + struct {
12622 + uint16_t capable_100base_t4:1;
12623 + uint16_t capable_100base_x_full:1;
12624 + uint16_t capable_100base_x_half:1;
12625 + uint16_t capable_10_full:1;
12626 + uint16_t capable_10_half:1;
12627 + uint16_t capable_100base_t2_full:1;
12628 + uint16_t capable_100base_t2_half:1;
12629 + uint16_t capable_extended_status:1;
12630 + uint16_t capable_unidirectional:1;
12631 + uint16_t capable_mf_preamble_suppression:1;
12632 + uint16_t autoneg_complete:1;
12633 + uint16_t remote_fault:1;
12634 + uint16_t capable_autoneg:1;
12635 + uint16_t link_status:1;
12636 + uint16_t jabber_detect:1;
12637 + uint16_t capable_extended_registers:1;
12638 +
12639 + } s;
12640 +} cvmx_mdio_phy_reg_status_t;
12641 +
12642 +/**
12643 + * PHY register 2 from the 802.3 spec
12644 + */
12645 +#define CVMX_MDIO_PHY_REG_ID1 2
12646 +typedef union {
12647 + uint16_t u16;
12648 + struct {
12649 + uint16_t oui_bits_3_18;
12650 + } s;
12651 +} cvmx_mdio_phy_reg_id1_t;
12652 +
12653 +/**
12654 + * PHY register 3 from the 802.3 spec
12655 + */
12656 +#define CVMX_MDIO_PHY_REG_ID2 3
12657 +typedef union {
12658 + uint16_t u16;
12659 + struct {
12660 + uint16_t oui_bits_19_24:6;
12661 + uint16_t model:6;
12662 + uint16_t revision:4;
12663 + } s;
12664 +} cvmx_mdio_phy_reg_id2_t;
12665 +
12666 +/**
12667 + * PHY register 4 from the 802.3 spec
12668 + */
12669 +#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4
12670 +typedef union {
12671 + uint16_t u16;
12672 + struct {
12673 + uint16_t next_page:1;
12674 + uint16_t reserved_14:1;
12675 + uint16_t remote_fault:1;
12676 + uint16_t reserved_12:1;
12677 + uint16_t asymmetric_pause:1;
12678 + uint16_t pause:1;
12679 + uint16_t advert_100base_t4:1;
12680 + uint16_t advert_100base_tx_full:1;
12681 + uint16_t advert_100base_tx_half:1;
12682 + uint16_t advert_10base_tx_full:1;
12683 + uint16_t advert_10base_tx_half:1;
12684 + uint16_t selector:5;
12685 + } s;
12686 +} cvmx_mdio_phy_reg_autoneg_adver_t;
12687 +
12688 +/**
12689 + * PHY register 5 from the 802.3 spec
12690 + */
12691 +#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5
12692 +typedef union {
12693 + uint16_t u16;
12694 + struct {
12695 + uint16_t next_page:1;
12696 + uint16_t ack:1;
12697 + uint16_t remote_fault:1;
12698 + uint16_t reserved_12:1;
12699 + uint16_t asymmetric_pause:1;
12700 + uint16_t pause:1;
12701 + uint16_t advert_100base_t4:1;
12702 + uint16_t advert_100base_tx_full:1;
12703 + uint16_t advert_100base_tx_half:1;
12704 + uint16_t advert_10base_tx_full:1;
12705 + uint16_t advert_10base_tx_half:1;
12706 + uint16_t selector:5;
12707 + } s;
12708 +} cvmx_mdio_phy_reg_link_partner_ability_t;
12709 +
12710 +/**
12711 + * PHY register 6 from the 802.3 spec
12712 + */
12713 +#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6
12714 +typedef union {
12715 + uint16_t u16;
12716 + struct {
12717 + uint16_t reserved_5_15:11;
12718 + uint16_t parallel_detection_fault:1;
12719 + uint16_t link_partner_next_page_capable:1;
12720 + uint16_t local_next_page_capable:1;
12721 + uint16_t page_received:1;
12722 + uint16_t link_partner_autoneg_capable:1;
12723 +
12724 + } s;
12725 +} cvmx_mdio_phy_reg_autoneg_expansion_t;
12726 +
12727 +/**
12728 + * PHY register 9 from the 802.3 spec
12729 + */
12730 +#define CVMX_MDIO_PHY_REG_CONTROL_1000 9
12731 +typedef union {
12732 + uint16_t u16;
12733 + struct {
12734 + uint16_t test_mode:3;
12735 + uint16_t manual_master_slave:1;
12736 + uint16_t master:1;
12737 + uint16_t port_type:1;
12738 + uint16_t advert_1000base_t_full:1;
12739 + uint16_t advert_1000base_t_half:1;
12740 + uint16_t reserved_0_7:8;
12741 + } s;
12742 +} cvmx_mdio_phy_reg_control_1000_t;
12743 +
12744 +/**
12745 + * PHY register 10 from the 802.3 spec
12746 + */
12747 +#define CVMX_MDIO_PHY_REG_STATUS_1000 10
12748 +typedef union {
12749 + uint16_t u16;
12750 + struct {
12751 + uint16_t master_slave_fault:1;
12752 + uint16_t is_master:1;
12753 + uint16_t local_receiver_ok:1;
12754 + uint16_t remote_receiver_ok:1;
12755 + uint16_t remote_capable_1000base_t_full:1;
12756 + uint16_t remote_capable_1000base_t_half:1;
12757 + uint16_t reserved_8_9:2;
12758 + uint16_t idle_error_count:8;
12759 + } s;
12760 +} cvmx_mdio_phy_reg_status_1000_t;
12761 +
12762 +/**
12763 + * PHY register 15 from the 802.3 spec
12764 + */
12765 +#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15
12766 +typedef union {
12767 + uint16_t u16;
12768 + struct {
12769 + uint16_t capable_1000base_x_full:1;
12770 + uint16_t capable_1000base_x_half:1;
12771 + uint16_t capable_1000base_t_full:1;
12772 + uint16_t capable_1000base_t_half:1;
12773 + uint16_t reserved_0_11:12;
12774 + } s;
12775 +} cvmx_mdio_phy_reg_extended_status_t;
12776 +
12777 +/**
12778 + * PHY register 13 from the 802.3 spec
12779 + */
12780 +#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13
12781 +typedef union {
12782 + uint16_t u16;
12783 + struct {
12784 + uint16_t function:2;
12785 + uint16_t reserved_5_13:9;
12786 + uint16_t devad:5;
12787 + } s;
12788 +} cvmx_mdio_phy_reg_mmd_control_t;
12789 +
12790 +/**
12791 + * PHY register 14 from the 802.3 spec
12792 + */
12793 +#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14
12794 +typedef union {
12795 + uint16_t u16;
12796 + struct {
12797 + uint16_t address_data:16;
12798 + } s;
12799 +} cvmx_mdio_phy_reg_mmd_address_data_t;
12800 +
12801 +/* Operating request encodings. */
12802 +#define MDIO_CLAUSE_22_WRITE 0
12803 +#define MDIO_CLAUSE_22_READ 1
12804 +
12805 +#define MDIO_CLAUSE_45_ADDRESS 0
12806 +#define MDIO_CLAUSE_45_WRITE 1
12807 +#define MDIO_CLAUSE_45_READ_INC 2
12808 +#define MDIO_CLAUSE_45_READ 3
12809 +
12810 +/* MMD identifiers, mostly for accessing devices withing XENPAK modules. */
12811 +#define CVMX_MMD_DEVICE_PMA_PMD 1
12812 +#define CVMX_MMD_DEVICE_WIS 2
12813 +#define CVMX_MMD_DEVICE_PCS 3
12814 +#define CVMX_MMD_DEVICE_PHY_XS 4
12815 +#define CVMX_MMD_DEVICE_DTS_XS 5
12816 +#define CVMX_MMD_DEVICE_TC 6
12817 +#define CVMX_MMD_DEVICE_CL22_EXT 29
12818 +#define CVMX_MMD_DEVICE_VENDOR_1 30
12819 +#define CVMX_MMD_DEVICE_VENDOR_2 31
12820 +
12821 +/* Helper function to put MDIO interface into clause 45 mode */
12822 +static inline void __cvmx_mdio_set_clause45_mode(int bus_id)
12823 +{
12824 + union cvmx_smix_clk smi_clk;
12825 + /* Put bus into clause 45 mode */
12826 + smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
12827 + smi_clk.s.mode = 1;
12828 + smi_clk.s.preamble = 1;
12829 + cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
12830 +}
12831 +
12832 +/* Helper function to put MDIO interface into clause 22 mode */
12833 +static inline void __cvmx_mdio_set_clause22_mode(int bus_id)
12834 +{
12835 + union cvmx_smix_clk smi_clk;
12836 + /* Put bus into clause 22 mode */
12837 + smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
12838 + smi_clk.s.mode = 0;
12839 + cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
12840 +}
12841 +
12842 +/**
12843 + * Perform an MII read. This function is used to read PHY
12844 + * registers controlling auto negotiation.
12845 + *
12846 + * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
12847 + * support multiple busses.
12848 + * @phy_id: The MII phy id
12849 + * @location: Register location to read
12850 + *
12851 + * Returns Result from the read or -1 on failure
12852 + */
12853 +static inline int cvmx_mdio_read(int bus_id, int phy_id, int location)
12854 +{
12855 + union cvmx_smix_cmd smi_cmd;
12856 + union cvmx_smix_rd_dat smi_rd;
12857 + int timeout = 1000;
12858 +
12859 + if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12860 + __cvmx_mdio_set_clause22_mode(bus_id);
12861 +
12862 + smi_cmd.u64 = 0;
12863 + smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ;
12864 + smi_cmd.s.phy_adr = phy_id;
12865 + smi_cmd.s.reg_adr = location;
12866 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12867 +
12868 + do {
12869 + cvmx_wait(1000);
12870 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
12871 + } while (smi_rd.s.pending && timeout--);
12872 +
12873 + if (smi_rd.s.val)
12874 + return smi_rd.s.dat;
12875 + else
12876 + return -1;
12877 +}
12878 +
12879 +/**
12880 + * Perform an MII write. This function is used to write PHY
12881 + * registers controlling auto negotiation.
12882 + *
12883 + * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
12884 + * support multiple busses.
12885 + * @phy_id: The MII phy id
12886 + * @location: Register location to write
12887 + * @val: Value to write
12888 + *
12889 + * Returns -1 on error
12890 + * 0 on success
12891 + */
12892 +static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val)
12893 +{
12894 + union cvmx_smix_cmd smi_cmd;
12895 + union cvmx_smix_wr_dat smi_wr;
12896 + int timeout = 1000;
12897 +
12898 + if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12899 + __cvmx_mdio_set_clause22_mode(bus_id);
12900 +
12901 + smi_wr.u64 = 0;
12902 + smi_wr.s.dat = val;
12903 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
12904 +
12905 + smi_cmd.u64 = 0;
12906 + smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE;
12907 + smi_cmd.s.phy_adr = phy_id;
12908 + smi_cmd.s.reg_adr = location;
12909 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12910 +
12911 + do {
12912 + cvmx_wait(1000);
12913 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
12914 + } while (smi_wr.s.pending && --timeout);
12915 + if (timeout <= 0)
12916 + return -1;
12917 +
12918 + return 0;
12919 +}
12920 +
12921 +/**
12922 + * Perform an IEEE 802.3 clause 45 MII read. This function is used to
12923 + * read PHY registers controlling auto negotiation.
12924 + *
12925 + * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
12926 + * support multiple busses.
12927 + * @phy_id: The MII phy id
12928 + * @device: MDIO Managable Device (MMD) id
12929 + * @location: Register location to read
12930 + *
12931 + * Returns Result from the read or -1 on failure
12932 + */
12933 +
12934 +static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
12935 + int location)
12936 +{
12937 + union cvmx_smix_cmd smi_cmd;
12938 + union cvmx_smix_rd_dat smi_rd;
12939 + union cvmx_smix_wr_dat smi_wr;
12940 + int timeout = 1000;
12941 +
12942 + if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12943 + return -1;
12944 +
12945 + __cvmx_mdio_set_clause45_mode(bus_id);
12946 +
12947 + smi_wr.u64 = 0;
12948 + smi_wr.s.dat = location;
12949 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
12950 +
12951 + smi_cmd.u64 = 0;
12952 + smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
12953 + smi_cmd.s.phy_adr = phy_id;
12954 + smi_cmd.s.reg_adr = device;
12955 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12956 +
12957 + do {
12958 + cvmx_wait(1000);
12959 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
12960 + } while (smi_wr.s.pending && --timeout);
12961 + if (timeout <= 0) {
12962 + cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
12963 + "device %2d register %2d TIME OUT(address)\n",
12964 + bus_id, phy_id, device, location);
12965 + return -1;
12966 + }
12967 +
12968 + smi_cmd.u64 = 0;
12969 + smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ;
12970 + smi_cmd.s.phy_adr = phy_id;
12971 + smi_cmd.s.reg_adr = device;
12972 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12973 +
12974 + do {
12975 + cvmx_wait(1000);
12976 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
12977 + } while (smi_rd.s.pending && timeout--);
12978 +
12979 + if (timeout <= 0) {
12980 + cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
12981 + "device %2d register %2d TIME OUT(data)\n",
12982 + bus_id, phy_id, device, location);
12983 + return -1;
12984 + }
12985 +
12986 + if (smi_rd.s.val)
12987 + return smi_rd.s.dat;
12988 + else {
12989 + cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
12990 + "device %2d register %2d INVALID READ\n",
12991 + bus_id, phy_id, device, location);
12992 + return -1;
12993 + }
12994 +}
12995 +
12996 +/**
12997 + * Perform an IEEE 802.3 clause 45 MII write. This function is used to
12998 + * write PHY registers controlling auto negotiation.
12999 + *
13000 + * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
13001 + * support multiple busses.
13002 + * @phy_id: The MII phy id
13003 + * @device: MDIO Managable Device (MMD) id
13004 + * @location: Register location to write
13005 + * @val: Value to write
13006 + *
13007 + * Returns -1 on error
13008 + * 0 on success
13009 + */
13010 +static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device,
13011 + int location, int val)
13012 +{
13013 + union cvmx_smix_cmd smi_cmd;
13014 + union cvmx_smix_wr_dat smi_wr;
13015 + int timeout = 1000;
13016 +
13017 + if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
13018 + return -1;
13019 +
13020 + __cvmx_mdio_set_clause45_mode(bus_id);
13021 +
13022 + smi_wr.u64 = 0;
13023 + smi_wr.s.dat = location;
13024 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
13025 +
13026 + smi_cmd.u64 = 0;
13027 + smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
13028 + smi_cmd.s.phy_adr = phy_id;
13029 + smi_cmd.s.reg_adr = device;
13030 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13031 +
13032 + do {
13033 + cvmx_wait(1000);
13034 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13035 + } while (smi_wr.s.pending && --timeout);
13036 + if (timeout <= 0)
13037 + return -1;
13038 +
13039 + smi_wr.u64 = 0;
13040 + smi_wr.s.dat = val;
13041 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
13042 +
13043 + smi_cmd.u64 = 0;
13044 + smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE;
13045 + smi_cmd.s.phy_adr = phy_id;
13046 + smi_cmd.s.reg_adr = device;
13047 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13048 +
13049 + do {
13050 + cvmx_wait(1000);
13051 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13052 + } while (smi_wr.s.pending && --timeout);
13053 + if (timeout <= 0)
13054 + return -1;
13055 +
13056 + return 0;
13057 +}
13058 +
13059 +#endif
13060 --- /dev/null
13061 +++ b/drivers/staging/octeon/cvmx-packet.h
13062 @@ -0,0 +1,65 @@
13063 +/***********************license start***************
13064 + * Author: Cavium Networks
13065 + *
13066 + * Contact: support@caviumnetworks.com
13067 + * This file is part of the OCTEON SDK
13068 + *
13069 + * Copyright (c) 2003-2008 Cavium Networks
13070 + *
13071 + * This file is free software; you can redistribute it and/or modify
13072 + * it under the terms of the GNU General Public License, Version 2, as
13073 + * published by the Free Software Foundation.
13074 + *
13075 + * This file is distributed in the hope that it will be useful, but
13076 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13077 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13078 + * NONINFRINGEMENT. See the GNU General Public License for more
13079 + * details.
13080 + *
13081 + * You should have received a copy of the GNU General Public License
13082 + * along with this file; if not, write to the Free Software
13083 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13084 + * or visit http://www.gnu.org/licenses/.
13085 + *
13086 + * This file may also be available under a different license from Cavium.
13087 + * Contact Cavium Networks for more information
13088 + ***********************license end**************************************/
13089 +
13090 +/**
13091 + *
13092 + * Packet buffer defines.
13093 + */
13094 +
13095 +#ifndef __CVMX_PACKET_H__
13096 +#define __CVMX_PACKET_H__
13097 +
13098 +/**
13099 + * This structure defines a buffer pointer on Octeon
13100 + */
13101 +union cvmx_buf_ptr {
13102 + void *ptr;
13103 + uint64_t u64;
13104 + struct {
13105 + /*
13106 + * if set, invert the "free" pick of the overall
13107 + * packet. HW always sets this bit to 0 on inbound
13108 + * packet
13109 + */
13110 + uint64_t i:1;
13111 + /*
13112 + * Indicates the amount to back up to get to the
13113 + * buffer start in cache lines. In most cases this is
13114 + * less than one complete cache line, so the value is
13115 + * zero.
13116 + */
13117 + uint64_t back:4;
13118 + /* The pool that the buffer came from / goes to */
13119 + uint64_t pool:3;
13120 + /* The size of the segment pointed to by addr (in bytes) */
13121 + uint64_t size:16;
13122 + /* Pointer to the first byte of the data, NOT buffer */
13123 + uint64_t addr:40;
13124 + } s;
13125 +};
13126 +
13127 +#endif /* __CVMX_PACKET_H__ */
13128 --- /dev/null
13129 +++ b/drivers/staging/octeon/cvmx-pcsx-defs.h
13130 @@ -0,0 +1,370 @@
13131 +/***********************license start***************
13132 + * Author: Cavium Networks
13133 + *
13134 + * Contact: support@caviumnetworks.com
13135 + * This file is part of the OCTEON SDK
13136 + *
13137 + * Copyright (c) 2003-2008 Cavium Networks
13138 + *
13139 + * This file is free software; you can redistribute it and/or modify
13140 + * it under the terms of the GNU General Public License, Version 2, as
13141 + * published by the Free Software Foundation.
13142 + *
13143 + * This file is distributed in the hope that it will be useful, but
13144 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13145 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13146 + * NONINFRINGEMENT. See the GNU General Public License for more
13147 + * details.
13148 + *
13149 + * You should have received a copy of the GNU General Public License
13150 + * along with this file; if not, write to the Free Software
13151 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13152 + * or visit http://www.gnu.org/licenses/.
13153 + *
13154 + * This file may also be available under a different license from Cavium.
13155 + * Contact Cavium Networks for more information
13156 + ***********************license end**************************************/
13157 +
13158 +#ifndef __CVMX_PCSX_DEFS_H__
13159 +#define __CVMX_PCSX_DEFS_H__
13160 +
13161 +#define CVMX_PCSX_ANX_ADV_REG(offset, block_id) \
13162 + CVMX_ADD_IO_SEG(0x00011800B0001010ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13163 +#define CVMX_PCSX_ANX_EXT_ST_REG(offset, block_id) \
13164 + CVMX_ADD_IO_SEG(0x00011800B0001028ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13165 +#define CVMX_PCSX_ANX_LP_ABIL_REG(offset, block_id) \
13166 + CVMX_ADD_IO_SEG(0x00011800B0001018ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13167 +#define CVMX_PCSX_ANX_RESULTS_REG(offset, block_id) \
13168 + CVMX_ADD_IO_SEG(0x00011800B0001020ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13169 +#define CVMX_PCSX_INTX_EN_REG(offset, block_id) \
13170 + CVMX_ADD_IO_SEG(0x00011800B0001088ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13171 +#define CVMX_PCSX_INTX_REG(offset, block_id) \
13172 + CVMX_ADD_IO_SEG(0x00011800B0001080ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13173 +#define CVMX_PCSX_LINKX_TIMER_COUNT_REG(offset, block_id) \
13174 + CVMX_ADD_IO_SEG(0x00011800B0001040ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13175 +#define CVMX_PCSX_LOG_ANLX_REG(offset, block_id) \
13176 + CVMX_ADD_IO_SEG(0x00011800B0001090ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13177 +#define CVMX_PCSX_MISCX_CTL_REG(offset, block_id) \
13178 + CVMX_ADD_IO_SEG(0x00011800B0001078ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13179 +#define CVMX_PCSX_MRX_CONTROL_REG(offset, block_id) \
13180 + CVMX_ADD_IO_SEG(0x00011800B0001000ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13181 +#define CVMX_PCSX_MRX_STATUS_REG(offset, block_id) \
13182 + CVMX_ADD_IO_SEG(0x00011800B0001008ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13183 +#define CVMX_PCSX_RXX_STATES_REG(offset, block_id) \
13184 + CVMX_ADD_IO_SEG(0x00011800B0001058ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13185 +#define CVMX_PCSX_RXX_SYNC_REG(offset, block_id) \
13186 + CVMX_ADD_IO_SEG(0x00011800B0001050ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13187 +#define CVMX_PCSX_SGMX_AN_ADV_REG(offset, block_id) \
13188 + CVMX_ADD_IO_SEG(0x00011800B0001068ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13189 +#define CVMX_PCSX_SGMX_LP_ADV_REG(offset, block_id) \
13190 + CVMX_ADD_IO_SEG(0x00011800B0001070ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13191 +#define CVMX_PCSX_TXX_STATES_REG(offset, block_id) \
13192 + CVMX_ADD_IO_SEG(0x00011800B0001060ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13193 +#define CVMX_PCSX_TX_RXX_POLARITY_REG(offset, block_id) \
13194 + CVMX_ADD_IO_SEG(0x00011800B0001048ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13195 +
13196 +union cvmx_pcsx_anx_adv_reg {
13197 + uint64_t u64;
13198 + struct cvmx_pcsx_anx_adv_reg_s {
13199 + uint64_t reserved_16_63:48;
13200 + uint64_t np:1;
13201 + uint64_t reserved_14_14:1;
13202 + uint64_t rem_flt:2;
13203 + uint64_t reserved_9_11:3;
13204 + uint64_t pause:2;
13205 + uint64_t hfd:1;
13206 + uint64_t fd:1;
13207 + uint64_t reserved_0_4:5;
13208 + } s;
13209 + struct cvmx_pcsx_anx_adv_reg_s cn52xx;
13210 + struct cvmx_pcsx_anx_adv_reg_s cn52xxp1;
13211 + struct cvmx_pcsx_anx_adv_reg_s cn56xx;
13212 + struct cvmx_pcsx_anx_adv_reg_s cn56xxp1;
13213 +};
13214 +
13215 +union cvmx_pcsx_anx_ext_st_reg {
13216 + uint64_t u64;
13217 + struct cvmx_pcsx_anx_ext_st_reg_s {
13218 + uint64_t reserved_16_63:48;
13219 + uint64_t thou_xfd:1;
13220 + uint64_t thou_xhd:1;
13221 + uint64_t thou_tfd:1;
13222 + uint64_t thou_thd:1;
13223 + uint64_t reserved_0_11:12;
13224 + } s;
13225 + struct cvmx_pcsx_anx_ext_st_reg_s cn52xx;
13226 + struct cvmx_pcsx_anx_ext_st_reg_s cn52xxp1;
13227 + struct cvmx_pcsx_anx_ext_st_reg_s cn56xx;
13228 + struct cvmx_pcsx_anx_ext_st_reg_s cn56xxp1;
13229 +};
13230 +
13231 +union cvmx_pcsx_anx_lp_abil_reg {
13232 + uint64_t u64;
13233 + struct cvmx_pcsx_anx_lp_abil_reg_s {
13234 + uint64_t reserved_16_63:48;
13235 + uint64_t np:1;
13236 + uint64_t ack:1;
13237 + uint64_t rem_flt:2;
13238 + uint64_t reserved_9_11:3;
13239 + uint64_t pause:2;
13240 + uint64_t hfd:1;
13241 + uint64_t fd:1;
13242 + uint64_t reserved_0_4:5;
13243 + } s;
13244 + struct cvmx_pcsx_anx_lp_abil_reg_s cn52xx;
13245 + struct cvmx_pcsx_anx_lp_abil_reg_s cn52xxp1;
13246 + struct cvmx_pcsx_anx_lp_abil_reg_s cn56xx;
13247 + struct cvmx_pcsx_anx_lp_abil_reg_s cn56xxp1;
13248 +};
13249 +
13250 +union cvmx_pcsx_anx_results_reg {
13251 + uint64_t u64;
13252 + struct cvmx_pcsx_anx_results_reg_s {
13253 + uint64_t reserved_7_63:57;
13254 + uint64_t pause:2;
13255 + uint64_t spd:2;
13256 + uint64_t an_cpt:1;
13257 + uint64_t dup:1;
13258 + uint64_t link_ok:1;
13259 + } s;
13260 + struct cvmx_pcsx_anx_results_reg_s cn52xx;
13261 + struct cvmx_pcsx_anx_results_reg_s cn52xxp1;
13262 + struct cvmx_pcsx_anx_results_reg_s cn56xx;
13263 + struct cvmx_pcsx_anx_results_reg_s cn56xxp1;
13264 +};
13265 +
13266 +union cvmx_pcsx_intx_en_reg {
13267 + uint64_t u64;
13268 + struct cvmx_pcsx_intx_en_reg_s {
13269 + uint64_t reserved_12_63:52;
13270 + uint64_t dup:1;
13271 + uint64_t sync_bad_en:1;
13272 + uint64_t an_bad_en:1;
13273 + uint64_t rxlock_en:1;
13274 + uint64_t rxbad_en:1;
13275 + uint64_t rxerr_en:1;
13276 + uint64_t txbad_en:1;
13277 + uint64_t txfifo_en:1;
13278 + uint64_t txfifu_en:1;
13279 + uint64_t an_err_en:1;
13280 + uint64_t xmit_en:1;
13281 + uint64_t lnkspd_en:1;
13282 + } s;
13283 + struct cvmx_pcsx_intx_en_reg_s cn52xx;
13284 + struct cvmx_pcsx_intx_en_reg_s cn52xxp1;
13285 + struct cvmx_pcsx_intx_en_reg_s cn56xx;
13286 + struct cvmx_pcsx_intx_en_reg_s cn56xxp1;
13287 +};
13288 +
13289 +union cvmx_pcsx_intx_reg {
13290 + uint64_t u64;
13291 + struct cvmx_pcsx_intx_reg_s {
13292 + uint64_t reserved_12_63:52;
13293 + uint64_t dup:1;
13294 + uint64_t sync_bad:1;
13295 + uint64_t an_bad:1;
13296 + uint64_t rxlock:1;
13297 + uint64_t rxbad:1;
13298 + uint64_t rxerr:1;
13299 + uint64_t txbad:1;
13300 + uint64_t txfifo:1;
13301 + uint64_t txfifu:1;
13302 + uint64_t an_err:1;
13303 + uint64_t xmit:1;
13304 + uint64_t lnkspd:1;
13305 + } s;
13306 + struct cvmx_pcsx_intx_reg_s cn52xx;
13307 + struct cvmx_pcsx_intx_reg_s cn52xxp1;
13308 + struct cvmx_pcsx_intx_reg_s cn56xx;
13309 + struct cvmx_pcsx_intx_reg_s cn56xxp1;
13310 +};
13311 +
13312 +union cvmx_pcsx_linkx_timer_count_reg {
13313 + uint64_t u64;
13314 + struct cvmx_pcsx_linkx_timer_count_reg_s {
13315 + uint64_t reserved_16_63:48;
13316 + uint64_t count:16;
13317 + } s;
13318 + struct cvmx_pcsx_linkx_timer_count_reg_s cn52xx;
13319 + struct cvmx_pcsx_linkx_timer_count_reg_s cn52xxp1;
13320 + struct cvmx_pcsx_linkx_timer_count_reg_s cn56xx;
13321 + struct cvmx_pcsx_linkx_timer_count_reg_s cn56xxp1;
13322 +};
13323 +
13324 +union cvmx_pcsx_log_anlx_reg {
13325 + uint64_t u64;
13326 + struct cvmx_pcsx_log_anlx_reg_s {
13327 + uint64_t reserved_4_63:60;
13328 + uint64_t lafifovfl:1;
13329 + uint64_t la_en:1;
13330 + uint64_t pkt_sz:2;
13331 + } s;
13332 + struct cvmx_pcsx_log_anlx_reg_s cn52xx;
13333 + struct cvmx_pcsx_log_anlx_reg_s cn52xxp1;
13334 + struct cvmx_pcsx_log_anlx_reg_s cn56xx;
13335 + struct cvmx_pcsx_log_anlx_reg_s cn56xxp1;
13336 +};
13337 +
13338 +union cvmx_pcsx_miscx_ctl_reg {
13339 + uint64_t u64;
13340 + struct cvmx_pcsx_miscx_ctl_reg_s {
13341 + uint64_t reserved_13_63:51;
13342 + uint64_t sgmii:1;
13343 + uint64_t gmxeno:1;
13344 + uint64_t loopbck2:1;
13345 + uint64_t mac_phy:1;
13346 + uint64_t mode:1;
13347 + uint64_t an_ovrd:1;
13348 + uint64_t samp_pt:7;
13349 + } s;
13350 + struct cvmx_pcsx_miscx_ctl_reg_s cn52xx;
13351 + struct cvmx_pcsx_miscx_ctl_reg_s cn52xxp1;
13352 + struct cvmx_pcsx_miscx_ctl_reg_s cn56xx;
13353 + struct cvmx_pcsx_miscx_ctl_reg_s cn56xxp1;
13354 +};
13355 +
13356 +union cvmx_pcsx_mrx_control_reg {
13357 + uint64_t u64;
13358 + struct cvmx_pcsx_mrx_control_reg_s {
13359 + uint64_t reserved_16_63:48;
13360 + uint64_t reset:1;
13361 + uint64_t loopbck1:1;
13362 + uint64_t spdlsb:1;
13363 + uint64_t an_en:1;
13364 + uint64_t pwr_dn:1;
13365 + uint64_t reserved_10_10:1;
13366 + uint64_t rst_an:1;
13367 + uint64_t dup:1;
13368 + uint64_t coltst:1;
13369 + uint64_t spdmsb:1;
13370 + uint64_t uni:1;
13371 + uint64_t reserved_0_4:5;
13372 + } s;
13373 + struct cvmx_pcsx_mrx_control_reg_s cn52xx;
13374 + struct cvmx_pcsx_mrx_control_reg_s cn52xxp1;
13375 + struct cvmx_pcsx_mrx_control_reg_s cn56xx;
13376 + struct cvmx_pcsx_mrx_control_reg_s cn56xxp1;
13377 +};
13378 +
13379 +union cvmx_pcsx_mrx_status_reg {
13380 + uint64_t u64;
13381 + struct cvmx_pcsx_mrx_status_reg_s {
13382 + uint64_t reserved_16_63:48;
13383 + uint64_t hun_t4:1;
13384 + uint64_t hun_xfd:1;
13385 + uint64_t hun_xhd:1;
13386 + uint64_t ten_fd:1;
13387 + uint64_t ten_hd:1;
13388 + uint64_t hun_t2fd:1;
13389 + uint64_t hun_t2hd:1;
13390 + uint64_t ext_st:1;
13391 + uint64_t reserved_7_7:1;
13392 + uint64_t prb_sup:1;
13393 + uint64_t an_cpt:1;
13394 + uint64_t rm_flt:1;
13395 + uint64_t an_abil:1;
13396 + uint64_t lnk_st:1;
13397 + uint64_t reserved_1_1:1;
13398 + uint64_t extnd:1;
13399 + } s;
13400 + struct cvmx_pcsx_mrx_status_reg_s cn52xx;
13401 + struct cvmx_pcsx_mrx_status_reg_s cn52xxp1;
13402 + struct cvmx_pcsx_mrx_status_reg_s cn56xx;
13403 + struct cvmx_pcsx_mrx_status_reg_s cn56xxp1;
13404 +};
13405 +
13406 +union cvmx_pcsx_rxx_states_reg {
13407 + uint64_t u64;
13408 + struct cvmx_pcsx_rxx_states_reg_s {
13409 + uint64_t reserved_16_63:48;
13410 + uint64_t rx_bad:1;
13411 + uint64_t rx_st:5;
13412 + uint64_t sync_bad:1;
13413 + uint64_t sync:4;
13414 + uint64_t an_bad:1;
13415 + uint64_t an_st:4;
13416 + } s;
13417 + struct cvmx_pcsx_rxx_states_reg_s cn52xx;
13418 + struct cvmx_pcsx_rxx_states_reg_s cn52xxp1;
13419 + struct cvmx_pcsx_rxx_states_reg_s cn56xx;
13420 + struct cvmx_pcsx_rxx_states_reg_s cn56xxp1;
13421 +};
13422 +
13423 +union cvmx_pcsx_rxx_sync_reg {
13424 + uint64_t u64;
13425 + struct cvmx_pcsx_rxx_sync_reg_s {
13426 + uint64_t reserved_2_63:62;
13427 + uint64_t sync:1;
13428 + uint64_t bit_lock:1;
13429 + } s;
13430 + struct cvmx_pcsx_rxx_sync_reg_s cn52xx;
13431 + struct cvmx_pcsx_rxx_sync_reg_s cn52xxp1;
13432 + struct cvmx_pcsx_rxx_sync_reg_s cn56xx;
13433 + struct cvmx_pcsx_rxx_sync_reg_s cn56xxp1;
13434 +};
13435 +
13436 +union cvmx_pcsx_sgmx_an_adv_reg {
13437 + uint64_t u64;
13438 + struct cvmx_pcsx_sgmx_an_adv_reg_s {
13439 + uint64_t reserved_16_63:48;
13440 + uint64_t link:1;
13441 + uint64_t ack:1;
13442 + uint64_t reserved_13_13:1;
13443 + uint64_t dup:1;
13444 + uint64_t speed:2;
13445 + uint64_t reserved_1_9:9;
13446 + uint64_t one:1;
13447 + } s;
13448 + struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xx;
13449 + struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xxp1;
13450 + struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xx;
13451 + struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xxp1;
13452 +};
13453 +
13454 +union cvmx_pcsx_sgmx_lp_adv_reg {
13455 + uint64_t u64;
13456 + struct cvmx_pcsx_sgmx_lp_adv_reg_s {
13457 + uint64_t reserved_16_63:48;
13458 + uint64_t link:1;
13459 + uint64_t reserved_13_14:2;
13460 + uint64_t dup:1;
13461 + uint64_t speed:2;
13462 + uint64_t reserved_1_9:9;
13463 + uint64_t one:1;
13464 + } s;
13465 + struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xx;
13466 + struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xxp1;
13467 + struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xx;
13468 + struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xxp1;
13469 +};
13470 +
13471 +union cvmx_pcsx_txx_states_reg {
13472 + uint64_t u64;
13473 + struct cvmx_pcsx_txx_states_reg_s {
13474 + uint64_t reserved_7_63:57;
13475 + uint64_t xmit:2;
13476 + uint64_t tx_bad:1;
13477 + uint64_t ord_st:4;
13478 + } s;
13479 + struct cvmx_pcsx_txx_states_reg_s cn52xx;
13480 + struct cvmx_pcsx_txx_states_reg_s cn52xxp1;
13481 + struct cvmx_pcsx_txx_states_reg_s cn56xx;
13482 + struct cvmx_pcsx_txx_states_reg_s cn56xxp1;
13483 +};
13484 +
13485 +union cvmx_pcsx_tx_rxx_polarity_reg {
13486 + uint64_t u64;
13487 + struct cvmx_pcsx_tx_rxx_polarity_reg_s {
13488 + uint64_t reserved_4_63:60;
13489 + uint64_t rxovrd:1;
13490 + uint64_t autorxpl:1;
13491 + uint64_t rxplrt:1;
13492 + uint64_t txplrt:1;
13493 + } s;
13494 + struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xx;
13495 + struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xxp1;
13496 + struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xx;
13497 + struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xxp1;
13498 +};
13499 +
13500 +#endif
13501 --- /dev/null
13502 +++ b/drivers/staging/octeon/cvmx-pcsxx-defs.h
13503 @@ -0,0 +1,316 @@
13504 +/***********************license start***************
13505 + * Author: Cavium Networks
13506 + *
13507 + * Contact: support@caviumnetworks.com
13508 + * This file is part of the OCTEON SDK
13509 + *
13510 + * Copyright (c) 2003-2008 Cavium Networks
13511 + *
13512 + * This file is free software; you can redistribute it and/or modify
13513 + * it under the terms of the GNU General Public License, Version 2, as
13514 + * published by the Free Software Foundation.
13515 + *
13516 + * This file is distributed in the hope that it will be useful, but
13517 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13518 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13519 + * NONINFRINGEMENT. See the GNU General Public License for more
13520 + * details.
13521 + *
13522 + * You should have received a copy of the GNU General Public License
13523 + * along with this file; if not, write to the Free Software
13524 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13525 + * or visit http://www.gnu.org/licenses/.
13526 + *
13527 + * This file may also be available under a different license from Cavium.
13528 + * Contact Cavium Networks for more information
13529 + ***********************license end**************************************/
13530 +
13531 +#ifndef __CVMX_PCSXX_DEFS_H__
13532 +#define __CVMX_PCSXX_DEFS_H__
13533 +
13534 +#define CVMX_PCSXX_10GBX_STATUS_REG(block_id) \
13535 + CVMX_ADD_IO_SEG(0x00011800B0000828ull + (((block_id) & 1) * 0x8000000ull))
13536 +#define CVMX_PCSXX_BIST_STATUS_REG(block_id) \
13537 + CVMX_ADD_IO_SEG(0x00011800B0000870ull + (((block_id) & 1) * 0x8000000ull))
13538 +#define CVMX_PCSXX_BIT_LOCK_STATUS_REG(block_id) \
13539 + CVMX_ADD_IO_SEG(0x00011800B0000850ull + (((block_id) & 1) * 0x8000000ull))
13540 +#define CVMX_PCSXX_CONTROL1_REG(block_id) \
13541 + CVMX_ADD_IO_SEG(0x00011800B0000800ull + (((block_id) & 1) * 0x8000000ull))
13542 +#define CVMX_PCSXX_CONTROL2_REG(block_id) \
13543 + CVMX_ADD_IO_SEG(0x00011800B0000818ull + (((block_id) & 1) * 0x8000000ull))
13544 +#define CVMX_PCSXX_INT_EN_REG(block_id) \
13545 + CVMX_ADD_IO_SEG(0x00011800B0000860ull + (((block_id) & 1) * 0x8000000ull))
13546 +#define CVMX_PCSXX_INT_REG(block_id) \
13547 + CVMX_ADD_IO_SEG(0x00011800B0000858ull + (((block_id) & 1) * 0x8000000ull))
13548 +#define CVMX_PCSXX_LOG_ANL_REG(block_id) \
13549 + CVMX_ADD_IO_SEG(0x00011800B0000868ull + (((block_id) & 1) * 0x8000000ull))
13550 +#define CVMX_PCSXX_MISC_CTL_REG(block_id) \
13551 + CVMX_ADD_IO_SEG(0x00011800B0000848ull + (((block_id) & 1) * 0x8000000ull))
13552 +#define CVMX_PCSXX_RX_SYNC_STATES_REG(block_id) \
13553 + CVMX_ADD_IO_SEG(0x00011800B0000838ull + (((block_id) & 1) * 0x8000000ull))
13554 +#define CVMX_PCSXX_SPD_ABIL_REG(block_id) \
13555 + CVMX_ADD_IO_SEG(0x00011800B0000810ull + (((block_id) & 1) * 0x8000000ull))
13556 +#define CVMX_PCSXX_STATUS1_REG(block_id) \
13557 + CVMX_ADD_IO_SEG(0x00011800B0000808ull + (((block_id) & 1) * 0x8000000ull))
13558 +#define CVMX_PCSXX_STATUS2_REG(block_id) \
13559 + CVMX_ADD_IO_SEG(0x00011800B0000820ull + (((block_id) & 1) * 0x8000000ull))
13560 +#define CVMX_PCSXX_TX_RX_POLARITY_REG(block_id) \
13561 + CVMX_ADD_IO_SEG(0x00011800B0000840ull + (((block_id) & 1) * 0x8000000ull))
13562 +#define CVMX_PCSXX_TX_RX_STATES_REG(block_id) \
13563 + CVMX_ADD_IO_SEG(0x00011800B0000830ull + (((block_id) & 1) * 0x8000000ull))
13564 +
13565 +union cvmx_pcsxx_10gbx_status_reg {
13566 + uint64_t u64;
13567 + struct cvmx_pcsxx_10gbx_status_reg_s {
13568 + uint64_t reserved_13_63:51;
13569 + uint64_t alignd:1;
13570 + uint64_t pattst:1;
13571 + uint64_t reserved_4_10:7;
13572 + uint64_t l3sync:1;
13573 + uint64_t l2sync:1;
13574 + uint64_t l1sync:1;
13575 + uint64_t l0sync:1;
13576 + } s;
13577 + struct cvmx_pcsxx_10gbx_status_reg_s cn52xx;
13578 + struct cvmx_pcsxx_10gbx_status_reg_s cn52xxp1;
13579 + struct cvmx_pcsxx_10gbx_status_reg_s cn56xx;
13580 + struct cvmx_pcsxx_10gbx_status_reg_s cn56xxp1;
13581 +};
13582 +
13583 +union cvmx_pcsxx_bist_status_reg {
13584 + uint64_t u64;
13585 + struct cvmx_pcsxx_bist_status_reg_s {
13586 + uint64_t reserved_1_63:63;
13587 + uint64_t bist_status:1;
13588 + } s;
13589 + struct cvmx_pcsxx_bist_status_reg_s cn52xx;
13590 + struct cvmx_pcsxx_bist_status_reg_s cn52xxp1;
13591 + struct cvmx_pcsxx_bist_status_reg_s cn56xx;
13592 + struct cvmx_pcsxx_bist_status_reg_s cn56xxp1;
13593 +};
13594 +
13595 +union cvmx_pcsxx_bit_lock_status_reg {
13596 + uint64_t u64;
13597 + struct cvmx_pcsxx_bit_lock_status_reg_s {
13598 + uint64_t reserved_4_63:60;
13599 + uint64_t bitlck3:1;
13600 + uint64_t bitlck2:1;
13601 + uint64_t bitlck1:1;
13602 + uint64_t bitlck0:1;
13603 + } s;
13604 + struct cvmx_pcsxx_bit_lock_status_reg_s cn52xx;
13605 + struct cvmx_pcsxx_bit_lock_status_reg_s cn52xxp1;
13606 + struct cvmx_pcsxx_bit_lock_status_reg_s cn56xx;
13607 + struct cvmx_pcsxx_bit_lock_status_reg_s cn56xxp1;
13608 +};
13609 +
13610 +union cvmx_pcsxx_control1_reg {
13611 + uint64_t u64;
13612 + struct cvmx_pcsxx_control1_reg_s {
13613 + uint64_t reserved_16_63:48;
13614 + uint64_t reset:1;
13615 + uint64_t loopbck1:1;
13616 + uint64_t spdsel1:1;
13617 + uint64_t reserved_12_12:1;
13618 + uint64_t lo_pwr:1;
13619 + uint64_t reserved_7_10:4;
13620 + uint64_t spdsel0:1;
13621 + uint64_t spd:4;
13622 + uint64_t reserved_0_1:2;
13623 + } s;
13624 + struct cvmx_pcsxx_control1_reg_s cn52xx;
13625 + struct cvmx_pcsxx_control1_reg_s cn52xxp1;
13626 + struct cvmx_pcsxx_control1_reg_s cn56xx;
13627 + struct cvmx_pcsxx_control1_reg_s cn56xxp1;
13628 +};
13629 +
13630 +union cvmx_pcsxx_control2_reg {
13631 + uint64_t u64;
13632 + struct cvmx_pcsxx_control2_reg_s {
13633 + uint64_t reserved_2_63:62;
13634 + uint64_t type:2;
13635 + } s;
13636 + struct cvmx_pcsxx_control2_reg_s cn52xx;
13637 + struct cvmx_pcsxx_control2_reg_s cn52xxp1;
13638 + struct cvmx_pcsxx_control2_reg_s cn56xx;
13639 + struct cvmx_pcsxx_control2_reg_s cn56xxp1;
13640 +};
13641 +
13642 +union cvmx_pcsxx_int_en_reg {
13643 + uint64_t u64;
13644 + struct cvmx_pcsxx_int_en_reg_s {
13645 + uint64_t reserved_6_63:58;
13646 + uint64_t algnlos_en:1;
13647 + uint64_t synlos_en:1;
13648 + uint64_t bitlckls_en:1;
13649 + uint64_t rxsynbad_en:1;
13650 + uint64_t rxbad_en:1;
13651 + uint64_t txflt_en:1;
13652 + } s;
13653 + struct cvmx_pcsxx_int_en_reg_s cn52xx;
13654 + struct cvmx_pcsxx_int_en_reg_s cn52xxp1;
13655 + struct cvmx_pcsxx_int_en_reg_s cn56xx;
13656 + struct cvmx_pcsxx_int_en_reg_s cn56xxp1;
13657 +};
13658 +
13659 +union cvmx_pcsxx_int_reg {
13660 + uint64_t u64;
13661 + struct cvmx_pcsxx_int_reg_s {
13662 + uint64_t reserved_6_63:58;
13663 + uint64_t algnlos:1;
13664 + uint64_t synlos:1;
13665 + uint64_t bitlckls:1;
13666 + uint64_t rxsynbad:1;
13667 + uint64_t rxbad:1;
13668 + uint64_t txflt:1;
13669 + } s;
13670 + struct cvmx_pcsxx_int_reg_s cn52xx;
13671 + struct cvmx_pcsxx_int_reg_s cn52xxp1;
13672 + struct cvmx_pcsxx_int_reg_s cn56xx;
13673 + struct cvmx_pcsxx_int_reg_s cn56xxp1;
13674 +};
13675 +
13676 +union cvmx_pcsxx_log_anl_reg {
13677 + uint64_t u64;
13678 + struct cvmx_pcsxx_log_anl_reg_s {
13679 + uint64_t reserved_7_63:57;
13680 + uint64_t enc_mode:1;
13681 + uint64_t drop_ln:2;
13682 + uint64_t lafifovfl:1;
13683 + uint64_t la_en:1;
13684 + uint64_t pkt_sz:2;
13685 + } s;
13686 + struct cvmx_pcsxx_log_anl_reg_s cn52xx;
13687 + struct cvmx_pcsxx_log_anl_reg_s cn52xxp1;
13688 + struct cvmx_pcsxx_log_anl_reg_s cn56xx;
13689 + struct cvmx_pcsxx_log_anl_reg_s cn56xxp1;
13690 +};
13691 +
13692 +union cvmx_pcsxx_misc_ctl_reg {
13693 + uint64_t u64;
13694 + struct cvmx_pcsxx_misc_ctl_reg_s {
13695 + uint64_t reserved_4_63:60;
13696 + uint64_t tx_swap:1;
13697 + uint64_t rx_swap:1;
13698 + uint64_t xaui:1;
13699 + uint64_t gmxeno:1;
13700 + } s;
13701 + struct cvmx_pcsxx_misc_ctl_reg_s cn52xx;
13702 + struct cvmx_pcsxx_misc_ctl_reg_s cn52xxp1;
13703 + struct cvmx_pcsxx_misc_ctl_reg_s cn56xx;
13704 + struct cvmx_pcsxx_misc_ctl_reg_s cn56xxp1;
13705 +};
13706 +
13707 +union cvmx_pcsxx_rx_sync_states_reg {
13708 + uint64_t u64;
13709 + struct cvmx_pcsxx_rx_sync_states_reg_s {
13710 + uint64_t reserved_16_63:48;
13711 + uint64_t sync3st:4;
13712 + uint64_t sync2st:4;
13713 + uint64_t sync1st:4;
13714 + uint64_t sync0st:4;
13715 + } s;
13716 + struct cvmx_pcsxx_rx_sync_states_reg_s cn52xx;
13717 + struct cvmx_pcsxx_rx_sync_states_reg_s cn52xxp1;
13718 + struct cvmx_pcsxx_rx_sync_states_reg_s cn56xx;
13719 + struct cvmx_pcsxx_rx_sync_states_reg_s cn56xxp1;
13720 +};
13721 +
13722 +union cvmx_pcsxx_spd_abil_reg {
13723 + uint64_t u64;
13724 + struct cvmx_pcsxx_spd_abil_reg_s {
13725 + uint64_t reserved_2_63:62;
13726 + uint64_t tenpasst:1;
13727 + uint64_t tengb:1;
13728 + } s;
13729 + struct cvmx_pcsxx_spd_abil_reg_s cn52xx;
13730 + struct cvmx_pcsxx_spd_abil_reg_s cn52xxp1;
13731 + struct cvmx_pcsxx_spd_abil_reg_s cn56xx;
13732 + struct cvmx_pcsxx_spd_abil_reg_s cn56xxp1;
13733 +};
13734 +
13735 +union cvmx_pcsxx_status1_reg {
13736 + uint64_t u64;
13737 + struct cvmx_pcsxx_status1_reg_s {
13738 + uint64_t reserved_8_63:56;
13739 + uint64_t flt:1;
13740 + uint64_t reserved_3_6:4;
13741 + uint64_t rcv_lnk:1;
13742 + uint64_t lpable:1;
13743 + uint64_t reserved_0_0:1;
13744 + } s;
13745 + struct cvmx_pcsxx_status1_reg_s cn52xx;
13746 + struct cvmx_pcsxx_status1_reg_s cn52xxp1;
13747 + struct cvmx_pcsxx_status1_reg_s cn56xx;
13748 + struct cvmx_pcsxx_status1_reg_s cn56xxp1;
13749 +};
13750 +
13751 +union cvmx_pcsxx_status2_reg {
13752 + uint64_t u64;
13753 + struct cvmx_pcsxx_status2_reg_s {
13754 + uint64_t reserved_16_63:48;
13755 + uint64_t dev:2;
13756 + uint64_t reserved_12_13:2;
13757 + uint64_t xmtflt:1;
13758 + uint64_t rcvflt:1;
13759 + uint64_t reserved_3_9:7;
13760 + uint64_t tengb_w:1;
13761 + uint64_t tengb_x:1;
13762 + uint64_t tengb_r:1;
13763 + } s;
13764 + struct cvmx_pcsxx_status2_reg_s cn52xx;
13765 + struct cvmx_pcsxx_status2_reg_s cn52xxp1;
13766 + struct cvmx_pcsxx_status2_reg_s cn56xx;
13767 + struct cvmx_pcsxx_status2_reg_s cn56xxp1;
13768 +};
13769 +
13770 +union cvmx_pcsxx_tx_rx_polarity_reg {
13771 + uint64_t u64;
13772 + struct cvmx_pcsxx_tx_rx_polarity_reg_s {
13773 + uint64_t reserved_10_63:54;
13774 + uint64_t xor_rxplrt:4;
13775 + uint64_t xor_txplrt:4;
13776 + uint64_t rxplrt:1;
13777 + uint64_t txplrt:1;
13778 + } s;
13779 + struct cvmx_pcsxx_tx_rx_polarity_reg_s cn52xx;
13780 + struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 {
13781 + uint64_t reserved_2_63:62;
13782 + uint64_t rxplrt:1;
13783 + uint64_t txplrt:1;
13784 + } cn52xxp1;
13785 + struct cvmx_pcsxx_tx_rx_polarity_reg_s cn56xx;
13786 + struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 cn56xxp1;
13787 +};
13788 +
13789 +union cvmx_pcsxx_tx_rx_states_reg {
13790 + uint64_t u64;
13791 + struct cvmx_pcsxx_tx_rx_states_reg_s {
13792 + uint64_t reserved_14_63:50;
13793 + uint64_t term_err:1;
13794 + uint64_t syn3bad:1;
13795 + uint64_t syn2bad:1;
13796 + uint64_t syn1bad:1;
13797 + uint64_t syn0bad:1;
13798 + uint64_t rxbad:1;
13799 + uint64_t algn_st:3;
13800 + uint64_t rx_st:2;
13801 + uint64_t tx_st:3;
13802 + } s;
13803 + struct cvmx_pcsxx_tx_rx_states_reg_s cn52xx;
13804 + struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 {
13805 + uint64_t reserved_13_63:51;
13806 + uint64_t syn3bad:1;
13807 + uint64_t syn2bad:1;
13808 + uint64_t syn1bad:1;
13809 + uint64_t syn0bad:1;
13810 + uint64_t rxbad:1;
13811 + uint64_t algn_st:3;
13812 + uint64_t rx_st:2;
13813 + uint64_t tx_st:3;
13814 + } cn52xxp1;
13815 + struct cvmx_pcsxx_tx_rx_states_reg_s cn56xx;
13816 + struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 cn56xxp1;
13817 +};
13818 +
13819 +#endif
13820 --- /dev/null
13821 +++ b/drivers/staging/octeon/cvmx-pip-defs.h
13822 @@ -0,0 +1,1267 @@
13823 +/***********************license start***************
13824 + * Author: Cavium Networks
13825 + *
13826 + * Contact: support@caviumnetworks.com
13827 + * This file is part of the OCTEON SDK
13828 + *
13829 + * Copyright (c) 2003-2008 Cavium Networks
13830 + *
13831 + * This file is free software; you can redistribute it and/or modify
13832 + * it under the terms of the GNU General Public License, Version 2, as
13833 + * published by the Free Software Foundation.
13834 + *
13835 + * This file is distributed in the hope that it will be useful, but
13836 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13837 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13838 + * NONINFRINGEMENT. See the GNU General Public License for more
13839 + * details.
13840 + *
13841 + * You should have received a copy of the GNU General Public License
13842 + * along with this file; if not, write to the Free Software
13843 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13844 + * or visit http://www.gnu.org/licenses/.
13845 + *
13846 + * This file may also be available under a different license from Cavium.
13847 + * Contact Cavium Networks for more information
13848 + ***********************license end**************************************/
13849 +
13850 +#ifndef __CVMX_PIP_DEFS_H__
13851 +#define __CVMX_PIP_DEFS_H__
13852 +
13853 +/*
13854 + * Enumeration representing the amount of packet processing
13855 + * and validation performed by the input hardware.
13856 + */
13857 +enum cvmx_pip_port_parse_mode {
13858 + /*
13859 + * Packet input doesn't perform any processing of the input
13860 + * packet.
13861 + */
13862 + CVMX_PIP_PORT_CFG_MODE_NONE = 0ull,
13863 + /*
13864 + * Full packet processing is performed with pointer starting
13865 + * at the L2 (ethernet MAC) header.
13866 + */
13867 + CVMX_PIP_PORT_CFG_MODE_SKIPL2 = 1ull,
13868 + /*
13869 + * Input packets are assumed to be IP. Results from non IP
13870 + * packets is undefined. Pointers reference the beginning of
13871 + * the IP header.
13872 + */
13873 + CVMX_PIP_PORT_CFG_MODE_SKIPIP = 2ull
13874 +};
13875 +
13876 +#define CVMX_PIP_BCK_PRS \
13877 + CVMX_ADD_IO_SEG(0x00011800A0000038ull)
13878 +#define CVMX_PIP_BIST_STATUS \
13879 + CVMX_ADD_IO_SEG(0x00011800A0000000ull)
13880 +#define CVMX_PIP_CRC_CTLX(offset) \
13881 + CVMX_ADD_IO_SEG(0x00011800A0000040ull + (((offset) & 1) * 8))
13882 +#define CVMX_PIP_CRC_IVX(offset) \
13883 + CVMX_ADD_IO_SEG(0x00011800A0000050ull + (((offset) & 1) * 8))
13884 +#define CVMX_PIP_DEC_IPSECX(offset) \
13885 + CVMX_ADD_IO_SEG(0x00011800A0000080ull + (((offset) & 3) * 8))
13886 +#define CVMX_PIP_DSA_SRC_GRP \
13887 + CVMX_ADD_IO_SEG(0x00011800A0000190ull)
13888 +#define CVMX_PIP_DSA_VID_GRP \
13889 + CVMX_ADD_IO_SEG(0x00011800A0000198ull)
13890 +#define CVMX_PIP_FRM_LEN_CHKX(offset) \
13891 + CVMX_ADD_IO_SEG(0x00011800A0000180ull + (((offset) & 1) * 8))
13892 +#define CVMX_PIP_GBL_CFG \
13893 + CVMX_ADD_IO_SEG(0x00011800A0000028ull)
13894 +#define CVMX_PIP_GBL_CTL \
13895 + CVMX_ADD_IO_SEG(0x00011800A0000020ull)
13896 +#define CVMX_PIP_HG_PRI_QOS \
13897 + CVMX_ADD_IO_SEG(0x00011800A00001A0ull)
13898 +#define CVMX_PIP_INT_EN \
13899 + CVMX_ADD_IO_SEG(0x00011800A0000010ull)
13900 +#define CVMX_PIP_INT_REG \
13901 + CVMX_ADD_IO_SEG(0x00011800A0000008ull)
13902 +#define CVMX_PIP_IP_OFFSET \
13903 + CVMX_ADD_IO_SEG(0x00011800A0000060ull)
13904 +#define CVMX_PIP_PRT_CFGX(offset) \
13905 + CVMX_ADD_IO_SEG(0x00011800A0000200ull + (((offset) & 63) * 8))
13906 +#define CVMX_PIP_PRT_TAGX(offset) \
13907 + CVMX_ADD_IO_SEG(0x00011800A0000400ull + (((offset) & 63) * 8))
13908 +#define CVMX_PIP_QOS_DIFFX(offset) \
13909 + CVMX_ADD_IO_SEG(0x00011800A0000600ull + (((offset) & 63) * 8))
13910 +#define CVMX_PIP_QOS_VLANX(offset) \
13911 + CVMX_ADD_IO_SEG(0x00011800A00000C0ull + (((offset) & 7) * 8))
13912 +#define CVMX_PIP_QOS_WATCHX(offset) \
13913 + CVMX_ADD_IO_SEG(0x00011800A0000100ull + (((offset) & 7) * 8))
13914 +#define CVMX_PIP_RAW_WORD \
13915 + CVMX_ADD_IO_SEG(0x00011800A00000B0ull)
13916 +#define CVMX_PIP_SFT_RST \
13917 + CVMX_ADD_IO_SEG(0x00011800A0000030ull)
13918 +#define CVMX_PIP_STAT0_PRTX(offset) \
13919 + CVMX_ADD_IO_SEG(0x00011800A0000800ull + (((offset) & 63) * 80))
13920 +#define CVMX_PIP_STAT1_PRTX(offset) \
13921 + CVMX_ADD_IO_SEG(0x00011800A0000808ull + (((offset) & 63) * 80))
13922 +#define CVMX_PIP_STAT2_PRTX(offset) \
13923 + CVMX_ADD_IO_SEG(0x00011800A0000810ull + (((offset) & 63) * 80))
13924 +#define CVMX_PIP_STAT3_PRTX(offset) \
13925 + CVMX_ADD_IO_SEG(0x00011800A0000818ull + (((offset) & 63) * 80))
13926 +#define CVMX_PIP_STAT4_PRTX(offset) \
13927 + CVMX_ADD_IO_SEG(0x00011800A0000820ull + (((offset) & 63) * 80))
13928 +#define CVMX_PIP_STAT5_PRTX(offset) \
13929 + CVMX_ADD_IO_SEG(0x00011800A0000828ull + (((offset) & 63) * 80))
13930 +#define CVMX_PIP_STAT6_PRTX(offset) \
13931 + CVMX_ADD_IO_SEG(0x00011800A0000830ull + (((offset) & 63) * 80))
13932 +#define CVMX_PIP_STAT7_PRTX(offset) \
13933 + CVMX_ADD_IO_SEG(0x00011800A0000838ull + (((offset) & 63) * 80))
13934 +#define CVMX_PIP_STAT8_PRTX(offset) \
13935 + CVMX_ADD_IO_SEG(0x00011800A0000840ull + (((offset) & 63) * 80))
13936 +#define CVMX_PIP_STAT9_PRTX(offset) \
13937 + CVMX_ADD_IO_SEG(0x00011800A0000848ull + (((offset) & 63) * 80))
13938 +#define CVMX_PIP_STAT_CTL \
13939 + CVMX_ADD_IO_SEG(0x00011800A0000018ull)
13940 +#define CVMX_PIP_STAT_INB_ERRSX(offset) \
13941 + CVMX_ADD_IO_SEG(0x00011800A0001A10ull + (((offset) & 63) * 32))
13942 +#define CVMX_PIP_STAT_INB_OCTSX(offset) \
13943 + CVMX_ADD_IO_SEG(0x00011800A0001A08ull + (((offset) & 63) * 32))
13944 +#define CVMX_PIP_STAT_INB_PKTSX(offset) \
13945 + CVMX_ADD_IO_SEG(0x00011800A0001A00ull + (((offset) & 63) * 32))
13946 +#define CVMX_PIP_TAG_INCX(offset) \
13947 + CVMX_ADD_IO_SEG(0x00011800A0001800ull + (((offset) & 63) * 8))
13948 +#define CVMX_PIP_TAG_MASK \
13949 + CVMX_ADD_IO_SEG(0x00011800A0000070ull)
13950 +#define CVMX_PIP_TAG_SECRET \
13951 + CVMX_ADD_IO_SEG(0x00011800A0000068ull)
13952 +#define CVMX_PIP_TODO_ENTRY \
13953 + CVMX_ADD_IO_SEG(0x00011800A0000078ull)
13954 +
13955 +union cvmx_pip_bck_prs {
13956 + uint64_t u64;
13957 + struct cvmx_pip_bck_prs_s {
13958 + uint64_t bckprs:1;
13959 + uint64_t reserved_13_62:50;
13960 + uint64_t hiwater:5;
13961 + uint64_t reserved_5_7:3;
13962 + uint64_t lowater:5;
13963 + } s;
13964 + struct cvmx_pip_bck_prs_s cn38xx;
13965 + struct cvmx_pip_bck_prs_s cn38xxp2;
13966 + struct cvmx_pip_bck_prs_s cn56xx;
13967 + struct cvmx_pip_bck_prs_s cn56xxp1;
13968 + struct cvmx_pip_bck_prs_s cn58xx;
13969 + struct cvmx_pip_bck_prs_s cn58xxp1;
13970 +};
13971 +
13972 +union cvmx_pip_bist_status {
13973 + uint64_t u64;
13974 + struct cvmx_pip_bist_status_s {
13975 + uint64_t reserved_18_63:46;
13976 + uint64_t bist:18;
13977 + } s;
13978 + struct cvmx_pip_bist_status_s cn30xx;
13979 + struct cvmx_pip_bist_status_s cn31xx;
13980 + struct cvmx_pip_bist_status_s cn38xx;
13981 + struct cvmx_pip_bist_status_s cn38xxp2;
13982 + struct cvmx_pip_bist_status_cn50xx {
13983 + uint64_t reserved_17_63:47;
13984 + uint64_t bist:17;
13985 + } cn50xx;
13986 + struct cvmx_pip_bist_status_s cn52xx;
13987 + struct cvmx_pip_bist_status_s cn52xxp1;
13988 + struct cvmx_pip_bist_status_s cn56xx;
13989 + struct cvmx_pip_bist_status_s cn56xxp1;
13990 + struct cvmx_pip_bist_status_s cn58xx;
13991 + struct cvmx_pip_bist_status_s cn58xxp1;
13992 +};
13993 +
13994 +union cvmx_pip_crc_ctlx {
13995 + uint64_t u64;
13996 + struct cvmx_pip_crc_ctlx_s {
13997 + uint64_t reserved_2_63:62;
13998 + uint64_t invres:1;
13999 + uint64_t reflect:1;
14000 + } s;
14001 + struct cvmx_pip_crc_ctlx_s cn38xx;
14002 + struct cvmx_pip_crc_ctlx_s cn38xxp2;
14003 + struct cvmx_pip_crc_ctlx_s cn58xx;
14004 + struct cvmx_pip_crc_ctlx_s cn58xxp1;
14005 +};
14006 +
14007 +union cvmx_pip_crc_ivx {
14008 + uint64_t u64;
14009 + struct cvmx_pip_crc_ivx_s {
14010 + uint64_t reserved_32_63:32;
14011 + uint64_t iv:32;
14012 + } s;
14013 + struct cvmx_pip_crc_ivx_s cn38xx;
14014 + struct cvmx_pip_crc_ivx_s cn38xxp2;
14015 + struct cvmx_pip_crc_ivx_s cn58xx;
14016 + struct cvmx_pip_crc_ivx_s cn58xxp1;
14017 +};
14018 +
14019 +union cvmx_pip_dec_ipsecx {
14020 + uint64_t u64;
14021 + struct cvmx_pip_dec_ipsecx_s {
14022 + uint64_t reserved_18_63:46;
14023 + uint64_t tcp:1;
14024 + uint64_t udp:1;
14025 + uint64_t dprt:16;
14026 + } s;
14027 + struct cvmx_pip_dec_ipsecx_s cn30xx;
14028 + struct cvmx_pip_dec_ipsecx_s cn31xx;
14029 + struct cvmx_pip_dec_ipsecx_s cn38xx;
14030 + struct cvmx_pip_dec_ipsecx_s cn38xxp2;
14031 + struct cvmx_pip_dec_ipsecx_s cn50xx;
14032 + struct cvmx_pip_dec_ipsecx_s cn52xx;
14033 + struct cvmx_pip_dec_ipsecx_s cn52xxp1;
14034 + struct cvmx_pip_dec_ipsecx_s cn56xx;
14035 + struct cvmx_pip_dec_ipsecx_s cn56xxp1;
14036 + struct cvmx_pip_dec_ipsecx_s cn58xx;
14037 + struct cvmx_pip_dec_ipsecx_s cn58xxp1;
14038 +};
14039 +
14040 +union cvmx_pip_dsa_src_grp {
14041 + uint64_t u64;
14042 + struct cvmx_pip_dsa_src_grp_s {
14043 + uint64_t map15:4;
14044 + uint64_t map14:4;
14045 + uint64_t map13:4;
14046 + uint64_t map12:4;
14047 + uint64_t map11:4;
14048 + uint64_t map10:4;
14049 + uint64_t map9:4;
14050 + uint64_t map8:4;
14051 + uint64_t map7:4;
14052 + uint64_t map6:4;
14053 + uint64_t map5:4;
14054 + uint64_t map4:4;
14055 + uint64_t map3:4;
14056 + uint64_t map2:4;
14057 + uint64_t map1:4;
14058 + uint64_t map0:4;
14059 + } s;
14060 + struct cvmx_pip_dsa_src_grp_s cn52xx;
14061 + struct cvmx_pip_dsa_src_grp_s cn52xxp1;
14062 + struct cvmx_pip_dsa_src_grp_s cn56xx;
14063 +};
14064 +
14065 +union cvmx_pip_dsa_vid_grp {
14066 + uint64_t u64;
14067 + struct cvmx_pip_dsa_vid_grp_s {
14068 + uint64_t map15:4;
14069 + uint64_t map14:4;
14070 + uint64_t map13:4;
14071 + uint64_t map12:4;
14072 + uint64_t map11:4;
14073 + uint64_t map10:4;
14074 + uint64_t map9:4;
14075 + uint64_t map8:4;
14076 + uint64_t map7:4;
14077 + uint64_t map6:4;
14078 + uint64_t map5:4;
14079 + uint64_t map4:4;
14080 + uint64_t map3:4;
14081 + uint64_t map2:4;
14082 + uint64_t map1:4;
14083 + uint64_t map0:4;
14084 + } s;
14085 + struct cvmx_pip_dsa_vid_grp_s cn52xx;
14086 + struct cvmx_pip_dsa_vid_grp_s cn52xxp1;
14087 + struct cvmx_pip_dsa_vid_grp_s cn56xx;
14088 +};
14089 +
14090 +union cvmx_pip_frm_len_chkx {
14091 + uint64_t u64;
14092 + struct cvmx_pip_frm_len_chkx_s {
14093 + uint64_t reserved_32_63:32;
14094 + uint64_t maxlen:16;
14095 + uint64_t minlen:16;
14096 + } s;
14097 + struct cvmx_pip_frm_len_chkx_s cn50xx;
14098 + struct cvmx_pip_frm_len_chkx_s cn52xx;
14099 + struct cvmx_pip_frm_len_chkx_s cn52xxp1;
14100 + struct cvmx_pip_frm_len_chkx_s cn56xx;
14101 + struct cvmx_pip_frm_len_chkx_s cn56xxp1;
14102 +};
14103 +
14104 +union cvmx_pip_gbl_cfg {
14105 + uint64_t u64;
14106 + struct cvmx_pip_gbl_cfg_s {
14107 + uint64_t reserved_19_63:45;
14108 + uint64_t tag_syn:1;
14109 + uint64_t ip6_udp:1;
14110 + uint64_t max_l2:1;
14111 + uint64_t reserved_11_15:5;
14112 + uint64_t raw_shf:3;
14113 + uint64_t reserved_3_7:5;
14114 + uint64_t nip_shf:3;
14115 + } s;
14116 + struct cvmx_pip_gbl_cfg_s cn30xx;
14117 + struct cvmx_pip_gbl_cfg_s cn31xx;
14118 + struct cvmx_pip_gbl_cfg_s cn38xx;
14119 + struct cvmx_pip_gbl_cfg_s cn38xxp2;
14120 + struct cvmx_pip_gbl_cfg_s cn50xx;
14121 + struct cvmx_pip_gbl_cfg_s cn52xx;
14122 + struct cvmx_pip_gbl_cfg_s cn52xxp1;
14123 + struct cvmx_pip_gbl_cfg_s cn56xx;
14124 + struct cvmx_pip_gbl_cfg_s cn56xxp1;
14125 + struct cvmx_pip_gbl_cfg_s cn58xx;
14126 + struct cvmx_pip_gbl_cfg_s cn58xxp1;
14127 +};
14128 +
14129 +union cvmx_pip_gbl_ctl {
14130 + uint64_t u64;
14131 + struct cvmx_pip_gbl_ctl_s {
14132 + uint64_t reserved_27_63:37;
14133 + uint64_t dsa_grp_tvid:1;
14134 + uint64_t dsa_grp_scmd:1;
14135 + uint64_t dsa_grp_sid:1;
14136 + uint64_t reserved_21_23:3;
14137 + uint64_t ring_en:1;
14138 + uint64_t reserved_17_19:3;
14139 + uint64_t ignrs:1;
14140 + uint64_t vs_wqe:1;
14141 + uint64_t vs_qos:1;
14142 + uint64_t l2_mal:1;
14143 + uint64_t tcp_flag:1;
14144 + uint64_t l4_len:1;
14145 + uint64_t l4_chk:1;
14146 + uint64_t l4_prt:1;
14147 + uint64_t l4_mal:1;
14148 + uint64_t reserved_6_7:2;
14149 + uint64_t ip6_eext:2;
14150 + uint64_t ip4_opts:1;
14151 + uint64_t ip_hop:1;
14152 + uint64_t ip_mal:1;
14153 + uint64_t ip_chk:1;
14154 + } s;
14155 + struct cvmx_pip_gbl_ctl_cn30xx {
14156 + uint64_t reserved_17_63:47;
14157 + uint64_t ignrs:1;
14158 + uint64_t vs_wqe:1;
14159 + uint64_t vs_qos:1;
14160 + uint64_t l2_mal:1;
14161 + uint64_t tcp_flag:1;
14162 + uint64_t l4_len:1;
14163 + uint64_t l4_chk:1;
14164 + uint64_t l4_prt:1;
14165 + uint64_t l4_mal:1;
14166 + uint64_t reserved_6_7:2;
14167 + uint64_t ip6_eext:2;
14168 + uint64_t ip4_opts:1;
14169 + uint64_t ip_hop:1;
14170 + uint64_t ip_mal:1;
14171 + uint64_t ip_chk:1;
14172 + } cn30xx;
14173 + struct cvmx_pip_gbl_ctl_cn30xx cn31xx;
14174 + struct cvmx_pip_gbl_ctl_cn30xx cn38xx;
14175 + struct cvmx_pip_gbl_ctl_cn30xx cn38xxp2;
14176 + struct cvmx_pip_gbl_ctl_cn30xx cn50xx;
14177 + struct cvmx_pip_gbl_ctl_s cn52xx;
14178 + struct cvmx_pip_gbl_ctl_s cn52xxp1;
14179 + struct cvmx_pip_gbl_ctl_s cn56xx;
14180 + struct cvmx_pip_gbl_ctl_cn56xxp1 {
14181 + uint64_t reserved_21_63:43;
14182 + uint64_t ring_en:1;
14183 + uint64_t reserved_17_19:3;
14184 + uint64_t ignrs:1;
14185 + uint64_t vs_wqe:1;
14186 + uint64_t vs_qos:1;
14187 + uint64_t l2_mal:1;
14188 + uint64_t tcp_flag:1;
14189 + uint64_t l4_len:1;
14190 + uint64_t l4_chk:1;
14191 + uint64_t l4_prt:1;
14192 + uint64_t l4_mal:1;
14193 + uint64_t reserved_6_7:2;
14194 + uint64_t ip6_eext:2;
14195 + uint64_t ip4_opts:1;
14196 + uint64_t ip_hop:1;
14197 + uint64_t ip_mal:1;
14198 + uint64_t ip_chk:1;
14199 + } cn56xxp1;
14200 + struct cvmx_pip_gbl_ctl_cn30xx cn58xx;
14201 + struct cvmx_pip_gbl_ctl_cn30xx cn58xxp1;
14202 +};
14203 +
14204 +union cvmx_pip_hg_pri_qos {
14205 + uint64_t u64;
14206 + struct cvmx_pip_hg_pri_qos_s {
14207 + uint64_t reserved_11_63:53;
14208 + uint64_t qos:3;
14209 + uint64_t reserved_6_7:2;
14210 + uint64_t pri:6;
14211 + } s;
14212 + struct cvmx_pip_hg_pri_qos_s cn52xx;
14213 + struct cvmx_pip_hg_pri_qos_s cn52xxp1;
14214 + struct cvmx_pip_hg_pri_qos_s cn56xx;
14215 +};
14216 +
14217 +union cvmx_pip_int_en {
14218 + uint64_t u64;
14219 + struct cvmx_pip_int_en_s {
14220 + uint64_t reserved_13_63:51;
14221 + uint64_t punyerr:1;
14222 + uint64_t lenerr:1;
14223 + uint64_t maxerr:1;
14224 + uint64_t minerr:1;
14225 + uint64_t beperr:1;
14226 + uint64_t feperr:1;
14227 + uint64_t todoovr:1;
14228 + uint64_t skprunt:1;
14229 + uint64_t badtag:1;
14230 + uint64_t prtnxa:1;
14231 + uint64_t bckprs:1;
14232 + uint64_t crcerr:1;
14233 + uint64_t pktdrp:1;
14234 + } s;
14235 + struct cvmx_pip_int_en_cn30xx {
14236 + uint64_t reserved_9_63:55;
14237 + uint64_t beperr:1;
14238 + uint64_t feperr:1;
14239 + uint64_t todoovr:1;
14240 + uint64_t skprunt:1;
14241 + uint64_t badtag:1;
14242 + uint64_t prtnxa:1;
14243 + uint64_t bckprs:1;
14244 + uint64_t crcerr:1;
14245 + uint64_t pktdrp:1;
14246 + } cn30xx;
14247 + struct cvmx_pip_int_en_cn30xx cn31xx;
14248 + struct cvmx_pip_int_en_cn30xx cn38xx;
14249 + struct cvmx_pip_int_en_cn30xx cn38xxp2;
14250 + struct cvmx_pip_int_en_cn50xx {
14251 + uint64_t reserved_12_63:52;
14252 + uint64_t lenerr:1;
14253 + uint64_t maxerr:1;
14254 + uint64_t minerr:1;
14255 + uint64_t beperr:1;
14256 + uint64_t feperr:1;
14257 + uint64_t todoovr:1;
14258 + uint64_t skprunt:1;
14259 + uint64_t badtag:1;
14260 + uint64_t prtnxa:1;
14261 + uint64_t bckprs:1;
14262 + uint64_t reserved_1_1:1;
14263 + uint64_t pktdrp:1;
14264 + } cn50xx;
14265 + struct cvmx_pip_int_en_cn52xx {
14266 + uint64_t reserved_13_63:51;
14267 + uint64_t punyerr:1;
14268 + uint64_t lenerr:1;
14269 + uint64_t maxerr:1;
14270 + uint64_t minerr:1;
14271 + uint64_t beperr:1;
14272 + uint64_t feperr:1;
14273 + uint64_t todoovr:1;
14274 + uint64_t skprunt:1;
14275 + uint64_t badtag:1;
14276 + uint64_t prtnxa:1;
14277 + uint64_t bckprs:1;
14278 + uint64_t reserved_1_1:1;
14279 + uint64_t pktdrp:1;
14280 + } cn52xx;
14281 + struct cvmx_pip_int_en_cn52xx cn52xxp1;
14282 + struct cvmx_pip_int_en_s cn56xx;
14283 + struct cvmx_pip_int_en_cn56xxp1 {
14284 + uint64_t reserved_12_63:52;
14285 + uint64_t lenerr:1;
14286 + uint64_t maxerr:1;
14287 + uint64_t minerr:1;
14288 + uint64_t beperr:1;
14289 + uint64_t feperr:1;
14290 + uint64_t todoovr:1;
14291 + uint64_t skprunt:1;
14292 + uint64_t badtag:1;
14293 + uint64_t prtnxa:1;
14294 + uint64_t bckprs:1;
14295 + uint64_t crcerr:1;
14296 + uint64_t pktdrp:1;
14297 + } cn56xxp1;
14298 + struct cvmx_pip_int_en_cn58xx {
14299 + uint64_t reserved_13_63:51;
14300 + uint64_t punyerr:1;
14301 + uint64_t reserved_9_11:3;
14302 + uint64_t beperr:1;
14303 + uint64_t feperr:1;
14304 + uint64_t todoovr:1;
14305 + uint64_t skprunt:1;
14306 + uint64_t badtag:1;
14307 + uint64_t prtnxa:1;
14308 + uint64_t bckprs:1;
14309 + uint64_t crcerr:1;
14310 + uint64_t pktdrp:1;
14311 + } cn58xx;
14312 + struct cvmx_pip_int_en_cn30xx cn58xxp1;
14313 +};
14314 +
14315 +union cvmx_pip_int_reg {
14316 + uint64_t u64;
14317 + struct cvmx_pip_int_reg_s {
14318 + uint64_t reserved_13_63:51;
14319 + uint64_t punyerr:1;
14320 + uint64_t lenerr:1;
14321 + uint64_t maxerr:1;
14322 + uint64_t minerr:1;
14323 + uint64_t beperr:1;
14324 + uint64_t feperr:1;
14325 + uint64_t todoovr:1;
14326 + uint64_t skprunt:1;
14327 + uint64_t badtag:1;
14328 + uint64_t prtnxa:1;
14329 + uint64_t bckprs:1;
14330 + uint64_t crcerr:1;
14331 + uint64_t pktdrp:1;
14332 + } s;
14333 + struct cvmx_pip_int_reg_cn30xx {
14334 + uint64_t reserved_9_63:55;
14335 + uint64_t beperr:1;
14336 + uint64_t feperr:1;
14337 + uint64_t todoovr:1;
14338 + uint64_t skprunt:1;
14339 + uint64_t badtag:1;
14340 + uint64_t prtnxa:1;
14341 + uint64_t bckprs:1;
14342 + uint64_t crcerr:1;
14343 + uint64_t pktdrp:1;
14344 + } cn30xx;
14345 + struct cvmx_pip_int_reg_cn30xx cn31xx;
14346 + struct cvmx_pip_int_reg_cn30xx cn38xx;
14347 + struct cvmx_pip_int_reg_cn30xx cn38xxp2;
14348 + struct cvmx_pip_int_reg_cn50xx {
14349 + uint64_t reserved_12_63:52;
14350 + uint64_t lenerr:1;
14351 + uint64_t maxerr:1;
14352 + uint64_t minerr:1;
14353 + uint64_t beperr:1;
14354 + uint64_t feperr:1;
14355 + uint64_t todoovr:1;
14356 + uint64_t skprunt:1;
14357 + uint64_t badtag:1;
14358 + uint64_t prtnxa:1;
14359 + uint64_t bckprs:1;
14360 + uint64_t reserved_1_1:1;
14361 + uint64_t pktdrp:1;
14362 + } cn50xx;
14363 + struct cvmx_pip_int_reg_cn52xx {
14364 + uint64_t reserved_13_63:51;
14365 + uint64_t punyerr:1;
14366 + uint64_t lenerr:1;
14367 + uint64_t maxerr:1;
14368 + uint64_t minerr:1;
14369 + uint64_t beperr:1;
14370 + uint64_t feperr:1;
14371 + uint64_t todoovr:1;
14372 + uint64_t skprunt:1;
14373 + uint64_t badtag:1;
14374 + uint64_t prtnxa:1;
14375 + uint64_t bckprs:1;
14376 + uint64_t reserved_1_1:1;
14377 + uint64_t pktdrp:1;
14378 + } cn52xx;
14379 + struct cvmx_pip_int_reg_cn52xx cn52xxp1;
14380 + struct cvmx_pip_int_reg_s cn56xx;
14381 + struct cvmx_pip_int_reg_cn56xxp1 {
14382 + uint64_t reserved_12_63:52;
14383 + uint64_t lenerr:1;
14384 + uint64_t maxerr:1;
14385 + uint64_t minerr:1;
14386 + uint64_t beperr:1;
14387 + uint64_t feperr:1;
14388 + uint64_t todoovr:1;
14389 + uint64_t skprunt:1;
14390 + uint64_t badtag:1;
14391 + uint64_t prtnxa:1;
14392 + uint64_t bckprs:1;
14393 + uint64_t crcerr:1;
14394 + uint64_t pktdrp:1;
14395 + } cn56xxp1;
14396 + struct cvmx_pip_int_reg_cn58xx {
14397 + uint64_t reserved_13_63:51;
14398 + uint64_t punyerr:1;
14399 + uint64_t reserved_9_11:3;
14400 + uint64_t beperr:1;
14401 + uint64_t feperr:1;
14402 + uint64_t todoovr:1;
14403 + uint64_t skprunt:1;
14404 + uint64_t badtag:1;
14405 + uint64_t prtnxa:1;
14406 + uint64_t bckprs:1;
14407 + uint64_t crcerr:1;
14408 + uint64_t pktdrp:1;
14409 + } cn58xx;
14410 + struct cvmx_pip_int_reg_cn30xx cn58xxp1;
14411 +};
14412 +
14413 +union cvmx_pip_ip_offset {
14414 + uint64_t u64;
14415 + struct cvmx_pip_ip_offset_s {
14416 + uint64_t reserved_3_63:61;
14417 + uint64_t offset:3;
14418 + } s;
14419 + struct cvmx_pip_ip_offset_s cn30xx;
14420 + struct cvmx_pip_ip_offset_s cn31xx;
14421 + struct cvmx_pip_ip_offset_s cn38xx;
14422 + struct cvmx_pip_ip_offset_s cn38xxp2;
14423 + struct cvmx_pip_ip_offset_s cn50xx;
14424 + struct cvmx_pip_ip_offset_s cn52xx;
14425 + struct cvmx_pip_ip_offset_s cn52xxp1;
14426 + struct cvmx_pip_ip_offset_s cn56xx;
14427 + struct cvmx_pip_ip_offset_s cn56xxp1;
14428 + struct cvmx_pip_ip_offset_s cn58xx;
14429 + struct cvmx_pip_ip_offset_s cn58xxp1;
14430 +};
14431 +
14432 +union cvmx_pip_prt_cfgx {
14433 + uint64_t u64;
14434 + struct cvmx_pip_prt_cfgx_s {
14435 + uint64_t reserved_53_63:11;
14436 + uint64_t pad_len:1;
14437 + uint64_t vlan_len:1;
14438 + uint64_t lenerr_en:1;
14439 + uint64_t maxerr_en:1;
14440 + uint64_t minerr_en:1;
14441 + uint64_t grp_wat_47:4;
14442 + uint64_t qos_wat_47:4;
14443 + uint64_t reserved_37_39:3;
14444 + uint64_t rawdrp:1;
14445 + uint64_t tag_inc:2;
14446 + uint64_t dyn_rs:1;
14447 + uint64_t inst_hdr:1;
14448 + uint64_t grp_wat:4;
14449 + uint64_t hg_qos:1;
14450 + uint64_t qos:3;
14451 + uint64_t qos_wat:4;
14452 + uint64_t qos_vsel:1;
14453 + uint64_t qos_vod:1;
14454 + uint64_t qos_diff:1;
14455 + uint64_t qos_vlan:1;
14456 + uint64_t reserved_13_15:3;
14457 + uint64_t crc_en:1;
14458 + uint64_t higig_en:1;
14459 + uint64_t dsa_en:1;
14460 + uint64_t mode:2;
14461 + uint64_t reserved_7_7:1;
14462 + uint64_t skip:7;
14463 + } s;
14464 + struct cvmx_pip_prt_cfgx_cn30xx {
14465 + uint64_t reserved_37_63:27;
14466 + uint64_t rawdrp:1;
14467 + uint64_t tag_inc:2;
14468 + uint64_t dyn_rs:1;
14469 + uint64_t inst_hdr:1;
14470 + uint64_t grp_wat:4;
14471 + uint64_t reserved_27_27:1;
14472 + uint64_t qos:3;
14473 + uint64_t qos_wat:4;
14474 + uint64_t reserved_18_19:2;
14475 + uint64_t qos_diff:1;
14476 + uint64_t qos_vlan:1;
14477 + uint64_t reserved_10_15:6;
14478 + uint64_t mode:2;
14479 + uint64_t reserved_7_7:1;
14480 + uint64_t skip:7;
14481 + } cn30xx;
14482 + struct cvmx_pip_prt_cfgx_cn30xx cn31xx;
14483 + struct cvmx_pip_prt_cfgx_cn38xx {
14484 + uint64_t reserved_37_63:27;
14485 + uint64_t rawdrp:1;
14486 + uint64_t tag_inc:2;
14487 + uint64_t dyn_rs:1;
14488 + uint64_t inst_hdr:1;
14489 + uint64_t grp_wat:4;
14490 + uint64_t reserved_27_27:1;
14491 + uint64_t qos:3;
14492 + uint64_t qos_wat:4;
14493 + uint64_t reserved_18_19:2;
14494 + uint64_t qos_diff:1;
14495 + uint64_t qos_vlan:1;
14496 + uint64_t reserved_13_15:3;
14497 + uint64_t crc_en:1;
14498 + uint64_t reserved_10_11:2;
14499 + uint64_t mode:2;
14500 + uint64_t reserved_7_7:1;
14501 + uint64_t skip:7;
14502 + } cn38xx;
14503 + struct cvmx_pip_prt_cfgx_cn38xx cn38xxp2;
14504 + struct cvmx_pip_prt_cfgx_cn50xx {
14505 + uint64_t reserved_53_63:11;
14506 + uint64_t pad_len:1;
14507 + uint64_t vlan_len:1;
14508 + uint64_t lenerr_en:1;
14509 + uint64_t maxerr_en:1;
14510 + uint64_t minerr_en:1;
14511 + uint64_t grp_wat_47:4;
14512 + uint64_t qos_wat_47:4;
14513 + uint64_t reserved_37_39:3;
14514 + uint64_t rawdrp:1;
14515 + uint64_t tag_inc:2;
14516 + uint64_t dyn_rs:1;
14517 + uint64_t inst_hdr:1;
14518 + uint64_t grp_wat:4;
14519 + uint64_t reserved_27_27:1;
14520 + uint64_t qos:3;
14521 + uint64_t qos_wat:4;
14522 + uint64_t reserved_19_19:1;
14523 + uint64_t qos_vod:1;
14524 + uint64_t qos_diff:1;
14525 + uint64_t qos_vlan:1;
14526 + uint64_t reserved_13_15:3;
14527 + uint64_t crc_en:1;
14528 + uint64_t reserved_10_11:2;
14529 + uint64_t mode:2;
14530 + uint64_t reserved_7_7:1;
14531 + uint64_t skip:7;
14532 + } cn50xx;
14533 + struct cvmx_pip_prt_cfgx_s cn52xx;
14534 + struct cvmx_pip_prt_cfgx_s cn52xxp1;
14535 + struct cvmx_pip_prt_cfgx_s cn56xx;
14536 + struct cvmx_pip_prt_cfgx_cn50xx cn56xxp1;
14537 + struct cvmx_pip_prt_cfgx_cn58xx {
14538 + uint64_t reserved_37_63:27;
14539 + uint64_t rawdrp:1;
14540 + uint64_t tag_inc:2;
14541 + uint64_t dyn_rs:1;
14542 + uint64_t inst_hdr:1;
14543 + uint64_t grp_wat:4;
14544 + uint64_t reserved_27_27:1;
14545 + uint64_t qos:3;
14546 + uint64_t qos_wat:4;
14547 + uint64_t reserved_19_19:1;
14548 + uint64_t qos_vod:1;
14549 + uint64_t qos_diff:1;
14550 + uint64_t qos_vlan:1;
14551 + uint64_t reserved_13_15:3;
14552 + uint64_t crc_en:1;
14553 + uint64_t reserved_10_11:2;
14554 + uint64_t mode:2;
14555 + uint64_t reserved_7_7:1;
14556 + uint64_t skip:7;
14557 + } cn58xx;
14558 + struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1;
14559 +};
14560 +
14561 +union cvmx_pip_prt_tagx {
14562 + uint64_t u64;
14563 + struct cvmx_pip_prt_tagx_s {
14564 + uint64_t reserved_40_63:24;
14565 + uint64_t grptagbase:4;
14566 + uint64_t grptagmask:4;
14567 + uint64_t grptag:1;
14568 + uint64_t grptag_mskip:1;
14569 + uint64_t tag_mode:2;
14570 + uint64_t inc_vs:2;
14571 + uint64_t inc_vlan:1;
14572 + uint64_t inc_prt_flag:1;
14573 + uint64_t ip6_dprt_flag:1;
14574 + uint64_t ip4_dprt_flag:1;
14575 + uint64_t ip6_sprt_flag:1;
14576 + uint64_t ip4_sprt_flag:1;
14577 + uint64_t ip6_nxth_flag:1;
14578 + uint64_t ip4_pctl_flag:1;
14579 + uint64_t ip6_dst_flag:1;
14580 + uint64_t ip4_dst_flag:1;
14581 + uint64_t ip6_src_flag:1;
14582 + uint64_t ip4_src_flag:1;
14583 + uint64_t tcp6_tag_type:2;
14584 + uint64_t tcp4_tag_type:2;
14585 + uint64_t ip6_tag_type:2;
14586 + uint64_t ip4_tag_type:2;
14587 + uint64_t non_tag_type:2;
14588 + uint64_t grp:4;
14589 + } s;
14590 + struct cvmx_pip_prt_tagx_cn30xx {
14591 + uint64_t reserved_40_63:24;
14592 + uint64_t grptagbase:4;
14593 + uint64_t grptagmask:4;
14594 + uint64_t grptag:1;
14595 + uint64_t reserved_30_30:1;
14596 + uint64_t tag_mode:2;
14597 + uint64_t inc_vs:2;
14598 + uint64_t inc_vlan:1;
14599 + uint64_t inc_prt_flag:1;
14600 + uint64_t ip6_dprt_flag:1;
14601 + uint64_t ip4_dprt_flag:1;
14602 + uint64_t ip6_sprt_flag:1;
14603 + uint64_t ip4_sprt_flag:1;
14604 + uint64_t ip6_nxth_flag:1;
14605 + uint64_t ip4_pctl_flag:1;
14606 + uint64_t ip6_dst_flag:1;
14607 + uint64_t ip4_dst_flag:1;
14608 + uint64_t ip6_src_flag:1;
14609 + uint64_t ip4_src_flag:1;
14610 + uint64_t tcp6_tag_type:2;
14611 + uint64_t tcp4_tag_type:2;
14612 + uint64_t ip6_tag_type:2;
14613 + uint64_t ip4_tag_type:2;
14614 + uint64_t non_tag_type:2;
14615 + uint64_t grp:4;
14616 + } cn30xx;
14617 + struct cvmx_pip_prt_tagx_cn30xx cn31xx;
14618 + struct cvmx_pip_prt_tagx_cn30xx cn38xx;
14619 + struct cvmx_pip_prt_tagx_cn30xx cn38xxp2;
14620 + struct cvmx_pip_prt_tagx_s cn50xx;
14621 + struct cvmx_pip_prt_tagx_s cn52xx;
14622 + struct cvmx_pip_prt_tagx_s cn52xxp1;
14623 + struct cvmx_pip_prt_tagx_s cn56xx;
14624 + struct cvmx_pip_prt_tagx_s cn56xxp1;
14625 + struct cvmx_pip_prt_tagx_cn30xx cn58xx;
14626 + struct cvmx_pip_prt_tagx_cn30xx cn58xxp1;
14627 +};
14628 +
14629 +union cvmx_pip_qos_diffx {
14630 + uint64_t u64;
14631 + struct cvmx_pip_qos_diffx_s {
14632 + uint64_t reserved_3_63:61;
14633 + uint64_t qos:3;
14634 + } s;
14635 + struct cvmx_pip_qos_diffx_s cn30xx;
14636 + struct cvmx_pip_qos_diffx_s cn31xx;
14637 + struct cvmx_pip_qos_diffx_s cn38xx;
14638 + struct cvmx_pip_qos_diffx_s cn38xxp2;
14639 + struct cvmx_pip_qos_diffx_s cn50xx;
14640 + struct cvmx_pip_qos_diffx_s cn52xx;
14641 + struct cvmx_pip_qos_diffx_s cn52xxp1;
14642 + struct cvmx_pip_qos_diffx_s cn56xx;
14643 + struct cvmx_pip_qos_diffx_s cn56xxp1;
14644 + struct cvmx_pip_qos_diffx_s cn58xx;
14645 + struct cvmx_pip_qos_diffx_s cn58xxp1;
14646 +};
14647 +
14648 +union cvmx_pip_qos_vlanx {
14649 + uint64_t u64;
14650 + struct cvmx_pip_qos_vlanx_s {
14651 + uint64_t reserved_7_63:57;
14652 + uint64_t qos1:3;
14653 + uint64_t reserved_3_3:1;
14654 + uint64_t qos:3;
14655 + } s;
14656 + struct cvmx_pip_qos_vlanx_cn30xx {
14657 + uint64_t reserved_3_63:61;
14658 + uint64_t qos:3;
14659 + } cn30xx;
14660 + struct cvmx_pip_qos_vlanx_cn30xx cn31xx;
14661 + struct cvmx_pip_qos_vlanx_cn30xx cn38xx;
14662 + struct cvmx_pip_qos_vlanx_cn30xx cn38xxp2;
14663 + struct cvmx_pip_qos_vlanx_cn30xx cn50xx;
14664 + struct cvmx_pip_qos_vlanx_s cn52xx;
14665 + struct cvmx_pip_qos_vlanx_s cn52xxp1;
14666 + struct cvmx_pip_qos_vlanx_s cn56xx;
14667 + struct cvmx_pip_qos_vlanx_cn30xx cn56xxp1;
14668 + struct cvmx_pip_qos_vlanx_cn30xx cn58xx;
14669 + struct cvmx_pip_qos_vlanx_cn30xx cn58xxp1;
14670 +};
14671 +
14672 +union cvmx_pip_qos_watchx {
14673 + uint64_t u64;
14674 + struct cvmx_pip_qos_watchx_s {
14675 + uint64_t reserved_48_63:16;
14676 + uint64_t mask:16;
14677 + uint64_t reserved_28_31:4;
14678 + uint64_t grp:4;
14679 + uint64_t reserved_23_23:1;
14680 + uint64_t qos:3;
14681 + uint64_t reserved_19_19:1;
14682 + uint64_t match_type:3;
14683 + uint64_t match_value:16;
14684 + } s;
14685 + struct cvmx_pip_qos_watchx_cn30xx {
14686 + uint64_t reserved_48_63:16;
14687 + uint64_t mask:16;
14688 + uint64_t reserved_28_31:4;
14689 + uint64_t grp:4;
14690 + uint64_t reserved_23_23:1;
14691 + uint64_t qos:3;
14692 + uint64_t reserved_18_19:2;
14693 + uint64_t match_type:2;
14694 + uint64_t match_value:16;
14695 + } cn30xx;
14696 + struct cvmx_pip_qos_watchx_cn30xx cn31xx;
14697 + struct cvmx_pip_qos_watchx_cn30xx cn38xx;
14698 + struct cvmx_pip_qos_watchx_cn30xx cn38xxp2;
14699 + struct cvmx_pip_qos_watchx_s cn50xx;
14700 + struct cvmx_pip_qos_watchx_s cn52xx;
14701 + struct cvmx_pip_qos_watchx_s cn52xxp1;
14702 + struct cvmx_pip_qos_watchx_s cn56xx;
14703 + struct cvmx_pip_qos_watchx_s cn56xxp1;
14704 + struct cvmx_pip_qos_watchx_cn30xx cn58xx;
14705 + struct cvmx_pip_qos_watchx_cn30xx cn58xxp1;
14706 +};
14707 +
14708 +union cvmx_pip_raw_word {
14709 + uint64_t u64;
14710 + struct cvmx_pip_raw_word_s {
14711 + uint64_t reserved_56_63:8;
14712 + uint64_t word:56;
14713 + } s;
14714 + struct cvmx_pip_raw_word_s cn30xx;
14715 + struct cvmx_pip_raw_word_s cn31xx;
14716 + struct cvmx_pip_raw_word_s cn38xx;
14717 + struct cvmx_pip_raw_word_s cn38xxp2;
14718 + struct cvmx_pip_raw_word_s cn50xx;
14719 + struct cvmx_pip_raw_word_s cn52xx;
14720 + struct cvmx_pip_raw_word_s cn52xxp1;
14721 + struct cvmx_pip_raw_word_s cn56xx;
14722 + struct cvmx_pip_raw_word_s cn56xxp1;
14723 + struct cvmx_pip_raw_word_s cn58xx;
14724 + struct cvmx_pip_raw_word_s cn58xxp1;
14725 +};
14726 +
14727 +union cvmx_pip_sft_rst {
14728 + uint64_t u64;
14729 + struct cvmx_pip_sft_rst_s {
14730 + uint64_t reserved_1_63:63;
14731 + uint64_t rst:1;
14732 + } s;
14733 + struct cvmx_pip_sft_rst_s cn30xx;
14734 + struct cvmx_pip_sft_rst_s cn31xx;
14735 + struct cvmx_pip_sft_rst_s cn38xx;
14736 + struct cvmx_pip_sft_rst_s cn50xx;
14737 + struct cvmx_pip_sft_rst_s cn52xx;
14738 + struct cvmx_pip_sft_rst_s cn52xxp1;
14739 + struct cvmx_pip_sft_rst_s cn56xx;
14740 + struct cvmx_pip_sft_rst_s cn56xxp1;
14741 + struct cvmx_pip_sft_rst_s cn58xx;
14742 + struct cvmx_pip_sft_rst_s cn58xxp1;
14743 +};
14744 +
14745 +union cvmx_pip_stat0_prtx {
14746 + uint64_t u64;
14747 + struct cvmx_pip_stat0_prtx_s {
14748 + uint64_t drp_pkts:32;
14749 + uint64_t drp_octs:32;
14750 + } s;
14751 + struct cvmx_pip_stat0_prtx_s cn30xx;
14752 + struct cvmx_pip_stat0_prtx_s cn31xx;
14753 + struct cvmx_pip_stat0_prtx_s cn38xx;
14754 + struct cvmx_pip_stat0_prtx_s cn38xxp2;
14755 + struct cvmx_pip_stat0_prtx_s cn50xx;
14756 + struct cvmx_pip_stat0_prtx_s cn52xx;
14757 + struct cvmx_pip_stat0_prtx_s cn52xxp1;
14758 + struct cvmx_pip_stat0_prtx_s cn56xx;
14759 + struct cvmx_pip_stat0_prtx_s cn56xxp1;
14760 + struct cvmx_pip_stat0_prtx_s cn58xx;
14761 + struct cvmx_pip_stat0_prtx_s cn58xxp1;
14762 +};
14763 +
14764 +union cvmx_pip_stat1_prtx {
14765 + uint64_t u64;
14766 + struct cvmx_pip_stat1_prtx_s {
14767 + uint64_t reserved_48_63:16;
14768 + uint64_t octs:48;
14769 + } s;
14770 + struct cvmx_pip_stat1_prtx_s cn30xx;
14771 + struct cvmx_pip_stat1_prtx_s cn31xx;
14772 + struct cvmx_pip_stat1_prtx_s cn38xx;
14773 + struct cvmx_pip_stat1_prtx_s cn38xxp2;
14774 + struct cvmx_pip_stat1_prtx_s cn50xx;
14775 + struct cvmx_pip_stat1_prtx_s cn52xx;
14776 + struct cvmx_pip_stat1_prtx_s cn52xxp1;
14777 + struct cvmx_pip_stat1_prtx_s cn56xx;
14778 + struct cvmx_pip_stat1_prtx_s cn56xxp1;
14779 + struct cvmx_pip_stat1_prtx_s cn58xx;
14780 + struct cvmx_pip_stat1_prtx_s cn58xxp1;
14781 +};
14782 +
14783 +union cvmx_pip_stat2_prtx {
14784 + uint64_t u64;
14785 + struct cvmx_pip_stat2_prtx_s {
14786 + uint64_t pkts:32;
14787 + uint64_t raw:32;
14788 + } s;
14789 + struct cvmx_pip_stat2_prtx_s cn30xx;
14790 + struct cvmx_pip_stat2_prtx_s cn31xx;
14791 + struct cvmx_pip_stat2_prtx_s cn38xx;
14792 + struct cvmx_pip_stat2_prtx_s cn38xxp2;
14793 + struct cvmx_pip_stat2_prtx_s cn50xx;
14794 + struct cvmx_pip_stat2_prtx_s cn52xx;
14795 + struct cvmx_pip_stat2_prtx_s cn52xxp1;
14796 + struct cvmx_pip_stat2_prtx_s cn56xx;
14797 + struct cvmx_pip_stat2_prtx_s cn56xxp1;
14798 + struct cvmx_pip_stat2_prtx_s cn58xx;
14799 + struct cvmx_pip_stat2_prtx_s cn58xxp1;
14800 +};
14801 +
14802 +union cvmx_pip_stat3_prtx {
14803 + uint64_t u64;
14804 + struct cvmx_pip_stat3_prtx_s {
14805 + uint64_t bcst:32;
14806 + uint64_t mcst:32;
14807 + } s;
14808 + struct cvmx_pip_stat3_prtx_s cn30xx;
14809 + struct cvmx_pip_stat3_prtx_s cn31xx;
14810 + struct cvmx_pip_stat3_prtx_s cn38xx;
14811 + struct cvmx_pip_stat3_prtx_s cn38xxp2;
14812 + struct cvmx_pip_stat3_prtx_s cn50xx;
14813 + struct cvmx_pip_stat3_prtx_s cn52xx;
14814 + struct cvmx_pip_stat3_prtx_s cn52xxp1;
14815 + struct cvmx_pip_stat3_prtx_s cn56xx;
14816 + struct cvmx_pip_stat3_prtx_s cn56xxp1;
14817 + struct cvmx_pip_stat3_prtx_s cn58xx;
14818 + struct cvmx_pip_stat3_prtx_s cn58xxp1;
14819 +};
14820 +
14821 +union cvmx_pip_stat4_prtx {
14822 + uint64_t u64;
14823 + struct cvmx_pip_stat4_prtx_s {
14824 + uint64_t h65to127:32;
14825 + uint64_t h64:32;
14826 + } s;
14827 + struct cvmx_pip_stat4_prtx_s cn30xx;
14828 + struct cvmx_pip_stat4_prtx_s cn31xx;
14829 + struct cvmx_pip_stat4_prtx_s cn38xx;
14830 + struct cvmx_pip_stat4_prtx_s cn38xxp2;
14831 + struct cvmx_pip_stat4_prtx_s cn50xx;
14832 + struct cvmx_pip_stat4_prtx_s cn52xx;
14833 + struct cvmx_pip_stat4_prtx_s cn52xxp1;
14834 + struct cvmx_pip_stat4_prtx_s cn56xx;
14835 + struct cvmx_pip_stat4_prtx_s cn56xxp1;
14836 + struct cvmx_pip_stat4_prtx_s cn58xx;
14837 + struct cvmx_pip_stat4_prtx_s cn58xxp1;
14838 +};
14839 +
14840 +union cvmx_pip_stat5_prtx {
14841 + uint64_t u64;
14842 + struct cvmx_pip_stat5_prtx_s {
14843 + uint64_t h256to511:32;
14844 + uint64_t h128to255:32;
14845 + } s;
14846 + struct cvmx_pip_stat5_prtx_s cn30xx;
14847 + struct cvmx_pip_stat5_prtx_s cn31xx;
14848 + struct cvmx_pip_stat5_prtx_s cn38xx;
14849 + struct cvmx_pip_stat5_prtx_s cn38xxp2;
14850 + struct cvmx_pip_stat5_prtx_s cn50xx;
14851 + struct cvmx_pip_stat5_prtx_s cn52xx;
14852 + struct cvmx_pip_stat5_prtx_s cn52xxp1;
14853 + struct cvmx_pip_stat5_prtx_s cn56xx;
14854 + struct cvmx_pip_stat5_prtx_s cn56xxp1;
14855 + struct cvmx_pip_stat5_prtx_s cn58xx;
14856 + struct cvmx_pip_stat5_prtx_s cn58xxp1;
14857 +};
14858 +
14859 +union cvmx_pip_stat6_prtx {
14860 + uint64_t u64;
14861 + struct cvmx_pip_stat6_prtx_s {
14862 + uint64_t h1024to1518:32;
14863 + uint64_t h512to1023:32;
14864 + } s;
14865 + struct cvmx_pip_stat6_prtx_s cn30xx;
14866 + struct cvmx_pip_stat6_prtx_s cn31xx;
14867 + struct cvmx_pip_stat6_prtx_s cn38xx;
14868 + struct cvmx_pip_stat6_prtx_s cn38xxp2;
14869 + struct cvmx_pip_stat6_prtx_s cn50xx;
14870 + struct cvmx_pip_stat6_prtx_s cn52xx;
14871 + struct cvmx_pip_stat6_prtx_s cn52xxp1;
14872 + struct cvmx_pip_stat6_prtx_s cn56xx;
14873 + struct cvmx_pip_stat6_prtx_s cn56xxp1;
14874 + struct cvmx_pip_stat6_prtx_s cn58xx;
14875 + struct cvmx_pip_stat6_prtx_s cn58xxp1;
14876 +};
14877 +
14878 +union cvmx_pip_stat7_prtx {
14879 + uint64_t u64;
14880 + struct cvmx_pip_stat7_prtx_s {
14881 + uint64_t fcs:32;
14882 + uint64_t h1519:32;
14883 + } s;
14884 + struct cvmx_pip_stat7_prtx_s cn30xx;
14885 + struct cvmx_pip_stat7_prtx_s cn31xx;
14886 + struct cvmx_pip_stat7_prtx_s cn38xx;
14887 + struct cvmx_pip_stat7_prtx_s cn38xxp2;
14888 + struct cvmx_pip_stat7_prtx_s cn50xx;
14889 + struct cvmx_pip_stat7_prtx_s cn52xx;
14890 + struct cvmx_pip_stat7_prtx_s cn52xxp1;
14891 + struct cvmx_pip_stat7_prtx_s cn56xx;
14892 + struct cvmx_pip_stat7_prtx_s cn56xxp1;
14893 + struct cvmx_pip_stat7_prtx_s cn58xx;
14894 + struct cvmx_pip_stat7_prtx_s cn58xxp1;
14895 +};
14896 +
14897 +union cvmx_pip_stat8_prtx {
14898 + uint64_t u64;
14899 + struct cvmx_pip_stat8_prtx_s {
14900 + uint64_t frag:32;
14901 + uint64_t undersz:32;
14902 + } s;
14903 + struct cvmx_pip_stat8_prtx_s cn30xx;
14904 + struct cvmx_pip_stat8_prtx_s cn31xx;
14905 + struct cvmx_pip_stat8_prtx_s cn38xx;
14906 + struct cvmx_pip_stat8_prtx_s cn38xxp2;
14907 + struct cvmx_pip_stat8_prtx_s cn50xx;
14908 + struct cvmx_pip_stat8_prtx_s cn52xx;
14909 + struct cvmx_pip_stat8_prtx_s cn52xxp1;
14910 + struct cvmx_pip_stat8_prtx_s cn56xx;
14911 + struct cvmx_pip_stat8_prtx_s cn56xxp1;
14912 + struct cvmx_pip_stat8_prtx_s cn58xx;
14913 + struct cvmx_pip_stat8_prtx_s cn58xxp1;
14914 +};
14915 +
14916 +union cvmx_pip_stat9_prtx {
14917 + uint64_t u64;
14918 + struct cvmx_pip_stat9_prtx_s {
14919 + uint64_t jabber:32;
14920 + uint64_t oversz:32;
14921 + } s;
14922 + struct cvmx_pip_stat9_prtx_s cn30xx;
14923 + struct cvmx_pip_stat9_prtx_s cn31xx;
14924 + struct cvmx_pip_stat9_prtx_s cn38xx;
14925 + struct cvmx_pip_stat9_prtx_s cn38xxp2;
14926 + struct cvmx_pip_stat9_prtx_s cn50xx;
14927 + struct cvmx_pip_stat9_prtx_s cn52xx;
14928 + struct cvmx_pip_stat9_prtx_s cn52xxp1;
14929 + struct cvmx_pip_stat9_prtx_s cn56xx;
14930 + struct cvmx_pip_stat9_prtx_s cn56xxp1;
14931 + struct cvmx_pip_stat9_prtx_s cn58xx;
14932 + struct cvmx_pip_stat9_prtx_s cn58xxp1;
14933 +};
14934 +
14935 +union cvmx_pip_stat_ctl {
14936 + uint64_t u64;
14937 + struct cvmx_pip_stat_ctl_s {
14938 + uint64_t reserved_1_63:63;
14939 + uint64_t rdclr:1;
14940 + } s;
14941 + struct cvmx_pip_stat_ctl_s cn30xx;
14942 + struct cvmx_pip_stat_ctl_s cn31xx;
14943 + struct cvmx_pip_stat_ctl_s cn38xx;
14944 + struct cvmx_pip_stat_ctl_s cn38xxp2;
14945 + struct cvmx_pip_stat_ctl_s cn50xx;
14946 + struct cvmx_pip_stat_ctl_s cn52xx;
14947 + struct cvmx_pip_stat_ctl_s cn52xxp1;
14948 + struct cvmx_pip_stat_ctl_s cn56xx;
14949 + struct cvmx_pip_stat_ctl_s cn56xxp1;
14950 + struct cvmx_pip_stat_ctl_s cn58xx;
14951 + struct cvmx_pip_stat_ctl_s cn58xxp1;
14952 +};
14953 +
14954 +union cvmx_pip_stat_inb_errsx {
14955 + uint64_t u64;
14956 + struct cvmx_pip_stat_inb_errsx_s {
14957 + uint64_t reserved_16_63:48;
14958 + uint64_t errs:16;
14959 + } s;
14960 + struct cvmx_pip_stat_inb_errsx_s cn30xx;
14961 + struct cvmx_pip_stat_inb_errsx_s cn31xx;
14962 + struct cvmx_pip_stat_inb_errsx_s cn38xx;
14963 + struct cvmx_pip_stat_inb_errsx_s cn38xxp2;
14964 + struct cvmx_pip_stat_inb_errsx_s cn50xx;
14965 + struct cvmx_pip_stat_inb_errsx_s cn52xx;
14966 + struct cvmx_pip_stat_inb_errsx_s cn52xxp1;
14967 + struct cvmx_pip_stat_inb_errsx_s cn56xx;
14968 + struct cvmx_pip_stat_inb_errsx_s cn56xxp1;
14969 + struct cvmx_pip_stat_inb_errsx_s cn58xx;
14970 + struct cvmx_pip_stat_inb_errsx_s cn58xxp1;
14971 +};
14972 +
14973 +union cvmx_pip_stat_inb_octsx {
14974 + uint64_t u64;
14975 + struct cvmx_pip_stat_inb_octsx_s {
14976 + uint64_t reserved_48_63:16;
14977 + uint64_t octs:48;
14978 + } s;
14979 + struct cvmx_pip_stat_inb_octsx_s cn30xx;
14980 + struct cvmx_pip_stat_inb_octsx_s cn31xx;
14981 + struct cvmx_pip_stat_inb_octsx_s cn38xx;
14982 + struct cvmx_pip_stat_inb_octsx_s cn38xxp2;
14983 + struct cvmx_pip_stat_inb_octsx_s cn50xx;
14984 + struct cvmx_pip_stat_inb_octsx_s cn52xx;
14985 + struct cvmx_pip_stat_inb_octsx_s cn52xxp1;
14986 + struct cvmx_pip_stat_inb_octsx_s cn56xx;
14987 + struct cvmx_pip_stat_inb_octsx_s cn56xxp1;
14988 + struct cvmx_pip_stat_inb_octsx_s cn58xx;
14989 + struct cvmx_pip_stat_inb_octsx_s cn58xxp1;
14990 +};
14991 +
14992 +union cvmx_pip_stat_inb_pktsx {
14993 + uint64_t u64;
14994 + struct cvmx_pip_stat_inb_pktsx_s {
14995 + uint64_t reserved_32_63:32;
14996 + uint64_t pkts:32;
14997 + } s;
14998 + struct cvmx_pip_stat_inb_pktsx_s cn30xx;
14999 + struct cvmx_pip_stat_inb_pktsx_s cn31xx;
15000 + struct cvmx_pip_stat_inb_pktsx_s cn38xx;
15001 + struct cvmx_pip_stat_inb_pktsx_s cn38xxp2;
15002 + struct cvmx_pip_stat_inb_pktsx_s cn50xx;
15003 + struct cvmx_pip_stat_inb_pktsx_s cn52xx;
15004 + struct cvmx_pip_stat_inb_pktsx_s cn52xxp1;
15005 + struct cvmx_pip_stat_inb_pktsx_s cn56xx;
15006 + struct cvmx_pip_stat_inb_pktsx_s cn56xxp1;
15007 + struct cvmx_pip_stat_inb_pktsx_s cn58xx;
15008 + struct cvmx_pip_stat_inb_pktsx_s cn58xxp1;
15009 +};
15010 +
15011 +union cvmx_pip_tag_incx {
15012 + uint64_t u64;
15013 + struct cvmx_pip_tag_incx_s {
15014 + uint64_t reserved_8_63:56;
15015 + uint64_t en:8;
15016 + } s;
15017 + struct cvmx_pip_tag_incx_s cn30xx;
15018 + struct cvmx_pip_tag_incx_s cn31xx;
15019 + struct cvmx_pip_tag_incx_s cn38xx;
15020 + struct cvmx_pip_tag_incx_s cn38xxp2;
15021 + struct cvmx_pip_tag_incx_s cn50xx;
15022 + struct cvmx_pip_tag_incx_s cn52xx;
15023 + struct cvmx_pip_tag_incx_s cn52xxp1;
15024 + struct cvmx_pip_tag_incx_s cn56xx;
15025 + struct cvmx_pip_tag_incx_s cn56xxp1;
15026 + struct cvmx_pip_tag_incx_s cn58xx;
15027 + struct cvmx_pip_tag_incx_s cn58xxp1;
15028 +};
15029 +
15030 +union cvmx_pip_tag_mask {
15031 + uint64_t u64;
15032 + struct cvmx_pip_tag_mask_s {
15033 + uint64_t reserved_16_63:48;
15034 + uint64_t mask:16;
15035 + } s;
15036 + struct cvmx_pip_tag_mask_s cn30xx;
15037 + struct cvmx_pip_tag_mask_s cn31xx;
15038 + struct cvmx_pip_tag_mask_s cn38xx;
15039 + struct cvmx_pip_tag_mask_s cn38xxp2;
15040 + struct cvmx_pip_tag_mask_s cn50xx;
15041 + struct cvmx_pip_tag_mask_s cn52xx;
15042 + struct cvmx_pip_tag_mask_s cn52xxp1;
15043 + struct cvmx_pip_tag_mask_s cn56xx;
15044 + struct cvmx_pip_tag_mask_s cn56xxp1;
15045 + struct cvmx_pip_tag_mask_s cn58xx;
15046 + struct cvmx_pip_tag_mask_s cn58xxp1;
15047 +};
15048 +
15049 +union cvmx_pip_tag_secret {
15050 + uint64_t u64;
15051 + struct cvmx_pip_tag_secret_s {
15052 + uint64_t reserved_32_63:32;
15053 + uint64_t dst:16;
15054 + uint64_t src:16;
15055 + } s;
15056 + struct cvmx_pip_tag_secret_s cn30xx;
15057 + struct cvmx_pip_tag_secret_s cn31xx;
15058 + struct cvmx_pip_tag_secret_s cn38xx;
15059 + struct cvmx_pip_tag_secret_s cn38xxp2;
15060 + struct cvmx_pip_tag_secret_s cn50xx;
15061 + struct cvmx_pip_tag_secret_s cn52xx;
15062 + struct cvmx_pip_tag_secret_s cn52xxp1;
15063 + struct cvmx_pip_tag_secret_s cn56xx;
15064 + struct cvmx_pip_tag_secret_s cn56xxp1;
15065 + struct cvmx_pip_tag_secret_s cn58xx;
15066 + struct cvmx_pip_tag_secret_s cn58xxp1;
15067 +};
15068 +
15069 +union cvmx_pip_todo_entry {
15070 + uint64_t u64;
15071 + struct cvmx_pip_todo_entry_s {
15072 + uint64_t val:1;
15073 + uint64_t reserved_62_62:1;
15074 + uint64_t entry:62;
15075 + } s;
15076 + struct cvmx_pip_todo_entry_s cn30xx;
15077 + struct cvmx_pip_todo_entry_s cn31xx;
15078 + struct cvmx_pip_todo_entry_s cn38xx;
15079 + struct cvmx_pip_todo_entry_s cn38xxp2;
15080 + struct cvmx_pip_todo_entry_s cn50xx;
15081 + struct cvmx_pip_todo_entry_s cn52xx;
15082 + struct cvmx_pip_todo_entry_s cn52xxp1;
15083 + struct cvmx_pip_todo_entry_s cn56xx;
15084 + struct cvmx_pip_todo_entry_s cn56xxp1;
15085 + struct cvmx_pip_todo_entry_s cn58xx;
15086 + struct cvmx_pip_todo_entry_s cn58xxp1;
15087 +};
15088 +
15089 +#endif
15090 --- /dev/null
15091 +++ b/drivers/staging/octeon/cvmx-pip.h
15092 @@ -0,0 +1,524 @@
15093 +/***********************license start***************
15094 + * Author: Cavium Networks
15095 + *
15096 + * Contact: support@caviumnetworks.com
15097 + * This file is part of the OCTEON SDK
15098 + *
15099 + * Copyright (c) 2003-2008 Cavium Networks
15100 + *
15101 + * This file is free software; you can redistribute it and/or modify
15102 + * it under the terms of the GNU General Public License, Version 2, as
15103 + * published by the Free Software Foundation.
15104 + *
15105 + * This file is distributed in the hope that it will be useful, but
15106 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15107 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
15108 + * NONINFRINGEMENT. See the GNU General Public License for more
15109 + * details.
15110 + *
15111 + * You should have received a copy of the GNU General Public License
15112 + * along with this file; if not, write to the Free Software
15113 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15114 + * or visit http://www.gnu.org/licenses/.
15115 + *
15116 + * This file may also be available under a different license from Cavium.
15117 + * Contact Cavium Networks for more information
15118 + ***********************license end**************************************/
15119 +
15120 +/*
15121 + * Interface to the hardware Packet Input Processing unit.
15122 + *
15123 + */
15124 +
15125 +#ifndef __CVMX_PIP_H__
15126 +#define __CVMX_PIP_H__
15127 +
15128 +#include "cvmx-wqe.h"
15129 +#include "cvmx-fpa.h"
15130 +#include "cvmx-pip-defs.h"
15131 +
15132 +#define CVMX_PIP_NUM_INPUT_PORTS 40
15133 +#define CVMX_PIP_NUM_WATCHERS 4
15134 +
15135 +/*
15136 + * Encodes the different error and exception codes
15137 + */
15138 +typedef enum {
15139 + CVMX_PIP_L4_NO_ERR = 0ull,
15140 + /*
15141 + * 1 = TCP (UDP) packet not long enough to cover TCP (UDP)
15142 + * header
15143 + */
15144 + CVMX_PIP_L4_MAL_ERR = 1ull,
15145 + /* 2 = TCP/UDP checksum failure */
15146 + CVMX_PIP_CHK_ERR = 2ull,
15147 + /*
15148 + * 3 = TCP/UDP length check (TCP/UDP length does not match IP
15149 + * length).
15150 + */
15151 + CVMX_PIP_L4_LENGTH_ERR = 3ull,
15152 + /* 4 = illegal TCP/UDP port (either source or dest port is zero) */
15153 + CVMX_PIP_BAD_PRT_ERR = 4ull,
15154 + /* 8 = TCP flags = FIN only */
15155 + CVMX_PIP_TCP_FLG8_ERR = 8ull,
15156 + /* 9 = TCP flags = 0 */
15157 + CVMX_PIP_TCP_FLG9_ERR = 9ull,
15158 + /* 10 = TCP flags = FIN+RST+* */
15159 + CVMX_PIP_TCP_FLG10_ERR = 10ull,
15160 + /* 11 = TCP flags = SYN+URG+* */
15161 + CVMX_PIP_TCP_FLG11_ERR = 11ull,
15162 + /* 12 = TCP flags = SYN+RST+* */
15163 + CVMX_PIP_TCP_FLG12_ERR = 12ull,
15164 + /* 13 = TCP flags = SYN+FIN+* */
15165 + CVMX_PIP_TCP_FLG13_ERR = 13ull
15166 +} cvmx_pip_l4_err_t;
15167 +
15168 +typedef enum {
15169 +
15170 + CVMX_PIP_IP_NO_ERR = 0ull,
15171 + /* 1 = not IPv4 or IPv6 */
15172 + CVMX_PIP_NOT_IP = 1ull,
15173 + /* 2 = IPv4 header checksum violation */
15174 + CVMX_PIP_IPV4_HDR_CHK = 2ull,
15175 + /* 3 = malformed (packet not long enough to cover IP hdr) */
15176 + CVMX_PIP_IP_MAL_HDR = 3ull,
15177 + /* 4 = malformed (packet not long enough to cover len in IP hdr) */
15178 + CVMX_PIP_IP_MAL_PKT = 4ull,
15179 + /* 5 = TTL / hop count equal zero */
15180 + CVMX_PIP_TTL_HOP = 5ull,
15181 + /* 6 = IPv4 options / IPv6 early extension headers */
15182 + CVMX_PIP_OPTS = 6ull
15183 +} cvmx_pip_ip_exc_t;
15184 +
15185 +/**
15186 + * NOTES
15187 + * late collision (data received before collision)
15188 + * late collisions cannot be detected by the receiver
15189 + * they would appear as JAM bits which would appear as bad FCS
15190 + * or carrier extend error which is CVMX_PIP_EXTEND_ERR
15191 + */
15192 +typedef enum {
15193 + /* No error */
15194 + CVMX_PIP_RX_NO_ERR = 0ull,
15195 + /* RGM+SPI 1 = partially received packet (buffering/bandwidth
15196 + * not adequate) */
15197 + CVMX_PIP_PARTIAL_ERR = 1ull,
15198 + /* RGM+SPI 2 = receive packet too large and truncated */
15199 + CVMX_PIP_JABBER_ERR = 2ull,
15200 + /*
15201 + * RGM 3 = max frame error (pkt len > max frame len) (with FCS
15202 + * error)
15203 + */
15204 + CVMX_PIP_OVER_FCS_ERR = 3ull,
15205 + /* RGM+SPI 4 = max frame error (pkt len > max frame len) */
15206 + CVMX_PIP_OVER_ERR = 4ull,
15207 + /*
15208 + * RGM 5 = nibble error (data not byte multiple - 100M and 10M
15209 + * only)
15210 + */
15211 + CVMX_PIP_ALIGN_ERR = 5ull,
15212 + /*
15213 + * RGM 6 = min frame error (pkt len < min frame len) (with FCS
15214 + * error)
15215 + */
15216 + CVMX_PIP_UNDER_FCS_ERR = 6ull,
15217 + /* RGM 7 = FCS error */
15218 + CVMX_PIP_GMX_FCS_ERR = 7ull,
15219 + /* RGM+SPI 8 = min frame error (pkt len < min frame len) */
15220 + CVMX_PIP_UNDER_ERR = 8ull,
15221 + /* RGM 9 = Frame carrier extend error */
15222 + CVMX_PIP_EXTEND_ERR = 9ull,
15223 + /*
15224 + * RGM 10 = length mismatch (len did not match len in L2
15225 + * length/type)
15226 + */
15227 + CVMX_PIP_LENGTH_ERR = 10ull,
15228 + /* RGM 11 = Frame error (some or all data bits marked err) */
15229 + CVMX_PIP_DAT_ERR = 11ull,
15230 + /* SPI 11 = DIP4 error */
15231 + CVMX_PIP_DIP_ERR = 11ull,
15232 + /*
15233 + * RGM 12 = packet was not large enough to pass the skipper -
15234 + * no inspection could occur.
15235 + */
15236 + CVMX_PIP_SKIP_ERR = 12ull,
15237 + /*
15238 + * RGM 13 = studder error (data not repeated - 100M and 10M
15239 + * only)
15240 + */
15241 + CVMX_PIP_NIBBLE_ERR = 13ull,
15242 + /* RGM+SPI 16 = FCS error */
15243 + CVMX_PIP_PIP_FCS = 16L,
15244 + /*
15245 + * RGM+SPI+PCI 17 = packet was not large enough to pass the
15246 + * skipper - no inspection could occur.
15247 + */
15248 + CVMX_PIP_PIP_SKIP_ERR = 17L,
15249 + /*
15250 + * RGM+SPI+PCI 18 = malformed l2 (packet not long enough to
15251 + * cover L2 hdr).
15252 + */
15253 + CVMX_PIP_PIP_L2_MAL_HDR = 18L
15254 + /*
15255 + * NOTES: xx = late collision (data received before collision)
15256 + * late collisions cannot be detected by the receiver
15257 + * they would appear as JAM bits which would appear as
15258 + * bad FCS or carrier extend error which is
15259 + * CVMX_PIP_EXTEND_ERR
15260 + */
15261 +} cvmx_pip_rcv_err_t;
15262 +
15263 +/**
15264 + * This defines the err_code field errors in the work Q entry
15265 + */
15266 +typedef union {
15267 + cvmx_pip_l4_err_t l4_err;
15268 + cvmx_pip_ip_exc_t ip_exc;
15269 + cvmx_pip_rcv_err_t rcv_err;
15270 +} cvmx_pip_err_t;
15271 +
15272 +/**
15273 + * Status statistics for a port
15274 + */
15275 +typedef struct {
15276 + /* Inbound octets marked to be dropped by the IPD */
15277 + uint32_t dropped_octets;
15278 + /* Inbound packets marked to be dropped by the IPD */
15279 + uint32_t dropped_packets;
15280 + /* RAW PCI Packets received by PIP per port */
15281 + uint32_t pci_raw_packets;
15282 + /* Number of octets processed by PIP */
15283 + uint32_t octets;
15284 + /* Number of packets processed by PIP */
15285 + uint32_t packets;
15286 + /*
15287 + * Number of indentified L2 multicast packets. Does not
15288 + * include broadcast packets. Only includes packets whose
15289 + * parse mode is SKIP_TO_L2
15290 + */
15291 + uint32_t multicast_packets;
15292 + /*
15293 + * Number of indentified L2 broadcast packets. Does not
15294 + * include multicast packets. Only includes packets whose
15295 + * parse mode is SKIP_TO_L2
15296 + */
15297 + uint32_t broadcast_packets;
15298 + /* Number of 64B packets */
15299 + uint32_t len_64_packets;
15300 + /* Number of 65-127B packets */
15301 + uint32_t len_65_127_packets;
15302 + /* Number of 128-255B packets */
15303 + uint32_t len_128_255_packets;
15304 + /* Number of 256-511B packets */
15305 + uint32_t len_256_511_packets;
15306 + /* Number of 512-1023B packets */
15307 + uint32_t len_512_1023_packets;
15308 + /* Number of 1024-1518B packets */
15309 + uint32_t len_1024_1518_packets;
15310 + /* Number of 1519-max packets */
15311 + uint32_t len_1519_max_packets;
15312 + /* Number of packets with FCS or Align opcode errors */
15313 + uint32_t fcs_align_err_packets;
15314 + /* Number of packets with length < min */
15315 + uint32_t runt_packets;
15316 + /* Number of packets with length < min and FCS error */
15317 + uint32_t runt_crc_packets;
15318 + /* Number of packets with length > max */
15319 + uint32_t oversize_packets;
15320 + /* Number of packets with length > max and FCS error */
15321 + uint32_t oversize_crc_packets;
15322 + /* Number of packets without GMX/SPX/PCI errors received by PIP */
15323 + uint32_t inb_packets;
15324 + /*
15325 + * Total number of octets from all packets received by PIP,
15326 + * including CRC
15327 + */
15328 + uint64_t inb_octets;
15329 + /* Number of packets with GMX/SPX/PCI errors received by PIP */
15330 + uint16_t inb_errors;
15331 +} cvmx_pip_port_status_t;
15332 +
15333 +/**
15334 + * Definition of the PIP custom header that can be prepended
15335 + * to a packet by external hardware.
15336 + */
15337 +typedef union {
15338 + uint64_t u64;
15339 + struct {
15340 + /*
15341 + * Documented as R - Set if the Packet is RAWFULL. If
15342 + * set, this header must be the full 8 bytes.
15343 + */
15344 + uint64_t rawfull:1;
15345 + /* Must be zero */
15346 + uint64_t reserved0:5;
15347 + /* PIP parse mode for this packet */
15348 + uint64_t parse_mode:2;
15349 + /* Must be zero */
15350 + uint64_t reserved1:1;
15351 + /*
15352 + * Skip amount, including this header, to the
15353 + * beginning of the packet
15354 + */
15355 + uint64_t skip_len:7;
15356 + /* Must be zero */
15357 + uint64_t reserved2:6;
15358 + /* POW input queue for this packet */
15359 + uint64_t qos:3;
15360 + /* POW input group for this packet */
15361 + uint64_t grp:4;
15362 + /*
15363 + * Flag to store this packet in the work queue entry,
15364 + * if possible
15365 + */
15366 + uint64_t rs:1;
15367 + /* POW input tag type */
15368 + uint64_t tag_type:2;
15369 + /* POW input tag */
15370 + uint64_t tag:32;
15371 + } s;
15372 +} cvmx_pip_pkt_inst_hdr_t;
15373 +
15374 +/* CSR typedefs have been moved to cvmx-csr-*.h */
15375 +
15376 +/**
15377 + * Configure an ethernet input port
15378 + *
15379 + * @port_num: Port number to configure
15380 + * @port_cfg: Port hardware configuration
15381 + * @port_tag_cfg:
15382 + * Port POW tagging configuration
15383 + */
15384 +static inline void cvmx_pip_config_port(uint64_t port_num,
15385 + union cvmx_pip_prt_cfgx port_cfg,
15386 + union cvmx_pip_prt_tagx port_tag_cfg)
15387 +{
15388 + cvmx_write_csr(CVMX_PIP_PRT_CFGX(port_num), port_cfg.u64);
15389 + cvmx_write_csr(CVMX_PIP_PRT_TAGX(port_num), port_tag_cfg.u64);
15390 +}
15391 +#if 0
15392 +/**
15393 + * @deprecated This function is a thin wrapper around the Pass1 version
15394 + * of the CVMX_PIP_QOS_WATCHX CSR; Pass2 has added a field for
15395 + * setting the group that is incompatible with this function,
15396 + * the preferred upgrade path is to use the CSR directly.
15397 + *
15398 + * Configure the global QoS packet watchers. Each watcher is
15399 + * capable of matching a field in a packet to determine the
15400 + * QoS queue for scheduling.
15401 + *
15402 + * @watcher: Watcher number to configure (0 - 3).
15403 + * @match_type: Watcher match type
15404 + * @match_value:
15405 + * Value the watcher will match against
15406 + * @qos: QoS queue for packets matching this watcher
15407 + */
15408 +static inline void cvmx_pip_config_watcher(uint64_t watcher,
15409 + cvmx_pip_qos_watch_types match_type,
15410 + uint64_t match_value, uint64_t qos)
15411 +{
15412 + cvmx_pip_port_watcher_cfg_t watcher_config;
15413 +
15414 + watcher_config.u64 = 0;
15415 + watcher_config.s.match_type = match_type;
15416 + watcher_config.s.match_value = match_value;
15417 + watcher_config.s.qos = qos;
15418 +
15419 + cvmx_write_csr(CVMX_PIP_QOS_WATCHX(watcher), watcher_config.u64);
15420 +}
15421 +#endif
15422 +/**
15423 + * Configure the VLAN priority to QoS queue mapping.
15424 + *
15425 + * @vlan_priority:
15426 + * VLAN priority (0-7)
15427 + * @qos: QoS queue for packets matching this watcher
15428 + */
15429 +static inline void cvmx_pip_config_vlan_qos(uint64_t vlan_priority,
15430 + uint64_t qos)
15431 +{
15432 + union cvmx_pip_qos_vlanx pip_qos_vlanx;
15433 + pip_qos_vlanx.u64 = 0;
15434 + pip_qos_vlanx.s.qos = qos;
15435 + cvmx_write_csr(CVMX_PIP_QOS_VLANX(vlan_priority), pip_qos_vlanx.u64);
15436 +}
15437 +
15438 +/**
15439 + * Configure the Diffserv to QoS queue mapping.
15440 + *
15441 + * @diffserv: Diffserv field value (0-63)
15442 + * @qos: QoS queue for packets matching this watcher
15443 + */
15444 +static inline void cvmx_pip_config_diffserv_qos(uint64_t diffserv, uint64_t qos)
15445 +{
15446 + union cvmx_pip_qos_diffx pip_qos_diffx;
15447 + pip_qos_diffx.u64 = 0;
15448 + pip_qos_diffx.s.qos = qos;
15449 + cvmx_write_csr(CVMX_PIP_QOS_DIFFX(diffserv), pip_qos_diffx.u64);
15450 +}
15451 +
15452 +/**
15453 + * Get the status counters for a port.
15454 + *
15455 + * @port_num: Port number to get statistics for.
15456 + * @clear: Set to 1 to clear the counters after they are read
15457 + * @status: Where to put the results.
15458 + */
15459 +static inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear,
15460 + cvmx_pip_port_status_t *status)
15461 +{
15462 + union cvmx_pip_stat_ctl pip_stat_ctl;
15463 + union cvmx_pip_stat0_prtx stat0;
15464 + union cvmx_pip_stat1_prtx stat1;
15465 + union cvmx_pip_stat2_prtx stat2;
15466 + union cvmx_pip_stat3_prtx stat3;
15467 + union cvmx_pip_stat4_prtx stat4;
15468 + union cvmx_pip_stat5_prtx stat5;
15469 + union cvmx_pip_stat6_prtx stat6;
15470 + union cvmx_pip_stat7_prtx stat7;
15471 + union cvmx_pip_stat8_prtx stat8;
15472 + union cvmx_pip_stat9_prtx stat9;
15473 + union cvmx_pip_stat_inb_pktsx pip_stat_inb_pktsx;
15474 + union cvmx_pip_stat_inb_octsx pip_stat_inb_octsx;
15475 + union cvmx_pip_stat_inb_errsx pip_stat_inb_errsx;
15476 +
15477 + pip_stat_ctl.u64 = 0;
15478 + pip_stat_ctl.s.rdclr = clear;
15479 + cvmx_write_csr(CVMX_PIP_STAT_CTL, pip_stat_ctl.u64);
15480 +
15481 + stat0.u64 = cvmx_read_csr(CVMX_PIP_STAT0_PRTX(port_num));
15482 + stat1.u64 = cvmx_read_csr(CVMX_PIP_STAT1_PRTX(port_num));
15483 + stat2.u64 = cvmx_read_csr(CVMX_PIP_STAT2_PRTX(port_num));
15484 + stat3.u64 = cvmx_read_csr(CVMX_PIP_STAT3_PRTX(port_num));
15485 + stat4.u64 = cvmx_read_csr(CVMX_PIP_STAT4_PRTX(port_num));
15486 + stat5.u64 = cvmx_read_csr(CVMX_PIP_STAT5_PRTX(port_num));
15487 + stat6.u64 = cvmx_read_csr(CVMX_PIP_STAT6_PRTX(port_num));
15488 + stat7.u64 = cvmx_read_csr(CVMX_PIP_STAT7_PRTX(port_num));
15489 + stat8.u64 = cvmx_read_csr(CVMX_PIP_STAT8_PRTX(port_num));
15490 + stat9.u64 = cvmx_read_csr(CVMX_PIP_STAT9_PRTX(port_num));
15491 + pip_stat_inb_pktsx.u64 =
15492 + cvmx_read_csr(CVMX_PIP_STAT_INB_PKTSX(port_num));
15493 + pip_stat_inb_octsx.u64 =
15494 + cvmx_read_csr(CVMX_PIP_STAT_INB_OCTSX(port_num));
15495 + pip_stat_inb_errsx.u64 =
15496 + cvmx_read_csr(CVMX_PIP_STAT_INB_ERRSX(port_num));
15497 +
15498 + status->dropped_octets = stat0.s.drp_octs;
15499 + status->dropped_packets = stat0.s.drp_pkts;
15500 + status->octets = stat1.s.octs;
15501 + status->pci_raw_packets = stat2.s.raw;
15502 + status->packets = stat2.s.pkts;
15503 + status->multicast_packets = stat3.s.mcst;
15504 + status->broadcast_packets = stat3.s.bcst;
15505 + status->len_64_packets = stat4.s.h64;
15506 + status->len_65_127_packets = stat4.s.h65to127;
15507 + status->len_128_255_packets = stat5.s.h128to255;
15508 + status->len_256_511_packets = stat5.s.h256to511;
15509 + status->len_512_1023_packets = stat6.s.h512to1023;
15510 + status->len_1024_1518_packets = stat6.s.h1024to1518;
15511 + status->len_1519_max_packets = stat7.s.h1519;
15512 + status->fcs_align_err_packets = stat7.s.fcs;
15513 + status->runt_packets = stat8.s.undersz;
15514 + status->runt_crc_packets = stat8.s.frag;
15515 + status->oversize_packets = stat9.s.oversz;
15516 + status->oversize_crc_packets = stat9.s.jabber;
15517 + status->inb_packets = pip_stat_inb_pktsx.s.pkts;
15518 + status->inb_octets = pip_stat_inb_octsx.s.octs;
15519 + status->inb_errors = pip_stat_inb_errsx.s.errs;
15520 +
15521 + if (cvmx_octeon_is_pass1()) {
15522 + /*
15523 + * Kludge to fix Octeon Pass 1 errata - Drop counts
15524 + * don't work.
15525 + */
15526 + if (status->inb_packets > status->packets)
15527 + status->dropped_packets =
15528 + status->inb_packets - status->packets;
15529 + else
15530 + status->dropped_packets = 0;
15531 + if (status->inb_octets - status->inb_packets * 4 >
15532 + status->octets)
15533 + status->dropped_octets =
15534 + status->inb_octets - status->inb_packets * 4 -
15535 + status->octets;
15536 + else
15537 + status->dropped_octets = 0;
15538 + }
15539 +}
15540 +
15541 +/**
15542 + * Configure the hardware CRC engine
15543 + *
15544 + * @interface: Interface to configure (0 or 1)
15545 + * @invert_result:
15546 + * Invert the result of the CRC
15547 + * @reflect: Reflect
15548 + * @initialization_vector:
15549 + * CRC initialization vector
15550 + */
15551 +static inline void cvmx_pip_config_crc(uint64_t interface,
15552 + uint64_t invert_result, uint64_t reflect,
15553 + uint32_t initialization_vector)
15554 +{
15555 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
15556 + union cvmx_pip_crc_ctlx config;
15557 + union cvmx_pip_crc_ivx pip_crc_ivx;
15558 +
15559 + config.u64 = 0;
15560 + config.s.invres = invert_result;
15561 + config.s.reflect = reflect;
15562 + cvmx_write_csr(CVMX_PIP_CRC_CTLX(interface), config.u64);
15563 +
15564 + pip_crc_ivx.u64 = 0;
15565 + pip_crc_ivx.s.iv = initialization_vector;
15566 + cvmx_write_csr(CVMX_PIP_CRC_IVX(interface), pip_crc_ivx.u64);
15567 + }
15568 +}
15569 +
15570 +/**
15571 + * Clear all bits in a tag mask. This should be called on
15572 + * startup before any calls to cvmx_pip_tag_mask_set. Each bit
15573 + * set in the final mask represent a byte used in the packet for
15574 + * tag generation.
15575 + *
15576 + * @mask_index: Which tag mask to clear (0..3)
15577 + */
15578 +static inline void cvmx_pip_tag_mask_clear(uint64_t mask_index)
15579 +{
15580 + uint64_t index;
15581 + union cvmx_pip_tag_incx pip_tag_incx;
15582 + pip_tag_incx.u64 = 0;
15583 + pip_tag_incx.s.en = 0;
15584 + for (index = mask_index * 16; index < (mask_index + 1) * 16; index++)
15585 + cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
15586 +}
15587 +
15588 +/**
15589 + * Sets a range of bits in the tag mask. The tag mask is used
15590 + * when the cvmx_pip_port_tag_cfg_t tag_mode is non zero.
15591 + * There are four separate masks that can be configured.
15592 + *
15593 + * @mask_index: Which tag mask to modify (0..3)
15594 + * @offset: Offset into the bitmask to set bits at. Use the GCC macro
15595 + * offsetof() to determine the offsets into packet headers.
15596 + * For example, offsetof(ethhdr, protocol) returns the offset
15597 + * of the ethernet protocol field. The bitmask selects which
15598 + * bytes to include the the tag, with bit offset X selecting
15599 + * byte at offset X from the beginning of the packet data.
15600 + * @len: Number of bytes to include. Usually this is the sizeof()
15601 + * the field.
15602 + */
15603 +static inline void cvmx_pip_tag_mask_set(uint64_t mask_index, uint64_t offset,
15604 + uint64_t len)
15605 +{
15606 + while (len--) {
15607 + union cvmx_pip_tag_incx pip_tag_incx;
15608 + uint64_t index = mask_index * 16 + offset / 8;
15609 + pip_tag_incx.u64 = cvmx_read_csr(CVMX_PIP_TAG_INCX(index));
15610 + pip_tag_incx.s.en |= 0x80 >> (offset & 0x7);
15611 + cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
15612 + offset++;
15613 + }
15614 +}
15615 +
15616 +#endif /* __CVMX_PIP_H__ */
15617 --- /dev/null
15618 +++ b/drivers/staging/octeon/cvmx-pko-defs.h
15619 @@ -0,0 +1,1133 @@
15620 +/***********************license start***************
15621 + * Author: Cavium Networks
15622 + *
15623 + * Contact: support@caviumnetworks.com
15624 + * This file is part of the OCTEON SDK
15625 + *
15626 + * Copyright (c) 2003-2008 Cavium Networks
15627 + *
15628 + * This file is free software; you can redistribute it and/or modify
15629 + * it under the terms of the GNU General Public License, Version 2, as
15630 + * published by the Free Software Foundation.
15631 + *
15632 + * This file is distributed in the hope that it will be useful, but
15633 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15634 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
15635 + * NONINFRINGEMENT. See the GNU General Public License for more
15636 + * details.
15637 + *
15638 + * You should have received a copy of the GNU General Public License
15639 + * along with this file; if not, write to the Free Software
15640 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15641 + * or visit http://www.gnu.org/licenses/.
15642 + *
15643 + * This file may also be available under a different license from Cavium.
15644 + * Contact Cavium Networks for more information
15645 + ***********************license end**************************************/
15646 +
15647 +#ifndef __CVMX_PKO_DEFS_H__
15648 +#define __CVMX_PKO_DEFS_H__
15649 +
15650 +#define CVMX_PKO_MEM_COUNT0 \
15651 + CVMX_ADD_IO_SEG(0x0001180050001080ull)
15652 +#define CVMX_PKO_MEM_COUNT1 \
15653 + CVMX_ADD_IO_SEG(0x0001180050001088ull)
15654 +#define CVMX_PKO_MEM_DEBUG0 \
15655 + CVMX_ADD_IO_SEG(0x0001180050001100ull)
15656 +#define CVMX_PKO_MEM_DEBUG1 \
15657 + CVMX_ADD_IO_SEG(0x0001180050001108ull)
15658 +#define CVMX_PKO_MEM_DEBUG10 \
15659 + CVMX_ADD_IO_SEG(0x0001180050001150ull)
15660 +#define CVMX_PKO_MEM_DEBUG11 \
15661 + CVMX_ADD_IO_SEG(0x0001180050001158ull)
15662 +#define CVMX_PKO_MEM_DEBUG12 \
15663 + CVMX_ADD_IO_SEG(0x0001180050001160ull)
15664 +#define CVMX_PKO_MEM_DEBUG13 \
15665 + CVMX_ADD_IO_SEG(0x0001180050001168ull)
15666 +#define CVMX_PKO_MEM_DEBUG14 \
15667 + CVMX_ADD_IO_SEG(0x0001180050001170ull)
15668 +#define CVMX_PKO_MEM_DEBUG2 \
15669 + CVMX_ADD_IO_SEG(0x0001180050001110ull)
15670 +#define CVMX_PKO_MEM_DEBUG3 \
15671 + CVMX_ADD_IO_SEG(0x0001180050001118ull)
15672 +#define CVMX_PKO_MEM_DEBUG4 \
15673 + CVMX_ADD_IO_SEG(0x0001180050001120ull)
15674 +#define CVMX_PKO_MEM_DEBUG5 \
15675 + CVMX_ADD_IO_SEG(0x0001180050001128ull)
15676 +#define CVMX_PKO_MEM_DEBUG6 \
15677 + CVMX_ADD_IO_SEG(0x0001180050001130ull)
15678 +#define CVMX_PKO_MEM_DEBUG7 \
15679 + CVMX_ADD_IO_SEG(0x0001180050001138ull)
15680 +#define CVMX_PKO_MEM_DEBUG8 \
15681 + CVMX_ADD_IO_SEG(0x0001180050001140ull)
15682 +#define CVMX_PKO_MEM_DEBUG9 \
15683 + CVMX_ADD_IO_SEG(0x0001180050001148ull)
15684 +#define CVMX_PKO_MEM_PORT_PTRS \
15685 + CVMX_ADD_IO_SEG(0x0001180050001010ull)
15686 +#define CVMX_PKO_MEM_PORT_QOS \
15687 + CVMX_ADD_IO_SEG(0x0001180050001018ull)
15688 +#define CVMX_PKO_MEM_PORT_RATE0 \
15689 + CVMX_ADD_IO_SEG(0x0001180050001020ull)
15690 +#define CVMX_PKO_MEM_PORT_RATE1 \
15691 + CVMX_ADD_IO_SEG(0x0001180050001028ull)
15692 +#define CVMX_PKO_MEM_QUEUE_PTRS \
15693 + CVMX_ADD_IO_SEG(0x0001180050001000ull)
15694 +#define CVMX_PKO_MEM_QUEUE_QOS \
15695 + CVMX_ADD_IO_SEG(0x0001180050001008ull)
15696 +#define CVMX_PKO_REG_BIST_RESULT \
15697 + CVMX_ADD_IO_SEG(0x0001180050000080ull)
15698 +#define CVMX_PKO_REG_CMD_BUF \
15699 + CVMX_ADD_IO_SEG(0x0001180050000010ull)
15700 +#define CVMX_PKO_REG_CRC_CTLX(offset) \
15701 + CVMX_ADD_IO_SEG(0x0001180050000028ull + (((offset) & 1) * 8))
15702 +#define CVMX_PKO_REG_CRC_ENABLE \
15703 + CVMX_ADD_IO_SEG(0x0001180050000020ull)
15704 +#define CVMX_PKO_REG_CRC_IVX(offset) \
15705 + CVMX_ADD_IO_SEG(0x0001180050000038ull + (((offset) & 1) * 8))
15706 +#define CVMX_PKO_REG_DEBUG0 \
15707 + CVMX_ADD_IO_SEG(0x0001180050000098ull)
15708 +#define CVMX_PKO_REG_DEBUG1 \
15709 + CVMX_ADD_IO_SEG(0x00011800500000A0ull)
15710 +#define CVMX_PKO_REG_DEBUG2 \
15711 + CVMX_ADD_IO_SEG(0x00011800500000A8ull)
15712 +#define CVMX_PKO_REG_DEBUG3 \
15713 + CVMX_ADD_IO_SEG(0x00011800500000B0ull)
15714 +#define CVMX_PKO_REG_ENGINE_INFLIGHT \
15715 + CVMX_ADD_IO_SEG(0x0001180050000050ull)
15716 +#define CVMX_PKO_REG_ENGINE_THRESH \
15717 + CVMX_ADD_IO_SEG(0x0001180050000058ull)
15718 +#define CVMX_PKO_REG_ERROR \
15719 + CVMX_ADD_IO_SEG(0x0001180050000088ull)
15720 +#define CVMX_PKO_REG_FLAGS \
15721 + CVMX_ADD_IO_SEG(0x0001180050000000ull)
15722 +#define CVMX_PKO_REG_GMX_PORT_MODE \
15723 + CVMX_ADD_IO_SEG(0x0001180050000018ull)
15724 +#define CVMX_PKO_REG_INT_MASK \
15725 + CVMX_ADD_IO_SEG(0x0001180050000090ull)
15726 +#define CVMX_PKO_REG_QUEUE_MODE \
15727 + CVMX_ADD_IO_SEG(0x0001180050000048ull)
15728 +#define CVMX_PKO_REG_QUEUE_PTRS1 \
15729 + CVMX_ADD_IO_SEG(0x0001180050000100ull)
15730 +#define CVMX_PKO_REG_READ_IDX \
15731 + CVMX_ADD_IO_SEG(0x0001180050000008ull)
15732 +
15733 +union cvmx_pko_mem_count0 {
15734 + uint64_t u64;
15735 + struct cvmx_pko_mem_count0_s {
15736 + uint64_t reserved_32_63:32;
15737 + uint64_t count:32;
15738 + } s;
15739 + struct cvmx_pko_mem_count0_s cn30xx;
15740 + struct cvmx_pko_mem_count0_s cn31xx;
15741 + struct cvmx_pko_mem_count0_s cn38xx;
15742 + struct cvmx_pko_mem_count0_s cn38xxp2;
15743 + struct cvmx_pko_mem_count0_s cn50xx;
15744 + struct cvmx_pko_mem_count0_s cn52xx;
15745 + struct cvmx_pko_mem_count0_s cn52xxp1;
15746 + struct cvmx_pko_mem_count0_s cn56xx;
15747 + struct cvmx_pko_mem_count0_s cn56xxp1;
15748 + struct cvmx_pko_mem_count0_s cn58xx;
15749 + struct cvmx_pko_mem_count0_s cn58xxp1;
15750 +};
15751 +
15752 +union cvmx_pko_mem_count1 {
15753 + uint64_t u64;
15754 + struct cvmx_pko_mem_count1_s {
15755 + uint64_t reserved_48_63:16;
15756 + uint64_t count:48;
15757 + } s;
15758 + struct cvmx_pko_mem_count1_s cn30xx;
15759 + struct cvmx_pko_mem_count1_s cn31xx;
15760 + struct cvmx_pko_mem_count1_s cn38xx;
15761 + struct cvmx_pko_mem_count1_s cn38xxp2;
15762 + struct cvmx_pko_mem_count1_s cn50xx;
15763 + struct cvmx_pko_mem_count1_s cn52xx;
15764 + struct cvmx_pko_mem_count1_s cn52xxp1;
15765 + struct cvmx_pko_mem_count1_s cn56xx;
15766 + struct cvmx_pko_mem_count1_s cn56xxp1;
15767 + struct cvmx_pko_mem_count1_s cn58xx;
15768 + struct cvmx_pko_mem_count1_s cn58xxp1;
15769 +};
15770 +
15771 +union cvmx_pko_mem_debug0 {
15772 + uint64_t u64;
15773 + struct cvmx_pko_mem_debug0_s {
15774 + uint64_t fau:28;
15775 + uint64_t cmd:14;
15776 + uint64_t segs:6;
15777 + uint64_t size:16;
15778 + } s;
15779 + struct cvmx_pko_mem_debug0_s cn30xx;
15780 + struct cvmx_pko_mem_debug0_s cn31xx;
15781 + struct cvmx_pko_mem_debug0_s cn38xx;
15782 + struct cvmx_pko_mem_debug0_s cn38xxp2;
15783 + struct cvmx_pko_mem_debug0_s cn50xx;
15784 + struct cvmx_pko_mem_debug0_s cn52xx;
15785 + struct cvmx_pko_mem_debug0_s cn52xxp1;
15786 + struct cvmx_pko_mem_debug0_s cn56xx;
15787 + struct cvmx_pko_mem_debug0_s cn56xxp1;
15788 + struct cvmx_pko_mem_debug0_s cn58xx;
15789 + struct cvmx_pko_mem_debug0_s cn58xxp1;
15790 +};
15791 +
15792 +union cvmx_pko_mem_debug1 {
15793 + uint64_t u64;
15794 + struct cvmx_pko_mem_debug1_s {
15795 + uint64_t i:1;
15796 + uint64_t back:4;
15797 + uint64_t pool:3;
15798 + uint64_t size:16;
15799 + uint64_t ptr:40;
15800 + } s;
15801 + struct cvmx_pko_mem_debug1_s cn30xx;
15802 + struct cvmx_pko_mem_debug1_s cn31xx;
15803 + struct cvmx_pko_mem_debug1_s cn38xx;
15804 + struct cvmx_pko_mem_debug1_s cn38xxp2;
15805 + struct cvmx_pko_mem_debug1_s cn50xx;
15806 + struct cvmx_pko_mem_debug1_s cn52xx;
15807 + struct cvmx_pko_mem_debug1_s cn52xxp1;
15808 + struct cvmx_pko_mem_debug1_s cn56xx;
15809 + struct cvmx_pko_mem_debug1_s cn56xxp1;
15810 + struct cvmx_pko_mem_debug1_s cn58xx;
15811 + struct cvmx_pko_mem_debug1_s cn58xxp1;
15812 +};
15813 +
15814 +union cvmx_pko_mem_debug10 {
15815 + uint64_t u64;
15816 + struct cvmx_pko_mem_debug10_s {
15817 + uint64_t reserved_0_63:64;
15818 + } s;
15819 + struct cvmx_pko_mem_debug10_cn30xx {
15820 + uint64_t fau:28;
15821 + uint64_t cmd:14;
15822 + uint64_t segs:6;
15823 + uint64_t size:16;
15824 + } cn30xx;
15825 + struct cvmx_pko_mem_debug10_cn30xx cn31xx;
15826 + struct cvmx_pko_mem_debug10_cn30xx cn38xx;
15827 + struct cvmx_pko_mem_debug10_cn30xx cn38xxp2;
15828 + struct cvmx_pko_mem_debug10_cn50xx {
15829 + uint64_t reserved_49_63:15;
15830 + uint64_t ptrs1:17;
15831 + uint64_t reserved_17_31:15;
15832 + uint64_t ptrs2:17;
15833 + } cn50xx;
15834 + struct cvmx_pko_mem_debug10_cn50xx cn52xx;
15835 + struct cvmx_pko_mem_debug10_cn50xx cn52xxp1;
15836 + struct cvmx_pko_mem_debug10_cn50xx cn56xx;
15837 + struct cvmx_pko_mem_debug10_cn50xx cn56xxp1;
15838 + struct cvmx_pko_mem_debug10_cn50xx cn58xx;
15839 + struct cvmx_pko_mem_debug10_cn50xx cn58xxp1;
15840 +};
15841 +
15842 +union cvmx_pko_mem_debug11 {
15843 + uint64_t u64;
15844 + struct cvmx_pko_mem_debug11_s {
15845 + uint64_t i:1;
15846 + uint64_t back:4;
15847 + uint64_t pool:3;
15848 + uint64_t size:16;
15849 + uint64_t reserved_0_39:40;
15850 + } s;
15851 + struct cvmx_pko_mem_debug11_cn30xx {
15852 + uint64_t i:1;
15853 + uint64_t back:4;
15854 + uint64_t pool:3;
15855 + uint64_t size:16;
15856 + uint64_t ptr:40;
15857 + } cn30xx;
15858 + struct cvmx_pko_mem_debug11_cn30xx cn31xx;
15859 + struct cvmx_pko_mem_debug11_cn30xx cn38xx;
15860 + struct cvmx_pko_mem_debug11_cn30xx cn38xxp2;
15861 + struct cvmx_pko_mem_debug11_cn50xx {
15862 + uint64_t reserved_23_63:41;
15863 + uint64_t maj:1;
15864 + uint64_t uid:3;
15865 + uint64_t sop:1;
15866 + uint64_t len:1;
15867 + uint64_t chk:1;
15868 + uint64_t cnt:13;
15869 + uint64_t mod:3;
15870 + } cn50xx;
15871 + struct cvmx_pko_mem_debug11_cn50xx cn52xx;
15872 + struct cvmx_pko_mem_debug11_cn50xx cn52xxp1;
15873 + struct cvmx_pko_mem_debug11_cn50xx cn56xx;
15874 + struct cvmx_pko_mem_debug11_cn50xx cn56xxp1;
15875 + struct cvmx_pko_mem_debug11_cn50xx cn58xx;
15876 + struct cvmx_pko_mem_debug11_cn50xx cn58xxp1;
15877 +};
15878 +
15879 +union cvmx_pko_mem_debug12 {
15880 + uint64_t u64;
15881 + struct cvmx_pko_mem_debug12_s {
15882 + uint64_t reserved_0_63:64;
15883 + } s;
15884 + struct cvmx_pko_mem_debug12_cn30xx {
15885 + uint64_t data:64;
15886 + } cn30xx;
15887 + struct cvmx_pko_mem_debug12_cn30xx cn31xx;
15888 + struct cvmx_pko_mem_debug12_cn30xx cn38xx;
15889 + struct cvmx_pko_mem_debug12_cn30xx cn38xxp2;
15890 + struct cvmx_pko_mem_debug12_cn50xx {
15891 + uint64_t fau:28;
15892 + uint64_t cmd:14;
15893 + uint64_t segs:6;
15894 + uint64_t size:16;
15895 + } cn50xx;
15896 + struct cvmx_pko_mem_debug12_cn50xx cn52xx;
15897 + struct cvmx_pko_mem_debug12_cn50xx cn52xxp1;
15898 + struct cvmx_pko_mem_debug12_cn50xx cn56xx;
15899 + struct cvmx_pko_mem_debug12_cn50xx cn56xxp1;
15900 + struct cvmx_pko_mem_debug12_cn50xx cn58xx;
15901 + struct cvmx_pko_mem_debug12_cn50xx cn58xxp1;
15902 +};
15903 +
15904 +union cvmx_pko_mem_debug13 {
15905 + uint64_t u64;
15906 + struct cvmx_pko_mem_debug13_s {
15907 + uint64_t i:1;
15908 + uint64_t back:4;
15909 + uint64_t pool:3;
15910 + uint64_t reserved_0_55:56;
15911 + } s;
15912 + struct cvmx_pko_mem_debug13_cn30xx {
15913 + uint64_t reserved_51_63:13;
15914 + uint64_t widx:17;
15915 + uint64_t ridx2:17;
15916 + uint64_t widx2:17;
15917 + } cn30xx;
15918 + struct cvmx_pko_mem_debug13_cn30xx cn31xx;
15919 + struct cvmx_pko_mem_debug13_cn30xx cn38xx;
15920 + struct cvmx_pko_mem_debug13_cn30xx cn38xxp2;
15921 + struct cvmx_pko_mem_debug13_cn50xx {
15922 + uint64_t i:1;
15923 + uint64_t back:4;
15924 + uint64_t pool:3;
15925 + uint64_t size:16;
15926 + uint64_t ptr:40;
15927 + } cn50xx;
15928 + struct cvmx_pko_mem_debug13_cn50xx cn52xx;
15929 + struct cvmx_pko_mem_debug13_cn50xx cn52xxp1;
15930 + struct cvmx_pko_mem_debug13_cn50xx cn56xx;
15931 + struct cvmx_pko_mem_debug13_cn50xx cn56xxp1;
15932 + struct cvmx_pko_mem_debug13_cn50xx cn58xx;
15933 + struct cvmx_pko_mem_debug13_cn50xx cn58xxp1;
15934 +};
15935 +
15936 +union cvmx_pko_mem_debug14 {
15937 + uint64_t u64;
15938 + struct cvmx_pko_mem_debug14_s {
15939 + uint64_t reserved_0_63:64;
15940 + } s;
15941 + struct cvmx_pko_mem_debug14_cn30xx {
15942 + uint64_t reserved_17_63:47;
15943 + uint64_t ridx:17;
15944 + } cn30xx;
15945 + struct cvmx_pko_mem_debug14_cn30xx cn31xx;
15946 + struct cvmx_pko_mem_debug14_cn30xx cn38xx;
15947 + struct cvmx_pko_mem_debug14_cn30xx cn38xxp2;
15948 + struct cvmx_pko_mem_debug14_cn52xx {
15949 + uint64_t data:64;
15950 + } cn52xx;
15951 + struct cvmx_pko_mem_debug14_cn52xx cn52xxp1;
15952 + struct cvmx_pko_mem_debug14_cn52xx cn56xx;
15953 + struct cvmx_pko_mem_debug14_cn52xx cn56xxp1;
15954 +};
15955 +
15956 +union cvmx_pko_mem_debug2 {
15957 + uint64_t u64;
15958 + struct cvmx_pko_mem_debug2_s {
15959 + uint64_t i:1;
15960 + uint64_t back:4;
15961 + uint64_t pool:3;
15962 + uint64_t size:16;
15963 + uint64_t ptr:40;
15964 + } s;
15965 + struct cvmx_pko_mem_debug2_s cn30xx;
15966 + struct cvmx_pko_mem_debug2_s cn31xx;
15967 + struct cvmx_pko_mem_debug2_s cn38xx;
15968 + struct cvmx_pko_mem_debug2_s cn38xxp2;
15969 + struct cvmx_pko_mem_debug2_s cn50xx;
15970 + struct cvmx_pko_mem_debug2_s cn52xx;
15971 + struct cvmx_pko_mem_debug2_s cn52xxp1;
15972 + struct cvmx_pko_mem_debug2_s cn56xx;
15973 + struct cvmx_pko_mem_debug2_s cn56xxp1;
15974 + struct cvmx_pko_mem_debug2_s cn58xx;
15975 + struct cvmx_pko_mem_debug2_s cn58xxp1;
15976 +};
15977 +
15978 +union cvmx_pko_mem_debug3 {
15979 + uint64_t u64;
15980 + struct cvmx_pko_mem_debug3_s {
15981 + uint64_t reserved_0_63:64;
15982 + } s;
15983 + struct cvmx_pko_mem_debug3_cn30xx {
15984 + uint64_t i:1;
15985 + uint64_t back:4;
15986 + uint64_t pool:3;
15987 + uint64_t size:16;
15988 + uint64_t ptr:40;
15989 + } cn30xx;
15990 + struct cvmx_pko_mem_debug3_cn30xx cn31xx;
15991 + struct cvmx_pko_mem_debug3_cn30xx cn38xx;
15992 + struct cvmx_pko_mem_debug3_cn30xx cn38xxp2;
15993 + struct cvmx_pko_mem_debug3_cn50xx {
15994 + uint64_t data:64;
15995 + } cn50xx;
15996 + struct cvmx_pko_mem_debug3_cn50xx cn52xx;
15997 + struct cvmx_pko_mem_debug3_cn50xx cn52xxp1;
15998 + struct cvmx_pko_mem_debug3_cn50xx cn56xx;
15999 + struct cvmx_pko_mem_debug3_cn50xx cn56xxp1;
16000 + struct cvmx_pko_mem_debug3_cn50xx cn58xx;
16001 + struct cvmx_pko_mem_debug3_cn50xx cn58xxp1;
16002 +};
16003 +
16004 +union cvmx_pko_mem_debug4 {
16005 + uint64_t u64;
16006 + struct cvmx_pko_mem_debug4_s {
16007 + uint64_t reserved_0_63:64;
16008 + } s;
16009 + struct cvmx_pko_mem_debug4_cn30xx {
16010 + uint64_t data:64;
16011 + } cn30xx;
16012 + struct cvmx_pko_mem_debug4_cn30xx cn31xx;
16013 + struct cvmx_pko_mem_debug4_cn30xx cn38xx;
16014 + struct cvmx_pko_mem_debug4_cn30xx cn38xxp2;
16015 + struct cvmx_pko_mem_debug4_cn50xx {
16016 + uint64_t cmnd_segs:3;
16017 + uint64_t cmnd_siz:16;
16018 + uint64_t cmnd_off:6;
16019 + uint64_t uid:3;
16020 + uint64_t dread_sop:1;
16021 + uint64_t init_dwrite:1;
16022 + uint64_t chk_once:1;
16023 + uint64_t chk_mode:1;
16024 + uint64_t active:1;
16025 + uint64_t static_p:1;
16026 + uint64_t qos:3;
16027 + uint64_t qcb_ridx:5;
16028 + uint64_t qid_off_max:4;
16029 + uint64_t qid_off:4;
16030 + uint64_t qid_base:8;
16031 + uint64_t wait:1;
16032 + uint64_t minor:2;
16033 + uint64_t major:3;
16034 + } cn50xx;
16035 + struct cvmx_pko_mem_debug4_cn52xx {
16036 + uint64_t curr_siz:8;
16037 + uint64_t curr_off:16;
16038 + uint64_t cmnd_segs:6;
16039 + uint64_t cmnd_siz:16;
16040 + uint64_t cmnd_off:6;
16041 + uint64_t uid:2;
16042 + uint64_t dread_sop:1;
16043 + uint64_t init_dwrite:1;
16044 + uint64_t chk_once:1;
16045 + uint64_t chk_mode:1;
16046 + uint64_t wait:1;
16047 + uint64_t minor:2;
16048 + uint64_t major:3;
16049 + } cn52xx;
16050 + struct cvmx_pko_mem_debug4_cn52xx cn52xxp1;
16051 + struct cvmx_pko_mem_debug4_cn52xx cn56xx;
16052 + struct cvmx_pko_mem_debug4_cn52xx cn56xxp1;
16053 + struct cvmx_pko_mem_debug4_cn50xx cn58xx;
16054 + struct cvmx_pko_mem_debug4_cn50xx cn58xxp1;
16055 +};
16056 +
16057 +union cvmx_pko_mem_debug5 {
16058 + uint64_t u64;
16059 + struct cvmx_pko_mem_debug5_s {
16060 + uint64_t reserved_0_63:64;
16061 + } s;
16062 + struct cvmx_pko_mem_debug5_cn30xx {
16063 + uint64_t dwri_mod:1;
16064 + uint64_t dwri_sop:1;
16065 + uint64_t dwri_len:1;
16066 + uint64_t dwri_cnt:13;
16067 + uint64_t cmnd_siz:16;
16068 + uint64_t uid:1;
16069 + uint64_t xfer_wor:1;
16070 + uint64_t xfer_dwr:1;
16071 + uint64_t cbuf_fre:1;
16072 + uint64_t reserved_27_27:1;
16073 + uint64_t chk_mode:1;
16074 + uint64_t active:1;
16075 + uint64_t qos:3;
16076 + uint64_t qcb_ridx:5;
16077 + uint64_t qid_off:3;
16078 + uint64_t qid_base:7;
16079 + uint64_t wait:1;
16080 + uint64_t minor:2;
16081 + uint64_t major:4;
16082 + } cn30xx;
16083 + struct cvmx_pko_mem_debug5_cn30xx cn31xx;
16084 + struct cvmx_pko_mem_debug5_cn30xx cn38xx;
16085 + struct cvmx_pko_mem_debug5_cn30xx cn38xxp2;
16086 + struct cvmx_pko_mem_debug5_cn50xx {
16087 + uint64_t curr_ptr:29;
16088 + uint64_t curr_siz:16;
16089 + uint64_t curr_off:16;
16090 + uint64_t cmnd_segs:3;
16091 + } cn50xx;
16092 + struct cvmx_pko_mem_debug5_cn52xx {
16093 + uint64_t reserved_54_63:10;
16094 + uint64_t nxt_inflt:6;
16095 + uint64_t curr_ptr:40;
16096 + uint64_t curr_siz:8;
16097 + } cn52xx;
16098 + struct cvmx_pko_mem_debug5_cn52xx cn52xxp1;
16099 + struct cvmx_pko_mem_debug5_cn52xx cn56xx;
16100 + struct cvmx_pko_mem_debug5_cn52xx cn56xxp1;
16101 + struct cvmx_pko_mem_debug5_cn50xx cn58xx;
16102 + struct cvmx_pko_mem_debug5_cn50xx cn58xxp1;
16103 +};
16104 +
16105 +union cvmx_pko_mem_debug6 {
16106 + uint64_t u64;
16107 + struct cvmx_pko_mem_debug6_s {
16108 + uint64_t reserved_37_63:27;
16109 + uint64_t qid_offres:4;
16110 + uint64_t qid_offths:4;
16111 + uint64_t preempter:1;
16112 + uint64_t preemptee:1;
16113 + uint64_t preempted:1;
16114 + uint64_t active:1;
16115 + uint64_t statc:1;
16116 + uint64_t qos:3;
16117 + uint64_t qcb_ridx:5;
16118 + uint64_t qid_offmax:4;
16119 + uint64_t reserved_0_11:12;
16120 + } s;
16121 + struct cvmx_pko_mem_debug6_cn30xx {
16122 + uint64_t reserved_11_63:53;
16123 + uint64_t qid_offm:3;
16124 + uint64_t static_p:1;
16125 + uint64_t work_min:3;
16126 + uint64_t dwri_chk:1;
16127 + uint64_t dwri_uid:1;
16128 + uint64_t dwri_mod:2;
16129 + } cn30xx;
16130 + struct cvmx_pko_mem_debug6_cn30xx cn31xx;
16131 + struct cvmx_pko_mem_debug6_cn30xx cn38xx;
16132 + struct cvmx_pko_mem_debug6_cn30xx cn38xxp2;
16133 + struct cvmx_pko_mem_debug6_cn50xx {
16134 + uint64_t reserved_11_63:53;
16135 + uint64_t curr_ptr:11;
16136 + } cn50xx;
16137 + struct cvmx_pko_mem_debug6_cn52xx {
16138 + uint64_t reserved_37_63:27;
16139 + uint64_t qid_offres:4;
16140 + uint64_t qid_offths:4;
16141 + uint64_t preempter:1;
16142 + uint64_t preemptee:1;
16143 + uint64_t preempted:1;
16144 + uint64_t active:1;
16145 + uint64_t statc:1;
16146 + uint64_t qos:3;
16147 + uint64_t qcb_ridx:5;
16148 + uint64_t qid_offmax:4;
16149 + uint64_t qid_off:4;
16150 + uint64_t qid_base:8;
16151 + } cn52xx;
16152 + struct cvmx_pko_mem_debug6_cn52xx cn52xxp1;
16153 + struct cvmx_pko_mem_debug6_cn52xx cn56xx;
16154 + struct cvmx_pko_mem_debug6_cn52xx cn56xxp1;
16155 + struct cvmx_pko_mem_debug6_cn50xx cn58xx;
16156 + struct cvmx_pko_mem_debug6_cn50xx cn58xxp1;
16157 +};
16158 +
16159 +union cvmx_pko_mem_debug7 {
16160 + uint64_t u64;
16161 + struct cvmx_pko_mem_debug7_s {
16162 + uint64_t qos:5;
16163 + uint64_t tail:1;
16164 + uint64_t reserved_0_57:58;
16165 + } s;
16166 + struct cvmx_pko_mem_debug7_cn30xx {
16167 + uint64_t reserved_58_63:6;
16168 + uint64_t dwb:9;
16169 + uint64_t start:33;
16170 + uint64_t size:16;
16171 + } cn30xx;
16172 + struct cvmx_pko_mem_debug7_cn30xx cn31xx;
16173 + struct cvmx_pko_mem_debug7_cn30xx cn38xx;
16174 + struct cvmx_pko_mem_debug7_cn30xx cn38xxp2;
16175 + struct cvmx_pko_mem_debug7_cn50xx {
16176 + uint64_t qos:5;
16177 + uint64_t tail:1;
16178 + uint64_t buf_siz:13;
16179 + uint64_t buf_ptr:33;
16180 + uint64_t qcb_widx:6;
16181 + uint64_t qcb_ridx:6;
16182 + } cn50xx;
16183 + struct cvmx_pko_mem_debug7_cn50xx cn52xx;
16184 + struct cvmx_pko_mem_debug7_cn50xx cn52xxp1;
16185 + struct cvmx_pko_mem_debug7_cn50xx cn56xx;
16186 + struct cvmx_pko_mem_debug7_cn50xx cn56xxp1;
16187 + struct cvmx_pko_mem_debug7_cn50xx cn58xx;
16188 + struct cvmx_pko_mem_debug7_cn50xx cn58xxp1;
16189 +};
16190 +
16191 +union cvmx_pko_mem_debug8 {
16192 + uint64_t u64;
16193 + struct cvmx_pko_mem_debug8_s {
16194 + uint64_t reserved_59_63:5;
16195 + uint64_t tail:1;
16196 + uint64_t buf_siz:13;
16197 + uint64_t reserved_0_44:45;
16198 + } s;
16199 + struct cvmx_pko_mem_debug8_cn30xx {
16200 + uint64_t qos:5;
16201 + uint64_t tail:1;
16202 + uint64_t buf_siz:13;
16203 + uint64_t buf_ptr:33;
16204 + uint64_t qcb_widx:6;
16205 + uint64_t qcb_ridx:6;
16206 + } cn30xx;
16207 + struct cvmx_pko_mem_debug8_cn30xx cn31xx;
16208 + struct cvmx_pko_mem_debug8_cn30xx cn38xx;
16209 + struct cvmx_pko_mem_debug8_cn30xx cn38xxp2;
16210 + struct cvmx_pko_mem_debug8_cn50xx {
16211 + uint64_t reserved_28_63:36;
16212 + uint64_t doorbell:20;
16213 + uint64_t reserved_6_7:2;
16214 + uint64_t static_p:1;
16215 + uint64_t s_tail:1;
16216 + uint64_t static_q:1;
16217 + uint64_t qos:3;
16218 + } cn50xx;
16219 + struct cvmx_pko_mem_debug8_cn52xx {
16220 + uint64_t reserved_29_63:35;
16221 + uint64_t preempter:1;
16222 + uint64_t doorbell:20;
16223 + uint64_t reserved_7_7:1;
16224 + uint64_t preemptee:1;
16225 + uint64_t static_p:1;
16226 + uint64_t s_tail:1;
16227 + uint64_t static_q:1;
16228 + uint64_t qos:3;
16229 + } cn52xx;
16230 + struct cvmx_pko_mem_debug8_cn52xx cn52xxp1;
16231 + struct cvmx_pko_mem_debug8_cn52xx cn56xx;
16232 + struct cvmx_pko_mem_debug8_cn52xx cn56xxp1;
16233 + struct cvmx_pko_mem_debug8_cn50xx cn58xx;
16234 + struct cvmx_pko_mem_debug8_cn50xx cn58xxp1;
16235 +};
16236 +
16237 +union cvmx_pko_mem_debug9 {
16238 + uint64_t u64;
16239 + struct cvmx_pko_mem_debug9_s {
16240 + uint64_t reserved_49_63:15;
16241 + uint64_t ptrs0:17;
16242 + uint64_t reserved_0_31:32;
16243 + } s;
16244 + struct cvmx_pko_mem_debug9_cn30xx {
16245 + uint64_t reserved_28_63:36;
16246 + uint64_t doorbell:20;
16247 + uint64_t reserved_5_7:3;
16248 + uint64_t s_tail:1;
16249 + uint64_t static_q:1;
16250 + uint64_t qos:3;
16251 + } cn30xx;
16252 + struct cvmx_pko_mem_debug9_cn30xx cn31xx;
16253 + struct cvmx_pko_mem_debug9_cn38xx {
16254 + uint64_t reserved_28_63:36;
16255 + uint64_t doorbell:20;
16256 + uint64_t reserved_6_7:2;
16257 + uint64_t static_p:1;
16258 + uint64_t s_tail:1;
16259 + uint64_t static_q:1;
16260 + uint64_t qos:3;
16261 + } cn38xx;
16262 + struct cvmx_pko_mem_debug9_cn38xx cn38xxp2;
16263 + struct cvmx_pko_mem_debug9_cn50xx {
16264 + uint64_t reserved_49_63:15;
16265 + uint64_t ptrs0:17;
16266 + uint64_t reserved_17_31:15;
16267 + uint64_t ptrs3:17;
16268 + } cn50xx;
16269 + struct cvmx_pko_mem_debug9_cn50xx cn52xx;
16270 + struct cvmx_pko_mem_debug9_cn50xx cn52xxp1;
16271 + struct cvmx_pko_mem_debug9_cn50xx cn56xx;
16272 + struct cvmx_pko_mem_debug9_cn50xx cn56xxp1;
16273 + struct cvmx_pko_mem_debug9_cn50xx cn58xx;
16274 + struct cvmx_pko_mem_debug9_cn50xx cn58xxp1;
16275 +};
16276 +
16277 +union cvmx_pko_mem_port_ptrs {
16278 + uint64_t u64;
16279 + struct cvmx_pko_mem_port_ptrs_s {
16280 + uint64_t reserved_62_63:2;
16281 + uint64_t static_p:1;
16282 + uint64_t qos_mask:8;
16283 + uint64_t reserved_16_52:37;
16284 + uint64_t bp_port:6;
16285 + uint64_t eid:4;
16286 + uint64_t pid:6;
16287 + } s;
16288 + struct cvmx_pko_mem_port_ptrs_s cn52xx;
16289 + struct cvmx_pko_mem_port_ptrs_s cn52xxp1;
16290 + struct cvmx_pko_mem_port_ptrs_s cn56xx;
16291 + struct cvmx_pko_mem_port_ptrs_s cn56xxp1;
16292 +};
16293 +
16294 +union cvmx_pko_mem_port_qos {
16295 + uint64_t u64;
16296 + struct cvmx_pko_mem_port_qos_s {
16297 + uint64_t reserved_61_63:3;
16298 + uint64_t qos_mask:8;
16299 + uint64_t reserved_10_52:43;
16300 + uint64_t eid:4;
16301 + uint64_t pid:6;
16302 + } s;
16303 + struct cvmx_pko_mem_port_qos_s cn52xx;
16304 + struct cvmx_pko_mem_port_qos_s cn52xxp1;
16305 + struct cvmx_pko_mem_port_qos_s cn56xx;
16306 + struct cvmx_pko_mem_port_qos_s cn56xxp1;
16307 +};
16308 +
16309 +union cvmx_pko_mem_port_rate0 {
16310 + uint64_t u64;
16311 + struct cvmx_pko_mem_port_rate0_s {
16312 + uint64_t reserved_51_63:13;
16313 + uint64_t rate_word:19;
16314 + uint64_t rate_pkt:24;
16315 + uint64_t reserved_6_7:2;
16316 + uint64_t pid:6;
16317 + } s;
16318 + struct cvmx_pko_mem_port_rate0_s cn52xx;
16319 + struct cvmx_pko_mem_port_rate0_s cn52xxp1;
16320 + struct cvmx_pko_mem_port_rate0_s cn56xx;
16321 + struct cvmx_pko_mem_port_rate0_s cn56xxp1;
16322 +};
16323 +
16324 +union cvmx_pko_mem_port_rate1 {
16325 + uint64_t u64;
16326 + struct cvmx_pko_mem_port_rate1_s {
16327 + uint64_t reserved_32_63:32;
16328 + uint64_t rate_lim:24;
16329 + uint64_t reserved_6_7:2;
16330 + uint64_t pid:6;
16331 + } s;
16332 + struct cvmx_pko_mem_port_rate1_s cn52xx;
16333 + struct cvmx_pko_mem_port_rate1_s cn52xxp1;
16334 + struct cvmx_pko_mem_port_rate1_s cn56xx;
16335 + struct cvmx_pko_mem_port_rate1_s cn56xxp1;
16336 +};
16337 +
16338 +union cvmx_pko_mem_queue_ptrs {
16339 + uint64_t u64;
16340 + struct cvmx_pko_mem_queue_ptrs_s {
16341 + uint64_t s_tail:1;
16342 + uint64_t static_p:1;
16343 + uint64_t static_q:1;
16344 + uint64_t qos_mask:8;
16345 + uint64_t buf_ptr:36;
16346 + uint64_t tail:1;
16347 + uint64_t index:3;
16348 + uint64_t port:6;
16349 + uint64_t queue:7;
16350 + } s;
16351 + struct cvmx_pko_mem_queue_ptrs_s cn30xx;
16352 + struct cvmx_pko_mem_queue_ptrs_s cn31xx;
16353 + struct cvmx_pko_mem_queue_ptrs_s cn38xx;
16354 + struct cvmx_pko_mem_queue_ptrs_s cn38xxp2;
16355 + struct cvmx_pko_mem_queue_ptrs_s cn50xx;
16356 + struct cvmx_pko_mem_queue_ptrs_s cn52xx;
16357 + struct cvmx_pko_mem_queue_ptrs_s cn52xxp1;
16358 + struct cvmx_pko_mem_queue_ptrs_s cn56xx;
16359 + struct cvmx_pko_mem_queue_ptrs_s cn56xxp1;
16360 + struct cvmx_pko_mem_queue_ptrs_s cn58xx;
16361 + struct cvmx_pko_mem_queue_ptrs_s cn58xxp1;
16362 +};
16363 +
16364 +union cvmx_pko_mem_queue_qos {
16365 + uint64_t u64;
16366 + struct cvmx_pko_mem_queue_qos_s {
16367 + uint64_t reserved_61_63:3;
16368 + uint64_t qos_mask:8;
16369 + uint64_t reserved_13_52:40;
16370 + uint64_t pid:6;
16371 + uint64_t qid:7;
16372 + } s;
16373 + struct cvmx_pko_mem_queue_qos_s cn30xx;
16374 + struct cvmx_pko_mem_queue_qos_s cn31xx;
16375 + struct cvmx_pko_mem_queue_qos_s cn38xx;
16376 + struct cvmx_pko_mem_queue_qos_s cn38xxp2;
16377 + struct cvmx_pko_mem_queue_qos_s cn50xx;
16378 + struct cvmx_pko_mem_queue_qos_s cn52xx;
16379 + struct cvmx_pko_mem_queue_qos_s cn52xxp1;
16380 + struct cvmx_pko_mem_queue_qos_s cn56xx;
16381 + struct cvmx_pko_mem_queue_qos_s cn56xxp1;
16382 + struct cvmx_pko_mem_queue_qos_s cn58xx;
16383 + struct cvmx_pko_mem_queue_qos_s cn58xxp1;
16384 +};
16385 +
16386 +union cvmx_pko_reg_bist_result {
16387 + uint64_t u64;
16388 + struct cvmx_pko_reg_bist_result_s {
16389 + uint64_t reserved_0_63:64;
16390 + } s;
16391 + struct cvmx_pko_reg_bist_result_cn30xx {
16392 + uint64_t reserved_27_63:37;
16393 + uint64_t psb2:5;
16394 + uint64_t count:1;
16395 + uint64_t rif:1;
16396 + uint64_t wif:1;
16397 + uint64_t ncb:1;
16398 + uint64_t out:1;
16399 + uint64_t crc:1;
16400 + uint64_t chk:1;
16401 + uint64_t qsb:2;
16402 + uint64_t qcb:2;
16403 + uint64_t pdb:4;
16404 + uint64_t psb:7;
16405 + } cn30xx;
16406 + struct cvmx_pko_reg_bist_result_cn30xx cn31xx;
16407 + struct cvmx_pko_reg_bist_result_cn30xx cn38xx;
16408 + struct cvmx_pko_reg_bist_result_cn30xx cn38xxp2;
16409 + struct cvmx_pko_reg_bist_result_cn50xx {
16410 + uint64_t reserved_33_63:31;
16411 + uint64_t csr:1;
16412 + uint64_t iob:1;
16413 + uint64_t out_crc:1;
16414 + uint64_t out_ctl:3;
16415 + uint64_t out_sta:1;
16416 + uint64_t out_wif:1;
16417 + uint64_t prt_chk:3;
16418 + uint64_t prt_nxt:1;
16419 + uint64_t prt_psb:6;
16420 + uint64_t ncb_inb:2;
16421 + uint64_t prt_qcb:2;
16422 + uint64_t prt_qsb:3;
16423 + uint64_t dat_dat:4;
16424 + uint64_t dat_ptr:4;
16425 + } cn50xx;
16426 + struct cvmx_pko_reg_bist_result_cn52xx {
16427 + uint64_t reserved_35_63:29;
16428 + uint64_t csr:1;
16429 + uint64_t iob:1;
16430 + uint64_t out_dat:1;
16431 + uint64_t out_ctl:3;
16432 + uint64_t out_sta:1;
16433 + uint64_t out_wif:1;
16434 + uint64_t prt_chk:3;
16435 + uint64_t prt_nxt:1;
16436 + uint64_t prt_psb:8;
16437 + uint64_t ncb_inb:2;
16438 + uint64_t prt_qcb:2;
16439 + uint64_t prt_qsb:3;
16440 + uint64_t prt_ctl:2;
16441 + uint64_t dat_dat:2;
16442 + uint64_t dat_ptr:4;
16443 + } cn52xx;
16444 + struct cvmx_pko_reg_bist_result_cn52xx cn52xxp1;
16445 + struct cvmx_pko_reg_bist_result_cn52xx cn56xx;
16446 + struct cvmx_pko_reg_bist_result_cn52xx cn56xxp1;
16447 + struct cvmx_pko_reg_bist_result_cn50xx cn58xx;
16448 + struct cvmx_pko_reg_bist_result_cn50xx cn58xxp1;
16449 +};
16450 +
16451 +union cvmx_pko_reg_cmd_buf {
16452 + uint64_t u64;
16453 + struct cvmx_pko_reg_cmd_buf_s {
16454 + uint64_t reserved_23_63:41;
16455 + uint64_t pool:3;
16456 + uint64_t reserved_13_19:7;
16457 + uint64_t size:13;
16458 + } s;
16459 + struct cvmx_pko_reg_cmd_buf_s cn30xx;
16460 + struct cvmx_pko_reg_cmd_buf_s cn31xx;
16461 + struct cvmx_pko_reg_cmd_buf_s cn38xx;
16462 + struct cvmx_pko_reg_cmd_buf_s cn38xxp2;
16463 + struct cvmx_pko_reg_cmd_buf_s cn50xx;
16464 + struct cvmx_pko_reg_cmd_buf_s cn52xx;
16465 + struct cvmx_pko_reg_cmd_buf_s cn52xxp1;
16466 + struct cvmx_pko_reg_cmd_buf_s cn56xx;
16467 + struct cvmx_pko_reg_cmd_buf_s cn56xxp1;
16468 + struct cvmx_pko_reg_cmd_buf_s cn58xx;
16469 + struct cvmx_pko_reg_cmd_buf_s cn58xxp1;
16470 +};
16471 +
16472 +union cvmx_pko_reg_crc_ctlx {
16473 + uint64_t u64;
16474 + struct cvmx_pko_reg_crc_ctlx_s {
16475 + uint64_t reserved_2_63:62;
16476 + uint64_t invres:1;
16477 + uint64_t refin:1;
16478 + } s;
16479 + struct cvmx_pko_reg_crc_ctlx_s cn38xx;
16480 + struct cvmx_pko_reg_crc_ctlx_s cn38xxp2;
16481 + struct cvmx_pko_reg_crc_ctlx_s cn58xx;
16482 + struct cvmx_pko_reg_crc_ctlx_s cn58xxp1;
16483 +};
16484 +
16485 +union cvmx_pko_reg_crc_enable {
16486 + uint64_t u64;
16487 + struct cvmx_pko_reg_crc_enable_s {
16488 + uint64_t reserved_32_63:32;
16489 + uint64_t enable:32;
16490 + } s;
16491 + struct cvmx_pko_reg_crc_enable_s cn38xx;
16492 + struct cvmx_pko_reg_crc_enable_s cn38xxp2;
16493 + struct cvmx_pko_reg_crc_enable_s cn58xx;
16494 + struct cvmx_pko_reg_crc_enable_s cn58xxp1;
16495 +};
16496 +
16497 +union cvmx_pko_reg_crc_ivx {
16498 + uint64_t u64;
16499 + struct cvmx_pko_reg_crc_ivx_s {
16500 + uint64_t reserved_32_63:32;
16501 + uint64_t iv:32;
16502 + } s;
16503 + struct cvmx_pko_reg_crc_ivx_s cn38xx;
16504 + struct cvmx_pko_reg_crc_ivx_s cn38xxp2;
16505 + struct cvmx_pko_reg_crc_ivx_s cn58xx;
16506 + struct cvmx_pko_reg_crc_ivx_s cn58xxp1;
16507 +};
16508 +
16509 +union cvmx_pko_reg_debug0 {
16510 + uint64_t u64;
16511 + struct cvmx_pko_reg_debug0_s {
16512 + uint64_t asserts:64;
16513 + } s;
16514 + struct cvmx_pko_reg_debug0_cn30xx {
16515 + uint64_t reserved_17_63:47;
16516 + uint64_t asserts:17;
16517 + } cn30xx;
16518 + struct cvmx_pko_reg_debug0_cn30xx cn31xx;
16519 + struct cvmx_pko_reg_debug0_cn30xx cn38xx;
16520 + struct cvmx_pko_reg_debug0_cn30xx cn38xxp2;
16521 + struct cvmx_pko_reg_debug0_s cn50xx;
16522 + struct cvmx_pko_reg_debug0_s cn52xx;
16523 + struct cvmx_pko_reg_debug0_s cn52xxp1;
16524 + struct cvmx_pko_reg_debug0_s cn56xx;
16525 + struct cvmx_pko_reg_debug0_s cn56xxp1;
16526 + struct cvmx_pko_reg_debug0_s cn58xx;
16527 + struct cvmx_pko_reg_debug0_s cn58xxp1;
16528 +};
16529 +
16530 +union cvmx_pko_reg_debug1 {
16531 + uint64_t u64;
16532 + struct cvmx_pko_reg_debug1_s {
16533 + uint64_t asserts:64;
16534 + } s;
16535 + struct cvmx_pko_reg_debug1_s cn50xx;
16536 + struct cvmx_pko_reg_debug1_s cn52xx;
16537 + struct cvmx_pko_reg_debug1_s cn52xxp1;
16538 + struct cvmx_pko_reg_debug1_s cn56xx;
16539 + struct cvmx_pko_reg_debug1_s cn56xxp1;
16540 + struct cvmx_pko_reg_debug1_s cn58xx;
16541 + struct cvmx_pko_reg_debug1_s cn58xxp1;
16542 +};
16543 +
16544 +union cvmx_pko_reg_debug2 {
16545 + uint64_t u64;
16546 + struct cvmx_pko_reg_debug2_s {
16547 + uint64_t asserts:64;
16548 + } s;
16549 + struct cvmx_pko_reg_debug2_s cn50xx;
16550 + struct cvmx_pko_reg_debug2_s cn52xx;
16551 + struct cvmx_pko_reg_debug2_s cn52xxp1;
16552 + struct cvmx_pko_reg_debug2_s cn56xx;
16553 + struct cvmx_pko_reg_debug2_s cn56xxp1;
16554 + struct cvmx_pko_reg_debug2_s cn58xx;
16555 + struct cvmx_pko_reg_debug2_s cn58xxp1;
16556 +};
16557 +
16558 +union cvmx_pko_reg_debug3 {
16559 + uint64_t u64;
16560 + struct cvmx_pko_reg_debug3_s {
16561 + uint64_t asserts:64;
16562 + } s;
16563 + struct cvmx_pko_reg_debug3_s cn50xx;
16564 + struct cvmx_pko_reg_debug3_s cn52xx;
16565 + struct cvmx_pko_reg_debug3_s cn52xxp1;
16566 + struct cvmx_pko_reg_debug3_s cn56xx;
16567 + struct cvmx_pko_reg_debug3_s cn56xxp1;
16568 + struct cvmx_pko_reg_debug3_s cn58xx;
16569 + struct cvmx_pko_reg_debug3_s cn58xxp1;
16570 +};
16571 +
16572 +union cvmx_pko_reg_engine_inflight {
16573 + uint64_t u64;
16574 + struct cvmx_pko_reg_engine_inflight_s {
16575 + uint64_t reserved_40_63:24;
16576 + uint64_t engine9:4;
16577 + uint64_t engine8:4;
16578 + uint64_t engine7:4;
16579 + uint64_t engine6:4;
16580 + uint64_t engine5:4;
16581 + uint64_t engine4:4;
16582 + uint64_t engine3:4;
16583 + uint64_t engine2:4;
16584 + uint64_t engine1:4;
16585 + uint64_t engine0:4;
16586 + } s;
16587 + struct cvmx_pko_reg_engine_inflight_s cn52xx;
16588 + struct cvmx_pko_reg_engine_inflight_s cn52xxp1;
16589 + struct cvmx_pko_reg_engine_inflight_s cn56xx;
16590 + struct cvmx_pko_reg_engine_inflight_s cn56xxp1;
16591 +};
16592 +
16593 +union cvmx_pko_reg_engine_thresh {
16594 + uint64_t u64;
16595 + struct cvmx_pko_reg_engine_thresh_s {
16596 + uint64_t reserved_10_63:54;
16597 + uint64_t mask:10;
16598 + } s;
16599 + struct cvmx_pko_reg_engine_thresh_s cn52xx;
16600 + struct cvmx_pko_reg_engine_thresh_s cn52xxp1;
16601 + struct cvmx_pko_reg_engine_thresh_s cn56xx;
16602 + struct cvmx_pko_reg_engine_thresh_s cn56xxp1;
16603 +};
16604 +
16605 +union cvmx_pko_reg_error {
16606 + uint64_t u64;
16607 + struct cvmx_pko_reg_error_s {
16608 + uint64_t reserved_3_63:61;
16609 + uint64_t currzero:1;
16610 + uint64_t doorbell:1;
16611 + uint64_t parity:1;
16612 + } s;
16613 + struct cvmx_pko_reg_error_cn30xx {
16614 + uint64_t reserved_2_63:62;
16615 + uint64_t doorbell:1;
16616 + uint64_t parity:1;
16617 + } cn30xx;
16618 + struct cvmx_pko_reg_error_cn30xx cn31xx;
16619 + struct cvmx_pko_reg_error_cn30xx cn38xx;
16620 + struct cvmx_pko_reg_error_cn30xx cn38xxp2;
16621 + struct cvmx_pko_reg_error_s cn50xx;
16622 + struct cvmx_pko_reg_error_s cn52xx;
16623 + struct cvmx_pko_reg_error_s cn52xxp1;
16624 + struct cvmx_pko_reg_error_s cn56xx;
16625 + struct cvmx_pko_reg_error_s cn56xxp1;
16626 + struct cvmx_pko_reg_error_s cn58xx;
16627 + struct cvmx_pko_reg_error_s cn58xxp1;
16628 +};
16629 +
16630 +union cvmx_pko_reg_flags {
16631 + uint64_t u64;
16632 + struct cvmx_pko_reg_flags_s {
16633 + uint64_t reserved_4_63:60;
16634 + uint64_t reset:1;
16635 + uint64_t store_be:1;
16636 + uint64_t ena_dwb:1;
16637 + uint64_t ena_pko:1;
16638 + } s;
16639 + struct cvmx_pko_reg_flags_s cn30xx;
16640 + struct cvmx_pko_reg_flags_s cn31xx;
16641 + struct cvmx_pko_reg_flags_s cn38xx;
16642 + struct cvmx_pko_reg_flags_s cn38xxp2;
16643 + struct cvmx_pko_reg_flags_s cn50xx;
16644 + struct cvmx_pko_reg_flags_s cn52xx;
16645 + struct cvmx_pko_reg_flags_s cn52xxp1;
16646 + struct cvmx_pko_reg_flags_s cn56xx;
16647 + struct cvmx_pko_reg_flags_s cn56xxp1;
16648 + struct cvmx_pko_reg_flags_s cn58xx;
16649 + struct cvmx_pko_reg_flags_s cn58xxp1;
16650 +};
16651 +
16652 +union cvmx_pko_reg_gmx_port_mode {
16653 + uint64_t u64;
16654 + struct cvmx_pko_reg_gmx_port_mode_s {
16655 + uint64_t reserved_6_63:58;
16656 + uint64_t mode1:3;
16657 + uint64_t mode0:3;
16658 + } s;
16659 + struct cvmx_pko_reg_gmx_port_mode_s cn30xx;
16660 + struct cvmx_pko_reg_gmx_port_mode_s cn31xx;
16661 + struct cvmx_pko_reg_gmx_port_mode_s cn38xx;
16662 + struct cvmx_pko_reg_gmx_port_mode_s cn38xxp2;
16663 + struct cvmx_pko_reg_gmx_port_mode_s cn50xx;
16664 + struct cvmx_pko_reg_gmx_port_mode_s cn52xx;
16665 + struct cvmx_pko_reg_gmx_port_mode_s cn52xxp1;
16666 + struct cvmx_pko_reg_gmx_port_mode_s cn56xx;
16667 + struct cvmx_pko_reg_gmx_port_mode_s cn56xxp1;
16668 + struct cvmx_pko_reg_gmx_port_mode_s cn58xx;
16669 + struct cvmx_pko_reg_gmx_port_mode_s cn58xxp1;
16670 +};
16671 +
16672 +union cvmx_pko_reg_int_mask {
16673 + uint64_t u64;
16674 + struct cvmx_pko_reg_int_mask_s {
16675 + uint64_t reserved_3_63:61;
16676 + uint64_t currzero:1;
16677 + uint64_t doorbell:1;
16678 + uint64_t parity:1;
16679 + } s;
16680 + struct cvmx_pko_reg_int_mask_cn30xx {
16681 + uint64_t reserved_2_63:62;
16682 + uint64_t doorbell:1;
16683 + uint64_t parity:1;
16684 + } cn30xx;
16685 + struct cvmx_pko_reg_int_mask_cn30xx cn31xx;
16686 + struct cvmx_pko_reg_int_mask_cn30xx cn38xx;
16687 + struct cvmx_pko_reg_int_mask_cn30xx cn38xxp2;
16688 + struct cvmx_pko_reg_int_mask_s cn50xx;
16689 + struct cvmx_pko_reg_int_mask_s cn52xx;
16690 + struct cvmx_pko_reg_int_mask_s cn52xxp1;
16691 + struct cvmx_pko_reg_int_mask_s cn56xx;
16692 + struct cvmx_pko_reg_int_mask_s cn56xxp1;
16693 + struct cvmx_pko_reg_int_mask_s cn58xx;
16694 + struct cvmx_pko_reg_int_mask_s cn58xxp1;
16695 +};
16696 +
16697 +union cvmx_pko_reg_queue_mode {
16698 + uint64_t u64;
16699 + struct cvmx_pko_reg_queue_mode_s {
16700 + uint64_t reserved_2_63:62;
16701 + uint64_t mode:2;
16702 + } s;
16703 + struct cvmx_pko_reg_queue_mode_s cn30xx;
16704 + struct cvmx_pko_reg_queue_mode_s cn31xx;
16705 + struct cvmx_pko_reg_queue_mode_s cn38xx;
16706 + struct cvmx_pko_reg_queue_mode_s cn38xxp2;
16707 + struct cvmx_pko_reg_queue_mode_s cn50xx;
16708 + struct cvmx_pko_reg_queue_mode_s cn52xx;
16709 + struct cvmx_pko_reg_queue_mode_s cn52xxp1;
16710 + struct cvmx_pko_reg_queue_mode_s cn56xx;
16711 + struct cvmx_pko_reg_queue_mode_s cn56xxp1;
16712 + struct cvmx_pko_reg_queue_mode_s cn58xx;
16713 + struct cvmx_pko_reg_queue_mode_s cn58xxp1;
16714 +};
16715 +
16716 +union cvmx_pko_reg_queue_ptrs1 {
16717 + uint64_t u64;
16718 + struct cvmx_pko_reg_queue_ptrs1_s {
16719 + uint64_t reserved_2_63:62;
16720 + uint64_t idx3:1;
16721 + uint64_t qid7:1;
16722 + } s;
16723 + struct cvmx_pko_reg_queue_ptrs1_s cn50xx;
16724 + struct cvmx_pko_reg_queue_ptrs1_s cn52xx;
16725 + struct cvmx_pko_reg_queue_ptrs1_s cn52xxp1;
16726 + struct cvmx_pko_reg_queue_ptrs1_s cn56xx;
16727 + struct cvmx_pko_reg_queue_ptrs1_s cn56xxp1;
16728 + struct cvmx_pko_reg_queue_ptrs1_s cn58xx;
16729 + struct cvmx_pko_reg_queue_ptrs1_s cn58xxp1;
16730 +};
16731 +
16732 +union cvmx_pko_reg_read_idx {
16733 + uint64_t u64;
16734 + struct cvmx_pko_reg_read_idx_s {
16735 + uint64_t reserved_16_63:48;
16736 + uint64_t inc:8;
16737 + uint64_t index:8;
16738 + } s;
16739 + struct cvmx_pko_reg_read_idx_s cn30xx;
16740 + struct cvmx_pko_reg_read_idx_s cn31xx;
16741 + struct cvmx_pko_reg_read_idx_s cn38xx;
16742 + struct cvmx_pko_reg_read_idx_s cn38xxp2;
16743 + struct cvmx_pko_reg_read_idx_s cn50xx;
16744 + struct cvmx_pko_reg_read_idx_s cn52xx;
16745 + struct cvmx_pko_reg_read_idx_s cn52xxp1;
16746 + struct cvmx_pko_reg_read_idx_s cn56xx;
16747 + struct cvmx_pko_reg_read_idx_s cn56xxp1;
16748 + struct cvmx_pko_reg_read_idx_s cn58xx;
16749 + struct cvmx_pko_reg_read_idx_s cn58xxp1;
16750 +};
16751 +
16752 +#endif
16753 --- /dev/null
16754 +++ b/drivers/staging/octeon/cvmx-pko.c
16755 @@ -0,0 +1,506 @@
16756 +/***********************license start***************
16757 + * Author: Cavium Networks
16758 + *
16759 + * Contact: support@caviumnetworks.com
16760 + * This file is part of the OCTEON SDK
16761 + *
16762 + * Copyright (c) 2003-2008 Cavium Networks
16763 + *
16764 + * This file is free software; you can redistribute it and/or modify
16765 + * it under the terms of the GNU General Public License, Version 2, as
16766 + * published by the Free Software Foundation.
16767 + *
16768 + * This file is distributed in the hope that it will be useful, but
16769 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
16770 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16771 + * NONINFRINGEMENT. See the GNU General Public License for more
16772 + * details.
16773 + *
16774 + * You should have received a copy of the GNU General Public License
16775 + * along with this file; if not, write to the Free Software
16776 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16777 + * or visit http://www.gnu.org/licenses/.
16778 + *
16779 + * This file may also be available under a different license from Cavium.
16780 + * Contact Cavium Networks for more information
16781 + ***********************license end**************************************/
16782 +
16783 +/*
16784 + * Support library for the hardware Packet Output unit.
16785 + */
16786 +
16787 +#include <asm/octeon/octeon.h>
16788 +
16789 +#include "cvmx-config.h"
16790 +#include "cvmx-pko.h"
16791 +#include "cvmx-helper.h"
16792 +
16793 +/**
16794 + * Internal state of packet output
16795 + */
16796 +
16797 +/**
16798 + * Call before any other calls to initialize the packet
16799 + * output system. This does chip global config, and should only be
16800 + * done by one core.
16801 + */
16802 +
16803 +void cvmx_pko_initialize_global(void)
16804 +{
16805 + int i;
16806 + uint64_t priority = 8;
16807 + union cvmx_pko_reg_cmd_buf config;
16808 +
16809 + /*
16810 + * Set the size of the PKO command buffers to an odd number of
16811 + * 64bit words. This allows the normal two word send to stay
16812 + * aligned and never span a comamnd word buffer.
16813 + */
16814 + config.u64 = 0;
16815 + config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL;
16816 + config.s.size = CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE / 8 - 1;
16817 +
16818 + cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);
16819 +
16820 + for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++)
16821 + cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1,
16822 + &priority);
16823 +
16824 + /*
16825 + * If we aren't using all of the queues optimize PKO's
16826 + * internal memory.
16827 + */
16828 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)
16829 + || OCTEON_IS_MODEL(OCTEON_CN56XX)
16830 + || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
16831 + int num_interfaces = cvmx_helper_get_number_of_interfaces();
16832 + int last_port =
16833 + cvmx_helper_get_last_ipd_port(num_interfaces - 1);
16834 + int max_queues =
16835 + cvmx_pko_get_base_queue(last_port) +
16836 + cvmx_pko_get_num_queues(last_port);
16837 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
16838 + if (max_queues <= 32)
16839 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
16840 + else if (max_queues <= 64)
16841 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
16842 + } else {
16843 + if (max_queues <= 64)
16844 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
16845 + else if (max_queues <= 128)
16846 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
16847 + }
16848 + }
16849 +}
16850 +
16851 +/**
16852 + * This function does per-core initialization required by the PKO routines.
16853 + * This must be called on all cores that will do packet output, and must
16854 + * be called after the FPA has been initialized and filled with pages.
16855 + *
16856 + * Returns 0 on success
16857 + * !0 on failure
16858 + */
16859 +int cvmx_pko_initialize_local(void)
16860 +{
16861 + /* Nothing to do */
16862 + return 0;
16863 +}
16864 +
16865 +/**
16866 + * Enables the packet output hardware. It must already be
16867 + * configured.
16868 + */
16869 +void cvmx_pko_enable(void)
16870 +{
16871 + union cvmx_pko_reg_flags flags;
16872 +
16873 + flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
16874 + if (flags.s.ena_pko)
16875 + cvmx_dprintf
16876 + ("Warning: Enabling PKO when PKO already enabled.\n");
16877 +
16878 + flags.s.ena_dwb = 1;
16879 + flags.s.ena_pko = 1;
16880 + /*
16881 + * always enable big endian for 3-word command. Does nothing
16882 + * for 2-word.
16883 + */
16884 + flags.s.store_be = 1;
16885 + cvmx_write_csr(CVMX_PKO_REG_FLAGS, flags.u64);
16886 +}
16887 +
16888 +/**
16889 + * Disables the packet output. Does not affect any configuration.
16890 + */
16891 +void cvmx_pko_disable(void)
16892 +{
16893 + union cvmx_pko_reg_flags pko_reg_flags;
16894 + pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
16895 + pko_reg_flags.s.ena_pko = 0;
16896 + cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
16897 +}
16898 +
16899 +
16900 +/**
16901 + * Reset the packet output.
16902 + */
16903 +static void __cvmx_pko_reset(void)
16904 +{
16905 + union cvmx_pko_reg_flags pko_reg_flags;
16906 + pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
16907 + pko_reg_flags.s.reset = 1;
16908 + cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
16909 +}
16910 +
16911 +/**
16912 + * Shutdown and free resources required by packet output.
16913 + */
16914 +void cvmx_pko_shutdown(void)
16915 +{
16916 + union cvmx_pko_mem_queue_ptrs config;
16917 + int queue;
16918 +
16919 + cvmx_pko_disable();
16920 +
16921 + for (queue = 0; queue < CVMX_PKO_MAX_OUTPUT_QUEUES; queue++) {
16922 + config.u64 = 0;
16923 + config.s.tail = 1;
16924 + config.s.index = 0;
16925 + config.s.port = CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID;
16926 + config.s.queue = queue & 0x7f;
16927 + config.s.qos_mask = 0;
16928 + config.s.buf_ptr = 0;
16929 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
16930 + union cvmx_pko_reg_queue_ptrs1 config1;
16931 + config1.u64 = 0;
16932 + config1.s.qid7 = queue >> 7;
16933 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
16934 + }
16935 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
16936 + cvmx_cmd_queue_shutdown(CVMX_CMD_QUEUE_PKO(queue));
16937 + }
16938 + __cvmx_pko_reset();
16939 +}
16940 +
16941 +/**
16942 + * Configure a output port and the associated queues for use.
16943 + *
16944 + * @port: Port to configure.
16945 + * @base_queue: First queue number to associate with this port.
16946 + * @num_queues: Number of queues to associate with this port
16947 + * @priority: Array of priority levels for each queue. Values are
16948 + * allowed to be 0-8. A value of 8 get 8 times the traffic
16949 + * of a value of 1. A value of 0 indicates that no rounds
16950 + * will be participated in. These priorities can be changed
16951 + * on the fly while the pko is enabled. A priority of 9
16952 + * indicates that static priority should be used. If static
16953 + * priority is used all queues with static priority must be
16954 + * contiguous starting at the base_queue, and lower numbered
16955 + * queues have higher priority than higher numbered queues.
16956 + * There must be num_queues elements in the array.
16957 + */
16958 +cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue,
16959 + uint64_t num_queues,
16960 + const uint64_t priority[])
16961 +{
16962 + cvmx_pko_status_t result_code;
16963 + uint64_t queue;
16964 + union cvmx_pko_mem_queue_ptrs config;
16965 + union cvmx_pko_reg_queue_ptrs1 config1;
16966 + int static_priority_base = -1;
16967 + int static_priority_end = -1;
16968 +
16969 + if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS)
16970 + && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) {
16971 + cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid port %llu\n",
16972 + (unsigned long long)port);
16973 + return CVMX_PKO_INVALID_PORT;
16974 + }
16975 +
16976 + if (base_queue + num_queues > CVMX_PKO_MAX_OUTPUT_QUEUES) {
16977 + cvmx_dprintf
16978 + ("ERROR: cvmx_pko_config_port: Invalid queue range %llu\n",
16979 + (unsigned long long)(base_queue + num_queues));
16980 + return CVMX_PKO_INVALID_QUEUE;
16981 + }
16982 +
16983 + if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
16984 + /*
16985 + * Validate the static queue priority setup and set
16986 + * static_priority_base and static_priority_end
16987 + * accordingly.
16988 + */
16989 + for (queue = 0; queue < num_queues; queue++) {
16990 + /* Find first queue of static priority */
16991 + if (static_priority_base == -1
16992 + && priority[queue] ==
16993 + CVMX_PKO_QUEUE_STATIC_PRIORITY)
16994 + static_priority_base = queue;
16995 + /* Find last queue of static priority */
16996 + if (static_priority_base != -1
16997 + && static_priority_end == -1
16998 + && priority[queue] != CVMX_PKO_QUEUE_STATIC_PRIORITY
16999 + && queue)
17000 + static_priority_end = queue - 1;
17001 + else if (static_priority_base != -1
17002 + && static_priority_end == -1
17003 + && queue == num_queues - 1)
17004 + /* all queues are static priority */
17005 + static_priority_end = queue;
17006 + /*
17007 + * Check to make sure all static priority
17008 + * queues are contiguous. Also catches some
17009 + * cases of static priorites not starting at
17010 + * queue 0.
17011 + */
17012 + if (static_priority_end != -1
17013 + && (int)queue > static_priority_end
17014 + && priority[queue] ==
17015 + CVMX_PKO_QUEUE_STATIC_PRIORITY) {
17016 + cvmx_dprintf("ERROR: cvmx_pko_config_port: "
17017 + "Static priority queues aren't "
17018 + "contiguous or don't start at "
17019 + "base queue. q: %d, eq: %d\n",
17020 + (int)queue, static_priority_end);
17021 + return CVMX_PKO_INVALID_PRIORITY;
17022 + }
17023 + }
17024 + if (static_priority_base > 0) {
17025 + cvmx_dprintf("ERROR: cvmx_pko_config_port: Static "
17026 + "priority queues don't start at base "
17027 + "queue. sq: %d\n",
17028 + static_priority_base);
17029 + return CVMX_PKO_INVALID_PRIORITY;
17030 + }
17031 +#if 0
17032 + cvmx_dprintf("Port %d: Static priority queue base: %d, "
17033 + "end: %d\n", port,
17034 + static_priority_base, static_priority_end);
17035 +#endif
17036 + }
17037 + /*
17038 + * At this point, static_priority_base and static_priority_end
17039 + * are either both -1, or are valid start/end queue
17040 + * numbers.
17041 + */
17042 +
17043 + result_code = CVMX_PKO_SUCCESS;
17044 +
17045 +#ifdef PKO_DEBUG
17046 + cvmx_dprintf("num queues: %d (%lld,%lld)\n", num_queues,
17047 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE0,
17048 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE1);
17049 +#endif
17050 +
17051 + for (queue = 0; queue < num_queues; queue++) {
17052 + uint64_t *buf_ptr = NULL;
17053 +
17054 + config1.u64 = 0;
17055 + config1.s.idx3 = queue >> 3;
17056 + config1.s.qid7 = (base_queue + queue) >> 7;
17057 +
17058 + config.u64 = 0;
17059 + config.s.tail = queue == (num_queues - 1);
17060 + config.s.index = queue;
17061 + config.s.port = port;
17062 + config.s.queue = base_queue + queue;
17063 +
17064 + if (!cvmx_octeon_is_pass1()) {
17065 + config.s.static_p = static_priority_base >= 0;
17066 + config.s.static_q = (int)queue <= static_priority_end;
17067 + config.s.s_tail = (int)queue == static_priority_end;
17068 + }
17069 + /*
17070 + * Convert the priority into an enable bit field. Try
17071 + * to space the bits out evenly so the packet don't
17072 + * get grouped up
17073 + */
17074 + switch ((int)priority[queue]) {
17075 + case 0:
17076 + config.s.qos_mask = 0x00;
17077 + break;
17078 + case 1:
17079 + config.s.qos_mask = 0x01;
17080 + break;
17081 + case 2:
17082 + config.s.qos_mask = 0x11;
17083 + break;
17084 + case 3:
17085 + config.s.qos_mask = 0x49;
17086 + break;
17087 + case 4:
17088 + config.s.qos_mask = 0x55;
17089 + break;
17090 + case 5:
17091 + config.s.qos_mask = 0x57;
17092 + break;
17093 + case 6:
17094 + config.s.qos_mask = 0x77;
17095 + break;
17096 + case 7:
17097 + config.s.qos_mask = 0x7f;
17098 + break;
17099 + case 8:
17100 + config.s.qos_mask = 0xff;
17101 + break;
17102 + case CVMX_PKO_QUEUE_STATIC_PRIORITY:
17103 + /* Pass 1 will fall through to the error case */
17104 + if (!cvmx_octeon_is_pass1()) {
17105 + config.s.qos_mask = 0xff;
17106 + break;
17107 + }
17108 + default:
17109 + cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid "
17110 + "priority %llu\n",
17111 + (unsigned long long)priority[queue]);
17112 + config.s.qos_mask = 0xff;
17113 + result_code = CVMX_PKO_INVALID_PRIORITY;
17114 + break;
17115 + }
17116 +
17117 + if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
17118 + cvmx_cmd_queue_result_t cmd_res =
17119 + cvmx_cmd_queue_initialize(CVMX_CMD_QUEUE_PKO
17120 + (base_queue + queue),
17121 + CVMX_PKO_MAX_QUEUE_DEPTH,
17122 + CVMX_FPA_OUTPUT_BUFFER_POOL,
17123 + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
17124 + -
17125 + CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST
17126 + * 8);
17127 + if (cmd_res != CVMX_CMD_QUEUE_SUCCESS) {
17128 + switch (cmd_res) {
17129 + case CVMX_CMD_QUEUE_NO_MEMORY:
17130 + cvmx_dprintf("ERROR: "
17131 + "cvmx_pko_config_port: "
17132 + "Unable to allocate "
17133 + "output buffer.\n");
17134 + return CVMX_PKO_NO_MEMORY;
17135 + case CVMX_CMD_QUEUE_ALREADY_SETUP:
17136 + cvmx_dprintf
17137 + ("ERROR: cvmx_pko_config_port: Port already setup.\n");
17138 + return CVMX_PKO_PORT_ALREADY_SETUP;
17139 + case CVMX_CMD_QUEUE_INVALID_PARAM:
17140 + default:
17141 + cvmx_dprintf
17142 + ("ERROR: cvmx_pko_config_port: Command queue initialization failed.\n");
17143 + return CVMX_PKO_CMD_QUEUE_INIT_ERROR;
17144 + }
17145 + }
17146 +
17147 + buf_ptr =
17148 + (uint64_t *)
17149 + cvmx_cmd_queue_buffer(CVMX_CMD_QUEUE_PKO
17150 + (base_queue + queue));
17151 + config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr);
17152 + } else
17153 + config.s.buf_ptr = 0;
17154 +
17155 + CVMX_SYNCWS;
17156 +
17157 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX))
17158 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
17159 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
17160 + }
17161 +
17162 + return result_code;
17163 +}
17164 +
17165 +#ifdef PKO_DEBUG
17166 +/**
17167 + * Show map of ports -> queues for different cores.
17168 + */
17169 +void cvmx_pko_show_queue_map()
17170 +{
17171 + int core, port;
17172 + int pko_output_ports = 36;
17173 +
17174 + cvmx_dprintf("port");
17175 + for (port = 0; port < pko_output_ports; port++)
17176 + cvmx_dprintf("%3d ", port);
17177 + cvmx_dprintf("\n");
17178 +
17179 + for (core = 0; core < CVMX_MAX_CORES; core++) {
17180 + cvmx_dprintf("\n%2d: ", core);
17181 + for (port = 0; port < pko_output_ports; port++) {
17182 + cvmx_dprintf("%3d ",
17183 + cvmx_pko_get_base_queue_per_core(port,
17184 + core));
17185 + }
17186 + }
17187 + cvmx_dprintf("\n");
17188 +}
17189 +#endif
17190 +
17191 +/**
17192 + * Rate limit a PKO port to a max packets/sec. This function is only
17193 + * supported on CN51XX and higher, excluding CN58XX.
17194 + *
17195 + * @port: Port to rate limit
17196 + * @packets_s: Maximum packet/sec
17197 + * @burst: Maximum number of packets to burst in a row before rate
17198 + * limiting cuts in.
17199 + *
17200 + * Returns Zero on success, negative on failure
17201 + */
17202 +int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst)
17203 +{
17204 + union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
17205 + union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
17206 +
17207 + pko_mem_port_rate0.u64 = 0;
17208 + pko_mem_port_rate0.s.pid = port;
17209 + pko_mem_port_rate0.s.rate_pkt =
17210 + cvmx_sysinfo_get()->cpu_clock_hz / packets_s / 16;
17211 + /* No cost per word since we are limited by packets/sec, not bits/sec */
17212 + pko_mem_port_rate0.s.rate_word = 0;
17213 +
17214 + pko_mem_port_rate1.u64 = 0;
17215 + pko_mem_port_rate1.s.pid = port;
17216 + pko_mem_port_rate1.s.rate_lim =
17217 + ((uint64_t) pko_mem_port_rate0.s.rate_pkt * burst) >> 8;
17218 +
17219 + cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
17220 + cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
17221 + return 0;
17222 +}
17223 +
17224 +/**
17225 + * Rate limit a PKO port to a max bits/sec. This function is only
17226 + * supported on CN51XX and higher, excluding CN58XX.
17227 + *
17228 + * @port: Port to rate limit
17229 + * @bits_s: PKO rate limit in bits/sec
17230 + * @burst: Maximum number of bits to burst before rate
17231 + * limiting cuts in.
17232 + *
17233 + * Returns Zero on success, negative on failure
17234 + */
17235 +int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst)
17236 +{
17237 + union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
17238 + union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
17239 + uint64_t clock_rate = cvmx_sysinfo_get()->cpu_clock_hz;
17240 + uint64_t tokens_per_bit = clock_rate * 16 / bits_s;
17241 +
17242 + pko_mem_port_rate0.u64 = 0;
17243 + pko_mem_port_rate0.s.pid = port;
17244 + /*
17245 + * Each packet has a 12 bytes of interframe gap, an 8 byte
17246 + * preamble, and a 4 byte CRC. These are not included in the
17247 + * per word count. Multiply by 8 to covert to bits and divide
17248 + * by 256 for limit granularity.
17249 + */
17250 + pko_mem_port_rate0.s.rate_pkt = (12 + 8 + 4) * 8 * tokens_per_bit / 256;
17251 + /* Each 8 byte word has 64bits */
17252 + pko_mem_port_rate0.s.rate_word = 64 * tokens_per_bit;
17253 +
17254 + pko_mem_port_rate1.u64 = 0;
17255 + pko_mem_port_rate1.s.pid = port;
17256 + pko_mem_port_rate1.s.rate_lim = tokens_per_bit * burst / 256;
17257 +
17258 + cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
17259 + cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
17260 + return 0;
17261 +}
17262 --- /dev/null
17263 +++ b/drivers/staging/octeon/cvmx-pko.h
17264 @@ -0,0 +1,610 @@
17265 +/***********************license start***************
17266 + * Author: Cavium Networks
17267 + *
17268 + * Contact: support@caviumnetworks.com
17269 + * This file is part of the OCTEON SDK
17270 + *
17271 + * Copyright (c) 2003-2008 Cavium Networks
17272 + *
17273 + * This file is free software; you can redistribute it and/or modify
17274 + * it under the terms of the GNU General Public License, Version 2, as
17275 + * published by the Free Software Foundation.
17276 + *
17277 + * This file is distributed in the hope that it will be useful, but
17278 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
17279 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
17280 + * NONINFRINGEMENT. See the GNU General Public License for more
17281 + * details.
17282 + *
17283 + * You should have received a copy of the GNU General Public License
17284 + * along with this file; if not, write to the Free Software
17285 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17286 + * or visit http://www.gnu.org/licenses/.
17287 + *
17288 + * This file may also be available under a different license from Cavium.
17289 + * Contact Cavium Networks for more information
17290 + ***********************license end**************************************/
17291 +
17292 +/**
17293 + *
17294 + * Interface to the hardware Packet Output unit.
17295 + *
17296 + * Starting with SDK 1.7.0, the PKO output functions now support
17297 + * two types of locking. CVMX_PKO_LOCK_ATOMIC_TAG continues to
17298 + * function similarly to previous SDKs by using POW atomic tags
17299 + * to preserve ordering and exclusivity. As a new option, you
17300 + * can now pass CVMX_PKO_LOCK_CMD_QUEUE which uses a ll/sc
17301 + * memory based locking instead. This locking has the advantage
17302 + * of not affecting the tag state but doesn't preserve packet
17303 + * ordering. CVMX_PKO_LOCK_CMD_QUEUE is appropriate in most
17304 + * generic code while CVMX_PKO_LOCK_CMD_QUEUE should be used
17305 + * with hand tuned fast path code.
17306 + *
17307 + * Some of other SDK differences visible to the command command
17308 + * queuing:
17309 + * - PKO indexes are no longer stored in the FAU. A large
17310 + * percentage of the FAU register block used to be tied up
17311 + * maintaining PKO queue pointers. These are now stored in a
17312 + * global named block.
17313 + * - The PKO <b>use_locking</b> parameter can now have a global
17314 + * effect. Since all application use the same named block,
17315 + * queue locking correctly applies across all operating
17316 + * systems when using CVMX_PKO_LOCK_CMD_QUEUE.
17317 + * - PKO 3 word commands are now supported. Use
17318 + * cvmx_pko_send_packet_finish3().
17319 + *
17320 + */
17321 +
17322 +#ifndef __CVMX_PKO_H__
17323 +#define __CVMX_PKO_H__
17324 +
17325 +#include "cvmx-fpa.h"
17326 +#include "cvmx-pow.h"
17327 +#include "cvmx-cmd-queue.h"
17328 +#include "cvmx-pko-defs.h"
17329 +
17330 +/* Adjust the command buffer size by 1 word so that in the case of using only
17331 + * two word PKO commands no command words stradle buffers. The useful values
17332 + * for this are 0 and 1. */
17333 +#define CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST (1)
17334 +
17335 +#define CVMX_PKO_MAX_OUTPUT_QUEUES_STATIC 256
17336 +#define CVMX_PKO_MAX_OUTPUT_QUEUES ((OCTEON_IS_MODEL(OCTEON_CN31XX) || \
17337 + OCTEON_IS_MODEL(OCTEON_CN3010) || OCTEON_IS_MODEL(OCTEON_CN3005) || \
17338 + OCTEON_IS_MODEL(OCTEON_CN50XX)) ? 32 : \
17339 + (OCTEON_IS_MODEL(OCTEON_CN58XX) || \
17340 + OCTEON_IS_MODEL(OCTEON_CN56XX)) ? 256 : 128)
17341 +#define CVMX_PKO_NUM_OUTPUT_PORTS 40
17342 +/* use this for queues that are not used */
17343 +#define CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63
17344 +#define CVMX_PKO_QUEUE_STATIC_PRIORITY 9
17345 +#define CVMX_PKO_ILLEGAL_QUEUE 0xFFFF
17346 +#define CVMX_PKO_MAX_QUEUE_DEPTH 0
17347 +
17348 +typedef enum {
17349 + CVMX_PKO_SUCCESS,
17350 + CVMX_PKO_INVALID_PORT,
17351 + CVMX_PKO_INVALID_QUEUE,
17352 + CVMX_PKO_INVALID_PRIORITY,
17353 + CVMX_PKO_NO_MEMORY,
17354 + CVMX_PKO_PORT_ALREADY_SETUP,
17355 + CVMX_PKO_CMD_QUEUE_INIT_ERROR
17356 +} cvmx_pko_status_t;
17357 +
17358 +/**
17359 + * This enumeration represents the differnet locking modes supported by PKO.
17360 + */
17361 +typedef enum {
17362 + /*
17363 + * PKO doesn't do any locking. It is the responsibility of the
17364 + * application to make sure that no other core is accessing
17365 + * the same queue at the smae time
17366 + */
17367 + CVMX_PKO_LOCK_NONE = 0,
17368 + /*
17369 + * PKO performs an atomic tagswitch to insure exclusive access
17370 + * to the output queue. This will maintain packet ordering on
17371 + * output.
17372 + */
17373 + CVMX_PKO_LOCK_ATOMIC_TAG = 1,
17374 + /*
17375 + * PKO uses the common command queue locks to insure exclusive
17376 + * access to the output queue. This is a memory based
17377 + * ll/sc. This is the most portable locking mechanism.
17378 + */
17379 + CVMX_PKO_LOCK_CMD_QUEUE = 2,
17380 +} cvmx_pko_lock_t;
17381 +
17382 +typedef struct {
17383 + uint32_t packets;
17384 + uint64_t octets;
17385 + uint64_t doorbell;
17386 +} cvmx_pko_port_status_t;
17387 +
17388 +/**
17389 + * This structure defines the address to use on a packet enqueue
17390 + */
17391 +typedef union {
17392 + uint64_t u64;
17393 + struct {
17394 + /* Must CVMX_IO_SEG */
17395 + uint64_t mem_space:2;
17396 + /* Must be zero */
17397 + uint64_t reserved:13;
17398 + /* Must be one */
17399 + uint64_t is_io:1;
17400 + /* The ID of the device on the non-coherent bus */
17401 + uint64_t did:8;
17402 + /* Must be zero */
17403 + uint64_t reserved2:4;
17404 + /* Must be zero */
17405 + uint64_t reserved3:18;
17406 + /*
17407 + * The hardware likes to have the output port in
17408 + * addition to the output queue,
17409 + */
17410 + uint64_t port:6;
17411 + /*
17412 + * The output queue to send the packet to (0-127 are
17413 + * legal)
17414 + */
17415 + uint64_t queue:9;
17416 + /* Must be zero */
17417 + uint64_t reserved4:3;
17418 + } s;
17419 +} cvmx_pko_doorbell_address_t;
17420 +
17421 +/**
17422 + * Structure of the first packet output command word.
17423 + */
17424 +typedef union {
17425 + uint64_t u64;
17426 + struct {
17427 + /*
17428 + * The size of the reg1 operation - could be 8, 16,
17429 + * 32, or 64 bits.
17430 + */
17431 + uint64_t size1:2;
17432 + /*
17433 + * The size of the reg0 operation - could be 8, 16,
17434 + * 32, or 64 bits.
17435 + */
17436 + uint64_t size0:2;
17437 + /*
17438 + * If set, subtract 1, if clear, subtract packet
17439 + * size.
17440 + */
17441 + uint64_t subone1:1;
17442 + /*
17443 + * The register, subtract will be done if reg1 is
17444 + * non-zero.
17445 + */
17446 + uint64_t reg1:11;
17447 + /* If set, subtract 1, if clear, subtract packet size */
17448 + uint64_t subone0:1;
17449 + /* The register, subtract will be done if reg0 is non-zero */
17450 + uint64_t reg0:11;
17451 + /*
17452 + * When set, interpret segment pointer and segment
17453 + * bytes in little endian order.
17454 + */
17455 + uint64_t le:1;
17456 + /*
17457 + * When set, packet data not allocated in L2 cache by
17458 + * PKO.
17459 + */
17460 + uint64_t n2:1;
17461 + /*
17462 + * If set and rsp is set, word3 contains a pointer to
17463 + * a work queue entry.
17464 + */
17465 + uint64_t wqp:1;
17466 + /* If set, the hardware will send a response when done */
17467 + uint64_t rsp:1;
17468 + /*
17469 + * If set, the supplied pkt_ptr is really a pointer to
17470 + * a list of pkt_ptr's.
17471 + */
17472 + uint64_t gather:1;
17473 + /*
17474 + * If ipoffp1 is non zero, (ipoffp1-1) is the number
17475 + * of bytes to IP header, and the hardware will
17476 + * calculate and insert the UDP/TCP checksum.
17477 + */
17478 + uint64_t ipoffp1:7;
17479 + /*
17480 + * If set, ignore the I bit (force to zero) from all
17481 + * pointer structures.
17482 + */
17483 + uint64_t ignore_i:1;
17484 + /*
17485 + * If clear, the hardware will attempt to free the
17486 + * buffers containing the packet.
17487 + */
17488 + uint64_t dontfree:1;
17489 + /*
17490 + * The total number of segs in the packet, if gather
17491 + * set, also gather list length.
17492 + */
17493 + uint64_t segs:6;
17494 + /* Including L2, but no trailing CRC */
17495 + uint64_t total_bytes:16;
17496 + } s;
17497 +} cvmx_pko_command_word0_t;
17498 +
17499 +/* CSR typedefs have been moved to cvmx-csr-*.h */
17500 +
17501 +/**
17502 + * Definition of internal state for Packet output processing
17503 + */
17504 +typedef struct {
17505 + /* ptr to start of buffer, offset kept in FAU reg */
17506 + uint64_t *start_ptr;
17507 +} cvmx_pko_state_elem_t;
17508 +
17509 +/**
17510 + * Call before any other calls to initialize the packet
17511 + * output system.
17512 + */
17513 +extern void cvmx_pko_initialize_global(void);
17514 +extern int cvmx_pko_initialize_local(void);
17515 +
17516 +/**
17517 + * Enables the packet output hardware. It must already be
17518 + * configured.
17519 + */
17520 +extern void cvmx_pko_enable(void);
17521 +
17522 +/**
17523 + * Disables the packet output. Does not affect any configuration.
17524 + */
17525 +extern void cvmx_pko_disable(void);
17526 +
17527 +/**
17528 + * Shutdown and free resources required by packet output.
17529 + */
17530 +
17531 +extern void cvmx_pko_shutdown(void);
17532 +
17533 +/**
17534 + * Configure a output port and the associated queues for use.
17535 + *
17536 + * @port: Port to configure.
17537 + * @base_queue: First queue number to associate with this port.
17538 + * @num_queues: Number of queues t oassociate with this port
17539 + * @priority: Array of priority levels for each queue. Values are
17540 + * allowed to be 1-8. A value of 8 get 8 times the traffic
17541 + * of a value of 1. There must be num_queues elements in the
17542 + * array.
17543 + */
17544 +extern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port,
17545 + uint64_t base_queue,
17546 + uint64_t num_queues,
17547 + const uint64_t priority[]);
17548 +
17549 +/**
17550 + * Ring the packet output doorbell. This tells the packet
17551 + * output hardware that "len" command words have been added
17552 + * to its pending list. This command includes the required
17553 + * CVMX_SYNCWS before the doorbell ring.
17554 + *
17555 + * @port: Port the packet is for
17556 + * @queue: Queue the packet is for
17557 + * @len: Length of the command in 64 bit words
17558 + */
17559 +static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
17560 + uint64_t len)
17561 +{
17562 + cvmx_pko_doorbell_address_t ptr;
17563 +
17564 + ptr.u64 = 0;
17565 + ptr.s.mem_space = CVMX_IO_SEG;
17566 + ptr.s.did = CVMX_OCT_DID_PKT_SEND;
17567 + ptr.s.is_io = 1;
17568 + ptr.s.port = port;
17569 + ptr.s.queue = queue;
17570 + /*
17571 + * Need to make sure output queue data is in DRAM before
17572 + * doorbell write.
17573 + */
17574 + CVMX_SYNCWS;
17575 + cvmx_write_io(ptr.u64, len);
17576 +}
17577 +
17578 +/**
17579 + * Prepare to send a packet. This may initiate a tag switch to
17580 + * get exclusive access to the output queue structure, and
17581 + * performs other prep work for the packet send operation.
17582 + *
17583 + * cvmx_pko_send_packet_finish() MUST be called after this function is called,
17584 + * and must be called with the same port/queue/use_locking arguments.
17585 + *
17586 + * The use_locking parameter allows the caller to use three
17587 + * possible locking modes.
17588 + * - CVMX_PKO_LOCK_NONE
17589 + * - PKO doesn't do any locking. It is the responsibility
17590 + * of the application to make sure that no other core
17591 + * is accessing the same queue at the smae time.
17592 + * - CVMX_PKO_LOCK_ATOMIC_TAG
17593 + * - PKO performs an atomic tagswitch to insure exclusive
17594 + * access to the output queue. This will maintain
17595 + * packet ordering on output.
17596 + * - CVMX_PKO_LOCK_CMD_QUEUE
17597 + * - PKO uses the common command queue locks to insure
17598 + * exclusive access to the output queue. This is a
17599 + * memory based ll/sc. This is the most portable
17600 + * locking mechanism.
17601 + *
17602 + * NOTE: If atomic locking is used, the POW entry CANNOT be
17603 + * descheduled, as it does not contain a valid WQE pointer.
17604 + *
17605 + * @port: Port to send it on
17606 + * @queue: Queue to use
17607 + * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17608 + * CVMX_PKO_LOCK_CMD_QUEUE
17609 + */
17610 +
17611 +static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
17612 + cvmx_pko_lock_t use_locking)
17613 +{
17614 + if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
17615 + /*
17616 + * Must do a full switch here to handle all cases. We
17617 + * use a fake WQE pointer, as the POW does not access
17618 + * this memory. The WQE pointer and group are only
17619 + * used if this work is descheduled, which is not
17620 + * supported by the
17621 + * cvmx_pko_send_packet_prepare/cvmx_pko_send_packet_finish
17622 + * combination. Note that this is a special case in
17623 + * which these fake values can be used - this is not a
17624 + * general technique.
17625 + */
17626 + uint32_t tag =
17627 + CVMX_TAG_SW_BITS_INTERNAL << CVMX_TAG_SW_SHIFT |
17628 + CVMX_TAG_SUBGROUP_PKO << CVMX_TAG_SUBGROUP_SHIFT |
17629 + (CVMX_TAG_SUBGROUP_MASK & queue);
17630 + cvmx_pow_tag_sw_full((cvmx_wqe_t *) cvmx_phys_to_ptr(0x80), tag,
17631 + CVMX_POW_TAG_TYPE_ATOMIC, 0);
17632 + }
17633 +}
17634 +
17635 +/**
17636 + * Complete packet output. cvmx_pko_send_packet_prepare() must be
17637 + * called exactly once before this, and the same parameters must be
17638 + * passed to both cvmx_pko_send_packet_prepare() and
17639 + * cvmx_pko_send_packet_finish().
17640 + *
17641 + * @port: Port to send it on
17642 + * @queue: Queue to use
17643 + * @pko_command:
17644 + * PKO HW command word
17645 + * @packet: Packet to send
17646 + * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17647 + * CVMX_PKO_LOCK_CMD_QUEUE
17648 + *
17649 + * Returns returns CVMX_PKO_SUCCESS on success, or error code on
17650 + * failure of output
17651 + */
17652 +static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
17653 + uint64_t port,
17654 + uint64_t queue,
17655 + cvmx_pko_command_word0_t pko_command,
17656 + union cvmx_buf_ptr packet,
17657 + cvmx_pko_lock_t use_locking)
17658 +{
17659 + cvmx_cmd_queue_result_t result;
17660 + if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
17661 + cvmx_pow_tag_sw_wait();
17662 + result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
17663 + (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
17664 + pko_command.u64, packet.u64);
17665 + if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
17666 + cvmx_pko_doorbell(port, queue, 2);
17667 + return CVMX_PKO_SUCCESS;
17668 + } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
17669 + || (result == CVMX_CMD_QUEUE_FULL)) {
17670 + return CVMX_PKO_NO_MEMORY;
17671 + } else {
17672 + return CVMX_PKO_INVALID_QUEUE;
17673 + }
17674 +}
17675 +
17676 +/**
17677 + * Complete packet output. cvmx_pko_send_packet_prepare() must be
17678 + * called exactly once before this, and the same parameters must be
17679 + * passed to both cvmx_pko_send_packet_prepare() and
17680 + * cvmx_pko_send_packet_finish().
17681 + *
17682 + * @port: Port to send it on
17683 + * @queue: Queue to use
17684 + * @pko_command:
17685 + * PKO HW command word
17686 + * @packet: Packet to send
17687 + * @addr: Plysical address of a work queue entry or physical address
17688 + * to zero on complete.
17689 + * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17690 + * CVMX_PKO_LOCK_CMD_QUEUE
17691 + *
17692 + * Returns returns CVMX_PKO_SUCCESS on success, or error code on
17693 + * failure of output
17694 + */
17695 +static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
17696 + uint64_t port,
17697 + uint64_t queue,
17698 + cvmx_pko_command_word0_t pko_command,
17699 + union cvmx_buf_ptr packet,
17700 + uint64_t addr,
17701 + cvmx_pko_lock_t use_locking)
17702 +{
17703 + cvmx_cmd_queue_result_t result;
17704 + if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
17705 + cvmx_pow_tag_sw_wait();
17706 + result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
17707 + (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
17708 + pko_command.u64, packet.u64, addr);
17709 + if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
17710 + cvmx_pko_doorbell(port, queue, 3);
17711 + return CVMX_PKO_SUCCESS;
17712 + } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
17713 + || (result == CVMX_CMD_QUEUE_FULL)) {
17714 + return CVMX_PKO_NO_MEMORY;
17715 + } else {
17716 + return CVMX_PKO_INVALID_QUEUE;
17717 + }
17718 +}
17719 +
17720 +/**
17721 + * Return the pko output queue associated with a port and a specific core.
17722 + * In normal mode (PKO lockless operation is disabled), the value returned
17723 + * is the base queue.
17724 + *
17725 + * @port: Port number
17726 + * @core: Core to get queue for
17727 + *
17728 + * Returns Core-specific output queue
17729 + */
17730 +static inline int cvmx_pko_get_base_queue_per_core(int port, int core)
17731 +{
17732 +#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
17733 +#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16
17734 +#endif
17735 +#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
17736 +#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16
17737 +#endif
17738 +
17739 + if (port < CVMX_PKO_MAX_PORTS_INTERFACE0)
17740 + return port * CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + core;
17741 + else if (port >= 16 && port < 16 + CVMX_PKO_MAX_PORTS_INTERFACE1)
17742 + return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17743 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + (port -
17744 + 16) *
17745 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + core;
17746 + else if ((port >= 32) && (port < 36))
17747 + return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17748 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
17749 + CVMX_PKO_MAX_PORTS_INTERFACE1 *
17750 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + (port -
17751 + 32) *
17752 + CVMX_PKO_QUEUES_PER_PORT_PCI;
17753 + else if ((port >= 36) && (port < 40))
17754 + return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17755 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
17756 + CVMX_PKO_MAX_PORTS_INTERFACE1 *
17757 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 +
17758 + 4 * CVMX_PKO_QUEUES_PER_PORT_PCI + (port -
17759 + 36) *
17760 + CVMX_PKO_QUEUES_PER_PORT_LOOP;
17761 + else
17762 + /* Given the limit on the number of ports we can map to
17763 + * CVMX_MAX_OUTPUT_QUEUES_STATIC queues (currently 256,
17764 + * divided among all cores), the remaining unmapped ports
17765 + * are assigned an illegal queue number */
17766 + return CVMX_PKO_ILLEGAL_QUEUE;
17767 +}
17768 +
17769 +/**
17770 + * For a given port number, return the base pko output queue
17771 + * for the port.
17772 + *
17773 + * @port: Port number
17774 + * Returns Base output queue
17775 + */
17776 +static inline int cvmx_pko_get_base_queue(int port)
17777 +{
17778 + return cvmx_pko_get_base_queue_per_core(port, 0);
17779 +}
17780 +
17781 +/**
17782 + * For a given port number, return the number of pko output queues.
17783 + *
17784 + * @port: Port number
17785 + * Returns Number of output queues
17786 + */
17787 +static inline int cvmx_pko_get_num_queues(int port)
17788 +{
17789 + if (port < 16)
17790 + return CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
17791 + else if (port < 32)
17792 + return CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
17793 + else if (port < 36)
17794 + return CVMX_PKO_QUEUES_PER_PORT_PCI;
17795 + else if (port < 40)
17796 + return CVMX_PKO_QUEUES_PER_PORT_LOOP;
17797 + else
17798 + return 0;
17799 +}
17800 +
17801 +/**
17802 + * Get the status counters for a port.
17803 + *
17804 + * @port_num: Port number to get statistics for.
17805 + * @clear: Set to 1 to clear the counters after they are read
17806 + * @status: Where to put the results.
17807 + */
17808 +static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
17809 + cvmx_pko_port_status_t *status)
17810 +{
17811 + union cvmx_pko_reg_read_idx pko_reg_read_idx;
17812 + union cvmx_pko_mem_count0 pko_mem_count0;
17813 + union cvmx_pko_mem_count1 pko_mem_count1;
17814 +
17815 + pko_reg_read_idx.u64 = 0;
17816 + pko_reg_read_idx.s.index = port_num;
17817 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17818 +
17819 + pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0);
17820 + status->packets = pko_mem_count0.s.count;
17821 + if (clear) {
17822 + pko_mem_count0.s.count = port_num;
17823 + cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64);
17824 + }
17825 +
17826 + pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1);
17827 + status->octets = pko_mem_count1.s.count;
17828 + if (clear) {
17829 + pko_mem_count1.s.count = port_num;
17830 + cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64);
17831 + }
17832 +
17833 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
17834 + union cvmx_pko_mem_debug9 debug9;
17835 + pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
17836 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17837 + debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
17838 + status->doorbell = debug9.cn38xx.doorbell;
17839 + } else {
17840 + union cvmx_pko_mem_debug8 debug8;
17841 + pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
17842 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17843 + debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
17844 + status->doorbell = debug8.cn58xx.doorbell;
17845 + }
17846 +}
17847 +
17848 +/**
17849 + * Rate limit a PKO port to a max packets/sec. This function is only
17850 + * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
17851 + *
17852 + * @port: Port to rate limit
17853 + * @packets_s: Maximum packet/sec
17854 + * @burst: Maximum number of packets to burst in a row before rate
17855 + * limiting cuts in.
17856 + *
17857 + * Returns Zero on success, negative on failure
17858 + */
17859 +extern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst);
17860 +
17861 +/**
17862 + * Rate limit a PKO port to a max bits/sec. This function is only
17863 + * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
17864 + *
17865 + * @port: Port to rate limit
17866 + * @bits_s: PKO rate limit in bits/sec
17867 + * @burst: Maximum number of bits to burst before rate
17868 + * limiting cuts in.
17869 + *
17870 + * Returns Zero on success, negative on failure
17871 + */
17872 +extern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst);
17873 +
17874 +#endif /* __CVMX_PKO_H__ */
17875 --- /dev/null
17876 +++ b/drivers/staging/octeon/cvmx-pow.h
17877 @@ -0,0 +1,1982 @@
17878 +/***********************license start***************
17879 + * Author: Cavium Networks
17880 + *
17881 + * Contact: support@caviumnetworks.com
17882 + * This file is part of the OCTEON SDK
17883 + *
17884 + * Copyright (c) 2003-2008 Cavium Networks
17885 + *
17886 + * This file is free software; you can redistribute it and/or modify
17887 + * it under the terms of the GNU General Public License, Version 2, as
17888 + * published by the Free Software Foundation.
17889 + *
17890 + * This file is distributed in the hope that it will be useful, but
17891 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
17892 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
17893 + * NONINFRINGEMENT. See the GNU General Public License for more
17894 + * details.
17895 + *
17896 + * You should have received a copy of the GNU General Public License
17897 + * along with this file; if not, write to the Free Software
17898 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17899 + * or visit http://www.gnu.org/licenses/.
17900 + *
17901 + * This file may also be available under a different license from Cavium.
17902 + * Contact Cavium Networks for more information
17903 + ***********************license end**************************************/
17904 +
17905 +/**
17906 + * Interface to the hardware Packet Order / Work unit.
17907 + *
17908 + * New, starting with SDK 1.7.0, cvmx-pow supports a number of
17909 + * extended consistency checks. The define
17910 + * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW
17911 + * internal state checks to find common programming errors. If
17912 + * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default
17913 + * enabled. For example, cvmx-pow will check for the following
17914 + * program errors or POW state inconsistency.
17915 + * - Requesting a POW operation with an active tag switch in
17916 + * progress.
17917 + * - Waiting for a tag switch to complete for an excessively
17918 + * long period. This is normally a sign of an error in locking
17919 + * causing deadlock.
17920 + * - Illegal tag switches from NULL_NULL.
17921 + * - Illegal tag switches from NULL.
17922 + * - Illegal deschedule request.
17923 + * - WQE pointer not matching the one attached to the core by
17924 + * the POW.
17925 + *
17926 + */
17927 +
17928 +#ifndef __CVMX_POW_H__
17929 +#define __CVMX_POW_H__
17930 +
17931 +#include <asm/octeon/cvmx-pow-defs.h>
17932 +
17933 +#include "cvmx-scratch.h"
17934 +#include "cvmx-wqe.h"
17935 +
17936 +/* Default to having all POW constancy checks turned on */
17937 +#ifndef CVMX_ENABLE_POW_CHECKS
17938 +#define CVMX_ENABLE_POW_CHECKS 1
17939 +#endif
17940 +
17941 +enum cvmx_pow_tag_type {
17942 + /* Tag ordering is maintained */
17943 + CVMX_POW_TAG_TYPE_ORDERED = 0L,
17944 + /* Tag ordering is maintained, and at most one PP has the tag */
17945 + CVMX_POW_TAG_TYPE_ATOMIC = 1L,
17946 + /*
17947 + * The work queue entry from the order - NEVER tag switch from
17948 + * NULL to NULL
17949 + */
17950 + CVMX_POW_TAG_TYPE_NULL = 2L,
17951 + /* A tag switch to NULL, and there is no space reserved in POW
17952 + * - NEVER tag switch to NULL_NULL
17953 + * - NEVER tag switch from NULL_NULL
17954 + * - NULL_NULL is entered at the beginning of time and on a deschedule.
17955 + * - NULL_NULL can be exited by a new work request. A NULL_SWITCH
17956 + * load can also switch the state to NULL
17957 + */
17958 + CVMX_POW_TAG_TYPE_NULL_NULL = 3L
17959 +};
17960 +
17961 +/**
17962 + * Wait flag values for pow functions.
17963 + */
17964 +typedef enum {
17965 + CVMX_POW_WAIT = 1,
17966 + CVMX_POW_NO_WAIT = 0,
17967 +} cvmx_pow_wait_t;
17968 +
17969 +/**
17970 + * POW tag operations. These are used in the data stored to the POW.
17971 + */
17972 +typedef enum {
17973 + /*
17974 + * switch the tag (only) for this PP
17975 + * - the previous tag should be non-NULL in this case
17976 + * - tag switch response required
17977 + * - fields used: op, type, tag
17978 + */
17979 + CVMX_POW_TAG_OP_SWTAG = 0L,
17980 + /*
17981 + * switch the tag for this PP, with full information
17982 + * - this should be used when the previous tag is NULL
17983 + * - tag switch response required
17984 + * - fields used: address, op, grp, type, tag
17985 + */
17986 + CVMX_POW_TAG_OP_SWTAG_FULL = 1L,
17987 + /*
17988 + * switch the tag (and/or group) for this PP and de-schedule
17989 + * - OK to keep the tag the same and only change the group
17990 + * - fields used: op, no_sched, grp, type, tag
17991 + */
17992 + CVMX_POW_TAG_OP_SWTAG_DESCH = 2L,
17993 + /*
17994 + * just de-schedule
17995 + * - fields used: op, no_sched
17996 + */
17997 + CVMX_POW_TAG_OP_DESCH = 3L,
17998 + /*
17999 + * create an entirely new work queue entry
18000 + * - fields used: address, op, qos, grp, type, tag
18001 + */
18002 + CVMX_POW_TAG_OP_ADDWQ = 4L,
18003 + /*
18004 + * just update the work queue pointer and grp for this PP
18005 + * - fields used: address, op, grp
18006 + */
18007 + CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L,
18008 + /*
18009 + * set the no_sched bit on the de-schedule list
18010 + *
18011 + * - does nothing if the selected entry is not on the
18012 + * de-schedule list
18013 + *
18014 + * - does nothing if the stored work queue pointer does not
18015 + * match the address field
18016 + *
18017 + * - fields used: address, index, op
18018 + *
18019 + * Before issuing a *_NSCHED operation, SW must guarantee
18020 + * that all prior deschedules and set/clr NSCHED operations
18021 + * are complete and all prior switches are complete. The
18022 + * hardware provides the opsdone bit and swdone bit for SW
18023 + * polling. After issuing a *_NSCHED operation, SW must
18024 + * guarantee that the set/clr NSCHED is complete before any
18025 + * subsequent operations.
18026 + */
18027 + CVMX_POW_TAG_OP_SET_NSCHED = 6L,
18028 + /*
18029 + * clears the no_sched bit on the de-schedule list
18030 + *
18031 + * - does nothing if the selected entry is not on the
18032 + * de-schedule list
18033 + *
18034 + * - does nothing if the stored work queue pointer does not
18035 + * match the address field
18036 + *
18037 + * - fields used: address, index, op
18038 + *
18039 + * Before issuing a *_NSCHED operation, SW must guarantee that
18040 + * all prior deschedules and set/clr NSCHED operations are
18041 + * complete and all prior switches are complete. The hardware
18042 + * provides the opsdone bit and swdone bit for SW
18043 + * polling. After issuing a *_NSCHED operation, SW must
18044 + * guarantee that the set/clr NSCHED is complete before any
18045 + * subsequent operations.
18046 + */
18047 + CVMX_POW_TAG_OP_CLR_NSCHED = 7L,
18048 + /* do nothing */
18049 + CVMX_POW_TAG_OP_NOP = 15L
18050 +} cvmx_pow_tag_op_t;
18051 +
18052 +/**
18053 + * This structure defines the store data on a store to POW
18054 + */
18055 +typedef union {
18056 + uint64_t u64;
18057 + struct {
18058 + /*
18059 + * Don't reschedule this entry. no_sched is used for
18060 + * CVMX_POW_TAG_OP_SWTAG_DESCH and
18061 + * CVMX_POW_TAG_OP_DESCH
18062 + */
18063 + uint64_t no_sched:1;
18064 + uint64_t unused:2;
18065 + /* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */
18066 + uint64_t index:13;
18067 + /* The operation to perform */
18068 + cvmx_pow_tag_op_t op:4;
18069 + uint64_t unused2:2;
18070 + /*
18071 + * The QOS level for the packet. qos is only used for
18072 + * CVMX_POW_TAG_OP_ADDWQ
18073 + */
18074 + uint64_t qos:3;
18075 + /*
18076 + * The group that the work queue entry will be
18077 + * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ,
18078 + * CVMX_POW_TAG_OP_SWTAG_FULL,
18079 + * CVMX_POW_TAG_OP_SWTAG_DESCH, and
18080 + * CVMX_POW_TAG_OP_UPDATE_WQP_GRP
18081 + */
18082 + uint64_t grp:4;
18083 + /*
18084 + * The type of the tag. type is used for everything
18085 + * except CVMX_POW_TAG_OP_DESCH,
18086 + * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
18087 + * CVMX_POW_TAG_OP_*_NSCHED
18088 + */
18089 + uint64_t type:3;
18090 + /*
18091 + * The actual tag. tag is used for everything except
18092 + * CVMX_POW_TAG_OP_DESCH,
18093 + * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
18094 + * CVMX_POW_TAG_OP_*_NSCHED
18095 + */
18096 + uint64_t tag:32;
18097 + } s;
18098 +} cvmx_pow_tag_req_t;
18099 +
18100 +/**
18101 + * This structure describes the address to load stuff from POW
18102 + */
18103 +typedef union {
18104 + uint64_t u64;
18105 +
18106 + /**
18107 + * Address for new work request loads (did<2:0> == 0)
18108 + */
18109 + struct {
18110 + /* Mips64 address region. Should be CVMX_IO_SEG */
18111 + uint64_t mem_region:2;
18112 + /* Must be zero */
18113 + uint64_t reserved_49_61:13;
18114 + /* Must be one */
18115 + uint64_t is_io:1;
18116 + /* the ID of POW -- did<2:0> == 0 in this case */
18117 + uint64_t did:8;
18118 + /* Must be zero */
18119 + uint64_t reserved_4_39:36;
18120 + /*
18121 + * If set, don't return load response until work is
18122 + * available.
18123 + */
18124 + uint64_t wait:1;
18125 + /* Must be zero */
18126 + uint64_t reserved_0_2:3;
18127 + } swork;
18128 +
18129 + /**
18130 + * Address for loads to get POW internal status
18131 + */
18132 + struct {
18133 + /* Mips64 address region. Should be CVMX_IO_SEG */
18134 + uint64_t mem_region:2;
18135 + /* Must be zero */
18136 + uint64_t reserved_49_61:13;
18137 + /* Must be one */
18138 + uint64_t is_io:1;
18139 + /* the ID of POW -- did<2:0> == 1 in this case */
18140 + uint64_t did:8;
18141 + /* Must be zero */
18142 + uint64_t reserved_10_39:30;
18143 + /* The core id to get status for */
18144 + uint64_t coreid:4;
18145 + /*
18146 + * If set and get_cur is set, return reverse tag-list
18147 + * pointer rather than forward tag-list pointer.
18148 + */
18149 + uint64_t get_rev:1;
18150 + /*
18151 + * If set, return current status rather than pending
18152 + * status.
18153 + */
18154 + uint64_t get_cur:1;
18155 + /*
18156 + * If set, get the work-queue pointer rather than
18157 + * tag/type.
18158 + */
18159 + uint64_t get_wqp:1;
18160 + /* Must be zero */
18161 + uint64_t reserved_0_2:3;
18162 + } sstatus;
18163 +
18164 + /**
18165 + * Address for memory loads to get POW internal state
18166 + */
18167 + struct {
18168 + /* Mips64 address region. Should be CVMX_IO_SEG */
18169 + uint64_t mem_region:2;
18170 + /* Must be zero */
18171 + uint64_t reserved_49_61:13;
18172 + /* Must be one */
18173 + uint64_t is_io:1;
18174 + /* the ID of POW -- did<2:0> == 2 in this case */
18175 + uint64_t did:8;
18176 + /* Must be zero */
18177 + uint64_t reserved_16_39:24;
18178 + /* POW memory index */
18179 + uint64_t index:11;
18180 + /*
18181 + * If set, return deschedule information rather than
18182 + * the standard response for work-queue index (invalid
18183 + * if the work-queue entry is not on the deschedule
18184 + * list).
18185 + */
18186 + uint64_t get_des:1;
18187 + /*
18188 + * If set, get the work-queue pointer rather than
18189 + * tag/type (no effect when get_des set).
18190 + */
18191 + uint64_t get_wqp:1;
18192 + /* Must be zero */
18193 + uint64_t reserved_0_2:3;
18194 + } smemload;
18195 +
18196 + /**
18197 + * Address for index/pointer loads
18198 + */
18199 + struct {
18200 + /* Mips64 address region. Should be CVMX_IO_SEG */
18201 + uint64_t mem_region:2;
18202 + /* Must be zero */
18203 + uint64_t reserved_49_61:13;
18204 + /* Must be one */
18205 + uint64_t is_io:1;
18206 + /* the ID of POW -- did<2:0> == 3 in this case */
18207 + uint64_t did:8;
18208 + /* Must be zero */
18209 + uint64_t reserved_9_39:31;
18210 + /*
18211 + * when {get_rmt ==0 AND get_des_get_tail == 0}, this
18212 + * field selects one of eight POW internal-input
18213 + * queues (0-7), one per QOS level; values 8-15 are
18214 + * illegal in this case; when {get_rmt ==0 AND
18215 + * get_des_get_tail == 1}, this field selects one of
18216 + * 16 deschedule lists (per group); when get_rmt ==1,
18217 + * this field selects one of 16 memory-input queue
18218 + * lists. The two memory-input queue lists associated
18219 + * with each QOS level are:
18220 + *
18221 + * - qosgrp = 0, qosgrp = 8: QOS0
18222 + * - qosgrp = 1, qosgrp = 9: QOS1
18223 + * - qosgrp = 2, qosgrp = 10: QOS2
18224 + * - qosgrp = 3, qosgrp = 11: QOS3
18225 + * - qosgrp = 4, qosgrp = 12: QOS4
18226 + * - qosgrp = 5, qosgrp = 13: QOS5
18227 + * - qosgrp = 6, qosgrp = 14: QOS6
18228 + * - qosgrp = 7, qosgrp = 15: QOS7
18229 + */
18230 + uint64_t qosgrp:4;
18231 + /*
18232 + * If set and get_rmt is clear, return deschedule list
18233 + * indexes rather than indexes for the specified qos
18234 + * level; if set and get_rmt is set, return the tail
18235 + * pointer rather than the head pointer for the
18236 + * specified qos level.
18237 + */
18238 + uint64_t get_des_get_tail:1;
18239 + /*
18240 + * If set, return remote pointers rather than the
18241 + * local indexes for the specified qos level.
18242 + */
18243 + uint64_t get_rmt:1;
18244 + /* Must be zero */
18245 + uint64_t reserved_0_2:3;
18246 + } sindexload;
18247 +
18248 + /**
18249 + * address for NULL_RD request (did<2:0> == 4) when this is read,
18250 + * HW attempts to change the state to NULL if it is NULL_NULL (the
18251 + * hardware cannot switch from NULL_NULL to NULL if a POW entry is
18252 + * not available - software may need to recover by finishing
18253 + * another piece of work before a POW entry can ever become
18254 + * available.)
18255 + */
18256 + struct {
18257 + /* Mips64 address region. Should be CVMX_IO_SEG */
18258 + uint64_t mem_region:2;
18259 + /* Must be zero */
18260 + uint64_t reserved_49_61:13;
18261 + /* Must be one */
18262 + uint64_t is_io:1;
18263 + /* the ID of POW -- did<2:0> == 4 in this case */
18264 + uint64_t did:8;
18265 + /* Must be zero */
18266 + uint64_t reserved_0_39:40;
18267 + } snull_rd;
18268 +} cvmx_pow_load_addr_t;
18269 +
18270 +/**
18271 + * This structure defines the response to a load/SENDSINGLE to POW
18272 + * (except CSR reads)
18273 + */
18274 +typedef union {
18275 + uint64_t u64;
18276 +
18277 + /**
18278 + * Response to new work request loads
18279 + */
18280 + struct {
18281 + /*
18282 + * Set when no new work queue entry was returned. *
18283 + * If there was de-scheduled work, the HW will
18284 + * definitely return it. When this bit is set, it
18285 + * could mean either mean:
18286 + *
18287 + * - There was no work, or
18288 + *
18289 + * - There was no work that the HW could find. This
18290 + * case can happen, regardless of the wait bit value
18291 + * in the original request, when there is work in
18292 + * the IQ's that is too deep down the list.
18293 + */
18294 + uint64_t no_work:1;
18295 + /* Must be zero */
18296 + uint64_t reserved_40_62:23;
18297 + /* 36 in O1 -- the work queue pointer */
18298 + uint64_t addr:40;
18299 + } s_work;
18300 +
18301 + /**
18302 + * Result for a POW Status Load (when get_cur==0 and get_wqp==0)
18303 + */
18304 + struct {
18305 + uint64_t reserved_62_63:2;
18306 + /* Set when there is a pending non-NULL SWTAG or
18307 + * SWTAG_FULL, and the POW entry has not left the list
18308 + * for the original tag. */
18309 + uint64_t pend_switch:1;
18310 + /* Set when SWTAG_FULL and pend_switch is set. */
18311 + uint64_t pend_switch_full:1;
18312 + /*
18313 + * Set when there is a pending NULL SWTAG, or an
18314 + * implicit switch to NULL.
18315 + */
18316 + uint64_t pend_switch_null:1;
18317 + /* Set when there is a pending DESCHED or SWTAG_DESCHED. */
18318 + uint64_t pend_desched:1;
18319 + /*
18320 + * Set when there is a pending SWTAG_DESCHED and
18321 + * pend_desched is set.
18322 + */
18323 + uint64_t pend_desched_switch:1;
18324 + /* Set when nosched is desired and pend_desched is set. */
18325 + uint64_t pend_nosched:1;
18326 + /* Set when there is a pending GET_WORK. */
18327 + uint64_t pend_new_work:1;
18328 + /*
18329 + * When pend_new_work is set, this bit indicates that
18330 + * the wait bit was set.
18331 + */
18332 + uint64_t pend_new_work_wait:1;
18333 + /* Set when there is a pending NULL_RD. */
18334 + uint64_t pend_null_rd:1;
18335 + /* Set when there is a pending CLR_NSCHED. */
18336 + uint64_t pend_nosched_clr:1;
18337 + uint64_t reserved_51:1;
18338 + /* This is the index when pend_nosched_clr is set. */
18339 + uint64_t pend_index:11;
18340 + /*
18341 + * This is the new_grp when (pend_desched AND
18342 + * pend_desched_switch) is set.
18343 + */
18344 + uint64_t pend_grp:4;
18345 + uint64_t reserved_34_35:2;
18346 + /*
18347 + * This is the tag type when pend_switch or
18348 + * (pend_desched AND pend_desched_switch) are set.
18349 + */
18350 + uint64_t pend_type:2;
18351 + /*
18352 + * - this is the tag when pend_switch or (pend_desched
18353 + * AND pend_desched_switch) are set.
18354 + */
18355 + uint64_t pend_tag:32;
18356 + } s_sstatus0;
18357 +
18358 + /**
18359 + * Result for a POW Status Load (when get_cur==0 and get_wqp==1)
18360 + */
18361 + struct {
18362 + uint64_t reserved_62_63:2;
18363 + /*
18364 + * Set when there is a pending non-NULL SWTAG or
18365 + * SWTAG_FULL, and the POW entry has not left the list
18366 + * for the original tag.
18367 + */
18368 + uint64_t pend_switch:1;
18369 + /* Set when SWTAG_FULL and pend_switch is set. */
18370 + uint64_t pend_switch_full:1;
18371 + /*
18372 + * Set when there is a pending NULL SWTAG, or an
18373 + * implicit switch to NULL.
18374 + */
18375 + uint64_t pend_switch_null:1;
18376 + /*
18377 + * Set when there is a pending DESCHED or
18378 + * SWTAG_DESCHED.
18379 + */
18380 + uint64_t pend_desched:1;
18381 + /*
18382 + * Set when there is a pending SWTAG_DESCHED and
18383 + * pend_desched is set.
18384 + */
18385 + uint64_t pend_desched_switch:1;
18386 + /* Set when nosched is desired and pend_desched is set. */
18387 + uint64_t pend_nosched:1;
18388 + /* Set when there is a pending GET_WORK. */
18389 + uint64_t pend_new_work:1;
18390 + /*
18391 + * When pend_new_work is set, this bit indicates that
18392 + * the wait bit was set.
18393 + */
18394 + uint64_t pend_new_work_wait:1;
18395 + /* Set when there is a pending NULL_RD. */
18396 + uint64_t pend_null_rd:1;
18397 + /* Set when there is a pending CLR_NSCHED. */
18398 + uint64_t pend_nosched_clr:1;
18399 + uint64_t reserved_51:1;
18400 + /* This is the index when pend_nosched_clr is set. */
18401 + uint64_t pend_index:11;
18402 + /*
18403 + * This is the new_grp when (pend_desched AND
18404 + * pend_desched_switch) is set.
18405 + */
18406 + uint64_t pend_grp:4;
18407 + /* This is the wqp when pend_nosched_clr is set. */
18408 + uint64_t pend_wqp:36;
18409 + } s_sstatus1;
18410 +
18411 + /**
18412 + * Result for a POW Status Load (when get_cur==1, get_wqp==0, and
18413 + * get_rev==0)
18414 + */
18415 + struct {
18416 + uint64_t reserved_62_63:2;
18417 + /*
18418 + * Points to the next POW entry in the tag list when
18419 + * tail == 0 (and tag_type is not NULL or NULL_NULL).
18420 + */
18421 + uint64_t link_index:11;
18422 + /* The POW entry attached to the core. */
18423 + uint64_t index:11;
18424 + /*
18425 + * The group attached to the core (updated when new
18426 + * tag list entered on SWTAG_FULL).
18427 + */
18428 + uint64_t grp:4;
18429 + /*
18430 + * Set when this POW entry is at the head of its tag
18431 + * list (also set when in the NULL or NULL_NULL
18432 + * state).
18433 + */
18434 + uint64_t head:1;
18435 + /*
18436 + * Set when this POW entry is at the tail of its tag
18437 + * list (also set when in the NULL or NULL_NULL
18438 + * state).
18439 + */
18440 + uint64_t tail:1;
18441 + /*
18442 + * The tag type attached to the core (updated when new
18443 + * tag list entered on SWTAG, SWTAG_FULL, or
18444 + * SWTAG_DESCHED).
18445 + */
18446 + uint64_t tag_type:2;
18447 + /*
18448 + * The tag attached to the core (updated when new tag
18449 + * list entered on SWTAG, SWTAG_FULL, or
18450 + * SWTAG_DESCHED).
18451 + */
18452 + uint64_t tag:32;
18453 + } s_sstatus2;
18454 +
18455 + /**
18456 + * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1)
18457 + */
18458 + struct {
18459 + uint64_t reserved_62_63:2;
18460 + /*
18461 + * Points to the prior POW entry in the tag list when
18462 + * head == 0 (and tag_type is not NULL or
18463 + * NULL_NULL). This field is unpredictable when the
18464 + * core's state is NULL or NULL_NULL.
18465 + */
18466 + uint64_t revlink_index:11;
18467 + /* The POW entry attached to the core. */
18468 + uint64_t index:11;
18469 + /*
18470 + * The group attached to the core (updated when new
18471 + * tag list entered on SWTAG_FULL).
18472 + */
18473 + uint64_t grp:4;
18474 + /* Set when this POW entry is at the head of its tag
18475 + * list (also set when in the NULL or NULL_NULL
18476 + * state).
18477 + */
18478 + uint64_t head:1;
18479 + /*
18480 + * Set when this POW entry is at the tail of its tag
18481 + * list (also set when in the NULL or NULL_NULL
18482 + * state).
18483 + */
18484 + uint64_t tail:1;
18485 + /*
18486 + * The tag type attached to the core (updated when new
18487 + * tag list entered on SWTAG, SWTAG_FULL, or
18488 + * SWTAG_DESCHED).
18489 + */
18490 + uint64_t tag_type:2;
18491 + /*
18492 + * The tag attached to the core (updated when new tag
18493 + * list entered on SWTAG, SWTAG_FULL, or
18494 + * SWTAG_DESCHED).
18495 + */
18496 + uint64_t tag:32;
18497 + } s_sstatus3;
18498 +
18499 + /**
18500 + * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
18501 + * get_rev==0)
18502 + */
18503 + struct {
18504 + uint64_t reserved_62_63:2;
18505 + /*
18506 + * Points to the next POW entry in the tag list when
18507 + * tail == 0 (and tag_type is not NULL or NULL_NULL).
18508 + */
18509 + uint64_t link_index:11;
18510 + /* The POW entry attached to the core. */
18511 + uint64_t index:11;
18512 + /*
18513 + * The group attached to the core (updated when new
18514 + * tag list entered on SWTAG_FULL).
18515 + */
18516 + uint64_t grp:4;
18517 + /*
18518 + * The wqp attached to the core (updated when new tag
18519 + * list entered on SWTAG_FULL).
18520 + */
18521 + uint64_t wqp:36;
18522 + } s_sstatus4;
18523 +
18524 + /**
18525 + * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
18526 + * get_rev==1)
18527 + */
18528 + struct {
18529 + uint64_t reserved_62_63:2;
18530 + /*
18531 + * Points to the prior POW entry in the tag list when
18532 + * head == 0 (and tag_type is not NULL or
18533 + * NULL_NULL). This field is unpredictable when the
18534 + * core's state is NULL or NULL_NULL.
18535 + */
18536 + uint64_t revlink_index:11;
18537 + /* The POW entry attached to the core. */
18538 + uint64_t index:11;
18539 + /*
18540 + * The group attached to the core (updated when new
18541 + * tag list entered on SWTAG_FULL).
18542 + */
18543 + uint64_t grp:4;
18544 + /*
18545 + * The wqp attached to the core (updated when new tag
18546 + * list entered on SWTAG_FULL).
18547 + */
18548 + uint64_t wqp:36;
18549 + } s_sstatus5;
18550 +
18551 + /**
18552 + * Result For POW Memory Load (get_des == 0 and get_wqp == 0)
18553 + */
18554 + struct {
18555 + uint64_t reserved_51_63:13;
18556 + /*
18557 + * The next entry in the input, free, descheduled_head
18558 + * list (unpredictable if entry is the tail of the
18559 + * list).
18560 + */
18561 + uint64_t next_index:11;
18562 + /* The group of the POW entry. */
18563 + uint64_t grp:4;
18564 + uint64_t reserved_35:1;
18565 + /*
18566 + * Set when this POW entry is at the tail of its tag
18567 + * list (also set when in the NULL or NULL_NULL
18568 + * state).
18569 + */
18570 + uint64_t tail:1;
18571 + /* The tag type of the POW entry. */
18572 + uint64_t tag_type:2;
18573 + /* The tag of the POW entry. */
18574 + uint64_t tag:32;
18575 + } s_smemload0;
18576 +
18577 + /**
18578 + * Result For POW Memory Load (get_des == 0 and get_wqp == 1)
18579 + */
18580 + struct {
18581 + uint64_t reserved_51_63:13;
18582 + /*
18583 + * The next entry in the input, free, descheduled_head
18584 + * list (unpredictable if entry is the tail of the
18585 + * list).
18586 + */
18587 + uint64_t next_index:11;
18588 + /* The group of the POW entry. */
18589 + uint64_t grp:4;
18590 + /* The WQP held in the POW entry. */
18591 + uint64_t wqp:36;
18592 + } s_smemload1;
18593 +
18594 + /**
18595 + * Result For POW Memory Load (get_des == 1)
18596 + */
18597 + struct {
18598 + uint64_t reserved_51_63:13;
18599 + /*
18600 + * The next entry in the tag list connected to the
18601 + * descheduled head.
18602 + */
18603 + uint64_t fwd_index:11;
18604 + /* The group of the POW entry. */
18605 + uint64_t grp:4;
18606 + /* The nosched bit for the POW entry. */
18607 + uint64_t nosched:1;
18608 + /* There is a pending tag switch */
18609 + uint64_t pend_switch:1;
18610 + /*
18611 + * The next tag type for the new tag list when
18612 + * pend_switch is set.
18613 + */
18614 + uint64_t pend_type:2;
18615 + /*
18616 + * The next tag for the new tag list when pend_switch
18617 + * is set.
18618 + */
18619 + uint64_t pend_tag:32;
18620 + } s_smemload2;
18621 +
18622 + /**
18623 + * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0)
18624 + */
18625 + struct {
18626 + uint64_t reserved_52_63:12;
18627 + /*
18628 + * set when there is one or more POW entries on the
18629 + * free list.
18630 + */
18631 + uint64_t free_val:1;
18632 + /*
18633 + * set when there is exactly one POW entry on the free
18634 + * list.
18635 + */
18636 + uint64_t free_one:1;
18637 + uint64_t reserved_49:1;
18638 + /*
18639 + * when free_val is set, indicates the first entry on
18640 + * the free list.
18641 + */
18642 + uint64_t free_head:11;
18643 + uint64_t reserved_37:1;
18644 + /*
18645 + * when free_val is set, indicates the last entry on
18646 + * the free list.
18647 + */
18648 + uint64_t free_tail:11;
18649 + /*
18650 + * set when there is one or more POW entries on the
18651 + * input Q list selected by qosgrp.
18652 + */
18653 + uint64_t loc_val:1;
18654 + /*
18655 + * set when there is exactly one POW entry on the
18656 + * input Q list selected by qosgrp.
18657 + */
18658 + uint64_t loc_one:1;
18659 + uint64_t reserved_23:1;
18660 + /*
18661 + * when loc_val is set, indicates the first entry on
18662 + * the input Q list selected by qosgrp.
18663 + */
18664 + uint64_t loc_head:11;
18665 + uint64_t reserved_11:1;
18666 + /*
18667 + * when loc_val is set, indicates the last entry on
18668 + * the input Q list selected by qosgrp.
18669 + */
18670 + uint64_t loc_tail:11;
18671 + } sindexload0;
18672 +
18673 + /**
18674 + * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1)
18675 + */
18676 + struct {
18677 + uint64_t reserved_52_63:12;
18678 + /*
18679 + * set when there is one or more POW entries on the
18680 + * nosched list.
18681 + */
18682 + uint64_t nosched_val:1;
18683 + /*
18684 + * set when there is exactly one POW entry on the
18685 + * nosched list.
18686 + */
18687 + uint64_t nosched_one:1;
18688 + uint64_t reserved_49:1;
18689 + /*
18690 + * when nosched_val is set, indicates the first entry
18691 + * on the nosched list.
18692 + */
18693 + uint64_t nosched_head:11;
18694 + uint64_t reserved_37:1;
18695 + /*
18696 + * when nosched_val is set, indicates the last entry
18697 + * on the nosched list.
18698 + */
18699 + uint64_t nosched_tail:11;
18700 + /*
18701 + * set when there is one or more descheduled heads on
18702 + * the descheduled list selected by qosgrp.
18703 + */
18704 + uint64_t des_val:1;
18705 + /*
18706 + * set when there is exactly one descheduled head on
18707 + * the descheduled list selected by qosgrp.
18708 + */
18709 + uint64_t des_one:1;
18710 + uint64_t reserved_23:1;
18711 + /*
18712 + * when des_val is set, indicates the first
18713 + * descheduled head on the descheduled list selected
18714 + * by qosgrp.
18715 + */
18716 + uint64_t des_head:11;
18717 + uint64_t reserved_11:1;
18718 + /*
18719 + * when des_val is set, indicates the last descheduled
18720 + * head on the descheduled list selected by qosgrp.
18721 + */
18722 + uint64_t des_tail:11;
18723 + } sindexload1;
18724 +
18725 + /**
18726 + * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0)
18727 + */
18728 + struct {
18729 + uint64_t reserved_39_63:25;
18730 + /*
18731 + * Set when this DRAM list is the current head
18732 + * (i.e. is the next to be reloaded when the POW
18733 + * hardware reloads a POW entry from DRAM). The POW
18734 + * hardware alternates between the two DRAM lists
18735 + * associated with a QOS level when it reloads work
18736 + * from DRAM into the POW unit.
18737 + */
18738 + uint64_t rmt_is_head:1;
18739 + /*
18740 + * Set when the DRAM portion of the input Q list
18741 + * selected by qosgrp contains one or more pieces of
18742 + * work.
18743 + */
18744 + uint64_t rmt_val:1;
18745 + /*
18746 + * Set when the DRAM portion of the input Q list
18747 + * selected by qosgrp contains exactly one piece of
18748 + * work.
18749 + */
18750 + uint64_t rmt_one:1;
18751 + /*
18752 + * When rmt_val is set, indicates the first piece of
18753 + * work on the DRAM input Q list selected by
18754 + * qosgrp.
18755 + */
18756 + uint64_t rmt_head:36;
18757 + } sindexload2;
18758 +
18759 + /**
18760 + * Result For POW Index/Pointer Load (get_rmt ==
18761 + * 1/get_des_get_tail == 1)
18762 + */
18763 + struct {
18764 + uint64_t reserved_39_63:25;
18765 + /*
18766 + * set when this DRAM list is the current head
18767 + * (i.e. is the next to be reloaded when the POW
18768 + * hardware reloads a POW entry from DRAM). The POW
18769 + * hardware alternates between the two DRAM lists
18770 + * associated with a QOS level when it reloads work
18771 + * from DRAM into the POW unit.
18772 + */
18773 + uint64_t rmt_is_head:1;
18774 + /*
18775 + * set when the DRAM portion of the input Q list
18776 + * selected by qosgrp contains one or more pieces of
18777 + * work.
18778 + */
18779 + uint64_t rmt_val:1;
18780 + /*
18781 + * set when the DRAM portion of the input Q list
18782 + * selected by qosgrp contains exactly one piece of
18783 + * work.
18784 + */
18785 + uint64_t rmt_one:1;
18786 + /*
18787 + * when rmt_val is set, indicates the last piece of
18788 + * work on the DRAM input Q list selected by
18789 + * qosgrp.
18790 + */
18791 + uint64_t rmt_tail:36;
18792 + } sindexload3;
18793 +
18794 + /**
18795 + * Response to NULL_RD request loads
18796 + */
18797 + struct {
18798 + uint64_t unused:62;
18799 + /* of type cvmx_pow_tag_type_t. state is one of the
18800 + * following:
18801 + *
18802 + * - CVMX_POW_TAG_TYPE_ORDERED
18803 + * - CVMX_POW_TAG_TYPE_ATOMIC
18804 + * - CVMX_POW_TAG_TYPE_NULL
18805 + * - CVMX_POW_TAG_TYPE_NULL_NULL
18806 + */
18807 + uint64_t state:2;
18808 + } s_null_rd;
18809 +
18810 +} cvmx_pow_tag_load_resp_t;
18811 +
18812 +/**
18813 + * This structure describes the address used for stores to the POW.
18814 + * The store address is meaningful on stores to the POW. The
18815 + * hardware assumes that an aligned 64-bit store was used for all
18816 + * these stores. Note the assumption that the work queue entry is
18817 + * aligned on an 8-byte boundary (since the low-order 3 address bits
18818 + * must be zero). Note that not all fields are used by all
18819 + * operations.
18820 + *
18821 + * NOTE: The following is the behavior of the pending switch bit at the PP
18822 + * for POW stores (i.e. when did<7:3> == 0xc)
18823 + * - did<2:0> == 0 => pending switch bit is set
18824 + * - did<2:0> == 1 => no affect on the pending switch bit
18825 + * - did<2:0> == 3 => pending switch bit is cleared
18826 + * - did<2:0> == 7 => no affect on the pending switch bit
18827 + * - did<2:0> == others => must not be used
18828 + * - No other loads/stores have an affect on the pending switch bit
18829 + * - The switch bus from POW can clear the pending switch bit
18830 + *
18831 + * NOTE: did<2:0> == 2 is used by the HW for a special single-cycle
18832 + * ADDWQ command that only contains the pointer). SW must never use
18833 + * did<2:0> == 2.
18834 + */
18835 +typedef union {
18836 + /**
18837 + * Unsigned 64 bit integer representation of store address
18838 + */
18839 + uint64_t u64;
18840 +
18841 + struct {
18842 + /* Memory region. Should be CVMX_IO_SEG in most cases */
18843 + uint64_t mem_reg:2;
18844 + uint64_t reserved_49_61:13; /* Must be zero */
18845 + uint64_t is_io:1; /* Must be one */
18846 + /* Device ID of POW. Note that different sub-dids are used. */
18847 + uint64_t did:8;
18848 + uint64_t reserved_36_39:4; /* Must be zero */
18849 + /* Address field. addr<2:0> must be zero */
18850 + uint64_t addr:36;
18851 + } stag;
18852 +} cvmx_pow_tag_store_addr_t;
18853 +
18854 +/**
18855 + * decode of the store data when an IOBDMA SENDSINGLE is sent to POW
18856 + */
18857 +typedef union {
18858 + uint64_t u64;
18859 +
18860 + struct {
18861 + /*
18862 + * the (64-bit word) location in scratchpad to write
18863 + * to (if len != 0)
18864 + */
18865 + uint64_t scraddr:8;
18866 + /* the number of words in the response (0 => no response) */
18867 + uint64_t len:8;
18868 + /* the ID of the device on the non-coherent bus */
18869 + uint64_t did:8;
18870 + uint64_t unused:36;
18871 + /* if set, don't return load response until work is available */
18872 + uint64_t wait:1;
18873 + uint64_t unused2:3;
18874 + } s;
18875 +
18876 +} cvmx_pow_iobdma_store_t;
18877 +
18878 +/* CSR typedefs have been moved to cvmx-csr-*.h */
18879 +
18880 +/**
18881 + * Get the POW tag for this core. This returns the current
18882 + * tag type, tag, group, and POW entry index associated with
18883 + * this core. Index is only valid if the tag type isn't NULL_NULL.
18884 + * If a tag switch is pending this routine returns the tag before
18885 + * the tag switch, not after.
18886 + *
18887 + * Returns Current tag
18888 + */
18889 +static inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void)
18890 +{
18891 + cvmx_pow_load_addr_t load_addr;
18892 + cvmx_pow_tag_load_resp_t load_resp;
18893 + cvmx_pow_tag_req_t result;
18894 +
18895 + load_addr.u64 = 0;
18896 + load_addr.sstatus.mem_region = CVMX_IO_SEG;
18897 + load_addr.sstatus.is_io = 1;
18898 + load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
18899 + load_addr.sstatus.coreid = cvmx_get_core_num();
18900 + load_addr.sstatus.get_cur = 1;
18901 + load_resp.u64 = cvmx_read_csr(load_addr.u64);
18902 + result.u64 = 0;
18903 + result.s.grp = load_resp.s_sstatus2.grp;
18904 + result.s.index = load_resp.s_sstatus2.index;
18905 + result.s.type = load_resp.s_sstatus2.tag_type;
18906 + result.s.tag = load_resp.s_sstatus2.tag;
18907 + return result;
18908 +}
18909 +
18910 +/**
18911 + * Get the POW WQE for this core. This returns the work queue
18912 + * entry currently associated with this core.
18913 + *
18914 + * Returns WQE pointer
18915 + */
18916 +static inline cvmx_wqe_t *cvmx_pow_get_current_wqp(void)
18917 +{
18918 + cvmx_pow_load_addr_t load_addr;
18919 + cvmx_pow_tag_load_resp_t load_resp;
18920 +
18921 + load_addr.u64 = 0;
18922 + load_addr.sstatus.mem_region = CVMX_IO_SEG;
18923 + load_addr.sstatus.is_io = 1;
18924 + load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
18925 + load_addr.sstatus.coreid = cvmx_get_core_num();
18926 + load_addr.sstatus.get_cur = 1;
18927 + load_addr.sstatus.get_wqp = 1;
18928 + load_resp.u64 = cvmx_read_csr(load_addr.u64);
18929 + return (cvmx_wqe_t *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp);
18930 +}
18931 +
18932 +#ifndef CVMX_MF_CHORD
18933 +#define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30)
18934 +#endif
18935 +
18936 +/**
18937 + * Print a warning if a tag switch is pending for this core
18938 + *
18939 + * @function: Function name checking for a pending tag switch
18940 + */
18941 +static inline void __cvmx_pow_warn_if_pending_switch(const char *function)
18942 +{
18943 + uint64_t switch_complete;
18944 + CVMX_MF_CHORD(switch_complete);
18945 + if (!switch_complete)
18946 + pr_warning("%s called with tag switch in progress\n", function);
18947 +}
18948 +
18949 +/**
18950 + * Waits for a tag switch to complete by polling the completion bit.
18951 + * Note that switches to NULL complete immediately and do not need
18952 + * to be waited for.
18953 + */
18954 +static inline void cvmx_pow_tag_sw_wait(void)
18955 +{
18956 + const uint64_t MAX_CYCLES = 1ull << 31;
18957 + uint64_t switch_complete;
18958 + uint64_t start_cycle = cvmx_get_cycle();
18959 + while (1) {
18960 + CVMX_MF_CHORD(switch_complete);
18961 + if (unlikely(switch_complete))
18962 + break;
18963 + if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) {
18964 + pr_warning("Tag switch is taking a long time, "
18965 + "possible deadlock\n");
18966 + start_cycle = -MAX_CYCLES - 1;
18967 + }
18968 + }
18969 +}
18970 +
18971 +/**
18972 + * Synchronous work request. Requests work from the POW.
18973 + * This function does NOT wait for previous tag switches to complete,
18974 + * so the caller must ensure that there is not a pending tag switch.
18975 + *
18976 + * @wait: When set, call stalls until work becomes avaiable, or times out.
18977 + * If not set, returns immediately.
18978 + *
18979 + * Returns Returns the WQE pointer from POW. Returns NULL if no work
18980 + * was available.
18981 + */
18982 +static inline cvmx_wqe_t *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t
18983 + wait)
18984 +{
18985 + cvmx_pow_load_addr_t ptr;
18986 + cvmx_pow_tag_load_resp_t result;
18987 +
18988 + if (CVMX_ENABLE_POW_CHECKS)
18989 + __cvmx_pow_warn_if_pending_switch(__func__);
18990 +
18991 + ptr.u64 = 0;
18992 + ptr.swork.mem_region = CVMX_IO_SEG;
18993 + ptr.swork.is_io = 1;
18994 + ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG;
18995 + ptr.swork.wait = wait;
18996 +
18997 + result.u64 = cvmx_read_csr(ptr.u64);
18998 +
18999 + if (result.s_work.no_work)
19000 + return NULL;
19001 + else
19002 + return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
19003 +}
19004 +
19005 +/**
19006 + * Synchronous work request. Requests work from the POW.
19007 + * This function waits for any previous tag switch to complete before
19008 + * requesting the new work.
19009 + *
19010 + * @wait: When set, call stalls until work becomes avaiable, or times out.
19011 + * If not set, returns immediately.
19012 + *
19013 + * Returns Returns the WQE pointer from POW. Returns NULL if no work
19014 + * was available.
19015 + */
19016 +static inline cvmx_wqe_t *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
19017 +{
19018 + if (CVMX_ENABLE_POW_CHECKS)
19019 + __cvmx_pow_warn_if_pending_switch(__func__);
19020 +
19021 + /* Must not have a switch pending when requesting work */
19022 + cvmx_pow_tag_sw_wait();
19023 + return cvmx_pow_work_request_sync_nocheck(wait);
19024 +
19025 +}
19026 +
19027 +/**
19028 + * Synchronous null_rd request. Requests a switch out of NULL_NULL POW state.
19029 + * This function waits for any previous tag switch to complete before
19030 + * requesting the null_rd.
19031 + *
19032 + * Returns Returns the POW state of type cvmx_pow_tag_type_t.
19033 + */
19034 +static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void)
19035 +{
19036 + cvmx_pow_load_addr_t ptr;
19037 + cvmx_pow_tag_load_resp_t result;
19038 +
19039 + if (CVMX_ENABLE_POW_CHECKS)
19040 + __cvmx_pow_warn_if_pending_switch(__func__);
19041 +
19042 + /* Must not have a switch pending when requesting work */
19043 + cvmx_pow_tag_sw_wait();
19044 +
19045 + ptr.u64 = 0;
19046 + ptr.snull_rd.mem_region = CVMX_IO_SEG;
19047 + ptr.snull_rd.is_io = 1;
19048 + ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD;
19049 +
19050 + result.u64 = cvmx_read_csr(ptr.u64);
19051 +
19052 + return (enum cvmx_pow_tag_type) result.s_null_rd.state;
19053 +}
19054 +
19055 +/**
19056 + * Asynchronous work request. Work is requested from the POW unit,
19057 + * and should later be checked with function
19058 + * cvmx_pow_work_response_async. This function does NOT wait for
19059 + * previous tag switches to complete, so the caller must ensure that
19060 + * there is not a pending tag switch.
19061 + *
19062 + * @scr_addr: Scratch memory address that response will be returned
19063 + * to, which is either a valid WQE, or a response with the
19064 + * invalid bit set. Byte address, must be 8 byte aligned.
19065 + *
19066 + * @wait: 1 to cause response to wait for work to become available (or
19067 + * timeout), 0 to cause response to return immediately
19068 + */
19069 +static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
19070 + cvmx_pow_wait_t wait)
19071 +{
19072 + cvmx_pow_iobdma_store_t data;
19073 +
19074 + if (CVMX_ENABLE_POW_CHECKS)
19075 + __cvmx_pow_warn_if_pending_switch(__func__);
19076 +
19077 + /* scr_addr must be 8 byte aligned */
19078 + data.s.scraddr = scr_addr >> 3;
19079 + data.s.len = 1;
19080 + data.s.did = CVMX_OCT_DID_TAG_SWTAG;
19081 + data.s.wait = wait;
19082 + cvmx_send_single(data.u64);
19083 +}
19084 +
19085 +/**
19086 + * Asynchronous work request. Work is requested from the POW unit,
19087 + * and should later be checked with function
19088 + * cvmx_pow_work_response_async. This function waits for any previous
19089 + * tag switch to complete before requesting the new work.
19090 + *
19091 + * @scr_addr: Scratch memory address that response will be returned
19092 + * to, which is either a valid WQE, or a response with the
19093 + * invalid bit set. Byte address, must be 8 byte aligned.
19094 + *
19095 + * @wait: 1 to cause response to wait for work to become available (or
19096 + * timeout), 0 to cause response to return immediately
19097 + */
19098 +static inline void cvmx_pow_work_request_async(int scr_addr,
19099 + cvmx_pow_wait_t wait)
19100 +{
19101 + if (CVMX_ENABLE_POW_CHECKS)
19102 + __cvmx_pow_warn_if_pending_switch(__func__);
19103 +
19104 + /* Must not have a switch pending when requesting work */
19105 + cvmx_pow_tag_sw_wait();
19106 + cvmx_pow_work_request_async_nocheck(scr_addr, wait);
19107 +}
19108 +
19109 +/**
19110 + * Gets result of asynchronous work request. Performs a IOBDMA sync
19111 + * to wait for the response.
19112 + *
19113 + * @scr_addr: Scratch memory address to get result from Byte address,
19114 + * must be 8 byte aligned.
19115 + *
19116 + * Returns Returns the WQE from the scratch register, or NULL if no
19117 + * work was available.
19118 + */
19119 +static inline cvmx_wqe_t *cvmx_pow_work_response_async(int scr_addr)
19120 +{
19121 + cvmx_pow_tag_load_resp_t result;
19122 +
19123 + CVMX_SYNCIOBDMA;
19124 + result.u64 = cvmx_scratch_read64(scr_addr);
19125 +
19126 + if (result.s_work.no_work)
19127 + return NULL;
19128 + else
19129 + return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
19130 +}
19131 +
19132 +/**
19133 + * Checks if a work queue entry pointer returned by a work
19134 + * request is valid. It may be invalid due to no work
19135 + * being available or due to a timeout.
19136 + *
19137 + * @wqe_ptr: pointer to a work queue entry returned by the POW
19138 + *
19139 + * Returns 0 if pointer is valid
19140 + * 1 if invalid (no work was returned)
19141 + */
19142 +static inline uint64_t cvmx_pow_work_invalid(cvmx_wqe_t *wqe_ptr)
19143 +{
19144 + return wqe_ptr == NULL;
19145 +}
19146 +
19147 +/**
19148 + * Starts a tag switch to the provided tag value and tag type.
19149 + * Completion for the tag switch must be checked for separately. This
19150 + * function does NOT update the work queue entry in dram to match tag
19151 + * value and type, so the application must keep track of these if they
19152 + * are important to the application. This tag switch command must not
19153 + * be used for switches to NULL, as the tag switch pending bit will be
19154 + * set by the switch request, but never cleared by the hardware.
19155 + *
19156 + * NOTE: This should not be used when switching from a NULL tag. Use
19157 + * cvmx_pow_tag_sw_full() instead.
19158 + *
19159 + * This function does no checks, so the caller must ensure that any
19160 + * previous tag switch has completed.
19161 + *
19162 + * @tag: new tag value
19163 + * @tag_type: new tag type (ordered or atomic)
19164 + */
19165 +static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag,
19166 + enum cvmx_pow_tag_type tag_type)
19167 +{
19168 + cvmx_addr_t ptr;
19169 + cvmx_pow_tag_req_t tag_req;
19170 +
19171 + if (CVMX_ENABLE_POW_CHECKS) {
19172 + cvmx_pow_tag_req_t current_tag;
19173 + __cvmx_pow_warn_if_pending_switch(__func__);
19174 + current_tag = cvmx_pow_get_current_tag();
19175 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19176 + pr_warning("%s called with NULL_NULL tag\n",
19177 + __func__);
19178 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19179 + pr_warning("%s called with NULL tag\n", __func__);
19180 + if ((current_tag.s.type == tag_type)
19181 + && (current_tag.s.tag == tag))
19182 + pr_warning("%s called to perform a tag switch to the "
19183 + "same tag\n",
19184 + __func__);
19185 + if (tag_type == CVMX_POW_TAG_TYPE_NULL)
19186 + pr_warning("%s called to perform a tag switch to "
19187 + "NULL. Use cvmx_pow_tag_sw_null() instead\n",
19188 + __func__);
19189 + }
19190 +
19191 + /*
19192 + * Note that WQE in DRAM is not updated here, as the POW does
19193 + * not read from DRAM once the WQE is in flight. See hardware
19194 + * manual for complete details. It is the application's
19195 + * responsibility to keep track of the current tag value if
19196 + * that is important.
19197 + */
19198 +
19199 + tag_req.u64 = 0;
19200 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
19201 + tag_req.s.tag = tag;
19202 + tag_req.s.type = tag_type;
19203 +
19204 + ptr.u64 = 0;
19205 + ptr.sio.mem_region = CVMX_IO_SEG;
19206 + ptr.sio.is_io = 1;
19207 + ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
19208 +
19209 + /* once this store arrives at POW, it will attempt the switch
19210 + software must wait for the switch to complete separately */
19211 + cvmx_write_io(ptr.u64, tag_req.u64);
19212 +}
19213 +
19214 +/**
19215 + * Starts a tag switch to the provided tag value and tag type.
19216 + * Completion for the tag switch must be checked for separately. This
19217 + * function does NOT update the work queue entry in dram to match tag
19218 + * value and type, so the application must keep track of these if they
19219 + * are important to the application. This tag switch command must not
19220 + * be used for switches to NULL, as the tag switch pending bit will be
19221 + * set by the switch request, but never cleared by the hardware.
19222 + *
19223 + * NOTE: This should not be used when switching from a NULL tag. Use
19224 + * cvmx_pow_tag_sw_full() instead.
19225 + *
19226 + * This function waits for any previous tag switch to complete, and also
19227 + * displays an error on tag switches to NULL.
19228 + *
19229 + * @tag: new tag value
19230 + * @tag_type: new tag type (ordered or atomic)
19231 + */
19232 +static inline void cvmx_pow_tag_sw(uint32_t tag,
19233 + enum cvmx_pow_tag_type tag_type)
19234 +{
19235 + if (CVMX_ENABLE_POW_CHECKS)
19236 + __cvmx_pow_warn_if_pending_switch(__func__);
19237 +
19238 + /*
19239 + * Note that WQE in DRAM is not updated here, as the POW does
19240 + * not read from DRAM once the WQE is in flight. See hardware
19241 + * manual for complete details. It is the application's
19242 + * responsibility to keep track of the current tag value if
19243 + * that is important.
19244 + */
19245 +
19246 + /*
19247 + * Ensure that there is not a pending tag switch, as a tag
19248 + * switch cannot be started if a previous switch is still
19249 + * pending.
19250 + */
19251 + cvmx_pow_tag_sw_wait();
19252 + cvmx_pow_tag_sw_nocheck(tag, tag_type);
19253 +}
19254 +
19255 +/**
19256 + * Starts a tag switch to the provided tag value and tag type.
19257 + * Completion for the tag switch must be checked for separately. This
19258 + * function does NOT update the work queue entry in dram to match tag
19259 + * value and type, so the application must keep track of these if they
19260 + * are important to the application. This tag switch command must not
19261 + * be used for switches to NULL, as the tag switch pending bit will be
19262 + * set by the switch request, but never cleared by the hardware.
19263 + *
19264 + * This function must be used for tag switches from NULL.
19265 + *
19266 + * This function does no checks, so the caller must ensure that any
19267 + * previous tag switch has completed.
19268 + *
19269 + * @wqp: pointer to work queue entry to submit. This entry is
19270 + * updated to match the other parameters
19271 + * @tag: tag value to be assigned to work queue entry
19272 + * @tag_type: type of tag
19273 + * @group: group value for the work queue entry.
19274 + */
19275 +static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag,
19276 + enum cvmx_pow_tag_type tag_type,
19277 + uint64_t group)
19278 +{
19279 + cvmx_addr_t ptr;
19280 + cvmx_pow_tag_req_t tag_req;
19281 +
19282 + if (CVMX_ENABLE_POW_CHECKS) {
19283 + cvmx_pow_tag_req_t current_tag;
19284 + __cvmx_pow_warn_if_pending_switch(__func__);
19285 + current_tag = cvmx_pow_get_current_tag();
19286 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19287 + pr_warning("%s called with NULL_NULL tag\n",
19288 + __func__);
19289 + if ((current_tag.s.type == tag_type)
19290 + && (current_tag.s.tag == tag))
19291 + pr_warning("%s called to perform a tag switch to "
19292 + "the same tag\n",
19293 + __func__);
19294 + if (tag_type == CVMX_POW_TAG_TYPE_NULL)
19295 + pr_warning("%s called to perform a tag switch to "
19296 + "NULL. Use cvmx_pow_tag_sw_null() instead\n",
19297 + __func__);
19298 + if (wqp != cvmx_phys_to_ptr(0x80))
19299 + if (wqp != cvmx_pow_get_current_wqp())
19300 + pr_warning("%s passed WQE(%p) doesn't match "
19301 + "the address in the POW(%p)\n",
19302 + __func__, wqp,
19303 + cvmx_pow_get_current_wqp());
19304 + }
19305 +
19306 + /*
19307 + * Note that WQE in DRAM is not updated here, as the POW does
19308 + * not read from DRAM once the WQE is in flight. See hardware
19309 + * manual for complete details. It is the application's
19310 + * responsibility to keep track of the current tag value if
19311 + * that is important.
19312 + */
19313 +
19314 + tag_req.u64 = 0;
19315 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL;
19316 + tag_req.s.tag = tag;
19317 + tag_req.s.type = tag_type;
19318 + tag_req.s.grp = group;
19319 +
19320 + ptr.u64 = 0;
19321 + ptr.sio.mem_region = CVMX_IO_SEG;
19322 + ptr.sio.is_io = 1;
19323 + ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
19324 + ptr.sio.offset = CAST64(wqp);
19325 +
19326 + /*
19327 + * once this store arrives at POW, it will attempt the switch
19328 + * software must wait for the switch to complete separately.
19329 + */
19330 + cvmx_write_io(ptr.u64, tag_req.u64);
19331 +}
19332 +
19333 +/**
19334 + * Starts a tag switch to the provided tag value and tag type.
19335 + * Completion for the tag switch must be checked for separately. This
19336 + * function does NOT update the work queue entry in dram to match tag
19337 + * value and type, so the application must keep track of these if they
19338 + * are important to the application. This tag switch command must not
19339 + * be used for switches to NULL, as the tag switch pending bit will be
19340 + * set by the switch request, but never cleared by the hardware.
19341 + *
19342 + * This function must be used for tag switches from NULL.
19343 + *
19344 + * This function waits for any pending tag switches to complete
19345 + * before requesting the tag switch.
19346 + *
19347 + * @wqp: pointer to work queue entry to submit. This entry is updated
19348 + * to match the other parameters
19349 + * @tag: tag value to be assigned to work queue entry
19350 + * @tag_type: type of tag
19351 + * @group: group value for the work queue entry.
19352 + */
19353 +static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag,
19354 + enum cvmx_pow_tag_type tag_type,
19355 + uint64_t group)
19356 +{
19357 + if (CVMX_ENABLE_POW_CHECKS)
19358 + __cvmx_pow_warn_if_pending_switch(__func__);
19359 +
19360 + /*
19361 + * Ensure that there is not a pending tag switch, as a tag
19362 + * switch cannot be started if a previous switch is still
19363 + * pending.
19364 + */
19365 + cvmx_pow_tag_sw_wait();
19366 + cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group);
19367 +}
19368 +
19369 +/**
19370 + * Switch to a NULL tag, which ends any ordering or
19371 + * synchronization provided by the POW for the current
19372 + * work queue entry. This operation completes immediatly,
19373 + * so completetion should not be waited for.
19374 + * This function does NOT wait for previous tag switches to complete,
19375 + * so the caller must ensure that any previous tag switches have completed.
19376 + */
19377 +static inline void cvmx_pow_tag_sw_null_nocheck(void)
19378 +{
19379 + cvmx_addr_t ptr;
19380 + cvmx_pow_tag_req_t tag_req;
19381 +
19382 + if (CVMX_ENABLE_POW_CHECKS) {
19383 + cvmx_pow_tag_req_t current_tag;
19384 + __cvmx_pow_warn_if_pending_switch(__func__);
19385 + current_tag = cvmx_pow_get_current_tag();
19386 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19387 + pr_warning("%s called with NULL_NULL tag\n",
19388 + __func__);
19389 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19390 + pr_warning("%s called when we already have a "
19391 + "NULL tag\n",
19392 + __func__);
19393 + }
19394 +
19395 + tag_req.u64 = 0;
19396 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
19397 + tag_req.s.type = CVMX_POW_TAG_TYPE_NULL;
19398 +
19399 + ptr.u64 = 0;
19400 + ptr.sio.mem_region = CVMX_IO_SEG;
19401 + ptr.sio.is_io = 1;
19402 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
19403 +
19404 + cvmx_write_io(ptr.u64, tag_req.u64);
19405 +
19406 + /* switch to NULL completes immediately */
19407 +}
19408 +
19409 +/**
19410 + * Switch to a NULL tag, which ends any ordering or
19411 + * synchronization provided by the POW for the current
19412 + * work queue entry. This operation completes immediatly,
19413 + * so completetion should not be waited for.
19414 + * This function waits for any pending tag switches to complete
19415 + * before requesting the switch to NULL.
19416 + */
19417 +static inline void cvmx_pow_tag_sw_null(void)
19418 +{
19419 + if (CVMX_ENABLE_POW_CHECKS)
19420 + __cvmx_pow_warn_if_pending_switch(__func__);
19421 +
19422 + /*
19423 + * Ensure that there is not a pending tag switch, as a tag
19424 + * switch cannot be started if a previous switch is still
19425 + * pending.
19426 + */
19427 + cvmx_pow_tag_sw_wait();
19428 + cvmx_pow_tag_sw_null_nocheck();
19429 +
19430 + /* switch to NULL completes immediately */
19431 +}
19432 +
19433 +/**
19434 + * Submits work to an input queue. This function updates the work
19435 + * queue entry in DRAM to match the arguments given. Note that the
19436 + * tag provided is for the work queue entry submitted, and is
19437 + * unrelated to the tag that the core currently holds.
19438 + *
19439 + * @wqp: pointer to work queue entry to submit. This entry is
19440 + * updated to match the other parameters
19441 + * @tag: tag value to be assigned to work queue entry
19442 + * @tag_type: type of tag
19443 + * @qos: Input queue to add to.
19444 + * @grp: group value for the work queue entry.
19445 + */
19446 +static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag,
19447 + enum cvmx_pow_tag_type tag_type,
19448 + uint64_t qos, uint64_t grp)
19449 +{
19450 + cvmx_addr_t ptr;
19451 + cvmx_pow_tag_req_t tag_req;
19452 +
19453 + wqp->qos = qos;
19454 + wqp->tag = tag;
19455 + wqp->tag_type = tag_type;
19456 + wqp->grp = grp;
19457 +
19458 + tag_req.u64 = 0;
19459 + tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ;
19460 + tag_req.s.type = tag_type;
19461 + tag_req.s.tag = tag;
19462 + tag_req.s.qos = qos;
19463 + tag_req.s.grp = grp;
19464 +
19465 + ptr.u64 = 0;
19466 + ptr.sio.mem_region = CVMX_IO_SEG;
19467 + ptr.sio.is_io = 1;
19468 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
19469 + ptr.sio.offset = cvmx_ptr_to_phys(wqp);
19470 +
19471 + /*
19472 + * SYNC write to memory before the work submit. This is
19473 + * necessary as POW may read values from DRAM at this time.
19474 + */
19475 + CVMX_SYNCWS;
19476 + cvmx_write_io(ptr.u64, tag_req.u64);
19477 +}
19478 +
19479 +/**
19480 + * This function sets the group mask for a core. The group mask
19481 + * indicates which groups each core will accept work from. There are
19482 + * 16 groups.
19483 + *
19484 + * @core_num: core to apply mask to
19485 + * @mask: Group mask. There are 16 groups, so only bits 0-15 are valid,
19486 + * representing groups 0-15.
19487 + * Each 1 bit in the mask enables the core to accept work from
19488 + * the corresponding group.
19489 + */
19490 +static inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask)
19491 +{
19492 + union cvmx_pow_pp_grp_mskx grp_msk;
19493 +
19494 + grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
19495 + grp_msk.s.grp_msk = mask;
19496 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
19497 +}
19498 +
19499 +/**
19500 + * This function sets POW static priorities for a core. Each input queue has
19501 + * an associated priority value.
19502 + *
19503 + * @core_num: core to apply priorities to
19504 + * @priority: Vector of 8 priorities, one per POW Input Queue (0-7).
19505 + * Highest priority is 0 and lowest is 7. A priority value
19506 + * of 0xF instructs POW to skip the Input Queue when
19507 + * scheduling to this specific core.
19508 + * NOTE: priorities should not have gaps in values, meaning
19509 + * {0,1,1,1,1,1,1,1} is a valid configuration while
19510 + * {0,2,2,2,2,2,2,2} is not.
19511 + */
19512 +static inline void cvmx_pow_set_priority(uint64_t core_num,
19513 + const uint8_t priority[])
19514 +{
19515 + /* POW priorities are supported on CN5xxx and later */
19516 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
19517 + union cvmx_pow_pp_grp_mskx grp_msk;
19518 +
19519 + grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
19520 + grp_msk.s.qos0_pri = priority[0];
19521 + grp_msk.s.qos1_pri = priority[1];
19522 + grp_msk.s.qos2_pri = priority[2];
19523 + grp_msk.s.qos3_pri = priority[3];
19524 + grp_msk.s.qos4_pri = priority[4];
19525 + grp_msk.s.qos5_pri = priority[5];
19526 + grp_msk.s.qos6_pri = priority[6];
19527 + grp_msk.s.qos7_pri = priority[7];
19528 +
19529 + /* Detect gaps between priorities and flag error */
19530 + {
19531 + int i;
19532 + uint32_t prio_mask = 0;
19533 +
19534 + for (i = 0; i < 8; i++)
19535 + if (priority[i] != 0xF)
19536 + prio_mask |= 1 << priority[i];
19537 +
19538 + if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) {
19539 + pr_err("POW static priorities should be "
19540 + "contiguous (0x%llx)\n",
19541 + (unsigned long long)prio_mask);
19542 + return;
19543 + }
19544 + }
19545 +
19546 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
19547 + }
19548 +}
19549 +
19550 +/**
19551 + * Performs a tag switch and then an immediate deschedule. This completes
19552 + * immediatly, so completion must not be waited for. This function does NOT
19553 + * update the wqe in DRAM to match arguments.
19554 + *
19555 + * This function does NOT wait for any prior tag switches to complete, so the
19556 + * calling code must do this.
19557 + *
19558 + * Note the following CAVEAT of the Octeon HW behavior when
19559 + * re-scheduling DE-SCHEDULEd items whose (next) state is
19560 + * ORDERED:
19561 + * - If there are no switches pending at the time that the
19562 + * HW executes the de-schedule, the HW will only re-schedule
19563 + * the head of the FIFO associated with the given tag. This
19564 + * means that in many respects, the HW treats this ORDERED
19565 + * tag as an ATOMIC tag. Note that in the SWTAG_DESCH
19566 + * case (to an ORDERED tag), the HW will do the switch
19567 + * before the deschedule whenever it is possible to do
19568 + * the switch immediately, so it may often look like
19569 + * this case.
19570 + * - If there is a pending switch to ORDERED at the time
19571 + * the HW executes the de-schedule, the HW will perform
19572 + * the switch at the time it re-schedules, and will be
19573 + * able to reschedule any/all of the entries with the
19574 + * same tag.
19575 + * Due to this behavior, the RECOMMENDATION to software is
19576 + * that they have a (next) state of ATOMIC when they
19577 + * DE-SCHEDULE. If an ORDERED tag is what was really desired,
19578 + * SW can choose to immediately switch to an ORDERED tag
19579 + * after the work (that has an ATOMIC tag) is re-scheduled.
19580 + * Note that since there are never any tag switches pending
19581 + * when the HW re-schedules, this switch can be IMMEDIATE upon
19582 + * the reception of the pointer during the re-schedule.
19583 + *
19584 + * @tag: New tag value
19585 + * @tag_type: New tag type
19586 + * @group: New group value
19587 + * @no_sched: Control whether this work queue entry will be rescheduled.
19588 + * - 1 : don't schedule this work
19589 + * - 0 : allow this work to be scheduled.
19590 + */
19591 +static inline void cvmx_pow_tag_sw_desched_nocheck(
19592 + uint32_t tag,
19593 + enum cvmx_pow_tag_type tag_type,
19594 + uint64_t group,
19595 + uint64_t no_sched)
19596 +{
19597 + cvmx_addr_t ptr;
19598 + cvmx_pow_tag_req_t tag_req;
19599 +
19600 + if (CVMX_ENABLE_POW_CHECKS) {
19601 + cvmx_pow_tag_req_t current_tag;
19602 + __cvmx_pow_warn_if_pending_switch(__func__);
19603 + current_tag = cvmx_pow_get_current_tag();
19604 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19605 + pr_warning("%s called with NULL_NULL tag\n",
19606 + __func__);
19607 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19608 + pr_warning("%s called with NULL tag. Deschedule not "
19609 + "allowed from NULL state\n",
19610 + __func__);
19611 + if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC)
19612 + && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC))
19613 + pr_warning("%s called where neither the before or "
19614 + "after tag is ATOMIC\n",
19615 + __func__);
19616 + }
19617 +
19618 + tag_req.u64 = 0;
19619 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH;
19620 + tag_req.s.tag = tag;
19621 + tag_req.s.type = tag_type;
19622 + tag_req.s.grp = group;
19623 + tag_req.s.no_sched = no_sched;
19624 +
19625 + ptr.u64 = 0;
19626 + ptr.sio.mem_region = CVMX_IO_SEG;
19627 + ptr.sio.is_io = 1;
19628 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
19629 + /*
19630 + * since TAG3 is used, this store will clear the local pending
19631 + * switch bit.
19632 + */
19633 + cvmx_write_io(ptr.u64, tag_req.u64);
19634 +}
19635 +
19636 +/**
19637 + * Performs a tag switch and then an immediate deschedule. This completes
19638 + * immediatly, so completion must not be waited for. This function does NOT
19639 + * update the wqe in DRAM to match arguments.
19640 + *
19641 + * This function waits for any prior tag switches to complete, so the
19642 + * calling code may call this function with a pending tag switch.
19643 + *
19644 + * Note the following CAVEAT of the Octeon HW behavior when
19645 + * re-scheduling DE-SCHEDULEd items whose (next) state is
19646 + * ORDERED:
19647 + * - If there are no switches pending at the time that the
19648 + * HW executes the de-schedule, the HW will only re-schedule
19649 + * the head of the FIFO associated with the given tag. This
19650 + * means that in many respects, the HW treats this ORDERED
19651 + * tag as an ATOMIC tag. Note that in the SWTAG_DESCH
19652 + * case (to an ORDERED tag), the HW will do the switch
19653 + * before the deschedule whenever it is possible to do
19654 + * the switch immediately, so it may often look like
19655 + * this case.
19656 + * - If there is a pending switch to ORDERED at the time
19657 + * the HW executes the de-schedule, the HW will perform
19658 + * the switch at the time it re-schedules, and will be
19659 + * able to reschedule any/all of the entries with the
19660 + * same tag.
19661 + * Due to this behavior, the RECOMMENDATION to software is
19662 + * that they have a (next) state of ATOMIC when they
19663 + * DE-SCHEDULE. If an ORDERED tag is what was really desired,
19664 + * SW can choose to immediately switch to an ORDERED tag
19665 + * after the work (that has an ATOMIC tag) is re-scheduled.
19666 + * Note that since there are never any tag switches pending
19667 + * when the HW re-schedules, this switch can be IMMEDIATE upon
19668 + * the reception of the pointer during the re-schedule.
19669 + *
19670 + * @tag: New tag value
19671 + * @tag_type: New tag type
19672 + * @group: New group value
19673 + * @no_sched: Control whether this work queue entry will be rescheduled.
19674 + * - 1 : don't schedule this work
19675 + * - 0 : allow this work to be scheduled.
19676 + */
19677 +static inline void cvmx_pow_tag_sw_desched(uint32_t tag,
19678 + enum cvmx_pow_tag_type tag_type,
19679 + uint64_t group, uint64_t no_sched)
19680 +{
19681 + if (CVMX_ENABLE_POW_CHECKS)
19682 + __cvmx_pow_warn_if_pending_switch(__func__);
19683 +
19684 + /* Need to make sure any writes to the work queue entry are complete */
19685 + CVMX_SYNCWS;
19686 + /*
19687 + * Ensure that there is not a pending tag switch, as a tag
19688 + * switch cannot be started if a previous switch is still
19689 + * pending.
19690 + */
19691 + cvmx_pow_tag_sw_wait();
19692 + cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched);
19693 +}
19694 +
19695 +/**
19696 + * Descchedules the current work queue entry.
19697 + *
19698 + * @no_sched: no schedule flag value to be set on the work queue
19699 + * entry. If this is set the entry will not be
19700 + * rescheduled.
19701 + */
19702 +static inline void cvmx_pow_desched(uint64_t no_sched)
19703 +{
19704 + cvmx_addr_t ptr;
19705 + cvmx_pow_tag_req_t tag_req;
19706 +
19707 + if (CVMX_ENABLE_POW_CHECKS) {
19708 + cvmx_pow_tag_req_t current_tag;
19709 + __cvmx_pow_warn_if_pending_switch(__func__);
19710 + current_tag = cvmx_pow_get_current_tag();
19711 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19712 + pr_warning("%s called with NULL_NULL tag\n",
19713 + __func__);
19714 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19715 + pr_warning("%s called with NULL tag. Deschedule not "
19716 + "expected from NULL state\n",
19717 + __func__);
19718 + }
19719 +
19720 + /* Need to make sure any writes to the work queue entry are complete */
19721 + CVMX_SYNCWS;
19722 +
19723 + tag_req.u64 = 0;
19724 + tag_req.s.op = CVMX_POW_TAG_OP_DESCH;
19725 + tag_req.s.no_sched = no_sched;
19726 +
19727 + ptr.u64 = 0;
19728 + ptr.sio.mem_region = CVMX_IO_SEG;
19729 + ptr.sio.is_io = 1;
19730 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
19731 + /*
19732 + * since TAG3 is used, this store will clear the local pending
19733 + * switch bit.
19734 + */
19735 + cvmx_write_io(ptr.u64, tag_req.u64);
19736 +}
19737 +
19738 +/****************************************************
19739 +* Define usage of bits within the 32 bit tag values.
19740 +*****************************************************/
19741 +
19742 +/*
19743 + * Number of bits of the tag used by software. The SW bits are always
19744 + * a contiguous block of the high starting at bit 31. The hardware
19745 + * bits are always the low bits. By default, the top 8 bits of the
19746 + * tag are reserved for software, and the low 24 are set by the IPD
19747 + * unit.
19748 + */
19749 +#define CVMX_TAG_SW_BITS (8)
19750 +#define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS)
19751 +
19752 +/* Below is the list of values for the top 8 bits of the tag. */
19753 +/*
19754 + * Tag values with top byte of this value are reserved for internal
19755 + * executive uses.
19756 + */
19757 +#define CVMX_TAG_SW_BITS_INTERNAL 0x1
19758 +/* The executive divides the remaining 24 bits as follows:
19759 + * - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup
19760 + *
19761 + * - the lower 16 bits (bits 15 - 0 of the tag) define are the value
19762 + * with the subgroup
19763 + *
19764 + * Note that this section describes the format of tags generated by
19765 + * software - refer to the hardware documentation for a description of
19766 + * the tags values generated by the packet input hardware. Subgroups
19767 + * are defined here.
19768 + */
19769 +/* Mask for the value portion of the tag */
19770 +#define CVMX_TAG_SUBGROUP_MASK 0xFFFF
19771 +#define CVMX_TAG_SUBGROUP_SHIFT 16
19772 +#define CVMX_TAG_SUBGROUP_PKO 0x1
19773 +
19774 +/* End of executive tag subgroup definitions */
19775 +
19776 +/*
19777 + * The remaining values software bit values 0x2 - 0xff are available
19778 + * for application use.
19779 + */
19780 +
19781 +/**
19782 + * This function creates a 32 bit tag value from the two values provided.
19783 + *
19784 + * @sw_bits: The upper bits (number depends on configuration) are set
19785 + * to this value. The remainder of bits are set by the
19786 + * hw_bits parameter.
19787 + *
19788 + * @hw_bits: The lower bits (number depends on configuration) are set
19789 + * to this value. The remainder of bits are set by the
19790 + * sw_bits parameter.
19791 + *
19792 + * Returns 32 bit value of the combined hw and sw bits.
19793 + */
19794 +static inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits)
19795 +{
19796 + return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) <<
19797 + CVMX_TAG_SW_SHIFT) |
19798 + (hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS));
19799 +}
19800 +
19801 +/**
19802 + * Extracts the bits allocated for software use from the tag
19803 + *
19804 + * @tag: 32 bit tag value
19805 + *
19806 + * Returns N bit software tag value, where N is configurable with the
19807 + * CVMX_TAG_SW_BITS define
19808 + */
19809 +static inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag)
19810 +{
19811 + return (tag >> (32 - CVMX_TAG_SW_BITS)) &
19812 + cvmx_build_mask(CVMX_TAG_SW_BITS);
19813 +}
19814 +
19815 +/**
19816 + *
19817 + * Extracts the bits allocated for hardware use from the tag
19818 + *
19819 + * @tag: 32 bit tag value
19820 + *
19821 + * Returns (32 - N) bit software tag value, where N is configurable
19822 + * with the CVMX_TAG_SW_BITS define
19823 + */
19824 +static inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag)
19825 +{
19826 + return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS);
19827 +}
19828 +
19829 +/**
19830 + * Store the current POW internal state into the supplied
19831 + * buffer. It is recommended that you pass a buffer of at least
19832 + * 128KB. The format of the capture may change based on SDK
19833 + * version and Octeon chip.
19834 + *
19835 + * @buffer: Buffer to store capture into
19836 + * @buffer_size:
19837 + * The size of the supplied buffer
19838 + *
19839 + * Returns Zero on sucess, negative on failure
19840 + */
19841 +extern int cvmx_pow_capture(void *buffer, int buffer_size);
19842 +
19843 +/**
19844 + * Dump a POW capture to the console in a human readable format.
19845 + *
19846 + * @buffer: POW capture from cvmx_pow_capture()
19847 + * @buffer_size:
19848 + * Size of the buffer
19849 + */
19850 +extern void cvmx_pow_display(void *buffer, int buffer_size);
19851 +
19852 +/**
19853 + * Return the number of POW entries supported by this chip
19854 + *
19855 + * Returns Number of POW entries
19856 + */
19857 +extern int cvmx_pow_get_num_entries(void);
19858 +
19859 +#endif /* __CVMX_POW_H__ */
19860 --- /dev/null
19861 +++ b/drivers/staging/octeon/cvmx-scratch.h
19862 @@ -0,0 +1,139 @@
19863 +/***********************license start***************
19864 + * Author: Cavium Networks
19865 + *
19866 + * Contact: support@caviumnetworks.com
19867 + * This file is part of the OCTEON SDK
19868 + *
19869 + * Copyright (c) 2003-2008 Cavium Networks
19870 + *
19871 + * This file is free software; you can redistribute it and/or modify
19872 + * it under the terms of the GNU General Public License, Version 2, as
19873 + * published by the Free Software Foundation.
19874 + *
19875 + * This file is distributed in the hope that it will be useful, but
19876 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
19877 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
19878 + * NONINFRINGEMENT. See the GNU General Public License for more
19879 + * details.
19880 + *
19881 + * You should have received a copy of the GNU General Public License
19882 + * along with this file; if not, write to the Free Software
19883 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19884 + * or visit http://www.gnu.org/licenses/.
19885 + *
19886 + * This file may also be available under a different license from Cavium.
19887 + * Contact Cavium Networks for more information
19888 + ***********************license end**************************************/
19889 +
19890 +/**
19891 + *
19892 + * This file provides support for the processor local scratch memory.
19893 + * Scratch memory is byte addressable - all addresses are byte addresses.
19894 + *
19895 + */
19896 +
19897 +#ifndef __CVMX_SCRATCH_H__
19898 +#define __CVMX_SCRATCH_H__
19899 +
19900 +/*
19901 + * Note: This define must be a long, not a long long in order to
19902 + * compile without warnings for both 32bit and 64bit.
19903 + */
19904 +#define CVMX_SCRATCH_BASE (-32768l) /* 0xffffffffffff8000 */
19905 +
19906 +/**
19907 + * Reads an 8 bit value from the processor local scratchpad memory.
19908 + *
19909 + * @address: byte address to read from
19910 + *
19911 + * Returns value read
19912 + */
19913 +static inline uint8_t cvmx_scratch_read8(uint64_t address)
19914 +{
19915 + return *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address);
19916 +}
19917 +
19918 +/**
19919 + * Reads a 16 bit value from the processor local scratchpad memory.
19920 + *
19921 + * @address: byte address to read from
19922 + *
19923 + * Returns value read
19924 + */
19925 +static inline uint16_t cvmx_scratch_read16(uint64_t address)
19926 +{
19927 + return *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address);
19928 +}
19929 +
19930 +/**
19931 + * Reads a 32 bit value from the processor local scratchpad memory.
19932 + *
19933 + * @address: byte address to read from
19934 + *
19935 + * Returns value read
19936 + */
19937 +static inline uint32_t cvmx_scratch_read32(uint64_t address)
19938 +{
19939 + return *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address);
19940 +}
19941 +
19942 +/**
19943 + * Reads a 64 bit value from the processor local scratchpad memory.
19944 + *
19945 + * @address: byte address to read from
19946 + *
19947 + * Returns value read
19948 + */
19949 +static inline uint64_t cvmx_scratch_read64(uint64_t address)
19950 +{
19951 + return *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address);
19952 +}
19953 +
19954 +/**
19955 + * Writes an 8 bit value to the processor local scratchpad memory.
19956 + *
19957 + * @address: byte address to write to
19958 + * @value: value to write
19959 + */
19960 +static inline void cvmx_scratch_write8(uint64_t address, uint64_t value)
19961 +{
19962 + *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address) =
19963 + (uint8_t) value;
19964 +}
19965 +
19966 +/**
19967 + * Writes a 32 bit value to the processor local scratchpad memory.
19968 + *
19969 + * @address: byte address to write to
19970 + * @value: value to write
19971 + */
19972 +static inline void cvmx_scratch_write16(uint64_t address, uint64_t value)
19973 +{
19974 + *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address) =
19975 + (uint16_t) value;
19976 +}
19977 +
19978 +/**
19979 + * Writes a 16 bit value to the processor local scratchpad memory.
19980 + *
19981 + * @address: byte address to write to
19982 + * @value: value to write
19983 + */
19984 +static inline void cvmx_scratch_write32(uint64_t address, uint64_t value)
19985 +{
19986 + *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address) =
19987 + (uint32_t) value;
19988 +}
19989 +
19990 +/**
19991 + * Writes a 64 bit value to the processor local scratchpad memory.
19992 + *
19993 + * @address: byte address to write to
19994 + * @value: value to write
19995 + */
19996 +static inline void cvmx_scratch_write64(uint64_t address, uint64_t value)
19997 +{
19998 + *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address) = value;
19999 +}
20000 +
20001 +#endif /* __CVMX_SCRATCH_H__ */
20002 --- /dev/null
20003 +++ b/drivers/staging/octeon/cvmx-smix-defs.h
20004 @@ -0,0 +1,178 @@
20005 +/***********************license start***************
20006 + * Author: Cavium Networks
20007 + *
20008 + * Contact: support@caviumnetworks.com
20009 + * This file is part of the OCTEON SDK
20010 + *
20011 + * Copyright (c) 2003-2008 Cavium Networks
20012 + *
20013 + * This file is free software; you can redistribute it and/or modify
20014 + * it under the terms of the GNU General Public License, Version 2, as
20015 + * published by the Free Software Foundation.
20016 + *
20017 + * This file is distributed in the hope that it will be useful, but
20018 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20019 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20020 + * NONINFRINGEMENT. See the GNU General Public License for more
20021 + * details.
20022 + *
20023 + * You should have received a copy of the GNU General Public License
20024 + * along with this file; if not, write to the Free Software
20025 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20026 + * or visit http://www.gnu.org/licenses/.
20027 + *
20028 + * This file may also be available under a different license from Cavium.
20029 + * Contact Cavium Networks for more information
20030 + ***********************license end**************************************/
20031 +
20032 +#ifndef __CVMX_SMIX_DEFS_H__
20033 +#define __CVMX_SMIX_DEFS_H__
20034 +
20035 +#define CVMX_SMIX_CLK(offset) \
20036 + CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
20037 +#define CVMX_SMIX_CMD(offset) \
20038 + CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
20039 +#define CVMX_SMIX_EN(offset) \
20040 + CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
20041 +#define CVMX_SMIX_RD_DAT(offset) \
20042 + CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
20043 +#define CVMX_SMIX_WR_DAT(offset) \
20044 + CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
20045 +
20046 +union cvmx_smix_clk {
20047 + uint64_t u64;
20048 + struct cvmx_smix_clk_s {
20049 + uint64_t reserved_25_63:39;
20050 + uint64_t mode:1;
20051 + uint64_t reserved_21_23:3;
20052 + uint64_t sample_hi:5;
20053 + uint64_t sample_mode:1;
20054 + uint64_t reserved_14_14:1;
20055 + uint64_t clk_idle:1;
20056 + uint64_t preamble:1;
20057 + uint64_t sample:4;
20058 + uint64_t phase:8;
20059 + } s;
20060 + struct cvmx_smix_clk_cn30xx {
20061 + uint64_t reserved_21_63:43;
20062 + uint64_t sample_hi:5;
20063 + uint64_t reserved_14_15:2;
20064 + uint64_t clk_idle:1;
20065 + uint64_t preamble:1;
20066 + uint64_t sample:4;
20067 + uint64_t phase:8;
20068 + } cn30xx;
20069 + struct cvmx_smix_clk_cn30xx cn31xx;
20070 + struct cvmx_smix_clk_cn30xx cn38xx;
20071 + struct cvmx_smix_clk_cn30xx cn38xxp2;
20072 + struct cvmx_smix_clk_cn50xx {
20073 + uint64_t reserved_25_63:39;
20074 + uint64_t mode:1;
20075 + uint64_t reserved_21_23:3;
20076 + uint64_t sample_hi:5;
20077 + uint64_t reserved_14_15:2;
20078 + uint64_t clk_idle:1;
20079 + uint64_t preamble:1;
20080 + uint64_t sample:4;
20081 + uint64_t phase:8;
20082 + } cn50xx;
20083 + struct cvmx_smix_clk_s cn52xx;
20084 + struct cvmx_smix_clk_cn50xx cn52xxp1;
20085 + struct cvmx_smix_clk_s cn56xx;
20086 + struct cvmx_smix_clk_cn50xx cn56xxp1;
20087 + struct cvmx_smix_clk_cn30xx cn58xx;
20088 + struct cvmx_smix_clk_cn30xx cn58xxp1;
20089 +};
20090 +
20091 +union cvmx_smix_cmd {
20092 + uint64_t u64;
20093 + struct cvmx_smix_cmd_s {
20094 + uint64_t reserved_18_63:46;
20095 + uint64_t phy_op:2;
20096 + uint64_t reserved_13_15:3;
20097 + uint64_t phy_adr:5;
20098 + uint64_t reserved_5_7:3;
20099 + uint64_t reg_adr:5;
20100 + } s;
20101 + struct cvmx_smix_cmd_cn30xx {
20102 + uint64_t reserved_17_63:47;
20103 + uint64_t phy_op:1;
20104 + uint64_t reserved_13_15:3;
20105 + uint64_t phy_adr:5;
20106 + uint64_t reserved_5_7:3;
20107 + uint64_t reg_adr:5;
20108 + } cn30xx;
20109 + struct cvmx_smix_cmd_cn30xx cn31xx;
20110 + struct cvmx_smix_cmd_cn30xx cn38xx;
20111 + struct cvmx_smix_cmd_cn30xx cn38xxp2;
20112 + struct cvmx_smix_cmd_s cn50xx;
20113 + struct cvmx_smix_cmd_s cn52xx;
20114 + struct cvmx_smix_cmd_s cn52xxp1;
20115 + struct cvmx_smix_cmd_s cn56xx;
20116 + struct cvmx_smix_cmd_s cn56xxp1;
20117 + struct cvmx_smix_cmd_cn30xx cn58xx;
20118 + struct cvmx_smix_cmd_cn30xx cn58xxp1;
20119 +};
20120 +
20121 +union cvmx_smix_en {
20122 + uint64_t u64;
20123 + struct cvmx_smix_en_s {
20124 + uint64_t reserved_1_63:63;
20125 + uint64_t en:1;
20126 + } s;
20127 + struct cvmx_smix_en_s cn30xx;
20128 + struct cvmx_smix_en_s cn31xx;
20129 + struct cvmx_smix_en_s cn38xx;
20130 + struct cvmx_smix_en_s cn38xxp2;
20131 + struct cvmx_smix_en_s cn50xx;
20132 + struct cvmx_smix_en_s cn52xx;
20133 + struct cvmx_smix_en_s cn52xxp1;
20134 + struct cvmx_smix_en_s cn56xx;
20135 + struct cvmx_smix_en_s cn56xxp1;
20136 + struct cvmx_smix_en_s cn58xx;
20137 + struct cvmx_smix_en_s cn58xxp1;
20138 +};
20139 +
20140 +union cvmx_smix_rd_dat {
20141 + uint64_t u64;
20142 + struct cvmx_smix_rd_dat_s {
20143 + uint64_t reserved_18_63:46;
20144 + uint64_t pending:1;
20145 + uint64_t val:1;
20146 + uint64_t dat:16;
20147 + } s;
20148 + struct cvmx_smix_rd_dat_s cn30xx;
20149 + struct cvmx_smix_rd_dat_s cn31xx;
20150 + struct cvmx_smix_rd_dat_s cn38xx;
20151 + struct cvmx_smix_rd_dat_s cn38xxp2;
20152 + struct cvmx_smix_rd_dat_s cn50xx;
20153 + struct cvmx_smix_rd_dat_s cn52xx;
20154 + struct cvmx_smix_rd_dat_s cn52xxp1;
20155 + struct cvmx_smix_rd_dat_s cn56xx;
20156 + struct cvmx_smix_rd_dat_s cn56xxp1;
20157 + struct cvmx_smix_rd_dat_s cn58xx;
20158 + struct cvmx_smix_rd_dat_s cn58xxp1;
20159 +};
20160 +
20161 +union cvmx_smix_wr_dat {
20162 + uint64_t u64;
20163 + struct cvmx_smix_wr_dat_s {
20164 + uint64_t reserved_18_63:46;
20165 + uint64_t pending:1;
20166 + uint64_t val:1;
20167 + uint64_t dat:16;
20168 + } s;
20169 + struct cvmx_smix_wr_dat_s cn30xx;
20170 + struct cvmx_smix_wr_dat_s cn31xx;
20171 + struct cvmx_smix_wr_dat_s cn38xx;
20172 + struct cvmx_smix_wr_dat_s cn38xxp2;
20173 + struct cvmx_smix_wr_dat_s cn50xx;
20174 + struct cvmx_smix_wr_dat_s cn52xx;
20175 + struct cvmx_smix_wr_dat_s cn52xxp1;
20176 + struct cvmx_smix_wr_dat_s cn56xx;
20177 + struct cvmx_smix_wr_dat_s cn56xxp1;
20178 + struct cvmx_smix_wr_dat_s cn58xx;
20179 + struct cvmx_smix_wr_dat_s cn58xxp1;
20180 +};
20181 +
20182 +#endif
20183 --- /dev/null
20184 +++ b/drivers/staging/octeon/cvmx-spi.c
20185 @@ -0,0 +1,667 @@
20186 +/***********************license start***************
20187 + * Author: Cavium Networks
20188 + *
20189 + * Contact: support@caviumnetworks.com
20190 + * This file is part of the OCTEON SDK
20191 + *
20192 + * Copyright (c) 2003-2008 Cavium Networks
20193 + *
20194 + * This file is free software; you can redistribute it and/or modify
20195 + * it under the terms of the GNU General Public License, Version 2, as
20196 + * published by the Free Software Foundation.
20197 + *
20198 + * This file is distributed in the hope that it will be useful, but
20199 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20200 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20201 + * NONINFRINGEMENT. See the GNU General Public License for more
20202 + * details.
20203 + *
20204 + * You should have received a copy of the GNU General Public License
20205 + * along with this file; if not, write to the Free Software
20206 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20207 + * or visit http://www.gnu.org/licenses/.
20208 + *
20209 + * This file may also be available under a different license from Cavium.
20210 + * Contact Cavium Networks for more information
20211 + ***********************license end**************************************/
20212 +
20213 +/*
20214 + *
20215 + * Support library for the SPI
20216 + */
20217 +#include <asm/octeon/octeon.h>
20218 +
20219 +#include "cvmx-config.h"
20220 +
20221 +#include "cvmx-pko.h"
20222 +#include "cvmx-spi.h"
20223 +
20224 +#include "cvmx-spxx-defs.h"
20225 +#include "cvmx-stxx-defs.h"
20226 +#include "cvmx-srxx-defs.h"
20227 +
20228 +#define INVOKE_CB(function_p, args...) \
20229 + do { \
20230 + if (function_p) { \
20231 + res = function_p(args); \
20232 + if (res) \
20233 + return res; \
20234 + } \
20235 + } while (0)
20236 +
20237 +#if CVMX_ENABLE_DEBUG_PRINTS
20238 +static const char *modes[] =
20239 + { "UNKNOWN", "TX Halfplex", "Rx Halfplex", "Duplex" };
20240 +#endif
20241 +
20242 +/* Default callbacks, can be overridden
20243 + * using cvmx_spi_get_callbacks/cvmx_spi_set_callbacks
20244 + */
20245 +static cvmx_spi_callbacks_t cvmx_spi_callbacks = {
20246 + .reset_cb = cvmx_spi_reset_cb,
20247 + .calendar_setup_cb = cvmx_spi_calendar_setup_cb,
20248 + .clock_detect_cb = cvmx_spi_clock_detect_cb,
20249 + .training_cb = cvmx_spi_training_cb,
20250 + .calendar_sync_cb = cvmx_spi_calendar_sync_cb,
20251 + .interface_up_cb = cvmx_spi_interface_up_cb
20252 +};
20253 +
20254 +/**
20255 + * Get current SPI4 initialization callbacks
20256 + *
20257 + * @callbacks: Pointer to the callbacks structure.to fill
20258 + *
20259 + * Returns Pointer to cvmx_spi_callbacks_t structure.
20260 + */
20261 +void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks)
20262 +{
20263 + memcpy(callbacks, &cvmx_spi_callbacks, sizeof(cvmx_spi_callbacks));
20264 +}
20265 +
20266 +/**
20267 + * Set new SPI4 initialization callbacks
20268 + *
20269 + * @new_callbacks: Pointer to an updated callbacks structure.
20270 + */
20271 +void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks)
20272 +{
20273 + memcpy(&cvmx_spi_callbacks, new_callbacks, sizeof(cvmx_spi_callbacks));
20274 +}
20275 +
20276 +/**
20277 + * Initialize and start the SPI interface.
20278 + *
20279 + * @interface: The identifier of the packet interface to configure and
20280 + * use as a SPI interface.
20281 + * @mode: The operating mode for the SPI interface. The interface
20282 + * can operate as a full duplex (both Tx and Rx data paths
20283 + * active) or as a halfplex (either the Tx data path is
20284 + * active or the Rx data path is active, but not both).
20285 + * @timeout: Timeout to wait for clock synchronization in seconds
20286 + * @num_ports: Number of SPI ports to configure
20287 + *
20288 + * Returns Zero on success, negative of failure.
20289 + */
20290 +int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout,
20291 + int num_ports)
20292 +{
20293 + int res = -1;
20294 +
20295 + if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
20296 + return res;
20297 +
20298 + /* Callback to perform SPI4 reset */
20299 + INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
20300 +
20301 + /* Callback to perform calendar setup */
20302 + INVOKE_CB(cvmx_spi_callbacks.calendar_setup_cb, interface, mode,
20303 + num_ports);
20304 +
20305 + /* Callback to perform clock detection */
20306 + INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
20307 +
20308 + /* Callback to perform SPI4 link training */
20309 + INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
20310 +
20311 + /* Callback to perform calendar sync */
20312 + INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
20313 + timeout);
20314 +
20315 + /* Callback to handle interface coming up */
20316 + INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
20317 +
20318 + return res;
20319 +}
20320 +
20321 +/**
20322 + * This routine restarts the SPI interface after it has lost synchronization
20323 + * with its correspondent system.
20324 + *
20325 + * @interface: The identifier of the packet interface to configure and
20326 + * use as a SPI interface.
20327 + * @mode: The operating mode for the SPI interface. The interface
20328 + * can operate as a full duplex (both Tx and Rx data paths
20329 + * active) or as a halfplex (either the Tx data path is
20330 + * active or the Rx data path is active, but not both).
20331 + * @timeout: Timeout to wait for clock synchronization in seconds
20332 + *
20333 + * Returns Zero on success, negative of failure.
20334 + */
20335 +int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout)
20336 +{
20337 + int res = -1;
20338 +
20339 + if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
20340 + return res;
20341 +
20342 + cvmx_dprintf("SPI%d: Restart %s\n", interface, modes[mode]);
20343 +
20344 + /* Callback to perform SPI4 reset */
20345 + INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
20346 +
20347 + /* NOTE: Calendar setup is not performed during restart */
20348 + /* Refer to cvmx_spi_start_interface() for the full sequence */
20349 +
20350 + /* Callback to perform clock detection */
20351 + INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
20352 +
20353 + /* Callback to perform SPI4 link training */
20354 + INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
20355 +
20356 + /* Callback to perform calendar sync */
20357 + INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
20358 + timeout);
20359 +
20360 + /* Callback to handle interface coming up */
20361 + INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
20362 +
20363 + return res;
20364 +}
20365 +
20366 +/**
20367 + * Callback to perform SPI4 reset
20368 + *
20369 + * @interface: The identifier of the packet interface to configure and
20370 + * use as a SPI interface.
20371 + * @mode: The operating mode for the SPI interface. The interface
20372 + * can operate as a full duplex (both Tx and Rx data paths
20373 + * active) or as a halfplex (either the Tx data path is
20374 + * active or the Rx data path is active, but not both).
20375 + *
20376 + * Returns Zero on success, non-zero error code on failure (will cause
20377 + * SPI initialization to abort)
20378 + */
20379 +int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode)
20380 +{
20381 + union cvmx_spxx_dbg_deskew_ctl spxx_dbg_deskew_ctl;
20382 + union cvmx_spxx_clk_ctl spxx_clk_ctl;
20383 + union cvmx_spxx_bist_stat spxx_bist_stat;
20384 + union cvmx_spxx_int_msk spxx_int_msk;
20385 + union cvmx_stxx_int_msk stxx_int_msk;
20386 + union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
20387 + int index;
20388 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20389 +
20390 + /* Disable SPI error events while we run BIST */
20391 + spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
20392 + cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
20393 + stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
20394 + cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
20395 +
20396 + /* Run BIST in the SPI interface */
20397 + cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), 0);
20398 + cvmx_write_csr(CVMX_STXX_COM_CTL(interface), 0);
20399 + spxx_clk_ctl.u64 = 0;
20400 + spxx_clk_ctl.s.runbist = 1;
20401 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20402 + cvmx_wait(10 * MS);
20403 + spxx_bist_stat.u64 = cvmx_read_csr(CVMX_SPXX_BIST_STAT(interface));
20404 + if (spxx_bist_stat.s.stat0)
20405 + cvmx_dprintf
20406 + ("ERROR SPI%d: BIST failed on receive datapath FIFO\n",
20407 + interface);
20408 + if (spxx_bist_stat.s.stat1)
20409 + cvmx_dprintf("ERROR SPI%d: BIST failed on RX calendar table\n",
20410 + interface);
20411 + if (spxx_bist_stat.s.stat2)
20412 + cvmx_dprintf("ERROR SPI%d: BIST failed on TX calendar table\n",
20413 + interface);
20414 +
20415 + /* Clear the calendar table after BIST to fix parity errors */
20416 + for (index = 0; index < 32; index++) {
20417 + union cvmx_srxx_spi4_calx srxx_spi4_calx;
20418 + union cvmx_stxx_spi4_calx stxx_spi4_calx;
20419 +
20420 + srxx_spi4_calx.u64 = 0;
20421 + srxx_spi4_calx.s.oddpar = 1;
20422 + cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface),
20423 + srxx_spi4_calx.u64);
20424 +
20425 + stxx_spi4_calx.u64 = 0;
20426 + stxx_spi4_calx.s.oddpar = 1;
20427 + cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface),
20428 + stxx_spi4_calx.u64);
20429 + }
20430 +
20431 + /* Re enable reporting of error interrupts */
20432 + cvmx_write_csr(CVMX_SPXX_INT_REG(interface),
20433 + cvmx_read_csr(CVMX_SPXX_INT_REG(interface)));
20434 + cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
20435 + cvmx_write_csr(CVMX_STXX_INT_REG(interface),
20436 + cvmx_read_csr(CVMX_STXX_INT_REG(interface)));
20437 + cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
20438 +
20439 + /* Setup the CLKDLY right in the middle */
20440 + spxx_clk_ctl.u64 = 0;
20441 + spxx_clk_ctl.s.seetrn = 0;
20442 + spxx_clk_ctl.s.clkdly = 0x10;
20443 + spxx_clk_ctl.s.runbist = 0;
20444 + spxx_clk_ctl.s.statdrv = 0;
20445 + /* This should always be on the opposite edge as statdrv */
20446 + spxx_clk_ctl.s.statrcv = 1;
20447 + spxx_clk_ctl.s.sndtrn = 0;
20448 + spxx_clk_ctl.s.drptrn = 0;
20449 + spxx_clk_ctl.s.rcvtrn = 0;
20450 + spxx_clk_ctl.s.srxdlck = 0;
20451 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20452 + cvmx_wait(100 * MS);
20453 +
20454 + /* Reset SRX0 DLL */
20455 + spxx_clk_ctl.s.srxdlck = 1;
20456 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20457 +
20458 + /* Waiting for Inf0 Spi4 RX DLL to lock */
20459 + cvmx_wait(100 * MS);
20460 +
20461 + /* Enable dynamic alignment */
20462 + spxx_trn4_ctl.s.trntest = 0;
20463 + spxx_trn4_ctl.s.jitter = 1;
20464 + spxx_trn4_ctl.s.clr_boot = 1;
20465 + spxx_trn4_ctl.s.set_boot = 0;
20466 + if (OCTEON_IS_MODEL(OCTEON_CN58XX))
20467 + spxx_trn4_ctl.s.maxdist = 3;
20468 + else
20469 + spxx_trn4_ctl.s.maxdist = 8;
20470 + spxx_trn4_ctl.s.macro_en = 1;
20471 + spxx_trn4_ctl.s.mux_en = 1;
20472 + cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64);
20473 +
20474 + spxx_dbg_deskew_ctl.u64 = 0;
20475 + cvmx_write_csr(CVMX_SPXX_DBG_DESKEW_CTL(interface),
20476 + spxx_dbg_deskew_ctl.u64);
20477 +
20478 + return 0;
20479 +}
20480 +
20481 +/**
20482 + * Callback to setup calendar and miscellaneous settings before clock detection
20483 + *
20484 + * @interface: The identifier of the packet interface to configure and
20485 + * use as a SPI interface.
20486 + * @mode: The operating mode for the SPI interface. The interface
20487 + * can operate as a full duplex (both Tx and Rx data paths
20488 + * active) or as a halfplex (either the Tx data path is
20489 + * active or the Rx data path is active, but not both).
20490 + * @num_ports: Number of ports to configure on SPI
20491 + *
20492 + * Returns Zero on success, non-zero error code on failure (will cause
20493 + * SPI initialization to abort)
20494 + */
20495 +int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
20496 + int num_ports)
20497 +{
20498 + int port;
20499 + int index;
20500 + if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20501 + union cvmx_srxx_com_ctl srxx_com_ctl;
20502 + union cvmx_srxx_spi4_stat srxx_spi4_stat;
20503 +
20504 + /* SRX0 number of Ports */
20505 + srxx_com_ctl.u64 = 0;
20506 + srxx_com_ctl.s.prts = num_ports - 1;
20507 + srxx_com_ctl.s.st_en = 0;
20508 + srxx_com_ctl.s.inf_en = 0;
20509 + cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20510 +
20511 + /* SRX0 Calendar Table. This round robbins through all ports */
20512 + port = 0;
20513 + index = 0;
20514 + while (port < num_ports) {
20515 + union cvmx_srxx_spi4_calx srxx_spi4_calx;
20516 + srxx_spi4_calx.u64 = 0;
20517 + srxx_spi4_calx.s.prt0 = port++;
20518 + srxx_spi4_calx.s.prt1 = port++;
20519 + srxx_spi4_calx.s.prt2 = port++;
20520 + srxx_spi4_calx.s.prt3 = port++;
20521 + srxx_spi4_calx.s.oddpar =
20522 + ~(cvmx_dpop(srxx_spi4_calx.u64) & 1);
20523 + cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface),
20524 + srxx_spi4_calx.u64);
20525 + index++;
20526 + }
20527 + srxx_spi4_stat.u64 = 0;
20528 + srxx_spi4_stat.s.len = num_ports;
20529 + srxx_spi4_stat.s.m = 1;
20530 + cvmx_write_csr(CVMX_SRXX_SPI4_STAT(interface),
20531 + srxx_spi4_stat.u64);
20532 + }
20533 +
20534 + if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20535 + union cvmx_stxx_arb_ctl stxx_arb_ctl;
20536 + union cvmx_gmxx_tx_spi_max gmxx_tx_spi_max;
20537 + union cvmx_gmxx_tx_spi_thresh gmxx_tx_spi_thresh;
20538 + union cvmx_gmxx_tx_spi_ctl gmxx_tx_spi_ctl;
20539 + union cvmx_stxx_spi4_stat stxx_spi4_stat;
20540 + union cvmx_stxx_spi4_dat stxx_spi4_dat;
20541 +
20542 + /* STX0 Config */
20543 + stxx_arb_ctl.u64 = 0;
20544 + stxx_arb_ctl.s.igntpa = 0;
20545 + stxx_arb_ctl.s.mintrn = 0;
20546 + cvmx_write_csr(CVMX_STXX_ARB_CTL(interface), stxx_arb_ctl.u64);
20547 +
20548 + gmxx_tx_spi_max.u64 = 0;
20549 + gmxx_tx_spi_max.s.max1 = 8;
20550 + gmxx_tx_spi_max.s.max2 = 4;
20551 + gmxx_tx_spi_max.s.slice = 0;
20552 + cvmx_write_csr(CVMX_GMXX_TX_SPI_MAX(interface),
20553 + gmxx_tx_spi_max.u64);
20554 +
20555 + gmxx_tx_spi_thresh.u64 = 0;
20556 + gmxx_tx_spi_thresh.s.thresh = 4;
20557 + cvmx_write_csr(CVMX_GMXX_TX_SPI_THRESH(interface),
20558 + gmxx_tx_spi_thresh.u64);
20559 +
20560 + gmxx_tx_spi_ctl.u64 = 0;
20561 + gmxx_tx_spi_ctl.s.tpa_clr = 0;
20562 + gmxx_tx_spi_ctl.s.cont_pkt = 0;
20563 + cvmx_write_csr(CVMX_GMXX_TX_SPI_CTL(interface),
20564 + gmxx_tx_spi_ctl.u64);
20565 +
20566 + /* STX0 Training Control */
20567 + stxx_spi4_dat.u64 = 0;
20568 + /*Minimum needed by dynamic alignment */
20569 + stxx_spi4_dat.s.alpha = 32;
20570 + stxx_spi4_dat.s.max_t = 0xFFFF; /*Minimum interval is 0x20 */
20571 + cvmx_write_csr(CVMX_STXX_SPI4_DAT(interface),
20572 + stxx_spi4_dat.u64);
20573 +
20574 + /* STX0 Calendar Table. This round robbins through all ports */
20575 + port = 0;
20576 + index = 0;
20577 + while (port < num_ports) {
20578 + union cvmx_stxx_spi4_calx stxx_spi4_calx;
20579 + stxx_spi4_calx.u64 = 0;
20580 + stxx_spi4_calx.s.prt0 = port++;
20581 + stxx_spi4_calx.s.prt1 = port++;
20582 + stxx_spi4_calx.s.prt2 = port++;
20583 + stxx_spi4_calx.s.prt3 = port++;
20584 + stxx_spi4_calx.s.oddpar =
20585 + ~(cvmx_dpop(stxx_spi4_calx.u64) & 1);
20586 + cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface),
20587 + stxx_spi4_calx.u64);
20588 + index++;
20589 + }
20590 + stxx_spi4_stat.u64 = 0;
20591 + stxx_spi4_stat.s.len = num_ports;
20592 + stxx_spi4_stat.s.m = 1;
20593 + cvmx_write_csr(CVMX_STXX_SPI4_STAT(interface),
20594 + stxx_spi4_stat.u64);
20595 + }
20596 +
20597 + return 0;
20598 +}
20599 +
20600 +/**
20601 + * Callback to perform clock detection
20602 + *
20603 + * @interface: The identifier of the packet interface to configure and
20604 + * use as a SPI interface.
20605 + * @mode: The operating mode for the SPI interface. The interface
20606 + * can operate as a full duplex (both Tx and Rx data paths
20607 + * active) or as a halfplex (either the Tx data path is
20608 + * active or the Rx data path is active, but not both).
20609 + * @timeout: Timeout to wait for clock synchronization in seconds
20610 + *
20611 + * Returns Zero on success, non-zero error code on failure (will cause
20612 + * SPI initialization to abort)
20613 + */
20614 +int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20615 +{
20616 + int clock_transitions;
20617 + union cvmx_spxx_clk_stat stat;
20618 + uint64_t timeout_time;
20619 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20620 +
20621 + /*
20622 + * Regardless of operating mode, both Tx and Rx clocks must be
20623 + * present for the SPI interface to operate.
20624 + */
20625 + cvmx_dprintf("SPI%d: Waiting to see TsClk...\n", interface);
20626 + timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20627 + /*
20628 + * Require 100 clock transitions in order to avoid any noise
20629 + * in the beginning.
20630 + */
20631 + clock_transitions = 100;
20632 + do {
20633 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20634 + if (stat.s.s4clk0 && stat.s.s4clk1 && clock_transitions) {
20635 + /*
20636 + * We've seen a clock transition, so decrement
20637 + * the number we still need.
20638 + */
20639 + clock_transitions--;
20640 + cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20641 + stat.s.s4clk0 = 0;
20642 + stat.s.s4clk1 = 0;
20643 + }
20644 + if (cvmx_get_cycle() > timeout_time) {
20645 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20646 + return -1;
20647 + }
20648 + } while (stat.s.s4clk0 == 0 || stat.s.s4clk1 == 0);
20649 +
20650 + cvmx_dprintf("SPI%d: Waiting to see RsClk...\n", interface);
20651 + timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20652 + /*
20653 + * Require 100 clock transitions in order to avoid any noise in the
20654 + * beginning.
20655 + */
20656 + clock_transitions = 100;
20657 + do {
20658 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20659 + if (stat.s.d4clk0 && stat.s.d4clk1 && clock_transitions) {
20660 + /*
20661 + * We've seen a clock transition, so decrement
20662 + * the number we still need
20663 + */
20664 + clock_transitions--;
20665 + cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20666 + stat.s.d4clk0 = 0;
20667 + stat.s.d4clk1 = 0;
20668 + }
20669 + if (cvmx_get_cycle() > timeout_time) {
20670 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20671 + return -1;
20672 + }
20673 + } while (stat.s.d4clk0 == 0 || stat.s.d4clk1 == 0);
20674 +
20675 + return 0;
20676 +}
20677 +
20678 +/**
20679 + * Callback to perform link training
20680 + *
20681 + * @interface: The identifier of the packet interface to configure and
20682 + * use as a SPI interface.
20683 + * @mode: The operating mode for the SPI interface. The interface
20684 + * can operate as a full duplex (both Tx and Rx data paths
20685 + * active) or as a halfplex (either the Tx data path is
20686 + * active or the Rx data path is active, but not both).
20687 + * @timeout: Timeout to wait for link to be trained (in seconds)
20688 + *
20689 + * Returns Zero on success, non-zero error code on failure (will cause
20690 + * SPI initialization to abort)
20691 + */
20692 +int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20693 +{
20694 + union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
20695 + union cvmx_spxx_clk_stat stat;
20696 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20697 + uint64_t timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20698 + int rx_training_needed;
20699 +
20700 + /* SRX0 & STX0 Inf0 Links are configured - begin training */
20701 + union cvmx_spxx_clk_ctl spxx_clk_ctl;
20702 + spxx_clk_ctl.u64 = 0;
20703 + spxx_clk_ctl.s.seetrn = 0;
20704 + spxx_clk_ctl.s.clkdly = 0x10;
20705 + spxx_clk_ctl.s.runbist = 0;
20706 + spxx_clk_ctl.s.statdrv = 0;
20707 + /* This should always be on the opposite edge as statdrv */
20708 + spxx_clk_ctl.s.statrcv = 1;
20709 + spxx_clk_ctl.s.sndtrn = 1;
20710 + spxx_clk_ctl.s.drptrn = 1;
20711 + spxx_clk_ctl.s.rcvtrn = 1;
20712 + spxx_clk_ctl.s.srxdlck = 1;
20713 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20714 + cvmx_wait(1000 * MS);
20715 +
20716 + /* SRX0 clear the boot bit */
20717 + spxx_trn4_ctl.u64 = cvmx_read_csr(CVMX_SPXX_TRN4_CTL(interface));
20718 + spxx_trn4_ctl.s.clr_boot = 1;
20719 + cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64);
20720 +
20721 + /* Wait for the training sequence to complete */
20722 + cvmx_dprintf("SPI%d: Waiting for training\n", interface);
20723 + cvmx_wait(1000 * MS);
20724 + /* Wait a really long time here */
20725 + timeout_time = cvmx_get_cycle() + 1000ull * MS * 600;
20726 + /*
20727 + * The HRM says we must wait for 34 + 16 * MAXDIST training sequences.
20728 + * We'll be pessimistic and wait for a lot more.
20729 + */
20730 + rx_training_needed = 500;
20731 + do {
20732 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20733 + if (stat.s.srxtrn && rx_training_needed) {
20734 + rx_training_needed--;
20735 + cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20736 + stat.s.srxtrn = 0;
20737 + }
20738 + if (cvmx_get_cycle() > timeout_time) {
20739 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20740 + return -1;
20741 + }
20742 + } while (stat.s.srxtrn == 0);
20743 +
20744 + return 0;
20745 +}
20746 +
20747 +/**
20748 + * Callback to perform calendar data synchronization
20749 + *
20750 + * @interface: The identifier of the packet interface to configure and
20751 + * use as a SPI interface.
20752 + * @mode: The operating mode for the SPI interface. The interface
20753 + * can operate as a full duplex (both Tx and Rx data paths
20754 + * active) or as a halfplex (either the Tx data path is
20755 + * active or the Rx data path is active, but not both).
20756 + * @timeout: Timeout to wait for calendar data in seconds
20757 + *
20758 + * Returns Zero on success, non-zero error code on failure (will cause
20759 + * SPI initialization to abort)
20760 + */
20761 +int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20762 +{
20763 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20764 + if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20765 + /* SRX0 interface should be good, send calendar data */
20766 + union cvmx_srxx_com_ctl srxx_com_ctl;
20767 + cvmx_dprintf
20768 + ("SPI%d: Rx is synchronized, start sending calendar data\n",
20769 + interface);
20770 + srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface));
20771 + srxx_com_ctl.s.inf_en = 1;
20772 + srxx_com_ctl.s.st_en = 1;
20773 + cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20774 + }
20775 +
20776 + if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20777 + /* STX0 has achieved sync */
20778 + /* The corespondant board should be sending calendar data */
20779 + /* Enable the STX0 STAT receiver. */
20780 + union cvmx_spxx_clk_stat stat;
20781 + uint64_t timeout_time;
20782 + union cvmx_stxx_com_ctl stxx_com_ctl;
20783 + stxx_com_ctl.u64 = 0;
20784 + stxx_com_ctl.s.st_en = 1;
20785 + cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64);
20786 +
20787 + /* Waiting for calendar sync on STX0 STAT */
20788 + cvmx_dprintf("SPI%d: Waiting to sync on STX[%d] STAT\n",
20789 + interface, interface);
20790 + timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20791 + /* SPX0_CLK_STAT - SPX0_CLK_STAT[STXCAL] should be 1 (bit10) */
20792 + do {
20793 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20794 + if (cvmx_get_cycle() > timeout_time) {
20795 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20796 + return -1;
20797 + }
20798 + } while (stat.s.stxcal == 0);
20799 + }
20800 +
20801 + return 0;
20802 +}
20803 +
20804 +/**
20805 + * Callback to handle interface up
20806 + *
20807 + * @interface: The identifier of the packet interface to configure and
20808 + * use as a SPI interface.
20809 + * @mode: The operating mode for the SPI interface. The interface
20810 + * can operate as a full duplex (both Tx and Rx data paths
20811 + * active) or as a halfplex (either the Tx data path is
20812 + * active or the Rx data path is active, but not both).
20813 + *
20814 + * Returns Zero on success, non-zero error code on failure (will cause
20815 + * SPI initialization to abort)
20816 + */
20817 +int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode)
20818 +{
20819 + union cvmx_gmxx_rxx_frm_min gmxx_rxx_frm_min;
20820 + union cvmx_gmxx_rxx_frm_max gmxx_rxx_frm_max;
20821 + union cvmx_gmxx_rxx_jabber gmxx_rxx_jabber;
20822 +
20823 + if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20824 + union cvmx_srxx_com_ctl srxx_com_ctl;
20825 + srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface));
20826 + srxx_com_ctl.s.inf_en = 1;
20827 + cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20828 + cvmx_dprintf("SPI%d: Rx is now up\n", interface);
20829 + }
20830 +
20831 + if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20832 + union cvmx_stxx_com_ctl stxx_com_ctl;
20833 + stxx_com_ctl.u64 = cvmx_read_csr(CVMX_STXX_COM_CTL(interface));
20834 + stxx_com_ctl.s.inf_en = 1;
20835 + cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64);
20836 + cvmx_dprintf("SPI%d: Tx is now up\n", interface);
20837 + }
20838 +
20839 + gmxx_rxx_frm_min.u64 = 0;
20840 + gmxx_rxx_frm_min.s.len = 64;
20841 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MIN(0, interface),
20842 + gmxx_rxx_frm_min.u64);
20843 + gmxx_rxx_frm_max.u64 = 0;
20844 + gmxx_rxx_frm_max.s.len = 64 * 1024 - 4;
20845 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(0, interface),
20846 + gmxx_rxx_frm_max.u64);
20847 + gmxx_rxx_jabber.u64 = 0;
20848 + gmxx_rxx_jabber.s.cnt = 64 * 1024 - 4;
20849 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER(0, interface), gmxx_rxx_jabber.u64);
20850 +
20851 + return 0;
20852 +}
20853 --- /dev/null
20854 +++ b/drivers/staging/octeon/cvmx-spi.h
20855 @@ -0,0 +1,269 @@
20856 +/***********************license start***************
20857 + * Author: Cavium Networks
20858 + *
20859 + * Contact: support@caviumnetworks.com
20860 + * This file is part of the OCTEON SDK
20861 + *
20862 + * Copyright (c) 2003-2008 Cavium Networks
20863 + *
20864 + * This file is free software; you can redistribute it and/or modify
20865 + * it under the terms of the GNU General Public License, Version 2, as
20866 + * published by the Free Software Foundation.
20867 + *
20868 + * This file is distributed in the hope that it will be useful, but
20869 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20870 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20871 + * NONINFRINGEMENT. See the GNU General Public License for more
20872 + * details.
20873 + *
20874 + * You should have received a copy of the GNU General Public License
20875 + * along with this file; if not, write to the Free Software
20876 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20877 + * or visit http://www.gnu.org/licenses/.
20878 + *
20879 + * This file may also be available under a different license from Cavium.
20880 + * Contact Cavium Networks for more information
20881 + ***********************license end**************************************/
20882 +
20883 +/*
20884 + *
20885 + * This file contains defines for the SPI interface
20886 + */
20887 +#ifndef __CVMX_SPI_H__
20888 +#define __CVMX_SPI_H__
20889 +
20890 +#include "cvmx-gmxx-defs.h"
20891 +
20892 +/* CSR typedefs have been moved to cvmx-csr-*.h */
20893 +
20894 +typedef enum {
20895 + CVMX_SPI_MODE_UNKNOWN = 0,
20896 + CVMX_SPI_MODE_TX_HALFPLEX = 1,
20897 + CVMX_SPI_MODE_RX_HALFPLEX = 2,
20898 + CVMX_SPI_MODE_DUPLEX = 3
20899 +} cvmx_spi_mode_t;
20900 +
20901 +/** Callbacks structure to customize SPI4 initialization sequence */
20902 +typedef struct {
20903 + /** Called to reset SPI4 DLL */
20904 + int (*reset_cb) (int interface, cvmx_spi_mode_t mode);
20905 +
20906 + /** Called to setup calendar */
20907 + int (*calendar_setup_cb) (int interface, cvmx_spi_mode_t mode,
20908 + int num_ports);
20909 +
20910 + /** Called for Tx and Rx clock detection */
20911 + int (*clock_detect_cb) (int interface, cvmx_spi_mode_t mode,
20912 + int timeout);
20913 +
20914 + /** Called to perform link training */
20915 + int (*training_cb) (int interface, cvmx_spi_mode_t mode, int timeout);
20916 +
20917 + /** Called for calendar data synchronization */
20918 + int (*calendar_sync_cb) (int interface, cvmx_spi_mode_t mode,
20919 + int timeout);
20920 +
20921 + /** Called when interface is up */
20922 + int (*interface_up_cb) (int interface, cvmx_spi_mode_t mode);
20923 +
20924 +} cvmx_spi_callbacks_t;
20925 +
20926 +/**
20927 + * Return true if the supplied interface is configured for SPI
20928 + *
20929 + * @interface: Interface to check
20930 + * Returns True if interface is SPI
20931 + */
20932 +static inline int cvmx_spi_is_spi_interface(int interface)
20933 +{
20934 + uint64_t gmxState = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
20935 + return (gmxState & 0x2) && (gmxState & 0x1);
20936 +}
20937 +
20938 +/**
20939 + * Initialize and start the SPI interface.
20940 + *
20941 + * @interface: The identifier of the packet interface to configure and
20942 + * use as a SPI interface.
20943 + * @mode: The operating mode for the SPI interface. The interface
20944 + * can operate as a full duplex (both Tx and Rx data paths
20945 + * active) or as a halfplex (either the Tx data path is
20946 + * active or the Rx data path is active, but not both).
20947 + * @timeout: Timeout to wait for clock synchronization in seconds
20948 + * @num_ports: Number of SPI ports to configure
20949 + *
20950 + * Returns Zero on success, negative of failure.
20951 + */
20952 +extern int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode,
20953 + int timeout, int num_ports);
20954 +
20955 +/**
20956 + * This routine restarts the SPI interface after it has lost synchronization
20957 + * with its corespondant system.
20958 + *
20959 + * @interface: The identifier of the packet interface to configure and
20960 + * use as a SPI interface.
20961 + * @mode: The operating mode for the SPI interface. The interface
20962 + * can operate as a full duplex (both Tx and Rx data paths
20963 + * active) or as a halfplex (either the Tx data path is
20964 + * active or the Rx data path is active, but not both).
20965 + * @timeout: Timeout to wait for clock synchronization in seconds
20966 + * Returns Zero on success, negative of failure.
20967 + */
20968 +extern int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode,
20969 + int timeout);
20970 +
20971 +/**
20972 + * Return non-zero if the SPI interface has a SPI4000 attached
20973 + *
20974 + * @interface: SPI interface the SPI4000 is connected to
20975 + *
20976 + * Returns
20977 + */
20978 +static inline int cvmx_spi4000_is_present(int interface)
20979 +{
20980 + return 0;
20981 +}
20982 +
20983 +/**
20984 + * Initialize the SPI4000 for use
20985 + *
20986 + * @interface: SPI interface the SPI4000 is connected to
20987 + */
20988 +static inline int cvmx_spi4000_initialize(int interface)
20989 +{
20990 + return 0;
20991 +}
20992 +
20993 +/**
20994 + * Poll all the SPI4000 port and check its speed
20995 + *
20996 + * @interface: Interface the SPI4000 is on
20997 + * @port: Port to poll (0-9)
20998 + * Returns Status of the port. 0=down. All other values the port is up.
20999 + */
21000 +static inline union cvmx_gmxx_rxx_rx_inbnd cvmx_spi4000_check_speed(
21001 + int interface,
21002 + int port)
21003 +{
21004 + union cvmx_gmxx_rxx_rx_inbnd r;
21005 + r.u64 = 0;
21006 + return r;
21007 +}
21008 +
21009 +/**
21010 + * Get current SPI4 initialization callbacks
21011 + *
21012 + * @callbacks: Pointer to the callbacks structure.to fill
21013 + *
21014 + * Returns Pointer to cvmx_spi_callbacks_t structure.
21015 + */
21016 +extern void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks);
21017 +
21018 +/**
21019 + * Set new SPI4 initialization callbacks
21020 + *
21021 + * @new_callbacks: Pointer to an updated callbacks structure.
21022 + */
21023 +extern void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks);
21024 +
21025 +/**
21026 + * Callback to perform SPI4 reset
21027 + *
21028 + * @interface: The identifier of the packet interface to configure and
21029 + * use as a SPI interface.
21030 + * @mode: The operating mode for the SPI interface. The interface
21031 + * can operate as a full duplex (both Tx and Rx data paths
21032 + * active) or as a halfplex (either the Tx data path is
21033 + * active or the Rx data path is active, but not both).
21034 + *
21035 + * Returns Zero on success, non-zero error code on failure (will cause
21036 + * SPI initialization to abort)
21037 + */
21038 +extern int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode);
21039 +
21040 +/**
21041 + * Callback to setup calendar and miscellaneous settings before clock
21042 + * detection
21043 + *
21044 + * @interface: The identifier of the packet interface to configure and
21045 + * use as a SPI interface.
21046 + * @mode: The operating mode for the SPI interface. The interface
21047 + * can operate as a full duplex (both Tx and Rx data paths
21048 + * active) or as a halfplex (either the Tx data path is
21049 + * active or the Rx data path is active, but not both).
21050 + * @num_ports: Number of ports to configure on SPI
21051 + *
21052 + * Returns Zero on success, non-zero error code on failure (will cause
21053 + * SPI initialization to abort)
21054 + */
21055 +extern int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
21056 + int num_ports);
21057 +
21058 +/**
21059 + * Callback to perform clock detection
21060 + *
21061 + * @interface: The identifier of the packet interface to configure and
21062 + * use as a SPI interface.
21063 + * @mode: The operating mode for the SPI interface. The interface
21064 + * can operate as a full duplex (both Tx and Rx data paths
21065 + * active) or as a halfplex (either the Tx data path is
21066 + * active or the Rx data path is active, but not both).
21067 + * @timeout: Timeout to wait for clock synchronization in seconds
21068 + *
21069 + * Returns Zero on success, non-zero error code on failure (will cause
21070 + * SPI initialization to abort)
21071 + */
21072 +extern int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode,
21073 + int timeout);
21074 +
21075 +/**
21076 + * Callback to perform link training
21077 + *
21078 + * @interface: The identifier of the packet interface to configure and
21079 + * use as a SPI interface.
21080 + * @mode: The operating mode for the SPI interface. The interface
21081 + * can operate as a full duplex (both Tx and Rx data paths
21082 + * active) or as a halfplex (either the Tx data path is
21083 + * active or the Rx data path is active, but not both).
21084 + * @timeout: Timeout to wait for link to be trained (in seconds)
21085 + *
21086 + * Returns Zero on success, non-zero error code on failure (will cause
21087 + * SPI initialization to abort)
21088 + */
21089 +extern int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode,
21090 + int timeout);
21091 +
21092 +/**
21093 + * Callback to perform calendar data synchronization
21094 + *
21095 + * @interface: The identifier of the packet interface to configure and
21096 + * use as a SPI interface.
21097 + * @mode: The operating mode for the SPI interface. The interface
21098 + * can operate as a full duplex (both Tx and Rx data paths
21099 + * active) or as a halfplex (either the Tx data path is
21100 + * active or the Rx data path is active, but not both).
21101 + * @timeout: Timeout to wait for calendar data in seconds
21102 + *
21103 + * Returns Zero on success, non-zero error code on failure (will cause
21104 + * SPI initialization to abort)
21105 + */
21106 +extern int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode,
21107 + int timeout);
21108 +
21109 +/**
21110 + * Callback to handle interface up
21111 + *
21112 + * @interface: The identifier of the packet interface to configure and
21113 + * use as a SPI interface.
21114 + * @mode: The operating mode for the SPI interface. The interface
21115 + * can operate as a full duplex (both Tx and Rx data paths
21116 + * active) or as a halfplex (either the Tx data path is
21117 + * active or the Rx data path is active, but not both).
21118 + *
21119 + * Returns Zero on success, non-zero error code on failure (will cause
21120 + * SPI initialization to abort)
21121 + */
21122 +extern int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode);
21123 +
21124 +#endif /* __CVMX_SPI_H__ */
21125 --- /dev/null
21126 +++ b/drivers/staging/octeon/cvmx-spxx-defs.h
21127 @@ -0,0 +1,347 @@
21128 +/***********************license start***************
21129 + * Author: Cavium Networks
21130 + *
21131 + * Contact: support@caviumnetworks.com
21132 + * This file is part of the OCTEON SDK
21133 + *
21134 + * Copyright (c) 2003-2008 Cavium Networks
21135 + *
21136 + * This file is free software; you can redistribute it and/or modify
21137 + * it under the terms of the GNU General Public License, Version 2, as
21138 + * published by the Free Software Foundation.
21139 + *
21140 + * This file is distributed in the hope that it will be useful, but
21141 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21142 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21143 + * NONINFRINGEMENT. See the GNU General Public License for more
21144 + * details.
21145 + *
21146 + * You should have received a copy of the GNU General Public License
21147 + * along with this file; if not, write to the Free Software
21148 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21149 + * or visit http://www.gnu.org/licenses/.
21150 + *
21151 + * This file may also be available under a different license from Cavium.
21152 + * Contact Cavium Networks for more information
21153 + ***********************license end**************************************/
21154 +
21155 +#ifndef __CVMX_SPXX_DEFS_H__
21156 +#define __CVMX_SPXX_DEFS_H__
21157 +
21158 +#define CVMX_SPXX_BCKPRS_CNT(block_id) \
21159 + CVMX_ADD_IO_SEG(0x0001180090000340ull + (((block_id) & 1) * 0x8000000ull))
21160 +#define CVMX_SPXX_BIST_STAT(block_id) \
21161 + CVMX_ADD_IO_SEG(0x00011800900007F8ull + (((block_id) & 1) * 0x8000000ull))
21162 +#define CVMX_SPXX_CLK_CTL(block_id) \
21163 + CVMX_ADD_IO_SEG(0x0001180090000348ull + (((block_id) & 1) * 0x8000000ull))
21164 +#define CVMX_SPXX_CLK_STAT(block_id) \
21165 + CVMX_ADD_IO_SEG(0x0001180090000350ull + (((block_id) & 1) * 0x8000000ull))
21166 +#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) \
21167 + CVMX_ADD_IO_SEG(0x0001180090000368ull + (((block_id) & 1) * 0x8000000ull))
21168 +#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) \
21169 + CVMX_ADD_IO_SEG(0x0001180090000370ull + (((block_id) & 1) * 0x8000000ull))
21170 +#define CVMX_SPXX_DRV_CTL(block_id) \
21171 + CVMX_ADD_IO_SEG(0x0001180090000358ull + (((block_id) & 1) * 0x8000000ull))
21172 +#define CVMX_SPXX_ERR_CTL(block_id) \
21173 + CVMX_ADD_IO_SEG(0x0001180090000320ull + (((block_id) & 1) * 0x8000000ull))
21174 +#define CVMX_SPXX_INT_DAT(block_id) \
21175 + CVMX_ADD_IO_SEG(0x0001180090000318ull + (((block_id) & 1) * 0x8000000ull))
21176 +#define CVMX_SPXX_INT_MSK(block_id) \
21177 + CVMX_ADD_IO_SEG(0x0001180090000308ull + (((block_id) & 1) * 0x8000000ull))
21178 +#define CVMX_SPXX_INT_REG(block_id) \
21179 + CVMX_ADD_IO_SEG(0x0001180090000300ull + (((block_id) & 1) * 0x8000000ull))
21180 +#define CVMX_SPXX_INT_SYNC(block_id) \
21181 + CVMX_ADD_IO_SEG(0x0001180090000310ull + (((block_id) & 1) * 0x8000000ull))
21182 +#define CVMX_SPXX_TPA_ACC(block_id) \
21183 + CVMX_ADD_IO_SEG(0x0001180090000338ull + (((block_id) & 1) * 0x8000000ull))
21184 +#define CVMX_SPXX_TPA_MAX(block_id) \
21185 + CVMX_ADD_IO_SEG(0x0001180090000330ull + (((block_id) & 1) * 0x8000000ull))
21186 +#define CVMX_SPXX_TPA_SEL(block_id) \
21187 + CVMX_ADD_IO_SEG(0x0001180090000328ull + (((block_id) & 1) * 0x8000000ull))
21188 +#define CVMX_SPXX_TRN4_CTL(block_id) \
21189 + CVMX_ADD_IO_SEG(0x0001180090000360ull + (((block_id) & 1) * 0x8000000ull))
21190 +
21191 +union cvmx_spxx_bckprs_cnt {
21192 + uint64_t u64;
21193 + struct cvmx_spxx_bckprs_cnt_s {
21194 + uint64_t reserved_32_63:32;
21195 + uint64_t cnt:32;
21196 + } s;
21197 + struct cvmx_spxx_bckprs_cnt_s cn38xx;
21198 + struct cvmx_spxx_bckprs_cnt_s cn38xxp2;
21199 + struct cvmx_spxx_bckprs_cnt_s cn58xx;
21200 + struct cvmx_spxx_bckprs_cnt_s cn58xxp1;
21201 +};
21202 +
21203 +union cvmx_spxx_bist_stat {
21204 + uint64_t u64;
21205 + struct cvmx_spxx_bist_stat_s {
21206 + uint64_t reserved_3_63:61;
21207 + uint64_t stat2:1;
21208 + uint64_t stat1:1;
21209 + uint64_t stat0:1;
21210 + } s;
21211 + struct cvmx_spxx_bist_stat_s cn38xx;
21212 + struct cvmx_spxx_bist_stat_s cn38xxp2;
21213 + struct cvmx_spxx_bist_stat_s cn58xx;
21214 + struct cvmx_spxx_bist_stat_s cn58xxp1;
21215 +};
21216 +
21217 +union cvmx_spxx_clk_ctl {
21218 + uint64_t u64;
21219 + struct cvmx_spxx_clk_ctl_s {
21220 + uint64_t reserved_17_63:47;
21221 + uint64_t seetrn:1;
21222 + uint64_t reserved_12_15:4;
21223 + uint64_t clkdly:5;
21224 + uint64_t runbist:1;
21225 + uint64_t statdrv:1;
21226 + uint64_t statrcv:1;
21227 + uint64_t sndtrn:1;
21228 + uint64_t drptrn:1;
21229 + uint64_t rcvtrn:1;
21230 + uint64_t srxdlck:1;
21231 + } s;
21232 + struct cvmx_spxx_clk_ctl_s cn38xx;
21233 + struct cvmx_spxx_clk_ctl_s cn38xxp2;
21234 + struct cvmx_spxx_clk_ctl_s cn58xx;
21235 + struct cvmx_spxx_clk_ctl_s cn58xxp1;
21236 +};
21237 +
21238 +union cvmx_spxx_clk_stat {
21239 + uint64_t u64;
21240 + struct cvmx_spxx_clk_stat_s {
21241 + uint64_t reserved_11_63:53;
21242 + uint64_t stxcal:1;
21243 + uint64_t reserved_9_9:1;
21244 + uint64_t srxtrn:1;
21245 + uint64_t s4clk1:1;
21246 + uint64_t s4clk0:1;
21247 + uint64_t d4clk1:1;
21248 + uint64_t d4clk0:1;
21249 + uint64_t reserved_0_3:4;
21250 + } s;
21251 + struct cvmx_spxx_clk_stat_s cn38xx;
21252 + struct cvmx_spxx_clk_stat_s cn38xxp2;
21253 + struct cvmx_spxx_clk_stat_s cn58xx;
21254 + struct cvmx_spxx_clk_stat_s cn58xxp1;
21255 +};
21256 +
21257 +union cvmx_spxx_dbg_deskew_ctl {
21258 + uint64_t u64;
21259 + struct cvmx_spxx_dbg_deskew_ctl_s {
21260 + uint64_t reserved_30_63:34;
21261 + uint64_t fallnop:1;
21262 + uint64_t fall8:1;
21263 + uint64_t reserved_26_27:2;
21264 + uint64_t sstep_go:1;
21265 + uint64_t sstep:1;
21266 + uint64_t reserved_22_23:2;
21267 + uint64_t clrdly:1;
21268 + uint64_t dec:1;
21269 + uint64_t inc:1;
21270 + uint64_t mux:1;
21271 + uint64_t offset:5;
21272 + uint64_t bitsel:5;
21273 + uint64_t offdly:6;
21274 + uint64_t dllfrc:1;
21275 + uint64_t dlldis:1;
21276 + } s;
21277 + struct cvmx_spxx_dbg_deskew_ctl_s cn38xx;
21278 + struct cvmx_spxx_dbg_deskew_ctl_s cn38xxp2;
21279 + struct cvmx_spxx_dbg_deskew_ctl_s cn58xx;
21280 + struct cvmx_spxx_dbg_deskew_ctl_s cn58xxp1;
21281 +};
21282 +
21283 +union cvmx_spxx_dbg_deskew_state {
21284 + uint64_t u64;
21285 + struct cvmx_spxx_dbg_deskew_state_s {
21286 + uint64_t reserved_9_63:55;
21287 + uint64_t testres:1;
21288 + uint64_t unxterm:1;
21289 + uint64_t muxsel:2;
21290 + uint64_t offset:5;
21291 + } s;
21292 + struct cvmx_spxx_dbg_deskew_state_s cn38xx;
21293 + struct cvmx_spxx_dbg_deskew_state_s cn38xxp2;
21294 + struct cvmx_spxx_dbg_deskew_state_s cn58xx;
21295 + struct cvmx_spxx_dbg_deskew_state_s cn58xxp1;
21296 +};
21297 +
21298 +union cvmx_spxx_drv_ctl {
21299 + uint64_t u64;
21300 + struct cvmx_spxx_drv_ctl_s {
21301 + uint64_t reserved_0_63:64;
21302 + } s;
21303 + struct cvmx_spxx_drv_ctl_cn38xx {
21304 + uint64_t reserved_16_63:48;
21305 + uint64_t stx4ncmp:4;
21306 + uint64_t stx4pcmp:4;
21307 + uint64_t srx4cmp:8;
21308 + } cn38xx;
21309 + struct cvmx_spxx_drv_ctl_cn38xx cn38xxp2;
21310 + struct cvmx_spxx_drv_ctl_cn58xx {
21311 + uint64_t reserved_24_63:40;
21312 + uint64_t stx4ncmp:4;
21313 + uint64_t stx4pcmp:4;
21314 + uint64_t reserved_10_15:6;
21315 + uint64_t srx4cmp:10;
21316 + } cn58xx;
21317 + struct cvmx_spxx_drv_ctl_cn58xx cn58xxp1;
21318 +};
21319 +
21320 +union cvmx_spxx_err_ctl {
21321 + uint64_t u64;
21322 + struct cvmx_spxx_err_ctl_s {
21323 + uint64_t reserved_9_63:55;
21324 + uint64_t prtnxa:1;
21325 + uint64_t dipcls:1;
21326 + uint64_t dippay:1;
21327 + uint64_t reserved_4_5:2;
21328 + uint64_t errcnt:4;
21329 + } s;
21330 + struct cvmx_spxx_err_ctl_s cn38xx;
21331 + struct cvmx_spxx_err_ctl_s cn38xxp2;
21332 + struct cvmx_spxx_err_ctl_s cn58xx;
21333 + struct cvmx_spxx_err_ctl_s cn58xxp1;
21334 +};
21335 +
21336 +union cvmx_spxx_int_dat {
21337 + uint64_t u64;
21338 + struct cvmx_spxx_int_dat_s {
21339 + uint64_t reserved_32_63:32;
21340 + uint64_t mul:1;
21341 + uint64_t reserved_14_30:17;
21342 + uint64_t calbnk:2;
21343 + uint64_t rsvop:4;
21344 + uint64_t prt:8;
21345 + } s;
21346 + struct cvmx_spxx_int_dat_s cn38xx;
21347 + struct cvmx_spxx_int_dat_s cn38xxp2;
21348 + struct cvmx_spxx_int_dat_s cn58xx;
21349 + struct cvmx_spxx_int_dat_s cn58xxp1;
21350 +};
21351 +
21352 +union cvmx_spxx_int_msk {
21353 + uint64_t u64;
21354 + struct cvmx_spxx_int_msk_s {
21355 + uint64_t reserved_12_63:52;
21356 + uint64_t calerr:1;
21357 + uint64_t syncerr:1;
21358 + uint64_t diperr:1;
21359 + uint64_t tpaovr:1;
21360 + uint64_t rsverr:1;
21361 + uint64_t drwnng:1;
21362 + uint64_t clserr:1;
21363 + uint64_t spiovr:1;
21364 + uint64_t reserved_2_3:2;
21365 + uint64_t abnorm:1;
21366 + uint64_t prtnxa:1;
21367 + } s;
21368 + struct cvmx_spxx_int_msk_s cn38xx;
21369 + struct cvmx_spxx_int_msk_s cn38xxp2;
21370 + struct cvmx_spxx_int_msk_s cn58xx;
21371 + struct cvmx_spxx_int_msk_s cn58xxp1;
21372 +};
21373 +
21374 +union cvmx_spxx_int_reg {
21375 + uint64_t u64;
21376 + struct cvmx_spxx_int_reg_s {
21377 + uint64_t reserved_32_63:32;
21378 + uint64_t spf:1;
21379 + uint64_t reserved_12_30:19;
21380 + uint64_t calerr:1;
21381 + uint64_t syncerr:1;
21382 + uint64_t diperr:1;
21383 + uint64_t tpaovr:1;
21384 + uint64_t rsverr:1;
21385 + uint64_t drwnng:1;
21386 + uint64_t clserr:1;
21387 + uint64_t spiovr:1;
21388 + uint64_t reserved_2_3:2;
21389 + uint64_t abnorm:1;
21390 + uint64_t prtnxa:1;
21391 + } s;
21392 + struct cvmx_spxx_int_reg_s cn38xx;
21393 + struct cvmx_spxx_int_reg_s cn38xxp2;
21394 + struct cvmx_spxx_int_reg_s cn58xx;
21395 + struct cvmx_spxx_int_reg_s cn58xxp1;
21396 +};
21397 +
21398 +union cvmx_spxx_int_sync {
21399 + uint64_t u64;
21400 + struct cvmx_spxx_int_sync_s {
21401 + uint64_t reserved_12_63:52;
21402 + uint64_t calerr:1;
21403 + uint64_t syncerr:1;
21404 + uint64_t diperr:1;
21405 + uint64_t tpaovr:1;
21406 + uint64_t rsverr:1;
21407 + uint64_t drwnng:1;
21408 + uint64_t clserr:1;
21409 + uint64_t spiovr:1;
21410 + uint64_t reserved_2_3:2;
21411 + uint64_t abnorm:1;
21412 + uint64_t prtnxa:1;
21413 + } s;
21414 + struct cvmx_spxx_int_sync_s cn38xx;
21415 + struct cvmx_spxx_int_sync_s cn38xxp2;
21416 + struct cvmx_spxx_int_sync_s cn58xx;
21417 + struct cvmx_spxx_int_sync_s cn58xxp1;
21418 +};
21419 +
21420 +union cvmx_spxx_tpa_acc {
21421 + uint64_t u64;
21422 + struct cvmx_spxx_tpa_acc_s {
21423 + uint64_t reserved_32_63:32;
21424 + uint64_t cnt:32;
21425 + } s;
21426 + struct cvmx_spxx_tpa_acc_s cn38xx;
21427 + struct cvmx_spxx_tpa_acc_s cn38xxp2;
21428 + struct cvmx_spxx_tpa_acc_s cn58xx;
21429 + struct cvmx_spxx_tpa_acc_s cn58xxp1;
21430 +};
21431 +
21432 +union cvmx_spxx_tpa_max {
21433 + uint64_t u64;
21434 + struct cvmx_spxx_tpa_max_s {
21435 + uint64_t reserved_32_63:32;
21436 + uint64_t max:32;
21437 + } s;
21438 + struct cvmx_spxx_tpa_max_s cn38xx;
21439 + struct cvmx_spxx_tpa_max_s cn38xxp2;
21440 + struct cvmx_spxx_tpa_max_s cn58xx;
21441 + struct cvmx_spxx_tpa_max_s cn58xxp1;
21442 +};
21443 +
21444 +union cvmx_spxx_tpa_sel {
21445 + uint64_t u64;
21446 + struct cvmx_spxx_tpa_sel_s {
21447 + uint64_t reserved_4_63:60;
21448 + uint64_t prtsel:4;
21449 + } s;
21450 + struct cvmx_spxx_tpa_sel_s cn38xx;
21451 + struct cvmx_spxx_tpa_sel_s cn38xxp2;
21452 + struct cvmx_spxx_tpa_sel_s cn58xx;
21453 + struct cvmx_spxx_tpa_sel_s cn58xxp1;
21454 +};
21455 +
21456 +union cvmx_spxx_trn4_ctl {
21457 + uint64_t u64;
21458 + struct cvmx_spxx_trn4_ctl_s {
21459 + uint64_t reserved_13_63:51;
21460 + uint64_t trntest:1;
21461 + uint64_t jitter:3;
21462 + uint64_t clr_boot:1;
21463 + uint64_t set_boot:1;
21464 + uint64_t maxdist:5;
21465 + uint64_t macro_en:1;
21466 + uint64_t mux_en:1;
21467 + } s;
21468 + struct cvmx_spxx_trn4_ctl_s cn38xx;
21469 + struct cvmx_spxx_trn4_ctl_s cn38xxp2;
21470 + struct cvmx_spxx_trn4_ctl_s cn58xx;
21471 + struct cvmx_spxx_trn4_ctl_s cn58xxp1;
21472 +};
21473 +
21474 +#endif
21475 --- /dev/null
21476 +++ b/drivers/staging/octeon/cvmx-srxx-defs.h
21477 @@ -0,0 +1,126 @@
21478 +/***********************license start***************
21479 + * Author: Cavium Networks
21480 + *
21481 + * Contact: support@caviumnetworks.com
21482 + * This file is part of the OCTEON SDK
21483 + *
21484 + * Copyright (c) 2003-2008 Cavium Networks
21485 + *
21486 + * This file is free software; you can redistribute it and/or modify
21487 + * it under the terms of the GNU General Public License, Version 2, as
21488 + * published by the Free Software Foundation.
21489 + *
21490 + * This file is distributed in the hope that it will be useful, but
21491 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21492 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21493 + * NONINFRINGEMENT. See the GNU General Public License for more
21494 + * details.
21495 + *
21496 + * You should have received a copy of the GNU General Public License
21497 + * along with this file; if not, write to the Free Software
21498 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21499 + * or visit http://www.gnu.org/licenses/.
21500 + *
21501 + * This file may also be available under a different license from Cavium.
21502 + * Contact Cavium Networks for more information
21503 + ***********************license end**************************************/
21504 +
21505 +#ifndef __CVMX_SRXX_DEFS_H__
21506 +#define __CVMX_SRXX_DEFS_H__
21507 +
21508 +#define CVMX_SRXX_COM_CTL(block_id) \
21509 + CVMX_ADD_IO_SEG(0x0001180090000200ull + (((block_id) & 1) * 0x8000000ull))
21510 +#define CVMX_SRXX_IGN_RX_FULL(block_id) \
21511 + CVMX_ADD_IO_SEG(0x0001180090000218ull + (((block_id) & 1) * 0x8000000ull))
21512 +#define CVMX_SRXX_SPI4_CALX(offset, block_id) \
21513 + CVMX_ADD_IO_SEG(0x0001180090000000ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
21514 +#define CVMX_SRXX_SPI4_STAT(block_id) \
21515 + CVMX_ADD_IO_SEG(0x0001180090000208ull + (((block_id) & 1) * 0x8000000ull))
21516 +#define CVMX_SRXX_SW_TICK_CTL(block_id) \
21517 + CVMX_ADD_IO_SEG(0x0001180090000220ull + (((block_id) & 1) * 0x8000000ull))
21518 +#define CVMX_SRXX_SW_TICK_DAT(block_id) \
21519 + CVMX_ADD_IO_SEG(0x0001180090000228ull + (((block_id) & 1) * 0x8000000ull))
21520 +
21521 +union cvmx_srxx_com_ctl {
21522 + uint64_t u64;
21523 + struct cvmx_srxx_com_ctl_s {
21524 + uint64_t reserved_8_63:56;
21525 + uint64_t prts:4;
21526 + uint64_t st_en:1;
21527 + uint64_t reserved_1_2:2;
21528 + uint64_t inf_en:1;
21529 + } s;
21530 + struct cvmx_srxx_com_ctl_s cn38xx;
21531 + struct cvmx_srxx_com_ctl_s cn38xxp2;
21532 + struct cvmx_srxx_com_ctl_s cn58xx;
21533 + struct cvmx_srxx_com_ctl_s cn58xxp1;
21534 +};
21535 +
21536 +union cvmx_srxx_ign_rx_full {
21537 + uint64_t u64;
21538 + struct cvmx_srxx_ign_rx_full_s {
21539 + uint64_t reserved_16_63:48;
21540 + uint64_t ignore:16;
21541 + } s;
21542 + struct cvmx_srxx_ign_rx_full_s cn38xx;
21543 + struct cvmx_srxx_ign_rx_full_s cn38xxp2;
21544 + struct cvmx_srxx_ign_rx_full_s cn58xx;
21545 + struct cvmx_srxx_ign_rx_full_s cn58xxp1;
21546 +};
21547 +
21548 +union cvmx_srxx_spi4_calx {
21549 + uint64_t u64;
21550 + struct cvmx_srxx_spi4_calx_s {
21551 + uint64_t reserved_17_63:47;
21552 + uint64_t oddpar:1;
21553 + uint64_t prt3:4;
21554 + uint64_t prt2:4;
21555 + uint64_t prt1:4;
21556 + uint64_t prt0:4;
21557 + } s;
21558 + struct cvmx_srxx_spi4_calx_s cn38xx;
21559 + struct cvmx_srxx_spi4_calx_s cn38xxp2;
21560 + struct cvmx_srxx_spi4_calx_s cn58xx;
21561 + struct cvmx_srxx_spi4_calx_s cn58xxp1;
21562 +};
21563 +
21564 +union cvmx_srxx_spi4_stat {
21565 + uint64_t u64;
21566 + struct cvmx_srxx_spi4_stat_s {
21567 + uint64_t reserved_16_63:48;
21568 + uint64_t m:8;
21569 + uint64_t reserved_7_7:1;
21570 + uint64_t len:7;
21571 + } s;
21572 + struct cvmx_srxx_spi4_stat_s cn38xx;
21573 + struct cvmx_srxx_spi4_stat_s cn38xxp2;
21574 + struct cvmx_srxx_spi4_stat_s cn58xx;
21575 + struct cvmx_srxx_spi4_stat_s cn58xxp1;
21576 +};
21577 +
21578 +union cvmx_srxx_sw_tick_ctl {
21579 + uint64_t u64;
21580 + struct cvmx_srxx_sw_tick_ctl_s {
21581 + uint64_t reserved_14_63:50;
21582 + uint64_t eop:1;
21583 + uint64_t sop:1;
21584 + uint64_t mod:4;
21585 + uint64_t opc:4;
21586 + uint64_t adr:4;
21587 + } s;
21588 + struct cvmx_srxx_sw_tick_ctl_s cn38xx;
21589 + struct cvmx_srxx_sw_tick_ctl_s cn58xx;
21590 + struct cvmx_srxx_sw_tick_ctl_s cn58xxp1;
21591 +};
21592 +
21593 +union cvmx_srxx_sw_tick_dat {
21594 + uint64_t u64;
21595 + struct cvmx_srxx_sw_tick_dat_s {
21596 + uint64_t dat:64;
21597 + } s;
21598 + struct cvmx_srxx_sw_tick_dat_s cn38xx;
21599 + struct cvmx_srxx_sw_tick_dat_s cn58xx;
21600 + struct cvmx_srxx_sw_tick_dat_s cn58xxp1;
21601 +};
21602 +
21603 +#endif
21604 --- /dev/null
21605 +++ b/drivers/staging/octeon/cvmx-stxx-defs.h
21606 @@ -0,0 +1,292 @@
21607 +/***********************license start***************
21608 + * Author: Cavium Networks
21609 + *
21610 + * Contact: support@caviumnetworks.com
21611 + * This file is part of the OCTEON SDK
21612 + *
21613 + * Copyright (c) 2003-2008 Cavium Networks
21614 + *
21615 + * This file is free software; you can redistribute it and/or modify
21616 + * it under the terms of the GNU General Public License, Version 2, as
21617 + * published by the Free Software Foundation.
21618 + *
21619 + * This file is distributed in the hope that it will be useful, but
21620 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21621 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21622 + * NONINFRINGEMENT. See the GNU General Public License for more
21623 + * details.
21624 + *
21625 + * You should have received a copy of the GNU General Public License
21626 + * along with this file; if not, write to the Free Software
21627 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21628 + * or visit http://www.gnu.org/licenses/.
21629 + *
21630 + * This file may also be available under a different license from Cavium.
21631 + * Contact Cavium Networks for more information
21632 + ***********************license end**************************************/
21633 +
21634 +#ifndef __CVMX_STXX_DEFS_H__
21635 +#define __CVMX_STXX_DEFS_H__
21636 +
21637 +#define CVMX_STXX_ARB_CTL(block_id) \
21638 + CVMX_ADD_IO_SEG(0x0001180090000608ull + (((block_id) & 1) * 0x8000000ull))
21639 +#define CVMX_STXX_BCKPRS_CNT(block_id) \
21640 + CVMX_ADD_IO_SEG(0x0001180090000688ull + (((block_id) & 1) * 0x8000000ull))
21641 +#define CVMX_STXX_COM_CTL(block_id) \
21642 + CVMX_ADD_IO_SEG(0x0001180090000600ull + (((block_id) & 1) * 0x8000000ull))
21643 +#define CVMX_STXX_DIP_CNT(block_id) \
21644 + CVMX_ADD_IO_SEG(0x0001180090000690ull + (((block_id) & 1) * 0x8000000ull))
21645 +#define CVMX_STXX_IGN_CAL(block_id) \
21646 + CVMX_ADD_IO_SEG(0x0001180090000610ull + (((block_id) & 1) * 0x8000000ull))
21647 +#define CVMX_STXX_INT_MSK(block_id) \
21648 + CVMX_ADD_IO_SEG(0x00011800900006A0ull + (((block_id) & 1) * 0x8000000ull))
21649 +#define CVMX_STXX_INT_REG(block_id) \
21650 + CVMX_ADD_IO_SEG(0x0001180090000698ull + (((block_id) & 1) * 0x8000000ull))
21651 +#define CVMX_STXX_INT_SYNC(block_id) \
21652 + CVMX_ADD_IO_SEG(0x00011800900006A8ull + (((block_id) & 1) * 0x8000000ull))
21653 +#define CVMX_STXX_MIN_BST(block_id) \
21654 + CVMX_ADD_IO_SEG(0x0001180090000618ull + (((block_id) & 1) * 0x8000000ull))
21655 +#define CVMX_STXX_SPI4_CALX(offset, block_id) \
21656 + CVMX_ADD_IO_SEG(0x0001180090000400ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
21657 +#define CVMX_STXX_SPI4_DAT(block_id) \
21658 + CVMX_ADD_IO_SEG(0x0001180090000628ull + (((block_id) & 1) * 0x8000000ull))
21659 +#define CVMX_STXX_SPI4_STAT(block_id) \
21660 + CVMX_ADD_IO_SEG(0x0001180090000630ull + (((block_id) & 1) * 0x8000000ull))
21661 +#define CVMX_STXX_STAT_BYTES_HI(block_id) \
21662 + CVMX_ADD_IO_SEG(0x0001180090000648ull + (((block_id) & 1) * 0x8000000ull))
21663 +#define CVMX_STXX_STAT_BYTES_LO(block_id) \
21664 + CVMX_ADD_IO_SEG(0x0001180090000680ull + (((block_id) & 1) * 0x8000000ull))
21665 +#define CVMX_STXX_STAT_CTL(block_id) \
21666 + CVMX_ADD_IO_SEG(0x0001180090000638ull + (((block_id) & 1) * 0x8000000ull))
21667 +#define CVMX_STXX_STAT_PKT_XMT(block_id) \
21668 + CVMX_ADD_IO_SEG(0x0001180090000640ull + (((block_id) & 1) * 0x8000000ull))
21669 +
21670 +union cvmx_stxx_arb_ctl {
21671 + uint64_t u64;
21672 + struct cvmx_stxx_arb_ctl_s {
21673 + uint64_t reserved_6_63:58;
21674 + uint64_t mintrn:1;
21675 + uint64_t reserved_4_4:1;
21676 + uint64_t igntpa:1;
21677 + uint64_t reserved_0_2:3;
21678 + } s;
21679 + struct cvmx_stxx_arb_ctl_s cn38xx;
21680 + struct cvmx_stxx_arb_ctl_s cn38xxp2;
21681 + struct cvmx_stxx_arb_ctl_s cn58xx;
21682 + struct cvmx_stxx_arb_ctl_s cn58xxp1;
21683 +};
21684 +
21685 +union cvmx_stxx_bckprs_cnt {
21686 + uint64_t u64;
21687 + struct cvmx_stxx_bckprs_cnt_s {
21688 + uint64_t reserved_32_63:32;
21689 + uint64_t cnt:32;
21690 + } s;
21691 + struct cvmx_stxx_bckprs_cnt_s cn38xx;
21692 + struct cvmx_stxx_bckprs_cnt_s cn38xxp2;
21693 + struct cvmx_stxx_bckprs_cnt_s cn58xx;
21694 + struct cvmx_stxx_bckprs_cnt_s cn58xxp1;
21695 +};
21696 +
21697 +union cvmx_stxx_com_ctl {
21698 + uint64_t u64;
21699 + struct cvmx_stxx_com_ctl_s {
21700 + uint64_t reserved_4_63:60;
21701 + uint64_t st_en:1;
21702 + uint64_t reserved_1_2:2;
21703 + uint64_t inf_en:1;
21704 + } s;
21705 + struct cvmx_stxx_com_ctl_s cn38xx;
21706 + struct cvmx_stxx_com_ctl_s cn38xxp2;
21707 + struct cvmx_stxx_com_ctl_s cn58xx;
21708 + struct cvmx_stxx_com_ctl_s cn58xxp1;
21709 +};
21710 +
21711 +union cvmx_stxx_dip_cnt {
21712 + uint64_t u64;
21713 + struct cvmx_stxx_dip_cnt_s {
21714 + uint64_t reserved_8_63:56;
21715 + uint64_t frmmax:4;
21716 + uint64_t dipmax:4;
21717 + } s;
21718 + struct cvmx_stxx_dip_cnt_s cn38xx;
21719 + struct cvmx_stxx_dip_cnt_s cn38xxp2;
21720 + struct cvmx_stxx_dip_cnt_s cn58xx;
21721 + struct cvmx_stxx_dip_cnt_s cn58xxp1;
21722 +};
21723 +
21724 +union cvmx_stxx_ign_cal {
21725 + uint64_t u64;
21726 + struct cvmx_stxx_ign_cal_s {
21727 + uint64_t reserved_16_63:48;
21728 + uint64_t igntpa:16;
21729 + } s;
21730 + struct cvmx_stxx_ign_cal_s cn38xx;
21731 + struct cvmx_stxx_ign_cal_s cn38xxp2;
21732 + struct cvmx_stxx_ign_cal_s cn58xx;
21733 + struct cvmx_stxx_ign_cal_s cn58xxp1;
21734 +};
21735 +
21736 +union cvmx_stxx_int_msk {
21737 + uint64_t u64;
21738 + struct cvmx_stxx_int_msk_s {
21739 + uint64_t reserved_8_63:56;
21740 + uint64_t frmerr:1;
21741 + uint64_t unxfrm:1;
21742 + uint64_t nosync:1;
21743 + uint64_t diperr:1;
21744 + uint64_t datovr:1;
21745 + uint64_t ovrbst:1;
21746 + uint64_t calpar1:1;
21747 + uint64_t calpar0:1;
21748 + } s;
21749 + struct cvmx_stxx_int_msk_s cn38xx;
21750 + struct cvmx_stxx_int_msk_s cn38xxp2;
21751 + struct cvmx_stxx_int_msk_s cn58xx;
21752 + struct cvmx_stxx_int_msk_s cn58xxp1;
21753 +};
21754 +
21755 +union cvmx_stxx_int_reg {
21756 + uint64_t u64;
21757 + struct cvmx_stxx_int_reg_s {
21758 + uint64_t reserved_9_63:55;
21759 + uint64_t syncerr:1;
21760 + uint64_t frmerr:1;
21761 + uint64_t unxfrm:1;
21762 + uint64_t nosync:1;
21763 + uint64_t diperr:1;
21764 + uint64_t datovr:1;
21765 + uint64_t ovrbst:1;
21766 + uint64_t calpar1:1;
21767 + uint64_t calpar0:1;
21768 + } s;
21769 + struct cvmx_stxx_int_reg_s cn38xx;
21770 + struct cvmx_stxx_int_reg_s cn38xxp2;
21771 + struct cvmx_stxx_int_reg_s cn58xx;
21772 + struct cvmx_stxx_int_reg_s cn58xxp1;
21773 +};
21774 +
21775 +union cvmx_stxx_int_sync {
21776 + uint64_t u64;
21777 + struct cvmx_stxx_int_sync_s {
21778 + uint64_t reserved_8_63:56;
21779 + uint64_t frmerr:1;
21780 + uint64_t unxfrm:1;
21781 + uint64_t nosync:1;
21782 + uint64_t diperr:1;
21783 + uint64_t datovr:1;
21784 + uint64_t ovrbst:1;
21785 + uint64_t calpar1:1;
21786 + uint64_t calpar0:1;
21787 + } s;
21788 + struct cvmx_stxx_int_sync_s cn38xx;
21789 + struct cvmx_stxx_int_sync_s cn38xxp2;
21790 + struct cvmx_stxx_int_sync_s cn58xx;
21791 + struct cvmx_stxx_int_sync_s cn58xxp1;
21792 +};
21793 +
21794 +union cvmx_stxx_min_bst {
21795 + uint64_t u64;
21796 + struct cvmx_stxx_min_bst_s {
21797 + uint64_t reserved_9_63:55;
21798 + uint64_t minb:9;
21799 + } s;
21800 + struct cvmx_stxx_min_bst_s cn38xx;
21801 + struct cvmx_stxx_min_bst_s cn38xxp2;
21802 + struct cvmx_stxx_min_bst_s cn58xx;
21803 + struct cvmx_stxx_min_bst_s cn58xxp1;
21804 +};
21805 +
21806 +union cvmx_stxx_spi4_calx {
21807 + uint64_t u64;
21808 + struct cvmx_stxx_spi4_calx_s {
21809 + uint64_t reserved_17_63:47;
21810 + uint64_t oddpar:1;
21811 + uint64_t prt3:4;
21812 + uint64_t prt2:4;
21813 + uint64_t prt1:4;
21814 + uint64_t prt0:4;
21815 + } s;
21816 + struct cvmx_stxx_spi4_calx_s cn38xx;
21817 + struct cvmx_stxx_spi4_calx_s cn38xxp2;
21818 + struct cvmx_stxx_spi4_calx_s cn58xx;
21819 + struct cvmx_stxx_spi4_calx_s cn58xxp1;
21820 +};
21821 +
21822 +union cvmx_stxx_spi4_dat {
21823 + uint64_t u64;
21824 + struct cvmx_stxx_spi4_dat_s {
21825 + uint64_t reserved_32_63:32;
21826 + uint64_t alpha:16;
21827 + uint64_t max_t:16;
21828 + } s;
21829 + struct cvmx_stxx_spi4_dat_s cn38xx;
21830 + struct cvmx_stxx_spi4_dat_s cn38xxp2;
21831 + struct cvmx_stxx_spi4_dat_s cn58xx;
21832 + struct cvmx_stxx_spi4_dat_s cn58xxp1;
21833 +};
21834 +
21835 +union cvmx_stxx_spi4_stat {
21836 + uint64_t u64;
21837 + struct cvmx_stxx_spi4_stat_s {
21838 + uint64_t reserved_16_63:48;
21839 + uint64_t m:8;
21840 + uint64_t reserved_7_7:1;
21841 + uint64_t len:7;
21842 + } s;
21843 + struct cvmx_stxx_spi4_stat_s cn38xx;
21844 + struct cvmx_stxx_spi4_stat_s cn38xxp2;
21845 + struct cvmx_stxx_spi4_stat_s cn58xx;
21846 + struct cvmx_stxx_spi4_stat_s cn58xxp1;
21847 +};
21848 +
21849 +union cvmx_stxx_stat_bytes_hi {
21850 + uint64_t u64;
21851 + struct cvmx_stxx_stat_bytes_hi_s {
21852 + uint64_t reserved_32_63:32;
21853 + uint64_t cnt:32;
21854 + } s;
21855 + struct cvmx_stxx_stat_bytes_hi_s cn38xx;
21856 + struct cvmx_stxx_stat_bytes_hi_s cn38xxp2;
21857 + struct cvmx_stxx_stat_bytes_hi_s cn58xx;
21858 + struct cvmx_stxx_stat_bytes_hi_s cn58xxp1;
21859 +};
21860 +
21861 +union cvmx_stxx_stat_bytes_lo {
21862 + uint64_t u64;
21863 + struct cvmx_stxx_stat_bytes_lo_s {
21864 + uint64_t reserved_32_63:32;
21865 + uint64_t cnt:32;
21866 + } s;
21867 + struct cvmx_stxx_stat_bytes_lo_s cn38xx;
21868 + struct cvmx_stxx_stat_bytes_lo_s cn38xxp2;
21869 + struct cvmx_stxx_stat_bytes_lo_s cn58xx;
21870 + struct cvmx_stxx_stat_bytes_lo_s cn58xxp1;
21871 +};
21872 +
21873 +union cvmx_stxx_stat_ctl {
21874 + uint64_t u64;
21875 + struct cvmx_stxx_stat_ctl_s {
21876 + uint64_t reserved_5_63:59;
21877 + uint64_t clr:1;
21878 + uint64_t bckprs:4;
21879 + } s;
21880 + struct cvmx_stxx_stat_ctl_s cn38xx;
21881 + struct cvmx_stxx_stat_ctl_s cn38xxp2;
21882 + struct cvmx_stxx_stat_ctl_s cn58xx;
21883 + struct cvmx_stxx_stat_ctl_s cn58xxp1;
21884 +};
21885 +
21886 +union cvmx_stxx_stat_pkt_xmt {
21887 + uint64_t u64;
21888 + struct cvmx_stxx_stat_pkt_xmt_s {
21889 + uint64_t reserved_32_63:32;
21890 + uint64_t cnt:32;
21891 + } s;
21892 + struct cvmx_stxx_stat_pkt_xmt_s cn38xx;
21893 + struct cvmx_stxx_stat_pkt_xmt_s cn38xxp2;
21894 + struct cvmx_stxx_stat_pkt_xmt_s cn58xx;
21895 + struct cvmx_stxx_stat_pkt_xmt_s cn58xxp1;
21896 +};
21897 +
21898 +#endif
21899 --- /dev/null
21900 +++ b/drivers/staging/octeon/cvmx-wqe.h
21901 @@ -0,0 +1,397 @@
21902 +/***********************license start***************
21903 + * Author: Cavium Networks
21904 + *
21905 + * Contact: support@caviumnetworks.com
21906 + * This file is part of the OCTEON SDK
21907 + *
21908 + * Copyright (c) 2003-2008 Cavium Networks
21909 + *
21910 + * This file is free software; you can redistribute it and/or modify
21911 + * it under the terms of the GNU General Public License, Version 2, as
21912 + * published by the Free Software Foundation.
21913 + *
21914 + * This file is distributed in the hope that it will be useful, but
21915 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21916 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21917 + * NONINFRINGEMENT. See the GNU General Public License for more
21918 + * details.
21919 + *
21920 + * You should have received a copy of the GNU General Public License
21921 + * along with this file; if not, write to the Free Software
21922 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21923 + * or visit http://www.gnu.org/licenses/.
21924 + *
21925 + * This file may also be available under a different license from Cavium.
21926 + * Contact Cavium Networks for more information
21927 + ***********************license end**************************************/
21928 +
21929 +/**
21930 + *
21931 + * This header file defines the work queue entry (wqe) data structure.
21932 + * Since this is a commonly used structure that depends on structures
21933 + * from several hardware blocks, those definitions have been placed
21934 + * in this file to create a single point of definition of the wqe
21935 + * format.
21936 + * Data structures are still named according to the block that they
21937 + * relate to.
21938 + *
21939 + */
21940 +
21941 +#ifndef __CVMX_WQE_H__
21942 +#define __CVMX_WQE_H__
21943 +
21944 +#include "cvmx-packet.h"
21945 +
21946 +
21947 +#define OCT_TAG_TYPE_STRING(x) \
21948 + (((x) == CVMX_POW_TAG_TYPE_ORDERED) ? "ORDERED" : \
21949 + (((x) == CVMX_POW_TAG_TYPE_ATOMIC) ? "ATOMIC" : \
21950 + (((x) == CVMX_POW_TAG_TYPE_NULL) ? "NULL" : \
21951 + "NULL_NULL")))
21952 +
21953 +/**
21954 + * HW decode / err_code in work queue entry
21955 + */
21956 +typedef union {
21957 + uint64_t u64;
21958 +
21959 + /* Use this struct if the hardware determines that the packet is IP */
21960 + struct {
21961 + /* HW sets this to the number of buffers used by this packet */
21962 + uint64_t bufs:8;
21963 + /* HW sets to the number of L2 bytes prior to the IP */
21964 + uint64_t ip_offset:8;
21965 + /* set to 1 if we found DSA/VLAN in the L2 */
21966 + uint64_t vlan_valid:1;
21967 + /* Set to 1 if the DSA/VLAN tag is stacked */
21968 + uint64_t vlan_stacked:1;
21969 + uint64_t unassigned:1;
21970 + /* HW sets to the DSA/VLAN CFI flag (valid when vlan_valid) */
21971 + uint64_t vlan_cfi:1;
21972 + /* HW sets to the DSA/VLAN_ID field (valid when vlan_valid) */
21973 + uint64_t vlan_id:12;
21974 + /* Ring Identifier (if PCIe). Requires PIP_GBL_CTL[RING_EN]=1 */
21975 + uint64_t pr:4;
21976 + uint64_t unassigned2:8;
21977 + /* the packet needs to be decompressed */
21978 + uint64_t dec_ipcomp:1;
21979 + /* the packet is either TCP or UDP */
21980 + uint64_t tcp_or_udp:1;
21981 + /* the packet needs to be decrypted (ESP or AH) */
21982 + uint64_t dec_ipsec:1;
21983 + /* the packet is IPv6 */
21984 + uint64_t is_v6:1;
21985 +
21986 + /*
21987 + * (rcv_error, not_IP, IP_exc, is_frag, L4_error,
21988 + * software, etc.).
21989 + */
21990 +
21991 + /*
21992 + * reserved for software use, hardware will clear on
21993 + * packet creation.
21994 + */
21995 + uint64_t software:1;
21996 + /* exceptional conditions below */
21997 + /* the receive interface hardware detected an L4 error
21998 + * (only applies if !is_frag) (only applies if
21999 + * !rcv_error && !not_IP && !IP_exc && !is_frag)
22000 + * failure indicated in err_code below, decode:
22001 + *
22002 + * - 1 = Malformed L4
22003 + * - 2 = L4 Checksum Error: the L4 checksum value is
22004 + * - 3 = UDP Length Error: The UDP length field would
22005 + * make the UDP data longer than what remains in
22006 + * the IP packet (as defined by the IP header
22007 + * length field).
22008 + * - 4 = Bad L4 Port: either the source or destination
22009 + * TCP/UDP port is 0.
22010 + * - 8 = TCP FIN Only: the packet is TCP and only the
22011 + * FIN flag set.
22012 + * - 9 = TCP No Flags: the packet is TCP and no flags
22013 + * are set.
22014 + * - 10 = TCP FIN RST: the packet is TCP and both FIN
22015 + * and RST are set.
22016 + * - 11 = TCP SYN URG: the packet is TCP and both SYN
22017 + * and URG are set.
22018 + * - 12 = TCP SYN RST: the packet is TCP and both SYN
22019 + * and RST are set.
22020 + * - 13 = TCP SYN FIN: the packet is TCP and both SYN
22021 + * and FIN are set.
22022 + */
22023 + uint64_t L4_error:1;
22024 + /* set if the packet is a fragment */
22025 + uint64_t is_frag:1;
22026 + /* the receive interface hardware detected an IP error
22027 + * / exception (only applies if !rcv_error && !not_IP)
22028 + * failure indicated in err_code below, decode:
22029 + *
22030 + * - 1 = Not IP: the IP version field is neither 4 nor
22031 + * 6.
22032 + * - 2 = IPv4 Header Checksum Error: the IPv4 header
22033 + * has a checksum violation.
22034 + * - 3 = IP Malformed Header: the packet is not long
22035 + * enough to contain the IP header.
22036 + * - 4 = IP Malformed: the packet is not long enough
22037 + * to contain the bytes indicated by the IP
22038 + * header. Pad is allowed.
22039 + * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6
22040 + * Hop Count field are zero.
22041 + * - 6 = IP Options
22042 + */
22043 + uint64_t IP_exc:1;
22044 + /*
22045 + * Set if the hardware determined that the packet is a
22046 + * broadcast.
22047 + */
22048 + uint64_t is_bcast:1;
22049 + /*
22050 + * St if the hardware determined that the packet is a
22051 + * multi-cast.
22052 + */
22053 + uint64_t is_mcast:1;
22054 + /*
22055 + * Set if the packet may not be IP (must be zero in
22056 + * this case).
22057 + */
22058 + uint64_t not_IP:1;
22059 + /*
22060 + * The receive interface hardware detected a receive
22061 + * error (must be zero in this case).
22062 + */
22063 + uint64_t rcv_error:1;
22064 + /* lower err_code = first-level descriptor of the
22065 + * work */
22066 + /* zero for packet submitted by hardware that isn't on
22067 + * the slow path */
22068 + /* type is cvmx_pip_err_t */
22069 + uint64_t err_code:8;
22070 + } s;
22071 +
22072 + /* use this to get at the 16 vlan bits */
22073 + struct {
22074 + uint64_t unused1:16;
22075 + uint64_t vlan:16;
22076 + uint64_t unused2:32;
22077 + } svlan;
22078 +
22079 + /*
22080 + * use this struct if the hardware could not determine that
22081 + * the packet is ip.
22082 + */
22083 + struct {
22084 + /*
22085 + * HW sets this to the number of buffers used by this
22086 + * packet.
22087 + */
22088 + uint64_t bufs:8;
22089 + uint64_t unused:8;
22090 + /* set to 1 if we found DSA/VLAN in the L2 */
22091 + uint64_t vlan_valid:1;
22092 + /* Set to 1 if the DSA/VLAN tag is stacked */
22093 + uint64_t vlan_stacked:1;
22094 + uint64_t unassigned:1;
22095 + /*
22096 + * HW sets to the DSA/VLAN CFI flag (valid when
22097 + * vlan_valid)
22098 + */
22099 + uint64_t vlan_cfi:1;
22100 + /*
22101 + * HW sets to the DSA/VLAN_ID field (valid when
22102 + * vlan_valid).
22103 + */
22104 + uint64_t vlan_id:12;
22105 + /*
22106 + * Ring Identifier (if PCIe). Requires
22107 + * PIP_GBL_CTL[RING_EN]=1
22108 + */
22109 + uint64_t pr:4;
22110 + uint64_t unassigned2:12;
22111 + /*
22112 + * reserved for software use, hardware will clear on
22113 + * packet creation.
22114 + */
22115 + uint64_t software:1;
22116 + uint64_t unassigned3:1;
22117 + /*
22118 + * set if the hardware determined that the packet is
22119 + * rarp.
22120 + */
22121 + uint64_t is_rarp:1;
22122 + /*
22123 + * set if the hardware determined that the packet is
22124 + * arp
22125 + */
22126 + uint64_t is_arp:1;
22127 + /*
22128 + * set if the hardware determined that the packet is a
22129 + * broadcast.
22130 + */
22131 + uint64_t is_bcast:1;
22132 + /*
22133 + * set if the hardware determined that the packet is a
22134 + * multi-cast
22135 + */
22136 + uint64_t is_mcast:1;
22137 + /*
22138 + * set if the packet may not be IP (must be one in
22139 + * this case)
22140 + */
22141 + uint64_t not_IP:1;
22142 + /* The receive interface hardware detected a receive
22143 + * error. Failure indicated in err_code below,
22144 + * decode:
22145 + *
22146 + * - 1 = partial error: a packet was partially
22147 + * received, but internal buffering / bandwidth
22148 + * was not adequate to receive the entire
22149 + * packet.
22150 + * - 2 = jabber error: the RGMII packet was too large
22151 + * and is truncated.
22152 + * - 3 = overrun error: the RGMII packet is longer
22153 + * than allowed and had an FCS error.
22154 + * - 4 = oversize error: the RGMII packet is longer
22155 + * than allowed.
22156 + * - 5 = alignment error: the RGMII packet is not an
22157 + * integer number of bytes
22158 + * and had an FCS error (100M and 10M only).
22159 + * - 6 = fragment error: the RGMII packet is shorter
22160 + * than allowed and had an FCS error.
22161 + * - 7 = GMX FCS error: the RGMII packet had an FCS
22162 + * error.
22163 + * - 8 = undersize error: the RGMII packet is shorter
22164 + * than allowed.
22165 + * - 9 = extend error: the RGMII packet had an extend
22166 + * error.
22167 + * - 10 = length mismatch error: the RGMII packet had
22168 + * a length that did not match the length field
22169 + * in the L2 HDR.
22170 + * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII
22171 + * packet had one or more data reception errors
22172 + * (RXERR) or the SPI4 packet had one or more
22173 + * DIP4 errors.
22174 + * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII
22175 + * packet was not large enough to cover the
22176 + * skipped bytes or the SPI4 packet was
22177 + * terminated with an About EOPS.
22178 + * - 13 = RGMII nibble error/SPI4 Port NXA Error: the
22179 + * RGMII packet had a studder error (data not
22180 + * repeated - 10/100M only) or the SPI4 packet
22181 + * was sent to an NXA.
22182 + * - 16 = FCS error: a SPI4.2 packet had an FCS error.
22183 + * - 17 = Skip error: a packet was not large enough to
22184 + * cover the skipped bytes.
22185 + * - 18 = L2 header malformed: the packet is not long
22186 + * enough to contain the L2.
22187 + */
22188 +
22189 + uint64_t rcv_error:1;
22190 + /*
22191 + * lower err_code = first-level descriptor of the
22192 + * work
22193 + */
22194 + /*
22195 + * zero for packet submitted by hardware that isn't on
22196 + * the slow path
22197 + */
22198 + /* type is cvmx_pip_err_t (union, so can't use directly */
22199 + uint64_t err_code:8;
22200 + } snoip;
22201 +
22202 +} cvmx_pip_wqe_word2;
22203 +
22204 +/**
22205 + * Work queue entry format
22206 + *
22207 + * must be 8-byte aligned
22208 + */
22209 +typedef struct {
22210 +
22211 + /*****************************************************************
22212 + * WORD 0
22213 + * HW WRITE: the following 64 bits are filled by HW when a packet arrives
22214 + */
22215 +
22216 + /**
22217 + * raw chksum result generated by the HW
22218 + */
22219 + uint16_t hw_chksum;
22220 + /**
22221 + * Field unused by hardware - available for software
22222 + */
22223 + uint8_t unused;
22224 + /**
22225 + * Next pointer used by hardware for list maintenance.
22226 + * May be written/read by HW before the work queue
22227 + * entry is scheduled to a PP
22228 + * (Only 36 bits used in Octeon 1)
22229 + */
22230 + uint64_t next_ptr:40;
22231 +
22232 + /*****************************************************************
22233 + * WORD 1
22234 + * HW WRITE: the following 64 bits are filled by HW when a packet arrives
22235 + */
22236 +
22237 + /**
22238 + * HW sets to the total number of bytes in the packet
22239 + */
22240 + uint64_t len:16;
22241 + /**
22242 + * HW sets this to input physical port
22243 + */
22244 + uint64_t ipprt:6;
22245 +
22246 + /**
22247 + * HW sets this to what it thought the priority of the input packet was
22248 + */
22249 + uint64_t qos:3;
22250 +
22251 + /**
22252 + * the group that the work queue entry will be scheduled to
22253 + */
22254 + uint64_t grp:4;
22255 + /**
22256 + * the type of the tag (ORDERED, ATOMIC, NULL)
22257 + */
22258 + uint64_t tag_type:3;
22259 + /**
22260 + * the synchronization/ordering tag
22261 + */
22262 + uint64_t tag:32;
22263 +
22264 + /**
22265 + * WORD 2 HW WRITE: the following 64-bits are filled in by
22266 + * hardware when a packet arrives This indicates a variety of
22267 + * status and error conditions.
22268 + */
22269 + cvmx_pip_wqe_word2 word2;
22270 +
22271 + /**
22272 + * Pointer to the first segment of the packet.
22273 + */
22274 + union cvmx_buf_ptr packet_ptr;
22275 +
22276 + /**
22277 + * HW WRITE: octeon will fill in a programmable amount from the
22278 + * packet, up to (at most, but perhaps less) the amount
22279 + * needed to fill the work queue entry to 128 bytes
22280 + *
22281 + * If the packet is recognized to be IP, the hardware starts
22282 + * (except that the IPv4 header is padded for appropriate
22283 + * alignment) writing here where the IP header starts. If the
22284 + * packet is not recognized to be IP, the hardware starts
22285 + * writing the beginning of the packet here.
22286 + */
22287 + uint8_t packet_data[96];
22288 +
22289 + /**
22290 + * If desired, SW can make the work Q entry any length. For the
22291 + * purposes of discussion here, Assume 128B always, as this is all that
22292 + * the hardware deals with.
22293 + *
22294 + */
22295 +
22296 +} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;
22297 +
22298 +#endif /* __CVMX_WQE_H__ */
22299 --- /dev/null
22300 +++ b/drivers/staging/octeon/ethernet-common.c
22301 @@ -0,0 +1,328 @@
22302 +/**********************************************************************
22303 + * Author: Cavium Networks
22304 + *
22305 + * Contact: support@caviumnetworks.com
22306 + * This file is part of the OCTEON SDK
22307 + *
22308 + * Copyright (c) 2003-2007 Cavium Networks
22309 + *
22310 + * This file is free software; you can redistribute it and/or modify
22311 + * it under the terms of the GNU General Public License, Version 2, as
22312 + * published by the Free Software Foundation.
22313 + *
22314 + * This file is distributed in the hope that it will be useful, but
22315 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22316 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22317 + * NONINFRINGEMENT. See the GNU General Public License for more
22318 + * details.
22319 + *
22320 + * You should have received a copy of the GNU General Public License
22321 + * along with this file; if not, write to the Free Software
22322 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22323 + * or visit http://www.gnu.org/licenses/.
22324 + *
22325 + * This file may also be available under a different license from Cavium.
22326 + * Contact Cavium Networks for more information
22327 +**********************************************************************/
22328 +#include <linux/kernel.h>
22329 +#include <linux/mii.h>
22330 +#include <net/dst.h>
22331 +
22332 +#include <asm/atomic.h>
22333 +#include <asm/octeon/octeon.h>
22334 +
22335 +#include "ethernet-defines.h"
22336 +#include "ethernet-tx.h"
22337 +#include "ethernet-mdio.h"
22338 +#include "ethernet-util.h"
22339 +#include "octeon-ethernet.h"
22340 +#include "ethernet-common.h"
22341 +
22342 +#include "cvmx-pip.h"
22343 +#include "cvmx-pko.h"
22344 +#include "cvmx-fau.h"
22345 +#include "cvmx-helper.h"
22346 +
22347 +#include "cvmx-gmxx-defs.h"
22348 +
22349 +/**
22350 + * Get the low level ethernet statistics
22351 + *
22352 + * @dev: Device to get the statistics from
22353 + * Returns Pointer to the statistics
22354 + */
22355 +static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
22356 +{
22357 + cvmx_pip_port_status_t rx_status;
22358 + cvmx_pko_port_status_t tx_status;
22359 + struct octeon_ethernet *priv = netdev_priv(dev);
22360 +
22361 + if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
22362 + if (octeon_is_simulation()) {
22363 + /* The simulator doesn't support statistics */
22364 + memset(&rx_status, 0, sizeof(rx_status));
22365 + memset(&tx_status, 0, sizeof(tx_status));
22366 + } else {
22367 + cvmx_pip_get_port_status(priv->port, 1, &rx_status);
22368 + cvmx_pko_get_port_status(priv->port, 1, &tx_status);
22369 + }
22370 +
22371 + priv->stats.rx_packets += rx_status.inb_packets;
22372 + priv->stats.tx_packets += tx_status.packets;
22373 + priv->stats.rx_bytes += rx_status.inb_octets;
22374 + priv->stats.tx_bytes += tx_status.octets;
22375 + priv->stats.multicast += rx_status.multicast_packets;
22376 + priv->stats.rx_crc_errors += rx_status.inb_errors;
22377 + priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
22378 +
22379 + /*
22380 + * The drop counter must be incremented atomically
22381 + * since the RX tasklet also increments it.
22382 + */
22383 +#ifdef CONFIG_64BIT
22384 + atomic64_add(rx_status.dropped_packets,
22385 + (atomic64_t *)&priv->stats.rx_dropped);
22386 +#else
22387 + atomic_add(rx_status.dropped_packets,
22388 + (atomic_t *)&priv->stats.rx_dropped);
22389 +#endif
22390 + }
22391 +
22392 + return &priv->stats;
22393 +}
22394 +
22395 +/**
22396 + * Set the multicast list. Currently unimplemented.
22397 + *
22398 + * @dev: Device to work on
22399 + */
22400 +static void cvm_oct_common_set_multicast_list(struct net_device *dev)
22401 +{
22402 + union cvmx_gmxx_prtx_cfg gmx_cfg;
22403 + struct octeon_ethernet *priv = netdev_priv(dev);
22404 + int interface = INTERFACE(priv->port);
22405 + int index = INDEX(priv->port);
22406 +
22407 + if ((interface < 2)
22408 + && (cvmx_helper_interface_get_mode(interface) !=
22409 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
22410 + union cvmx_gmxx_rxx_adr_ctl control;
22411 + control.u64 = 0;
22412 + control.s.bcst = 1; /* Allow broadcast MAC addresses */
22413 +
22414 + if (dev->mc_list || (dev->flags & IFF_ALLMULTI) ||
22415 + (dev->flags & IFF_PROMISC))
22416 + /* Force accept multicast packets */
22417 + control.s.mcst = 2;
22418 + else
22419 + /* Force reject multicat packets */
22420 + control.s.mcst = 1;
22421 +
22422 + if (dev->flags & IFF_PROMISC)
22423 + /*
22424 + * Reject matches if promisc. Since CAM is
22425 + * shut off, should accept everything.
22426 + */
22427 + control.s.cam_mode = 0;
22428 + else
22429 + /* Filter packets based on the CAM */
22430 + control.s.cam_mode = 1;
22431 +
22432 + gmx_cfg.u64 =
22433 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
22434 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22435 + gmx_cfg.u64 & ~1ull);
22436 +
22437 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
22438 + control.u64);
22439 + if (dev->flags & IFF_PROMISC)
22440 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
22441 + (index, interface), 0);
22442 + else
22443 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
22444 + (index, interface), 1);
22445 +
22446 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22447 + gmx_cfg.u64);
22448 + }
22449 +}
22450 +
22451 +/**
22452 + * Set the hardware MAC address for a device
22453 + *
22454 + * @dev: Device to change the MAC address for
22455 + * @addr: Address structure to change it too. MAC address is addr + 2.
22456 + * Returns Zero on success
22457 + */
22458 +static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
22459 +{
22460 + struct octeon_ethernet *priv = netdev_priv(dev);
22461 + union cvmx_gmxx_prtx_cfg gmx_cfg;
22462 + int interface = INTERFACE(priv->port);
22463 + int index = INDEX(priv->port);
22464 +
22465 + memcpy(dev->dev_addr, addr + 2, 6);
22466 +
22467 + if ((interface < 2)
22468 + && (cvmx_helper_interface_get_mode(interface) !=
22469 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
22470 + int i;
22471 + uint8_t *ptr = addr;
22472 + uint64_t mac = 0;
22473 + for (i = 0; i < 6; i++)
22474 + mac = (mac << 8) | (uint64_t) (ptr[i + 2]);
22475 +
22476 + gmx_cfg.u64 =
22477 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
22478 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22479 + gmx_cfg.u64 & ~1ull);
22480 +
22481 + cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
22482 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
22483 + ptr[2]);
22484 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
22485 + ptr[3]);
22486 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
22487 + ptr[4]);
22488 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
22489 + ptr[5]);
22490 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
22491 + ptr[6]);
22492 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
22493 + ptr[7]);
22494 + cvm_oct_common_set_multicast_list(dev);
22495 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22496 + gmx_cfg.u64);
22497 + }
22498 + return 0;
22499 +}
22500 +
22501 +/**
22502 + * Change the link MTU. Unimplemented
22503 + *
22504 + * @dev: Device to change
22505 + * @new_mtu: The new MTU
22506 + *
22507 + * Returns Zero on success
22508 + */
22509 +static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
22510 +{
22511 + struct octeon_ethernet *priv = netdev_priv(dev);
22512 + int interface = INTERFACE(priv->port);
22513 + int index = INDEX(priv->port);
22514 +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
22515 + int vlan_bytes = 4;
22516 +#else
22517 + int vlan_bytes = 0;
22518 +#endif
22519 +
22520 + /*
22521 + * Limit the MTU to make sure the ethernet packets are between
22522 + * 64 bytes and 65535 bytes.
22523 + */
22524 + if ((new_mtu + 14 + 4 + vlan_bytes < 64)
22525 + || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
22526 + pr_err("MTU must be between %d and %d.\n",
22527 + 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes);
22528 + return -EINVAL;
22529 + }
22530 + dev->mtu = new_mtu;
22531 +
22532 + if ((interface < 2)
22533 + && (cvmx_helper_interface_get_mode(interface) !=
22534 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
22535 + /* Add ethernet header and FCS, and VLAN if configured. */
22536 + int max_packet = new_mtu + 14 + 4 + vlan_bytes;
22537 +
22538 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
22539 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
22540 + /* Signal errors on packets larger than the MTU */
22541 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface),
22542 + max_packet);
22543 + } else {
22544 + /*
22545 + * Set the hardware to truncate packets larger
22546 + * than the MTU and smaller the 64 bytes.
22547 + */
22548 + union cvmx_pip_frm_len_chkx frm_len_chk;
22549 + frm_len_chk.u64 = 0;
22550 + frm_len_chk.s.minlen = 64;
22551 + frm_len_chk.s.maxlen = max_packet;
22552 + cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
22553 + frm_len_chk.u64);
22554 + }
22555 + /*
22556 + * Set the hardware to truncate packets larger than
22557 + * the MTU. The jabber register must be set to a
22558 + * multiple of 8 bytes, so round up.
22559 + */
22560 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
22561 + (max_packet + 7) & ~7u);
22562 + }
22563 + return 0;
22564 +}
22565 +
22566 +/**
22567 + * Per network device initialization
22568 + *
22569 + * @dev: Device to initialize
22570 + * Returns Zero on success
22571 + */
22572 +int cvm_oct_common_init(struct net_device *dev)
22573 +{
22574 + static int count;
22575 + char mac[8] = { 0x00, 0x00,
22576 + octeon_bootinfo->mac_addr_base[0],
22577 + octeon_bootinfo->mac_addr_base[1],
22578 + octeon_bootinfo->mac_addr_base[2],
22579 + octeon_bootinfo->mac_addr_base[3],
22580 + octeon_bootinfo->mac_addr_base[4],
22581 + octeon_bootinfo->mac_addr_base[5] + count
22582 + };
22583 + struct octeon_ethernet *priv = netdev_priv(dev);
22584 +
22585 + /*
22586 + * Force the interface to use the POW send if always_use_pow
22587 + * was specified or it is in the pow send list.
22588 + */
22589 + if ((pow_send_group != -1)
22590 + && (always_use_pow || strstr(pow_send_list, dev->name)))
22591 + priv->queue = -1;
22592 +
22593 + if (priv->queue != -1) {
22594 + dev->hard_start_xmit = cvm_oct_xmit;
22595 + if (USE_HW_TCPUDP_CHECKSUM)
22596 + dev->features |= NETIF_F_IP_CSUM;
22597 + } else
22598 + dev->hard_start_xmit = cvm_oct_xmit_pow;
22599 + count++;
22600 +
22601 + dev->get_stats = cvm_oct_common_get_stats;
22602 + dev->set_mac_address = cvm_oct_common_set_mac_address;
22603 + dev->set_multicast_list = cvm_oct_common_set_multicast_list;
22604 + dev->change_mtu = cvm_oct_common_change_mtu;
22605 + dev->do_ioctl = cvm_oct_ioctl;
22606 + /* We do our own locking, Linux doesn't need to */
22607 + dev->features |= NETIF_F_LLTX;
22608 + SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
22609 +#ifdef CONFIG_NET_POLL_CONTROLLER
22610 + dev->poll_controller = cvm_oct_poll_controller;
22611 +#endif
22612 +
22613 + cvm_oct_mdio_setup_device(dev);
22614 + dev->set_mac_address(dev, mac);
22615 + dev->change_mtu(dev, dev->mtu);
22616 +
22617 + /*
22618 + * Zero out stats for port so we won't mistakenly show
22619 + * counters from the bootloader.
22620 + */
22621 + memset(dev->get_stats(dev), 0, sizeof(struct net_device_stats));
22622 +
22623 + return 0;
22624 +}
22625 +
22626 +void cvm_oct_common_uninit(struct net_device *dev)
22627 +{
22628 + /* Currently nothing to do */
22629 +}
22630 --- /dev/null
22631 +++ b/drivers/staging/octeon/ethernet-common.h
22632 @@ -0,0 +1,29 @@
22633 +/*********************************************************************
22634 + * Author: Cavium Networks
22635 + *
22636 + * Contact: support@caviumnetworks.com
22637 + * This file is part of the OCTEON SDK
22638 + *
22639 + * Copyright (c) 2003-2007 Cavium Networks
22640 + *
22641 + * This file is free software; you can redistribute it and/or modify
22642 + * it under the terms of the GNU General Public License, Version 2, as
22643 + * published by the Free Software Foundation.
22644 + *
22645 + * This file is distributed in the hope that it will be useful, but
22646 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22647 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22648 + * NONINFRINGEMENT. See the GNU General Public License for more
22649 + * details.
22650 + *
22651 + * You should have received a copy of the GNU General Public License
22652 + * along with this file; if not, write to the Free Software
22653 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22654 + * or visit http://www.gnu.org/licenses/.
22655 + *
22656 + * This file may also be available under a different license from Cavium.
22657 + * Contact Cavium Networks for more information
22658 +*********************************************************************/
22659 +
22660 +int cvm_oct_common_init(struct net_device *dev);
22661 +void cvm_oct_common_uninit(struct net_device *dev);
22662 --- /dev/null
22663 +++ b/drivers/staging/octeon/ethernet-defines.h
22664 @@ -0,0 +1,134 @@
22665 +/**********************************************************************
22666 + * Author: Cavium Networks
22667 + *
22668 + * Contact: support@caviumnetworks.com
22669 + * This file is part of the OCTEON SDK
22670 + *
22671 + * Copyright (c) 2003-2007 Cavium Networks
22672 + *
22673 + * This file is free software; you can redistribute it and/or modify
22674 + * it under the terms of the GNU General Public License, Version 2, as
22675 + * published by the Free Software Foundation.
22676 + *
22677 + * This file is distributed in the hope that it will be useful, but
22678 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22679 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22680 + * NONINFRINGEMENT. See the GNU General Public License for more
22681 + * details.
22682 + *
22683 + * You should have received a copy of the GNU General Public License
22684 + * along with this file; if not, write to the Free Software
22685 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22686 + * or visit http://www.gnu.org/licenses/.
22687 + *
22688 + * This file may also be available under a different license from Cavium.
22689 + * Contact Cavium Networks for more information
22690 +**********************************************************************/
22691 +
22692 +/*
22693 + * A few defines are used to control the operation of this driver:
22694 + * CONFIG_CAVIUM_RESERVE32
22695 + * This kernel config options controls the amount of memory configured
22696 + * in a wired TLB entry for all processes to share. If this is set, the
22697 + * driver will use this memory instead of kernel memory for pools. This
22698 + * allows 32bit userspace application to access the buffers, but also
22699 + * requires all received packets to be copied.
22700 + * CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
22701 + * This kernel config option allows the user to control the number of
22702 + * packet and work queue buffers allocated by the driver. If this is zero,
22703 + * the driver uses the default from below.
22704 + * USE_SKBUFFS_IN_HW
22705 + * Tells the driver to populate the packet buffers with kernel skbuffs.
22706 + * This allows the driver to receive packets without copying them. It also
22707 + * means that 32bit userspace can't access the packet buffers.
22708 + * USE_32BIT_SHARED
22709 + * This define tells the driver to allocate memory for buffers from the
22710 + * 32bit sahred region instead of the kernel memory space.
22711 + * USE_HW_TCPUDP_CHECKSUM
22712 + * Controls if the Octeon TCP/UDP checksum engine is used for packet
22713 + * output. If this is zero, the kernel will perform the checksum in
22714 + * software.
22715 + * USE_MULTICORE_RECEIVE
22716 + * Process receive interrupts on multiple cores. This spreads the network
22717 + * load across the first 8 processors. If ths is zero, only one core
22718 + * processes incomming packets.
22719 + * USE_ASYNC_IOBDMA
22720 + * Use asynchronous IO access to hardware. This uses Octeon's asynchronous
22721 + * IOBDMAs to issue IO accesses without stalling. Set this to zero
22722 + * to disable this. Note that IOBDMAs require CVMSEG.
22723 + * REUSE_SKBUFFS_WITHOUT_FREE
22724 + * Allows the TX path to free an skbuff into the FPA hardware pool. This
22725 + * can significantly improve performance for forwarding and bridging, but
22726 + * may be somewhat dangerous. Checks are made, but if any buffer is reused
22727 + * without the proper Linux cleanup, the networking stack may have very
22728 + * bizarre bugs.
22729 + */
22730 +#ifndef __ETHERNET_DEFINES_H__
22731 +#define __ETHERNET_DEFINES_H__
22732 +
22733 +#include "cvmx-config.h"
22734 +
22735 +
22736 +#define OCTEON_ETHERNET_VERSION "1.9"
22737 +
22738 +#ifndef CONFIG_CAVIUM_RESERVE32
22739 +#define CONFIG_CAVIUM_RESERVE32 0
22740 +#endif
22741 +
22742 +#if CONFIG_CAVIUM_RESERVE32
22743 +#define USE_32BIT_SHARED 1
22744 +#define USE_SKBUFFS_IN_HW 0
22745 +#define REUSE_SKBUFFS_WITHOUT_FREE 0
22746 +#else
22747 +#define USE_32BIT_SHARED 0
22748 +#define USE_SKBUFFS_IN_HW 1
22749 +#ifdef CONFIG_NETFILTER
22750 +#define REUSE_SKBUFFS_WITHOUT_FREE 0
22751 +#else
22752 +#define REUSE_SKBUFFS_WITHOUT_FREE 1
22753 +#endif
22754 +#endif
22755 +
22756 +/* Max interrupts per second per core */
22757 +#define INTERRUPT_LIMIT 10000
22758 +
22759 +/* Don't limit the number of interrupts */
22760 +/*#define INTERRUPT_LIMIT 0 */
22761 +#define USE_HW_TCPUDP_CHECKSUM 1
22762 +
22763 +#define USE_MULTICORE_RECEIVE 1
22764 +
22765 +/* Enable Random Early Dropping under load */
22766 +#define USE_RED 1
22767 +#define USE_ASYNC_IOBDMA (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0)
22768 +
22769 +/*
22770 + * Allow SW based preamble removal at 10Mbps to workaround PHYs giving
22771 + * us bad preambles.
22772 + */
22773 +#define USE_10MBPS_PREAMBLE_WORKAROUND 1
22774 +/*
22775 + * Use this to have all FPA frees also tell the L2 not to write data
22776 + * to memory.
22777 + */
22778 +#define DONT_WRITEBACK(x) (x)
22779 +/* Use this to not have FPA frees control L2 */
22780 +/*#define DONT_WRITEBACK(x) 0 */
22781 +
22782 +/* Maximum number of packets to process per interrupt. */
22783 +#define MAX_RX_PACKETS 120
22784 +#define MAX_OUT_QUEUE_DEPTH 1000
22785 +
22786 +#ifndef CONFIG_SMP
22787 +#undef USE_MULTICORE_RECEIVE
22788 +#define USE_MULTICORE_RECEIVE 0
22789 +#endif
22790 +
22791 +#define IP_PROTOCOL_TCP 6
22792 +#define IP_PROTOCOL_UDP 0x11
22793 +
22794 +#define FAU_NUM_PACKET_BUFFERS_TO_FREE (CVMX_FAU_REG_END - sizeof(uint32_t))
22795 +#define TOTAL_NUMBER_OF_PORTS (CVMX_PIP_NUM_INPUT_PORTS+1)
22796 +
22797 +
22798 +#endif /* __ETHERNET_DEFINES_H__ */
22799 --- /dev/null
22800 +++ b/drivers/staging/octeon/ethernet-mdio.c
22801 @@ -0,0 +1,231 @@
22802 +/**********************************************************************
22803 + * Author: Cavium Networks
22804 + *
22805 + * Contact: support@caviumnetworks.com
22806 + * This file is part of the OCTEON SDK
22807 + *
22808 + * Copyright (c) 2003-2007 Cavium Networks
22809 + *
22810 + * This file is free software; you can redistribute it and/or modify
22811 + * it under the terms of the GNU General Public License, Version 2, as
22812 + * published by the Free Software Foundation.
22813 + *
22814 + * This file is distributed in the hope that it will be useful, but
22815 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22816 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22817 + * NONINFRINGEMENT. See the GNU General Public License for more
22818 + * details.
22819 + *
22820 + * You should have received a copy of the GNU General Public License
22821 + * along with this file; if not, write to the Free Software
22822 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22823 + * or visit http://www.gnu.org/licenses/.
22824 + *
22825 + * This file may also be available under a different license from Cavium.
22826 + * Contact Cavium Networks for more information
22827 +**********************************************************************/
22828 +#include <linux/kernel.h>
22829 +#include <linux/ethtool.h>
22830 +#include <linux/mii.h>
22831 +#include <net/dst.h>
22832 +
22833 +#include <asm/octeon/octeon.h>
22834 +
22835 +#include "ethernet-defines.h"
22836 +#include "octeon-ethernet.h"
22837 +#include "ethernet-mdio.h"
22838 +
22839 +#include "cvmx-helper-board.h"
22840 +
22841 +#include "cvmx-smix-defs.h"
22842 +
22843 +DECLARE_MUTEX(mdio_sem);
22844 +
22845 +/**
22846 + * Perform an MII read. Called by the generic MII routines
22847 + *
22848 + * @dev: Device to perform read for
22849 + * @phy_id: The MII phy id
22850 + * @location: Register location to read
22851 + * Returns Result from the read or zero on failure
22852 + */
22853 +static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location)
22854 +{
22855 + union cvmx_smix_cmd smi_cmd;
22856 + union cvmx_smix_rd_dat smi_rd;
22857 +
22858 + smi_cmd.u64 = 0;
22859 + smi_cmd.s.phy_op = 1;
22860 + smi_cmd.s.phy_adr = phy_id;
22861 + smi_cmd.s.reg_adr = location;
22862 + cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
22863 +
22864 + do {
22865 + if (!in_interrupt())
22866 + yield();
22867 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0));
22868 + } while (smi_rd.s.pending);
22869 +
22870 + if (smi_rd.s.val)
22871 + return smi_rd.s.dat;
22872 + else
22873 + return 0;
22874 +}
22875 +
22876 +static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id,
22877 + int location)
22878 +{
22879 + return 0xffff;
22880 +}
22881 +
22882 +/**
22883 + * Perform an MII write. Called by the generic MII routines
22884 + *
22885 + * @dev: Device to perform write for
22886 + * @phy_id: The MII phy id
22887 + * @location: Register location to write
22888 + * @val: Value to write
22889 + */
22890 +static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location,
22891 + int val)
22892 +{
22893 + union cvmx_smix_cmd smi_cmd;
22894 + union cvmx_smix_wr_dat smi_wr;
22895 +
22896 + smi_wr.u64 = 0;
22897 + smi_wr.s.dat = val;
22898 + cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64);
22899 +
22900 + smi_cmd.u64 = 0;
22901 + smi_cmd.s.phy_op = 0;
22902 + smi_cmd.s.phy_adr = phy_id;
22903 + smi_cmd.s.reg_adr = location;
22904 + cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
22905 +
22906 + do {
22907 + if (!in_interrupt())
22908 + yield();
22909 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0));
22910 + } while (smi_wr.s.pending);
22911 +}
22912 +
22913 +static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id,
22914 + int location, int val)
22915 +{
22916 +}
22917 +
22918 +static void cvm_oct_get_drvinfo(struct net_device *dev,
22919 + struct ethtool_drvinfo *info)
22920 +{
22921 + strcpy(info->driver, "cavium-ethernet");
22922 + strcpy(info->version, OCTEON_ETHERNET_VERSION);
22923 + strcpy(info->bus_info, "Builtin");
22924 +}
22925 +
22926 +static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
22927 +{
22928 + struct octeon_ethernet *priv = netdev_priv(dev);
22929 + int ret;
22930 +
22931 + down(&mdio_sem);
22932 + ret = mii_ethtool_gset(&priv->mii_info, cmd);
22933 + up(&mdio_sem);
22934 +
22935 + return ret;
22936 +}
22937 +
22938 +static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
22939 +{
22940 + struct octeon_ethernet *priv = netdev_priv(dev);
22941 + int ret;
22942 +
22943 + down(&mdio_sem);
22944 + ret = mii_ethtool_sset(&priv->mii_info, cmd);
22945 + up(&mdio_sem);
22946 +
22947 + return ret;
22948 +}
22949 +
22950 +static int cvm_oct_nway_reset(struct net_device *dev)
22951 +{
22952 + struct octeon_ethernet *priv = netdev_priv(dev);
22953 + int ret;
22954 +
22955 + down(&mdio_sem);
22956 + ret = mii_nway_restart(&priv->mii_info);
22957 + up(&mdio_sem);
22958 +
22959 + return ret;
22960 +}
22961 +
22962 +static u32 cvm_oct_get_link(struct net_device *dev)
22963 +{
22964 + struct octeon_ethernet *priv = netdev_priv(dev);
22965 + u32 ret;
22966 +
22967 + down(&mdio_sem);
22968 + ret = mii_link_ok(&priv->mii_info);
22969 + up(&mdio_sem);
22970 +
22971 + return ret;
22972 +}
22973 +
22974 +struct ethtool_ops cvm_oct_ethtool_ops = {
22975 + .get_drvinfo = cvm_oct_get_drvinfo,
22976 + .get_settings = cvm_oct_get_settings,
22977 + .set_settings = cvm_oct_set_settings,
22978 + .nway_reset = cvm_oct_nway_reset,
22979 + .get_link = cvm_oct_get_link,
22980 + .get_sg = ethtool_op_get_sg,
22981 + .get_tx_csum = ethtool_op_get_tx_csum,
22982 +};
22983 +
22984 +/**
22985 + * IOCTL support for PHY control
22986 + *
22987 + * @dev: Device to change
22988 + * @rq: the request
22989 + * @cmd: the command
22990 + * Returns Zero on success
22991 + */
22992 +int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
22993 +{
22994 + struct octeon_ethernet *priv = netdev_priv(dev);
22995 + struct mii_ioctl_data *data = if_mii(rq);
22996 + unsigned int duplex_chg;
22997 + int ret;
22998 +
22999 + down(&mdio_sem);
23000 + ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg);
23001 + up(&mdio_sem);
23002 +
23003 + return ret;
23004 +}
23005 +
23006 +/**
23007 + * Setup the MDIO device structures
23008 + *
23009 + * @dev: Device to setup
23010 + *
23011 + * Returns Zero on success, negative on failure
23012 + */
23013 +int cvm_oct_mdio_setup_device(struct net_device *dev)
23014 +{
23015 + struct octeon_ethernet *priv = netdev_priv(dev);
23016 + int phy_id = cvmx_helper_board_get_mii_address(priv->port);
23017 + if (phy_id != -1) {
23018 + priv->mii_info.dev = dev;
23019 + priv->mii_info.phy_id = phy_id;
23020 + priv->mii_info.phy_id_mask = 0xff;
23021 + priv->mii_info.supports_gmii = 1;
23022 + priv->mii_info.reg_num_mask = 0x1f;
23023 + priv->mii_info.mdio_read = cvm_oct_mdio_read;
23024 + priv->mii_info.mdio_write = cvm_oct_mdio_write;
23025 + } else {
23026 + /* Supply dummy MDIO routines so the kernel won't crash
23027 + if the user tries to read them */
23028 + priv->mii_info.mdio_read = cvm_oct_mdio_dummy_read;
23029 + priv->mii_info.mdio_write = cvm_oct_mdio_dummy_write;
23030 + }
23031 + return 0;
23032 +}
23033 --- /dev/null
23034 +++ b/drivers/staging/octeon/ethernet-mdio.h
23035 @@ -0,0 +1,46 @@
23036 +/*********************************************************************
23037 + * Author: Cavium Networks
23038 + *
23039 + * Contact: support@caviumnetworks.com
23040 + * This file is part of the OCTEON SDK
23041 + *
23042 + * Copyright (c) 2003-2007 Cavium Networks
23043 + *
23044 + * This file is free software; you can redistribute it and/or modify
23045 + * it under the terms of the GNU General Public License, Version 2, as
23046 + * published by the Free Software Foundation.
23047 + *
23048 + * This file is distributed in the hope that it will be useful, but
23049 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23050 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23051 + * NONINFRINGEMENT. See the GNU General Public License for more
23052 + * details.
23053 + *
23054 + * You should have received a copy of the GNU General Public License
23055 + * along with this file; if not, write to the Free Software
23056 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23057 + * or visit http://www.gnu.org/licenses/.
23058 + *
23059 + * This file may also be available under a different license from Cavium.
23060 + * Contact Cavium Networks for more information
23061 +*********************************************************************/
23062 +#include <linux/module.h>
23063 +#include <linux/kernel.h>
23064 +#include <linux/netdevice.h>
23065 +#include <linux/init.h>
23066 +#include <linux/etherdevice.h>
23067 +#include <linux/ip.h>
23068 +#include <linux/string.h>
23069 +#include <linux/ethtool.h>
23070 +#include <linux/mii.h>
23071 +#include <linux/seq_file.h>
23072 +#include <linux/proc_fs.h>
23073 +#include <net/dst.h>
23074 +#ifdef CONFIG_XFRM
23075 +#include <linux/xfrm.h>
23076 +#include <net/xfrm.h>
23077 +#endif /* CONFIG_XFRM */
23078 +
23079 +extern struct ethtool_ops cvm_oct_ethtool_ops;
23080 +int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
23081 +int cvm_oct_mdio_setup_device(struct net_device *dev);
23082 --- /dev/null
23083 +++ b/drivers/staging/octeon/ethernet-mem.c
23084 @@ -0,0 +1,198 @@
23085 +/**********************************************************************
23086 + * Author: Cavium Networks
23087 + *
23088 + * Contact: support@caviumnetworks.com
23089 + * This file is part of the OCTEON SDK
23090 + *
23091 + * Copyright (c) 2003-2007 Cavium Networks
23092 + *
23093 + * This file is free software; you can redistribute it and/or modify
23094 + * it under the terms of the GNU General Public License, Version 2, as
23095 + * published by the Free Software Foundation.
23096 + *
23097 + * This file is distributed in the hope that it will be useful, but
23098 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23099 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23100 + * NONINFRINGEMENT. See the GNU General Public License for more
23101 + * details.
23102 + *
23103 + * You should have received a copy of the GNU General Public License
23104 + * along with this file; if not, write to the Free Software
23105 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23106 + * or visit http://www.gnu.org/licenses/.
23107 + *
23108 + * This file may also be available under a different license from Cavium.
23109 + * Contact Cavium Networks for more information
23110 +**********************************************************************/
23111 +#include <linux/kernel.h>
23112 +#include <linux/netdevice.h>
23113 +#include <linux/mii.h>
23114 +#include <net/dst.h>
23115 +
23116 +#include <asm/octeon/octeon.h>
23117 +
23118 +#include "ethernet-defines.h"
23119 +
23120 +#include "cvmx-fpa.h"
23121 +
23122 +/**
23123 + * Fill the supplied hardware pool with skbuffs
23124 + *
23125 + * @pool: Pool to allocate an skbuff for
23126 + * @size: Size of the buffer needed for the pool
23127 + * @elements: Number of buffers to allocate
23128 + */
23129 +static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements)
23130 +{
23131 + int freed = elements;
23132 + while (freed) {
23133 +
23134 + struct sk_buff *skb = dev_alloc_skb(size + 128);
23135 + if (unlikely(skb == NULL)) {
23136 + pr_warning
23137 + ("Failed to allocate skb for hardware pool %d\n",
23138 + pool);
23139 + break;
23140 + }
23141 +
23142 + skb_reserve(skb, 128 - (((unsigned long)skb->data) & 0x7f));
23143 + *(struct sk_buff **)(skb->data - sizeof(void *)) = skb;
23144 + cvmx_fpa_free(skb->data, pool, DONT_WRITEBACK(size / 128));
23145 + freed--;
23146 + }
23147 + return elements - freed;
23148 +}
23149 +
23150 +/**
23151 + * Free the supplied hardware pool of skbuffs
23152 + *
23153 + * @pool: Pool to allocate an skbuff for
23154 + * @size: Size of the buffer needed for the pool
23155 + * @elements: Number of buffers to allocate
23156 + */
23157 +static void cvm_oct_free_hw_skbuff(int pool, int size, int elements)
23158 +{
23159 + char *memory;
23160 +
23161 + do {
23162 + memory = cvmx_fpa_alloc(pool);
23163 + if (memory) {
23164 + struct sk_buff *skb =
23165 + *(struct sk_buff **)(memory - sizeof(void *));
23166 + elements--;
23167 + dev_kfree_skb(skb);
23168 + }
23169 + } while (memory);
23170 +
23171 + if (elements < 0)
23172 + pr_warning("Freeing of pool %u had too many skbuffs (%d)\n",
23173 + pool, elements);
23174 + else if (elements > 0)
23175 + pr_warning("Freeing of pool %u is missing %d skbuffs\n",
23176 + pool, elements);
23177 +}
23178 +
23179 +/**
23180 + * This function fills a hardware pool with memory. Depending
23181 + * on the config defines, this memory might come from the
23182 + * kernel or global 32bit memory allocated with
23183 + * cvmx_bootmem_alloc.
23184 + *
23185 + * @pool: Pool to populate
23186 + * @size: Size of each buffer in the pool
23187 + * @elements: Number of buffers to allocate
23188 + */
23189 +static int cvm_oct_fill_hw_memory(int pool, int size, int elements)
23190 +{
23191 + char *memory;
23192 + int freed = elements;
23193 +
23194 + if (USE_32BIT_SHARED) {
23195 + extern uint64_t octeon_reserve32_memory;
23196 +
23197 + memory =
23198 + cvmx_bootmem_alloc_range(elements * size, 128,
23199 + octeon_reserve32_memory,
23200 + octeon_reserve32_memory +
23201 + (CONFIG_CAVIUM_RESERVE32 << 20) -
23202 + 1);
23203 + if (memory == NULL)
23204 + panic("Unable to allocate %u bytes for FPA pool %d\n",
23205 + elements * size, pool);
23206 +
23207 + pr_notice("Memory range %p - %p reserved for "
23208 + "hardware\n", memory,
23209 + memory + elements * size - 1);
23210 +
23211 + while (freed) {
23212 + cvmx_fpa_free(memory, pool, 0);
23213 + memory += size;
23214 + freed--;
23215 + }
23216 + } else {
23217 + while (freed) {
23218 + /* We need to force alignment to 128 bytes here */
23219 + memory = kmalloc(size + 127, GFP_ATOMIC);
23220 + if (unlikely(memory == NULL)) {
23221 + pr_warning("Unable to allocate %u bytes for "
23222 + "FPA pool %d\n",
23223 + elements * size, pool);
23224 + break;
23225 + }
23226 + memory = (char *)(((unsigned long)memory + 127) & -128);
23227 + cvmx_fpa_free(memory, pool, 0);
23228 + freed--;
23229 + }
23230 + }
23231 + return elements - freed;
23232 +}
23233 +
23234 +/**
23235 + * Free memory previously allocated with cvm_oct_fill_hw_memory
23236 + *
23237 + * @pool: FPA pool to free
23238 + * @size: Size of each buffer in the pool
23239 + * @elements: Number of buffers that should be in the pool
23240 + */
23241 +static void cvm_oct_free_hw_memory(int pool, int size, int elements)
23242 +{
23243 + if (USE_32BIT_SHARED) {
23244 + pr_warning("Warning: 32 shared memory is not freeable\n");
23245 + } else {
23246 + char *memory;
23247 + do {
23248 + memory = cvmx_fpa_alloc(pool);
23249 + if (memory) {
23250 + elements--;
23251 + kfree(phys_to_virt(cvmx_ptr_to_phys(memory)));
23252 + }
23253 + } while (memory);
23254 +
23255 + if (elements < 0)
23256 + pr_warning("Freeing of pool %u had too many "
23257 + "buffers (%d)\n",
23258 + pool, elements);
23259 + else if (elements > 0)
23260 + pr_warning("Warning: Freeing of pool %u is "
23261 + "missing %d buffers\n",
23262 + pool, elements);
23263 + }
23264 +}
23265 +
23266 +int cvm_oct_mem_fill_fpa(int pool, int size, int elements)
23267 +{
23268 + int freed;
23269 + if (USE_SKBUFFS_IN_HW)
23270 + freed = cvm_oct_fill_hw_skbuff(pool, size, elements);
23271 + else
23272 + freed = cvm_oct_fill_hw_memory(pool, size, elements);
23273 + return freed;
23274 +}
23275 +
23276 +void cvm_oct_mem_empty_fpa(int pool, int size, int elements)
23277 +{
23278 + if (USE_SKBUFFS_IN_HW)
23279 + cvm_oct_free_hw_skbuff(pool, size, elements);
23280 + else
23281 + cvm_oct_free_hw_memory(pool, size, elements);
23282 +}
23283 --- /dev/null
23284 +++ b/drivers/staging/octeon/ethernet-mem.h
23285 @@ -0,0 +1,29 @@
23286 +/*********************************************************************
23287 + * Author: Cavium Networks
23288 + *
23289 + * Contact: support@caviumnetworks.com
23290 + * This file is part of the OCTEON SDK
23291 + *
23292 + * Copyright (c) 2003-2007 Cavium Networks
23293 + *
23294 + * This file is free software; you can redistribute it and/or modify
23295 + * it under the terms of the GNU General Public License, Version 2, as
23296 + * published by the Free Software Foundation.
23297 + *
23298 + * This file is distributed in the hope that it will be useful, but
23299 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23300 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23301 + * NONINFRINGEMENT. See the GNU General Public License for more
23302 + * details.
23303 + *
23304 + * You should have received a copy of the GNU General Public License
23305 + * along with this file; if not, write to the Free Software
23306 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23307 + * or visit http://www.gnu.org/licenses/.
23308 + *
23309 + * This file may also be available under a different license from Cavium.
23310 + * Contact Cavium Networks for more information
23311 +********************************************************************/
23312 +
23313 +int cvm_oct_mem_fill_fpa(int pool, int size, int elements);
23314 +void cvm_oct_mem_empty_fpa(int pool, int size, int elements);
23315 --- /dev/null
23316 +++ b/drivers/staging/octeon/ethernet-proc.c
23317 @@ -0,0 +1,256 @@
23318 +/**********************************************************************
23319 + * Author: Cavium Networks
23320 + *
23321 + * Contact: support@caviumnetworks.com
23322 + * This file is part of the OCTEON SDK
23323 + *
23324 + * Copyright (c) 2003-2007 Cavium Networks
23325 + *
23326 + * This file is free software; you can redistribute it and/or modify
23327 + * it under the terms of the GNU General Public License, Version 2, as
23328 + * published by the Free Software Foundation.
23329 + *
23330 + * This file is distributed in the hope that it will be useful, but
23331 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23332 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23333 + * NONINFRINGEMENT. See the GNU General Public License for more
23334 + * details.
23335 + *
23336 + * You should have received a copy of the GNU General Public License
23337 + * along with this file; if not, write to the Free Software
23338 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23339 + * or visit http://www.gnu.org/licenses/.
23340 + *
23341 + * This file may also be available under a different license from Cavium.
23342 + * Contact Cavium Networks for more information
23343 +**********************************************************************/
23344 +#include <linux/kernel.h>
23345 +#include <linux/mii.h>
23346 +#include <linux/seq_file.h>
23347 +#include <linux/proc_fs.h>
23348 +#include <net/dst.h>
23349 +
23350 +#include <asm/octeon/octeon.h>
23351 +
23352 +#include "octeon-ethernet.h"
23353 +#include "ethernet-defines.h"
23354 +
23355 +#include "cvmx-helper.h"
23356 +#include "cvmx-pip.h"
23357 +
23358 +static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev,
23359 + int phy_id, int offset)
23360 +{
23361 + struct octeon_ethernet *priv = netdev_priv(dev);
23362 +
23363 + priv->mii_info.mdio_write(dev, phy_id, 0x1d, 0xcc00 | offset);
23364 + return ((uint64_t) priv->mii_info.
23365 + mdio_read(dev, phy_id,
23366 + 0x1e) << 16) | (uint64_t) priv->mii_info.
23367 + mdio_read(dev, phy_id, 0x1f);
23368 +}
23369 +
23370 +static int cvm_oct_stats_switch_show(struct seq_file *m, void *v)
23371 +{
23372 + static const int ports[] = { 0, 1, 2, 3, 9, -1 };
23373 + struct net_device *dev = cvm_oct_device[0];
23374 + int index = 0;
23375 +
23376 + while (ports[index] != -1) {
23377 +
23378 + /* Latch port */
23379 + struct octeon_ethernet *priv = netdev_priv(dev);
23380 +
23381 + priv->mii_info.mdio_write(dev, 0x1b, 0x1d,
23382 + 0xdc00 | ports[index]);
23383 + seq_printf(m, "\nSwitch Port %d\n", ports[index]);
23384 + seq_printf(m, "InGoodOctets: %12llu\t"
23385 + "OutOctets: %12llu\t"
23386 + "64 Octets: %12llu\n",
23387 + cvm_oct_stats_read_switch(dev, 0x1b,
23388 + 0x00) |
23389 + (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32),
23390 + cvm_oct_stats_read_switch(dev, 0x1b,
23391 + 0x0E) |
23392 + (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32),
23393 + cvm_oct_stats_read_switch(dev, 0x1b, 0x08));
23394 +
23395 + seq_printf(m, "InBadOctets: %12llu\t"
23396 + "OutUnicast: %12llu\t"
23397 + "65-127 Octets: %12llu\n",
23398 + cvm_oct_stats_read_switch(dev, 0x1b, 0x02),
23399 + cvm_oct_stats_read_switch(dev, 0x1b, 0x10),
23400 + cvm_oct_stats_read_switch(dev, 0x1b, 0x09));
23401 +
23402 + seq_printf(m, "InUnicast: %12llu\t"
23403 + "OutBroadcasts: %12llu\t"
23404 + "128-255 Octets: %12llu\n",
23405 + cvm_oct_stats_read_switch(dev, 0x1b, 0x04),
23406 + cvm_oct_stats_read_switch(dev, 0x1b, 0x13),
23407 + cvm_oct_stats_read_switch(dev, 0x1b, 0x0A));
23408 +
23409 + seq_printf(m, "InBroadcasts: %12llu\t"
23410 + "OutMulticasts: %12llu\t"
23411 + "256-511 Octets: %12llu\n",
23412 + cvm_oct_stats_read_switch(dev, 0x1b, 0x06),
23413 + cvm_oct_stats_read_switch(dev, 0x1b, 0x12),
23414 + cvm_oct_stats_read_switch(dev, 0x1b, 0x0B));
23415 +
23416 + seq_printf(m, "InMulticasts: %12llu\t"
23417 + "OutPause: %12llu\t"
23418 + "512-1023 Octets:%12llu\n",
23419 + cvm_oct_stats_read_switch(dev, 0x1b, 0x07),
23420 + cvm_oct_stats_read_switch(dev, 0x1b, 0x15),
23421 + cvm_oct_stats_read_switch(dev, 0x1b, 0x0C));
23422 +
23423 + seq_printf(m, "InPause: %12llu\t"
23424 + "Excessive: %12llu\t"
23425 + "1024-Max Octets:%12llu\n",
23426 + cvm_oct_stats_read_switch(dev, 0x1b, 0x16),
23427 + cvm_oct_stats_read_switch(dev, 0x1b, 0x11),
23428 + cvm_oct_stats_read_switch(dev, 0x1b, 0x0D));
23429 +
23430 + seq_printf(m, "InUndersize: %12llu\t"
23431 + "Collisions: %12llu\n",
23432 + cvm_oct_stats_read_switch(dev, 0x1b, 0x18),
23433 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1E));
23434 +
23435 + seq_printf(m, "InFragments: %12llu\t"
23436 + "Deferred: %12llu\n",
23437 + cvm_oct_stats_read_switch(dev, 0x1b, 0x19),
23438 + cvm_oct_stats_read_switch(dev, 0x1b, 0x05));
23439 +
23440 + seq_printf(m, "InOversize: %12llu\t"
23441 + "Single: %12llu\n",
23442 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1A),
23443 + cvm_oct_stats_read_switch(dev, 0x1b, 0x14));
23444 +
23445 + seq_printf(m, "InJabber: %12llu\t"
23446 + "Multiple: %12llu\n",
23447 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1B),
23448 + cvm_oct_stats_read_switch(dev, 0x1b, 0x17));
23449 +
23450 + seq_printf(m, "In RxErr: %12llu\t"
23451 + "OutFCSErr: %12llu\n",
23452 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1C),
23453 + cvm_oct_stats_read_switch(dev, 0x1b, 0x03));
23454 +
23455 + seq_printf(m, "InFCSErr: %12llu\t"
23456 + "Late: %12llu\n",
23457 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1D),
23458 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1F));
23459 + index++;
23460 + }
23461 + return 0;
23462 +}
23463 +
23464 +/**
23465 + * User is reading /proc/octeon_ethernet_stats
23466 + *
23467 + * @m:
23468 + * @v:
23469 + * Returns
23470 + */
23471 +static int cvm_oct_stats_show(struct seq_file *m, void *v)
23472 +{
23473 + struct octeon_ethernet *priv;
23474 + int port;
23475 +
23476 + for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
23477 +
23478 + if (cvm_oct_device[port]) {
23479 + priv = netdev_priv(cvm_oct_device[port]);
23480 +
23481 + seq_printf(m, "\nOcteon Port %d (%s)\n", port,
23482 + cvm_oct_device[port]->name);
23483 + seq_printf(m,
23484 + "rx_packets: %12lu\t"
23485 + "tx_packets: %12lu\n",
23486 + priv->stats.rx_packets,
23487 + priv->stats.tx_packets);
23488 + seq_printf(m,
23489 + "rx_bytes: %12lu\t"
23490 + "tx_bytes: %12lu\n",
23491 + priv->stats.rx_bytes, priv->stats.tx_bytes);
23492 + seq_printf(m,
23493 + "rx_errors: %12lu\t"
23494 + "tx_errors: %12lu\n",
23495 + priv->stats.rx_errors,
23496 + priv->stats.tx_errors);
23497 + seq_printf(m,
23498 + "rx_dropped: %12lu\t"
23499 + "tx_dropped: %12lu\n",
23500 + priv->stats.rx_dropped,
23501 + priv->stats.tx_dropped);
23502 + seq_printf(m,
23503 + "rx_length_errors: %12lu\t"
23504 + "tx_aborted_errors: %12lu\n",
23505 + priv->stats.rx_length_errors,
23506 + priv->stats.tx_aborted_errors);
23507 + seq_printf(m,
23508 + "rx_over_errors: %12lu\t"
23509 + "tx_carrier_errors: %12lu\n",
23510 + priv->stats.rx_over_errors,
23511 + priv->stats.tx_carrier_errors);
23512 + seq_printf(m,
23513 + "rx_crc_errors: %12lu\t"
23514 + "tx_fifo_errors: %12lu\n",
23515 + priv->stats.rx_crc_errors,
23516 + priv->stats.tx_fifo_errors);
23517 + seq_printf(m,
23518 + "rx_frame_errors: %12lu\t"
23519 + "tx_heartbeat_errors: %12lu\n",
23520 + priv->stats.rx_frame_errors,
23521 + priv->stats.tx_heartbeat_errors);
23522 + seq_printf(m,
23523 + "rx_fifo_errors: %12lu\t"
23524 + "tx_window_errors: %12lu\n",
23525 + priv->stats.rx_fifo_errors,
23526 + priv->stats.tx_window_errors);
23527 + seq_printf(m,
23528 + "rx_missed_errors: %12lu\t"
23529 + "multicast: %12lu\n",
23530 + priv->stats.rx_missed_errors,
23531 + priv->stats.multicast);
23532 + }
23533 + }
23534 +
23535 + if (cvm_oct_device[0]) {
23536 + priv = netdev_priv(cvm_oct_device[0]);
23537 + if (priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23538 + cvm_oct_stats_switch_show(m, v);
23539 + }
23540 + return 0;
23541 +}
23542 +
23543 +/**
23544 + * /proc/octeon_ethernet_stats was openned. Use the single_open iterator
23545 + *
23546 + * @inode:
23547 + * @file:
23548 + * Returns
23549 + */
23550 +static int cvm_oct_stats_open(struct inode *inode, struct file *file)
23551 +{
23552 + return single_open(file, cvm_oct_stats_show, NULL);
23553 +}
23554 +
23555 +static const struct file_operations cvm_oct_stats_operations = {
23556 + .open = cvm_oct_stats_open,
23557 + .read = seq_read,
23558 + .llseek = seq_lseek,
23559 + .release = single_release,
23560 +};
23561 +
23562 +void cvm_oct_proc_initialize(void)
23563 +{
23564 + struct proc_dir_entry *entry =
23565 + create_proc_entry("octeon_ethernet_stats", 0, NULL);
23566 + if (entry)
23567 + entry->proc_fops = &cvm_oct_stats_operations;
23568 +}
23569 +
23570 +void cvm_oct_proc_shutdown(void)
23571 +{
23572 + remove_proc_entry("octeon_ethernet_stats", NULL);
23573 +}
23574 --- /dev/null
23575 +++ b/drivers/staging/octeon/ethernet-proc.h
23576 @@ -0,0 +1,29 @@
23577 +/*********************************************************************
23578 + * Author: Cavium Networks
23579 + *
23580 + * Contact: support@caviumnetworks.com
23581 + * This file is part of the OCTEON SDK
23582 + *
23583 + * Copyright (c) 2003-2007 Cavium Networks
23584 + *
23585 + * This file is free software; you can redistribute it and/or modify
23586 + * it under the terms of the GNU General Public License, Version 2, as
23587 + * published by the Free Software Foundation.
23588 + *
23589 + * This file is distributed in the hope that it will be useful, but
23590 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23591 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23592 + * NONINFRINGEMENT. See the GNU General Public License for more
23593 + * details.
23594 + *
23595 + * You should have received a copy of the GNU General Public License
23596 + * along with this file; if not, write to the Free Software
23597 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23598 + * or visit http://www.gnu.org/licenses/.
23599 + *
23600 + * This file may also be available under a different license from Cavium.
23601 + * Contact Cavium Networks for more information
23602 +*********************************************************************/
23603 +
23604 +void cvm_oct_proc_initialize(void);
23605 +void cvm_oct_proc_shutdown(void);
23606 --- /dev/null
23607 +++ b/drivers/staging/octeon/ethernet-rgmii.c
23608 @@ -0,0 +1,397 @@
23609 +/*********************************************************************
23610 + * Author: Cavium Networks
23611 + *
23612 + * Contact: support@caviumnetworks.com
23613 + * This file is part of the OCTEON SDK
23614 + *
23615 + * Copyright (c) 2003-2007 Cavium Networks
23616 + *
23617 + * This file is free software; you can redistribute it and/or modify
23618 + * it under the terms of the GNU General Public License, Version 2, as
23619 + * published by the Free Software Foundation.
23620 + *
23621 + * This file is distributed in the hope that it will be useful, but
23622 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23623 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23624 + * NONINFRINGEMENT. See the GNU General Public License for more
23625 + * details.
23626 + *
23627 + * You should have received a copy of the GNU General Public License
23628 + * along with this file; if not, write to the Free Software
23629 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23630 + * or visit http://www.gnu.org/licenses/.
23631 + *
23632 + * This file may also be available under a different license from Cavium.
23633 + * Contact Cavium Networks for more information
23634 +**********************************************************************/
23635 +#include <linux/kernel.h>
23636 +#include <linux/netdevice.h>
23637 +#include <linux/mii.h>
23638 +#include <net/dst.h>
23639 +
23640 +#include <asm/octeon/octeon.h>
23641 +
23642 +#include "ethernet-defines.h"
23643 +#include "octeon-ethernet.h"
23644 +#include "ethernet-common.h"
23645 +#include "ethernet-util.h"
23646 +
23647 +#include "cvmx-helper.h"
23648 +
23649 +#include <asm/octeon/cvmx-ipd-defs.h>
23650 +#include <asm/octeon/cvmx-npi-defs.h>
23651 +#include "cvmx-gmxx-defs.h"
23652 +
23653 +DEFINE_SPINLOCK(global_register_lock);
23654 +
23655 +static int number_rgmii_ports;
23656 +
23657 +static void cvm_oct_rgmii_poll(struct net_device *dev)
23658 +{
23659 + struct octeon_ethernet *priv = netdev_priv(dev);
23660 + unsigned long flags;
23661 + cvmx_helper_link_info_t link_info;
23662 +
23663 + /*
23664 + * Take the global register lock since we are going to touch
23665 + * registers that affect more than one port.
23666 + */
23667 + spin_lock_irqsave(&global_register_lock, flags);
23668 +
23669 + link_info = cvmx_helper_link_get(priv->port);
23670 + if (link_info.u64 == priv->link_info) {
23671 +
23672 + /*
23673 + * If the 10Mbps preamble workaround is supported and we're
23674 + * at 10Mbps we may need to do some special checking.
23675 + */
23676 + if (USE_10MBPS_PREAMBLE_WORKAROUND && (link_info.s.speed == 10)) {
23677 +
23678 + /*
23679 + * Read the GMXX_RXX_INT_REG[PCTERR] bit and
23680 + * see if we are getting preamble errors.
23681 + */
23682 + int interface = INTERFACE(priv->port);
23683 + int index = INDEX(priv->port);
23684 + union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
23685 + gmxx_rxx_int_reg.u64 =
23686 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
23687 + (index, interface));
23688 + if (gmxx_rxx_int_reg.s.pcterr) {
23689 +
23690 + /*
23691 + * We are getting preamble errors at
23692 + * 10Mbps. Most likely the PHY is
23693 + * giving us packets with mis aligned
23694 + * preambles. In order to get these
23695 + * packets we need to disable preamble
23696 + * checking and do it in software.
23697 + */
23698 + union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
23699 + union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
23700 +
23701 + /* Disable preamble checking */
23702 + gmxx_rxx_frm_ctl.u64 =
23703 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
23704 + (index, interface));
23705 + gmxx_rxx_frm_ctl.s.pre_chk = 0;
23706 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL
23707 + (index, interface),
23708 + gmxx_rxx_frm_ctl.u64);
23709 +
23710 + /* Disable FCS stripping */
23711 + ipd_sub_port_fcs.u64 =
23712 + cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
23713 + ipd_sub_port_fcs.s.port_bit &=
23714 + 0xffffffffull ^ (1ull << priv->port);
23715 + cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS,
23716 + ipd_sub_port_fcs.u64);
23717 +
23718 + /* Clear any error bits */
23719 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
23720 + (index, interface),
23721 + gmxx_rxx_int_reg.u64);
23722 + DEBUGPRINT("%s: Using 10Mbps with software "
23723 + "preamble removal\n",
23724 + dev->name);
23725 + }
23726 + }
23727 + spin_unlock_irqrestore(&global_register_lock, flags);
23728 + return;
23729 + }
23730 +
23731 + /* If the 10Mbps preamble workaround is allowed we need to on
23732 + preamble checking, FCS stripping, and clear error bits on
23733 + every speed change. If errors occur during 10Mbps operation
23734 + the above code will change this stuff */
23735 + if (USE_10MBPS_PREAMBLE_WORKAROUND) {
23736 +
23737 + union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
23738 + union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
23739 + union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
23740 + int interface = INTERFACE(priv->port);
23741 + int index = INDEX(priv->port);
23742 +
23743 + /* Enable preamble checking */
23744 + gmxx_rxx_frm_ctl.u64 =
23745 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
23746 + gmxx_rxx_frm_ctl.s.pre_chk = 1;
23747 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface),
23748 + gmxx_rxx_frm_ctl.u64);
23749 + /* Enable FCS stripping */
23750 + ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
23751 + ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port;
23752 + cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
23753 + /* Clear any error bits */
23754 + gmxx_rxx_int_reg.u64 =
23755 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, interface));
23756 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface),
23757 + gmxx_rxx_int_reg.u64);
23758 + }
23759 +
23760 + link_info = cvmx_helper_link_autoconf(priv->port);
23761 + priv->link_info = link_info.u64;
23762 + spin_unlock_irqrestore(&global_register_lock, flags);
23763 +
23764 + /* Tell Linux */
23765 + if (link_info.s.link_up) {
23766 +
23767 + if (!netif_carrier_ok(dev))
23768 + netif_carrier_on(dev);
23769 + if (priv->queue != -1)
23770 + DEBUGPRINT
23771 + ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
23772 + dev->name, link_info.s.speed,
23773 + (link_info.s.full_duplex) ? "Full" : "Half",
23774 + priv->port, priv->queue);
23775 + else
23776 + DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
23777 + dev->name, link_info.s.speed,
23778 + (link_info.s.full_duplex) ? "Full" : "Half",
23779 + priv->port);
23780 + } else {
23781 +
23782 + if (netif_carrier_ok(dev))
23783 + netif_carrier_off(dev);
23784 + DEBUGPRINT("%s: Link down\n", dev->name);
23785 + }
23786 +}
23787 +
23788 +static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id)
23789 +{
23790 + union cvmx_npi_rsl_int_blocks rsl_int_blocks;
23791 + int index;
23792 + irqreturn_t return_status = IRQ_NONE;
23793 +
23794 + rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
23795 +
23796 + /* Check and see if this interrupt was caused by the GMX0 block */
23797 + if (rsl_int_blocks.s.gmx0) {
23798 +
23799 + int interface = 0;
23800 + /* Loop through every port of this interface */
23801 + for (index = 0;
23802 + index < cvmx_helper_ports_on_interface(interface);
23803 + index++) {
23804 +
23805 + /* Read the GMX interrupt status bits */
23806 + union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
23807 + gmx_rx_int_reg.u64 =
23808 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
23809 + (index, interface));
23810 + gmx_rx_int_reg.u64 &=
23811 + cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
23812 + (index, interface));
23813 + /* Poll the port if inband status changed */
23814 + if (gmx_rx_int_reg.s.phy_dupx
23815 + || gmx_rx_int_reg.s.phy_link
23816 + || gmx_rx_int_reg.s.phy_spd) {
23817 +
23818 + struct net_device *dev =
23819 + cvm_oct_device[cvmx_helper_get_ipd_port
23820 + (interface, index)];
23821 + if (dev)
23822 + cvm_oct_rgmii_poll(dev);
23823 + gmx_rx_int_reg.u64 = 0;
23824 + gmx_rx_int_reg.s.phy_dupx = 1;
23825 + gmx_rx_int_reg.s.phy_link = 1;
23826 + gmx_rx_int_reg.s.phy_spd = 1;
23827 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
23828 + (index, interface),
23829 + gmx_rx_int_reg.u64);
23830 + return_status = IRQ_HANDLED;
23831 + }
23832 + }
23833 + }
23834 +
23835 + /* Check and see if this interrupt was caused by the GMX1 block */
23836 + if (rsl_int_blocks.s.gmx1) {
23837 +
23838 + int interface = 1;
23839 + /* Loop through every port of this interface */
23840 + for (index = 0;
23841 + index < cvmx_helper_ports_on_interface(interface);
23842 + index++) {
23843 +
23844 + /* Read the GMX interrupt status bits */
23845 + union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
23846 + gmx_rx_int_reg.u64 =
23847 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
23848 + (index, interface));
23849 + gmx_rx_int_reg.u64 &=
23850 + cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
23851 + (index, interface));
23852 + /* Poll the port if inband status changed */
23853 + if (gmx_rx_int_reg.s.phy_dupx
23854 + || gmx_rx_int_reg.s.phy_link
23855 + || gmx_rx_int_reg.s.phy_spd) {
23856 +
23857 + struct net_device *dev =
23858 + cvm_oct_device[cvmx_helper_get_ipd_port
23859 + (interface, index)];
23860 + if (dev)
23861 + cvm_oct_rgmii_poll(dev);
23862 + gmx_rx_int_reg.u64 = 0;
23863 + gmx_rx_int_reg.s.phy_dupx = 1;
23864 + gmx_rx_int_reg.s.phy_link = 1;
23865 + gmx_rx_int_reg.s.phy_spd = 1;
23866 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
23867 + (index, interface),
23868 + gmx_rx_int_reg.u64);
23869 + return_status = IRQ_HANDLED;
23870 + }
23871 + }
23872 + }
23873 + return return_status;
23874 +}
23875 +
23876 +static int cvm_oct_rgmii_open(struct net_device *dev)
23877 +{
23878 + union cvmx_gmxx_prtx_cfg gmx_cfg;
23879 + struct octeon_ethernet *priv = netdev_priv(dev);
23880 + int interface = INTERFACE(priv->port);
23881 + int index = INDEX(priv->port);
23882 + cvmx_helper_link_info_t link_info;
23883 +
23884 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
23885 + gmx_cfg.s.en = 1;
23886 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
23887 +
23888 + if (!octeon_is_simulation()) {
23889 + link_info = cvmx_helper_link_get(priv->port);
23890 + if (!link_info.s.link_up)
23891 + netif_carrier_off(dev);
23892 + }
23893 +
23894 + return 0;
23895 +}
23896 +
23897 +static int cvm_oct_rgmii_stop(struct net_device *dev)
23898 +{
23899 + union cvmx_gmxx_prtx_cfg gmx_cfg;
23900 + struct octeon_ethernet *priv = netdev_priv(dev);
23901 + int interface = INTERFACE(priv->port);
23902 + int index = INDEX(priv->port);
23903 +
23904 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
23905 + gmx_cfg.s.en = 0;
23906 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
23907 + return 0;
23908 +}
23909 +
23910 +int cvm_oct_rgmii_init(struct net_device *dev)
23911 +{
23912 + struct octeon_ethernet *priv = netdev_priv(dev);
23913 + int r;
23914 +
23915 + cvm_oct_common_init(dev);
23916 + dev->open = cvm_oct_rgmii_open;
23917 + dev->stop = cvm_oct_rgmii_stop;
23918 + dev->stop(dev);
23919 +
23920 + /*
23921 + * Due to GMX errata in CN3XXX series chips, it is necessary
23922 + * to take the link down immediately whne the PHY changes
23923 + * state. In order to do this we call the poll function every
23924 + * time the RGMII inband status changes. This may cause
23925 + * problems if the PHY doesn't implement inband status
23926 + * properly.
23927 + */
23928 + if (number_rgmii_ports == 0) {
23929 + r = request_irq(OCTEON_IRQ_RML, cvm_oct_rgmii_rml_interrupt,
23930 + IRQF_SHARED, "RGMII", &number_rgmii_ports);
23931 + }
23932 + number_rgmii_ports++;
23933 +
23934 + /*
23935 + * Only true RGMII ports need to be polled. In GMII mode, port
23936 + * 0 is really a RGMII port.
23937 + */
23938 + if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23939 + && (priv->port == 0))
23940 + || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
23941 +
23942 + if (!octeon_is_simulation()) {
23943 +
23944 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
23945 + int interface = INTERFACE(priv->port);
23946 + int index = INDEX(priv->port);
23947 +
23948 + /*
23949 + * Enable interrupts on inband status changes
23950 + * for this port.
23951 + */
23952 + gmx_rx_int_en.u64 =
23953 + cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
23954 + (index, interface));
23955 + gmx_rx_int_en.s.phy_dupx = 1;
23956 + gmx_rx_int_en.s.phy_link = 1;
23957 + gmx_rx_int_en.s.phy_spd = 1;
23958 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
23959 + gmx_rx_int_en.u64);
23960 + priv->poll = cvm_oct_rgmii_poll;
23961 + }
23962 + }
23963 +
23964 + return 0;
23965 +}
23966 +
23967 +void cvm_oct_rgmii_uninit(struct net_device *dev)
23968 +{
23969 + struct octeon_ethernet *priv = netdev_priv(dev);
23970 + cvm_oct_common_uninit(dev);
23971 +
23972 + /*
23973 + * Only true RGMII ports need to be polled. In GMII mode, port
23974 + * 0 is really a RGMII port.
23975 + */
23976 + if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23977 + && (priv->port == 0))
23978 + || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
23979 +
23980 + if (!octeon_is_simulation()) {
23981 +
23982 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
23983 + int interface = INTERFACE(priv->port);
23984 + int index = INDEX(priv->port);
23985 +
23986 + /*
23987 + * Disable interrupts on inband status changes
23988 + * for this port.
23989 + */
23990 + gmx_rx_int_en.u64 =
23991 + cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
23992 + (index, interface));
23993 + gmx_rx_int_en.s.phy_dupx = 0;
23994 + gmx_rx_int_en.s.phy_link = 0;
23995 + gmx_rx_int_en.s.phy_spd = 0;
23996 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
23997 + gmx_rx_int_en.u64);
23998 + }
23999 + }
24000 +
24001 + /* Remove the interrupt handler when the last port is removed. */
24002 + number_rgmii_ports--;
24003 + if (number_rgmii_ports == 0)
24004 + free_irq(OCTEON_IRQ_RML, &number_rgmii_ports);
24005 +}
24006 --- /dev/null
24007 +++ b/drivers/staging/octeon/ethernet-rx.c
24008 @@ -0,0 +1,505 @@
24009 +/**********************************************************************
24010 + * Author: Cavium Networks
24011 + *
24012 + * Contact: support@caviumnetworks.com
24013 + * This file is part of the OCTEON SDK
24014 + *
24015 + * Copyright (c) 2003-2007 Cavium Networks
24016 + *
24017 + * This file is free software; you can redistribute it and/or modify
24018 + * it under the terms of the GNU General Public License, Version 2, as
24019 + * published by the Free Software Foundation.
24020 + *
24021 + * This file is distributed in the hope that it will be useful, but
24022 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24023 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24024 + * NONINFRINGEMENT. See the GNU General Public License for more
24025 + * details.
24026 + *
24027 + * You should have received a copy of the GNU General Public License
24028 + * along with this file; if not, write to the Free Software
24029 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24030 + * or visit http://www.gnu.org/licenses/.
24031 + *
24032 + * This file may also be available under a different license from Cavium.
24033 + * Contact Cavium Networks for more information
24034 +**********************************************************************/
24035 +#include <linux/module.h>
24036 +#include <linux/kernel.h>
24037 +#include <linux/cache.h>
24038 +#include <linux/netdevice.h>
24039 +#include <linux/init.h>
24040 +#include <linux/etherdevice.h>
24041 +#include <linux/ip.h>
24042 +#include <linux/string.h>
24043 +#include <linux/prefetch.h>
24044 +#include <linux/ethtool.h>
24045 +#include <linux/mii.h>
24046 +#include <linux/seq_file.h>
24047 +#include <linux/proc_fs.h>
24048 +#include <net/dst.h>
24049 +#ifdef CONFIG_XFRM
24050 +#include <linux/xfrm.h>
24051 +#include <net/xfrm.h>
24052 +#endif /* CONFIG_XFRM */
24053 +
24054 +#include <asm/atomic.h>
24055 +
24056 +#include <asm/octeon/octeon.h>
24057 +
24058 +#include "ethernet-defines.h"
24059 +#include "octeon-ethernet.h"
24060 +#include "ethernet-mem.h"
24061 +#include "ethernet-util.h"
24062 +
24063 +#include "cvmx-helper.h"
24064 +#include "cvmx-wqe.h"
24065 +#include "cvmx-fau.h"
24066 +#include "cvmx-pow.h"
24067 +#include "cvmx-pip.h"
24068 +#include "cvmx-scratch.h"
24069 +
24070 +#include "cvmx-gmxx-defs.h"
24071 +
24072 +struct cvm_tasklet_wrapper {
24073 + struct tasklet_struct t;
24074 +};
24075 +
24076 +/*
24077 + * Aligning the tasklet_struct on cachline boundries seems to decrease
24078 + * throughput even though in theory it would reduce contantion on the
24079 + * cache lines containing the locks.
24080 + */
24081 +
24082 +static struct cvm_tasklet_wrapper cvm_oct_tasklet[NR_CPUS];
24083 +
24084 +/**
24085 + * Interrupt handler. The interrupt occurs whenever the POW
24086 + * transitions from 0->1 packets in our group.
24087 + *
24088 + * @cpl:
24089 + * @dev_id:
24090 + * @regs:
24091 + * Returns
24092 + */
24093 +irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
24094 +{
24095 + /* Acknowledge the interrupt */
24096 + if (INTERRUPT_LIMIT)
24097 + cvmx_write_csr(CVMX_POW_WQ_INT, 1 << pow_receive_group);
24098 + else
24099 + cvmx_write_csr(CVMX_POW_WQ_INT, 0x10001 << pow_receive_group);
24100 + preempt_disable();
24101 + tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
24102 + preempt_enable();
24103 + return IRQ_HANDLED;
24104 +}
24105 +
24106 +#ifdef CONFIG_NET_POLL_CONTROLLER
24107 +/**
24108 + * This is called when the kernel needs to manually poll the
24109 + * device. For Octeon, this is simply calling the interrupt
24110 + * handler. We actually poll all the devices, not just the
24111 + * one supplied.
24112 + *
24113 + * @dev: Device to poll. Unused
24114 + */
24115 +void cvm_oct_poll_controller(struct net_device *dev)
24116 +{
24117 + preempt_disable();
24118 + tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
24119 + preempt_enable();
24120 +}
24121 +#endif
24122 +
24123 +/**
24124 + * This is called on receive errors, and determines if the packet
24125 + * can be dropped early-on in cvm_oct_tasklet_rx().
24126 + *
24127 + * @work: Work queue entry pointing to the packet.
24128 + * Returns Non-zero if the packet can be dropped, zero otherwise.
24129 + */
24130 +static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
24131 +{
24132 + if ((work->word2.snoip.err_code == 10) && (work->len <= 64)) {
24133 + /*
24134 + * Ignore length errors on min size packets. Some
24135 + * equipment incorrectly pads packets to 64+4FCS
24136 + * instead of 60+4FCS. Note these packets still get
24137 + * counted as frame errors.
24138 + */
24139 + } else
24140 + if (USE_10MBPS_PREAMBLE_WORKAROUND
24141 + && ((work->word2.snoip.err_code == 5)
24142 + || (work->word2.snoip.err_code == 7))) {
24143 +
24144 + /*
24145 + * We received a packet with either an alignment error
24146 + * or a FCS error. This may be signalling that we are
24147 + * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK}
24148 + * off. If this is the case we need to parse the
24149 + * packet to determine if we can remove a non spec
24150 + * preamble and generate a correct packet.
24151 + */
24152 + int interface = cvmx_helper_get_interface_num(work->ipprt);
24153 + int index = cvmx_helper_get_interface_index_num(work->ipprt);
24154 + union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
24155 + gmxx_rxx_frm_ctl.u64 =
24156 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
24157 + if (gmxx_rxx_frm_ctl.s.pre_chk == 0) {
24158 +
24159 + uint8_t *ptr =
24160 + cvmx_phys_to_ptr(work->packet_ptr.s.addr);
24161 + int i = 0;
24162 +
24163 + while (i < work->len - 1) {
24164 + if (*ptr != 0x55)
24165 + break;
24166 + ptr++;
24167 + i++;
24168 + }
24169 +
24170 + if (*ptr == 0xd5) {
24171 + /*
24172 + DEBUGPRINT("Port %d received 0xd5 preamble\n", work->ipprt);
24173 + */
24174 + work->packet_ptr.s.addr += i + 1;
24175 + work->len -= i + 5;
24176 + } else if ((*ptr & 0xf) == 0xd) {
24177 + /*
24178 + DEBUGPRINT("Port %d received 0x?d preamble\n", work->ipprt);
24179 + */
24180 + work->packet_ptr.s.addr += i;
24181 + work->len -= i + 4;
24182 + for (i = 0; i < work->len; i++) {
24183 + *ptr =
24184 + ((*ptr & 0xf0) >> 4) |
24185 + ((*(ptr + 1) & 0xf) << 4);
24186 + ptr++;
24187 + }
24188 + } else {
24189 + DEBUGPRINT("Port %d unknown preamble, packet "
24190 + "dropped\n",
24191 + work->ipprt);
24192 + /*
24193 + cvmx_helper_dump_packet(work);
24194 + */
24195 + cvm_oct_free_work(work);
24196 + return 1;
24197 + }
24198 + }
24199 + } else {
24200 + DEBUGPRINT("Port %d receive error code %d, packet dropped\n",
24201 + work->ipprt, work->word2.snoip.err_code);
24202 + cvm_oct_free_work(work);
24203 + return 1;
24204 + }
24205 +
24206 + return 0;
24207 +}
24208 +
24209 +/**
24210 + * Tasklet function that is scheduled on a core when an interrupt occurs.
24211 + *
24212 + * @unused:
24213 + */
24214 +void cvm_oct_tasklet_rx(unsigned long unused)
24215 +{
24216 + const int coreid = cvmx_get_core_num();
24217 + uint64_t old_group_mask;
24218 + uint64_t old_scratch;
24219 + int rx_count = 0;
24220 + int number_to_free;
24221 + int num_freed;
24222 + int packet_not_copied;
24223 +
24224 + /* Prefetch cvm_oct_device since we know we need it soon */
24225 + prefetch(cvm_oct_device);
24226 +
24227 + if (USE_ASYNC_IOBDMA) {
24228 + /* Save scratch in case userspace is using it */
24229 + CVMX_SYNCIOBDMA;
24230 + old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
24231 + }
24232 +
24233 + /* Only allow work for our group (and preserve priorities) */
24234 + old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));
24235 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
24236 + (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group);
24237 +
24238 + if (USE_ASYNC_IOBDMA)
24239 + cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
24240 +
24241 + while (1) {
24242 + struct sk_buff *skb = NULL;
24243 + int skb_in_hw;
24244 + cvmx_wqe_t *work;
24245 +
24246 + if (USE_ASYNC_IOBDMA) {
24247 + work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);
24248 + } else {
24249 + if ((INTERRUPT_LIMIT == 0)
24250 + || likely(rx_count < MAX_RX_PACKETS))
24251 + work =
24252 + cvmx_pow_work_request_sync
24253 + (CVMX_POW_NO_WAIT);
24254 + else
24255 + work = NULL;
24256 + }
24257 + prefetch(work);
24258 + if (work == NULL)
24259 + break;
24260 +
24261 + /*
24262 + * Limit each core to processing MAX_RX_PACKETS
24263 + * packets without a break. This way the RX can't
24264 + * starve the TX task.
24265 + */
24266 + if (USE_ASYNC_IOBDMA) {
24267 +
24268 + if ((INTERRUPT_LIMIT == 0)
24269 + || likely(rx_count < MAX_RX_PACKETS))
24270 + cvmx_pow_work_request_async_nocheck
24271 + (CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
24272 + else {
24273 + cvmx_scratch_write64(CVMX_SCR_SCRATCH,
24274 + 0x8000000000000000ull);
24275 + cvmx_pow_tag_sw_null_nocheck();
24276 + }
24277 + }
24278 +
24279 + skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1;
24280 + if (likely(skb_in_hw)) {
24281 + skb =
24282 + *(struct sk_buff
24283 + **)(cvm_oct_get_buffer_ptr(work->packet_ptr) -
24284 + sizeof(void *));
24285 + prefetch(&skb->head);
24286 + prefetch(&skb->len);
24287 + }
24288 + prefetch(cvm_oct_device[work->ipprt]);
24289 +
24290 + rx_count++;
24291 + /* Immediately throw away all packets with receive errors */
24292 + if (unlikely(work->word2.snoip.rcv_error)) {
24293 + if (cvm_oct_check_rcv_error(work))
24294 + continue;
24295 + }
24296 +
24297 + /*
24298 + * We can only use the zero copy path if skbuffs are
24299 + * in the FPA pool and the packet fits in a single
24300 + * buffer.
24301 + */
24302 + if (likely(skb_in_hw)) {
24303 + /*
24304 + * This calculation was changed in case the
24305 + * skb header is using a different address
24306 + * aliasing type than the buffer. It doesn't
24307 + * make any differnece now, but the new one is
24308 + * more correct.
24309 + */
24310 + skb->data =
24311 + skb->head + work->packet_ptr.s.addr -
24312 + cvmx_ptr_to_phys(skb->head);
24313 + prefetch(skb->data);
24314 + skb->len = work->len;
24315 + skb_set_tail_pointer(skb, skb->len);
24316 + packet_not_copied = 1;
24317 + } else {
24318 +
24319 + /*
24320 + * We have to copy the packet. First allocate
24321 + * an skbuff for it.
24322 + */
24323 + skb = dev_alloc_skb(work->len);
24324 + if (!skb) {
24325 + DEBUGPRINT("Port %d failed to allocate "
24326 + "skbuff, packet dropped\n",
24327 + work->ipprt);
24328 + cvm_oct_free_work(work);
24329 + continue;
24330 + }
24331 +
24332 + /*
24333 + * Check if we've received a packet that was
24334 + * entirely stored in the work entry. This is
24335 + * untested.
24336 + */
24337 + if (unlikely(work->word2.s.bufs == 0)) {
24338 + uint8_t *ptr = work->packet_data;
24339 +
24340 + if (likely(!work->word2.s.not_IP)) {
24341 + /*
24342 + * The beginning of the packet
24343 + * moves for IP packets.
24344 + */
24345 + if (work->word2.s.is_v6)
24346 + ptr += 2;
24347 + else
24348 + ptr += 6;
24349 + }
24350 + memcpy(skb_put(skb, work->len), ptr, work->len);
24351 + /* No packet buffers to free */
24352 + } else {
24353 + int segments = work->word2.s.bufs;
24354 + union cvmx_buf_ptr segment_ptr =
24355 + work->packet_ptr;
24356 + int len = work->len;
24357 +
24358 + while (segments--) {
24359 + union cvmx_buf_ptr next_ptr =
24360 + *(union cvmx_buf_ptr *)
24361 + cvmx_phys_to_ptr(segment_ptr.s.
24362 + addr - 8);
24363 + /*
24364 + * Octeon Errata PKI-100: The segment size is
24365 + * wrong. Until it is fixed, calculate the
24366 + * segment size based on the packet pool
24367 + * buffer size. When it is fixed, the
24368 + * following line should be replaced with this
24369 + * one: int segment_size =
24370 + * segment_ptr.s.size;
24371 + */
24372 + int segment_size =
24373 + CVMX_FPA_PACKET_POOL_SIZE -
24374 + (segment_ptr.s.addr -
24375 + (((segment_ptr.s.addr >> 7) -
24376 + segment_ptr.s.back) << 7));
24377 + /* Don't copy more than what is left
24378 + in the packet */
24379 + if (segment_size > len)
24380 + segment_size = len;
24381 + /* Copy the data into the packet */
24382 + memcpy(skb_put(skb, segment_size),
24383 + cvmx_phys_to_ptr(segment_ptr.s.
24384 + addr),
24385 + segment_size);
24386 + /* Reduce the amount of bytes left
24387 + to copy */
24388 + len -= segment_size;
24389 + segment_ptr = next_ptr;
24390 + }
24391 + }
24392 + packet_not_copied = 0;
24393 + }
24394 +
24395 + if (likely((work->ipprt < TOTAL_NUMBER_OF_PORTS) &&
24396 + cvm_oct_device[work->ipprt])) {
24397 + struct net_device *dev = cvm_oct_device[work->ipprt];
24398 + struct octeon_ethernet *priv = netdev_priv(dev);
24399 +
24400 + /* Only accept packets for devices
24401 + that are currently up */
24402 + if (likely(dev->flags & IFF_UP)) {
24403 + skb->protocol = eth_type_trans(skb, dev);
24404 + skb->dev = dev;
24405 +
24406 + if (unlikely
24407 + (work->word2.s.not_IP
24408 + || work->word2.s.IP_exc
24409 + || work->word2.s.L4_error))
24410 + skb->ip_summed = CHECKSUM_NONE;
24411 + else
24412 + skb->ip_summed = CHECKSUM_UNNECESSARY;
24413 +
24414 + /* Increment RX stats for virtual ports */
24415 + if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) {
24416 +#ifdef CONFIG_64BIT
24417 + atomic64_add(1, (atomic64_t *)&priv->stats.rx_packets);
24418 + atomic64_add(skb->len, (atomic64_t *)&priv->stats.rx_bytes);
24419 +#else
24420 + atomic_add(1, (atomic_t *)&priv->stats.rx_packets);
24421 + atomic_add(skb->len, (atomic_t *)&priv->stats.rx_bytes);
24422 +#endif
24423 + }
24424 + netif_receive_skb(skb);
24425 + } else {
24426 + /*
24427 + * Drop any packet received for a
24428 + * device that isn't up.
24429 + */
24430 + /*
24431 + DEBUGPRINT("%s: Device not up, packet dropped\n",
24432 + dev->name);
24433 + */
24434 +#ifdef CONFIG_64BIT
24435 + atomic64_add(1, (atomic64_t *)&priv->stats.rx_dropped);
24436 +#else
24437 + atomic_add(1, (atomic_t *)&priv->stats.rx_dropped);
24438 +#endif
24439 + dev_kfree_skb_irq(skb);
24440 + }
24441 + } else {
24442 + /*
24443 + * Drop any packet received for a device that
24444 + * doesn't exist.
24445 + */
24446 + DEBUGPRINT("Port %d not controlled by Linux, packet "
24447 + "dropped\n",
24448 + work->ipprt);
24449 + dev_kfree_skb_irq(skb);
24450 + }
24451 + /*
24452 + * Check to see if the skbuff and work share the same
24453 + * packet buffer.
24454 + */
24455 + if (USE_SKBUFFS_IN_HW && likely(packet_not_copied)) {
24456 + /*
24457 + * This buffer needs to be replaced, increment
24458 + * the number of buffers we need to free by
24459 + * one.
24460 + */
24461 + cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
24462 + 1);
24463 +
24464 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL,
24465 + DONT_WRITEBACK(1));
24466 + } else {
24467 + cvm_oct_free_work(work);
24468 + }
24469 + }
24470 +
24471 + /* Restore the original POW group mask */
24472 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask);
24473 + if (USE_ASYNC_IOBDMA) {
24474 + /* Restore the scratch area */
24475 + cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
24476 + }
24477 +
24478 + if (USE_SKBUFFS_IN_HW) {
24479 + /* Refill the packet buffer pool */
24480 + number_to_free =
24481 + cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
24482 +
24483 + if (number_to_free > 0) {
24484 + cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
24485 + -number_to_free);
24486 + num_freed =
24487 + cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL,
24488 + CVMX_FPA_PACKET_POOL_SIZE,
24489 + number_to_free);
24490 + if (num_freed != number_to_free) {
24491 + cvmx_fau_atomic_add32
24492 + (FAU_NUM_PACKET_BUFFERS_TO_FREE,
24493 + number_to_free - num_freed);
24494 + }
24495 + }
24496 + }
24497 +}
24498 +
24499 +void cvm_oct_rx_initialize(void)
24500 +{
24501 + int i;
24502 + /* Initialize all of the tasklets */
24503 + for (i = 0; i < NR_CPUS; i++)
24504 + tasklet_init(&cvm_oct_tasklet[i].t, cvm_oct_tasklet_rx, 0);
24505 +}
24506 +
24507 +void cvm_oct_rx_shutdown(void)
24508 +{
24509 + int i;
24510 + /* Shutdown all of the tasklets */
24511 + for (i = 0; i < NR_CPUS; i++)
24512 + tasklet_kill(&cvm_oct_tasklet[i].t);
24513 +}
24514 --- /dev/null
24515 +++ b/drivers/staging/octeon/ethernet-rx.h
24516 @@ -0,0 +1,33 @@
24517 +/*********************************************************************
24518 + * Author: Cavium Networks
24519 + *
24520 + * Contact: support@caviumnetworks.com
24521 + * This file is part of the OCTEON SDK
24522 + *
24523 + * Copyright (c) 2003-2007 Cavium Networks
24524 + *
24525 + * This file is free software; you can redistribute it and/or modify
24526 + * it under the terms of the GNU General Public License, Version 2, as
24527 + * published by the Free Software Foundation.
24528 + *
24529 + * This file is distributed in the hope that it will be useful, but
24530 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24531 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24532 + * NONINFRINGEMENT. See the GNU General Public License for more
24533 + * details.
24534 + *
24535 + * You should have received a copy of the GNU General Public License
24536 + * along with this file; if not, write to the Free Software
24537 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24538 + * or visit http://www.gnu.org/licenses/.
24539 + *
24540 + * This file may also be available under a different license from Cavium.
24541 + * Contact Cavium Networks for more information
24542 +*********************************************************************/
24543 +
24544 +irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id);
24545 +void cvm_oct_poll_controller(struct net_device *dev);
24546 +void cvm_oct_tasklet_rx(unsigned long unused);
24547 +
24548 +void cvm_oct_rx_initialize(void);
24549 +void cvm_oct_rx_shutdown(void);
24550 --- /dev/null
24551 +++ b/drivers/staging/octeon/ethernet-sgmii.c
24552 @@ -0,0 +1,129 @@
24553 +/**********************************************************************
24554 + * Author: Cavium Networks
24555 + *
24556 + * Contact: support@caviumnetworks.com
24557 + * This file is part of the OCTEON SDK
24558 + *
24559 + * Copyright (c) 2003-2007 Cavium Networks
24560 + *
24561 + * This file is free software; you can redistribute it and/or modify
24562 + * it under the terms of the GNU General Public License, Version 2, as
24563 + * published by the Free Software Foundation.
24564 + *
24565 + * This file is distributed in the hope that it will be useful, but
24566 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24567 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24568 + * NONINFRINGEMENT. See the GNU General Public License for more
24569 + * details.
24570 + *
24571 + * You should have received a copy of the GNU General Public License
24572 + * along with this file; if not, write to the Free Software
24573 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24574 + * or visit http://www.gnu.org/licenses/.
24575 + *
24576 + * This file may also be available under a different license from Cavium.
24577 + * Contact Cavium Networks for more information
24578 +**********************************************************************/
24579 +#include <linux/kernel.h>
24580 +#include <linux/netdevice.h>
24581 +#include <linux/mii.h>
24582 +#include <net/dst.h>
24583 +
24584 +#include <asm/octeon/octeon.h>
24585 +
24586 +#include "ethernet-defines.h"
24587 +#include "octeon-ethernet.h"
24588 +#include "ethernet-util.h"
24589 +#include "ethernet-common.h"
24590 +
24591 +#include "cvmx-helper.h"
24592 +
24593 +#include "cvmx-gmxx-defs.h"
24594 +
24595 +static int cvm_oct_sgmii_open(struct net_device *dev)
24596 +{
24597 + union cvmx_gmxx_prtx_cfg gmx_cfg;
24598 + struct octeon_ethernet *priv = netdev_priv(dev);
24599 + int interface = INTERFACE(priv->port);
24600 + int index = INDEX(priv->port);
24601 + cvmx_helper_link_info_t link_info;
24602 +
24603 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
24604 + gmx_cfg.s.en = 1;
24605 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
24606 +
24607 + if (!octeon_is_simulation()) {
24608 + link_info = cvmx_helper_link_get(priv->port);
24609 + if (!link_info.s.link_up)
24610 + netif_carrier_off(dev);
24611 + }
24612 +
24613 + return 0;
24614 +}
24615 +
24616 +static int cvm_oct_sgmii_stop(struct net_device *dev)
24617 +{
24618 + union cvmx_gmxx_prtx_cfg gmx_cfg;
24619 + struct octeon_ethernet *priv = netdev_priv(dev);
24620 + int interface = INTERFACE(priv->port);
24621 + int index = INDEX(priv->port);
24622 +
24623 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
24624 + gmx_cfg.s.en = 0;
24625 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
24626 + return 0;
24627 +}
24628 +
24629 +static void cvm_oct_sgmii_poll(struct net_device *dev)
24630 +{
24631 + struct octeon_ethernet *priv = netdev_priv(dev);
24632 + cvmx_helper_link_info_t link_info;
24633 +
24634 + link_info = cvmx_helper_link_get(priv->port);
24635 + if (link_info.u64 == priv->link_info)
24636 + return;
24637 +
24638 + link_info = cvmx_helper_link_autoconf(priv->port);
24639 + priv->link_info = link_info.u64;
24640 +
24641 + /* Tell Linux */
24642 + if (link_info.s.link_up) {
24643 +
24644 + if (!netif_carrier_ok(dev))
24645 + netif_carrier_on(dev);
24646 + if (priv->queue != -1)
24647 + DEBUGPRINT
24648 + ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
24649 + dev->name, link_info.s.speed,
24650 + (link_info.s.full_duplex) ? "Full" : "Half",
24651 + priv->port, priv->queue);
24652 + else
24653 + DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
24654 + dev->name, link_info.s.speed,
24655 + (link_info.s.full_duplex) ? "Full" : "Half",
24656 + priv->port);
24657 + } else {
24658 + if (netif_carrier_ok(dev))
24659 + netif_carrier_off(dev);
24660 + DEBUGPRINT("%s: Link down\n", dev->name);
24661 + }
24662 +}
24663 +
24664 +int cvm_oct_sgmii_init(struct net_device *dev)
24665 +{
24666 + struct octeon_ethernet *priv = netdev_priv(dev);
24667 + cvm_oct_common_init(dev);
24668 + dev->open = cvm_oct_sgmii_open;
24669 + dev->stop = cvm_oct_sgmii_stop;
24670 + dev->stop(dev);
24671 + if (!octeon_is_simulation())
24672 + priv->poll = cvm_oct_sgmii_poll;
24673 +
24674 + /* FIXME: Need autoneg logic */
24675 + return 0;
24676 +}
24677 +
24678 +void cvm_oct_sgmii_uninit(struct net_device *dev)
24679 +{
24680 + cvm_oct_common_uninit(dev);
24681 +}
24682 --- /dev/null
24683 +++ b/drivers/staging/octeon/ethernet-spi.c
24684 @@ -0,0 +1,323 @@
24685 +/**********************************************************************
24686 + * Author: Cavium Networks
24687 + *
24688 + * Contact: support@caviumnetworks.com
24689 + * This file is part of the OCTEON SDK
24690 + *
24691 + * Copyright (c) 2003-2007 Cavium Networks
24692 + *
24693 + * This file is free software; you can redistribute it and/or modify
24694 + * it under the terms of the GNU General Public License, Version 2, as
24695 + * published by the Free Software Foundation.
24696 + *
24697 + * This file is distributed in the hope that it will be useful, but
24698 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24699 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24700 + * NONINFRINGEMENT. See the GNU General Public License for more
24701 + * details.
24702 + *
24703 + * You should have received a copy of the GNU General Public License
24704 + * along with this file; if not, write to the Free Software
24705 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24706 + * or visit http://www.gnu.org/licenses/.
24707 + *
24708 + * This file may also be available under a different license from Cavium.
24709 + * Contact Cavium Networks for more information
24710 +**********************************************************************/
24711 +#include <linux/kernel.h>
24712 +#include <linux/netdevice.h>
24713 +#include <linux/mii.h>
24714 +#include <net/dst.h>
24715 +
24716 +#include <asm/octeon/octeon.h>
24717 +
24718 +#include "ethernet-defines.h"
24719 +#include "octeon-ethernet.h"
24720 +#include "ethernet-common.h"
24721 +#include "ethernet-util.h"
24722 +
24723 +#include "cvmx-spi.h"
24724 +
24725 +#include <asm/octeon/cvmx-npi-defs.h>
24726 +#include "cvmx-spxx-defs.h"
24727 +#include "cvmx-stxx-defs.h"
24728 +
24729 +static int number_spi_ports;
24730 +static int need_retrain[2] = { 0, 0 };
24731 +
24732 +static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
24733 +{
24734 + irqreturn_t return_status = IRQ_NONE;
24735 + union cvmx_npi_rsl_int_blocks rsl_int_blocks;
24736 +
24737 + /* Check and see if this interrupt was caused by the GMX block */
24738 + rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
24739 + if (rsl_int_blocks.s.spx1) { /* 19 - SPX1_INT_REG & STX1_INT_REG */
24740 +
24741 + union cvmx_spxx_int_reg spx_int_reg;
24742 + union cvmx_stxx_int_reg stx_int_reg;
24743 +
24744 + spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(1));
24745 + cvmx_write_csr(CVMX_SPXX_INT_REG(1), spx_int_reg.u64);
24746 + if (!need_retrain[1]) {
24747 +
24748 + spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(1));
24749 + if (spx_int_reg.s.spf)
24750 + pr_err("SPI1: SRX Spi4 interface down\n");
24751 + if (spx_int_reg.s.calerr)
24752 + pr_err("SPI1: SRX Spi4 Calendar table "
24753 + "parity error\n");
24754 + if (spx_int_reg.s.syncerr)
24755 + pr_err("SPI1: SRX Consecutive Spi4 DIP4 "
24756 + "errors have exceeded "
24757 + "SPX_ERR_CTL[ERRCNT]\n");
24758 + if (spx_int_reg.s.diperr)
24759 + pr_err("SPI1: SRX Spi4 DIP4 error\n");
24760 + if (spx_int_reg.s.tpaovr)
24761 + pr_err("SPI1: SRX Selected port has hit "
24762 + "TPA overflow\n");
24763 + if (spx_int_reg.s.rsverr)
24764 + pr_err("SPI1: SRX Spi4 reserved control "
24765 + "word detected\n");
24766 + if (spx_int_reg.s.drwnng)
24767 + pr_err("SPI1: SRX Spi4 receive FIFO "
24768 + "drowning/overflow\n");
24769 + if (spx_int_reg.s.clserr)
24770 + pr_err("SPI1: SRX Spi4 packet closed on "
24771 + "non-16B alignment without EOP\n");
24772 + if (spx_int_reg.s.spiovr)
24773 + pr_err("SPI1: SRX Spi4 async FIFO overflow\n");
24774 + if (spx_int_reg.s.abnorm)
24775 + pr_err("SPI1: SRX Abnormal packet "
24776 + "termination (ERR bit)\n");
24777 + if (spx_int_reg.s.prtnxa)
24778 + pr_err("SPI1: SRX Port out of range\n");
24779 + }
24780 +
24781 + stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(1));
24782 + cvmx_write_csr(CVMX_STXX_INT_REG(1), stx_int_reg.u64);
24783 + if (!need_retrain[1]) {
24784 +
24785 + stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(1));
24786 + if (stx_int_reg.s.syncerr)
24787 + pr_err("SPI1: STX Interface encountered a "
24788 + "fatal error\n");
24789 + if (stx_int_reg.s.frmerr)
24790 + pr_err("SPI1: STX FRMCNT has exceeded "
24791 + "STX_DIP_CNT[MAXFRM]\n");
24792 + if (stx_int_reg.s.unxfrm)
24793 + pr_err("SPI1: STX Unexpected framing "
24794 + "sequence\n");
24795 + if (stx_int_reg.s.nosync)
24796 + pr_err("SPI1: STX ERRCNT has exceeded "
24797 + "STX_DIP_CNT[MAXDIP]\n");
24798 + if (stx_int_reg.s.diperr)
24799 + pr_err("SPI1: STX DIP2 error on the Spi4 "
24800 + "Status channel\n");
24801 + if (stx_int_reg.s.datovr)
24802 + pr_err("SPI1: STX Spi4 FIFO overflow error\n");
24803 + if (stx_int_reg.s.ovrbst)
24804 + pr_err("SPI1: STX Transmit packet burst "
24805 + "too big\n");
24806 + if (stx_int_reg.s.calpar1)
24807 + pr_err("SPI1: STX Calendar Table Parity "
24808 + "Error Bank1\n");
24809 + if (stx_int_reg.s.calpar0)
24810 + pr_err("SPI1: STX Calendar Table Parity "
24811 + "Error Bank0\n");
24812 + }
24813 +
24814 + cvmx_write_csr(CVMX_SPXX_INT_MSK(1), 0);
24815 + cvmx_write_csr(CVMX_STXX_INT_MSK(1), 0);
24816 + need_retrain[1] = 1;
24817 + return_status = IRQ_HANDLED;
24818 + }
24819 +
24820 + if (rsl_int_blocks.s.spx0) { /* 18 - SPX0_INT_REG & STX0_INT_REG */
24821 + union cvmx_spxx_int_reg spx_int_reg;
24822 + union cvmx_stxx_int_reg stx_int_reg;
24823 +
24824 + spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(0));
24825 + cvmx_write_csr(CVMX_SPXX_INT_REG(0), spx_int_reg.u64);
24826 + if (!need_retrain[0]) {
24827 +
24828 + spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(0));
24829 + if (spx_int_reg.s.spf)
24830 + pr_err("SPI0: SRX Spi4 interface down\n");
24831 + if (spx_int_reg.s.calerr)
24832 + pr_err("SPI0: SRX Spi4 Calendar table "
24833 + "parity error\n");
24834 + if (spx_int_reg.s.syncerr)
24835 + pr_err("SPI0: SRX Consecutive Spi4 DIP4 "
24836 + "errors have exceeded "
24837 + "SPX_ERR_CTL[ERRCNT]\n");
24838 + if (spx_int_reg.s.diperr)
24839 + pr_err("SPI0: SRX Spi4 DIP4 error\n");
24840 + if (spx_int_reg.s.tpaovr)
24841 + pr_err("SPI0: SRX Selected port has hit "
24842 + "TPA overflow\n");
24843 + if (spx_int_reg.s.rsverr)
24844 + pr_err("SPI0: SRX Spi4 reserved control "
24845 + "word detected\n");
24846 + if (spx_int_reg.s.drwnng)
24847 + pr_err("SPI0: SRX Spi4 receive FIFO "
24848 + "drowning/overflow\n");
24849 + if (spx_int_reg.s.clserr)
24850 + pr_err("SPI0: SRX Spi4 packet closed on "
24851 + "non-16B alignment without EOP\n");
24852 + if (spx_int_reg.s.spiovr)
24853 + pr_err("SPI0: SRX Spi4 async FIFO overflow\n");
24854 + if (spx_int_reg.s.abnorm)
24855 + pr_err("SPI0: SRX Abnormal packet "
24856 + "termination (ERR bit)\n");
24857 + if (spx_int_reg.s.prtnxa)
24858 + pr_err("SPI0: SRX Port out of range\n");
24859 + }
24860 +
24861 + stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(0));
24862 + cvmx_write_csr(CVMX_STXX_INT_REG(0), stx_int_reg.u64);
24863 + if (!need_retrain[0]) {
24864 +
24865 + stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(0));
24866 + if (stx_int_reg.s.syncerr)
24867 + pr_err("SPI0: STX Interface encountered a "
24868 + "fatal error\n");
24869 + if (stx_int_reg.s.frmerr)
24870 + pr_err("SPI0: STX FRMCNT has exceeded "
24871 + "STX_DIP_CNT[MAXFRM]\n");
24872 + if (stx_int_reg.s.unxfrm)
24873 + pr_err("SPI0: STX Unexpected framing "
24874 + "sequence\n");
24875 + if (stx_int_reg.s.nosync)
24876 + pr_err("SPI0: STX ERRCNT has exceeded "
24877 + "STX_DIP_CNT[MAXDIP]\n");
24878 + if (stx_int_reg.s.diperr)
24879 + pr_err("SPI0: STX DIP2 error on the Spi4 "
24880 + "Status channel\n");
24881 + if (stx_int_reg.s.datovr)
24882 + pr_err("SPI0: STX Spi4 FIFO overflow error\n");
24883 + if (stx_int_reg.s.ovrbst)
24884 + pr_err("SPI0: STX Transmit packet burst "
24885 + "too big\n");
24886 + if (stx_int_reg.s.calpar1)
24887 + pr_err("SPI0: STX Calendar Table Parity "
24888 + "Error Bank1\n");
24889 + if (stx_int_reg.s.calpar0)
24890 + pr_err("SPI0: STX Calendar Table Parity "
24891 + "Error Bank0\n");
24892 + }
24893 +
24894 + cvmx_write_csr(CVMX_SPXX_INT_MSK(0), 0);
24895 + cvmx_write_csr(CVMX_STXX_INT_MSK(0), 0);
24896 + need_retrain[0] = 1;
24897 + return_status = IRQ_HANDLED;
24898 + }
24899 +
24900 + return return_status;
24901 +}
24902 +
24903 +static void cvm_oct_spi_enable_error_reporting(int interface)
24904 +{
24905 + union cvmx_spxx_int_msk spxx_int_msk;
24906 + union cvmx_stxx_int_msk stxx_int_msk;
24907 +
24908 + spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
24909 + spxx_int_msk.s.calerr = 1;
24910 + spxx_int_msk.s.syncerr = 1;
24911 + spxx_int_msk.s.diperr = 1;
24912 + spxx_int_msk.s.tpaovr = 1;
24913 + spxx_int_msk.s.rsverr = 1;
24914 + spxx_int_msk.s.drwnng = 1;
24915 + spxx_int_msk.s.clserr = 1;
24916 + spxx_int_msk.s.spiovr = 1;
24917 + spxx_int_msk.s.abnorm = 1;
24918 + spxx_int_msk.s.prtnxa = 1;
24919 + cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
24920 +
24921 + stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
24922 + stxx_int_msk.s.frmerr = 1;
24923 + stxx_int_msk.s.unxfrm = 1;
24924 + stxx_int_msk.s.nosync = 1;
24925 + stxx_int_msk.s.diperr = 1;
24926 + stxx_int_msk.s.datovr = 1;
24927 + stxx_int_msk.s.ovrbst = 1;
24928 + stxx_int_msk.s.calpar1 = 1;
24929 + stxx_int_msk.s.calpar0 = 1;
24930 + cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
24931 +}
24932 +
24933 +static void cvm_oct_spi_poll(struct net_device *dev)
24934 +{
24935 + static int spi4000_port;
24936 + struct octeon_ethernet *priv = netdev_priv(dev);
24937 + int interface;
24938 +
24939 + for (interface = 0; interface < 2; interface++) {
24940 +
24941 + if ((priv->port == interface * 16) && need_retrain[interface]) {
24942 +
24943 + if (cvmx_spi_restart_interface
24944 + (interface, CVMX_SPI_MODE_DUPLEX, 10) == 0) {
24945 + need_retrain[interface] = 0;
24946 + cvm_oct_spi_enable_error_reporting(interface);
24947 + }
24948 + }
24949 +
24950 + /*
24951 + * The SPI4000 TWSI interface is very slow. In order
24952 + * not to bring the system to a crawl, we only poll a
24953 + * single port every second. This means negotiation
24954 + * speed changes take up to 10 seconds, but at least
24955 + * we don't waste absurd amounts of time waiting for
24956 + * TWSI.
24957 + */
24958 + if (priv->port == spi4000_port) {
24959 + /*
24960 + * This function does nothing if it is called on an
24961 + * interface without a SPI4000.
24962 + */
24963 + cvmx_spi4000_check_speed(interface, priv->port);
24964 + /*
24965 + * Normal ordering increments. By decrementing
24966 + * we only match once per iteration.
24967 + */
24968 + spi4000_port--;
24969 + if (spi4000_port < 0)
24970 + spi4000_port = 10;
24971 + }
24972 + }
24973 +}
24974 +
24975 +int cvm_oct_spi_init(struct net_device *dev)
24976 +{
24977 + int r;
24978 + struct octeon_ethernet *priv = netdev_priv(dev);
24979 +
24980 + if (number_spi_ports == 0) {
24981 + r = request_irq(OCTEON_IRQ_RML, cvm_oct_spi_rml_interrupt,
24982 + IRQF_SHARED, "SPI", &number_spi_ports);
24983 + }
24984 + number_spi_ports++;
24985 +
24986 + if ((priv->port == 0) || (priv->port == 16)) {
24987 + cvm_oct_spi_enable_error_reporting(INTERFACE(priv->port));
24988 + priv->poll = cvm_oct_spi_poll;
24989 + }
24990 + cvm_oct_common_init(dev);
24991 + return 0;
24992 +}
24993 +
24994 +void cvm_oct_spi_uninit(struct net_device *dev)
24995 +{
24996 + int interface;
24997 +
24998 + cvm_oct_common_uninit(dev);
24999 + number_spi_ports--;
25000 + if (number_spi_ports == 0) {
25001 + for (interface = 0; interface < 2; interface++) {
25002 + cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
25003 + cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
25004 + }
25005 + free_irq(8 + 46, &number_spi_ports);
25006 + }
25007 +}
25008 --- /dev/null
25009 +++ b/drivers/staging/octeon/ethernet-tx.c
25010 @@ -0,0 +1,634 @@
25011 +/*********************************************************************
25012 + * Author: Cavium Networks
25013 + *
25014 + * Contact: support@caviumnetworks.com
25015 + * This file is part of the OCTEON SDK
25016 + *
25017 + * Copyright (c) 2003-2007 Cavium Networks
25018 + *
25019 + * This file is free software; you can redistribute it and/or modify
25020 + * it under the terms of the GNU General Public License, Version 2, as
25021 + * published by the Free Software Foundation.
25022 + *
25023 + * This file is distributed in the hope that it will be useful, but
25024 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25025 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25026 + * NONINFRINGEMENT. See the GNU General Public License for more
25027 + * details.
25028 + *
25029 + * You should have received a copy of the GNU General Public License
25030 + * along with this file; if not, write to the Free Software
25031 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25032 + * or visit http://www.gnu.org/licenses/.
25033 + *
25034 + * This file may also be available under a different license from Cavium.
25035 + * Contact Cavium Networks for more information
25036 +*********************************************************************/
25037 +#include <linux/module.h>
25038 +#include <linux/kernel.h>
25039 +#include <linux/netdevice.h>
25040 +#include <linux/init.h>
25041 +#include <linux/etherdevice.h>
25042 +#include <linux/ip.h>
25043 +#include <linux/string.h>
25044 +#include <linux/ethtool.h>
25045 +#include <linux/mii.h>
25046 +#include <linux/seq_file.h>
25047 +#include <linux/proc_fs.h>
25048 +#include <net/dst.h>
25049 +#ifdef CONFIG_XFRM
25050 +#include <linux/xfrm.h>
25051 +#include <net/xfrm.h>
25052 +#endif /* CONFIG_XFRM */
25053 +
25054 +#include <asm/atomic.h>
25055 +
25056 +#include <asm/octeon/octeon.h>
25057 +
25058 +#include "ethernet-defines.h"
25059 +#include "octeon-ethernet.h"
25060 +#include "ethernet-util.h"
25061 +
25062 +#include "cvmx-wqe.h"
25063 +#include "cvmx-fau.h"
25064 +#include "cvmx-pko.h"
25065 +#include "cvmx-helper.h"
25066 +
25067 +#include "cvmx-gmxx-defs.h"
25068 +
25069 +/*
25070 + * You can define GET_SKBUFF_QOS() to override how the skbuff output
25071 + * function determines which output queue is used. The default
25072 + * implementation always uses the base queue for the port. If, for
25073 + * example, you wanted to use the skb->priority fieid, define
25074 + * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority)
25075 + */
25076 +#ifndef GET_SKBUFF_QOS
25077 +#define GET_SKBUFF_QOS(skb) 0
25078 +#endif
25079 +
25080 +/**
25081 + * Packet transmit
25082 + *
25083 + * @skb: Packet to send
25084 + * @dev: Device info structure
25085 + * Returns Always returns zero
25086 + */
25087 +int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
25088 +{
25089 + cvmx_pko_command_word0_t pko_command;
25090 + union cvmx_buf_ptr hw_buffer;
25091 + uint64_t old_scratch;
25092 + uint64_t old_scratch2;
25093 + int dropped;
25094 + int qos;
25095 + struct octeon_ethernet *priv = netdev_priv(dev);
25096 + int32_t in_use;
25097 + int32_t buffers_to_free;
25098 +#if REUSE_SKBUFFS_WITHOUT_FREE
25099 + unsigned char *fpa_head;
25100 +#endif
25101 +
25102 + /*
25103 + * Prefetch the private data structure. It is larger that one
25104 + * cache line.
25105 + */
25106 + prefetch(priv);
25107 +
25108 + /* Start off assuming no drop */
25109 + dropped = 0;
25110 +
25111 + /*
25112 + * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
25113 + * completely remove "qos" in the event neither interface
25114 + * supports multiple queues per port.
25115 + */
25116 + if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
25117 + (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
25118 + qos = GET_SKBUFF_QOS(skb);
25119 + if (qos <= 0)
25120 + qos = 0;
25121 + else if (qos >= cvmx_pko_get_num_queues(priv->port))
25122 + qos = 0;
25123 + } else
25124 + qos = 0;
25125 +
25126 + if (USE_ASYNC_IOBDMA) {
25127 + /* Save scratch in case userspace is using it */
25128 + CVMX_SYNCIOBDMA;
25129 + old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
25130 + old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
25131 +
25132 + /*
25133 + * Assume we're going to be able t osend this
25134 + * packet. Fetch and increment the number of pending
25135 + * packets for output.
25136 + */
25137 + cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8,
25138 + FAU_NUM_PACKET_BUFFERS_TO_FREE,
25139 + 0);
25140 + cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
25141 + priv->fau + qos * 4, 1);
25142 + }
25143 +
25144 + /*
25145 + * The CN3XXX series of parts has an errata (GMX-401) which
25146 + * causes the GMX block to hang if a collision occurs towards
25147 + * the end of a <68 byte packet. As a workaround for this, we
25148 + * pad packets to be 68 bytes whenever we are in half duplex
25149 + * mode. We don't handle the case of having a small packet but
25150 + * no room to add the padding. The kernel should always give
25151 + * us at least a cache line
25152 + */
25153 + if ((skb->len < 64) && OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
25154 + union cvmx_gmxx_prtx_cfg gmx_prt_cfg;
25155 + int interface = INTERFACE(priv->port);
25156 + int index = INDEX(priv->port);
25157 +
25158 + if (interface < 2) {
25159 + /* We only need to pad packet in half duplex mode */
25160 + gmx_prt_cfg.u64 =
25161 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
25162 + if (gmx_prt_cfg.s.duplex == 0) {
25163 + int add_bytes = 64 - skb->len;
25164 + if ((skb_tail_pointer(skb) + add_bytes) <=
25165 + skb_end_pointer(skb))
25166 + memset(__skb_put(skb, add_bytes), 0,
25167 + add_bytes);
25168 + }
25169 + }
25170 + }
25171 +
25172 + /* Build the PKO buffer pointer */
25173 + hw_buffer.u64 = 0;
25174 + hw_buffer.s.addr = cvmx_ptr_to_phys(skb->data);
25175 + hw_buffer.s.pool = 0;
25176 + hw_buffer.s.size =
25177 + (unsigned long)skb_end_pointer(skb) - (unsigned long)skb->head;
25178 +
25179 + /* Build the PKO command */
25180 + pko_command.u64 = 0;
25181 + pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */
25182 + pko_command.s.segs = 1;
25183 + pko_command.s.total_bytes = skb->len;
25184 + pko_command.s.size0 = CVMX_FAU_OP_SIZE_32;
25185 + pko_command.s.subone0 = 1;
25186 +
25187 + pko_command.s.dontfree = 1;
25188 + pko_command.s.reg0 = priv->fau + qos * 4;
25189 + /*
25190 + * See if we can put this skb in the FPA pool. Any strange
25191 + * behavior from the Linux networking stack will most likely
25192 + * be caused by a bug in the following code. If some field is
25193 + * in use by the network stack and get carried over when a
25194 + * buffer is reused, bad thing may happen. If in doubt and
25195 + * you dont need the absolute best performance, disable the
25196 + * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has
25197 + * shown a 25% increase in performance under some loads.
25198 + */
25199 +#if REUSE_SKBUFFS_WITHOUT_FREE
25200 + fpa_head = skb->head + 128 - ((unsigned long)skb->head & 0x7f);
25201 + if (unlikely(skb->data < fpa_head)) {
25202 + /*
25203 + * printk("TX buffer beginning can't meet FPA
25204 + * alignment constraints\n");
25205 + */
25206 + goto dont_put_skbuff_in_hw;
25207 + }
25208 + if (unlikely
25209 + ((skb_end_pointer(skb) - fpa_head) < CVMX_FPA_PACKET_POOL_SIZE)) {
25210 + /*
25211 + printk("TX buffer isn't large enough for the FPA\n");
25212 + */
25213 + goto dont_put_skbuff_in_hw;
25214 + }
25215 + if (unlikely(skb_shared(skb))) {
25216 + /*
25217 + printk("TX buffer sharing data with someone else\n");
25218 + */
25219 + goto dont_put_skbuff_in_hw;
25220 + }
25221 + if (unlikely(skb_cloned(skb))) {
25222 + /*
25223 + printk("TX buffer has been cloned\n");
25224 + */
25225 + goto dont_put_skbuff_in_hw;
25226 + }
25227 + if (unlikely(skb_header_cloned(skb))) {
25228 + /*
25229 + printk("TX buffer header has been cloned\n");
25230 + */
25231 + goto dont_put_skbuff_in_hw;
25232 + }
25233 + if (unlikely(skb->destructor)) {
25234 + /*
25235 + printk("TX buffer has a destructor\n");
25236 + */
25237 + goto dont_put_skbuff_in_hw;
25238 + }
25239 + if (unlikely(skb_shinfo(skb)->nr_frags)) {
25240 + /*
25241 + printk("TX buffer has fragments\n");
25242 + */
25243 + goto dont_put_skbuff_in_hw;
25244 + }
25245 + if (unlikely
25246 + (skb->truesize !=
25247 + sizeof(*skb) + skb_end_pointer(skb) - skb->head)) {
25248 + /*
25249 + printk("TX buffer truesize has been changed\n");
25250 + */
25251 + goto dont_put_skbuff_in_hw;
25252 + }
25253 +
25254 + /*
25255 + * We can use this buffer in the FPA. We don't need the FAU
25256 + * update anymore
25257 + */
25258 + pko_command.s.reg0 = 0;
25259 + pko_command.s.dontfree = 0;
25260 +
25261 + hw_buffer.s.back = (skb->data - fpa_head) >> 7;
25262 + *(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
25263 +
25264 + /*
25265 + * The skbuff will be reused without ever being freed. We must
25266 + * cleanup a bunch of Linux stuff.
25267 + */
25268 + dst_release(skb->dst);
25269 + skb->dst = NULL;
25270 +#ifdef CONFIG_XFRM
25271 + secpath_put(skb->sp);
25272 + skb->sp = NULL;
25273 +#endif
25274 + nf_reset(skb);
25275 +
25276 +#ifdef CONFIG_NET_SCHED
25277 + skb->tc_index = 0;
25278 +#ifdef CONFIG_NET_CLS_ACT
25279 + skb->tc_verd = 0;
25280 +#endif /* CONFIG_NET_CLS_ACT */
25281 +#endif /* CONFIG_NET_SCHED */
25282 +
25283 +dont_put_skbuff_in_hw:
25284 +#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
25285 +
25286 + /* Check if we can use the hardware checksumming */
25287 + if (USE_HW_TCPUDP_CHECKSUM && (skb->protocol == htons(ETH_P_IP)) &&
25288 + (ip_hdr(skb)->version == 4) && (ip_hdr(skb)->ihl == 5) &&
25289 + ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == 1 << 14))
25290 + && ((ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
25291 + || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP))) {
25292 + /* Use hardware checksum calc */
25293 + pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
25294 + }
25295 +
25296 + if (USE_ASYNC_IOBDMA) {
25297 + /* Get the number of skbuffs in use by the hardware */
25298 + CVMX_SYNCIOBDMA;
25299 + in_use = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
25300 + buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
25301 + } else {
25302 + /* Get the number of skbuffs in use by the hardware */
25303 + in_use = cvmx_fau_fetch_and_add32(priv->fau + qos * 4, 1);
25304 + buffers_to_free =
25305 + cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
25306 + }
25307 +
25308 + /*
25309 + * If we're sending faster than the receive can free them then
25310 + * don't do the HW free.
25311 + */
25312 + if ((buffers_to_free < -100) && !pko_command.s.dontfree) {
25313 + pko_command.s.dontfree = 1;
25314 + pko_command.s.reg0 = priv->fau + qos * 4;
25315 + }
25316 +
25317 + cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
25318 + CVMX_PKO_LOCK_CMD_QUEUE);
25319 +
25320 + /* Drop this packet if we have too many already queued to the HW */
25321 + if (unlikely
25322 + (skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) {
25323 + /*
25324 + DEBUGPRINT("%s: Tx dropped. Too many queued\n", dev->name);
25325 + */
25326 + dropped = 1;
25327 + }
25328 + /* Send the packet to the output queue */
25329 + else if (unlikely
25330 + (cvmx_pko_send_packet_finish
25331 + (priv->port, priv->queue + qos, pko_command, hw_buffer,
25332 + CVMX_PKO_LOCK_CMD_QUEUE))) {
25333 + DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
25334 + dropped = 1;
25335 + }
25336 +
25337 + if (USE_ASYNC_IOBDMA) {
25338 + /* Restore the scratch area */
25339 + cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
25340 + cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2);
25341 + }
25342 +
25343 + if (unlikely(dropped)) {
25344 + dev_kfree_skb_any(skb);
25345 + cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
25346 + priv->stats.tx_dropped++;
25347 + } else {
25348 + if (USE_SKBUFFS_IN_HW) {
25349 + /* Put this packet on the queue to be freed later */
25350 + if (pko_command.s.dontfree)
25351 + skb_queue_tail(&priv->tx_free_list[qos], skb);
25352 + else {
25353 + cvmx_fau_atomic_add32
25354 + (FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
25355 + cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
25356 + }
25357 + } else {
25358 + /* Put this packet on the queue to be freed later */
25359 + skb_queue_tail(&priv->tx_free_list[qos], skb);
25360 + }
25361 + }
25362 +
25363 + /* Free skbuffs not in use by the hardware, possibly two at a time */
25364 + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) {
25365 + spin_lock(&priv->tx_free_list[qos].lock);
25366 + /*
25367 + * Check again now that we have the lock. It might
25368 + * have changed.
25369 + */
25370 + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use)
25371 + dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
25372 + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use)
25373 + dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
25374 + spin_unlock(&priv->tx_free_list[qos].lock);
25375 + }
25376 +
25377 + return 0;
25378 +}
25379 +
25380 +/**
25381 + * Packet transmit to the POW
25382 + *
25383 + * @skb: Packet to send
25384 + * @dev: Device info structure
25385 + * Returns Always returns zero
25386 + */
25387 +int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
25388 +{
25389 + struct octeon_ethernet *priv = netdev_priv(dev);
25390 + void *packet_buffer;
25391 + void *copy_location;
25392 +
25393 + /* Get a work queue entry */
25394 + cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL);
25395 + if (unlikely(work == NULL)) {
25396 + DEBUGPRINT("%s: Failed to allocate a work queue entry\n",
25397 + dev->name);
25398 + priv->stats.tx_dropped++;
25399 + dev_kfree_skb(skb);
25400 + return 0;
25401 + }
25402 +
25403 + /* Get a packet buffer */
25404 + packet_buffer = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL);
25405 + if (unlikely(packet_buffer == NULL)) {
25406 + DEBUGPRINT("%s: Failed to allocate a packet buffer\n",
25407 + dev->name);
25408 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
25409 + priv->stats.tx_dropped++;
25410 + dev_kfree_skb(skb);
25411 + return 0;
25412 + }
25413 +
25414 + /*
25415 + * Calculate where we need to copy the data to. We need to
25416 + * leave 8 bytes for a next pointer (unused). We also need to
25417 + * include any configure skip. Then we need to align the IP
25418 + * packet src and dest into the same 64bit word. The below
25419 + * calculation may add a little extra, but that doesn't
25420 + * hurt.
25421 + */
25422 + copy_location = packet_buffer + sizeof(uint64_t);
25423 + copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6;
25424 +
25425 + /*
25426 + * We have to copy the packet since whoever processes this
25427 + * packet will free it to a hardware pool. We can't use the
25428 + * trick of counting outstanding packets like in
25429 + * cvm_oct_xmit.
25430 + */
25431 + memcpy(copy_location, skb->data, skb->len);
25432 +
25433 + /*
25434 + * Fill in some of the work queue fields. We may need to add
25435 + * more if the software at the other end needs them.
25436 + */
25437 + work->hw_chksum = skb->csum;
25438 + work->len = skb->len;
25439 + work->ipprt = priv->port;
25440 + work->qos = priv->port & 0x7;
25441 + work->grp = pow_send_group;
25442 + work->tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
25443 + work->tag = pow_send_group; /* FIXME */
25444 + /* Default to zero. Sets of zero later are commented out */
25445 + work->word2.u64 = 0;
25446 + work->word2.s.bufs = 1;
25447 + work->packet_ptr.u64 = 0;
25448 + work->packet_ptr.s.addr = cvmx_ptr_to_phys(copy_location);
25449 + work->packet_ptr.s.pool = CVMX_FPA_PACKET_POOL;
25450 + work->packet_ptr.s.size = CVMX_FPA_PACKET_POOL_SIZE;
25451 + work->packet_ptr.s.back = (copy_location - packet_buffer) >> 7;
25452 +
25453 + if (skb->protocol == htons(ETH_P_IP)) {
25454 + work->word2.s.ip_offset = 14;
25455 +#if 0
25456 + work->word2.s.vlan_valid = 0; /* FIXME */
25457 + work->word2.s.vlan_cfi = 0; /* FIXME */
25458 + work->word2.s.vlan_id = 0; /* FIXME */
25459 + work->word2.s.dec_ipcomp = 0; /* FIXME */
25460 +#endif
25461 + work->word2.s.tcp_or_udp =
25462 + (ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
25463 + || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP);
25464 +#if 0
25465 + /* FIXME */
25466 + work->word2.s.dec_ipsec = 0;
25467 + /* We only support IPv4 right now */
25468 + work->word2.s.is_v6 = 0;
25469 + /* Hardware would set to zero */
25470 + work->word2.s.software = 0;
25471 + /* No error, packet is internal */
25472 + work->word2.s.L4_error = 0;
25473 +#endif
25474 + work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0)
25475 + || (ip_hdr(skb)->frag_off ==
25476 + 1 << 14));
25477 +#if 0
25478 + /* Assume Linux is sending a good packet */
25479 + work->word2.s.IP_exc = 0;
25480 +#endif
25481 + work->word2.s.is_bcast = (skb->pkt_type == PACKET_BROADCAST);
25482 + work->word2.s.is_mcast = (skb->pkt_type == PACKET_MULTICAST);
25483 +#if 0
25484 + /* This is an IP packet */
25485 + work->word2.s.not_IP = 0;
25486 + /* No error, packet is internal */
25487 + work->word2.s.rcv_error = 0;
25488 + /* No error, packet is internal */
25489 + work->word2.s.err_code = 0;
25490 +#endif
25491 +
25492 + /*
25493 + * When copying the data, include 4 bytes of the
25494 + * ethernet header to align the same way hardware
25495 + * does.
25496 + */
25497 + memcpy(work->packet_data, skb->data + 10,
25498 + sizeof(work->packet_data));
25499 + } else {
25500 +#if 0
25501 + work->word2.snoip.vlan_valid = 0; /* FIXME */
25502 + work->word2.snoip.vlan_cfi = 0; /* FIXME */
25503 + work->word2.snoip.vlan_id = 0; /* FIXME */
25504 + work->word2.snoip.software = 0; /* Hardware would set to zero */
25505 +#endif
25506 + work->word2.snoip.is_rarp = skb->protocol == htons(ETH_P_RARP);
25507 + work->word2.snoip.is_arp = skb->protocol == htons(ETH_P_ARP);
25508 + work->word2.snoip.is_bcast =
25509 + (skb->pkt_type == PACKET_BROADCAST);
25510 + work->word2.snoip.is_mcast =
25511 + (skb->pkt_type == PACKET_MULTICAST);
25512 + work->word2.snoip.not_IP = 1; /* IP was done up above */
25513 +#if 0
25514 + /* No error, packet is internal */
25515 + work->word2.snoip.rcv_error = 0;
25516 + /* No error, packet is internal */
25517 + work->word2.snoip.err_code = 0;
25518 +#endif
25519 + memcpy(work->packet_data, skb->data, sizeof(work->packet_data));
25520 + }
25521 +
25522 + /* Submit the packet to the POW */
25523 + cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos,
25524 + work->grp);
25525 + priv->stats.tx_packets++;
25526 + priv->stats.tx_bytes += skb->len;
25527 + dev_kfree_skb(skb);
25528 + return 0;
25529 +}
25530 +
25531 +/**
25532 + * Transmit a work queue entry out of the ethernet port. Both
25533 + * the work queue entry and the packet data can optionally be
25534 + * freed. The work will be freed on error as well.
25535 + *
25536 + * @dev: Device to transmit out.
25537 + * @work_queue_entry:
25538 + * Work queue entry to send
25539 + * @do_free: True if the work queue entry and packet data should be
25540 + * freed. If false, neither will be freed.
25541 + * @qos: Index into the queues for this port to transmit on. This
25542 + * is used to implement QoS if their are multiple queues per
25543 + * port. This parameter must be between 0 and the number of
25544 + * queues per port minus 1. Values outside of this range will
25545 + * be change to zero.
25546 + *
25547 + * Returns Zero on success, negative on failure.
25548 + */
25549 +int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
25550 + int do_free, int qos)
25551 +{
25552 + unsigned long flags;
25553 + union cvmx_buf_ptr hw_buffer;
25554 + cvmx_pko_command_word0_t pko_command;
25555 + int dropped;
25556 + struct octeon_ethernet *priv = netdev_priv(dev);
25557 + cvmx_wqe_t *work = work_queue_entry;
25558 +
25559 + if (!(dev->flags & IFF_UP)) {
25560 + DEBUGPRINT("%s: Device not up\n", dev->name);
25561 + if (do_free)
25562 + cvm_oct_free_work(work);
25563 + return -1;
25564 + }
25565 +
25566 + /* The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to completely
25567 + remove "qos" in the event neither interface supports
25568 + multiple queues per port */
25569 + if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
25570 + (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
25571 + if (qos <= 0)
25572 + qos = 0;
25573 + else if (qos >= cvmx_pko_get_num_queues(priv->port))
25574 + qos = 0;
25575 + } else
25576 + qos = 0;
25577 +
25578 + /* Start off assuming no drop */
25579 + dropped = 0;
25580 +
25581 + local_irq_save(flags);
25582 + cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
25583 + CVMX_PKO_LOCK_CMD_QUEUE);
25584 +
25585 + /* Build the PKO buffer pointer */
25586 + hw_buffer.u64 = 0;
25587 + hw_buffer.s.addr = work->packet_ptr.s.addr;
25588 + hw_buffer.s.pool = CVMX_FPA_PACKET_POOL;
25589 + hw_buffer.s.size = CVMX_FPA_PACKET_POOL_SIZE;
25590 + hw_buffer.s.back = work->packet_ptr.s.back;
25591 +
25592 + /* Build the PKO command */
25593 + pko_command.u64 = 0;
25594 + pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */
25595 + pko_command.s.dontfree = !do_free;
25596 + pko_command.s.segs = work->word2.s.bufs;
25597 + pko_command.s.total_bytes = work->len;
25598 +
25599 + /* Check if we can use the hardware checksumming */
25600 + if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc))
25601 + pko_command.s.ipoffp1 = 0;
25602 + else
25603 + pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
25604 +
25605 + /* Send the packet to the output queue */
25606 + if (unlikely
25607 + (cvmx_pko_send_packet_finish
25608 + (priv->port, priv->queue + qos, pko_command, hw_buffer,
25609 + CVMX_PKO_LOCK_CMD_QUEUE))) {
25610 + DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
25611 + dropped = -1;
25612 + }
25613 + local_irq_restore(flags);
25614 +
25615 + if (unlikely(dropped)) {
25616 + if (do_free)
25617 + cvm_oct_free_work(work);
25618 + priv->stats.tx_dropped++;
25619 + } else if (do_free)
25620 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
25621 +
25622 + return dropped;
25623 +}
25624 +EXPORT_SYMBOL(cvm_oct_transmit_qos);
25625 +
25626 +/**
25627 + * This function frees all skb that are currenty queued for TX.
25628 + *
25629 + * @dev: Device being shutdown
25630 + */
25631 +void cvm_oct_tx_shutdown(struct net_device *dev)
25632 +{
25633 + struct octeon_ethernet *priv = netdev_priv(dev);
25634 + unsigned long flags;
25635 + int qos;
25636 +
25637 + for (qos = 0; qos < 16; qos++) {
25638 + spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
25639 + while (skb_queue_len(&priv->tx_free_list[qos]))
25640 + dev_kfree_skb_any(__skb_dequeue
25641 + (&priv->tx_free_list[qos]));
25642 + spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
25643 + }
25644 +}
25645 --- /dev/null
25646 +++ b/drivers/staging/octeon/ethernet-tx.h
25647 @@ -0,0 +1,32 @@
25648 +/*********************************************************************
25649 + * Author: Cavium Networks
25650 + *
25651 + * Contact: support@caviumnetworks.com
25652 + * This file is part of the OCTEON SDK
25653 + *
25654 + * Copyright (c) 2003-2007 Cavium Networks
25655 + *
25656 + * This file is free software; you can redistribute it and/or modify
25657 + * it under the terms of the GNU General Public License, Version 2, as
25658 + * published by the Free Software Foundation.
25659 + *
25660 + * This file is distributed in the hope that it will be useful, but
25661 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25662 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25663 + * NONINFRINGEMENT. See the GNU General Public License for more
25664 + * details.
25665 + *
25666 + * You should have received a copy of the GNU General Public License
25667 + * along with this file; if not, write to the Free Software
25668 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25669 + * or visit http://www.gnu.org/licenses/.
25670 + *
25671 + * This file may also be available under a different license from Cavium.
25672 + * Contact Cavium Networks for more information
25673 +*********************************************************************/
25674 +
25675 +int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev);
25676 +int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev);
25677 +int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
25678 + int do_free, int qos);
25679 +void cvm_oct_tx_shutdown(struct net_device *dev);
25680 --- /dev/null
25681 +++ b/drivers/staging/octeon/ethernet-util.h
25682 @@ -0,0 +1,81 @@
25683 +/**********************************************************************
25684 + * Author: Cavium Networks
25685 + *
25686 + * Contact: support@caviumnetworks.com
25687 + * This file is part of the OCTEON SDK
25688 + *
25689 + * Copyright (c) 2003-2007 Cavium Networks
25690 + *
25691 + * This file is free software; you can redistribute it and/or modify
25692 + * it under the terms of the GNU General Public License, Version 2, as
25693 + * published by the Free Software Foundation.
25694 + *
25695 + * This file is distributed in the hope that it will be useful, but
25696 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25697 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25698 + * NONINFRINGEMENT. See the GNU General Public License for more
25699 + * details.
25700 + *
25701 + * You should have received a copy of the GNU General Public License
25702 + * along with this file; if not, write to the Free Software
25703 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25704 + * or visit http://www.gnu.org/licenses/.
25705 + *
25706 + * This file may also be available under a different license from Cavium.
25707 + * Contact Cavium Networks for more information
25708 +*********************************************************************/
25709 +
25710 +#define DEBUGPRINT(format, ...) do { if (printk_ratelimit()) \
25711 + printk(format, ##__VA_ARGS__); \
25712 + } while (0)
25713 +
25714 +/**
25715 + * Given a packet data address, return a pointer to the
25716 + * beginning of the packet buffer.
25717 + *
25718 + * @packet_ptr: Packet data hardware address
25719 + * Returns Packet buffer pointer
25720 + */
25721 +static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr)
25722 +{
25723 + return cvmx_phys_to_ptr(((packet_ptr.s.addr >> 7) - packet_ptr.s.back)
25724 + << 7);
25725 +}
25726 +
25727 +/**
25728 + * Given an IPD/PKO port number, return the logical interface it is
25729 + * on.
25730 + *
25731 + * @ipd_port: Port to check
25732 + *
25733 + * Returns Logical interface
25734 + */
25735 +static inline int INTERFACE(int ipd_port)
25736 +{
25737 + if (ipd_port < 32) /* Interface 0 or 1 for RGMII,GMII,SPI, etc */
25738 + return ipd_port >> 4;
25739 + else if (ipd_port < 36) /* Interface 2 for NPI */
25740 + return 2;
25741 + else if (ipd_port < 40) /* Interface 3 for loopback */
25742 + return 3;
25743 + else if (ipd_port == 40) /* Non existant interface for POW0 */
25744 + return 4;
25745 + else
25746 + panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);
25747 +}
25748 +
25749 +/**
25750 + * Given an IPD/PKO port number, return the port's index on a
25751 + * logical interface.
25752 + *
25753 + * @ipd_port: Port to check
25754 + *
25755 + * Returns Index into interface port list
25756 + */
25757 +static inline int INDEX(int ipd_port)
25758 +{
25759 + if (ipd_port < 32)
25760 + return ipd_port & 15;
25761 + else
25762 + return ipd_port & 3;
25763 +}
25764 --- /dev/null
25765 +++ b/drivers/staging/octeon/ethernet-xaui.c
25766 @@ -0,0 +1,127 @@
25767 +/**********************************************************************
25768 + * Author: Cavium Networks
25769 + *
25770 + * Contact: support@caviumnetworks.com
25771 + * This file is part of the OCTEON SDK
25772 + *
25773 + * Copyright (c) 2003-2007 Cavium Networks
25774 + *
25775 + * This file is free software; you can redistribute it and/or modify
25776 + * it under the terms of the GNU General Public License, Version 2, as
25777 + * published by the Free Software Foundation.
25778 + *
25779 + * This file is distributed in the hope that it will be useful, but
25780 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25781 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25782 + * NONINFRINGEMENT. See the GNU General Public License for more
25783 + * details.
25784 + *
25785 + * You should have received a copy of the GNU General Public License
25786 + * along with this file; if not, write to the Free Software
25787 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25788 + * or visit http://www.gnu.org/licenses/.
25789 + *
25790 + * This file may also be available under a different license from Cavium.
25791 + * Contact Cavium Networks for more information
25792 +**********************************************************************/
25793 +#include <linux/kernel.h>
25794 +#include <linux/netdevice.h>
25795 +#include <linux/mii.h>
25796 +#include <net/dst.h>
25797 +
25798 +#include <asm/octeon/octeon.h>
25799 +
25800 +#include "ethernet-defines.h"
25801 +#include "octeon-ethernet.h"
25802 +#include "ethernet-common.h"
25803 +#include "ethernet-util.h"
25804 +
25805 +#include "cvmx-helper.h"
25806 +
25807 +#include "cvmx-gmxx-defs.h"
25808 +
25809 +static int cvm_oct_xaui_open(struct net_device *dev)
25810 +{
25811 + union cvmx_gmxx_prtx_cfg gmx_cfg;
25812 + struct octeon_ethernet *priv = netdev_priv(dev);
25813 + int interface = INTERFACE(priv->port);
25814 + int index = INDEX(priv->port);
25815 + cvmx_helper_link_info_t link_info;
25816 +
25817 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
25818 + gmx_cfg.s.en = 1;
25819 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
25820 +
25821 + if (!octeon_is_simulation()) {
25822 + link_info = cvmx_helper_link_get(priv->port);
25823 + if (!link_info.s.link_up)
25824 + netif_carrier_off(dev);
25825 + }
25826 + return 0;
25827 +}
25828 +
25829 +static int cvm_oct_xaui_stop(struct net_device *dev)
25830 +{
25831 + union cvmx_gmxx_prtx_cfg gmx_cfg;
25832 + struct octeon_ethernet *priv = netdev_priv(dev);
25833 + int interface = INTERFACE(priv->port);
25834 + int index = INDEX(priv->port);
25835 +
25836 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
25837 + gmx_cfg.s.en = 0;
25838 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
25839 + return 0;
25840 +}
25841 +
25842 +static void cvm_oct_xaui_poll(struct net_device *dev)
25843 +{
25844 + struct octeon_ethernet *priv = netdev_priv(dev);
25845 + cvmx_helper_link_info_t link_info;
25846 +
25847 + link_info = cvmx_helper_link_get(priv->port);
25848 + if (link_info.u64 == priv->link_info)
25849 + return;
25850 +
25851 + link_info = cvmx_helper_link_autoconf(priv->port);
25852 + priv->link_info = link_info.u64;
25853 +
25854 + /* Tell Linux */
25855 + if (link_info.s.link_up) {
25856 +
25857 + if (!netif_carrier_ok(dev))
25858 + netif_carrier_on(dev);
25859 + if (priv->queue != -1)
25860 + DEBUGPRINT
25861 + ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
25862 + dev->name, link_info.s.speed,
25863 + (link_info.s.full_duplex) ? "Full" : "Half",
25864 + priv->port, priv->queue);
25865 + else
25866 + DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
25867 + dev->name, link_info.s.speed,
25868 + (link_info.s.full_duplex) ? "Full" : "Half",
25869 + priv->port);
25870 + } else {
25871 + if (netif_carrier_ok(dev))
25872 + netif_carrier_off(dev);
25873 + DEBUGPRINT("%s: Link down\n", dev->name);
25874 + }
25875 +}
25876 +
25877 +int cvm_oct_xaui_init(struct net_device *dev)
25878 +{
25879 + struct octeon_ethernet *priv = netdev_priv(dev);
25880 + cvm_oct_common_init(dev);
25881 + dev->open = cvm_oct_xaui_open;
25882 + dev->stop = cvm_oct_xaui_stop;
25883 + dev->stop(dev);
25884 + if (!octeon_is_simulation())
25885 + priv->poll = cvm_oct_xaui_poll;
25886 +
25887 + return 0;
25888 +}
25889 +
25890 +void cvm_oct_xaui_uninit(struct net_device *dev)
25891 +{
25892 + cvm_oct_common_uninit(dev);
25893 +}
25894 --- /dev/null
25895 +++ b/drivers/staging/octeon/ethernet.c
25896 @@ -0,0 +1,507 @@
25897 +/**********************************************************************
25898 + * Author: Cavium Networks
25899 + *
25900 + * Contact: support@caviumnetworks.com
25901 + * This file is part of the OCTEON SDK
25902 + *
25903 + * Copyright (c) 2003-2007 Cavium Networks
25904 + *
25905 + * This file is free software; you can redistribute it and/or modify
25906 + * it under the terms of the GNU General Public License, Version 2, as
25907 + * published by the Free Software Foundation.
25908 + *
25909 + * This file is distributed in the hope that it will be useful, but
25910 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25911 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25912 + * NONINFRINGEMENT. See the GNU General Public License for more
25913 + * details.
25914 + *
25915 + * You should have received a copy of the GNU General Public License
25916 + * along with this file; if not, write to the Free Software
25917 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25918 + * or visit http://www.gnu.org/licenses/.
25919 + *
25920 + * This file may also be available under a different license from Cavium.
25921 + * Contact Cavium Networks for more information
25922 +**********************************************************************/
25923 +#include <linux/kernel.h>
25924 +#include <linux/init.h>
25925 +#include <linux/module.h>
25926 +#include <linux/netdevice.h>
25927 +#include <linux/etherdevice.h>
25928 +#include <linux/delay.h>
25929 +#include <linux/mii.h>
25930 +
25931 +#include <net/dst.h>
25932 +
25933 +#include <asm/octeon/octeon.h>
25934 +
25935 +#include "ethernet-defines.h"
25936 +#include "ethernet-mem.h"
25937 +#include "ethernet-rx.h"
25938 +#include "ethernet-tx.h"
25939 +#include "ethernet-util.h"
25940 +#include "ethernet-proc.h"
25941 +#include "ethernet-common.h"
25942 +#include "octeon-ethernet.h"
25943 +
25944 +#include "cvmx-pip.h"
25945 +#include "cvmx-pko.h"
25946 +#include "cvmx-fau.h"
25947 +#include "cvmx-ipd.h"
25948 +#include "cvmx-helper.h"
25949 +
25950 +#include "cvmx-smix-defs.h"
25951 +
25952 +#if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \
25953 + && CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
25954 +int num_packet_buffers = CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS;
25955 +#else
25956 +int num_packet_buffers = 1024;
25957 +#endif
25958 +module_param(num_packet_buffers, int, 0444);
25959 +MODULE_PARM_DESC(num_packet_buffers, "\n"
25960 + "\tNumber of packet buffers to allocate and store in the\n"
25961 + "\tFPA. By default, 1024 packet buffers are used unless\n"
25962 + "\tCONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS is defined.");
25963 +
25964 +int pow_receive_group = 15;
25965 +module_param(pow_receive_group, int, 0444);
25966 +MODULE_PARM_DESC(pow_receive_group, "\n"
25967 + "\tPOW group to receive packets from. All ethernet hardware\n"
25968 + "\twill be configured to send incomming packets to this POW\n"
25969 + "\tgroup. Also any other software can submit packets to this\n"
25970 + "\tgroup for the kernel to process.");
25971 +
25972 +int pow_send_group = -1;
25973 +module_param(pow_send_group, int, 0644);
25974 +MODULE_PARM_DESC(pow_send_group, "\n"
25975 + "\tPOW group to send packets to other software on. This\n"
25976 + "\tcontrols the creation of the virtual device pow0.\n"
25977 + "\talways_use_pow also depends on this value.");
25978 +
25979 +int always_use_pow;
25980 +module_param(always_use_pow, int, 0444);
25981 +MODULE_PARM_DESC(always_use_pow, "\n"
25982 + "\tWhen set, always send to the pow group. This will cause\n"
25983 + "\tpackets sent to real ethernet devices to be sent to the\n"
25984 + "\tPOW group instead of the hardware. Unless some other\n"
25985 + "\tapplication changes the config, packets will still be\n"
25986 + "\treceived from the low level hardware. Use this option\n"
25987 + "\tto allow a CVMX app to intercept all packets from the\n"
25988 + "\tlinux kernel. You must specify pow_send_group along with\n"
25989 + "\tthis option.");
25990 +
25991 +char pow_send_list[128] = "";
25992 +module_param_string(pow_send_list, pow_send_list, sizeof(pow_send_list), 0444);
25993 +MODULE_PARM_DESC(pow_send_list, "\n"
25994 + "\tComma separated list of ethernet devices that should use the\n"
25995 + "\tPOW for transmit instead of the actual ethernet hardware. This\n"
25996 + "\tis a per port version of always_use_pow. always_use_pow takes\n"
25997 + "\tprecedence over this list. For example, setting this to\n"
25998 + "\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n"
25999 + "\tusing the pow_send_group.");
26000 +
26001 +static int disable_core_queueing = 1;
26002 +module_param(disable_core_queueing, int, 0444);
26003 +MODULE_PARM_DESC(disable_core_queueing, "\n"
26004 + "\tWhen set the networking core's tx_queue_len is set to zero. This\n"
26005 + "\tallows packets to be sent without lock contention in the packet\n"
26006 + "\tscheduler resulting in some cases in improved throughput.\n");
26007 +
26008 +/**
26009 + * Periodic timer to check auto negotiation
26010 + */
26011 +static struct timer_list cvm_oct_poll_timer;
26012 +
26013 +/**
26014 + * Array of every ethernet device owned by this driver indexed by
26015 + * the ipd input port number.
26016 + */
26017 +struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
26018 +
26019 +extern struct semaphore mdio_sem;
26020 +
26021 +/**
26022 + * Periodic timer tick for slow management operations
26023 + *
26024 + * @arg: Device to check
26025 + */
26026 +static void cvm_do_timer(unsigned long arg)
26027 +{
26028 + static int port;
26029 + if (port < CVMX_PIP_NUM_INPUT_PORTS) {
26030 + if (cvm_oct_device[port]) {
26031 + int queues_per_port;
26032 + int qos;
26033 + struct octeon_ethernet *priv =
26034 + netdev_priv(cvm_oct_device[port]);
26035 + if (priv->poll) {
26036 + /* skip polling if we don't get the lock */
26037 + if (!down_trylock(&mdio_sem)) {
26038 + priv->poll(cvm_oct_device[port]);
26039 + up(&mdio_sem);
26040 + }
26041 + }
26042 +
26043 + queues_per_port = cvmx_pko_get_num_queues(port);
26044 + /* Drain any pending packets in the free list */
26045 + for (qos = 0; qos < queues_per_port; qos++) {
26046 + if (skb_queue_len(&priv->tx_free_list[qos])) {
26047 + spin_lock(&priv->tx_free_list[qos].
26048 + lock);
26049 + while (skb_queue_len
26050 + (&priv->tx_free_list[qos]) >
26051 + cvmx_fau_fetch_and_add32(priv->
26052 + fau +
26053 + qos * 4,
26054 + 0))
26055 + dev_kfree_skb(__skb_dequeue
26056 + (&priv->
26057 + tx_free_list
26058 + [qos]));
26059 + spin_unlock(&priv->tx_free_list[qos].
26060 + lock);
26061 + }
26062 + }
26063 + cvm_oct_device[port]->get_stats(cvm_oct_device[port]);
26064 + }
26065 + port++;
26066 + /* Poll the next port in a 50th of a second.
26067 + This spreads the polling of ports out a little bit */
26068 + mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50);
26069 + } else {
26070 + port = 0;
26071 + /* All ports have been polled. Start the next iteration through
26072 + the ports in one second */
26073 + mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
26074 + }
26075 +}
26076 +
26077 +/**
26078 + * Configure common hardware for all interfaces
26079 + */
26080 +static __init void cvm_oct_configure_common_hw(void)
26081 +{
26082 + int r;
26083 + /* Setup the FPA */
26084 + cvmx_fpa_enable();
26085 + cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
26086 + num_packet_buffers);
26087 + cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
26088 + num_packet_buffers);
26089 + if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
26090 + cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
26091 + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
26092 +
26093 + if (USE_RED)
26094 + cvmx_helper_setup_red(num_packet_buffers / 4,
26095 + num_packet_buffers / 8);
26096 +
26097 + /* Enable the MII interface */
26098 + if (!octeon_is_simulation())
26099 + cvmx_write_csr(CVMX_SMIX_EN(0), 1);
26100 +
26101 + /* Register an IRQ hander for to receive POW interrupts */
26102 + r = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
26103 + cvm_oct_do_interrupt, IRQF_SHARED, "Ethernet",
26104 + cvm_oct_device);
26105 +
26106 +#if defined(CONFIG_SMP) && 0
26107 + if (USE_MULTICORE_RECEIVE) {
26108 + irq_set_affinity(OCTEON_IRQ_WORKQ0 + pow_receive_group,
26109 + cpu_online_mask);
26110 + }
26111 +#endif
26112 +}
26113 +
26114 +/**
26115 + * Free a work queue entry received in a intercept callback.
26116 + *
26117 + * @work_queue_entry:
26118 + * Work queue entry to free
26119 + * Returns Zero on success, Negative on failure.
26120 + */
26121 +int cvm_oct_free_work(void *work_queue_entry)
26122 +{
26123 + cvmx_wqe_t *work = work_queue_entry;
26124 +
26125 + int segments = work->word2.s.bufs;
26126 + union cvmx_buf_ptr segment_ptr = work->packet_ptr;
26127 +
26128 + while (segments--) {
26129 + union cvmx_buf_ptr next_ptr = *(union cvmx_buf_ptr *)
26130 + cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
26131 + if (unlikely(!segment_ptr.s.i))
26132 + cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr),
26133 + segment_ptr.s.pool,
26134 + DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE /
26135 + 128));
26136 + segment_ptr = next_ptr;
26137 + }
26138 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
26139 +
26140 + return 0;
26141 +}
26142 +EXPORT_SYMBOL(cvm_oct_free_work);
26143 +
26144 +/**
26145 + * Module/ driver initialization. Creates the linux network
26146 + * devices.
26147 + *
26148 + * Returns Zero on success
26149 + */
26150 +static int __init cvm_oct_init_module(void)
26151 +{
26152 + int num_interfaces;
26153 + int interface;
26154 + int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
26155 + int qos;
26156 +
26157 + pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
26158 +
26159 + cvm_oct_proc_initialize();
26160 + cvm_oct_rx_initialize();
26161 + cvm_oct_configure_common_hw();
26162 +
26163 + cvmx_helper_initialize_packet_io_global();
26164 +
26165 + /* Change the input group for all ports before input is enabled */
26166 + num_interfaces = cvmx_helper_get_number_of_interfaces();
26167 + for (interface = 0; interface < num_interfaces; interface++) {
26168 + int num_ports = cvmx_helper_ports_on_interface(interface);
26169 + int port;
26170 +
26171 + for (port = cvmx_helper_get_ipd_port(interface, 0);
26172 + port < cvmx_helper_get_ipd_port(interface, num_ports);
26173 + port++) {
26174 + union cvmx_pip_prt_tagx pip_prt_tagx;
26175 + pip_prt_tagx.u64 =
26176 + cvmx_read_csr(CVMX_PIP_PRT_TAGX(port));
26177 + pip_prt_tagx.s.grp = pow_receive_group;
26178 + cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
26179 + pip_prt_tagx.u64);
26180 + }
26181 + }
26182 +
26183 + cvmx_helper_ipd_and_packet_input_enable();
26184 +
26185 + memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
26186 +
26187 + /*
26188 + * Initialize the FAU used for counting packet buffers that
26189 + * need to be freed.
26190 + */
26191 + cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
26192 +
26193 + if ((pow_send_group != -1)) {
26194 + struct net_device *dev;
26195 + pr_info("\tConfiguring device for POW only access\n");
26196 + dev = alloc_etherdev(sizeof(struct octeon_ethernet));
26197 + if (dev) {
26198 + /* Initialize the device private structure. */
26199 + struct octeon_ethernet *priv = netdev_priv(dev);
26200 + memset(priv, 0, sizeof(struct octeon_ethernet));
26201 +
26202 + dev->init = cvm_oct_common_init;
26203 + priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
26204 + priv->port = CVMX_PIP_NUM_INPUT_PORTS;
26205 + priv->queue = -1;
26206 + strcpy(dev->name, "pow%d");
26207 + for (qos = 0; qos < 16; qos++)
26208 + skb_queue_head_init(&priv->tx_free_list[qos]);
26209 +
26210 + if (register_netdev(dev) < 0) {
26211 + pr_err("Failed to register ethernet "
26212 + "device for POW\n");
26213 + kfree(dev);
26214 + } else {
26215 + cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
26216 + pr_info("%s: POW send group %d, receive "
26217 + "group %d\n",
26218 + dev->name, pow_send_group,
26219 + pow_receive_group);
26220 + }
26221 + } else {
26222 + pr_err("Failed to allocate ethernet device "
26223 + "for POW\n");
26224 + }
26225 + }
26226 +
26227 + num_interfaces = cvmx_helper_get_number_of_interfaces();
26228 + for (interface = 0; interface < num_interfaces; interface++) {
26229 + cvmx_helper_interface_mode_t imode =
26230 + cvmx_helper_interface_get_mode(interface);
26231 + int num_ports = cvmx_helper_ports_on_interface(interface);
26232 + int port;
26233 +
26234 + for (port = cvmx_helper_get_ipd_port(interface, 0);
26235 + port < cvmx_helper_get_ipd_port(interface, num_ports);
26236 + port++) {
26237 + struct octeon_ethernet *priv;
26238 + struct net_device *dev =
26239 + alloc_etherdev(sizeof(struct octeon_ethernet));
26240 + if (!dev) {
26241 + pr_err("Failed to allocate ethernet device "
26242 + "for port %d\n", port);
26243 + continue;
26244 + }
26245 + if (disable_core_queueing)
26246 + dev->tx_queue_len = 0;
26247 +
26248 + /* Initialize the device private structure. */
26249 + priv = netdev_priv(dev);
26250 + memset(priv, 0, sizeof(struct octeon_ethernet));
26251 +
26252 + priv->imode = imode;
26253 + priv->port = port;
26254 + priv->queue = cvmx_pko_get_base_queue(priv->port);
26255 + priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
26256 + for (qos = 0; qos < 16; qos++)
26257 + skb_queue_head_init(&priv->tx_free_list[qos]);
26258 + for (qos = 0; qos < cvmx_pko_get_num_queues(port);
26259 + qos++)
26260 + cvmx_fau_atomic_write32(priv->fau + qos * 4, 0);
26261 +
26262 + switch (priv->imode) {
26263 +
26264 + /* These types don't support ports to IPD/PKO */
26265 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
26266 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
26267 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
26268 + break;
26269 +
26270 + case CVMX_HELPER_INTERFACE_MODE_NPI:
26271 + dev->init = cvm_oct_common_init;
26272 + dev->uninit = cvm_oct_common_uninit;
26273 + strcpy(dev->name, "npi%d");
26274 + break;
26275 +
26276 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
26277 + dev->init = cvm_oct_xaui_init;
26278 + dev->uninit = cvm_oct_xaui_uninit;
26279 + strcpy(dev->name, "xaui%d");
26280 + break;
26281 +
26282 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
26283 + dev->init = cvm_oct_common_init;
26284 + dev->uninit = cvm_oct_common_uninit;
26285 + strcpy(dev->name, "loop%d");
26286 + break;
26287 +
26288 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
26289 + dev->init = cvm_oct_sgmii_init;
26290 + dev->uninit = cvm_oct_sgmii_uninit;
26291 + strcpy(dev->name, "eth%d");
26292 + break;
26293 +
26294 + case CVMX_HELPER_INTERFACE_MODE_SPI:
26295 + dev->init = cvm_oct_spi_init;
26296 + dev->uninit = cvm_oct_spi_uninit;
26297 + strcpy(dev->name, "spi%d");
26298 + break;
26299 +
26300 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
26301 + case CVMX_HELPER_INTERFACE_MODE_GMII:
26302 + dev->init = cvm_oct_rgmii_init;
26303 + dev->uninit = cvm_oct_rgmii_uninit;
26304 + strcpy(dev->name, "eth%d");
26305 + break;
26306 + }
26307 +
26308 + if (!dev->init) {
26309 + kfree(dev);
26310 + } else if (register_netdev(dev) < 0) {
26311 + pr_err("Failed to register ethernet device "
26312 + "for interface %d, port %d\n",
26313 + interface, priv->port);
26314 + kfree(dev);
26315 + } else {
26316 + cvm_oct_device[priv->port] = dev;
26317 + fau -=
26318 + cvmx_pko_get_num_queues(priv->port) *
26319 + sizeof(uint32_t);
26320 + }
26321 + }
26322 + }
26323 +
26324 + if (INTERRUPT_LIMIT) {
26325 + /*
26326 + * Set the POW timer rate to give an interrupt at most
26327 + * INTERRUPT_LIMIT times per second.
26328 + */
26329 + cvmx_write_csr(CVMX_POW_WQ_INT_PC,
26330 + octeon_bootinfo->eclock_hz / (INTERRUPT_LIMIT *
26331 + 16 * 256) << 8);
26332 +
26333 + /*
26334 + * Enable POW timer interrupt. It will count when
26335 + * there are packets available.
26336 + */
26337 + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
26338 + 0x1ful << 24);
26339 + } else {
26340 + /* Enable POW interrupt when our port has at least one packet */
26341 + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1001);
26342 + }
26343 +
26344 + /* Enable the poll timer for checking RGMII status */
26345 + init_timer(&cvm_oct_poll_timer);
26346 + cvm_oct_poll_timer.data = 0;
26347 + cvm_oct_poll_timer.function = cvm_do_timer;
26348 + mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
26349 +
26350 + return 0;
26351 +}
26352 +
26353 +/**
26354 + * Module / driver shutdown
26355 + *
26356 + * Returns Zero on success
26357 + */
26358 +static void __exit cvm_oct_cleanup_module(void)
26359 +{
26360 + int port;
26361 +
26362 + /* Disable POW interrupt */
26363 + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
26364 +
26365 + cvmx_ipd_disable();
26366 +
26367 + /* Free the interrupt handler */
26368 + free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
26369 +
26370 + del_timer(&cvm_oct_poll_timer);
26371 + cvm_oct_rx_shutdown();
26372 + cvmx_pko_disable();
26373 +
26374 + /* Free the ethernet devices */
26375 + for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
26376 + if (cvm_oct_device[port]) {
26377 + cvm_oct_tx_shutdown(cvm_oct_device[port]);
26378 + unregister_netdev(cvm_oct_device[port]);
26379 + kfree(cvm_oct_device[port]);
26380 + cvm_oct_device[port] = NULL;
26381 + }
26382 + }
26383 +
26384 + cvmx_pko_shutdown();
26385 + cvm_oct_proc_shutdown();
26386 +
26387 + cvmx_ipd_free_ptr();
26388 +
26389 + /* Free the HW pools */
26390 + cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
26391 + num_packet_buffers);
26392 + cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
26393 + num_packet_buffers);
26394 + if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
26395 + cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
26396 + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
26397 +}
26398 +
26399 +MODULE_LICENSE("GPL");
26400 +MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
26401 +MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver.");
26402 +module_init(cvm_oct_init_module);
26403 +module_exit(cvm_oct_cleanup_module);
26404 --- /dev/null
26405 +++ b/drivers/staging/octeon/octeon-ethernet.h
26406 @@ -0,0 +1,127 @@
26407 +/**********************************************************************
26408 + * Author: Cavium Networks
26409 + *
26410 + * Contact: support@caviumnetworks.com
26411 + * This file is part of the OCTEON SDK
26412 + *
26413 + * Copyright (c) 2003-2007 Cavium Networks
26414 + *
26415 + * This file is free software; you can redistribute it and/or modify
26416 + * it under the terms of the GNU General Public License, Version 2, as
26417 + * published by the Free Software Foundation.
26418 + *
26419 + * This file is distributed in the hope that it will be useful, but
26420 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
26421 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
26422 + * NONINFRINGEMENT. See the GNU General Public License for more
26423 + * details.
26424 + *
26425 + * You should have received a copy of the GNU General Public License
26426 + * along with this file; if not, write to the Free Software
26427 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26428 + * or visit http://www.gnu.org/licenses/.
26429 + *
26430 + * This file may also be available under a different license from Cavium.
26431 + * Contact Cavium Networks for more information
26432 +**********************************************************************/
26433 +
26434 +/*
26435 + * External interface for the Cavium Octeon ethernet driver.
26436 + */
26437 +#ifndef OCTEON_ETHERNET_H
26438 +#define OCTEON_ETHERNET_H
26439 +
26440 +/**
26441 + * This is the definition of the Ethernet driver's private
26442 + * driver state stored in netdev_priv(dev).
26443 + */
26444 +struct octeon_ethernet {
26445 + /* PKO hardware output port */
26446 + int port;
26447 + /* PKO hardware queue for the port */
26448 + int queue;
26449 + /* Hardware fetch and add to count outstanding tx buffers */
26450 + int fau;
26451 + /*
26452 + * Type of port. This is one of the enums in
26453 + * cvmx_helper_interface_mode_t
26454 + */
26455 + int imode;
26456 + /* List of outstanding tx buffers per queue */
26457 + struct sk_buff_head tx_free_list[16];
26458 + /* Device statistics */
26459 + struct net_device_stats stats
26460 +; /* Generic MII info structure */
26461 + struct mii_if_info mii_info;
26462 + /* Last negotiated link state */
26463 + uint64_t link_info;
26464 + /* Called periodically to check link status */
26465 + void (*poll) (struct net_device *dev);
26466 +};
26467 +
26468 +/**
26469 + * Free a work queue entry received in a intercept callback.
26470 + *
26471 + * @work_queue_entry:
26472 + * Work queue entry to free
26473 + * Returns Zero on success, Negative on failure.
26474 + */
26475 +int cvm_oct_free_work(void *work_queue_entry);
26476 +
26477 +/**
26478 + * Transmit a work queue entry out of the ethernet port. Both
26479 + * the work queue entry and the packet data can optionally be
26480 + * freed. The work will be freed on error as well.
26481 + *
26482 + * @dev: Device to transmit out.
26483 + * @work_queue_entry:
26484 + * Work queue entry to send
26485 + * @do_free: True if the work queue entry and packet data should be
26486 + * freed. If false, neither will be freed.
26487 + * @qos: Index into the queues for this port to transmit on. This
26488 + * is used to implement QoS if their are multiple queues per
26489 + * port. This parameter must be between 0 and the number of
26490 + * queues per port minus 1. Values outside of this range will
26491 + * be change to zero.
26492 + *
26493 + * Returns Zero on success, negative on failure.
26494 + */
26495 +int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
26496 + int do_free, int qos);
26497 +
26498 +/**
26499 + * Transmit a work queue entry out of the ethernet port. Both
26500 + * the work queue entry and the packet data can optionally be
26501 + * freed. The work will be freed on error as well. This simply
26502 + * wraps cvmx_oct_transmit_qos() for backwards compatability.
26503 + *
26504 + * @dev: Device to transmit out.
26505 + * @work_queue_entry:
26506 + * Work queue entry to send
26507 + * @do_free: True if the work queue entry and packet data should be
26508 + * freed. If false, neither will be freed.
26509 + *
26510 + * Returns Zero on success, negative on failure.
26511 + */
26512 +static inline int cvm_oct_transmit(struct net_device *dev,
26513 + void *work_queue_entry, int do_free)
26514 +{
26515 + return cvm_oct_transmit_qos(dev, work_queue_entry, do_free, 0);
26516 +}
26517 +
26518 +extern int cvm_oct_rgmii_init(struct net_device *dev);
26519 +extern void cvm_oct_rgmii_uninit(struct net_device *dev);
26520 +extern int cvm_oct_sgmii_init(struct net_device *dev);
26521 +extern void cvm_oct_sgmii_uninit(struct net_device *dev);
26522 +extern int cvm_oct_spi_init(struct net_device *dev);
26523 +extern void cvm_oct_spi_uninit(struct net_device *dev);
26524 +extern int cvm_oct_xaui_init(struct net_device *dev);
26525 +extern void cvm_oct_xaui_uninit(struct net_device *dev);
26526 +
26527 +extern int always_use_pow;
26528 +extern int pow_send_group;
26529 +extern int pow_receive_group;
26530 +extern char pow_send_list[];
26531 +extern struct net_device *cvm_oct_device[];
26532 +
26533 +#endif