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.
5 The driver files can be categorized into three basic groups:
7 1) Register definitions, these are named cvmx-*-defs.h
9 2) Main driver code, these have names that don't start cvmx-.
11 3) Interface specific functions and other utility code, names starting
14 Signed-off-by: David Daney <ddaney@caviumnetworks.com>
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
167 +++ b/drivers/staging/octeon/Kconfig
169 +config OCTEON_ETHERNET
170 + tristate "Cavium Networks Octeon Ethernet support"
171 + depends on CPU_CAVIUM_OCTEON
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.
178 + To compile this driver as a module, choose M here. The module
179 + will be called octeon-ethernet.
182 +++ b/drivers/staging/octeon/Makefile
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
188 +# Copyright (C) 2005-2009 Cavium Networks
192 +# Makefile for Cavium OCTEON on-board ethernet driver
195 +obj-${CONFIG_OCTEON_ETHERNET} := octeon-ethernet.o
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
215 +++ b/drivers/staging/octeon/cvmx-address.h
217 +/***********************license start***************
218 + * Author: Cavium Networks
220 + * Contact: support@caviumnetworks.com
221 + * This file is part of the OCTEON SDK
223 + * Copyright (c) 2003-2009 Cavium Networks
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.
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
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/.
240 + * This file may also be available under a different license from Cavium.
241 + * Contact Cavium Networks for more information
242 + ***********************license end**************************************/
245 + * Typedefs and defines for working with Octeon physical addresses.
248 +#ifndef __CVMX_ADDRESS_H__
249 +#define __CVMX_ADDRESS_H__
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;
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;
267 +/* decodes <14:13> of a kseg3 window address */
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;
276 +/* decode within DMA space */
279 + * Add store data to the write buffer entry, allocating it if
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;
298 + * Physical Address Decode
300 + * Octeon-I HW never interprets this X (<39:36> reserved
301 + * for future expansion), software should set to 0.
303 + * - 0x0 XXX0 0000 0000 to DRAM Cached
304 + * - 0x0 XXX0 0FFF FFFF
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)
309 + * - 0x0 XXX0 2000 0000 to DRAM Cached
310 + * - 0x0 XXXF FFFF FFFF
312 + * - 0x1 00X0 0000 0000 to Boot Bus Uncached
313 + * - 0x1 00XF FFFF FFFF
315 + * - 0x1 01X0 0000 0000 to Other NCB Uncached
316 + * - 0x1 FFXF FFFF FFFF devices
318 + * Decode of all Octeon addresses
323 + /* mapped or unmapped virtual address */
326 + uint64_t offset:62;
329 + /* mapped USEG virtual addresses (typically) */
331 + uint64_t zeroes:33;
332 + uint64_t offset:31;
335 + /* mapped or unmapped virtual address */
339 + uint64_t offset:29;
343 + * physical address accessed through xkphys unmapped virtual
347 + uint64_t R:2; /* CVMX_MIPS_SPACE_XKPHYS in this case */
348 + uint64_t cca:3; /* ignored by octeon */
350 + uint64_t pa:49; /* physical address */
353 + /* physical address */
356 + /* if set, the address is uncached and resides on MCB bus */
359 + * the hardware ignores this field when is_io==0, else
363 + /* the hardware ignores <39:36> in Octeon I */
365 + uint64_t offset:36;
368 + /* physical mem address */
370 + /* techically, <47:40> are dont-cares */
371 + uint64_t zeroes:24;
372 + /* the hardware ignores <39:36> in Octeon I */
374 + uint64_t offset:36;
377 + /* physical IO address */
379 + uint64_t mem_region:2;
381 + /* 1 in this case */
384 + * The hardware ignores this field when is_io==0, else
388 + /* the hardware ignores <39:36> in Octeon I */
390 + uint64_t offset:36;
394 + * Scratchpad virtual address - accessed through a window at
399 + /* CVMX_ADD_WIN_SCR (0) in this case */
400 + cvmx_add_win_dec_t csrdec:2;
404 + /* there should only be stores to IOBDMA space, no loads */
406 + * IOBDMA virtual address - accessed through a window at the
411 + uint64_t csrdec:2; /* CVMX_ADD_WIN_DMA (1) in this case */
412 + uint64_t unused2:3;
418 + uint64_t didspace:24;
419 + uint64_t unused:40;
424 +/* These macros for used by 32 bit applications */
426 +#define CVMX_MIPS32_SPACE_KSEG0 1l
427 +#define CVMX_ADD_SEG32(segment, add) \
428 + (((int32_t)segment << 31) | (int32_t)(add))
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.
437 +#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
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))
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))
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
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)
490 +#endif /* __CVMX_ADDRESS_H__ */
492 +++ b/drivers/staging/octeon/cvmx-asxx-defs.h
494 +/***********************license start***************
495 + * Author: Cavium Networks
497 + * Contact: support@caviumnetworks.com
498 + * This file is part of the OCTEON SDK
500 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
517 + * This file may also be available under a different license from Cavium.
518 + * Contact Cavium Networks for more information
519 + ***********************license end**************************************/
521 +#ifndef __CVMX_ASXX_DEFS_H__
522 +#define __CVMX_ASXX_DEFS_H__
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))
577 +union cvmx_asxx_gmii_rx_clk_set {
579 + struct cvmx_asxx_gmii_rx_clk_set_s {
580 + uint64_t reserved_5_63:59;
581 + uint64_t setting:5;
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;
588 +union cvmx_asxx_gmii_rx_dat_set {
590 + struct cvmx_asxx_gmii_rx_dat_set_s {
591 + uint64_t reserved_5_63:59;
592 + uint64_t setting:5;
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;
599 +union cvmx_asxx_int_en {
601 + struct cvmx_asxx_int_en_s {
602 + uint64_t reserved_12_63:52;
607 + struct cvmx_asxx_int_en_cn30xx {
608 + uint64_t reserved_11_63:53;
610 + uint64_t reserved_7_7:1;
612 + uint64_t reserved_3_3:1;
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;
623 +union cvmx_asxx_int_reg {
625 + struct cvmx_asxx_int_reg_s {
626 + uint64_t reserved_12_63:52;
631 + struct cvmx_asxx_int_reg_cn30xx {
632 + uint64_t reserved_11_63:53;
634 + uint64_t reserved_7_7:1;
636 + uint64_t reserved_3_3:1;
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;
647 +union cvmx_asxx_mii_rx_dat_set {
649 + struct cvmx_asxx_mii_rx_dat_set_s {
650 + uint64_t reserved_5_63:59;
651 + uint64_t setting:5;
653 + struct cvmx_asxx_mii_rx_dat_set_s cn30xx;
654 + struct cvmx_asxx_mii_rx_dat_set_s cn50xx;
657 +union cvmx_asxx_prt_loop {
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;
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;
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;
678 +union cvmx_asxx_rld_bypass {
680 + struct cvmx_asxx_rld_bypass_s {
681 + uint64_t reserved_1_63:63;
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;
690 +union cvmx_asxx_rld_bypass_setting {
692 + struct cvmx_asxx_rld_bypass_setting_s {
693 + uint64_t reserved_5_63:59;
694 + uint64_t setting:5;
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;
702 +union cvmx_asxx_rld_comp {
704 + struct cvmx_asxx_rld_comp_s {
705 + uint64_t reserved_9_63:55;
709 + struct cvmx_asxx_rld_comp_cn38xx {
710 + uint64_t reserved_8_63:56;
714 + struct cvmx_asxx_rld_comp_cn38xx cn38xxp2;
715 + struct cvmx_asxx_rld_comp_s cn58xx;
716 + struct cvmx_asxx_rld_comp_s cn58xxp1;
719 +union cvmx_asxx_rld_data_drv {
721 + struct cvmx_asxx_rld_data_drv_s {
722 + uint64_t reserved_8_63:56;
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;
732 +union cvmx_asxx_rld_fcram_mode {
734 + struct cvmx_asxx_rld_fcram_mode_s {
735 + uint64_t reserved_1_63:63;
738 + struct cvmx_asxx_rld_fcram_mode_s cn38xx;
739 + struct cvmx_asxx_rld_fcram_mode_s cn38xxp2;
742 +union cvmx_asxx_rld_nctl_strong {
744 + struct cvmx_asxx_rld_nctl_strong_s {
745 + uint64_t reserved_5_63:59;
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;
754 +union cvmx_asxx_rld_nctl_weak {
756 + struct cvmx_asxx_rld_nctl_weak_s {
757 + uint64_t reserved_5_63:59;
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;
766 +union cvmx_asxx_rld_pctl_strong {
768 + struct cvmx_asxx_rld_pctl_strong_s {
769 + uint64_t reserved_5_63:59;
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;
778 +union cvmx_asxx_rld_pctl_weak {
780 + struct cvmx_asxx_rld_pctl_weak_s {
781 + uint64_t reserved_5_63:59;
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;
790 +union cvmx_asxx_rld_setting {
792 + struct cvmx_asxx_rld_setting_s {
793 + uint64_t reserved_13_63:51;
796 + uint64_t dfalead:1;
797 + uint64_t dfalock:1;
798 + uint64_t setting:5;
800 + struct cvmx_asxx_rld_setting_cn38xx {
801 + uint64_t reserved_5_63:59;
802 + uint64_t setting:5;
804 + struct cvmx_asxx_rld_setting_cn38xx cn38xxp2;
805 + struct cvmx_asxx_rld_setting_s cn58xx;
806 + struct cvmx_asxx_rld_setting_s cn58xxp1;
809 +union cvmx_asxx_rx_clk_setx {
811 + struct cvmx_asxx_rx_clk_setx_s {
812 + uint64_t reserved_5_63:59;
813 + uint64_t setting:5;
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;
824 +union cvmx_asxx_rx_prt_en {
826 + struct cvmx_asxx_rx_prt_en_s {
827 + uint64_t reserved_4_63:60;
830 + struct cvmx_asxx_rx_prt_en_cn30xx {
831 + uint64_t reserved_3_63:61;
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;
842 +union cvmx_asxx_rx_wol {
844 + struct cvmx_asxx_rx_wol_s {
845 + uint64_t reserved_2_63:62;
849 + struct cvmx_asxx_rx_wol_s cn38xx;
850 + struct cvmx_asxx_rx_wol_s cn38xxp2;
853 +union cvmx_asxx_rx_wol_msk {
855 + struct cvmx_asxx_rx_wol_msk_s {
858 + struct cvmx_asxx_rx_wol_msk_s cn38xx;
859 + struct cvmx_asxx_rx_wol_msk_s cn38xxp2;
862 +union cvmx_asxx_rx_wol_powok {
864 + struct cvmx_asxx_rx_wol_powok_s {
865 + uint64_t reserved_1_63:63;
866 + uint64_t powerok:1;
868 + struct cvmx_asxx_rx_wol_powok_s cn38xx;
869 + struct cvmx_asxx_rx_wol_powok_s cn38xxp2;
872 +union cvmx_asxx_rx_wol_sig {
874 + struct cvmx_asxx_rx_wol_sig_s {
875 + uint64_t reserved_32_63:32;
878 + struct cvmx_asxx_rx_wol_sig_s cn38xx;
879 + struct cvmx_asxx_rx_wol_sig_s cn38xxp2;
882 +union cvmx_asxx_tx_clk_setx {
884 + struct cvmx_asxx_tx_clk_setx_s {
885 + uint64_t reserved_5_63:59;
886 + uint64_t setting:5;
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;
897 +union cvmx_asxx_tx_comp_byp {
899 + struct cvmx_asxx_tx_comp_byp_s {
900 + uint64_t reserved_0_63:64;
902 + struct cvmx_asxx_tx_comp_byp_cn30xx {
903 + uint64_t reserved_9_63:55;
908 + struct cvmx_asxx_tx_comp_byp_cn30xx cn31xx;
909 + struct cvmx_asxx_tx_comp_byp_cn38xx {
910 + uint64_t reserved_8_63:56;
914 + struct cvmx_asxx_tx_comp_byp_cn38xx cn38xxp2;
915 + struct cvmx_asxx_tx_comp_byp_cn50xx {
916 + uint64_t reserved_17_63:47;
918 + uint64_t reserved_13_15:3;
920 + uint64_t reserved_5_7:3;
923 + struct cvmx_asxx_tx_comp_byp_cn58xx {
924 + uint64_t reserved_13_63:51;
926 + uint64_t reserved_5_7:3;
929 + struct cvmx_asxx_tx_comp_byp_cn58xx cn58xxp1;
932 +union cvmx_asxx_tx_hi_waterx {
934 + struct cvmx_asxx_tx_hi_waterx_s {
935 + uint64_t reserved_4_63:60;
938 + struct cvmx_asxx_tx_hi_waterx_cn30xx {
939 + uint64_t reserved_3_63:61;
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;
950 +union cvmx_asxx_tx_prt_en {
952 + struct cvmx_asxx_tx_prt_en_s {
953 + uint64_t reserved_4_63:60;
956 + struct cvmx_asxx_tx_prt_en_cn30xx {
957 + uint64_t reserved_3_63:61;
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;
970 +++ b/drivers/staging/octeon/cvmx-cmd-queue.c
972 +/***********************license start***************
973 + * Author: Cavium Networks
975 + * Contact: support@caviumnetworks.com
976 + * This file is part of the OCTEON SDK
978 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
995 + * This file may also be available under a different license from Cavium.
996 + * Contact Cavium Networks for more information
997 + ***********************license end**************************************/
1000 + * Support functions for managing command queues used for
1001 + * various hardware blocks.
1004 +#include <linux/kernel.h>
1006 +#include <asm/octeon/octeon.h>
1008 +#include "cvmx-config.h"
1009 +#include "cvmx-fpa.h"
1010 +#include "cvmx-cmd-queue.h"
1012 +#include <asm/octeon/cvmx-npei-defs.h>
1013 +#include <asm/octeon/cvmx-pexp-defs.h>
1014 +#include "cvmx-pko-defs.h"
1017 + * This application uses this pointer to access the global queue
1018 + * state. It points to a bootmem named block.
1020 +__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr;
1023 + * Initialize the Global queue state pointer.
1025 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1027 +static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void)
1029 + char *alloc_name = "cvmx_cmd_queues";
1030 +#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
1031 + extern uint64_t octeon_reserve32_memory;
1034 + if (likely(__cvmx_cmd_queue_state_ptr))
1035 + return CVMX_CMD_QUEUE_SUCCESS;
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);
1047 + __cvmx_cmd_queue_state_ptr =
1048 + cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr),
1051 + if (__cvmx_cmd_queue_state_ptr)
1052 + memset(__cvmx_cmd_queue_state_ptr, 0,
1053 + sizeof(*__cvmx_cmd_queue_state_ptr));
1055 + struct cvmx_bootmem_named_block_desc *block_desc =
1056 + cvmx_bootmem_find_named_block(alloc_name);
1058 + __cvmx_cmd_queue_state_ptr =
1059 + cvmx_phys_to_ptr(block_desc->base_addr);
1062 + ("ERROR: cvmx_cmd_queue_initialize: Unable to get named block %s.\n",
1064 + return CVMX_CMD_QUEUE_NO_MEMORY;
1067 + return CVMX_CMD_QUEUE_SUCCESS;
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.
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)
1080 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1082 +cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
1083 + int max_depth, int fpa_pool,
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)
1091 + qstate = __cvmx_cmd_queue_get_state(queue_id);
1092 + if (qstate == NULL)
1093 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1096 + * We artificially limit max_depth to 1<<20 words. It is an
1097 + * arbitrary limit.
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;
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;
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;
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;
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;
1134 + return CVMX_CMD_QUEUE_ALREADY_SETUP;
1136 + union cvmx_fpa_ctl_status status;
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;
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;
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;
1158 + * We zeroed the now serving field so we need to also
1159 + * zero the ticket.
1161 + __cvmx_cmd_queue_state_ptr->
1162 + ticket[__cvmx_cmd_queue_get_index(queue_id)] = 0;
1164 + return CVMX_CMD_QUEUE_SUCCESS;
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.
1173 + * @queue_id: Queue to shutdown
1175 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1177 +cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id)
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;
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;
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;
1199 + __cvmx_cmd_queue_unlock(qptr);
1201 + return CVMX_CMD_QUEUE_SUCCESS;
1205 + * Return the number of command words pending in the queue. This
1206 + * function may be relatively slow for some hardware units.
1208 + * @queue_id: Hardware command queue to query
1210 + * Returns Number of outstanding commands
1212 +int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id)
1214 + if (CVMX_ENABLE_PARAMETER_CHECKING) {
1215 + if (__cvmx_cmd_queue_get_state(queue_id) == NULL)
1216 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1220 + * The cast is here so gcc with check that all values in the
1221 + * cvmx_cmd_queue_id_t enumeration are here.
1223 + switch ((cvmx_cmd_queue_id_t) (queue_id & 0xff0000)) {
1224 + case CVMX_CMD_QUEUE_PKO_BASE:
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.
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;
1237 + union cvmx_pko_mem_debug8 debug8;
1238 + debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
1239 + return debug8.cn58xx.doorbell;
1241 + case CVMX_CMD_QUEUE_ZIP:
1242 + case CVMX_CMD_QUEUE_DFA:
1243 + case CVMX_CMD_QUEUE_RAID:
1244 + /* FIXME: Implement other lengths */
1246 + case CVMX_CMD_QUEUE_DMA_BASE:
1248 + union cvmx_npei_dmax_counts dmax_counts;
1250 + cvmx_read_csr(CVMX_PEXP_NPEI_DMAX_COUNTS
1251 + (queue_id & 0x7));
1252 + return dmax_counts.s.dbell;
1254 + case CVMX_CMD_QUEUE_END:
1255 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1257 + return CVMX_CMD_QUEUE_INVALID_PARAM;
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.
1266 + * @queue_id: Command queue to query
1268 + * Returns Command buffer or NULL on failure
1270 +void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id)
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);
1279 +++ b/drivers/staging/octeon/cvmx-cmd-queue.h
1281 +/***********************license start***************
1282 + * Author: Cavium Networks
1284 + * Contact: support@caviumnetworks.com
1285 + * This file is part of the OCTEON SDK
1287 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
1304 + * This file may also be available under a different license from Cavium.
1305 + * Contact Cavium Networks for more information
1306 + ***********************license end**************************************/
1310 + * Support functions for managing command queues used for
1311 + * various hardware blocks.
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
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.
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
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
1354 +#ifndef __CVMX_CMD_QUEUE_H__
1355 +#define __CVMX_CMD_QUEUE_H__
1357 +#include <linux/prefetch.h>
1359 +#include "cvmx-fpa.h"
1361 + * By default we disable the max depth support. Most programs
1362 + * don't use it and it slows down the command queue processing
1365 +#ifndef CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH
1366 +#define CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH 0
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
1376 + CVMX_CMD_QUEUE_PKO_BASE = 0x00000,
1378 +#define CVMX_CMD_QUEUE_PKO(queue) \
1379 + ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_PKO_BASE + (0xffff&(queue))))
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,
1386 +#define CVMX_CMD_QUEUE_DMA(queue) \
1387 + ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_DMA_BASE + (0xffff&(queue))))
1389 + CVMX_CMD_QUEUE_END = 0x50000,
1390 +} cvmx_cmd_queue_id_t;
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.
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;
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;
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.
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;
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.
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)
1446 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1448 +cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
1449 + int max_depth, int fpa_pool,
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.
1457 + * @queue_id: Queue to shutdown
1459 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1461 +cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id);
1464 + * Return the number of command words pending in the queue. This
1465 + * function may be relatively slow for some hardware units.
1467 + * @queue_id: Hardware command queue to query
1469 + * Returns Number of outstanding commands
1471 +int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id);
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.
1479 + * @queue_id: Command queue to query
1481 + * Returns Command buffer or NULL on failure
1483 +void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id);
1486 + * Get the index into the state arrays for the supplied queue id.
1488 + * @queue_id: Queue ID to get an index for
1490 + * Returns Index into the state arrays
1492 +static inline int __cvmx_cmd_queue_get_index(cvmx_cmd_queue_id_t queue_id)
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.
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;
1508 + * Lock the supplied queue so nobody else is updating it at the same
1511 + * @queue_id: Queue ID to lock
1512 + * @qptr: Pointer to the queue's global state
1514 +static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id,
1515 + __cvmx_cmd_queue_state_t *qptr)
1517 + extern __cvmx_cmd_queue_all_state_t
1518 + *__cvmx_cmd_queue_state_ptr;
1524 + ".set noreorder\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"
1535 + /* Load the current now_serving ticket */
1536 + "lbu %[ticket], %[now_serving]\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"
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 */
1552 + /* Load the current now_serving ticket */
1553 + " lbu %[ticket], %[now_serving]\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)
1563 + * Unlock the queue, flushing all writes.
1565 + * @qptr: Queue to unlock
1567 +static inline void __cvmx_cmd_queue_unlock(__cvmx_cmd_queue_state_t *qptr)
1569 + qptr->now_serving++;
1574 + * Get the queue state structure for the given queue id
1576 + * @queue_id: Queue id to get
1578 + * Returns Queue structure or NULL on failure
1580 +static inline __cvmx_cmd_queue_state_t
1581 + *__cvmx_cmd_queue_get_state(cvmx_cmd_queue_id_t queue_id)
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)];
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.
1594 + * @queue_id: Hardware command queue to write to
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
1602 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1604 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write(cvmx_cmd_queue_id_t
1610 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1612 + /* Make sure nobody else is updating the same queue */
1613 + if (likely(use_locking))
1614 + __cvmx_cmd_queue_lock(queue_id, qptr);
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.
1621 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
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;
1631 + * Normally there is plenty of room in the current buffer for
1634 + if (likely(qptr->index + cmd_count < qptr->pool_size_m1)) {
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--)
1646 + * We need a new comamnd buffer. Fail if there isn't
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;
1657 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1658 + base_ptr_div128 << 7);
1660 + * Figure out how many command words will fit in this
1661 + * buffer. One location will be needed for the next
1664 + count = qptr->pool_size_m1 - qptr->index;
1665 + ptr += qptr->index;
1666 + cmd_count -= count;
1669 + *ptr = cvmx_ptr_to_phys(new_buffer);
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.
1675 + qptr->base_ptr_div128 = *ptr >> 7;
1676 + qptr->index = cmd_count;
1678 + while (cmd_count--)
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;
1689 + * Simple function to write two command words to a command
1692 + * @queue_id: Hardware command queue to write to
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.
1700 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1702 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write2(cvmx_cmd_queue_id_t
1708 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1710 + /* Make sure nobody else is updating the same queue */
1711 + if (likely(use_locking))
1712 + __cvmx_cmd_queue_lock(queue_id, qptr);
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.
1719 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
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;
1729 + * Normally there is plenty of room in the current buffer for
1732 + if (likely(qptr->index + 2 < qptr->pool_size_m1)) {
1734 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1735 + base_ptr_div128 << 7);
1736 + ptr += qptr->index;
1743 + * Figure out how many command words will fit in this
1744 + * buffer. One location will be needed for the next
1747 + int count = qptr->pool_size_m1 - qptr->index;
1749 + * We need a new comamnd buffer. Fail if there isn't
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;
1761 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1762 + base_ptr_div128 << 7);
1763 + ptr += qptr->index;
1765 + if (likely(count))
1767 + *ptr = cvmx_ptr_to_phys(new_buffer);
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.
1773 + qptr->base_ptr_div128 = *ptr >> 7;
1775 + if (unlikely(count == 0)) {
1777 + new_buffer[0] = cmd2;
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;
1788 + * Simple function to write three command words to a command
1791 + * @queue_id: Hardware command queue to write to
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.
1800 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1802 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write3(cvmx_cmd_queue_id_t
1809 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1811 + /* Make sure nobody else is updating the same queue */
1812 + if (likely(use_locking))
1813 + __cvmx_cmd_queue_lock(queue_id, qptr);
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.
1820 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
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;
1830 + * Normally there is plenty of room in the current buffer for
1833 + if (likely(qptr->index + 3 < qptr->pool_size_m1)) {
1835 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1836 + base_ptr_div128 << 7);
1837 + ptr += qptr->index;
1845 + * Figure out how many command words will fit in this
1846 + * buffer. One location will be needed for the next
1849 + int count = qptr->pool_size_m1 - qptr->index;
1851 + * We need a new comamnd buffer. Fail if there isn't
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;
1863 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1864 + base_ptr_div128 << 7);
1865 + ptr += qptr->index;
1872 + *ptr = cvmx_ptr_to_phys(new_buffer);
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.
1878 + qptr->base_ptr_div128 = *ptr >> 7;
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;
1897 +#endif /* __CVMX_CMD_QUEUE_H__ */
1899 +++ b/drivers/staging/octeon/cvmx-config.h
1901 +#ifndef __CVMX_CONFIG_H__
1902 +#define __CVMX_CONFIG_H__
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
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)
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
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
1954 +#define CVMX_FAU_REG_64_ADDR(x) ((x << 3) + CVMX_FAU_REG_64_START)
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;
1960 +#define CVMX_FAU_REG_32_ADDR(x) ((x << 2) + CVMX_FAU_REG_32_START)
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;
1966 +#define CVMX_FAU_REG_16_ADDR(x) ((x << 1) + CVMX_FAU_REG_16_START)
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;
1972 +#define CVMX_FAU_REG_8_ADDR(x) ((x) + CVMX_FAU_REG_8_START)
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;
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.
1983 +#define CVMX_FAU_REG_AVAIL_BASE ((CVMX_FAU_REG_8_END + 0x7) & (~0x7ULL))
1984 +#define CVMX_FAU_REG_END (2048)
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.
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)
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
2003 +#define CVMX_HELPER_FIRST_MBUFF_SKIP 184
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
2010 +#define CVMX_HELPER_NOT_FIRST_MBUFF_SKIP 0
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.
2022 +#define CVMX_HELPER_ENABLE_BACK_PRESSURE 1
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.
2031 +#define CVMX_HELPER_ENABLE_IPD 0
2034 + * CVMX_HELPER_INPUT_TAG_TYPE selects the type of tag that the IPD assigns
2035 + * to incoming packets.
2037 +#define CVMX_HELPER_INPUT_TAG_TYPE CVMX_POW_TAG_TYPE_ORDERED
2039 +#define CVMX_ENABLE_PARAMETER_CHECKING 0
2042 + * The following select which fields are used by the PIP to generate
2043 + * the tag on INPUT
2044 + * 0: don't include
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
2059 +/* Select skip mode for input ports */
2060 +#define CVMX_HELPER_INPUT_PORT_SKIP_MODE CVMX_PIP_PORT_CFG_MODE_SKIPL2
2063 + * Force backpressure to be disabled. This overrides all other
2064 + * backpressure configuration.
2066 +#define CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 0
2068 +#endif /* __CVMX_CONFIG_H__ */
2071 +++ b/drivers/staging/octeon/cvmx-dbg-defs.h
2073 +/***********************license start***************
2074 + * Author: Cavium Networks
2076 + * Contact: support@caviumnetworks.com
2077 + * This file is part of the OCTEON SDK
2079 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
2096 + * This file may also be available under a different license from Cavium.
2097 + * Contact Cavium Networks for more information
2098 + ***********************license end**************************************/
2100 +#ifndef __CVMX_DBG_DEFS_H__
2101 +#define __CVMX_DBG_DEFS_H__
2103 +#define CVMX_DBG_DATA \
2104 + CVMX_ADD_IO_SEG(0x00011F00000001E8ull)
2106 +union cvmx_dbg_data {
2108 + struct cvmx_dbg_data_s {
2109 + uint64_t reserved_23_63:41;
2111 + uint64_t dsel_ext:1;
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;
2119 + uint64_t dsel_ext:1;
2122 + struct cvmx_dbg_data_cn30xx cn31xx;
2123 + struct cvmx_dbg_data_cn38xx {
2124 + uint64_t reserved_29_63:35;
2126 + uint64_t dclk_mul2:1;
2127 + uint64_t cclk_div2:1;
2129 + uint64_t dsel_ext:1;
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;
2138 + uint64_t dsel_ext:1;
2141 + struct cvmx_dbg_data_cn58xx cn58xxp1;
2146 +++ b/drivers/staging/octeon/cvmx-fau.h
2148 +/***********************license start***************
2149 + * Author: Cavium Networks
2151 + * Contact: support@caviumnetworks.com
2152 + * This file is part of the OCTEON SDK
2154 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
2171 + * This file may also be available under a different license from Cavium.
2172 + * Contact Cavium Networks for more information
2173 + ***********************license end**************************************/
2176 + * Interface to the hardware Fetch and Add Unit.
2179 +#ifndef __CVMX_FAU_H__
2180 +#define __CVMX_FAU_H__
2183 + * Octeon Fetch and Add Unit (FAU)
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
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;
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.
2210 +} cvmx_fau_tagwait64_t;
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.
2220 +} cvmx_fau_tagwait32_t;
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.
2230 +} cvmx_fau_tagwait16_t;
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.
2240 +} cvmx_fau_tagwait8_t;
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.
2250 + uint64_t invalid:1;
2251 + uint64_t data:63; /* unpredictable if invalid is set */
2253 +} cvmx_fau_async_tagwait_result_t;
2256 + * Builds a store I/O address for writing to the FAU
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
2266 +static inline uint64_t __cvmx_fau_store_address(uint64_t noadd, uint64_t reg)
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);
2274 + * Builds a I/O address for accessing the FAU
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
2289 +static inline uint64_t __cvmx_fau_atomic_address(uint64_t tagwait, uint64_t reg,
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);
2299 + * Perform an atomic 64 bit add
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
2307 +static inline int64_t cvmx_fau_fetch_and_add64(cvmx_fau_reg_64_t reg,
2310 + return cvmx_read64_int64(__cvmx_fau_atomic_address(0, reg, value));
2314 + * Perform an atomic 32 bit add
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
2322 +static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg_32_t reg,
2325 + return cvmx_read64_int32(__cvmx_fau_atomic_address(0, reg, value));
2329 + * Perform an atomic 16 bit add
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
2336 +static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg_16_t reg,
2339 + return cvmx_read64_int16(__cvmx_fau_atomic_address(0, reg, value));
2343 + * Perform an atomic 8 bit add
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
2349 +static inline int8_t cvmx_fau_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
2351 + return cvmx_read64_int8(__cvmx_fau_atomic_address(0, reg, value));
2355 + * Perform an atomic 64 bit add after the current tag switch
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
2366 +static inline cvmx_fau_tagwait64_t
2367 +cvmx_fau_tagwait_fetch_and_add64(cvmx_fau_reg_64_t reg, int64_t value)
2371 + cvmx_fau_tagwait64_t t;
2374 + cvmx_read64_int64(__cvmx_fau_atomic_address(1, reg, value));
2379 + * Perform an atomic 32 bit add after the current tag switch
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
2390 +static inline cvmx_fau_tagwait32_t
2391 +cvmx_fau_tagwait_fetch_and_add32(cvmx_fau_reg_32_t reg, int32_t value)
2395 + cvmx_fau_tagwait32_t t;
2398 + cvmx_read64_int32(__cvmx_fau_atomic_address(1, reg, value));
2403 + * Perform an atomic 16 bit add after the current tag switch
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
2413 +static inline cvmx_fau_tagwait16_t
2414 +cvmx_fau_tagwait_fetch_and_add16(cvmx_fau_reg_16_t reg, int16_t value)
2418 + cvmx_fau_tagwait16_t t;
2421 + cvmx_read64_int16(__cvmx_fau_atomic_address(1, reg, value));
2426 + * Perform an atomic 8 bit add after the current tag switch
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
2435 +static inline cvmx_fau_tagwait8_t
2436 +cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
2440 + cvmx_fau_tagwait8_t t;
2442 + result.i8 = cvmx_read64_int8(__cvmx_fau_atomic_address(1, reg, value));
2447 + * Builds I/O data for async operations
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
2468 +static inline uint64_t __cvmx_fau_iobdma_data(uint64_t scraddr, int64_t value,
2470 + cvmx_fau_op_size_t size,
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);
2483 + * Perform an async atomic 64 bit add. The old value is
2484 + * placed in the scratch memory at byte address scraddr.
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
2494 +static inline void cvmx_fau_async_fetch_and_add64(uint64_t scraddr,
2495 + cvmx_fau_reg_64_t reg,
2498 + cvmx_send_single(__cvmx_fau_iobdma_data
2499 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_64, reg));
2503 + * Perform an async atomic 32 bit add. The old value is
2504 + * placed in the scratch memory at byte address scraddr.
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
2514 +static inline void cvmx_fau_async_fetch_and_add32(uint64_t scraddr,
2515 + cvmx_fau_reg_32_t reg,
2518 + cvmx_send_single(__cvmx_fau_iobdma_data
2519 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_32, reg));
2523 + * Perform an async atomic 16 bit add. The old value is
2524 + * placed in the scratch memory at byte address scraddr.
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
2533 +static inline void cvmx_fau_async_fetch_and_add16(uint64_t scraddr,
2534 + cvmx_fau_reg_16_t reg,
2537 + cvmx_send_single(__cvmx_fau_iobdma_data
2538 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_16, reg));
2542 + * Perform an async atomic 8 bit add. The old value is
2543 + * placed in the scratch memory at byte address scraddr.
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
2551 +static inline void cvmx_fau_async_fetch_and_add8(uint64_t scraddr,
2552 + cvmx_fau_reg_8_t reg,
2555 + cvmx_send_single(__cvmx_fau_iobdma_data
2556 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_8, reg));
2560 + * Perform an async atomic 64 bit add after the current tag
2561 + * switch completes.
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
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
2574 +static inline void cvmx_fau_async_tagwait_fetch_and_add64(uint64_t scraddr,
2575 + cvmx_fau_reg_64_t reg,
2578 + cvmx_send_single(__cvmx_fau_iobdma_data
2579 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_64, reg));
2583 + * Perform an async atomic 32 bit add after the current tag
2584 + * switch completes.
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
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
2597 +static inline void cvmx_fau_async_tagwait_fetch_and_add32(uint64_t scraddr,
2598 + cvmx_fau_reg_32_t reg,
2601 + cvmx_send_single(__cvmx_fau_iobdma_data
2602 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_32, reg));
2606 + * Perform an async atomic 16 bit add after the current tag
2607 + * switch completes.
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
2614 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2615 + * - Step by 2 for 16 bit access.
2616 + * @value: Signed value to add.
2618 + * Returns Placed in the scratch pad register
2620 +static inline void cvmx_fau_async_tagwait_fetch_and_add16(uint64_t scraddr,
2621 + cvmx_fau_reg_16_t reg,
2624 + cvmx_send_single(__cvmx_fau_iobdma_data
2625 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_16, reg));
2629 + * Perform an async atomic 8 bit add after the current tag
2630 + * switch completes.
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
2637 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2638 + * @value: Signed value to add.
2640 + * Returns Placed in the scratch pad register
2642 +static inline void cvmx_fau_async_tagwait_fetch_and_add8(uint64_t scraddr,
2643 + cvmx_fau_reg_8_t reg,
2646 + cvmx_send_single(__cvmx_fau_iobdma_data
2647 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_8, reg));
2651 + * Perform an atomic 64 bit add
2653 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2654 + * - Step by 8 for 64 bit access.
2655 + * @value: Signed value to add.
2657 +static inline void cvmx_fau_atomic_add64(cvmx_fau_reg_64_t reg, int64_t value)
2659 + cvmx_write64_int64(__cvmx_fau_store_address(0, reg), value);
2663 + * Perform an atomic 32 bit add
2665 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2666 + * - Step by 4 for 32 bit access.
2667 + * @value: Signed value to add.
2669 +static inline void cvmx_fau_atomic_add32(cvmx_fau_reg_32_t reg, int32_t value)
2671 + cvmx_write64_int32(__cvmx_fau_store_address(0, reg), value);
2675 + * Perform an atomic 16 bit add
2677 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2678 + * - Step by 2 for 16 bit access.
2679 + * @value: Signed value to add.
2681 +static inline void cvmx_fau_atomic_add16(cvmx_fau_reg_16_t reg, int16_t value)
2683 + cvmx_write64_int16(__cvmx_fau_store_address(0, reg), value);
2687 + * Perform an atomic 8 bit add
2689 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2690 + * @value: Signed value to add.
2692 +static inline void cvmx_fau_atomic_add8(cvmx_fau_reg_8_t reg, int8_t value)
2694 + cvmx_write64_int8(__cvmx_fau_store_address(0, reg), value);
2698 + * Perform an atomic 64 bit write
2700 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2701 + * - Step by 8 for 64 bit access.
2702 + * @value: Signed value to write.
2704 +static inline void cvmx_fau_atomic_write64(cvmx_fau_reg_64_t reg, int64_t value)
2706 + cvmx_write64_int64(__cvmx_fau_store_address(1, reg), value);
2710 + * Perform an atomic 32 bit write
2712 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2713 + * - Step by 4 for 32 bit access.
2714 + * @value: Signed value to write.
2716 +static inline void cvmx_fau_atomic_write32(cvmx_fau_reg_32_t reg, int32_t value)
2718 + cvmx_write64_int32(__cvmx_fau_store_address(1, reg), value);
2722 + * Perform an atomic 16 bit write
2724 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2725 + * - Step by 2 for 16 bit access.
2726 + * @value: Signed value to write.
2728 +static inline void cvmx_fau_atomic_write16(cvmx_fau_reg_16_t reg, int16_t value)
2730 + cvmx_write64_int16(__cvmx_fau_store_address(1, reg), value);
2734 + * Perform an atomic 8 bit write
2736 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2737 + * @value: Signed value to write.
2739 +static inline void cvmx_fau_atomic_write8(cvmx_fau_reg_8_t reg, int8_t value)
2741 + cvmx_write64_int8(__cvmx_fau_store_address(1, reg), value);
2744 +#endif /* __CVMX_FAU_H__ */
2746 +++ b/drivers/staging/octeon/cvmx-fpa-defs.h
2748 +/***********************license start***************
2749 + * Author: Cavium Networks
2751 + * Contact: support@caviumnetworks.com
2752 + * This file is part of the OCTEON SDK
2754 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
2771 + * This file may also be available under a different license from Cavium.
2772 + * Contact Cavium Networks for more information
2773 + ***********************license end**************************************/
2775 +#ifndef __CVMX_FPA_DEFS_H__
2776 +#define __CVMX_FPA_DEFS_H__
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)
2837 +union cvmx_fpa_bist_status {
2839 + struct cvmx_fpa_bist_status_s {
2840 + uint64_t reserved_5_63:59;
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;
2860 +union cvmx_fpa_ctl_status {
2862 + struct cvmx_fpa_ctl_status_s {
2863 + uint64_t reserved_18_63:46;
2865 + uint64_t use_ldt:1;
2866 + uint64_t use_stt:1;
2868 + uint64_t mem1_err:7;
2869 + uint64_t mem0_err:7;
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;
2884 +union cvmx_fpa_fpfx_marks {
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;
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;
2899 +union cvmx_fpa_fpfx_size {
2901 + struct cvmx_fpa_fpfx_size_s {
2902 + uint64_t reserved_11_63:53;
2903 + uint64_t fpf_siz:11;
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;
2913 +union cvmx_fpa_fpf0_marks {
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;
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;
2928 +union cvmx_fpa_fpf0_size {
2930 + struct cvmx_fpa_fpf0_size_s {
2931 + uint64_t reserved_12_63:52;
2932 + uint64_t fpf_siz:12;
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;
2942 +union cvmx_fpa_int_enb {
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;
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;
2988 +union cvmx_fpa_int_sum {
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;
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;
3034 +union cvmx_fpa_quex_available {
3036 + struct cvmx_fpa_quex_available_s {
3037 + uint64_t reserved_29_63:35;
3038 + uint64_t que_siz:29;
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;
3053 +union cvmx_fpa_quex_page_index {
3055 + struct cvmx_fpa_quex_page_index_s {
3056 + uint64_t reserved_25_63:39;
3057 + uint64_t pg_num:25;
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;
3072 +union cvmx_fpa_que_act {
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;
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;
3092 +union cvmx_fpa_que_exp {
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;
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;
3112 +union cvmx_fpa_wart_ctl {
3114 + struct cvmx_fpa_wart_ctl_s {
3115 + uint64_t reserved_16_63:48;
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;
3131 +union cvmx_fpa_wart_status {
3133 + struct cvmx_fpa_wart_status_s {
3134 + uint64_t reserved_32_63:32;
3135 + uint64_t status:32;
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;
3152 +++ b/drivers/staging/octeon/cvmx-fpa.c
3154 +/***********************license start***************
3155 + * Author: Cavium Networks
3157 + * Contact: support@caviumnetworks.com
3158 + * This file is part of the OCTEON SDK
3160 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
3177 + * This file may also be available under a different license from Cavium.
3178 + * Contact Cavium Networks for more information
3179 + ***********************license end**************************************/
3184 + * Support library for the hardware Free Pool Allocator.
3189 +#include "cvmx-config.h"
3191 +#include "cvmx-fpa.h"
3192 +#include "cvmx-ipd.h"
3195 + * Current state of all the pools. Use access functions
3196 + * instead of using it directly.
3198 +CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
3201 + * Setup a FPA pool to control a new block of memory. The
3202 + * buffer pointer must be a physical address.
3204 + * @pool: Pool to initialize
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
3213 + * Returns 0 on Success,
3216 +int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
3217 + uint64_t block_size, uint64_t num_blocks)
3222 + ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
3225 + if (pool >= CVMX_FPA_NUM_POOLS) {
3226 + cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
3230 + if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
3232 + ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
3236 + if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
3238 + ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
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;
3247 + ptr = (char *)buffer;
3248 + while (num_blocks--) {
3249 + cvmx_fpa_free(ptr, pool, 0);
3250 + ptr += block_size;
3256 + * Shutdown a Memory pool and validate that it had all of
3257 + * the buffers originally placed in it.
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
3264 +uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
3266 + uint64_t errors = 0;
3267 + uint64_t count = 0;
3268 + uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
3271 + cvmx_fpa_pool_info[pool].size *
3272 + cvmx_fpa_pool_info[pool].starting_element_count;
3278 + ptr = cvmx_fpa_alloc(pool);
3280 + address = cvmx_ptr_to_phys(ptr);
3284 + if ((address >= base) && (address < finish) &&
3286 + base) % cvmx_fpa_pool_info[pool].size) == 0)) {
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);
3296 + } while (address);
3298 +#ifdef CVMX_ENABLE_PKO_FUNCTIONS
3300 + cvmx_ipd_free_ptr();
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);
3314 +uint64_t cvmx_fpa_get_block_size(uint64_t pool)
3318 + return CVMX_FPA_POOL_0_SIZE;
3320 + return CVMX_FPA_POOL_1_SIZE;
3322 + return CVMX_FPA_POOL_2_SIZE;
3324 + return CVMX_FPA_POOL_3_SIZE;
3326 + return CVMX_FPA_POOL_4_SIZE;
3328 + return CVMX_FPA_POOL_5_SIZE;
3330 + return CVMX_FPA_POOL_6_SIZE;
3332 + return CVMX_FPA_POOL_7_SIZE;
3338 +++ b/drivers/staging/octeon/cvmx-fpa.h
3340 +/***********************license start***************
3341 + * Author: Cavium Networks
3343 + * Contact: support@caviumnetworks.com
3344 + * This file is part of the OCTEON SDK
3346 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
3363 + * This file may also be available under a different license from Cavium.
3364 + * Contact Cavium Networks for more information
3365 + ***********************license end**************************************/
3370 + * Interface to the hardware Free Pool Allocator.
3375 +#ifndef __CVMX_FPA_H__
3376 +#define __CVMX_FPA_H__
3378 +#include "cvmx-address.h"
3379 +#include "cvmx-fpa-defs.h"
3381 +#define CVMX_FPA_NUM_POOLS 8
3382 +#define CVMX_FPA_MIN_BLOCK_SIZE 128
3383 +#define CVMX_FPA_ALIGNMENT 128
3386 + * Structure describing the data format used for stores to the FPA.
3392 + * the (64-bit word) location in scratchpad to write
3393 + * to (if len != 0)
3395 + uint64_t scraddr:8;
3396 + /* the number of words in the response (0 => no response) */
3398 + /* the ID of the device on the non-coherent bus */
3401 + * the address that will appear in the first tick on
3406 +} cvmx_fpa_iobdma_data_t;
3409 + * Structure describing the current state of a FPA pool.
3412 + /* Name it was created under */
3414 + /* Size of each block */
3416 + /* The base memory address of whole block */
3418 + /* The number of elements in the pool at creation */
3419 + uint64_t starting_element_count;
3420 +} cvmx_fpa_pool_info_t;
3423 + * Current state of all the pools. Use access functions
3424 + * instead of using it directly.
3426 +extern cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
3428 +/* CSR typedefs have been moved to cvmx-csr-*.h */
3431 + * Return the name of the pool
3433 + * @pool: Pool to get the name of
3434 + * Returns The name
3436 +static inline const char *cvmx_fpa_get_name(uint64_t pool)
3438 + return cvmx_fpa_pool_info[pool].name;
3442 + * Return the base of the pool
3444 + * @pool: Pool to get the base of
3445 + * Returns The base
3447 +static inline void *cvmx_fpa_get_base(uint64_t pool)
3449 + return cvmx_fpa_pool_info[pool].base;
3453 + * Check if a pointer belongs to an FPA pool. Return non-zero
3454 + * if the supplied pointer is inside the memory controlled by
3457 + * @pool: Pool to check
3458 + * @ptr: Pointer to check
3459 + * Returns Non-zero if pointer is in the pool. Zero if not
3461 +static inline int cvmx_fpa_is_member(uint64_t pool, void *ptr)
3463 + return ((ptr >= cvmx_fpa_pool_info[pool].base) &&
3465 + ((char *)(cvmx_fpa_pool_info[pool].base)) +
3466 + cvmx_fpa_pool_info[pool].size *
3467 + cvmx_fpa_pool_info[pool].starting_element_count));
3471 + * Enable the FPA for use. Must be performed after any CSR
3472 + * configuration but before any other FPA functions.
3474 +static inline void cvmx_fpa_enable(void)
3476 + union cvmx_fpa_ctl_status status;
3478 + status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
3479 + if (status.s.enb) {
3481 + ("Warning: Enabling FPA when FPA already enabled.\n");
3485 + * Do runtime check as we allow pass1 compiled code to run on
3488 + if (cvmx_octeon_is_pass1()) {
3489 + union cvmx_fpa_fpfx_marks marks;
3491 + for (i = 1; i < 8; i++) {
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,
3499 + /* Enforce a 10 cycle delay between config and enable */
3503 + /* FIXME: CVMX_FPA_CTL_STATUS read is unmodelled */
3506 + cvmx_write_csr(CVMX_FPA_CTL_STATUS, status.u64);
3510 + * Get a new block from the FPA
3512 + * @pool: Pool to get the block from
3513 + * Returns Pointer to the block or NULL on failure
3515 +static inline void *cvmx_fpa_alloc(uint64_t pool)
3517 + uint64_t address =
3518 + cvmx_read_csr(CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool)));
3520 + return cvmx_phys_to_ptr(address);
3526 + * Asynchronously get a new block from the FPA
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
3532 +static inline void cvmx_fpa_async_alloc(uint64_t scr_addr, uint64_t pool)
3534 + cvmx_fpa_iobdma_data_t data;
3537 + * Hardware only uses 64 bit alligned locations, so convert
3538 + * from byte address to 64-bit index
3540 + data.s.scraddr = scr_addr >> 3;
3542 + data.s.did = CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool);
3544 + cvmx_send_single(data.u64);
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.
3551 + * @ptr: Block to free
3552 + * @pool: Pool to put it in
3553 + * @num_cache_lines:
3554 + * Cache lines to invalidate
3556 +static inline void cvmx_fpa_free_nosync(void *ptr, uint64_t pool,
3557 + uint64_t num_cache_lines)
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 */
3565 + /* value written is number of cache lines not written back */
3566 + cvmx_write_io(newptr.u64, num_cache_lines);
3570 + * Free a block allocated with a FPA pool. Provides required memory
3571 + * ordering in cases where memory block was modified by core.
3573 + * @ptr: Block to free
3574 + * @pool: Pool to put it in
3575 + * @num_cache_lines:
3576 + * Cache lines to invalidate
3578 +static inline void cvmx_fpa_free(void *ptr, uint64_t pool,
3579 + uint64_t num_cache_lines)
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));
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
3592 + /* value written is number of cache lines not written back */
3593 + cvmx_write_io(newptr.u64, num_cache_lines);
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.
3601 + * @pool: Pool to initialize
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
3610 + * Returns 0 on Success,
3613 +extern int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
3614 + uint64_t block_size, uint64_t num_blocks);
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
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
3627 +extern uint64_t cvmx_fpa_shutdown_pool(uint64_t pool);
3630 + * Get the size of blocks controlled by the pool
3631 + * This is resolved to a constant at compile time.
3633 + * @pool: Pool to access
3634 + * Returns Size of the block in bytes
3636 +uint64_t cvmx_fpa_get_block_size(uint64_t pool);
3638 +#endif /* __CVM_FPA_H__ */
3640 +++ b/drivers/staging/octeon/cvmx-gmxx-defs.h
3642 +/***********************license start***************
3643 + * Author: Cavium Networks
3645 + * Contact: support@caviumnetworks.com
3646 + * This file is part of the OCTEON SDK
3648 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
3665 + * This file may also be available under a different license from Cavium.
3666 + * Contact Cavium Networks for more information
3667 + ***********************license end**************************************/
3669 +#ifndef __CVMX_GMXX_DEFS_H__
3670 +#define __CVMX_GMXX_DEFS_H__
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))
3871 +union cvmx_gmxx_bad_reg {
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;
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;
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;
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;
3913 +union cvmx_gmxx_bist {
3915 + struct cvmx_gmxx_bist_s {
3916 + uint64_t reserved_17_63:47;
3917 + uint64_t status:17;
3919 + struct cvmx_gmxx_bist_cn30xx {
3920 + uint64_t reserved_10_63:54;
3921 + uint64_t status:10;
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;
3930 + struct cvmx_gmxx_bist_cn52xx {
3931 + uint64_t reserved_16_63:48;
3932 + uint64_t status:16;
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;
3941 +union cvmx_gmxx_clk_en {
3943 + struct cvmx_gmxx_clk_en_s {
3944 + uint64_t reserved_1_63:63;
3945 + uint64_t clk_en:1;
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;
3953 +union cvmx_gmxx_hg2_control {
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;
3962 + struct cvmx_gmxx_hg2_control_s cn52xx;
3963 + struct cvmx_gmxx_hg2_control_s cn52xxp1;
3964 + struct cvmx_gmxx_hg2_control_s cn56xx;
3967 +union cvmx_gmxx_inf_mode {
3969 + struct cvmx_gmxx_inf_mode_s {
3970 + uint64_t reserved_10_63:54;
3972 + uint64_t reserved_6_7:2;
3974 + uint64_t reserved_3_3:1;
3979 + struct cvmx_gmxx_inf_mode_cn30xx {
3980 + uint64_t reserved_3_63:61;
3985 + struct cvmx_gmxx_inf_mode_cn31xx {
3986 + uint64_t reserved_2_63:62;
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;
3996 + uint64_t reserved_6_7:2;
3998 + uint64_t reserved_2_3:2;
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;
4009 +union cvmx_gmxx_nxa_adr {
4011 + struct cvmx_gmxx_nxa_adr_s {
4012 + uint64_t reserved_6_63:58;
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;
4028 +union cvmx_gmxx_prtx_cbfc_ctl {
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;
4040 + struct cvmx_gmxx_prtx_cbfc_ctl_s cn52xx;
4041 + struct cvmx_gmxx_prtx_cbfc_ctl_s cn56xx;
4044 +union cvmx_gmxx_prtx_cfg {
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;
4058 + struct cvmx_gmxx_prtx_cfg_cn30xx {
4059 + uint64_t reserved_4_63:60;
4060 + uint64_t slottime:1;
4061 + uint64_t duplex:1;
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;
4077 +union cvmx_gmxx_rxx_adr_cam0 {
4079 + struct cvmx_gmxx_rxx_adr_cam0_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;
4095 +union cvmx_gmxx_rxx_adr_cam1 {
4097 + struct cvmx_gmxx_rxx_adr_cam1_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;
4113 +union cvmx_gmxx_rxx_adr_cam2 {
4115 + struct cvmx_gmxx_rxx_adr_cam2_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;
4131 +union cvmx_gmxx_rxx_adr_cam3 {
4133 + struct cvmx_gmxx_rxx_adr_cam3_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;
4149 +union cvmx_gmxx_rxx_adr_cam4 {
4151 + struct cvmx_gmxx_rxx_adr_cam4_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;
4167 +union cvmx_gmxx_rxx_adr_cam5 {
4169 + struct cvmx_gmxx_rxx_adr_cam5_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;
4185 +union cvmx_gmxx_rxx_adr_cam_en {
4187 + struct cvmx_gmxx_rxx_adr_cam_en_s {
4188 + uint64_t reserved_8_63:56;
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;
4204 +union cvmx_gmxx_rxx_adr_ctl {
4206 + struct cvmx_gmxx_rxx_adr_ctl_s {
4207 + uint64_t reserved_4_63:60;
4208 + uint64_t cam_mode:1;
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;
4225 +union cvmx_gmxx_rxx_decision {
4227 + struct cvmx_gmxx_rxx_decision_s {
4228 + uint64_t reserved_5_63:59;
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;
4244 +union cvmx_gmxx_rxx_frm_chk {
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;
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;
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;
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;
4294 +union cvmx_gmxx_rxx_frm_ctl {
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;
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;
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;
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;
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;
4363 + struct cvmx_gmxx_rxx_frm_ctl_s cn58xx;
4364 + struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn58xxp1;
4367 +union cvmx_gmxx_rxx_frm_max {
4369 + struct cvmx_gmxx_rxx_frm_max_s {
4370 + uint64_t reserved_16_63:48;
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;
4381 +union cvmx_gmxx_rxx_frm_min {
4383 + struct cvmx_gmxx_rxx_frm_min_s {
4384 + uint64_t reserved_16_63:48;
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;
4395 +union cvmx_gmxx_rxx_ifg {
4397 + struct cvmx_gmxx_rxx_ifg_s {
4398 + uint64_t reserved_4_63:60;
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;
4414 +union cvmx_gmxx_rxx_int_en {
4416 + struct cvmx_gmxx_rxx_int_en_s {
4417 + uint64_t reserved_29_63:35;
4419 + uint64_t hg2fld: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;
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;
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;
4496 + struct cvmx_gmxx_rxx_int_en_cn52xx {
4497 + uint64_t reserved_29_63:35;
4499 + uint64_t hg2fld: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;
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;
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;
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;
4577 + struct cvmx_gmxx_rxx_int_en_cn58xx cn58xxp1;
4580 +union cvmx_gmxx_rxx_int_reg {
4582 + struct cvmx_gmxx_rxx_int_reg_s {
4583 + uint64_t reserved_29_63:35;
4585 + uint64_t hg2fld: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;
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;
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;
4662 + struct cvmx_gmxx_rxx_int_reg_cn52xx {
4663 + uint64_t reserved_29_63:35;
4665 + uint64_t hg2fld: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;
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;
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;
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;
4743 + struct cvmx_gmxx_rxx_int_reg_cn58xx cn58xxp1;
4746 +union cvmx_gmxx_rxx_jabber {
4748 + struct cvmx_gmxx_rxx_jabber_s {
4749 + uint64_t reserved_16_63:48;
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;
4765 +union cvmx_gmxx_rxx_pause_drop_time {
4767 + struct cvmx_gmxx_rxx_pause_drop_time_s {
4768 + uint64_t reserved_16_63:48;
4769 + uint64_t status:16;
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;
4780 +union cvmx_gmxx_rxx_rx_inbnd {
4782 + struct cvmx_gmxx_rxx_rx_inbnd_s {
4783 + uint64_t reserved_4_63:60;
4784 + uint64_t duplex:1;
4786 + uint64_t status:1;
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;
4797 +union cvmx_gmxx_rxx_stats_ctl {
4799 + struct cvmx_gmxx_rxx_stats_ctl_s {
4800 + uint64_t reserved_1_63:63;
4801 + uint64_t rd_clr:1;
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;
4816 +union cvmx_gmxx_rxx_stats_octs {
4818 + struct cvmx_gmxx_rxx_stats_octs_s {
4819 + uint64_t reserved_48_63:16;
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;
4835 +union cvmx_gmxx_rxx_stats_octs_ctl {
4837 + struct cvmx_gmxx_rxx_stats_octs_ctl_s {
4838 + uint64_t reserved_48_63:16;
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;
4854 +union cvmx_gmxx_rxx_stats_octs_dmac {
4856 + struct cvmx_gmxx_rxx_stats_octs_dmac_s {
4857 + uint64_t reserved_48_63:16;
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;
4873 +union cvmx_gmxx_rxx_stats_octs_drp {
4875 + struct cvmx_gmxx_rxx_stats_octs_drp_s {
4876 + uint64_t reserved_48_63:16;
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;
4892 +union cvmx_gmxx_rxx_stats_pkts {
4894 + struct cvmx_gmxx_rxx_stats_pkts_s {
4895 + uint64_t reserved_32_63:32;
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;
4911 +union cvmx_gmxx_rxx_stats_pkts_bad {
4913 + struct cvmx_gmxx_rxx_stats_pkts_bad_s {
4914 + uint64_t reserved_32_63:32;
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;
4930 +union cvmx_gmxx_rxx_stats_pkts_ctl {
4932 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s {
4933 + uint64_t reserved_32_63:32;
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;
4949 +union cvmx_gmxx_rxx_stats_pkts_dmac {
4951 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s {
4952 + uint64_t reserved_32_63:32;
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;
4968 +union cvmx_gmxx_rxx_stats_pkts_drp {
4970 + struct cvmx_gmxx_rxx_stats_pkts_drp_s {
4971 + uint64_t reserved_32_63:32;
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;
4987 +union cvmx_gmxx_rxx_udd_skp {
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;
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;
5008 +union cvmx_gmxx_rx_bp_dropx {
5010 + struct cvmx_gmxx_rx_bp_dropx_s {
5011 + uint64_t reserved_6_63:58;
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;
5027 +union cvmx_gmxx_rx_bp_offx {
5029 + struct cvmx_gmxx_rx_bp_offx_s {
5030 + uint64_t reserved_6_63:58;
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;
5046 +union cvmx_gmxx_rx_bp_onx {
5048 + struct cvmx_gmxx_rx_bp_onx_s {
5049 + uint64_t reserved_9_63:55;
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;
5065 +union cvmx_gmxx_rx_hg2_status {
5067 + struct cvmx_gmxx_rx_hg2_status_s {
5068 + uint64_t reserved_48_63:16;
5069 + uint64_t phtim2go:16;
5071 + uint64_t lgtim2go:16;
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;
5078 +union cvmx_gmxx_rx_pass_en {
5080 + struct cvmx_gmxx_rx_pass_en_s {
5081 + uint64_t reserved_16_63:48;
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;
5090 +union cvmx_gmxx_rx_pass_mapx {
5092 + struct cvmx_gmxx_rx_pass_mapx_s {
5093 + uint64_t reserved_4_63:60;
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;
5102 +union cvmx_gmxx_rx_prt_info {
5104 + struct cvmx_gmxx_rx_prt_info_s {
5105 + uint64_t reserved_32_63:32;
5107 + uint64_t commit:16;
5109 + struct cvmx_gmxx_rx_prt_info_cn30xx {
5110 + uint64_t reserved_19_63:45;
5112 + uint64_t reserved_3_15:13;
5113 + uint64_t commit:3;
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;
5121 + uint64_t reserved_4_15:12;
5122 + uint64_t commit:4;
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;
5131 +union cvmx_gmxx_rx_prts {
5133 + struct cvmx_gmxx_rx_prts_s {
5134 + uint64_t reserved_3_63:61;
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;
5150 +union cvmx_gmxx_rx_tx_status {
5152 + struct cvmx_gmxx_rx_tx_status_s {
5153 + uint64_t reserved_7_63:57;
5155 + uint64_t reserved_3_3:1;
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;
5163 +union cvmx_gmxx_rx_xaui_bad_col {
5165 + struct cvmx_gmxx_rx_xaui_bad_col_s {
5166 + uint64_t reserved_40_63:24;
5169 + uint64_t lane_rxc:4;
5170 + uint64_t lane_rxd:32;
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;
5178 +union cvmx_gmxx_rx_xaui_ctl {
5180 + struct cvmx_gmxx_rx_xaui_ctl_s {
5181 + uint64_t reserved_2_63:62;
5182 + uint64_t status:2;
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;
5190 +union cvmx_gmxx_smacx {
5192 + struct cvmx_gmxx_smacx_s {
5193 + uint64_t reserved_48_63:16;
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;
5209 +union cvmx_gmxx_stat_bp {
5211 + struct cvmx_gmxx_stat_bp_s {
5212 + uint64_t reserved_17_63:47;
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;
5229 +union cvmx_gmxx_txx_append {
5231 + struct cvmx_gmxx_txx_append_s {
5232 + uint64_t reserved_4_63:60;
5233 + uint64_t force_fcs:1;
5236 + uint64_t preamble:1;
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;
5251 +union cvmx_gmxx_txx_burst {
5253 + struct cvmx_gmxx_txx_burst_s {
5254 + uint64_t reserved_16_63:48;
5255 + uint64_t burst:16;
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;
5270 +union cvmx_gmxx_txx_cbfc_xoff {
5272 + struct cvmx_gmxx_txx_cbfc_xoff_s {
5273 + uint64_t reserved_16_63:48;
5276 + struct cvmx_gmxx_txx_cbfc_xoff_s cn52xx;
5277 + struct cvmx_gmxx_txx_cbfc_xoff_s cn56xx;
5280 +union cvmx_gmxx_txx_cbfc_xon {
5282 + struct cvmx_gmxx_txx_cbfc_xon_s {
5283 + uint64_t reserved_16_63:48;
5286 + struct cvmx_gmxx_txx_cbfc_xon_s cn52xx;
5287 + struct cvmx_gmxx_txx_cbfc_xon_s cn56xx;
5290 +union cvmx_gmxx_txx_clk {
5292 + struct cvmx_gmxx_txx_clk_s {
5293 + uint64_t reserved_6_63:58;
5294 + uint64_t clk_cnt:6;
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;
5305 +union cvmx_gmxx_txx_ctl {
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;
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;
5325 +union cvmx_gmxx_txx_min_pkt {
5327 + struct cvmx_gmxx_txx_min_pkt_s {
5328 + uint64_t reserved_8_63:56;
5329 + uint64_t min_size:8;
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;
5344 +union cvmx_gmxx_txx_pause_pkt_interval {
5346 + struct cvmx_gmxx_txx_pause_pkt_interval_s {
5347 + uint64_t reserved_16_63:48;
5348 + uint64_t interval:16;
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;
5363 +union cvmx_gmxx_txx_pause_pkt_time {
5365 + struct cvmx_gmxx_txx_pause_pkt_time_s {
5366 + uint64_t reserved_16_63:48;
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;
5382 +union cvmx_gmxx_txx_pause_togo {
5384 + struct cvmx_gmxx_txx_pause_togo_s {
5385 + uint64_t reserved_32_63:32;
5386 + uint64_t msg_time:16;
5389 + struct cvmx_gmxx_txx_pause_togo_cn30xx {
5390 + uint64_t reserved_16_63:48;
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;
5405 +union cvmx_gmxx_txx_pause_zero {
5407 + struct cvmx_gmxx_txx_pause_zero_s {
5408 + uint64_t reserved_1_63:63;
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;
5424 +union cvmx_gmxx_txx_sgmii_ctl {
5426 + struct cvmx_gmxx_txx_sgmii_ctl_s {
5427 + uint64_t reserved_1_63:63;
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;
5436 +union cvmx_gmxx_txx_slot {
5438 + struct cvmx_gmxx_txx_slot_s {
5439 + uint64_t reserved_10_63:54;
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;
5455 +union cvmx_gmxx_txx_soft_pause {
5457 + struct cvmx_gmxx_txx_soft_pause_s {
5458 + uint64_t reserved_16_63:48;
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;
5474 +union cvmx_gmxx_txx_stat0 {
5476 + struct cvmx_gmxx_txx_stat0_s {
5477 + uint64_t xsdef:32;
5478 + uint64_t xscol:32;
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;
5493 +union cvmx_gmxx_txx_stat1 {
5495 + struct cvmx_gmxx_txx_stat1_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;
5512 +union cvmx_gmxx_txx_stat2 {
5514 + struct cvmx_gmxx_txx_stat2_s {
5515 + uint64_t reserved_48_63:16;
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;
5531 +union cvmx_gmxx_txx_stat3 {
5533 + struct cvmx_gmxx_txx_stat3_s {
5534 + uint64_t reserved_32_63:32;
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;
5550 +union cvmx_gmxx_txx_stat4 {
5552 + struct cvmx_gmxx_txx_stat4_s {
5553 + uint64_t hist1:32;
5554 + uint64_t hist0:32;
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;
5569 +union cvmx_gmxx_txx_stat5 {
5571 + struct cvmx_gmxx_txx_stat5_s {
5572 + uint64_t hist3:32;
5573 + uint64_t hist2:32;
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;
5588 +union cvmx_gmxx_txx_stat6 {
5590 + struct cvmx_gmxx_txx_stat6_s {
5591 + uint64_t hist5:32;
5592 + uint64_t hist4:32;
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;
5607 +union cvmx_gmxx_txx_stat7 {
5609 + struct cvmx_gmxx_txx_stat7_s {
5610 + uint64_t hist7:32;
5611 + uint64_t hist6:32;
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;
5626 +union cvmx_gmxx_txx_stat8 {
5628 + struct cvmx_gmxx_txx_stat8_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;
5645 +union cvmx_gmxx_txx_stat9 {
5647 + struct cvmx_gmxx_txx_stat9_s {
5648 + uint64_t undflw:32;
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;
5664 +union cvmx_gmxx_txx_stats_ctl {
5666 + struct cvmx_gmxx_txx_stats_ctl_s {
5667 + uint64_t reserved_1_63:63;
5668 + uint64_t rd_clr:1;
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;
5683 +union cvmx_gmxx_txx_thresh {
5685 + struct cvmx_gmxx_txx_thresh_s {
5686 + uint64_t reserved_9_63:55;
5689 + struct cvmx_gmxx_txx_thresh_cn30xx {
5690 + uint64_t reserved_7_63:57;
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;
5705 +union cvmx_gmxx_tx_bp {
5707 + struct cvmx_gmxx_tx_bp_s {
5708 + uint64_t reserved_4_63:60;
5711 + struct cvmx_gmxx_tx_bp_cn30xx {
5712 + uint64_t reserved_3_63:61;
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;
5727 +union cvmx_gmxx_tx_clk_mskx {
5729 + struct cvmx_gmxx_tx_clk_mskx_s {
5730 + uint64_t reserved_1_63:63;
5733 + struct cvmx_gmxx_tx_clk_mskx_s cn30xx;
5734 + struct cvmx_gmxx_tx_clk_mskx_s cn50xx;
5737 +union cvmx_gmxx_tx_col_attempt {
5739 + struct cvmx_gmxx_tx_col_attempt_s {
5740 + uint64_t reserved_5_63:59;
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;
5756 +union cvmx_gmxx_tx_corrupt {
5758 + struct cvmx_gmxx_tx_corrupt_s {
5759 + uint64_t reserved_4_63:60;
5760 + uint64_t corrupt:4;
5762 + struct cvmx_gmxx_tx_corrupt_cn30xx {
5763 + uint64_t reserved_3_63:61;
5764 + uint64_t corrupt:3;
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;
5778 +union cvmx_gmxx_tx_hg2_reg1 {
5780 + struct cvmx_gmxx_tx_hg2_reg1_s {
5781 + uint64_t reserved_16_63:48;
5782 + uint64_t tx_xof:16;
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;
5789 +union cvmx_gmxx_tx_hg2_reg2 {
5791 + struct cvmx_gmxx_tx_hg2_reg2_s {
5792 + uint64_t reserved_16_63:48;
5793 + uint64_t tx_xon:16;
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;
5800 +union cvmx_gmxx_tx_ifg {
5802 + struct cvmx_gmxx_tx_ifg_s {
5803 + uint64_t reserved_8_63:56;
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;
5820 +union cvmx_gmxx_tx_int_en {
5822 + struct cvmx_gmxx_tx_int_en_s {
5823 + uint64_t reserved_20_63:44;
5824 + uint64_t late_col: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;
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;
5837 + uint64_t reserved_11_11:1;
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;
5844 + struct cvmx_gmxx_tx_int_en_cn31xx {
5845 + uint64_t reserved_15_63:49;
5847 + uint64_t reserved_11_11:1;
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;
5854 + struct cvmx_gmxx_tx_int_en_s cn38xx;
5855 + struct cvmx_gmxx_tx_int_en_cn38xxp2 {
5856 + uint64_t reserved_16_63:48;
5859 + uint64_t reserved_6_7:2;
5860 + uint64_t undflw:4;
5861 + uint64_t ncb_nxa:1;
5862 + uint64_t pko_nxa:1;
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;
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;
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;
5882 +union cvmx_gmxx_tx_int_reg {
5884 + struct cvmx_gmxx_tx_int_reg_s {
5885 + uint64_t reserved_20_63:44;
5886 + uint64_t late_col: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;
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;
5899 + uint64_t reserved_11_11:1;
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;
5906 + struct cvmx_gmxx_tx_int_reg_cn31xx {
5907 + uint64_t reserved_15_63:49;
5909 + uint64_t reserved_11_11:1;
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;
5916 + struct cvmx_gmxx_tx_int_reg_s cn38xx;
5917 + struct cvmx_gmxx_tx_int_reg_cn38xxp2 {
5918 + uint64_t reserved_16_63:48;
5921 + uint64_t reserved_6_7:2;
5922 + uint64_t undflw:4;
5923 + uint64_t ncb_nxa:1;
5924 + uint64_t pko_nxa:1;
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;
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;
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;
5944 +union cvmx_gmxx_tx_jam {
5946 + struct cvmx_gmxx_tx_jam_s {
5947 + uint64_t reserved_8_63:56;
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;
5963 +union cvmx_gmxx_tx_lfsr {
5965 + struct cvmx_gmxx_tx_lfsr_s {
5966 + uint64_t reserved_16_63:48;
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;
5982 +union cvmx_gmxx_tx_ovr_bp {
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;
5990 + uint64_t ign_full:4;
5992 + struct cvmx_gmxx_tx_ovr_bp_cn30xx {
5993 + uint64_t reserved_11_63:53;
5995 + uint64_t reserved_7_7:1;
5997 + uint64_t reserved_3_3:1;
5998 + uint64_t ign_full:3;
6000 + struct cvmx_gmxx_tx_ovr_bp_cn30xx cn31xx;
6001 + struct cvmx_gmxx_tx_ovr_bp_cn38xx {
6002 + uint64_t reserved_12_63:52;
6005 + uint64_t ign_full:4;
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;
6017 +union cvmx_gmxx_tx_pause_pkt_dmac {
6019 + struct cvmx_gmxx_tx_pause_pkt_dmac_s {
6020 + uint64_t reserved_48_63:16;
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;
6036 +union cvmx_gmxx_tx_pause_pkt_type {
6038 + struct cvmx_gmxx_tx_pause_pkt_type_s {
6039 + uint64_t reserved_16_63:48;
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;
6055 +union cvmx_gmxx_tx_prts {
6057 + struct cvmx_gmxx_tx_prts_s {
6058 + uint64_t reserved_5_63:59;
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;
6074 +union cvmx_gmxx_tx_spi_ctl {
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;
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;
6087 +union cvmx_gmxx_tx_spi_drain {
6089 + struct cvmx_gmxx_tx_spi_drain_s {
6090 + uint64_t reserved_16_63:48;
6091 + uint64_t drain:16;
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;
6098 +union cvmx_gmxx_tx_spi_max {
6100 + struct cvmx_gmxx_tx_spi_max_s {
6101 + uint64_t reserved_23_63:41;
6106 + struct cvmx_gmxx_tx_spi_max_cn38xx {
6107 + uint64_t reserved_16_63:48;
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;
6116 +union cvmx_gmxx_tx_spi_roundx {
6118 + struct cvmx_gmxx_tx_spi_roundx_s {
6119 + uint64_t reserved_16_63:48;
6120 + uint64_t round:16;
6122 + struct cvmx_gmxx_tx_spi_roundx_s cn58xx;
6123 + struct cvmx_gmxx_tx_spi_roundx_s cn58xxp1;
6126 +union cvmx_gmxx_tx_spi_thresh {
6128 + struct cvmx_gmxx_tx_spi_thresh_s {
6129 + uint64_t reserved_6_63:58;
6130 + uint64_t thresh:6;
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;
6138 +union cvmx_gmxx_tx_xaui_ctl {
6140 + struct cvmx_gmxx_tx_xaui_ctl_s {
6141 + uint64_t reserved_11_63:53;
6142 + uint64_t hg_pause_hgi:2;
6144 + uint64_t reserved_7_7:1;
6145 + uint64_t ls_byp:1;
6147 + uint64_t reserved_2_3:2;
6148 + uint64_t uni_en:1;
6149 + uint64_t dic_en:1;
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;
6157 +union cvmx_gmxx_xaui_ext_loopback {
6159 + struct cvmx_gmxx_xaui_ext_loopback_s {
6160 + uint64_t reserved_5_63:59;
6162 + uint64_t thresh:4;
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;
6172 +++ b/drivers/staging/octeon/cvmx-helper-board.c
6174 +/***********************license start***************
6175 + * Author: Cavium Networks
6177 + * Contact: support@caviumnetworks.com
6178 + * This file is part of the OCTEON SDK
6180 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
6197 + * This file may also be available under a different license from Cavium.
6198 + * Contact Cavium Networks for more information
6199 + ***********************license end**************************************/
6203 + * Helper functions to abstract board specific data about
6204 + * network ports from the rest of the cvmx-helper files.
6207 +#include <asm/octeon/octeon.h>
6208 +#include <asm/octeon/cvmx-bootinfo.h>
6210 +#include "cvmx-config.h"
6212 +#include "cvmx-mdio.h"
6214 +#include "cvmx-helper.h"
6215 +#include "cvmx-helper-util.h"
6216 +#include "cvmx-helper-board.h"
6218 +#include "cvmx-gmxx-defs.h"
6219 +#include "cvmx-asxx-defs.h"
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
6229 +cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port) =
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>.
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.
6244 + * @ipd_port: Octeon IPD port to get the MII address for.
6246 + * Returns MII PHY address and bus number or -1.
6248 +int cvmx_helper_board_get_mii_address(int ipd_port)
6250 + switch (cvmx_sysinfo_get()->board_type) {
6251 + case CVMX_BOARD_TYPE_SIM:
6252 + /* Simulator doesn't have MII */
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;
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:
6270 + * Port 0 is WAN connected to a PHY, Port 1 is GMII
6271 + * connected to a switch
6273 + if (ipd_port == 0)
6275 + else if (ipd_port == 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))
6283 + else if ((ipd_port >= 16) && (ipd_port < 20))
6284 + return ipd_port - 16 + 4;
6287 + case CVMX_BOARD_TYPE_EBH3000:
6288 + /* Board has dual SPI4 and no PHYs */
6290 + case CVMX_BOARD_TYPE_EBH5200:
6291 + case CVMX_BOARD_TYPE_EBH5201:
6292 + case CVMX_BOARD_TYPE_EBT5200:
6294 + * Board has 4 SGMII ports. The PHYs start right after the MII
6295 + * ports MII0 = 0, MII1 = 1, SGMII = 2-5.
6297 + if ((ipd_port >= 0) && (ipd_port < 4))
6298 + return ipd_port + 2;
6301 + case CVMX_BOARD_TYPE_EBH5600:
6302 + case CVMX_BOARD_TYPE_EBH5601:
6303 + case CVMX_BOARD_TYPE_EBH5610:
6305 + * Board has 8 SGMII ports. 4 connect out, two connect
6306 + * to a switch, and 2 loop to each other
6308 + if ((ipd_port >= 0) && (ipd_port < 4))
6309 + return ipd_port + 1;
6312 + case CVMX_BOARD_TYPE_CUST_NB5:
6313 + if (ipd_port == 2)
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;
6323 + case CVMX_BOARD_TYPE_BBGW_REF:
6325 + * No PHYs are connected to Octeon, everything is
6331 + /* Some unknown board. Somebody forgot to update this function... */
6333 + ("cvmx_helper_board_get_mii_address: Unknown board type %d\n",
6334 + cvmx_sysinfo_get()->board_type);
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.
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.
6350 + * @ipd_port: IPD input port associated with the port we want to get link
6353 + * Returns The ports link status. If the link isn't fully resolved, this must
6356 +cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
6358 + cvmx_helper_link_info_t result;
6360 + int is_broadcom_phy = 0;
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);
6366 + /* Unless we fix it later, all links are defaulted to down */
6370 + * This switch statement should handle all ports that either don't use
6371 + * Marvell PHYS, or don't support in-band status.
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;
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;
6391 + /* Fall through to the generic code below */
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;
6400 + } else /* The other port uses a broadcom PHY */
6401 + is_broadcom_phy = 1;
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 */
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;
6419 + phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
6420 + if (phy_addr != -1) {
6421 + if (is_broadcom_phy) {
6423 + * Below we are going to read SMI/MDIO
6424 + * register 0x19 which works on Broadcom
6428 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6430 + switch ((phy_status >> 8) & 0x7) {
6435 + result.s.link_up = 1;
6436 + result.s.full_duplex = 0;
6437 + result.s.speed = 10;
6440 + result.s.link_up = 1;
6441 + result.s.full_duplex = 1;
6442 + result.s.speed = 10;
6445 + result.s.link_up = 1;
6446 + result.s.full_duplex = 0;
6447 + result.s.speed = 100;
6450 + result.s.link_up = 1;
6451 + result.s.full_duplex = 1;
6452 + result.s.speed = 100;
6455 + result.s.link_up = 1;
6456 + result.s.full_duplex = 1;
6457 + result.s.speed = 100;
6460 + result.s.link_up = 1;
6461 + result.s.full_duplex = 0;
6462 + result.s.speed = 1000;
6465 + result.s.link_up = 1;
6466 + result.s.full_duplex = 1;
6467 + result.s.speed = 1000;
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
6480 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17);
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.
6488 + if ((phy_status & (1 << 11)) == 0) {
6490 + cvmx_mdio_read(phy_addr >> 8,
6491 + phy_addr & 0xff, 0);
6492 + if ((auto_status & (1 << 12)) == 0)
6493 + phy_status |= 1 << 11;
6497 + * Only return a link if the PHY has finished
6498 + * auto negotiation and set the resolved bit
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;
6508 + case 1: /* 100 Mbps */
6509 + result.s.speed = 100;
6511 + case 2: /* 1 Gbps */
6512 + result.s.speed = 1000;
6514 + case 3: /* Illegal */
6520 + } else if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
6521 + || OCTEON_IS_MODEL(OCTEON_CN58XX)
6522 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
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
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));
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;
6542 + case 1: /* 100 Mbps */
6543 + result.s.speed = 100;
6545 + case 2: /* 1 Gbps */
6546 + result.s.speed = 1000;
6548 + case 3: /* Illegal */
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
6562 + /* If link is down, return all fields as zero. */
6563 + if (!result.s.link_up)
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.
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.
6581 + * Returns Zero on success, negative on failure
6583 +int cvmx_helper_board_link_set_phy(int phy_addr,
6584 + cvmx_helper_board_set_phy_link_flags_types_t
6586 + cvmx_helper_link_info_t link_info)
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);
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;
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);
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;
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;
6685 + switch (link_info.s.speed) {
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;
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;
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;
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);
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);
6720 + cvmx_mdio_phy_reg_control_t reg_control;
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;
6737 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6738 + CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
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
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.
6757 + * @interface: Interface to probe
6758 + * @supported_ports:
6759 + * Number of ports Octeon supports.
6761 + * Returns Number of ports the actual board supports. Many times this will
6762 + * simple be "support_ports".
6764 +int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
6766 + switch (cvmx_sysinfo_get()->board_type) {
6767 + case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6768 + if (interface == 0)
6771 + case CVMX_BOARD_TYPE_BBGW_REF:
6772 + if (interface == 0)
6775 + case CVMX_BOARD_TYPE_NIC_XLE_4G:
6776 + if (interface == 0)
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)
6786 + return supported_ports;
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.
6795 + * @interface: Interface to enable
6797 + * Returns Zero on success, negative on failure
6799 +int __cvmx_helper_board_hardware_enable(int interface)
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);
6807 + * Boards with gigabit WAN ports need a
6808 + * different setting that is compatible with
6809 + * 100 Mbit settings
6811 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface),
6813 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface),
6816 + } else if (cvmx_sysinfo_get()->board_type ==
6817 + CVMX_BOARD_TYPE_CN3010_EVB_HS5) {
6819 + * Broadcom PHYs require differnet ASX
6820 + * clocks. Unfortunately many boards don't define a
6821 + * new board Id and simply mangle the
6824 + if (interface == 0) {
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.
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");
6843 + ("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n");
6845 + ("ERROR: The board type is mis-configured, and software malfunctions are likely.\n");
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);
6862 +cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void)
6864 + switch (cvmx_sysinfo_get()->board_type) {
6865 + case CVMX_BOARD_TYPE_BBGW_REF:
6866 + return USB_CLOCK_TYPE_CRYSTAL_12;
6868 + return USB_CLOCK_TYPE_REF_48;
6871 +int __cvmx_helper_board_usb_get_num_ports(int supported_ports)
6873 + switch (cvmx_sysinfo_get()->board_type) {
6874 + case CVMX_BOARD_TYPE_NIC_XLE_4G:
6878 + return supported_ports;
6881 +++ b/drivers/staging/octeon/cvmx-helper-board.h
6883 +/***********************license start***************
6884 + * Author: Cavium Networks
6886 + * Contact: support@caviumnetworks.com
6887 + * This file is part of the OCTEON SDK
6889 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
6906 + * This file may also be available under a different license from Cavium.
6907 + * Contact Cavium Networks for more information
6908 + ***********************license end**************************************/
6912 + * Helper functions to abstract board specific data about
6913 + * network ports from the rest of the cvmx-helper files.
6916 +#ifndef __CVMX_HELPER_BOARD_H__
6917 +#define __CVMX_HELPER_BOARD_H__
6919 +#include "cvmx-helper.h"
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;
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;
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
6944 +extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port);
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>.
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.
6958 + * @ipd_port: Octeon IPD port to get the MII address for.
6960 + * Returns MII PHY address and bus number or -1.
6962 +extern int cvmx_helper_board_get_mii_address(int ipd_port);
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.
6970 + * @phy_addr: The address of the PHY to program
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.
6977 + * Returns Zero on success, negative on failure
6979 +int cvmx_helper_board_link_set_phy(int phy_addr,
6980 + cvmx_helper_board_set_phy_link_flags_types_t
6982 + cvmx_helper_link_info_t link_info);
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.
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.
6996 + * @ipd_port: IPD input port associated with the port we want to get link
6999 + * Returns The ports link status. If the link isn't fully resolved, this must
7002 +extern cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port);
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
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.
7018 + * @interface: Interface to probe
7019 + * @supported_ports:
7020 + * Number of ports Octeon supports.
7022 + * Returns Number of ports the actual board supports. Many times this will
7023 + * simple be "support_ports".
7025 +extern int __cvmx_helper_board_interface_probe(int interface,
7026 + int supported_ports);
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.
7034 + * @interface: Interface to enable
7036 + * Returns Zero on success, negative on failure
7038 +extern int __cvmx_helper_board_hardware_enable(int interface);
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.
7044 + * Returns USB clock type enumeration
7046 +cvmx_helper_board_usb_clock_types_t
7047 +__cvmx_helper_board_usb_get_clock_type(void);
7050 + * Adjusts the number of available USB ports on Octeon based on board
7053 + * @supported_ports: expected number of ports based on chip type;
7056 + * Returns number of available usb ports, based on board specifics.
7057 + * Return value is supported_ports if function does not
7060 +int __cvmx_helper_board_usb_get_num_ports(int supported_ports);
7062 +#endif /* __CVMX_HELPER_BOARD_H__ */
7064 +++ b/drivers/staging/octeon/cvmx-helper-fpa.c
7066 +/***********************license start***************
7067 + * Author: Cavium Networks
7069 + * Contact: support@caviumnetworks.com
7070 + * This file is part of the OCTEON SDK
7072 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
7089 + * This file may also be available under a different license from Cavium.
7090 + * Contact Cavium Networks for more information
7091 + ***********************license end**************************************/
7096 + * Helper functions for FPA setup.
7099 +#include "executive-config.h"
7100 +#include "cvmx-config.h"
7102 +#include "cvmx-bootmem.h"
7103 +#include "cvmx-fpa.h"
7104 +#include "cvmx-helper-fpa.h"
7107 + * Allocate memory for and initialize a single FPA pool.
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
7115 +static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size,
7116 + uint64_t buffers, const char *name)
7118 + uint64_t current_num;
7120 + uint64_t align = CVMX_CACHE_LINE_SIZE;
7123 + * Align the allocation so that power of 2 size buffers are
7124 + * naturally aligned.
7126 + while (align < buffer_size)
7127 + align = align << 1;
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);
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",
7146 + cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers);
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.
7158 + * @pip_pool: Should always be CVMX_FPA_PACKET_POOL
7159 + * @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE
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
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
7169 + * PKO Command buffers. You should at minimum have two per
7171 + * @tim_pool: Should always be CVMX_FPA_TIMER_POOL
7172 + * @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE
7174 + * TIM ring buffer command queues. At least two per timer bucket
7176 + * @dfa_pool: Should always be CVMX_FPA_DFA_POOL
7177 + * @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE
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
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,
7194 + cvmx_fpa_enable();
7196 + if ((pip_buffers > 0) && (pip_buffers <= 64))
7198 + ("Warning: %d packet buffers may not be enough for hardware"
7199 + " prefetch. 65 or more is recommended.\n", pip_buffers);
7201 + if (pip_pool >= 0) {
7203 + __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size,
7205 + "Packet Buffers");
7210 + if (wqe_pool >= 0) {
7212 + __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size,
7214 + "Work Queue Entries");
7219 + if (pko_pool >= 0) {
7221 + __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size,
7223 + "PKO Command Buffers");
7228 + if (tim_pool >= 0) {
7230 + __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size,
7232 + "TIM Command Buffers");
7237 + if (dfa_pool >= 0) {
7239 + __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size,
7241 + "DFA Command Buffers");
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.
7257 + * @packet_buffers:
7258 + * Number of packet buffers to allocate
7259 + * @work_queue_entries:
7260 + * Number of work queue entries
7262 + * PKO Command buffers. You should at minimum have two per
7265 + * TIM ring buffer command queues. At least two per timer bucket
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
7272 +int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries,
7273 + int pko_buffers, int tim_buffers,
7276 +#ifndef CVMX_FPA_PACKET_POOL
7277 +#define CVMX_FPA_PACKET_POOL -1
7278 +#define CVMX_FPA_PACKET_POOL_SIZE 0
7280 +#ifndef CVMX_FPA_WQE_POOL
7281 +#define CVMX_FPA_WQE_POOL -1
7282 +#define CVMX_FPA_WQE_POOL_SIZE 0
7284 +#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL
7285 +#define CVMX_FPA_OUTPUT_BUFFER_POOL -1
7286 +#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0
7288 +#ifndef CVMX_FPA_TIMER_POOL
7289 +#define CVMX_FPA_TIMER_POOL -1
7290 +#define CVMX_FPA_TIMER_POOL_SIZE 0
7292 +#ifndef CVMX_FPA_DFA_POOL
7293 +#define CVMX_FPA_DFA_POOL -1
7294 +#define CVMX_FPA_DFA_POOL_SIZE 0
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,
7310 +++ b/drivers/staging/octeon/cvmx-helper-fpa.h
7312 +/***********************license start***************
7313 + * Author: Cavium Networks
7315 + * Contact: support@caviumnetworks.com
7316 + * This file is part of the OCTEON SDK
7318 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
7335 + * This file may also be available under a different license from Cavium.
7336 + * Contact Cavium Networks for more information
7337 + ***********************license end**************************************/
7342 + * Helper functions for FPA setup.
7345 +#ifndef __CVMX_HELPER_H_FPA__
7346 +#define __CVMX_HELPER_H_FPA__
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.
7356 + * @packet_buffers:
7357 + * Number of packet buffers to allocate
7358 + * @work_queue_entries:
7359 + * Number of work queue entries
7361 + * PKO Command buffers. You should at minimum have two per
7364 + * TIM ring buffer command queues. At least two per timer bucket
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
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);
7375 +#endif /* __CVMX_HELPER_H__ */
7377 +++ b/drivers/staging/octeon/cvmx-helper-loop.c
7379 +/***********************license start***************
7380 + * Author: Cavium Networks
7382 + * Contact: support@caviumnetworks.com
7383 + * This file is part of the OCTEON SDK
7385 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
7402 + * This file may also be available under a different license from Cavium.
7403 + * Contact Cavium Networks for more information
7404 + ***********************license end**************************************/
7407 + * Functions for LOOP initialization, configuration,
7410 +#include <asm/octeon/octeon.h>
7412 +#include "cvmx-config.h"
7414 +#include "cvmx-helper.h"
7415 +#include "cvmx-pip-defs.h"
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.
7422 + * @interface: Interface to probe
7424 + * Returns Number of ports on the interface. Zero to disable.
7426 +int __cvmx_helper_loop_probe(int interface)
7428 + union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
7429 + int num_ports = 4;
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);
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);
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.
7455 + * @interface: Interface to bring up
7457 + * Returns Zero on success, negative on failure
7459 +int __cvmx_helper_loop_enable(int interface)
7465 +++ b/drivers/staging/octeon/cvmx-helper-loop.h
7467 +/***********************license start***************
7468 + * Author: Cavium Networks
7470 + * Contact: support@caviumnetworks.com
7471 + * This file is part of the OCTEON SDK
7473 + * Copyright (c) 2003-2008 Cavium Networks
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.
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.
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/.
7489 + * This file may also be available under a different license from Cavium.
7490 + * Contact Cavium Networks for more information
7491 + ***********************license end**************************************/
7496 + * Functions for LOOP initialization, configuration,
7500 +#ifndef __CVMX_HELPER_LOOP_H__
7501 +#define __CVMX_HELPER_LOOP_H__
7504 + * Probe a LOOP interface and determine the number of ports
7505 + * connected to it. The LOOP interface should still be down after
7508 + * @interface: Interface to probe
7510 + * Returns Number of ports on the interface. Zero to disable.
7512 +extern int __cvmx_helper_loop_probe(int interface);
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.
7519 + * @interface: Interface to bring up
7521 + * Returns Zero on success, negative on failure
7523 +extern int __cvmx_helper_loop_enable(int interface);
7527 +++ b/drivers/staging/octeon/cvmx-helper-npi.c
7529 +/***********************license start***************
7530 + * Author: Cavium Networks
7532 + * Contact: support@caviumnetworks.com
7533 + * This file is part of the OCTEON SDK
7535 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
7552 + * This file may also be available under a different license from Cavium.
7553 + * Contact Cavium Networks for more information
7554 + ***********************license end**************************************/
7557 + * Functions for NPI initialization, configuration,
7560 +#include <asm/octeon/octeon.h>
7562 +#include "cvmx-config.h"
7564 +#include "cvmx-helper.h"
7566 +#include "cvmx-pip-defs.h"
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.
7573 + * @interface: Interface to probe
7575 + * Returns Number of ports on the interface. Zero to disable.
7577 +int __cvmx_helper_npi_probe(int interface)
7579 +#if CVMX_PKO_QUEUES_PER_PORT_PCI > 0
7580 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
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 */
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 */
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.
7596 + else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7597 + || OCTEON_IS_MODEL(OCTEON_CN50XX))
7599 + else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
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.
7611 + * @interface: Interface to bring up
7613 + * Returns Zero on success, negative on failure
7615 +int __cvmx_helper_npi_enable(int interface)
7618 + * On CN50XX, CN52XX, and CN56XX we need to disable length
7619 + * checking so packet < 64 bytes and jumbo frames don't get
7622 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
7623 + !OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7624 + int num_ports = cvmx_helper_ports_on_interface(interface);
7626 + for (port = 0; port < num_ports; port++) {
7627 + union cvmx_pip_prt_cfgx port_cfg;
7629 + cvmx_helper_get_ipd_port(interface, port);
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),
7639 + /* Enables are controlled by the remote host, so nothing to do here */
7643 +++ b/drivers/staging/octeon/cvmx-helper-npi.h
7645 +/***********************license start***************
7646 + * Author: Cavium Networks
7648 + * Contact: support@caviumnetworks.com
7649 + * This file is part of the OCTEON SDK
7651 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
7668 + * This file may also be available under a different license from Cavium.
7669 + * Contact Cavium Networks for more information
7670 + ***********************license end**************************************/
7675 + * Functions for NPI initialization, configuration,
7679 +#ifndef __CVMX_HELPER_NPI_H__
7680 +#define __CVMX_HELPER_NPI_H__
7683 + * Probe a NPI interface and determine the number of ports
7684 + * connected to it. The NPI interface should still be down after
7687 + * @interface: Interface to probe
7689 + * Returns Number of ports on the interface. Zero to disable.
7691 +extern int __cvmx_helper_npi_probe(int interface);
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.
7698 + * @interface: Interface to bring up
7700 + * Returns Zero on success, negative on failure
7702 +extern int __cvmx_helper_npi_enable(int interface);
7706 +++ b/drivers/staging/octeon/cvmx-helper-rgmii.c
7708 +/***********************license start***************
7709 + * Author: Cavium Networks
7711 + * Contact: support@caviumnetworks.com
7712 + * This file is part of the OCTEON SDK
7714 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
7731 + * This file may also be available under a different license from Cavium.
7732 + * Contact Cavium Networks for more information
7733 + ***********************license end**************************************/
7736 + * Functions for RGMII/GMII/MII initialization, configuration,
7739 +#include <asm/octeon/octeon.h>
7741 +#include "cvmx-config.h"
7744 +#include "cvmx-mdio.h"
7745 +#include "cvmx-pko.h"
7746 +#include "cvmx-helper.h"
7747 +#include "cvmx-helper-board.h"
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"
7754 +void __cvmx_interrupt_gmxx_enable(int interface);
7755 +void __cvmx_interrupt_asxx_enable(int block);
7758 + * Probe RGMII ports and determine the number present
7760 + * @interface: Interface to probe
7762 + * Returns Number of RGMII/GMII/MII ports (0-4).
7764 +int __cvmx_helper_rgmii_probe(int interface)
7766 + int num_ports = 0;
7767 + union cvmx_gmxx_inf_mode mode;
7768 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
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)) {
7779 + * On these chips "type" says we're in
7780 + * GMII/MII mode. This limits us to 2 ports
7784 + cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
7788 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
7789 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7791 + } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7792 + || OCTEON_IS_MODEL(OCTEON_CN30XX)
7793 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7796 + cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
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.
7808 + * @port: IPD port number to loop.
7810 +void cvmx_helper_rgmii_internal_loopback(int port)
7812 + int interface = (port >> 4) & 1;
7813 + int index = port & 0xf;
7816 + union cvmx_gmxx_prtx_cfg gmx_cfg;
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);
7832 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
7836 + * Workaround ASX setup errata with CN38XX pass1
7838 + * @interface: Interface to setup
7839 + * @port: Port to setup (0..3)
7841 + * Chip frequency in Hertz
7843 + * Returns Zero on success, negative on failure
7845 +static int __cvmx_helper_errata_asx_pass1(int interface, int port,
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);
7858 + cvmx_dprintf("Illegal clock frequency (%d). "
7859 + "CVMX_ASXX_TX_HI_WATERX not set\n", cpu_clock_hz);
7864 + * Configure all of the ASX, GMX, and PKO regsiters required
7865 + * to get RGMII to function on the supplied interface.
7867 + * @interface: PKO Interface to configure (0 or 1)
7869 + * Returns Zero on success
7871 +int __cvmx_helper_rgmii_enable(int interface)
7873 + int num_ports = cvmx_helper_ports_on_interface(interface);
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;
7880 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
7882 + if (mode.s.en == 0)
7884 + if ((OCTEON_IS_MODEL(OCTEON_CN38XX) ||
7885 + OCTEON_IS_MODEL(OCTEON_CN58XX)) && mode.s.type == 1)
7886 + /* Ignore SPI interfaces */
7889 + /* Configure the ASX registers needed to use the RGMII ports */
7891 + asx_tx.s.prt_en = cvmx_build_mask(num_ports);
7892 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), asx_tx.u64);
7895 + asx_rx.s.prt_en = cvmx_build_mask(num_ports);
7896 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), asx_rx.u64);
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() */
7903 + if (cvmx_octeon_is_pass1())
7904 + __cvmx_helper_errata_asx_pass1(interface, port,
7909 + * Configure more flexible RGMII preamble
7910 + * checking. Pass 1 doesn't support this
7913 + union cvmx_gmxx_rxx_frm_ctl frm_ctl;
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),
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
7930 + cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_TIME(port, interface),
7932 + cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL
7933 + (port, interface), 19000);
7935 + if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7936 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
7938 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
7941 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
7943 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
7948 + __cvmx_helper_setup_gmx(interface, num_ports);
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));
7956 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(port, interface));
7958 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(port, interface),
7961 + __cvmx_interrupt_asxx_enable(interface);
7962 + __cvmx_interrupt_gmxx_enable(interface);
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().
7973 + * @ipd_port: IPD/PKO port to query
7975 + * Returns Link state
7977 +cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port)
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;
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;
7988 + result.s.full_duplex = 1;
7989 + result.s.link_up = 1;
7990 + result.s.speed = 1000;
7993 + return __cvmx_helper_board_link_get(ipd_port);
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.
8003 + * @ipd_port: IPD/PKO port to configure
8004 + * @link_info: The new link state
8006 + * Returns Zero on success, negative on failure
8008 +int __cvmx_helper_rgmii_link_set(int ipd_port,
8009 + cvmx_helper_link_info_t link_info)
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;
8022 + /* Ignore speed sets in the simulator */
8023 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
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;
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)) &
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);
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));
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
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,
8067 + CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 0xf,
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));
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;
8083 + new_gmx_cfg.s.duplex = link_info.s.full_duplex;
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;
8093 + new_gmx_cfg.s.slottime = 1;
8094 + new_gmx_cfg.s.speed = 1;
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);
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);
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));
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].
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);
8137 + /* Do a read to make sure all setup stuff is complete */
8138 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8140 + /* Save the new GMX setting without enabling the port */
8141 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
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 <<
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);
8156 + /* Restore backpressure */
8157 + cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp_save.u64);
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);
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.
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
8177 + * Returns Zero on success, negative on failure.
8179 +int __cvmx_helper_rgmii_configure_loopback(int ipd_port, int enable_internal,
8180 + int enable_external)
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;
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 */
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);
8202 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
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;
8209 + asxx_prt_loop.s.int_loop &= ~(1 << index);
8210 + if (enable_external)
8211 + asxx_prt_loop.s.ext_loop |= 1 << index;
8213 + asxx_prt_loop.s.ext_loop &= ~(1 << index);
8214 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), asxx_prt_loop.u64);
8216 + /* Force enables in internal loopback */
8217 + if (enable_internal) {
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;
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);
8234 +++ b/drivers/staging/octeon/cvmx-helper-rgmii.h
8236 +/***********************license start***************
8237 + * Author: Cavium Networks
8239 + * Contact: support@caviumnetworks.com
8240 + * This file is part of the OCTEON SDK
8242 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
8259 + * This file may also be available under a different license from Cavium.
8260 + * Contact Cavium Networks for more information
8261 + ***********************license end**************************************/
8266 + * Functions for RGMII/GMII/MII initialization, configuration,
8270 +#ifndef __CVMX_HELPER_RGMII_H__
8271 +#define __CVMX_HELPER_RGMII_H__
8274 + * Probe RGMII ports and determine the number present
8276 + * @interface: Interface to probe
8278 + * Returns Number of RGMII/GMII/MII ports (0-4).
8280 +extern int __cvmx_helper_rgmii_probe(int interface);
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.
8287 + * @port: IPD port number to loop.
8289 +extern void cvmx_helper_rgmii_internal_loopback(int port);
8292 + * Configure all of the ASX, GMX, and PKO regsiters required
8293 + * to get RGMII to function on the supplied interface.
8295 + * @interface: PKO Interface to configure (0 or 1)
8297 + * Returns Zero on success
8299 +extern int __cvmx_helper_rgmii_enable(int interface);
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().
8307 + * @ipd_port: IPD/PKO port to query
8309 + * Returns Link state
8311 +extern cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port);
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.
8320 + * @ipd_port: IPD/PKO port to configure
8321 + * @link_info: The new link state
8323 + * Returns Zero on success, negative on failure
8325 +extern int __cvmx_helper_rgmii_link_set(int ipd_port,
8326 + cvmx_helper_link_info_t link_info);
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.
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
8339 + * Returns Zero on success, negative on failure.
8341 +extern int __cvmx_helper_rgmii_configure_loopback(int ipd_port,
8342 + int enable_internal,
8343 + int enable_external);
8347 +++ b/drivers/staging/octeon/cvmx-helper-sgmii.c
8349 +/***********************license start***************
8350 + * Author: Cavium Networks
8352 + * Contact: support@caviumnetworks.com
8353 + * This file is part of the OCTEON SDK
8355 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
8372 + * This file may also be available under a different license from Cavium.
8373 + * Contact Cavium Networks for more information
8374 + ***********************license end**************************************/
8377 + * Functions for SGMII initialization, configuration,
8381 +#include <asm/octeon/octeon.h>
8383 +#include "cvmx-config.h"
8385 +#include "cvmx-mdio.h"
8386 +#include "cvmx-helper.h"
8387 +#include "cvmx-helper-board.h"
8389 +#include "cvmx-gmxx-defs.h"
8390 +#include "cvmx-pcsx-defs.h"
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);
8397 + * Perform initialization required only once for an SGMII port.
8399 + * @interface: Interface to init
8400 + * @index: Index of prot on the interface
8402 + * Returns Zero on success, negative on failure
8404 +static int __cvmx_helper_sgmii_hardware_init_one_time(int interface, int index)
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;
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);
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.
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) {
8427 + pcsx_linkx_timer_count_reg.s.count =
8428 + (10000ull * clock_mhz) >> 10;
8431 + pcsx_linkx_timer_count_reg.s.count =
8432 + (1600ull * clock_mhz) >> 10;
8434 + cvmx_write_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface),
8435 + pcsx_linkx_timer_count_reg.u64);
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.
8446 + if (pcs_misc_ctl_reg.s.mode) {
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);
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) {
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);
8474 + /* MAC Mode - Nothing to do */
8481 + * Initialize the SERTES link for the first time or after a loss
8484 + * @interface: Interface to init
8485 + * @index: Index of prot on the interface
8487 + * Returns Zero on success, negative on failure
8489 +static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index)
8491 + union cvmx_pcsx_mrx_control_reg control_reg;
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
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),
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);
8518 + * Write PCS*_MR*_CONTROL_REG[RST_AN]=1 to ensure a fresh
8519 + * sgmii negotiation starts.
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),
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
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,
8537 + /* cvmx_dprintf("SGMII%d: Port %d link timeout\n", interface, index); */
8544 + * Configure an SGMII link to the specified speed after the SERTES
8547 + * @interface: Interface to init
8548 + * @index: Index of prot on the interface
8549 + * @link_info: Link state to configure
8551 + * Returns Zero on success, negative on failure
8553 +static int __cvmx_helper_sgmii_hardware_init_link_speed(int interface,
8555 + cvmx_helper_link_info_t
8559 + union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8560 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
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);
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,
8576 + ("SGMII%d: Timeout waiting for port %d to be idle\n",
8577 + interface, index);
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));
8585 + * Get the misc control for PCS. We will need to set the
8586 + * duplication amount.
8588 + pcsx_miscx_ctl_reg.u64 =
8589 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8592 + * Use GMXENO to force the link down if the status we get says
8593 + * it should be down.
8595 + pcsx_miscx_ctl_reg.s.gmxeno = !link_info.s.link_up;
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;
8601 + /* Do speed based setting for GMX */
8602 + switch (link_info.s.speed) {
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);
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);
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);
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);
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);
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));
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);
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.
8654 + * @interface: Interface to bringup
8655 + * @num_ports: Number of ports on the interface
8657 + * Returns Zero on success, negative on failure
8659 +static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
8663 + __cvmx_helper_setup_gmx(interface, num_ports);
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
8678 + * Probe a SGMII interface and determine the number of ports
8679 + * connected to it. The SGMII interface should still be down after
8682 + * @interface: Interface to probe
8684 + * Returns Number of ports on the interface. Zero to disable.
8686 +int __cvmx_helper_sgmii_probe(int interface)
8688 + union cvmx_gmxx_inf_mode mode;
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
8695 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
8697 + cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
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.
8706 + * @interface: Interface to bring up
8708 + * Returns Zero on success, negative on failure
8710 +int __cvmx_helper_sgmii_enable(int interface)
8712 + int num_ports = cvmx_helper_ports_on_interface(interface);
8715 + __cvmx_helper_sgmii_hardware_init(interface, num_ports);
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);
8726 + __cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
8727 + __cvmx_interrupt_gmxx_enable(interface);
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().
8737 + * @ipd_port: IPD/PKO port to query
8739 + * Returns Link state
8741 +cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port)
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;
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;
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;
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) {
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) {
8780 + union cvmx_pcsx_mrx_status_reg pcsx_mrx_status_reg;
8781 + union cvmx_pcsx_anx_results_reg pcsx_anx_results_reg;
8784 + * Don't bother continuing if the SERTES low
8785 + * level link is down
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)
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) {
8802 + * Auto negotiation is complete. Set
8803 + * status accordingly.
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) {
8811 + result.s.speed = 10;
8814 + result.s.speed = 100;
8817 + result.s.speed = 1000;
8820 + result.s.speed = 0;
8821 + result.s.link_up = 0;
8826 + * Auto negotiation isn't
8827 + * complete. Return link down.
8829 + result.s.speed = 0;
8830 + result.s.link_up = 0;
8832 + } else { /* MAC Mode */
8834 + result = __cvmx_helper_board_link_get(ipd_port);
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.
8847 + * @ipd_port: IPD/PKO port to configure
8848 + * @link_info: The new link state
8850 + * Returns Zero on success, negative on failure
8852 +int __cvmx_helper_sgmii_link_set(int ipd_port,
8853 + cvmx_helper_link_info_t link_info)
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,
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
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
8874 + * Returns Zero on success, negative on failure.
8876 +int __cvmx_helper_sgmii_configure_loopback(int ipd_port, int enable_internal,
8877 + int enable_external)
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;
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);
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);
8896 + __cvmx_helper_sgmii_hardware_init_link(interface, index);
8900 +++ b/drivers/staging/octeon/cvmx-helper-sgmii.h
8902 +/***********************license start***************
8903 + * Author: Cavium Networks
8905 + * Contact: support@caviumnetworks.com
8906 + * This file is part of the OCTEON SDK
8908 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
8925 + * This file may also be available under a different license from Cavium.
8926 + * Contact Cavium Networks for more information
8927 + ***********************license end**************************************/
8932 + * Functions for SGMII initialization, configuration,
8936 +#ifndef __CVMX_HELPER_SGMII_H__
8937 +#define __CVMX_HELPER_SGMII_H__
8940 + * Probe a SGMII interface and determine the number of ports
8941 + * connected to it. The SGMII interface should still be down after
8944 + * @interface: Interface to probe
8946 + * Returns Number of ports on the interface. Zero to disable.
8948 +extern int __cvmx_helper_sgmii_probe(int interface);
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.
8955 + * @interface: Interface to bring up
8957 + * Returns Zero on success, negative on failure
8959 +extern int __cvmx_helper_sgmii_enable(int interface);
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().
8967 + * @ipd_port: IPD/PKO port to query
8969 + * Returns Link state
8971 +extern cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port);
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.
8980 + * @ipd_port: IPD/PKO port to configure
8981 + * @link_info: The new link state
8983 + * Returns Zero on success, negative on failure
8985 +extern int __cvmx_helper_sgmii_link_set(int ipd_port,
8986 + cvmx_helper_link_info_t link_info);
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.
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
8999 + * Returns Zero on success, negative on failure.
9001 +extern int __cvmx_helper_sgmii_configure_loopback(int ipd_port,
9002 + int enable_internal,
9003 + int enable_external);
9007 +++ b/drivers/staging/octeon/cvmx-helper-spi.c
9009 +/***********************license start***************
9010 + * Author: Cavium Networks
9012 + * Contact: support@caviumnetworks.com
9013 + * This file is part of the OCTEON SDK
9015 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
9032 + * This file may also be available under a different license from Cavium.
9033 + * Contact Cavium Networks for more information
9034 + ***********************license end**************************************/
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);
9041 + * Functions for SPI initialization, configuration,
9044 +#include <asm/octeon/octeon.h>
9046 +#include "cvmx-config.h"
9047 +#include "cvmx-spi.h"
9048 +#include "cvmx-helper.h"
9050 +#include "cvmx-pip-defs.h"
9051 +#include "cvmx-pko-defs.h"
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.
9058 +#ifndef CVMX_HELPER_SPI_TIMEOUT
9059 +#define CVMX_HELPER_SPI_TIMEOUT 10
9063 + * Probe a SPI interface and determine the number of ports
9064 + * connected to it. The SPI interface should still be down after
9067 + * @interface: Interface to probe
9069 + * Returns Number of ports on the interface. Zero to disable.
9071 +int __cvmx_helper_spi_probe(int interface)
9073 + int num_ports = 0;
9075 + if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
9076 + cvmx_spi4000_is_present(interface)) {
9079 + union cvmx_pko_reg_crc_enable enable;
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
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);
9091 + __cvmx_helper_setup_gmx(interface, num_ports);
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
9100 + * @interface: Interface to bring up
9102 + * Returns Zero on success, negative on failure
9104 +int __cvmx_helper_spi_enable(int interface)
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.
9111 + int num_ports = cvmx_helper_ports_on_interface(interface);
9113 + for (ipd_port = interface * 16; ipd_port < interface * 16 + num_ports;
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);
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);
9127 + __cvmx_interrupt_spxx_int_msk_enable(interface);
9128 + __cvmx_interrupt_stxx_int_msk_enable(interface);
9129 + __cvmx_interrupt_gmxx_enable(interface);
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().
9139 + * @ipd_port: IPD/PKO port to query
9141 + * Returns Link state
9143 +cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port)
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);
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;
9164 + case 1: /* 100 Mbps */
9165 + result.s.speed = 100;
9167 + case 2: /* 1 Gbps */
9168 + result.s.speed = 1000;
9170 + case 3: /* Illegal */
9171 + result.s.speed = 0;
9172 + result.s.link_up = 0;
9176 + /* For generic SPI we can't determine the link, just return some
9178 + result.s.link_up = 1;
9179 + result.s.full_duplex = 1;
9180 + result.s.speed = 10000;
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.
9192 + * @ipd_port: IPD/PKO port to configure
9193 + * @link_info: The new link state
9195 + * Returns Zero on success, negative on failure
9197 +int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
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
9205 +++ b/drivers/staging/octeon/cvmx-helper-spi.h
9207 +/***********************license start***************
9208 + * Author: Cavium Networks
9210 + * Contact: support@caviumnetworks.com
9211 + * This file is part of the OCTEON SDK
9213 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
9230 + * This file may also be available under a different license from Cavium.
9231 + * Contact Cavium Networks for more information
9232 + ***********************license end**************************************/
9235 + * Functions for SPI initialization, configuration,
9238 +#ifndef __CVMX_HELPER_SPI_H__
9239 +#define __CVMX_HELPER_SPI_H__
9242 + * Probe a SPI interface and determine the number of ports
9243 + * connected to it. The SPI interface should still be down after
9246 + * @interface: Interface to probe
9248 + * Returns Number of ports on the interface. Zero to disable.
9250 +extern int __cvmx_helper_spi_probe(int interface);
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
9257 + * @interface: Interface to bring up
9259 + * Returns Zero on success, negative on failure
9261 +extern int __cvmx_helper_spi_enable(int interface);
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().
9269 + * @ipd_port: IPD/PKO port to query
9271 + * Returns Link state
9273 +extern cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port);
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.
9282 + * @ipd_port: IPD/PKO port to configure
9283 + * @link_info: The new link state
9285 + * Returns Zero on success, negative on failure
9287 +extern int __cvmx_helper_spi_link_set(int ipd_port,
9288 + cvmx_helper_link_info_t link_info);
9292 +++ b/drivers/staging/octeon/cvmx-helper-util.c
9294 +/***********************license start***************
9295 + * Author: Cavium Networks
9297 + * Contact: support@caviumnetworks.com
9298 + * This file is part of the OCTEON SDK
9300 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
9317 + * This file may also be available under a different license from Cavium.
9318 + * Contact Cavium Networks for more information
9319 + ***********************license end**************************************/
9322 + * Small helper utilities.
9324 +#include <linux/kernel.h>
9326 +#include <asm/octeon/octeon.h>
9328 +#include "cvmx-config.h"
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"
9336 +#include "cvmx-helper.h"
9337 +#include "cvmx-helper-util.h"
9339 +#include <asm/octeon/cvmx-ipd-defs.h>
9342 + * Convert a interface mode into a human readable string
9344 + * @mode: Mode to convert
9348 +const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t
9352 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
9353 + return "DISABLED";
9354 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
9356 + case CVMX_HELPER_INTERFACE_MODE_GMII:
9358 + case CVMX_HELPER_INTERFACE_MODE_SPI:
9360 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
9362 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
9364 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
9366 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
9368 + case CVMX_HELPER_INTERFACE_MODE_NPI:
9370 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
9377 + * Debug routine to dump the packet structure to the console
9379 + * @work: Work queue entry containing the packet to dump
9382 +int cvmx_helper_dump_packet(cvmx_wqe_t *work)
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;
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);
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;
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].
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;
9422 + buffer_ptr = work->packet_ptr;
9423 + remaining_bytes = work->len;
9425 + while (remaining_bytes) {
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);
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;
9441 + while (data_address < end_of_data) {
9442 + if (remaining_bytes == 0)
9445 + remaining_bytes--;
9446 + cvmx_dprintf("%02x", (unsigned int)*data_address);
9448 + if (remaining_bytes && (count == 7)) {
9449 + cvmx_dprintf("\n\t\t");
9454 + cvmx_dprintf("\n");
9456 + if (remaining_bytes)
9457 + buffer_ptr = *(union cvmx_buf_ptr *)
9458 + cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9464 + * Setup Random Early Drop on a specific input queue
9466 + * @queue: Input queue to setup RED on (0-7)
9468 + * Packets will begin slowly dropping when there are less than
9469 + * this many packet buffers free in FPA 0.
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
9475 +int cvmx_helper_setup_red_queue(int queue, int pass_thresh, int drop_thresh)
9477 + union cvmx_ipd_qosx_red_marks red_marks;
9478 + union cvmx_ipd_red_quex_param red_param;
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
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);
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);
9500 + * Setup Random Early Drop to automatically begin dropping packets.
9503 + * Packets will begin slowly dropping when there are less than
9504 + * this many packet buffers free in FPA 0.
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
9510 +int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
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;
9519 + /* Disable backpressure based on queued buffers. It needs SW support */
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),
9530 + for (queue = 0; queue < 8; queue++)
9531 + cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh);
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);
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);
9549 + * Setup the common GMX settings that determine the number of
9550 + * ports. These setting apply to almost all configurations of all
9553 + * @interface: Interface to configure
9554 + * @num_ports: Number of ports on the interface
9556 + * Returns Zero on success, negative on failure
9558 +int __cvmx_helper_setup_gmx(int interface, int num_ports)
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;
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);
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 "
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);
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;
9607 + pko_mode.s.mode0 = 0;
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;
9618 + pko_mode.s.mode1 = 0;
9620 + cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64);
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
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;
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;
9642 + gmx_tx_thresh.s.cnt = 0x100 / 4;
9645 + * SPI and XAUI can have lots of ports but the GMX hardware
9646 + * only ever has a max of 4.
9648 + if (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);
9658 + * Returns the IPD/PKO port number for a port on teh given
9661 + * @interface: Interface to use
9662 + * @port: Port on the interface
9664 + * Returns IPD/PKO port number
9666 +int cvmx_helper_get_ipd_port(int interface, int port)
9668 + switch (interface) {
9682 + * Returns the interface number for an IPD/PKO port number.
9684 + * @ipd_port: IPD/PKO port number
9686 + * Returns Interface number
9688 +int cvmx_helper_get_interface_num(int ipd_port)
9690 + if (ipd_port < 16)
9692 + else if (ipd_port < 32)
9694 + else if (ipd_port < 36)
9696 + else if (ipd_port < 40)
9699 + cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "
9706 + * Returns the interface index number for an IPD/PKO port
9709 + * @ipd_port: IPD/PKO port number
9711 + * Returns Interface index number
9713 +int cvmx_helper_get_interface_index_num(int ipd_port)
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;
9722 + cvmx_dprintf("cvmx_helper_get_interface_index_num: "
9723 + "Illegal IPD port number\n");
9728 +++ b/drivers/staging/octeon/cvmx-helper-util.h
9730 +/***********************license start***************
9731 + * Author: Cavium Networks
9733 + * Contact: support@caviumnetworks.com
9734 + * This file is part of the OCTEON SDK
9736 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
9753 + * This file may also be available under a different license from Cavium.
9754 + * Contact Cavium Networks for more information
9755 + ***********************license end**************************************/
9759 + * Small helper utilities.
9763 +#ifndef __CVMX_HELPER_UTIL_H__
9764 +#define __CVMX_HELPER_UTIL_H__
9767 + * Convert a interface mode into a human readable string
9769 + * @mode: Mode to convert
9774 + *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode);
9777 + * Debug routine to dump the packet structure to the console
9779 + * @work: Work queue entry containing the packet to dump
9782 +extern int cvmx_helper_dump_packet(cvmx_wqe_t *work);
9785 + * Setup Random Early Drop on a specific input queue
9787 + * @queue: Input queue to setup RED on (0-7)
9789 + * Packets will begin slowly dropping when there are less than
9790 + * this many packet buffers free in FPA 0.
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
9796 +extern int cvmx_helper_setup_red_queue(int queue, int pass_thresh,
9800 + * Setup Random Early Drop to automatically begin dropping packets.
9803 + * Packets will begin slowly dropping when there are less than
9804 + * this many packet buffers free in FPA 0.
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
9810 +extern int cvmx_helper_setup_red(int pass_thresh, int drop_thresh);
9813 + * Get the version of the CVMX libraries.
9815 + * Returns Version string. Note this buffer is allocated statically
9816 + * and will be shared by all callers.
9818 +extern const char *cvmx_helper_get_version(void);
9821 + * Setup the common GMX settings that determine the number of
9822 + * ports. These setting apply to almost all configurations of all
9825 + * @interface: Interface to configure
9826 + * @num_ports: Number of ports on the interface
9828 + * Returns Zero on success, negative on failure
9830 +extern int __cvmx_helper_setup_gmx(int interface, int num_ports);
9833 + * Returns the IPD/PKO port number for a port on the given
9836 + * @interface: Interface to use
9837 + * @port: Port on the interface
9839 + * Returns IPD/PKO port number
9841 +extern int cvmx_helper_get_ipd_port(int interface, int port);
9844 + * Returns the IPD/PKO port number for the first port on the given
9847 + * @interface: Interface to use
9849 + * Returns IPD/PKO port number
9851 +static inline int cvmx_helper_get_first_ipd_port(int interface)
9853 + return cvmx_helper_get_ipd_port(interface, 0);
9857 + * Returns the IPD/PKO port number for the last port on the given
9860 + * @interface: Interface to use
9862 + * Returns IPD/PKO port number
9864 +static inline int cvmx_helper_get_last_ipd_port(int interface)
9866 + extern int cvmx_helper_ports_on_interface(int interface);
9868 + return cvmx_helper_get_first_ipd_port(interface) +
9869 + cvmx_helper_ports_on_interface(interface) - 1;
9873 + * Free the packet buffers contained in a work queue entry.
9874 + * The work queue entry is not freed.
9876 + * @work: Work queue entry with packet to free
9878 +static inline void cvmx_helper_free_packet_data(cvmx_wqe_t *work)
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;
9885 + number_buffers = work->word2.s.bufs;
9886 + if (number_buffers == 0)
9888 + buffer_ptr = work->packet_ptr;
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
9898 + start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9899 + if (cvmx_ptr_to_phys(work) == start_of_buffer) {
9901 + *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9902 + buffer_ptr = next_buffer_ptr;
9906 + while (number_buffers--) {
9908 + * Remember the back pointer is in cache lines, not
9912 + ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9914 + * Read pointer to next buffer before we free the
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;
9926 + * Returns the interface number for an IPD/PKO port number.
9928 + * @ipd_port: IPD/PKO port number
9930 + * Returns Interface number
9932 +extern int cvmx_helper_get_interface_num(int ipd_port);
9935 + * Returns the interface index number for an IPD/PKO port
9938 + * @ipd_port: IPD/PKO port number
9940 + * Returns Interface index number
9942 +extern int cvmx_helper_get_interface_index_num(int ipd_port);
9944 +#endif /* __CVMX_HELPER_H__ */
9946 +++ b/drivers/staging/octeon/cvmx-helper-xaui.c
9948 +/***********************license start***************
9949 + * Author: Cavium Networks
9951 + * Contact: support@caviumnetworks.com
9952 + * This file is part of the OCTEON SDK
9954 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
9971 + * This file may also be available under a different license from Cavium.
9972 + * Contact Cavium Networks for more information
9973 + ***********************license end**************************************/
9976 + * Functions for XAUI initialization, configuration,
9981 +#include <asm/octeon/octeon.h>
9983 +#include "cvmx-config.h"
9985 +#include "cvmx-helper.h"
9987 +#include "cvmx-pko-defs.h"
9988 +#include "cvmx-gmxx-defs.h"
9989 +#include "cvmx-pcsxx-defs.h"
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);
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.
9999 + * @interface: Interface to probe
10001 + * Returns Number of ports on the interface. Zero to disable.
10003 +int __cvmx_helper_xaui_probe(int interface)
10006 + union cvmx_gmxx_hg2_control gmx_hg2_control;
10007 + union cvmx_gmxx_inf_mode mode;
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.
10014 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
10016 + cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
10018 + __cvmx_helper_setup_gmx(interface, 1);
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.
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;
10030 + * We set each PKO port to have equal priority in a
10031 + * round robin fashion.
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);
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)
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.
10054 + * @interface: Interface to bring up
10056 + * Returns Zero on success, negative on failure
10058 +int __cvmx_helper_xaui_enable(int interface)
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;
10068 + /* (1) Interface has already been enabled. */
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);
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);
10083 + /* (4) Bring up the PCSX and GMX reconciliation layer. */
10084 + /* (4)a Set polarity and lane swapping. */
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);
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);
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))
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))
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))
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);
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))
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))
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);
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)));
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))
10153 + if (CVMX_WAIT_FOR_FIELD64
10154 + (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
10155 + xmtflt, ==, 0, 10000))
10157 + if (CVMX_WAIT_FOR_FIELD64
10158 + (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
10159 + rcvflt, ==, 0, 10000))
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);
10166 + cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port(interface, 0));
10168 + /* (8) Enable packet reception */
10169 + xauiMiscCtl.s.gmxeno = 0;
10170 + cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
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);
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);
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().
10192 + * @ipd_port: IPD/PKO port to query
10194 + * Returns Link state
10196 +cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port)
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;
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));
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;
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);
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.
10232 + * @ipd_port: IPD/PKO port to configure
10233 + * @link_info: The new link state
10235 + * Returns Zero on success, negative on failure
10237 +int __cvmx_helper_xaui_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
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;
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));
10246 + /* If the link shouldn't be up, then just return */
10247 + if (!link_info.s.link_up)
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))
10254 + /* Bring the link up */
10255 + return __cvmx_helper_xaui_enable(interface);
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.
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
10269 + * Returns Zero on success, negative on failure.
10271 +extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
10272 + int enable_internal,
10273 + int enable_external)
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;
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);
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);
10293 + /* Take the link through a reset */
10294 + return __cvmx_helper_xaui_enable(interface);
10297 +++ b/drivers/staging/octeon/cvmx-helper-xaui.h
10299 +/***********************license start***************
10300 + * Author: Cavium Networks
10302 + * Contact: support@caviumnetworks.com
10303 + * This file is part of the OCTEON SDK
10305 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
10322 + * This file may also be available under a different license from Cavium.
10323 + * Contact Cavium Networks for more information
10324 + ***********************license end**************************************/
10329 + * Functions for XAUI initialization, configuration,
10330 + * and monitoring.
10333 +#ifndef __CVMX_HELPER_XAUI_H__
10334 +#define __CVMX_HELPER_XAUI_H__
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.
10341 + * @interface: Interface to probe
10343 + * Returns Number of ports on the interface. Zero to disable.
10345 +extern int __cvmx_helper_xaui_probe(int interface);
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.
10352 + * @interface: Interface to bring up
10354 + * Returns Zero on success, negative on failure
10356 +extern int __cvmx_helper_xaui_enable(int interface);
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().
10364 + * @ipd_port: IPD/PKO port to query
10366 + * Returns Link state
10368 +extern cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port);
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.
10377 + * @ipd_port: IPD/PKO port to configure
10378 + * @link_info: The new link state
10380 + * Returns Zero on success, negative on failure
10382 +extern int __cvmx_helper_xaui_link_set(int ipd_port,
10383 + cvmx_helper_link_info_t link_info);
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.
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
10396 + * Returns Zero on success, negative on failure.
10398 +extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
10399 + int enable_internal,
10400 + int enable_external);
10403 +++ b/drivers/staging/octeon/cvmx-helper.c
10405 +/***********************license start***************
10406 + * Author: Cavium Networks
10408 + * Contact: support@caviumnetworks.com
10409 + * This file is part of the OCTEON SDK
10411 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
10428 + * This file may also be available under a different license from Cavium.
10429 + * Contact Cavium Networks for more information
10430 + ***********************license end**************************************/
10434 + * Helper functions for common, but complicated tasks.
10437 +#include <asm/octeon/octeon.h>
10439 +#include "cvmx-config.h"
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"
10449 +#include "cvmx-pip-defs.h"
10450 +#include "cvmx-smix-defs.h"
10451 +#include "cvmx-asxx-defs.h"
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.
10460 +void (*cvmx_override_pko_queue_priority) (int pko_port,
10461 + uint64_t priorities[16]);
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.
10471 +void (*cvmx_override_ipd_port_setup) (int ipd_port);
10473 +/* Port count per interface */
10474 +static int interface_port_count[4] = { 0, 0, 0, 0 };
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];
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
10486 + * Returns Number of interfaces on chip
10488 +int cvmx_helper_get_number_of_interfaces(void)
10490 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
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.
10501 + * @interface: Interface to get the port count for
10503 + * Returns Number of ports on interface. Can be Zero.
10505 +int cvmx_helper_ports_on_interface(int interface)
10507 + return interface_port_count[interface];
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.
10515 + * @interface: Interface to probe
10517 + * Returns Mode of the interface. Unknown or unsupported interfaces return
10520 +cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
10522 + union cvmx_gmxx_inf_mode mode;
10523 + if (interface == 2)
10524 + return CVMX_HELPER_INTERFACE_MODE_NPI;
10526 + if (interface == 3) {
10527 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)
10528 + || OCTEON_IS_MODEL(OCTEON_CN52XX))
10529 + return CVMX_HELPER_INTERFACE_MODE_LOOP;
10531 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10534 + if (interface == 0
10535 + && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
10536 + && cvmx_sysinfo_get()->board_rev_major == 1) {
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.
10547 + return CVMX_HELPER_INTERFACE_MODE_GMII;
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;
10557 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
10559 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
10560 + switch (mode.cn56xx.mode) {
10562 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10564 + return CVMX_HELPER_INTERFACE_MODE_XAUI;
10566 + return CVMX_HELPER_INTERFACE_MODE_SGMII;
10568 + return CVMX_HELPER_INTERFACE_MODE_PICMG;
10570 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10574 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
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;
10581 + return CVMX_HELPER_INTERFACE_MODE_GMII;
10583 + return CVMX_HELPER_INTERFACE_MODE_RGMII;
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.
10593 + * @ipd_port: Port to configure. This follows the IPD numbering, not the
10594 + * per interface numbering
10596 + * Returns Zero on success, negative on failure
10598 +static int __cvmx_helper_port_setup_ipd(int ipd_port)
10600 + union cvmx_pip_prt_cfgx port_config;
10601 + union cvmx_pip_prt_tagx tag_config;
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));
10606 + /* Have each port go to a different POW queue */
10607 + port_config.s.qos = ipd_port & 0x7;
10609 + /* Process the headers and place the IP header in the work queue */
10610 + port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
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;
10631 + cvmx_pip_config_port(ipd_port, port_config, tag_config);
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);
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.
10647 + * @interface: Interface to probe
10649 + * Returns Zero on success, negative on failure
10651 +int cvmx_helper_interface_probe(int interface)
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;
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);
10668 + * RGMII/GMII/MII are all treated about the same. Most
10669 + * functions refer to these ports as RGMII.
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);
10677 + * SPI4 can have 1-16 ports depending on the device at
10680 + case CVMX_HELPER_INTERFACE_MODE_SPI:
10681 + interface_port_count[interface] =
10682 + __cvmx_helper_spi_probe(interface);
10685 + * SGMII can have 1-4 ports depending on how many are
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);
10693 + /* PCI target Network Packet Interface */
10694 + case CVMX_HELPER_INTERFACE_MODE_NPI:
10695 + interface_port_count[interface] =
10696 + __cvmx_helper_npi_probe(interface);
10699 + * Special loopback only ports. These are not the same
10700 + * as other ports in loopback mode.
10702 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
10703 + interface_port_count[interface] =
10704 + __cvmx_helper_loop_probe(interface);
10708 + interface_port_count[interface] =
10709 + __cvmx_helper_board_interface_probe(interface,
10710 + interface_port_count
10713 + /* Make sure all global variables propagate to other cores */
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.
10725 + * @interface: Interface to setup IPD/PIP for
10727 + * Returns Zero on success, negative on failure
10729 +static int __cvmx_helper_interface_setup_ipd(int interface)
10731 + int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
10732 + int num_ports = interface_port_count[interface];
10734 + while (num_ports--) {
10735 + __cvmx_helper_port_setup_ipd(ipd_port);
10742 + * Setup global setting for IPD/PIP not related to a specific
10743 + * interface or port. This must be called before IPD is enabled.
10745 + * Returns Zero on success, negative on failure.
10747 +static int __cvmx_helper_global_setup_ipd(void)
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);
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.
10768 + * @interface: Interface to setup PKO for
10770 + * Returns Zero on success, negative on failure
10772 +static int __cvmx_helper_interface_setup_pko(int interface)
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.
10786 + uint64_t priorities[16] =
10787 + { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
10790 + * Setup the IPD/PIP and PKO for the ports discovered
10791 + * above. Here packet classification, tagging and output
10792 + * priorities are set.
10794 + int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
10795 + int num_ports = interface_port_count[interface];
10796 + while (num_ports--) {
10798 + * Give the user a chance to override the per queue
10801 + if (cvmx_override_pko_queue_priority)
10802 + cvmx_override_pko_queue_priority(ipd_port, priorities);
10804 + cvmx_pko_config_port(ipd_port,
10805 + cvmx_pko_get_base_queue_per_core(ipd_port,
10807 + cvmx_pko_get_num_queues(ipd_port),
10815 + * Setup global setting for PKO not related to a specific
10816 + * interface or port. This must be called before PKO is enabled.
10818 + * Returns Zero on success, negative on failure.
10820 +static int __cvmx_helper_global_setup_pko(void)
10823 + * Disable tagwait FAU timeout. This needs to be done before
10824 + * anyone might start packet output using tags.
10826 + union cvmx_iob_fau_timeout fau_to;
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);
10835 + * Setup global backpressure setting.
10837 + * Returns Zero on success, negative on failure
10839 +static int __cvmx_helper_global_setup_backpressure(void)
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();
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:
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);
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.
10875 + * @interface: Interface to enable
10877 + * Returns Zero on success, negative on failure
10879 +static int __cvmx_helper_packet_hardware_enable(int interface)
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 */
10888 + /* XAUI is a single high speed port */
10889 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
10890 + result = __cvmx_helper_xaui_enable(interface);
10893 + * RGMII/GMII/MII are all treated about the same. Most
10894 + * functions refer to these ports as RGMII
10896 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
10897 + case CVMX_HELPER_INTERFACE_MODE_GMII:
10898 + result = __cvmx_helper_rgmii_enable(interface);
10901 + * SPI4 can have 1-16 ports depending on the device at
10904 + case CVMX_HELPER_INTERFACE_MODE_SPI:
10905 + result = __cvmx_helper_spi_enable(interface);
10908 + * SGMII can have 1-4 ports depending on how many are
10911 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
10912 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
10913 + result = __cvmx_helper_sgmii_enable(interface);
10915 + /* PCI target Network Packet Interface */
10916 + case CVMX_HELPER_INTERFACE_MODE_NPI:
10917 + result = __cvmx_helper_npi_enable(interface);
10920 + * Special loopback only ports. These are not the same
10921 + * as other ports in loopback mode
10923 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
10924 + result = __cvmx_helper_loop_enable(interface);
10927 + result |= __cvmx_helper_board_hardware_enable(interface);
10932 + * Function to adjust internal IPD pointer alignments
10934 + * Returns 0 on success
10937 +int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
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)
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;
10954 + int retry_loop_cnt;
10957 + cvmx_helper_link_info_t link_info;
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)));
10974 + /* Configure port to gig FDX as required for loopback mode */
10975 + cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
10978 + * Disable reception on all ports so if traffic is present it
10979 + * will not interfere.
10981 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
10983 + cvmx_wait(100000000ull);
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;
10991 + num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
10993 + if (num_segs == 0)
10994 + goto fix_ipd_exit;
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);
11003 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
11004 + 1 << INDEX(FIX_IPD_OUTPORT));
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;
11016 + g_buffer.s.pool = CVMX_FPA_WQE_POOL;
11017 + g_buffer.s.size = num_segs;
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;
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;
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;
11037 + for (i = 0; i < num_segs; i++) {
11039 + pkt_buffer.s.size =
11040 + FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
11042 + if (i == (num_segs - 1))
11043 + pkt_buffer.s.i = 0;
11045 + *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
11046 + 8 * i) = pkt_buffer.u64;
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;
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));
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);
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);
11092 + work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
11094 + } while ((work == NULL) && (retry_cnt > 0));
11097 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11098 + "get_work() timeout occured.\n");
11100 + /* Free packet */
11102 + cvmx_helper_free_packet_data(work);
11107 + /* Return CSR configs to saved values */
11108 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG
11109 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11111 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11113 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11115 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER
11116 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11118 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
11119 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
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);
11127 + * Bring the link back up as autonegotiation is not done in
11128 + * user applications.
11130 + cvmx_helper_link_autoconf(FIX_IPD_OUTPORT);
11134 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
11136 + return !!num_segs;
11141 + * Called after all internal packet IO paths are setup. This
11142 + * function enables IPD/PIP and begins packet input and output.
11144 + * Returns Zero on success, negative on failure
11146 +int cvmx_helper_ipd_and_packet_input_enable(void)
11148 + int num_interfaces;
11152 + cvmx_ipd_enable();
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
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);
11165 + /* Finally enable PKO now that the entire path is up and running */
11166 + cvmx_pko_enable();
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();
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.
11182 + * Returns Zero on success, non-zero on failure
11184 +int cvmx_helper_initialize_packet_io_global(void)
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();
11193 + * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to
11196 + if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
11197 + __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
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.
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);
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);
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);
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",
11233 + cvmx_helper_ports_on_interface(interface),
11234 + cvmx_helper_interface_mode_to_string
11235 + (cvmx_helper_interface_get_mode
11237 + result |= __cvmx_helper_interface_setup_ipd(interface);
11238 + result |= __cvmx_helper_interface_setup_pko(interface);
11241 + result |= __cvmx_helper_global_setup_ipd();
11242 + result |= __cvmx_helper_global_setup_pko();
11244 + /* Enable any flow control and backpressure */
11245 + result |= __cvmx_helper_global_setup_backpressure();
11247 +#if CVMX_HELPER_ENABLE_IPD
11248 + result |= cvmx_helper_ipd_and_packet_input_enable();
11254 + * Does core local initialization for packet io
11256 + * Returns Zero on success, non-zero on failure
11258 +int cvmx_helper_initialize_packet_io_local(void)
11260 + return cvmx_pko_initialize_local();
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));
11268 + * @ipd_port: IPD/PKO port to auto configure
11270 + * Returns Link state after configure
11272 +cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
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);
11278 + if (index >= cvmx_helper_ports_on_interface(interface)) {
11279 + link_info.u64 = 0;
11280 + return link_info;
11283 + link_info = cvmx_helper_link_get(ipd_port);
11284 + if (link_info.u64 == port_link_info[ipd_port].u64)
11285 + return link_info;
11287 + /* If we fail to set the link speed, port_link_info will not change */
11288 + cvmx_helper_link_set(ipd_port, link_info);
11291 + * port_link_info should be the current value, which will be
11292 + * different than expect if cvmx_helper_link_set() failed.
11294 + return port_link_info[ipd_port];
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().
11303 + * @ipd_port: IPD/PKO port to query
11305 + * Returns Link state
11307 +cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
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);
11313 + /* The default result will be a down link unless the code below
11317 + if (index >= cvmx_helper_ports_on_interface(interface))
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 */
11325 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11326 + result = __cvmx_helper_xaui_link_get(ipd_port);
11328 + case CVMX_HELPER_INTERFACE_MODE_GMII:
11330 + result = __cvmx_helper_rgmii_link_get(ipd_port);
11332 + result.s.full_duplex = 1;
11333 + result.s.link_up = 1;
11334 + result.s.speed = 1000;
11337 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
11338 + result = __cvmx_helper_rgmii_link_get(ipd_port);
11340 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11341 + result = __cvmx_helper_spi_link_get(ipd_port);
11343 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11344 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11345 + result = __cvmx_helper_sgmii_link_get(ipd_port);
11347 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11348 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
11349 + /* Network links are not supported */
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.
11362 + * @ipd_port: IPD/PKO port to configure
11363 + * @link_info: The new link state
11365 + * Returns Zero on success, negative on failure
11367 +int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
11370 + int interface = cvmx_helper_get_interface_num(ipd_port);
11371 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11373 + if (index >= cvmx_helper_ports_on_interface(interface))
11376 + switch (cvmx_helper_interface_get_mode(interface)) {
11377 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11378 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
11380 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11381 + result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
11384 + * RGMII/GMII/MII are all treated about the same. Most
11385 + * functions refer to these ports as RGMII.
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);
11391 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11392 + result = __cvmx_helper_spi_link_set(ipd_port, link_info);
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);
11398 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11399 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
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 */
11406 + port_link_info[ipd_port].u64 = link_info.u64;
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.
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
11421 + * Returns Zero on success, negative on failure.
11423 +int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
11424 + int enable_external)
11427 + int interface = cvmx_helper_get_interface_num(ipd_port);
11428 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11430 + if (index >= cvmx_helper_ports_on_interface(interface))
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:
11440 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11442 + __cvmx_helper_xaui_configure_loopback(ipd_port,
11444 + enable_external);
11446 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
11447 + case CVMX_HELPER_INTERFACE_MODE_GMII:
11449 + __cvmx_helper_rgmii_configure_loopback(ipd_port,
11451 + enable_external);
11453 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11454 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11456 + __cvmx_helper_sgmii_configure_loopback(ipd_port,
11458 + enable_external);
11464 +++ b/drivers/staging/octeon/cvmx-helper.h
11466 +/***********************license start***************
11467 + * Author: Cavium Networks
11469 + * Contact: support@caviumnetworks.com
11470 + * This file is part of the OCTEON SDK
11472 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
11489 + * This file may also be available under a different license from Cavium.
11490 + * Contact Cavium Networks for more information
11491 + ***********************license end**************************************/
11495 + * Helper functions for common, but complicated tasks.
11499 +#ifndef __CVMX_HELPER_H__
11500 +#define __CVMX_HELPER_H__
11502 +#include "cvmx-config.h"
11503 +#include "cvmx-fpa.h"
11504 +#include "cvmx-wqe.h"
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;
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 */
11527 +} cvmx_helper_link_info_t;
11529 +#include "cvmx-helper-fpa.h"
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"
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.
11547 +extern void (*cvmx_override_pko_queue_priority) (int pko_port,
11548 + uint64_t priorities[16]);
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.
11558 +extern void (*cvmx_override_ipd_port_setup) (int ipd_port);
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.
11567 + * Returns 0 on success
11570 +extern int cvmx_helper_ipd_and_packet_input_enable(void);
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.
11579 + * Returns Zero on success, non-zero on failure
11581 +extern int cvmx_helper_initialize_packet_io_global(void);
11584 + * Does core local initialization for packet io
11586 + * Returns Zero on success, non-zero on failure
11588 +extern int cvmx_helper_initialize_packet_io_local(void);
11591 + * Returns the number of ports on the given interface.
11592 + * The interface must be initialized before the port count
11593 + * can be returned.
11595 + * @interface: Which interface to return port count for.
11597 + * Returns Port count for interface
11598 + * -1 for uninitialized interface
11600 +extern int cvmx_helper_ports_on_interface(int interface);
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
11608 + * Returns Number of interfaces on chip
11610 +extern int cvmx_helper_get_number_of_interfaces(void);
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.
11617 + * @interface: Interface to probe
11619 + * Returns Mode of the interface. Unknown or unsupported interfaces return
11622 +extern cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int
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));
11630 + * @ipd_port: IPD/PKO port to auto configure
11632 + * Returns Link state after configure
11634 +extern cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port);
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().
11642 + * @ipd_port: IPD/PKO port to query
11644 + * Returns Link state
11646 +extern cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port);
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.
11655 + * @ipd_port: IPD/PKO port to configure
11656 + * @link_info: The new link state
11658 + * Returns Zero on success, negative on failure
11660 +extern int cvmx_helper_link_set(int ipd_port,
11661 + cvmx_helper_link_info_t link_info);
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.
11670 + * @interface: Interface to probe
11672 + * Returns Zero on success, negative on failure
11674 +extern int cvmx_helper_interface_probe(int interface);
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.
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
11687 + * Returns Zero on success, negative on failure.
11689 +extern int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
11690 + int enable_external);
11692 +#endif /* __CVMX_HELPER_H__ */
11694 +++ b/drivers/staging/octeon/cvmx-interrupt-decodes.c
11696 +/***********************license start***************
11697 + * Author: Cavium Networks
11699 + * Contact: support@caviumnetworks.com
11700 + * This file is part of the OCTEON SDK
11702 + * Copyright (c) 2003-2009 Cavium Networks
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.
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
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/.
11719 + * This file may also be available under a different license from Cavium.
11720 + * Contact Cavium Networks for more information
11721 + ***********************license end**************************************/
11725 + * Automatically generated functions useful for enabling
11726 + * and decoding RSL_INT_BLOCKS interrupts.
11730 +#include <asm/octeon/octeon.h>
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"
11738 +#ifndef PRINT_ERROR
11739 +#define PRINT_ERROR(format, ...)
11744 + * __cvmx_interrupt_gmxx_rxx_int_en_enable enables all interrupt bits in cvmx_gmxx_rxx_int_en_t
11746 +void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block)
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 */
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;
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 */
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;
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;
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;
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 */
11922 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, block), gmx_rx_int_en.u64);
11925 + * __cvmx_interrupt_pcsx_intx_en_reg_enable enables all interrupt bits in cvmx_pcsx_intx_en_reg_t
11927 +void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block)
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 */
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 */
11963 + cvmx_write_csr(CVMX_PCSX_INTX_EN_REG(index, block), pcs_int_en_reg.u64);
11966 + * __cvmx_interrupt_pcsxx_int_en_reg_enable enables all interrupt bits in cvmx_pcsxx_int_en_reg_t
11968 +void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index)
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;
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;
11992 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(index), pcsx_int_en_reg.u64);
11996 + * __cvmx_interrupt_spxx_int_msk_enable enables all interrupt bits in cvmx_spxx_int_msk_t
11998 +void __cvmx_interrupt_spxx_int_msk_enable(int index)
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;
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;
12032 + cvmx_write_csr(CVMX_SPXX_INT_MSK(index), spx_int_msk.u64);
12035 + * __cvmx_interrupt_stxx_int_msk_enable enables all interrupt bits in cvmx_stxx_int_msk_t
12037 +void __cvmx_interrupt_stxx_int_msk_enable(int index)
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;
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;
12065 + cvmx_write_csr(CVMX_STXX_INT_MSK(index), stx_int_msk.u64);
12068 +++ b/drivers/staging/octeon/cvmx-interrupt-rsl.c
12070 +/***********************license start***************
12071 + * Author: Cavium Networks
12073 + * Contact: support@caviumnetworks.com
12074 + * This file is part of the OCTEON SDK
12076 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
12093 + * This file may also be available under a different license from Cavium.
12094 + * Contact Cavium Networks for more information
12095 + ***********************license end**************************************/
12098 + * Utility functions to decode Octeon's RSL_INT_BLOCKS
12099 + * interrupts into error messages.
12102 +#include <asm/octeon/octeon.h>
12104 +#include "cvmx-asxx-defs.h"
12105 +#include "cvmx-gmxx-defs.h"
12107 +#ifndef PRINT_ERROR
12108 +#define PRINT_ERROR(format, ...)
12111 +void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block);
12114 + * Enable ASX error interrupts that exist on CN3XXX, CN50XX, and
12117 + * @block: Interface to enable 0-1
12119 +void __cvmx_interrupt_asxx_enable(int block)
12122 + union cvmx_asxx_int_en csr;
12124 + * CN38XX and CN58XX have two interfaces with 4 ports per
12125 + * interface. All other chips have a max of 3 ports on
12128 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
12129 + mask = 0xf; /* Set enables for 4 ports */
12131 + mask = 0x7; /* Set enables for 3 ports */
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);
12141 + * Enable GMX error reporting for the supplied interface
12143 + * @interface: Interface to enable
12145 +void __cvmx_interrupt_gmxx_enable(int interface)
12147 + union cvmx_gmxx_inf_mode mode;
12148 + union cvmx_gmxx_tx_int_en gmx_tx_int_en;
12152 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
12154 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
12156 + switch (mode.cn56xx.mode) {
12157 + case 1: /* XAUI */
12160 + case 2: /* SGMII */
12161 + case 3: /* PICMG */
12164 + default: /* Disabled */
12172 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
12173 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12175 + * SPI on CN38XX and CN58XX report all
12176 + * errors through port 0. RGMII needs
12177 + * to check all 4 ports
12185 + * CN30XX, CN31XX, and CN50XX have two
12186 + * or three ports. GMII and MII has 2,
12187 + * RGMII has three
12198 + gmx_tx_int_en.u64 = 0;
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;
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);
12211 +++ b/drivers/staging/octeon/cvmx-ipd.h
12213 +/***********************license start***************
12214 + * Author: Cavium Networks
12216 + * Contact: support@caviumnetworks.com
12217 + * This file is part of the OCTEON SDK
12219 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
12236 + * This file may also be available under a different license from Cavium.
12237 + * Contact Cavium Networks for more information
12238 + ***********************license end**************************************/
12242 + * Interface to the hardware Input Packet Data unit.
12245 +#ifndef __CVMX_IPD_H__
12246 +#define __CVMX_IPD_H__
12248 +#include <asm/octeon/octeon-feature.h>
12250 +#include <asm/octeon/cvmx-ipd-defs.h>
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 */
12259 +#ifndef CVMX_ENABLE_LEN_M8_FIX
12260 +#define CVMX_ENABLE_LEN_M8_FIX 0
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;
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;
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
12280 + * Must be same as not_first_mbuff_skip / 128
12282 + * FPA pool to get work entries from
12284 + * @back_pres_enable_flag:
12285 + * Enable or disable port back pressure
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)
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;
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);
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);
12313 + size.s.mb_size = mbuff_size;
12314 + cvmx_write_csr(CVMX_IPD_PACKET_MBUFF_SIZE, size.u64);
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);
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);
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);
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);
12333 + /* Note: the example RED code that used to be here has been moved to
12334 + cvmx_helper_setup_red */
12340 +static inline void cvmx_ipd_enable(void)
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) {
12346 + ("Warning: Enabling IPD when IPD already enabled.\n");
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;
12353 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
12359 +static inline void cvmx_ipd_disable(void)
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);
12368 + * Supportive function for cvmx_fpa_shutdown_pool.
12370 +static inline void cvmx_ipd_free_ptr(void)
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)) {
12376 + union cvmx_ipd_ptr_count ipd_ptr_count;
12377 + ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
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)
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);
12393 + cvmx_fpa_free(cvmx_phys_to_ptr
12394 + ((uint64_t) ipd_wqe_ptr_valid.s.
12395 + ptr << 7), CVMX_FPA_PACKET_POOL,
12398 + cvmx_fpa_free(cvmx_phys_to_ptr
12399 + ((uint64_t) ipd_wqe_ptr_valid.s.
12400 + ptr << 7), CVMX_FPA_WQE_POOL, 0);
12403 + /* Free all WQE in the fifo */
12404 + if (ipd_ptr_count.s.wqe_pcnt) {
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);
12420 + cvmx_fpa_free(cvmx_phys_to_ptr
12422 + ipd_pwp_ptr_fifo_ctl.s.
12424 + CVMX_FPA_PACKET_POOL, 0);
12426 + cvmx_fpa_free(cvmx_phys_to_ptr
12428 + ipd_pwp_ptr_fifo_ctl.s.
12430 + CVMX_FPA_WQE_POOL, 0);
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);
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);
12447 + /* Free the per port prefetched packets */
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);
12455 + for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
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 =
12464 + (CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
12465 + cvmx_fpa_free(cvmx_phys_to_ptr
12467 + ipd_prc_port_ptr_fifo_ctl.s.
12468 + ptr << 7), CVMX_FPA_PACKET_POOL,
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);
12476 + /* Free all packets in the holding fifo */
12477 + if (ipd_ptr_count.s.pfif_cnt) {
12479 + union cvmx_ipd_prc_hold_ptr_fifo_ctl
12480 + ipd_prc_hold_ptr_fifo_ctl;
12482 + ipd_prc_hold_ptr_fifo_ctl.u64 =
12483 + cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
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 =
12494 + (CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
12495 + cvmx_fpa_free(cvmx_phys_to_ptr
12497 + ipd_prc_hold_ptr_fifo_ctl.s.
12498 + ptr << 7), CVMX_FPA_PACKET_POOL,
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);
12506 + /* Free all packets in the fifo */
12507 + if (ipd_ptr_count.s.pkt_pcnt) {
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);
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.
12525 + CVMX_FPA_PACKET_POOL, 0);
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);
12532 + /* Reset the IPD to get all buffers out of it */
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);
12540 + /* Reset the PIP */
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);
12550 +#endif /* __CVMX_IPD_H__ */
12552 +++ b/drivers/staging/octeon/cvmx-mdio.h
12554 +/***********************license start***************
12555 + * Author: Cavium Networks
12557 + * Contact: support@caviumnetworks.com
12558 + * This file is part of the OCTEON SDK
12560 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
12577 + * This file may also be available under a different license from Cavium.
12578 + * Contact Cavium Networks for more information
12579 + ***********************license end**************************************/
12583 + * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3
12584 + * clause 22 and clause 45 operations.
12588 +#ifndef __CVMX_MIO_H__
12589 +#define __CVMX_MIO_H__
12591 +#include "cvmx-smix-defs.h"
12594 + * PHY register 0 from the 802.3 spec
12596 +#define CVMX_MDIO_PHY_REG_CONTROL 0
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;
12613 +} cvmx_mdio_phy_reg_control_t;
12616 + * PHY register 1 from the 802.3 spec
12618 +#define CVMX_MDIO_PHY_REG_STATUS 1
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;
12640 +} cvmx_mdio_phy_reg_status_t;
12643 + * PHY register 2 from the 802.3 spec
12645 +#define CVMX_MDIO_PHY_REG_ID1 2
12649 + uint16_t oui_bits_3_18;
12651 +} cvmx_mdio_phy_reg_id1_t;
12654 + * PHY register 3 from the 802.3 spec
12656 +#define CVMX_MDIO_PHY_REG_ID2 3
12660 + uint16_t oui_bits_19_24:6;
12661 + uint16_t model:6;
12662 + uint16_t revision:4;
12664 +} cvmx_mdio_phy_reg_id2_t;
12667 + * PHY register 4 from the 802.3 spec
12669 +#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4
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;
12686 +} cvmx_mdio_phy_reg_autoneg_adver_t;
12689 + * PHY register 5 from the 802.3 spec
12691 +#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5
12695 + uint16_t next_page: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;
12708 +} cvmx_mdio_phy_reg_link_partner_ability_t;
12711 + * PHY register 6 from the 802.3 spec
12713 +#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6
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;
12725 +} cvmx_mdio_phy_reg_autoneg_expansion_t;
12728 + * PHY register 9 from the 802.3 spec
12730 +#define CVMX_MDIO_PHY_REG_CONTROL_1000 9
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;
12742 +} cvmx_mdio_phy_reg_control_1000_t;
12745 + * PHY register 10 from the 802.3 spec
12747 +#define CVMX_MDIO_PHY_REG_STATUS_1000 10
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;
12760 +} cvmx_mdio_phy_reg_status_1000_t;
12763 + * PHY register 15 from the 802.3 spec
12765 +#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15
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;
12775 +} cvmx_mdio_phy_reg_extended_status_t;
12778 + * PHY register 13 from the 802.3 spec
12780 +#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13
12784 + uint16_t function:2;
12785 + uint16_t reserved_5_13:9;
12786 + uint16_t devad:5;
12788 +} cvmx_mdio_phy_reg_mmd_control_t;
12791 + * PHY register 14 from the 802.3 spec
12793 +#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14
12797 + uint16_t address_data:16;
12799 +} cvmx_mdio_phy_reg_mmd_address_data_t;
12801 +/* Operating request encodings. */
12802 +#define MDIO_CLAUSE_22_WRITE 0
12803 +#define MDIO_CLAUSE_22_READ 1
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
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
12821 +/* Helper function to put MDIO interface into clause 45 mode */
12822 +static inline void __cvmx_mdio_set_clause45_mode(int bus_id)
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);
12832 +/* Helper function to put MDIO interface into clause 22 mode */
12833 +static inline void __cvmx_mdio_set_clause22_mode(int bus_id)
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);
12843 + * Perform an MII read. This function is used to read PHY
12844 + * registers controlling auto negotiation.
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
12851 + * Returns Result from the read or -1 on failure
12853 +static inline int cvmx_mdio_read(int bus_id, int phy_id, int location)
12855 + union cvmx_smix_cmd smi_cmd;
12856 + union cvmx_smix_rd_dat smi_rd;
12857 + int timeout = 1000;
12859 + if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12860 + __cvmx_mdio_set_clause22_mode(bus_id);
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);
12870 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
12871 + } while (smi_rd.s.pending && timeout--);
12873 + if (smi_rd.s.val)
12874 + return smi_rd.s.dat;
12880 + * Perform an MII write. This function is used to write PHY
12881 + * registers controlling auto negotiation.
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
12889 + * Returns -1 on error
12892 +static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val)
12894 + union cvmx_smix_cmd smi_cmd;
12895 + union cvmx_smix_wr_dat smi_wr;
12896 + int timeout = 1000;
12898 + if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12899 + __cvmx_mdio_set_clause22_mode(bus_id);
12902 + smi_wr.s.dat = val;
12903 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
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);
12913 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
12914 + } while (smi_wr.s.pending && --timeout);
12915 + if (timeout <= 0)
12922 + * Perform an IEEE 802.3 clause 45 MII read. This function is used to
12923 + * read PHY registers controlling auto negotiation.
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
12931 + * Returns Result from the read or -1 on failure
12934 +static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
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;
12942 + if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12945 + __cvmx_mdio_set_clause45_mode(bus_id);
12948 + smi_wr.s.dat = location;
12949 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
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);
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);
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);
12976 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
12977 + } while (smi_rd.s.pending && timeout--);
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);
12986 + if (smi_rd.s.val)
12987 + return smi_rd.s.dat;
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);
12997 + * Perform an IEEE 802.3 clause 45 MII write. This function is used to
12998 + * write PHY registers controlling auto negotiation.
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
13007 + * Returns -1 on error
13010 +static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device,
13011 + int location, int val)
13013 + union cvmx_smix_cmd smi_cmd;
13014 + union cvmx_smix_wr_dat smi_wr;
13015 + int timeout = 1000;
13017 + if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
13020 + __cvmx_mdio_set_clause45_mode(bus_id);
13023 + smi_wr.s.dat = location;
13024 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
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);
13034 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13035 + } while (smi_wr.s.pending && --timeout);
13036 + if (timeout <= 0)
13040 + smi_wr.s.dat = val;
13041 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
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);
13051 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13052 + } while (smi_wr.s.pending && --timeout);
13053 + if (timeout <= 0)
13061 +++ b/drivers/staging/octeon/cvmx-packet.h
13063 +/***********************license start***************
13064 + * Author: Cavium Networks
13066 + * Contact: support@caviumnetworks.com
13067 + * This file is part of the OCTEON SDK
13069 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
13086 + * This file may also be available under a different license from Cavium.
13087 + * Contact Cavium Networks for more information
13088 + ***********************license end**************************************/
13092 + * Packet buffer defines.
13095 +#ifndef __CVMX_PACKET_H__
13096 +#define __CVMX_PACKET_H__
13099 + * This structure defines a buffer pointer on Octeon
13101 +union cvmx_buf_ptr {
13106 + * if set, invert the "free" pick of the overall
13107 + * packet. HW always sets this bit to 0 on inbound
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
13118 + /* The pool that the buffer came from / goes to */
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;
13127 +#endif /* __CVMX_PACKET_H__ */
13129 +++ b/drivers/staging/octeon/cvmx-pcsx-defs.h
13131 +/***********************license start***************
13132 + * Author: Cavium Networks
13134 + * Contact: support@caviumnetworks.com
13135 + * This file is part of the OCTEON SDK
13137 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
13154 + * This file may also be available under a different license from Cavium.
13155 + * Contact Cavium Networks for more information
13156 + ***********************license end**************************************/
13158 +#ifndef __CVMX_PCSX_DEFS_H__
13159 +#define __CVMX_PCSX_DEFS_H__
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))
13196 +union cvmx_pcsx_anx_adv_reg {
13198 + struct cvmx_pcsx_anx_adv_reg_s {
13199 + uint64_t reserved_16_63:48;
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;
13207 + uint64_t reserved_0_4:5;
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;
13215 +union cvmx_pcsx_anx_ext_st_reg {
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;
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;
13231 +union cvmx_pcsx_anx_lp_abil_reg {
13233 + struct cvmx_pcsx_anx_lp_abil_reg_s {
13234 + uint64_t reserved_16_63:48;
13237 + uint64_t rem_flt:2;
13238 + uint64_t reserved_9_11:3;
13239 + uint64_t pause:2;
13242 + uint64_t reserved_0_4:5;
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;
13250 +union cvmx_pcsx_anx_results_reg {
13252 + struct cvmx_pcsx_anx_results_reg_s {
13253 + uint64_t reserved_7_63:57;
13254 + uint64_t pause:2;
13256 + uint64_t an_cpt:1;
13258 + uint64_t link_ok:1;
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;
13266 +union cvmx_pcsx_intx_en_reg {
13268 + struct cvmx_pcsx_intx_en_reg_s {
13269 + uint64_t reserved_12_63:52;
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;
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;
13289 +union cvmx_pcsx_intx_reg {
13291 + struct cvmx_pcsx_intx_reg_s {
13292 + uint64_t reserved_12_63:52;
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;
13304 + uint64_t lnkspd:1;
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;
13312 +union cvmx_pcsx_linkx_timer_count_reg {
13314 + struct cvmx_pcsx_linkx_timer_count_reg_s {
13315 + uint64_t reserved_16_63:48;
13316 + uint64_t count:16;
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;
13324 +union cvmx_pcsx_log_anlx_reg {
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;
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;
13338 +union cvmx_pcsx_miscx_ctl_reg {
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;
13347 + uint64_t an_ovrd:1;
13348 + uint64_t samp_pt:7;
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;
13356 +union cvmx_pcsx_mrx_control_reg {
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;
13368 + uint64_t coltst:1;
13369 + uint64_t spdmsb:1;
13371 + uint64_t reserved_0_4:5;
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;
13379 +union cvmx_pcsx_mrx_status_reg {
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;
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;
13406 +union cvmx_pcsx_rxx_states_reg {
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;
13414 + uint64_t an_bad:1;
13415 + uint64_t an_st:4;
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;
13423 +union cvmx_pcsx_rxx_sync_reg {
13425 + struct cvmx_pcsx_rxx_sync_reg_s {
13426 + uint64_t reserved_2_63:62;
13428 + uint64_t bit_lock:1;
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;
13436 +union cvmx_pcsx_sgmx_an_adv_reg {
13438 + struct cvmx_pcsx_sgmx_an_adv_reg_s {
13439 + uint64_t reserved_16_63:48;
13442 + uint64_t reserved_13_13:1;
13444 + uint64_t speed:2;
13445 + uint64_t reserved_1_9:9;
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;
13454 +union cvmx_pcsx_sgmx_lp_adv_reg {
13456 + struct cvmx_pcsx_sgmx_lp_adv_reg_s {
13457 + uint64_t reserved_16_63:48;
13459 + uint64_t reserved_13_14:2;
13461 + uint64_t speed:2;
13462 + uint64_t reserved_1_9:9;
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;
13471 +union cvmx_pcsx_txx_states_reg {
13473 + struct cvmx_pcsx_txx_states_reg_s {
13474 + uint64_t reserved_7_63:57;
13476 + uint64_t tx_bad:1;
13477 + uint64_t ord_st:4;
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;
13485 +union cvmx_pcsx_tx_rxx_polarity_reg {
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;
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;
13502 +++ b/drivers/staging/octeon/cvmx-pcsxx-defs.h
13504 +/***********************license start***************
13505 + * Author: Cavium Networks
13507 + * Contact: support@caviumnetworks.com
13508 + * This file is part of the OCTEON SDK
13510 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
13527 + * This file may also be available under a different license from Cavium.
13528 + * Contact Cavium Networks for more information
13529 + ***********************license end**************************************/
13531 +#ifndef __CVMX_PCSXX_DEFS_H__
13532 +#define __CVMX_PCSXX_DEFS_H__
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))
13565 +union cvmx_pcsxx_10gbx_status_reg {
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;
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;
13583 +union cvmx_pcsxx_bist_status_reg {
13585 + struct cvmx_pcsxx_bist_status_reg_s {
13586 + uint64_t reserved_1_63:63;
13587 + uint64_t bist_status:1;
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;
13595 +union cvmx_pcsxx_bit_lock_status_reg {
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;
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;
13610 +union cvmx_pcsxx_control1_reg {
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;
13622 + uint64_t reserved_0_1:2;
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;
13630 +union cvmx_pcsxx_control2_reg {
13632 + struct cvmx_pcsxx_control2_reg_s {
13633 + uint64_t reserved_2_63:62;
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;
13642 +union cvmx_pcsxx_int_en_reg {
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;
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;
13659 +union cvmx_pcsxx_int_reg {
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;
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;
13676 +union cvmx_pcsxx_log_anl_reg {
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;
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;
13692 +union cvmx_pcsxx_misc_ctl_reg {
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;
13699 + uint64_t gmxeno:1;
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;
13707 +union cvmx_pcsxx_rx_sync_states_reg {
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;
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;
13722 +union cvmx_pcsxx_spd_abil_reg {
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;
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;
13735 +union cvmx_pcsxx_status1_reg {
13737 + struct cvmx_pcsxx_status1_reg_s {
13738 + uint64_t reserved_8_63:56;
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;
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;
13751 +union cvmx_pcsxx_status2_reg {
13753 + struct cvmx_pcsxx_status2_reg_s {
13754 + uint64_t reserved_16_63:48;
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;
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;
13770 +union cvmx_pcsxx_tx_rx_polarity_reg {
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;
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;
13785 + struct cvmx_pcsxx_tx_rx_polarity_reg_s cn56xx;
13786 + struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 cn56xxp1;
13789 +union cvmx_pcsxx_tx_rx_states_reg {
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;
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;
13815 + struct cvmx_pcsxx_tx_rx_states_reg_s cn56xx;
13816 + struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 cn56xxp1;
13821 +++ b/drivers/staging/octeon/cvmx-pip-defs.h
13823 +/***********************license start***************
13824 + * Author: Cavium Networks
13826 + * Contact: support@caviumnetworks.com
13827 + * This file is part of the OCTEON SDK
13829 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
13846 + * This file may also be available under a different license from Cavium.
13847 + * Contact Cavium Networks for more information
13848 + ***********************license end**************************************/
13850 +#ifndef __CVMX_PIP_DEFS_H__
13851 +#define __CVMX_PIP_DEFS_H__
13854 + * Enumeration representing the amount of packet processing
13855 + * and validation performed by the input hardware.
13857 +enum cvmx_pip_port_parse_mode {
13859 + * Packet input doesn't perform any processing of the input
13862 + CVMX_PIP_PORT_CFG_MODE_NONE = 0ull,
13864 + * Full packet processing is performed with pointer starting
13865 + * at the L2 (ethernet MAC) header.
13867 + CVMX_PIP_PORT_CFG_MODE_SKIPL2 = 1ull,
13869 + * Input packets are assumed to be IP. Results from non IP
13870 + * packets is undefined. Pointers reference the beginning of
13873 + CVMX_PIP_PORT_CFG_MODE_SKIPIP = 2ull
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)
13955 +union cvmx_pip_bck_prs {
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;
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;
13972 +union cvmx_pip_bist_status {
13974 + struct cvmx_pip_bist_status_s {
13975 + uint64_t reserved_18_63:46;
13976 + uint64_t bist:18;
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;
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;
13994 +union cvmx_pip_crc_ctlx {
13996 + struct cvmx_pip_crc_ctlx_s {
13997 + uint64_t reserved_2_63:62;
13998 + uint64_t invres:1;
13999 + uint64_t reflect:1;
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;
14007 +union cvmx_pip_crc_ivx {
14009 + struct cvmx_pip_crc_ivx_s {
14010 + uint64_t reserved_32_63:32;
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;
14019 +union cvmx_pip_dec_ipsecx {
14021 + struct cvmx_pip_dec_ipsecx_s {
14022 + uint64_t reserved_18_63:46;
14025 + uint64_t dprt:16;
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;
14040 +union cvmx_pip_dsa_src_grp {
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;
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;
14065 +union cvmx_pip_dsa_vid_grp {
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;
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;
14090 +union cvmx_pip_frm_len_chkx {
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;
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;
14104 +union cvmx_pip_gbl_cfg {
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;
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;
14129 +union cvmx_pip_gbl_ctl {
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;
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;
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;
14200 + struct cvmx_pip_gbl_ctl_cn30xx cn58xx;
14201 + struct cvmx_pip_gbl_ctl_cn30xx cn58xxp1;
14204 +union cvmx_pip_hg_pri_qos {
14206 + struct cvmx_pip_hg_pri_qos_s {
14207 + uint64_t reserved_11_63:53;
14209 + uint64_t reserved_6_7:2;
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;
14217 +union cvmx_pip_int_en {
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;
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;
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;
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;
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;
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;
14312 + struct cvmx_pip_int_en_cn30xx cn58xxp1;
14315 +union cvmx_pip_int_reg {
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;
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;
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;
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;
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;
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;
14410 + struct cvmx_pip_int_reg_cn30xx cn58xxp1;
14413 +union cvmx_pip_ip_offset {
14415 + struct cvmx_pip_ip_offset_s {
14416 + uint64_t reserved_3_63:61;
14417 + uint64_t offset:3;
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;
14432 +union cvmx_pip_prt_cfgx {
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;
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;
14461 + uint64_t reserved_7_7:1;
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;
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;
14479 + uint64_t reserved_7_7:1;
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;
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;
14500 + uint64_t reserved_7_7:1;
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;
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;
14530 + uint64_t reserved_7_7:1;
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;
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;
14555 + uint64_t reserved_7_7:1;
14558 + struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1;
14561 +union cvmx_pip_prt_tagx {
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;
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;
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;
14629 +union cvmx_pip_qos_diffx {
14631 + struct cvmx_pip_qos_diffx_s {
14632 + uint64_t reserved_3_63:61;
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;
14648 +union cvmx_pip_qos_vlanx {
14650 + struct cvmx_pip_qos_vlanx_s {
14651 + uint64_t reserved_7_63:57;
14653 + uint64_t reserved_3_3:1;
14656 + struct cvmx_pip_qos_vlanx_cn30xx {
14657 + uint64_t reserved_3_63:61;
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;
14672 +union cvmx_pip_qos_watchx {
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;
14679 + uint64_t reserved_23_23:1;
14681 + uint64_t reserved_19_19:1;
14682 + uint64_t match_type:3;
14683 + uint64_t match_value:16;
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;
14690 + uint64_t reserved_23_23:1;
14692 + uint64_t reserved_18_19:2;
14693 + uint64_t match_type:2;
14694 + uint64_t match_value:16;
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;
14708 +union cvmx_pip_raw_word {
14710 + struct cvmx_pip_raw_word_s {
14711 + uint64_t reserved_56_63:8;
14712 + uint64_t word:56;
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;
14727 +union cvmx_pip_sft_rst {
14729 + struct cvmx_pip_sft_rst_s {
14730 + uint64_t reserved_1_63:63;
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;
14745 +union cvmx_pip_stat0_prtx {
14747 + struct cvmx_pip_stat0_prtx_s {
14748 + uint64_t drp_pkts:32;
14749 + uint64_t drp_octs:32;
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;
14764 +union cvmx_pip_stat1_prtx {
14766 + struct cvmx_pip_stat1_prtx_s {
14767 + uint64_t reserved_48_63:16;
14768 + uint64_t octs:48;
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;
14783 +union cvmx_pip_stat2_prtx {
14785 + struct cvmx_pip_stat2_prtx_s {
14786 + uint64_t pkts:32;
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;
14802 +union cvmx_pip_stat3_prtx {
14804 + struct cvmx_pip_stat3_prtx_s {
14805 + uint64_t bcst:32;
14806 + uint64_t mcst:32;
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;
14821 +union cvmx_pip_stat4_prtx {
14823 + struct cvmx_pip_stat4_prtx_s {
14824 + uint64_t h65to127:32;
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;
14840 +union cvmx_pip_stat5_prtx {
14842 + struct cvmx_pip_stat5_prtx_s {
14843 + uint64_t h256to511:32;
14844 + uint64_t h128to255:32;
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;
14859 +union cvmx_pip_stat6_prtx {
14861 + struct cvmx_pip_stat6_prtx_s {
14862 + uint64_t h1024to1518:32;
14863 + uint64_t h512to1023:32;
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;
14878 +union cvmx_pip_stat7_prtx {
14880 + struct cvmx_pip_stat7_prtx_s {
14882 + uint64_t h1519:32;
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;
14897 +union cvmx_pip_stat8_prtx {
14899 + struct cvmx_pip_stat8_prtx_s {
14900 + uint64_t frag:32;
14901 + uint64_t undersz:32;
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;
14916 +union cvmx_pip_stat9_prtx {
14918 + struct cvmx_pip_stat9_prtx_s {
14919 + uint64_t jabber:32;
14920 + uint64_t oversz:32;
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;
14935 +union cvmx_pip_stat_ctl {
14937 + struct cvmx_pip_stat_ctl_s {
14938 + uint64_t reserved_1_63:63;
14939 + uint64_t rdclr:1;
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;
14954 +union cvmx_pip_stat_inb_errsx {
14956 + struct cvmx_pip_stat_inb_errsx_s {
14957 + uint64_t reserved_16_63:48;
14958 + uint64_t errs:16;
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;
14973 +union cvmx_pip_stat_inb_octsx {
14975 + struct cvmx_pip_stat_inb_octsx_s {
14976 + uint64_t reserved_48_63:16;
14977 + uint64_t octs:48;
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;
14992 +union cvmx_pip_stat_inb_pktsx {
14994 + struct cvmx_pip_stat_inb_pktsx_s {
14995 + uint64_t reserved_32_63:32;
14996 + uint64_t pkts:32;
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;
15011 +union cvmx_pip_tag_incx {
15013 + struct cvmx_pip_tag_incx_s {
15014 + uint64_t reserved_8_63:56;
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;
15030 +union cvmx_pip_tag_mask {
15032 + struct cvmx_pip_tag_mask_s {
15033 + uint64_t reserved_16_63:48;
15034 + uint64_t mask:16;
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;
15049 +union cvmx_pip_tag_secret {
15051 + struct cvmx_pip_tag_secret_s {
15052 + uint64_t reserved_32_63:32;
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;
15069 +union cvmx_pip_todo_entry {
15071 + struct cvmx_pip_todo_entry_s {
15073 + uint64_t reserved_62_62:1;
15074 + uint64_t entry:62;
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;
15091 +++ b/drivers/staging/octeon/cvmx-pip.h
15093 +/***********************license start***************
15094 + * Author: Cavium Networks
15096 + * Contact: support@caviumnetworks.com
15097 + * This file is part of the OCTEON SDK
15099 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
15116 + * This file may also be available under a different license from Cavium.
15117 + * Contact Cavium Networks for more information
15118 + ***********************license end**************************************/
15121 + * Interface to the hardware Packet Input Processing unit.
15125 +#ifndef __CVMX_PIP_H__
15126 +#define __CVMX_PIP_H__
15128 +#include "cvmx-wqe.h"
15129 +#include "cvmx-fpa.h"
15130 +#include "cvmx-pip-defs.h"
15132 +#define CVMX_PIP_NUM_INPUT_PORTS 40
15133 +#define CVMX_PIP_NUM_WATCHERS 4
15136 + * Encodes the different error and exception codes
15139 + CVMX_PIP_L4_NO_ERR = 0ull,
15141 + * 1 = TCP (UDP) packet not long enough to cover TCP (UDP)
15144 + CVMX_PIP_L4_MAL_ERR = 1ull,
15145 + /* 2 = TCP/UDP checksum failure */
15146 + CVMX_PIP_CHK_ERR = 2ull,
15148 + * 3 = TCP/UDP length check (TCP/UDP length does not match IP
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;
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;
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
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,
15201 + * RGM 3 = max frame error (pkt len > max frame len) (with FCS
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,
15208 + * RGM 5 = nibble error (data not byte multiple - 100M and 10M
15211 + CVMX_PIP_ALIGN_ERR = 5ull,
15213 + * RGM 6 = min frame error (pkt len < min frame len) (with FCS
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,
15224 + * RGM 10 = length mismatch (len did not match len in L2
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,
15233 + * RGM 12 = packet was not large enough to pass the skipper -
15234 + * no inspection could occur.
15236 + CVMX_PIP_SKIP_ERR = 12ull,
15238 + * RGM 13 = studder error (data not repeated - 100M and 10M
15241 + CVMX_PIP_NIBBLE_ERR = 13ull,
15242 + /* RGM+SPI 16 = FCS error */
15243 + CVMX_PIP_PIP_FCS = 16L,
15245 + * RGM+SPI+PCI 17 = packet was not large enough to pass the
15246 + * skipper - no inspection could occur.
15248 + CVMX_PIP_PIP_SKIP_ERR = 17L,
15250 + * RGM+SPI+PCI 18 = malformed l2 (packet not long enough to
15253 + CVMX_PIP_PIP_L2_MAL_HDR = 18L
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
15261 +} cvmx_pip_rcv_err_t;
15264 + * This defines the err_code field errors in the work Q entry
15267 + cvmx_pip_l4_err_t l4_err;
15268 + cvmx_pip_ip_exc_t ip_exc;
15269 + cvmx_pip_rcv_err_t rcv_err;
15273 + * Status statistics for a port
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 */
15284 + /* Number of packets processed by PIP */
15285 + uint32_t packets;
15287 + * Number of indentified L2 multicast packets. Does not
15288 + * include broadcast packets. Only includes packets whose
15289 + * parse mode is SKIP_TO_L2
15291 + uint32_t multicast_packets;
15293 + * Number of indentified L2 broadcast packets. Does not
15294 + * include multicast packets. Only includes packets whose
15295 + * parse mode is SKIP_TO_L2
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;
15325 + * Total number of octets from all packets received by PIP,
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;
15334 + * Definition of the PIP custom header that can be prepended
15335 + * to a packet by external hardware.
15341 + * Documented as R - Set if the Packet is RAWFULL. If
15342 + * set, this header must be the full 8 bytes.
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;
15352 + * Skip amount, including this header, to the
15353 + * beginning of the packet
15355 + uint64_t skip_len:7;
15356 + /* Must be zero */
15357 + uint64_t reserved2:6;
15358 + /* POW input queue for this packet */
15360 + /* POW input group for this packet */
15363 + * Flag to store this packet in the work queue entry,
15367 + /* POW input tag type */
15368 + uint64_t tag_type:2;
15369 + /* POW input tag */
15372 +} cvmx_pip_pkt_inst_hdr_t;
15374 +/* CSR typedefs have been moved to cvmx-csr-*.h */
15377 + * Configure an ethernet input port
15379 + * @port_num: Port number to configure
15380 + * @port_cfg: Port hardware configuration
15382 + * Port POW tagging configuration
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)
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);
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.
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.
15402 + * @watcher: Watcher number to configure (0 - 3).
15403 + * @match_type: Watcher match type
15405 + * Value the watcher will match against
15406 + * @qos: QoS queue for packets matching this watcher
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)
15412 + cvmx_pip_port_watcher_cfg_t watcher_config;
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;
15419 + cvmx_write_csr(CVMX_PIP_QOS_WATCHX(watcher), watcher_config.u64);
15423 + * Configure the VLAN priority to QoS queue mapping.
15425 + * @vlan_priority:
15426 + * VLAN priority (0-7)
15427 + * @qos: QoS queue for packets matching this watcher
15429 +static inline void cvmx_pip_config_vlan_qos(uint64_t vlan_priority,
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);
15439 + * Configure the Diffserv to QoS queue mapping.
15441 + * @diffserv: Diffserv field value (0-63)
15442 + * @qos: QoS queue for packets matching this watcher
15444 +static inline void cvmx_pip_config_diffserv_qos(uint64_t diffserv, uint64_t qos)
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);
15453 + * Get the status counters for a port.
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.
15459 +static inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear,
15460 + cvmx_pip_port_status_t *status)
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;
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);
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));
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;
15521 + if (cvmx_octeon_is_pass1()) {
15523 + * Kludge to fix Octeon Pass 1 errata - Drop counts
15526 + if (status->inb_packets > status->packets)
15527 + status->dropped_packets =
15528 + status->inb_packets - status->packets;
15530 + status->dropped_packets = 0;
15531 + if (status->inb_octets - status->inb_packets * 4 >
15533 + status->dropped_octets =
15534 + status->inb_octets - status->inb_packets * 4 -
15537 + status->dropped_octets = 0;
15542 + * Configure the hardware CRC engine
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
15551 +static inline void cvmx_pip_config_crc(uint64_t interface,
15552 + uint64_t invert_result, uint64_t reflect,
15553 + uint32_t initialization_vector)
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;
15560 + config.s.invres = invert_result;
15561 + config.s.reflect = reflect;
15562 + cvmx_write_csr(CVMX_PIP_CRC_CTLX(interface), config.u64);
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);
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.
15576 + * @mask_index: Which tag mask to clear (0..3)
15578 +static inline void cvmx_pip_tag_mask_clear(uint64_t mask_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);
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.
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()
15603 +static inline void cvmx_pip_tag_mask_set(uint64_t mask_index, uint64_t offset,
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);
15616 +#endif /* __CVMX_PIP_H__ */
15618 +++ b/drivers/staging/octeon/cvmx-pko-defs.h
15620 +/***********************license start***************
15621 + * Author: Cavium Networks
15623 + * Contact: support@caviumnetworks.com
15624 + * This file is part of the OCTEON SDK
15626 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
15643 + * This file may also be available under a different license from Cavium.
15644 + * Contact Cavium Networks for more information
15645 + ***********************license end**************************************/
15647 +#ifndef __CVMX_PKO_DEFS_H__
15648 +#define __CVMX_PKO_DEFS_H__
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)
15733 +union cvmx_pko_mem_count0 {
15735 + struct cvmx_pko_mem_count0_s {
15736 + uint64_t reserved_32_63:32;
15737 + uint64_t count:32;
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;
15752 +union cvmx_pko_mem_count1 {
15754 + struct cvmx_pko_mem_count1_s {
15755 + uint64_t reserved_48_63:16;
15756 + uint64_t count:48;
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;
15771 +union cvmx_pko_mem_debug0 {
15773 + struct cvmx_pko_mem_debug0_s {
15777 + uint64_t size:16;
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;
15792 +union cvmx_pko_mem_debug1 {
15794 + struct cvmx_pko_mem_debug1_s {
15798 + uint64_t size:16;
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;
15814 +union cvmx_pko_mem_debug10 {
15816 + struct cvmx_pko_mem_debug10_s {
15817 + uint64_t reserved_0_63:64;
15819 + struct cvmx_pko_mem_debug10_cn30xx {
15823 + uint64_t size:16;
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;
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;
15842 +union cvmx_pko_mem_debug11 {
15844 + struct cvmx_pko_mem_debug11_s {
15848 + uint64_t size:16;
15849 + uint64_t reserved_0_39:40;
15851 + struct cvmx_pko_mem_debug11_cn30xx {
15855 + uint64_t size:16;
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;
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;
15879 +union cvmx_pko_mem_debug12 {
15881 + struct cvmx_pko_mem_debug12_s {
15882 + uint64_t reserved_0_63:64;
15884 + struct cvmx_pko_mem_debug12_cn30xx {
15885 + uint64_t data:64;
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 {
15894 + uint64_t size:16;
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;
15904 +union cvmx_pko_mem_debug13 {
15906 + struct cvmx_pko_mem_debug13_s {
15910 + uint64_t reserved_0_55:56;
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;
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 {
15925 + uint64_t size:16;
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;
15936 +union cvmx_pko_mem_debug14 {
15938 + struct cvmx_pko_mem_debug14_s {
15939 + uint64_t reserved_0_63:64;
15941 + struct cvmx_pko_mem_debug14_cn30xx {
15942 + uint64_t reserved_17_63:47;
15943 + uint64_t ridx:17;
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;
15951 + struct cvmx_pko_mem_debug14_cn52xx cn52xxp1;
15952 + struct cvmx_pko_mem_debug14_cn52xx cn56xx;
15953 + struct cvmx_pko_mem_debug14_cn52xx cn56xxp1;
15956 +union cvmx_pko_mem_debug2 {
15958 + struct cvmx_pko_mem_debug2_s {
15962 + uint64_t size:16;
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;
15978 +union cvmx_pko_mem_debug3 {
15980 + struct cvmx_pko_mem_debug3_s {
15981 + uint64_t reserved_0_63:64;
15983 + struct cvmx_pko_mem_debug3_cn30xx {
15987 + uint64_t size:16;
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;
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;
16004 +union cvmx_pko_mem_debug4 {
16006 + struct cvmx_pko_mem_debug4_s {
16007 + uint64_t reserved_0_63:64;
16009 + struct cvmx_pko_mem_debug4_cn30xx {
16010 + uint64_t data:64;
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;
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;
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;
16032 + uint64_t minor:2;
16033 + uint64_t major:3;
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;
16042 + uint64_t dread_sop:1;
16043 + uint64_t init_dwrite:1;
16044 + uint64_t chk_once:1;
16045 + uint64_t chk_mode:1;
16047 + uint64_t minor:2;
16048 + uint64_t major:3;
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;
16057 +union cvmx_pko_mem_debug5 {
16059 + struct cvmx_pko_mem_debug5_s {
16060 + uint64_t reserved_0_63:64;
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;
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;
16076 + uint64_t qcb_ridx:5;
16077 + uint64_t qid_off:3;
16078 + uint64_t qid_base:7;
16080 + uint64_t minor:2;
16081 + uint64_t major:4;
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;
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;
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;
16105 +union cvmx_pko_mem_debug6 {
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;
16117 + uint64_t qcb_ridx:5;
16118 + uint64_t qid_offmax:4;
16119 + uint64_t reserved_0_11:12;
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;
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;
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;
16147 + uint64_t qcb_ridx:5;
16148 + uint64_t qid_offmax:4;
16149 + uint64_t qid_off:4;
16150 + uint64_t qid_base:8;
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;
16159 +union cvmx_pko_mem_debug7 {
16161 + struct cvmx_pko_mem_debug7_s {
16164 + uint64_t reserved_0_57:58;
16166 + struct cvmx_pko_mem_debug7_cn30xx {
16167 + uint64_t reserved_58_63:6;
16169 + uint64_t start:33;
16170 + uint64_t size:16;
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 {
16178 + uint64_t buf_siz:13;
16179 + uint64_t buf_ptr:33;
16180 + uint64_t qcb_widx:6;
16181 + uint64_t qcb_ridx:6;
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;
16191 +union cvmx_pko_mem_debug8 {
16193 + struct cvmx_pko_mem_debug8_s {
16194 + uint64_t reserved_59_63:5;
16196 + uint64_t buf_siz:13;
16197 + uint64_t reserved_0_44:45;
16199 + struct cvmx_pko_mem_debug8_cn30xx {
16202 + uint64_t buf_siz:13;
16203 + uint64_t buf_ptr:33;
16204 + uint64_t qcb_widx:6;
16205 + uint64_t qcb_ridx:6;
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;
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;
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;
16237 +union cvmx_pko_mem_debug9 {
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;
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;
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;
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;
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;
16277 +union cvmx_pko_mem_port_ptrs {
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;
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;
16294 +union cvmx_pko_mem_port_qos {
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;
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;
16309 +union cvmx_pko_mem_port_rate0 {
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;
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;
16324 +union cvmx_pko_mem_port_rate1 {
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;
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;
16338 +union cvmx_pko_mem_queue_ptrs {
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;
16347 + uint64_t index:3;
16349 + uint64_t queue:7;
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;
16364 +union cvmx_pko_mem_queue_qos {
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;
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;
16386 +union cvmx_pko_reg_bist_result {
16388 + struct cvmx_pko_reg_bist_result_s {
16389 + uint64_t reserved_0_63:64;
16391 + struct cvmx_pko_reg_bist_result_cn30xx {
16392 + uint64_t reserved_27_63:37;
16394 + uint64_t count:1;
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;
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;
16426 + struct cvmx_pko_reg_bist_result_cn52xx {
16427 + uint64_t reserved_35_63:29;
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;
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;
16451 +union cvmx_pko_reg_cmd_buf {
16453 + struct cvmx_pko_reg_cmd_buf_s {
16454 + uint64_t reserved_23_63:41;
16456 + uint64_t reserved_13_19:7;
16457 + uint64_t size:13;
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;
16472 +union cvmx_pko_reg_crc_ctlx {
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;
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;
16485 +union cvmx_pko_reg_crc_enable {
16487 + struct cvmx_pko_reg_crc_enable_s {
16488 + uint64_t reserved_32_63:32;
16489 + uint64_t enable:32;
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;
16497 +union cvmx_pko_reg_crc_ivx {
16499 + struct cvmx_pko_reg_crc_ivx_s {
16500 + uint64_t reserved_32_63:32;
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;
16509 +union cvmx_pko_reg_debug0 {
16511 + struct cvmx_pko_reg_debug0_s {
16512 + uint64_t asserts:64;
16514 + struct cvmx_pko_reg_debug0_cn30xx {
16515 + uint64_t reserved_17_63:47;
16516 + uint64_t asserts:17;
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;
16530 +union cvmx_pko_reg_debug1 {
16532 + struct cvmx_pko_reg_debug1_s {
16533 + uint64_t asserts:64;
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;
16544 +union cvmx_pko_reg_debug2 {
16546 + struct cvmx_pko_reg_debug2_s {
16547 + uint64_t asserts:64;
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;
16558 +union cvmx_pko_reg_debug3 {
16560 + struct cvmx_pko_reg_debug3_s {
16561 + uint64_t asserts:64;
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;
16572 +union cvmx_pko_reg_engine_inflight {
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;
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;
16593 +union cvmx_pko_reg_engine_thresh {
16595 + struct cvmx_pko_reg_engine_thresh_s {
16596 + uint64_t reserved_10_63:54;
16597 + uint64_t mask:10;
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;
16605 +union cvmx_pko_reg_error {
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;
16613 + struct cvmx_pko_reg_error_cn30xx {
16614 + uint64_t reserved_2_63:62;
16615 + uint64_t doorbell:1;
16616 + uint64_t parity:1;
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;
16630 +union cvmx_pko_reg_flags {
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;
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;
16652 +union cvmx_pko_reg_gmx_port_mode {
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;
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;
16672 +union cvmx_pko_reg_int_mask {
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;
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;
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;
16697 +union cvmx_pko_reg_queue_mode {
16699 + struct cvmx_pko_reg_queue_mode_s {
16700 + uint64_t reserved_2_63:62;
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;
16716 +union cvmx_pko_reg_queue_ptrs1 {
16718 + struct cvmx_pko_reg_queue_ptrs1_s {
16719 + uint64_t reserved_2_63:62;
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;
16732 +union cvmx_pko_reg_read_idx {
16734 + struct cvmx_pko_reg_read_idx_s {
16735 + uint64_t reserved_16_63:48;
16737 + uint64_t index:8;
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;
16754 +++ b/drivers/staging/octeon/cvmx-pko.c
16756 +/***********************license start***************
16757 + * Author: Cavium Networks
16759 + * Contact: support@caviumnetworks.com
16760 + * This file is part of the OCTEON SDK
16762 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
16779 + * This file may also be available under a different license from Cavium.
16780 + * Contact Cavium Networks for more information
16781 + ***********************license end**************************************/
16784 + * Support library for the hardware Packet Output unit.
16787 +#include <asm/octeon/octeon.h>
16789 +#include "cvmx-config.h"
16790 +#include "cvmx-pko.h"
16791 +#include "cvmx-helper.h"
16794 + * Internal state of packet output
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.
16803 +void cvmx_pko_initialize_global(void)
16806 + uint64_t priority = 8;
16807 + union cvmx_pko_reg_cmd_buf config;
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.
16815 + config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL;
16816 + config.s.size = CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE / 8 - 1;
16818 + cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);
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,
16825 + * If we aren't using all of the queues optimize PKO's
16826 + * internal memory.
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();
16833 + cvmx_helper_get_last_ipd_port(num_interfaces - 1);
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);
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);
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.
16856 + * Returns 0 on success
16859 +int cvmx_pko_initialize_local(void)
16861 + /* Nothing to do */
16866 + * Enables the packet output hardware. It must already be
16869 +void cvmx_pko_enable(void)
16871 + union cvmx_pko_reg_flags flags;
16873 + flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
16874 + if (flags.s.ena_pko)
16876 + ("Warning: Enabling PKO when PKO already enabled.\n");
16878 + flags.s.ena_dwb = 1;
16879 + flags.s.ena_pko = 1;
16881 + * always enable big endian for 3-word command. Does nothing
16884 + flags.s.store_be = 1;
16885 + cvmx_write_csr(CVMX_PKO_REG_FLAGS, flags.u64);
16889 + * Disables the packet output. Does not affect any configuration.
16891 +void cvmx_pko_disable(void)
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);
16901 + * Reset the packet output.
16903 +static void __cvmx_pko_reset(void)
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);
16912 + * Shutdown and free resources required by packet output.
16914 +void cvmx_pko_shutdown(void)
16916 + union cvmx_pko_mem_queue_ptrs config;
16919 + cvmx_pko_disable();
16921 + for (queue = 0; queue < CVMX_PKO_MAX_OUTPUT_QUEUES; queue++) {
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;
16932 + config1.s.qid7 = queue >> 7;
16933 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
16935 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
16936 + cvmx_cmd_queue_shutdown(CVMX_CMD_QUEUE_PKO(queue));
16938 + __cvmx_pko_reset();
16942 + * Configure a output port and the associated queues for use.
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.
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[])
16962 + cvmx_pko_status_t result_code;
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;
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;
16976 + if (base_queue + num_queues > CVMX_PKO_MAX_OUTPUT_QUEUES) {
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;
16983 + if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
16985 + * Validate the static queue priority setup and set
16986 + * static_priority_base and static_priority_end
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
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;
17007 + * Check to make sure all static priority
17008 + * queues are contiguous. Also catches some
17009 + * cases of static priorites not starting at
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;
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;
17032 + cvmx_dprintf("Port %d: Static priority queue base: %d, "
17033 + "end: %d\n", port,
17034 + static_priority_base, static_priority_end);
17038 + * At this point, static_priority_base and static_priority_end
17039 + * are either both -1, or are valid start/end queue
17043 + result_code = CVMX_PKO_SUCCESS;
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);
17051 + for (queue = 0; queue < num_queues; queue++) {
17052 + uint64_t *buf_ptr = NULL;
17055 + config1.s.idx3 = queue >> 3;
17056 + config1.s.qid7 = (base_queue + queue) >> 7;
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;
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;
17070 + * Convert the priority into an enable bit field. Try
17071 + * to space the bits out evenly so the packet don't
17074 + switch ((int)priority[queue]) {
17076 + config.s.qos_mask = 0x00;
17079 + config.s.qos_mask = 0x01;
17082 + config.s.qos_mask = 0x11;
17085 + config.s.qos_mask = 0x49;
17088 + config.s.qos_mask = 0x55;
17091 + config.s.qos_mask = 0x57;
17094 + config.s.qos_mask = 0x77;
17097 + config.s.qos_mask = 0x7f;
17100 + config.s.qos_mask = 0xff;
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;
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;
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
17125 + CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST
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:
17137 + ("ERROR: cvmx_pko_config_port: Port already setup.\n");
17138 + return CVMX_PKO_PORT_ALREADY_SETUP;
17139 + case CVMX_CMD_QUEUE_INVALID_PARAM:
17142 + ("ERROR: cvmx_pko_config_port: Command queue initialization failed.\n");
17143 + return CVMX_PKO_CMD_QUEUE_INIT_ERROR;
17149 + cvmx_cmd_queue_buffer(CVMX_CMD_QUEUE_PKO
17150 + (base_queue + queue));
17151 + config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr);
17153 + config.s.buf_ptr = 0;
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);
17162 + return result_code;
17167 + * Show map of ports -> queues for different cores.
17169 +void cvmx_pko_show_queue_map()
17172 + int pko_output_ports = 36;
17174 + cvmx_dprintf("port");
17175 + for (port = 0; port < pko_output_ports; port++)
17176 + cvmx_dprintf("%3d ", port);
17177 + cvmx_dprintf("\n");
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,
17187 + cvmx_dprintf("\n");
17192 + * Rate limit a PKO port to a max packets/sec. This function is only
17193 + * supported on CN51XX and higher, excluding CN58XX.
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.
17200 + * Returns Zero on success, negative on failure
17202 +int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst)
17204 + union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
17205 + union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
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;
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;
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);
17225 + * Rate limit a PKO port to a max bits/sec. This function is only
17226 + * supported on CN51XX and higher, excluding CN58XX.
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.
17233 + * Returns Zero on success, negative on failure
17235 +int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst)
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;
17242 + pko_mem_port_rate0.u64 = 0;
17243 + pko_mem_port_rate0.s.pid = port;
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.
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;
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;
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);
17263 +++ b/drivers/staging/octeon/cvmx-pko.h
17265 +/***********************license start***************
17266 + * Author: Cavium Networks
17268 + * Contact: support@caviumnetworks.com
17269 + * This file is part of the OCTEON SDK
17271 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
17288 + * This file may also be available under a different license from Cavium.
17289 + * Contact Cavium Networks for more information
17290 + ***********************license end**************************************/
17294 + * Interface to the hardware Packet Output unit.
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.
17307 + * Some of other SDK differences visible to the command command
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().
17322 +#ifndef __CVMX_PKO_H__
17323 +#define __CVMX_PKO_H__
17325 +#include "cvmx-fpa.h"
17326 +#include "cvmx-pow.h"
17327 +#include "cvmx-cmd-queue.h"
17328 +#include "cvmx-pko-defs.h"
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)
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
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;
17359 + * This enumeration represents the differnet locking modes supported by PKO.
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
17367 + CVMX_PKO_LOCK_NONE = 0,
17369 + * PKO performs an atomic tagswitch to insure exclusive access
17370 + * to the output queue. This will maintain packet ordering on
17373 + CVMX_PKO_LOCK_ATOMIC_TAG = 1,
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.
17379 + CVMX_PKO_LOCK_CMD_QUEUE = 2,
17380 +} cvmx_pko_lock_t;
17383 + uint32_t packets;
17385 + uint64_t doorbell;
17386 +} cvmx_pko_port_status_t;
17389 + * This structure defines the address to use on a packet enqueue
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 */
17402 + /* Must be zero */
17403 + uint64_t reserved2:4;
17404 + /* Must be zero */
17405 + uint64_t reserved3:18;
17407 + * The hardware likes to have the output port in
17408 + * addition to the output queue,
17412 + * The output queue to send the packet to (0-127 are
17415 + uint64_t queue:9;
17416 + /* Must be zero */
17417 + uint64_t reserved4:3;
17419 +} cvmx_pko_doorbell_address_t;
17422 + * Structure of the first packet output command word.
17428 + * The size of the reg1 operation - could be 8, 16,
17429 + * 32, or 64 bits.
17431 + uint64_t size1:2;
17433 + * The size of the reg0 operation - could be 8, 16,
17434 + * 32, or 64 bits.
17436 + uint64_t size0:2;
17438 + * If set, subtract 1, if clear, subtract packet
17441 + uint64_t subone1:1;
17443 + * The register, subtract will be done if reg1 is
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;
17452 + * When set, interpret segment pointer and segment
17453 + * bytes in little endian order.
17457 + * When set, packet data not allocated in L2 cache by
17462 + * If set and rsp is set, word3 contains a pointer to
17463 + * a work queue entry.
17466 + /* If set, the hardware will send a response when done */
17469 + * If set, the supplied pkt_ptr is really a pointer to
17470 + * a list of pkt_ptr's.
17472 + uint64_t gather:1;
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.
17478 + uint64_t ipoffp1:7;
17480 + * If set, ignore the I bit (force to zero) from all
17481 + * pointer structures.
17483 + uint64_t ignore_i:1;
17485 + * If clear, the hardware will attempt to free the
17486 + * buffers containing the packet.
17488 + uint64_t dontfree:1;
17490 + * The total number of segs in the packet, if gather
17491 + * set, also gather list length.
17494 + /* Including L2, but no trailing CRC */
17495 + uint64_t total_bytes:16;
17497 +} cvmx_pko_command_word0_t;
17499 +/* CSR typedefs have been moved to cvmx-csr-*.h */
17502 + * Definition of internal state for Packet output processing
17505 + /* ptr to start of buffer, offset kept in FAU reg */
17506 + uint64_t *start_ptr;
17507 +} cvmx_pko_state_elem_t;
17510 + * Call before any other calls to initialize the packet
17513 +extern void cvmx_pko_initialize_global(void);
17514 +extern int cvmx_pko_initialize_local(void);
17517 + * Enables the packet output hardware. It must already be
17520 +extern void cvmx_pko_enable(void);
17523 + * Disables the packet output. Does not affect any configuration.
17525 +extern void cvmx_pko_disable(void);
17528 + * Shutdown and free resources required by packet output.
17531 +extern void cvmx_pko_shutdown(void);
17534 + * Configure a output port and the associated queues for use.
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
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[]);
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.
17555 + * @port: Port the packet is for
17556 + * @queue: Queue the packet is for
17557 + * @len: Length of the command in 64 bit words
17559 +static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
17562 + cvmx_pko_doorbell_address_t ptr;
17565 + ptr.s.mem_space = CVMX_IO_SEG;
17566 + ptr.s.did = CVMX_OCT_DID_PKT_SEND;
17568 + ptr.s.port = port;
17569 + ptr.s.queue = queue;
17571 + * Need to make sure output queue data is in DRAM before
17572 + * doorbell write.
17575 + cvmx_write_io(ptr.u64, len);
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.
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.
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.
17602 + * NOTE: If atomic locking is used, the POW entry CANNOT be
17603 + * descheduled, as it does not contain a valid WQE pointer.
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
17611 +static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
17612 + cvmx_pko_lock_t use_locking)
17614 + if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
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.
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);
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().
17641 + * @port: Port to send it on
17642 + * @queue: Queue to use
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
17649 + * Returns returns CVMX_PKO_SUCCESS on success, or error code on
17650 + * failure of output
17652 +static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
17655 + cvmx_pko_command_word0_t pko_command,
17656 + union cvmx_buf_ptr packet,
17657 + cvmx_pko_lock_t use_locking)
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;
17672 + return CVMX_PKO_INVALID_QUEUE;
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().
17682 + * @port: Port to send it on
17683 + * @queue: Queue to use
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
17692 + * Returns returns CVMX_PKO_SUCCESS on success, or error code on
17693 + * failure of output
17695 +static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
17698 + cvmx_pko_command_word0_t pko_command,
17699 + union cvmx_buf_ptr packet,
17701 + cvmx_pko_lock_t use_locking)
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;
17716 + return CVMX_PKO_INVALID_QUEUE;
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.
17725 + * @port: Port number
17726 + * @core: Core to get queue for
17728 + * Returns Core-specific output queue
17730 +static inline int cvmx_pko_get_base_queue_per_core(int port, int core)
17732 +#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
17733 +#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16
17735 +#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
17736 +#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16
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 -
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 -
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 -
17760 + CVMX_PKO_QUEUES_PER_PORT_LOOP;
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;
17770 + * For a given port number, return the base pko output queue
17773 + * @port: Port number
17774 + * Returns Base output queue
17776 +static inline int cvmx_pko_get_base_queue(int port)
17778 + return cvmx_pko_get_base_queue_per_core(port, 0);
17782 + * For a given port number, return the number of pko output queues.
17784 + * @port: Port number
17785 + * Returns Number of output queues
17787 +static inline int cvmx_pko_get_num_queues(int port)
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;
17802 + * Get the status counters for a port.
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.
17808 +static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
17809 + cvmx_pko_port_status_t *status)
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;
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);
17819 + pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0);
17820 + status->packets = pko_mem_count0.s.count;
17822 + pko_mem_count0.s.count = port_num;
17823 + cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64);
17826 + pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1);
17827 + status->octets = pko_mem_count1.s.count;
17829 + pko_mem_count1.s.count = port_num;
17830 + cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64);
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;
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;
17849 + * Rate limit a PKO port to a max packets/sec. This function is only
17850 + * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
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.
17857 + * Returns Zero on success, negative on failure
17859 +extern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst);
17862 + * Rate limit a PKO port to a max bits/sec. This function is only
17863 + * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
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.
17870 + * Returns Zero on success, negative on failure
17872 +extern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst);
17874 +#endif /* __CVMX_PKO_H__ */
17876 +++ b/drivers/staging/octeon/cvmx-pow.h
17878 +/***********************license start***************
17879 + * Author: Cavium Networks
17881 + * Contact: support@caviumnetworks.com
17882 + * This file is part of the OCTEON SDK
17884 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
17901 + * This file may also be available under a different license from Cavium.
17902 + * Contact Cavium Networks for more information
17903 + ***********************license end**************************************/
17906 + * Interface to the hardware Packet Order / Work unit.
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
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
17928 +#ifndef __CVMX_POW_H__
17929 +#define __CVMX_POW_H__
17931 +#include <asm/octeon/cvmx-pow-defs.h>
17933 +#include "cvmx-scratch.h"
17934 +#include "cvmx-wqe.h"
17936 +/* Default to having all POW constancy checks turned on */
17937 +#ifndef CVMX_ENABLE_POW_CHECKS
17938 +#define CVMX_ENABLE_POW_CHECKS 1
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,
17947 + * The work queue entry from the order - NEVER tag switch from
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
17958 + CVMX_POW_TAG_TYPE_NULL_NULL = 3L
17962 + * Wait flag values for pow functions.
17965 + CVMX_POW_WAIT = 1,
17966 + CVMX_POW_NO_WAIT = 0,
17967 +} cvmx_pow_wait_t;
17970 + * POW tag operations. These are used in the data stored to the POW.
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
17979 + CVMX_POW_TAG_OP_SWTAG = 0L,
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
17986 + CVMX_POW_TAG_OP_SWTAG_FULL = 1L,
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
17992 + CVMX_POW_TAG_OP_SWTAG_DESCH = 2L,
17994 + * just de-schedule
17995 + * - fields used: op, no_sched
17997 + CVMX_POW_TAG_OP_DESCH = 3L,
17999 + * create an entirely new work queue entry
18000 + * - fields used: address, op, qos, grp, type, tag
18002 + CVMX_POW_TAG_OP_ADDWQ = 4L,
18004 + * just update the work queue pointer and grp for this PP
18005 + * - fields used: address, op, grp
18007 + CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L,
18009 + * set the no_sched bit on the de-schedule list
18011 + * - does nothing if the selected entry is not on the
18012 + * de-schedule list
18014 + * - does nothing if the stored work queue pointer does not
18015 + * match the address field
18017 + * - fields used: address, index, op
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.
18027 + CVMX_POW_TAG_OP_SET_NSCHED = 6L,
18029 + * clears the no_sched bit on the de-schedule list
18031 + * - does nothing if the selected entry is not on the
18032 + * de-schedule list
18034 + * - does nothing if the stored work queue pointer does not
18035 + * match the address field
18037 + * - fields used: address, index, op
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.
18047 + CVMX_POW_TAG_OP_CLR_NSCHED = 7L,
18049 + CVMX_POW_TAG_OP_NOP = 15L
18050 +} cvmx_pow_tag_op_t;
18053 + * This structure defines the store data on a store to POW
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
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;
18071 + * The QOS level for the packet. qos is only used for
18072 + * CVMX_POW_TAG_OP_ADDWQ
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
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
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
18098 +} cvmx_pow_tag_req_t;
18101 + * This structure describes the address to load stuff from POW
18107 + * Address for new work request loads (did<2:0> == 0)
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 */
18118 + /* Must be zero */
18119 + uint64_t reserved_4_39:36;
18121 + * If set, don't return load response until work is
18125 + /* Must be zero */
18126 + uint64_t reserved_0_2:3;
18130 + * Address for loads to get POW internal status
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 */
18141 + /* Must be zero */
18142 + uint64_t reserved_10_39:30;
18143 + /* The core id to get status for */
18144 + uint64_t coreid:4;
18146 + * If set and get_cur is set, return reverse tag-list
18147 + * pointer rather than forward tag-list pointer.
18149 + uint64_t get_rev:1;
18151 + * If set, return current status rather than pending
18154 + uint64_t get_cur:1;
18156 + * If set, get the work-queue pointer rather than
18159 + uint64_t get_wqp:1;
18160 + /* Must be zero */
18161 + uint64_t reserved_0_2:3;
18165 + * Address for memory loads to get POW internal state
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 */
18176 + /* Must be zero */
18177 + uint64_t reserved_16_39:24;
18178 + /* POW memory index */
18179 + uint64_t index:11;
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
18186 + uint64_t get_des:1;
18188 + * If set, get the work-queue pointer rather than
18189 + * tag/type (no effect when get_des set).
18191 + uint64_t get_wqp:1;
18192 + /* Must be zero */
18193 + uint64_t reserved_0_2:3;
18197 + * Address for index/pointer loads
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 */
18208 + /* Must be zero */
18209 + uint64_t reserved_9_39:31;
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:
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
18230 + uint64_t qosgrp:4;
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.
18238 + uint64_t get_des_get_tail:1;
18240 + * If set, return remote pointers rather than the
18241 + * local indexes for the specified qos level.
18243 + uint64_t get_rmt:1;
18244 + /* Must be zero */
18245 + uint64_t reserved_0_2:3;
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
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 */
18265 + /* Must be zero */
18266 + uint64_t reserved_0_39:40;
18268 +} cvmx_pow_load_addr_t;
18271 + * This structure defines the response to a load/SENDSINGLE to POW
18272 + * (except CSR reads)
18278 + * Response to new work request loads
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:
18287 + * - There was no work, or
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.
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;
18302 + * Result for a POW Status Load (when get_cur==0 and get_wqp==0)
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;
18313 + * Set when there is a pending NULL SWTAG, or an
18314 + * implicit switch to NULL.
18316 + uint64_t pend_switch_null:1;
18317 + /* Set when there is a pending DESCHED or SWTAG_DESCHED. */
18318 + uint64_t pend_desched:1;
18320 + * Set when there is a pending SWTAG_DESCHED and
18321 + * pend_desched is set.
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;
18329 + * When pend_new_work is set, this bit indicates that
18330 + * the wait bit was set.
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;
18341 + * This is the new_grp when (pend_desched AND
18342 + * pend_desched_switch) is set.
18344 + uint64_t pend_grp:4;
18345 + uint64_t reserved_34_35:2;
18347 + * This is the tag type when pend_switch or
18348 + * (pend_desched AND pend_desched_switch) are set.
18350 + uint64_t pend_type:2;
18352 + * - this is the tag when pend_switch or (pend_desched
18353 + * AND pend_desched_switch) are set.
18355 + uint64_t pend_tag:32;
18359 + * Result for a POW Status Load (when get_cur==0 and get_wqp==1)
18362 + uint64_t reserved_62_63:2;
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.
18368 + uint64_t pend_switch:1;
18369 + /* Set when SWTAG_FULL and pend_switch is set. */
18370 + uint64_t pend_switch_full:1;
18372 + * Set when there is a pending NULL SWTAG, or an
18373 + * implicit switch to NULL.
18375 + uint64_t pend_switch_null:1;
18377 + * Set when there is a pending DESCHED or
18380 + uint64_t pend_desched:1;
18382 + * Set when there is a pending SWTAG_DESCHED and
18383 + * pend_desched is set.
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;
18391 + * When pend_new_work is set, this bit indicates that
18392 + * the wait bit was set.
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;
18403 + * This is the new_grp when (pend_desched AND
18404 + * pend_desched_switch) is set.
18406 + uint64_t pend_grp:4;
18407 + /* This is the wqp when pend_nosched_clr is set. */
18408 + uint64_t pend_wqp:36;
18412 + * Result for a POW Status Load (when get_cur==1, get_wqp==0, and
18416 + uint64_t reserved_62_63:2;
18418 + * Points to the next POW entry in the tag list when
18419 + * tail == 0 (and tag_type is not NULL or NULL_NULL).
18421 + uint64_t link_index:11;
18422 + /* The POW entry attached to the core. */
18423 + uint64_t index:11;
18425 + * The group attached to the core (updated when new
18426 + * tag list entered on SWTAG_FULL).
18430 + * Set when this POW entry is at the head of its tag
18431 + * list (also set when in the NULL or NULL_NULL
18436 + * Set when this POW entry is at the tail of its tag
18437 + * list (also set when in the NULL or NULL_NULL
18442 + * The tag type attached to the core (updated when new
18443 + * tag list entered on SWTAG, SWTAG_FULL, or
18444 + * SWTAG_DESCHED).
18446 + uint64_t tag_type:2;
18448 + * The tag attached to the core (updated when new tag
18449 + * list entered on SWTAG, SWTAG_FULL, or
18450 + * SWTAG_DESCHED).
18456 + * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1)
18459 + uint64_t reserved_62_63:2;
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.
18466 + uint64_t revlink_index:11;
18467 + /* The POW entry attached to the core. */
18468 + uint64_t index:11;
18470 + * The group attached to the core (updated when new
18471 + * tag list entered on SWTAG_FULL).
18474 + /* Set when this POW entry is at the head of its tag
18475 + * list (also set when in the NULL or NULL_NULL
18480 + * Set when this POW entry is at the tail of its tag
18481 + * list (also set when in the NULL or NULL_NULL
18486 + * The tag type attached to the core (updated when new
18487 + * tag list entered on SWTAG, SWTAG_FULL, or
18488 + * SWTAG_DESCHED).
18490 + uint64_t tag_type:2;
18492 + * The tag attached to the core (updated when new tag
18493 + * list entered on SWTAG, SWTAG_FULL, or
18494 + * SWTAG_DESCHED).
18500 + * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
18504 + uint64_t reserved_62_63:2;
18506 + * Points to the next POW entry in the tag list when
18507 + * tail == 0 (and tag_type is not NULL or NULL_NULL).
18509 + uint64_t link_index:11;
18510 + /* The POW entry attached to the core. */
18511 + uint64_t index:11;
18513 + * The group attached to the core (updated when new
18514 + * tag list entered on SWTAG_FULL).
18518 + * The wqp attached to the core (updated when new tag
18519 + * list entered on SWTAG_FULL).
18525 + * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
18529 + uint64_t reserved_62_63:2;
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.
18536 + uint64_t revlink_index:11;
18537 + /* The POW entry attached to the core. */
18538 + uint64_t index:11;
18540 + * The group attached to the core (updated when new
18541 + * tag list entered on SWTAG_FULL).
18545 + * The wqp attached to the core (updated when new tag
18546 + * list entered on SWTAG_FULL).
18552 + * Result For POW Memory Load (get_des == 0 and get_wqp == 0)
18555 + uint64_t reserved_51_63:13;
18557 + * The next entry in the input, free, descheduled_head
18558 + * list (unpredictable if entry is the tail of the
18561 + uint64_t next_index:11;
18562 + /* The group of the POW entry. */
18564 + uint64_t reserved_35:1;
18566 + * Set when this POW entry is at the tail of its tag
18567 + * list (also set when in the NULL or NULL_NULL
18571 + /* The tag type of the POW entry. */
18572 + uint64_t tag_type:2;
18573 + /* The tag of the POW entry. */
18578 + * Result For POW Memory Load (get_des == 0 and get_wqp == 1)
18581 + uint64_t reserved_51_63:13;
18583 + * The next entry in the input, free, descheduled_head
18584 + * list (unpredictable if entry is the tail of the
18587 + uint64_t next_index:11;
18588 + /* The group of the POW entry. */
18590 + /* The WQP held in the POW entry. */
18595 + * Result For POW Memory Load (get_des == 1)
18598 + uint64_t reserved_51_63:13;
18600 + * The next entry in the tag list connected to the
18601 + * descheduled head.
18603 + uint64_t fwd_index:11;
18604 + /* The group of the POW entry. */
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;
18611 + * The next tag type for the new tag list when
18612 + * pend_switch is set.
18614 + uint64_t pend_type:2;
18616 + * The next tag for the new tag list when pend_switch
18619 + uint64_t pend_tag:32;
18623 + * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0)
18626 + uint64_t reserved_52_63:12;
18628 + * set when there is one or more POW entries on the
18631 + uint64_t free_val:1;
18633 + * set when there is exactly one POW entry on the free
18636 + uint64_t free_one:1;
18637 + uint64_t reserved_49:1;
18639 + * when free_val is set, indicates the first entry on
18642 + uint64_t free_head:11;
18643 + uint64_t reserved_37:1;
18645 + * when free_val is set, indicates the last entry on
18648 + uint64_t free_tail:11;
18650 + * set when there is one or more POW entries on the
18651 + * input Q list selected by qosgrp.
18653 + uint64_t loc_val:1;
18655 + * set when there is exactly one POW entry on the
18656 + * input Q list selected by qosgrp.
18658 + uint64_t loc_one:1;
18659 + uint64_t reserved_23:1;
18661 + * when loc_val is set, indicates the first entry on
18662 + * the input Q list selected by qosgrp.
18664 + uint64_t loc_head:11;
18665 + uint64_t reserved_11:1;
18667 + * when loc_val is set, indicates the last entry on
18668 + * the input Q list selected by qosgrp.
18670 + uint64_t loc_tail:11;
18674 + * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1)
18677 + uint64_t reserved_52_63:12;
18679 + * set when there is one or more POW entries on the
18682 + uint64_t nosched_val:1;
18684 + * set when there is exactly one POW entry on the
18687 + uint64_t nosched_one:1;
18688 + uint64_t reserved_49:1;
18690 + * when nosched_val is set, indicates the first entry
18691 + * on the nosched list.
18693 + uint64_t nosched_head:11;
18694 + uint64_t reserved_37:1;
18696 + * when nosched_val is set, indicates the last entry
18697 + * on the nosched list.
18699 + uint64_t nosched_tail:11;
18701 + * set when there is one or more descheduled heads on
18702 + * the descheduled list selected by qosgrp.
18704 + uint64_t des_val:1;
18706 + * set when there is exactly one descheduled head on
18707 + * the descheduled list selected by qosgrp.
18709 + uint64_t des_one:1;
18710 + uint64_t reserved_23:1;
18712 + * when des_val is set, indicates the first
18713 + * descheduled head on the descheduled list selected
18716 + uint64_t des_head:11;
18717 + uint64_t reserved_11:1;
18719 + * when des_val is set, indicates the last descheduled
18720 + * head on the descheduled list selected by qosgrp.
18722 + uint64_t des_tail:11;
18726 + * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0)
18729 + uint64_t reserved_39_63:25;
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.
18738 + uint64_t rmt_is_head:1;
18740 + * Set when the DRAM portion of the input Q list
18741 + * selected by qosgrp contains one or more pieces of
18744 + uint64_t rmt_val:1;
18746 + * Set when the DRAM portion of the input Q list
18747 + * selected by qosgrp contains exactly one piece of
18750 + uint64_t rmt_one:1;
18752 + * When rmt_val is set, indicates the first piece of
18753 + * work on the DRAM input Q list selected by
18756 + uint64_t rmt_head:36;
18760 + * Result For POW Index/Pointer Load (get_rmt ==
18761 + * 1/get_des_get_tail == 1)
18764 + uint64_t reserved_39_63:25;
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.
18773 + uint64_t rmt_is_head:1;
18775 + * set when the DRAM portion of the input Q list
18776 + * selected by qosgrp contains one or more pieces of
18779 + uint64_t rmt_val:1;
18781 + * set when the DRAM portion of the input Q list
18782 + * selected by qosgrp contains exactly one piece of
18785 + uint64_t rmt_one:1;
18787 + * when rmt_val is set, indicates the last piece of
18788 + * work on the DRAM input Q list selected by
18791 + uint64_t rmt_tail:36;
18795 + * Response to NULL_RD request loads
18798 + uint64_t unused:62;
18799 + /* of type cvmx_pow_tag_type_t. state is one of the
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
18807 + uint64_t state:2;
18810 +} cvmx_pow_tag_load_resp_t;
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
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
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
18837 + * Unsigned 64 bit integer representation of store address
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. */
18848 + uint64_t reserved_36_39:4; /* Must be zero */
18849 + /* Address field. addr<2:0> must be zero */
18850 + uint64_t addr:36;
18852 +} cvmx_pow_tag_store_addr_t;
18855 + * decode of the store data when an IOBDMA SENDSINGLE is sent to POW
18862 + * the (64-bit word) location in scratchpad to write
18863 + * to (if len != 0)
18865 + uint64_t scraddr:8;
18866 + /* the number of words in the response (0 => no response) */
18868 + /* the ID of the device on the non-coherent bus */
18870 + uint64_t unused:36;
18871 + /* if set, don't return load response until work is available */
18873 + uint64_t unused2:3;
18876 +} cvmx_pow_iobdma_store_t;
18878 +/* CSR typedefs have been moved to cvmx-csr-*.h */
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.
18887 + * Returns Current tag
18889 +static inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void)
18891 + cvmx_pow_load_addr_t load_addr;
18892 + cvmx_pow_tag_load_resp_t load_resp;
18893 + cvmx_pow_tag_req_t result;
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);
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;
18911 + * Get the POW WQE for this core. This returns the work queue
18912 + * entry currently associated with this core.
18914 + * Returns WQE pointer
18916 +static inline cvmx_wqe_t *cvmx_pow_get_current_wqp(void)
18918 + cvmx_pow_load_addr_t load_addr;
18919 + cvmx_pow_tag_load_resp_t load_resp;
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);
18932 +#ifndef CVMX_MF_CHORD
18933 +#define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30)
18937 + * Print a warning if a tag switch is pending for this core
18939 + * @function: Function name checking for a pending tag switch
18941 +static inline void __cvmx_pow_warn_if_pending_switch(const char *function)
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);
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.
18954 +static inline void cvmx_pow_tag_sw_wait(void)
18956 + const uint64_t MAX_CYCLES = 1ull << 31;
18957 + uint64_t switch_complete;
18958 + uint64_t start_cycle = cvmx_get_cycle();
18960 + CVMX_MF_CHORD(switch_complete);
18961 + if (unlikely(switch_complete))
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;
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.
18976 + * @wait: When set, call stalls until work becomes avaiable, or times out.
18977 + * If not set, returns immediately.
18979 + * Returns Returns the WQE pointer from POW. Returns NULL if no work
18982 +static inline cvmx_wqe_t *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t
18985 + cvmx_pow_load_addr_t ptr;
18986 + cvmx_pow_tag_load_resp_t result;
18988 + if (CVMX_ENABLE_POW_CHECKS)
18989 + __cvmx_pow_warn_if_pending_switch(__func__);
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;
18997 + result.u64 = cvmx_read_csr(ptr.u64);
18999 + if (result.s_work.no_work)
19002 + return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
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.
19010 + * @wait: When set, call stalls until work becomes avaiable, or times out.
19011 + * If not set, returns immediately.
19013 + * Returns Returns the WQE pointer from POW. Returns NULL if no work
19016 +static inline cvmx_wqe_t *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
19018 + if (CVMX_ENABLE_POW_CHECKS)
19019 + __cvmx_pow_warn_if_pending_switch(__func__);
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);
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.
19032 + * Returns Returns the POW state of type cvmx_pow_tag_type_t.
19034 +static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void)
19036 + cvmx_pow_load_addr_t ptr;
19037 + cvmx_pow_tag_load_resp_t result;
19039 + if (CVMX_ENABLE_POW_CHECKS)
19040 + __cvmx_pow_warn_if_pending_switch(__func__);
19042 + /* Must not have a switch pending when requesting work */
19043 + cvmx_pow_tag_sw_wait();
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;
19050 + result.u64 = cvmx_read_csr(ptr.u64);
19052 + return (enum cvmx_pow_tag_type) result.s_null_rd.state;
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.
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.
19066 + * @wait: 1 to cause response to wait for work to become available (or
19067 + * timeout), 0 to cause response to return immediately
19069 +static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
19070 + cvmx_pow_wait_t wait)
19072 + cvmx_pow_iobdma_store_t data;
19074 + if (CVMX_ENABLE_POW_CHECKS)
19075 + __cvmx_pow_warn_if_pending_switch(__func__);
19077 + /* scr_addr must be 8 byte aligned */
19078 + data.s.scraddr = scr_addr >> 3;
19080 + data.s.did = CVMX_OCT_DID_TAG_SWTAG;
19081 + data.s.wait = wait;
19082 + cvmx_send_single(data.u64);
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.
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.
19095 + * @wait: 1 to cause response to wait for work to become available (or
19096 + * timeout), 0 to cause response to return immediately
19098 +static inline void cvmx_pow_work_request_async(int scr_addr,
19099 + cvmx_pow_wait_t wait)
19101 + if (CVMX_ENABLE_POW_CHECKS)
19102 + __cvmx_pow_warn_if_pending_switch(__func__);
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);
19110 + * Gets result of asynchronous work request. Performs a IOBDMA sync
19111 + * to wait for the response.
19113 + * @scr_addr: Scratch memory address to get result from Byte address,
19114 + * must be 8 byte aligned.
19116 + * Returns Returns the WQE from the scratch register, or NULL if no
19117 + * work was available.
19119 +static inline cvmx_wqe_t *cvmx_pow_work_response_async(int scr_addr)
19121 + cvmx_pow_tag_load_resp_t result;
19124 + result.u64 = cvmx_scratch_read64(scr_addr);
19126 + if (result.s_work.no_work)
19129 + return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
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.
19137 + * @wqe_ptr: pointer to a work queue entry returned by the POW
19139 + * Returns 0 if pointer is valid
19140 + * 1 if invalid (no work was returned)
19142 +static inline uint64_t cvmx_pow_work_invalid(cvmx_wqe_t *wqe_ptr)
19144 + return wqe_ptr == NULL;
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.
19156 + * NOTE: This should not be used when switching from a NULL tag. Use
19157 + * cvmx_pow_tag_sw_full() instead.
19159 + * This function does no checks, so the caller must ensure that any
19160 + * previous tag switch has completed.
19162 + * @tag: new tag value
19163 + * @tag_type: new tag type (ordered or atomic)
19165 +static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag,
19166 + enum cvmx_pow_tag_type tag_type)
19169 + cvmx_pow_tag_req_t tag_req;
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",
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 "
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",
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.
19200 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
19201 + tag_req.s.tag = tag;
19202 + tag_req.s.type = tag_type;
19205 + ptr.sio.mem_region = CVMX_IO_SEG;
19206 + ptr.sio.is_io = 1;
19207 + ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
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);
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.
19223 + * NOTE: This should not be used when switching from a NULL tag. Use
19224 + * cvmx_pow_tag_sw_full() instead.
19226 + * This function waits for any previous tag switch to complete, and also
19227 + * displays an error on tag switches to NULL.
19229 + * @tag: new tag value
19230 + * @tag_type: new tag type (ordered or atomic)
19232 +static inline void cvmx_pow_tag_sw(uint32_t tag,
19233 + enum cvmx_pow_tag_type tag_type)
19235 + if (CVMX_ENABLE_POW_CHECKS)
19236 + __cvmx_pow_warn_if_pending_switch(__func__);
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.
19247 + * Ensure that there is not a pending tag switch, as a tag
19248 + * switch cannot be started if a previous switch is still
19251 + cvmx_pow_tag_sw_wait();
19252 + cvmx_pow_tag_sw_nocheck(tag, tag_type);
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.
19264 + * This function must be used for tag switches from NULL.
19266 + * This function does no checks, so the caller must ensure that any
19267 + * previous tag switch has completed.
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.
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,
19280 + cvmx_pow_tag_req_t tag_req;
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",
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",
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",
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",
19303 + cvmx_pow_get_current_wqp());
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.
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;
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);
19327 + * once this store arrives at POW, it will attempt the switch
19328 + * software must wait for the switch to complete separately.
19330 + cvmx_write_io(ptr.u64, tag_req.u64);
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.
19342 + * This function must be used for tag switches from NULL.
19344 + * This function waits for any pending tag switches to complete
19345 + * before requesting the tag switch.
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.
19353 +static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag,
19354 + enum cvmx_pow_tag_type tag_type,
19357 + if (CVMX_ENABLE_POW_CHECKS)
19358 + __cvmx_pow_warn_if_pending_switch(__func__);
19361 + * Ensure that there is not a pending tag switch, as a tag
19362 + * switch cannot be started if a previous switch is still
19365 + cvmx_pow_tag_sw_wait();
19366 + cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group);
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.
19377 +static inline void cvmx_pow_tag_sw_null_nocheck(void)
19380 + cvmx_pow_tag_req_t tag_req;
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",
19389 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19390 + pr_warning("%s called when we already have a "
19396 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
19397 + tag_req.s.type = CVMX_POW_TAG_TYPE_NULL;
19400 + ptr.sio.mem_region = CVMX_IO_SEG;
19401 + ptr.sio.is_io = 1;
19402 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
19404 + cvmx_write_io(ptr.u64, tag_req.u64);
19406 + /* switch to NULL completes immediately */
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.
19417 +static inline void cvmx_pow_tag_sw_null(void)
19419 + if (CVMX_ENABLE_POW_CHECKS)
19420 + __cvmx_pow_warn_if_pending_switch(__func__);
19423 + * Ensure that there is not a pending tag switch, as a tag
19424 + * switch cannot be started if a previous switch is still
19427 + cvmx_pow_tag_sw_wait();
19428 + cvmx_pow_tag_sw_null_nocheck();
19430 + /* switch to NULL completes immediately */
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.
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.
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)
19451 + cvmx_pow_tag_req_t tag_req;
19455 + wqp->tag_type = tag_type;
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;
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);
19472 + * SYNC write to memory before the work submit. This is
19473 + * necessary as POW may read values from DRAM at this time.
19476 + cvmx_write_io(ptr.u64, tag_req.u64);
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
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.
19490 +static inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask)
19492 + union cvmx_pow_pp_grp_mskx grp_msk;
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);
19500 + * This function sets POW static priorities for a core. Each input queue has
19501 + * an associated priority value.
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.
19512 +static inline void cvmx_pow_set_priority(uint64_t core_num,
19513 + const uint8_t priority[])
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;
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];
19529 + /* Detect gaps between priorities and flag error */
19532 + uint32_t prio_mask = 0;
19534 + for (i = 0; i < 8; i++)
19535 + if (priority[i] != 0xF)
19536 + prio_mask |= 1 << priority[i];
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);
19546 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
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.
19555 + * This function does NOT wait for any prior tag switches to complete, so the
19556 + * calling code must do this.
19558 + * Note the following CAVEAT of the Octeon HW behavior when
19559 + * re-scheduling DE-SCHEDULEd items whose (next) state is
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
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
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.
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.
19591 +static inline void cvmx_pow_tag_sw_desched_nocheck(
19593 + enum cvmx_pow_tag_type tag_type,
19595 + uint64_t no_sched)
19598 + cvmx_pow_tag_req_t tag_req;
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",
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",
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",
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;
19626 + ptr.sio.mem_region = CVMX_IO_SEG;
19627 + ptr.sio.is_io = 1;
19628 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
19630 + * since TAG3 is used, this store will clear the local pending
19633 + cvmx_write_io(ptr.u64, tag_req.u64);
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.
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.
19644 + * Note the following CAVEAT of the Octeon HW behavior when
19645 + * re-scheduling DE-SCHEDULEd items whose (next) state is
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
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
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.
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.
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)
19681 + if (CVMX_ENABLE_POW_CHECKS)
19682 + __cvmx_pow_warn_if_pending_switch(__func__);
19684 + /* Need to make sure any writes to the work queue entry are complete */
19687 + * Ensure that there is not a pending tag switch, as a tag
19688 + * switch cannot be started if a previous switch is still
19691 + cvmx_pow_tag_sw_wait();
19692 + cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched);
19696 + * Descchedules the current work queue entry.
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
19702 +static inline void cvmx_pow_desched(uint64_t no_sched)
19705 + cvmx_pow_tag_req_t tag_req;
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",
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",
19720 + /* Need to make sure any writes to the work queue entry are complete */
19724 + tag_req.s.op = CVMX_POW_TAG_OP_DESCH;
19725 + tag_req.s.no_sched = no_sched;
19728 + ptr.sio.mem_region = CVMX_IO_SEG;
19729 + ptr.sio.is_io = 1;
19730 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
19732 + * since TAG3 is used, this store will clear the local pending
19735 + cvmx_write_io(ptr.u64, tag_req.u64);
19738 +/****************************************************
19739 +* Define usage of bits within the 32 bit tag values.
19740 +*****************************************************/
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
19749 +#define CVMX_TAG_SW_BITS (8)
19750 +#define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS)
19752 +/* Below is the list of values for the top 8 bits of the tag. */
19754 + * Tag values with top byte of this value are reserved for internal
19755 + * executive uses.
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
19761 + * - the lower 16 bits (bits 15 - 0 of the tag) define are the value
19762 + * with the subgroup
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.
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
19774 +/* End of executive tag subgroup definitions */
19777 + * The remaining values software bit values 0x2 - 0xff are available
19778 + * for application use.
19782 + * This function creates a 32 bit tag value from the two values provided.
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.
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.
19792 + * Returns 32 bit value of the combined hw and sw bits.
19794 +static inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits)
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));
19802 + * Extracts the bits allocated for software use from the tag
19804 + * @tag: 32 bit tag value
19806 + * Returns N bit software tag value, where N is configurable with the
19807 + * CVMX_TAG_SW_BITS define
19809 +static inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag)
19811 + return (tag >> (32 - CVMX_TAG_SW_BITS)) &
19812 + cvmx_build_mask(CVMX_TAG_SW_BITS);
19817 + * Extracts the bits allocated for hardware use from the tag
19819 + * @tag: 32 bit tag value
19821 + * Returns (32 - N) bit software tag value, where N is configurable
19822 + * with the CVMX_TAG_SW_BITS define
19824 +static inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag)
19826 + return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS);
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.
19835 + * @buffer: Buffer to store capture into
19837 + * The size of the supplied buffer
19839 + * Returns Zero on sucess, negative on failure
19841 +extern int cvmx_pow_capture(void *buffer, int buffer_size);
19844 + * Dump a POW capture to the console in a human readable format.
19846 + * @buffer: POW capture from cvmx_pow_capture()
19848 + * Size of the buffer
19850 +extern void cvmx_pow_display(void *buffer, int buffer_size);
19853 + * Return the number of POW entries supported by this chip
19855 + * Returns Number of POW entries
19857 +extern int cvmx_pow_get_num_entries(void);
19859 +#endif /* __CVMX_POW_H__ */
19861 +++ b/drivers/staging/octeon/cvmx-scratch.h
19863 +/***********************license start***************
19864 + * Author: Cavium Networks
19866 + * Contact: support@caviumnetworks.com
19867 + * This file is part of the OCTEON SDK
19869 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
19886 + * This file may also be available under a different license from Cavium.
19887 + * Contact Cavium Networks for more information
19888 + ***********************license end**************************************/
19892 + * This file provides support for the processor local scratch memory.
19893 + * Scratch memory is byte addressable - all addresses are byte addresses.
19897 +#ifndef __CVMX_SCRATCH_H__
19898 +#define __CVMX_SCRATCH_H__
19901 + * Note: This define must be a long, not a long long in order to
19902 + * compile without warnings for both 32bit and 64bit.
19904 +#define CVMX_SCRATCH_BASE (-32768l) /* 0xffffffffffff8000 */
19907 + * Reads an 8 bit value from the processor local scratchpad memory.
19909 + * @address: byte address to read from
19911 + * Returns value read
19913 +static inline uint8_t cvmx_scratch_read8(uint64_t address)
19915 + return *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address);
19919 + * Reads a 16 bit value from the processor local scratchpad memory.
19921 + * @address: byte address to read from
19923 + * Returns value read
19925 +static inline uint16_t cvmx_scratch_read16(uint64_t address)
19927 + return *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address);
19931 + * Reads a 32 bit value from the processor local scratchpad memory.
19933 + * @address: byte address to read from
19935 + * Returns value read
19937 +static inline uint32_t cvmx_scratch_read32(uint64_t address)
19939 + return *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address);
19943 + * Reads a 64 bit value from the processor local scratchpad memory.
19945 + * @address: byte address to read from
19947 + * Returns value read
19949 +static inline uint64_t cvmx_scratch_read64(uint64_t address)
19951 + return *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address);
19955 + * Writes an 8 bit value to the processor local scratchpad memory.
19957 + * @address: byte address to write to
19958 + * @value: value to write
19960 +static inline void cvmx_scratch_write8(uint64_t address, uint64_t value)
19962 + *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address) =
19967 + * Writes a 32 bit value to the processor local scratchpad memory.
19969 + * @address: byte address to write to
19970 + * @value: value to write
19972 +static inline void cvmx_scratch_write16(uint64_t address, uint64_t value)
19974 + *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address) =
19975 + (uint16_t) value;
19979 + * Writes a 16 bit value to the processor local scratchpad memory.
19981 + * @address: byte address to write to
19982 + * @value: value to write
19984 +static inline void cvmx_scratch_write32(uint64_t address, uint64_t value)
19986 + *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address) =
19987 + (uint32_t) value;
19991 + * Writes a 64 bit value to the processor local scratchpad memory.
19993 + * @address: byte address to write to
19994 + * @value: value to write
19996 +static inline void cvmx_scratch_write64(uint64_t address, uint64_t value)
19998 + *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address) = value;
20001 +#endif /* __CVMX_SCRATCH_H__ */
20003 +++ b/drivers/staging/octeon/cvmx-smix-defs.h
20005 +/***********************license start***************
20006 + * Author: Cavium Networks
20008 + * Contact: support@caviumnetworks.com
20009 + * This file is part of the OCTEON SDK
20011 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
20028 + * This file may also be available under a different license from Cavium.
20029 + * Contact Cavium Networks for more information
20030 + ***********************license end**************************************/
20032 +#ifndef __CVMX_SMIX_DEFS_H__
20033 +#define __CVMX_SMIX_DEFS_H__
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))
20046 +union cvmx_smix_clk {
20048 + struct cvmx_smix_clk_s {
20049 + uint64_t reserved_25_63:39;
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;
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;
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;
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;
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;
20091 +union cvmx_smix_cmd {
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;
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;
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;
20121 +union cvmx_smix_en {
20123 + struct cvmx_smix_en_s {
20124 + uint64_t reserved_1_63:63;
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;
20140 +union cvmx_smix_rd_dat {
20142 + struct cvmx_smix_rd_dat_s {
20143 + uint64_t reserved_18_63:46;
20144 + uint64_t pending:1;
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;
20161 +union cvmx_smix_wr_dat {
20163 + struct cvmx_smix_wr_dat_s {
20164 + uint64_t reserved_18_63:46;
20165 + uint64_t pending:1;
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;
20184 +++ b/drivers/staging/octeon/cvmx-spi.c
20186 +/***********************license start***************
20187 + * Author: Cavium Networks
20189 + * Contact: support@caviumnetworks.com
20190 + * This file is part of the OCTEON SDK
20192 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
20209 + * This file may also be available under a different license from Cavium.
20210 + * Contact Cavium Networks for more information
20211 + ***********************license end**************************************/
20215 + * Support library for the SPI
20217 +#include <asm/octeon/octeon.h>
20219 +#include "cvmx-config.h"
20221 +#include "cvmx-pko.h"
20222 +#include "cvmx-spi.h"
20224 +#include "cvmx-spxx-defs.h"
20225 +#include "cvmx-stxx-defs.h"
20226 +#include "cvmx-srxx-defs.h"
20228 +#define INVOKE_CB(function_p, args...) \
20230 + if (function_p) { \
20231 + res = function_p(args); \
20237 +#if CVMX_ENABLE_DEBUG_PRINTS
20238 +static const char *modes[] =
20239 + { "UNKNOWN", "TX Halfplex", "Rx Halfplex", "Duplex" };
20242 +/* Default callbacks, can be overridden
20243 + * using cvmx_spi_get_callbacks/cvmx_spi_set_callbacks
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
20255 + * Get current SPI4 initialization callbacks
20257 + * @callbacks: Pointer to the callbacks structure.to fill
20259 + * Returns Pointer to cvmx_spi_callbacks_t structure.
20261 +void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks)
20263 + memcpy(callbacks, &cvmx_spi_callbacks, sizeof(cvmx_spi_callbacks));
20267 + * Set new SPI4 initialization callbacks
20269 + * @new_callbacks: Pointer to an updated callbacks structure.
20271 +void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks)
20273 + memcpy(&cvmx_spi_callbacks, new_callbacks, sizeof(cvmx_spi_callbacks));
20277 + * Initialize and start the SPI interface.
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
20288 + * Returns Zero on success, negative of failure.
20290 +int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout,
20295 + if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
20298 + /* Callback to perform SPI4 reset */
20299 + INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
20301 + /* Callback to perform calendar setup */
20302 + INVOKE_CB(cvmx_spi_callbacks.calendar_setup_cb, interface, mode,
20305 + /* Callback to perform clock detection */
20306 + INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
20308 + /* Callback to perform SPI4 link training */
20309 + INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
20311 + /* Callback to perform calendar sync */
20312 + INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
20315 + /* Callback to handle interface coming up */
20316 + INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
20322 + * This routine restarts the SPI interface after it has lost synchronization
20323 + * with its correspondent system.
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
20333 + * Returns Zero on success, negative of failure.
20335 +int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout)
20339 + if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
20342 + cvmx_dprintf("SPI%d: Restart %s\n", interface, modes[mode]);
20344 + /* Callback to perform SPI4 reset */
20345 + INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
20347 + /* NOTE: Calendar setup is not performed during restart */
20348 + /* Refer to cvmx_spi_start_interface() for the full sequence */
20350 + /* Callback to perform clock detection */
20351 + INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
20353 + /* Callback to perform SPI4 link training */
20354 + INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
20356 + /* Callback to perform calendar sync */
20357 + INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
20360 + /* Callback to handle interface coming up */
20361 + INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
20367 + * Callback to perform SPI4 reset
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).
20376 + * Returns Zero on success, non-zero error code on failure (will cause
20377 + * SPI initialization to abort)
20379 +int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode)
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;
20388 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
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);
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)
20406 + ("ERROR SPI%d: BIST failed on receive datapath FIFO\n",
20408 + if (spxx_bist_stat.s.stat1)
20409 + cvmx_dprintf("ERROR SPI%d: BIST failed on RX calendar table\n",
20411 + if (spxx_bist_stat.s.stat2)
20412 + cvmx_dprintf("ERROR SPI%d: BIST failed on TX calendar table\n",
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;
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);
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);
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);
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);
20454 + /* Reset SRX0 DLL */
20455 + spxx_clk_ctl.s.srxdlck = 1;
20456 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20458 + /* Waiting for Inf0 Spi4 RX DLL to lock */
20459 + cvmx_wait(100 * MS);
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;
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);
20474 + spxx_dbg_deskew_ctl.u64 = 0;
20475 + cvmx_write_csr(CVMX_SPXX_DBG_DESKEW_CTL(interface),
20476 + spxx_dbg_deskew_ctl.u64);
20482 + * Callback to setup calendar and miscellaneous settings before clock detection
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
20492 + * Returns Zero on success, non-zero error code on failure (will cause
20493 + * SPI initialization to abort)
20495 +int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
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;
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);
20511 + /* SRX0 Calendar Table. This round robbins through all ports */
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);
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);
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;
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);
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);
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);
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);
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);
20574 + /* STX0 Calendar Table. This round robbins through all ports */
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);
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);
20601 + * Callback to perform clock detection
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
20611 + * Returns Zero on success, non-zero error code on failure (will cause
20612 + * SPI initialization to abort)
20614 +int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout)
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;
20622 + * Regardless of operating mode, both Tx and Rx clocks must be
20623 + * present for the SPI interface to operate.
20625 + cvmx_dprintf("SPI%d: Waiting to see TsClk...\n", interface);
20626 + timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20628 + * Require 100 clock transitions in order to avoid any noise
20629 + * in the beginning.
20631 + clock_transitions = 100;
20633 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20634 + if (stat.s.s4clk0 && stat.s.s4clk1 && clock_transitions) {
20636 + * We've seen a clock transition, so decrement
20637 + * the number we still need.
20639 + clock_transitions--;
20640 + cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20641 + stat.s.s4clk0 = 0;
20642 + stat.s.s4clk1 = 0;
20644 + if (cvmx_get_cycle() > timeout_time) {
20645 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20648 + } while (stat.s.s4clk0 == 0 || stat.s.s4clk1 == 0);
20650 + cvmx_dprintf("SPI%d: Waiting to see RsClk...\n", interface);
20651 + timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20653 + * Require 100 clock transitions in order to avoid any noise in the
20656 + clock_transitions = 100;
20658 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20659 + if (stat.s.d4clk0 && stat.s.d4clk1 && clock_transitions) {
20661 + * We've seen a clock transition, so decrement
20662 + * the number we still need
20664 + clock_transitions--;
20665 + cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20666 + stat.s.d4clk0 = 0;
20667 + stat.s.d4clk1 = 0;
20669 + if (cvmx_get_cycle() > timeout_time) {
20670 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20673 + } while (stat.s.d4clk0 == 0 || stat.s.d4clk1 == 0);
20679 + * Callback to perform link training
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)
20689 + * Returns Zero on success, non-zero error code on failure (will cause
20690 + * SPI initialization to abort)
20692 +int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout)
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;
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);
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);
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;
20727 + * The HRM says we must wait for 34 + 16 * MAXDIST training sequences.
20728 + * We'll be pessimistic and wait for a lot more.
20730 + rx_training_needed = 500;
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;
20738 + if (cvmx_get_cycle() > timeout_time) {
20739 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20742 + } while (stat.s.srxtrn == 0);
20748 + * Callback to perform calendar data synchronization
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
20758 + * Returns Zero on success, non-zero error code on failure (will cause
20759 + * SPI initialization to abort)
20761 +int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout)
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;
20768 + ("SPI%d: Rx is synchronized, start sending calendar data\n",
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);
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);
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) */
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);
20798 + } while (stat.s.stxcal == 0);
20805 + * Callback to handle interface up
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).
20814 + * Returns Zero on success, non-zero error code on failure (will cause
20815 + * SPI initialization to abort)
20817 +int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode)
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;
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);
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);
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);
20854 +++ b/drivers/staging/octeon/cvmx-spi.h
20856 +/***********************license start***************
20857 + * Author: Cavium Networks
20859 + * Contact: support@caviumnetworks.com
20860 + * This file is part of the OCTEON SDK
20862 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
20879 + * This file may also be available under a different license from Cavium.
20880 + * Contact Cavium Networks for more information
20881 + ***********************license end**************************************/
20885 + * This file contains defines for the SPI interface
20887 +#ifndef __CVMX_SPI_H__
20888 +#define __CVMX_SPI_H__
20890 +#include "cvmx-gmxx-defs.h"
20892 +/* CSR typedefs have been moved to cvmx-csr-*.h */
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;
20901 +/** Callbacks structure to customize SPI4 initialization sequence */
20903 + /** Called to reset SPI4 DLL */
20904 + int (*reset_cb) (int interface, cvmx_spi_mode_t mode);
20906 + /** Called to setup calendar */
20907 + int (*calendar_setup_cb) (int interface, cvmx_spi_mode_t mode,
20910 + /** Called for Tx and Rx clock detection */
20911 + int (*clock_detect_cb) (int interface, cvmx_spi_mode_t mode,
20914 + /** Called to perform link training */
20915 + int (*training_cb) (int interface, cvmx_spi_mode_t mode, int timeout);
20917 + /** Called for calendar data synchronization */
20918 + int (*calendar_sync_cb) (int interface, cvmx_spi_mode_t mode,
20921 + /** Called when interface is up */
20922 + int (*interface_up_cb) (int interface, cvmx_spi_mode_t mode);
20924 +} cvmx_spi_callbacks_t;
20927 + * Return true if the supplied interface is configured for SPI
20929 + * @interface: Interface to check
20930 + * Returns True if interface is SPI
20932 +static inline int cvmx_spi_is_spi_interface(int interface)
20934 + uint64_t gmxState = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
20935 + return (gmxState & 0x2) && (gmxState & 0x1);
20939 + * Initialize and start the SPI interface.
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
20950 + * Returns Zero on success, negative of failure.
20952 +extern int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode,
20953 + int timeout, int num_ports);
20956 + * This routine restarts the SPI interface after it has lost synchronization
20957 + * with its corespondant system.
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.
20968 +extern int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode,
20972 + * Return non-zero if the SPI interface has a SPI4000 attached
20974 + * @interface: SPI interface the SPI4000 is connected to
20978 +static inline int cvmx_spi4000_is_present(int interface)
20984 + * Initialize the SPI4000 for use
20986 + * @interface: SPI interface the SPI4000 is connected to
20988 +static inline int cvmx_spi4000_initialize(int interface)
20994 + * Poll all the SPI4000 port and check its speed
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.
21000 +static inline union cvmx_gmxx_rxx_rx_inbnd cvmx_spi4000_check_speed(
21004 + union cvmx_gmxx_rxx_rx_inbnd r;
21010 + * Get current SPI4 initialization callbacks
21012 + * @callbacks: Pointer to the callbacks structure.to fill
21014 + * Returns Pointer to cvmx_spi_callbacks_t structure.
21016 +extern void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks);
21019 + * Set new SPI4 initialization callbacks
21021 + * @new_callbacks: Pointer to an updated callbacks structure.
21023 +extern void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks);
21026 + * Callback to perform SPI4 reset
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).
21035 + * Returns Zero on success, non-zero error code on failure (will cause
21036 + * SPI initialization to abort)
21038 +extern int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode);
21041 + * Callback to setup calendar and miscellaneous settings before clock
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
21052 + * Returns Zero on success, non-zero error code on failure (will cause
21053 + * SPI initialization to abort)
21055 +extern int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
21059 + * Callback to perform clock detection
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
21069 + * Returns Zero on success, non-zero error code on failure (will cause
21070 + * SPI initialization to abort)
21072 +extern int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode,
21076 + * Callback to perform link training
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)
21086 + * Returns Zero on success, non-zero error code on failure (will cause
21087 + * SPI initialization to abort)
21089 +extern int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode,
21093 + * Callback to perform calendar data synchronization
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
21103 + * Returns Zero on success, non-zero error code on failure (will cause
21104 + * SPI initialization to abort)
21106 +extern int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode,
21110 + * Callback to handle interface up
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).
21119 + * Returns Zero on success, non-zero error code on failure (will cause
21120 + * SPI initialization to abort)
21122 +extern int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode);
21124 +#endif /* __CVMX_SPI_H__ */
21126 +++ b/drivers/staging/octeon/cvmx-spxx-defs.h
21128 +/***********************license start***************
21129 + * Author: Cavium Networks
21131 + * Contact: support@caviumnetworks.com
21132 + * This file is part of the OCTEON SDK
21134 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
21151 + * This file may also be available under a different license from Cavium.
21152 + * Contact Cavium Networks for more information
21153 + ***********************license end**************************************/
21155 +#ifndef __CVMX_SPXX_DEFS_H__
21156 +#define __CVMX_SPXX_DEFS_H__
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))
21191 +union cvmx_spxx_bckprs_cnt {
21193 + struct cvmx_spxx_bckprs_cnt_s {
21194 + uint64_t reserved_32_63:32;
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;
21203 +union cvmx_spxx_bist_stat {
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;
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;
21217 +union cvmx_spxx_clk_ctl {
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;
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;
21238 +union cvmx_spxx_clk_stat {
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;
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;
21257 +union cvmx_spxx_dbg_deskew_ctl {
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;
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;
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;
21283 +union cvmx_spxx_dbg_deskew_state {
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;
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;
21298 +union cvmx_spxx_drv_ctl {
21300 + struct cvmx_spxx_drv_ctl_s {
21301 + uint64_t reserved_0_63:64;
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;
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;
21317 + struct cvmx_spxx_drv_ctl_cn58xx cn58xxp1;
21320 +union cvmx_spxx_err_ctl {
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;
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;
21336 +union cvmx_spxx_int_dat {
21338 + struct cvmx_spxx_int_dat_s {
21339 + uint64_t reserved_32_63:32;
21341 + uint64_t reserved_14_30:17;
21342 + uint64_t calbnk:2;
21343 + uint64_t rsvop:4;
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;
21352 +union cvmx_spxx_int_msk {
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;
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;
21374 +union cvmx_spxx_int_reg {
21376 + struct cvmx_spxx_int_reg_s {
21377 + uint64_t reserved_32_63:32;
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;
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;
21398 +union cvmx_spxx_int_sync {
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;
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;
21420 +union cvmx_spxx_tpa_acc {
21422 + struct cvmx_spxx_tpa_acc_s {
21423 + uint64_t reserved_32_63:32;
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;
21432 +union cvmx_spxx_tpa_max {
21434 + struct cvmx_spxx_tpa_max_s {
21435 + uint64_t reserved_32_63:32;
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;
21444 +union cvmx_spxx_tpa_sel {
21446 + struct cvmx_spxx_tpa_sel_s {
21447 + uint64_t reserved_4_63:60;
21448 + uint64_t prtsel:4;
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;
21456 +union cvmx_spxx_trn4_ctl {
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;
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;
21476 +++ b/drivers/staging/octeon/cvmx-srxx-defs.h
21478 +/***********************license start***************
21479 + * Author: Cavium Networks
21481 + * Contact: support@caviumnetworks.com
21482 + * This file is part of the OCTEON SDK
21484 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
21501 + * This file may also be available under a different license from Cavium.
21502 + * Contact Cavium Networks for more information
21503 + ***********************license end**************************************/
21505 +#ifndef __CVMX_SRXX_DEFS_H__
21506 +#define __CVMX_SRXX_DEFS_H__
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))
21521 +union cvmx_srxx_com_ctl {
21523 + struct cvmx_srxx_com_ctl_s {
21524 + uint64_t reserved_8_63:56;
21526 + uint64_t st_en:1;
21527 + uint64_t reserved_1_2:2;
21528 + uint64_t inf_en:1;
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;
21536 +union cvmx_srxx_ign_rx_full {
21538 + struct cvmx_srxx_ign_rx_full_s {
21539 + uint64_t reserved_16_63:48;
21540 + uint64_t ignore:16;
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;
21548 +union cvmx_srxx_spi4_calx {
21550 + struct cvmx_srxx_spi4_calx_s {
21551 + uint64_t reserved_17_63:47;
21552 + uint64_t oddpar:1;
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;
21564 +union cvmx_srxx_spi4_stat {
21566 + struct cvmx_srxx_spi4_stat_s {
21567 + uint64_t reserved_16_63:48;
21569 + uint64_t reserved_7_7:1;
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;
21578 +union cvmx_srxx_sw_tick_ctl {
21580 + struct cvmx_srxx_sw_tick_ctl_s {
21581 + uint64_t reserved_14_63:50;
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;
21593 +union cvmx_srxx_sw_tick_dat {
21595 + struct cvmx_srxx_sw_tick_dat_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;
21605 +++ b/drivers/staging/octeon/cvmx-stxx-defs.h
21607 +/***********************license start***************
21608 + * Author: Cavium Networks
21610 + * Contact: support@caviumnetworks.com
21611 + * This file is part of the OCTEON SDK
21613 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
21630 + * This file may also be available under a different license from Cavium.
21631 + * Contact Cavium Networks for more information
21632 + ***********************license end**************************************/
21634 +#ifndef __CVMX_STXX_DEFS_H__
21635 +#define __CVMX_STXX_DEFS_H__
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))
21670 +union cvmx_stxx_arb_ctl {
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;
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;
21685 +union cvmx_stxx_bckprs_cnt {
21687 + struct cvmx_stxx_bckprs_cnt_s {
21688 + uint64_t reserved_32_63:32;
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;
21697 +union cvmx_stxx_com_ctl {
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;
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;
21711 +union cvmx_stxx_dip_cnt {
21713 + struct cvmx_stxx_dip_cnt_s {
21714 + uint64_t reserved_8_63:56;
21715 + uint64_t frmmax:4;
21716 + uint64_t dipmax:4;
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;
21724 +union cvmx_stxx_ign_cal {
21726 + struct cvmx_stxx_ign_cal_s {
21727 + uint64_t reserved_16_63:48;
21728 + uint64_t igntpa:16;
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;
21736 +union cvmx_stxx_int_msk {
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;
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;
21755 +union cvmx_stxx_int_reg {
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;
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;
21775 +union cvmx_stxx_int_sync {
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;
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;
21794 +union cvmx_stxx_min_bst {
21796 + struct cvmx_stxx_min_bst_s {
21797 + uint64_t reserved_9_63:55;
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;
21806 +union cvmx_stxx_spi4_calx {
21808 + struct cvmx_stxx_spi4_calx_s {
21809 + uint64_t reserved_17_63:47;
21810 + uint64_t oddpar:1;
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;
21822 +union cvmx_stxx_spi4_dat {
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;
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;
21835 +union cvmx_stxx_spi4_stat {
21837 + struct cvmx_stxx_spi4_stat_s {
21838 + uint64_t reserved_16_63:48;
21840 + uint64_t reserved_7_7:1;
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;
21849 +union cvmx_stxx_stat_bytes_hi {
21851 + struct cvmx_stxx_stat_bytes_hi_s {
21852 + uint64_t reserved_32_63:32;
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;
21861 +union cvmx_stxx_stat_bytes_lo {
21863 + struct cvmx_stxx_stat_bytes_lo_s {
21864 + uint64_t reserved_32_63:32;
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;
21873 +union cvmx_stxx_stat_ctl {
21875 + struct cvmx_stxx_stat_ctl_s {
21876 + uint64_t reserved_5_63:59;
21878 + uint64_t bckprs:4;
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;
21886 +union cvmx_stxx_stat_pkt_xmt {
21888 + struct cvmx_stxx_stat_pkt_xmt_s {
21889 + uint64_t reserved_32_63:32;
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;
21900 +++ b/drivers/staging/octeon/cvmx-wqe.h
21902 +/***********************license start***************
21903 + * Author: Cavium Networks
21905 + * Contact: support@caviumnetworks.com
21906 + * This file is part of the OCTEON SDK
21908 + * Copyright (c) 2003-2008 Cavium Networks
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.
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
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/.
21925 + * This file may also be available under a different license from Cavium.
21926 + * Contact Cavium Networks for more information
21927 + ***********************license end**************************************/
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
21936 + * Data structures are still named according to the block that they
21941 +#ifndef __CVMX_WQE_H__
21942 +#define __CVMX_WQE_H__
21944 +#include "cvmx-packet.h"
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" : \
21954 + * HW decode / err_code in work queue entry
21959 + /* Use this struct if the hardware determines that the packet is IP */
21961 + /* HW sets this to the number of buffers used by this packet */
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 */
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;
21987 + * (rcv_error, not_IP, IP_exc, is_frag, L4_error,
21988 + * software, etc.).
21992 + * reserved for software use, hardware will clear on
21993 + * packet creation.
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:
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
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
22012 + * - 9 = TCP No Flags: the packet is TCP and no flags
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.
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:
22030 + * - 1 = Not IP: the IP version field is neither 4 nor
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
22043 + uint64_t IP_exc:1;
22045 + * Set if the hardware determined that the packet is a
22048 + uint64_t is_bcast:1;
22050 + * St if the hardware determined that the packet is a
22053 + uint64_t is_mcast:1;
22055 + * Set if the packet may not be IP (must be zero in
22058 + uint64_t not_IP:1;
22060 + * The receive interface hardware detected a receive
22061 + * error (must be zero in this case).
22063 + uint64_t rcv_error:1;
22064 + /* lower err_code = first-level descriptor of the
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;
22072 + /* use this to get at the 16 vlan bits */
22074 + uint64_t unused1:16;
22075 + uint64_t vlan:16;
22076 + uint64_t unused2:32;
22080 + * use this struct if the hardware could not determine that
22081 + * the packet is ip.
22085 + * HW sets this to the number of buffers used by this
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;
22096 + * HW sets to the DSA/VLAN CFI flag (valid when
22099 + uint64_t vlan_cfi:1;
22101 + * HW sets to the DSA/VLAN_ID field (valid when
22104 + uint64_t vlan_id:12;
22106 + * Ring Identifier (if PCIe). Requires
22107 + * PIP_GBL_CTL[RING_EN]=1
22110 + uint64_t unassigned2:12;
22112 + * reserved for software use, hardware will clear on
22113 + * packet creation.
22115 + uint64_t software:1;
22116 + uint64_t unassigned3:1;
22118 + * set if the hardware determined that the packet is
22121 + uint64_t is_rarp:1;
22123 + * set if the hardware determined that the packet is
22126 + uint64_t is_arp:1;
22128 + * set if the hardware determined that the packet is a
22131 + uint64_t is_bcast:1;
22133 + * set if the hardware determined that the packet is a
22136 + uint64_t is_mcast:1;
22138 + * set if the packet may not be IP (must be one in
22141 + uint64_t not_IP:1;
22142 + /* The receive interface hardware detected a receive
22143 + * error. Failure indicated in err_code below,
22146 + * - 1 = partial error: a packet was partially
22147 + * received, but internal buffering / bandwidth
22148 + * was not adequate to receive the entire
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
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
22163 + * - 8 = undersize error: the RGMII packet is shorter
22165 + * - 9 = extend error: the RGMII packet had an extend
22167 + * - 10 = length mismatch error: the RGMII packet had
22168 + * a length that did not match the length field
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
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.
22189 + uint64_t rcv_error:1;
22191 + * lower err_code = first-level descriptor of the
22195 + * zero for packet submitted by hardware that isn't on
22198 + /* type is cvmx_pip_err_t (union, so can't use directly */
22199 + uint64_t err_code:8;
22202 +} cvmx_pip_wqe_word2;
22205 + * Work queue entry format
22207 + * must be 8-byte aligned
22211 + /*****************************************************************
22213 + * HW WRITE: the following 64 bits are filled by HW when a packet arrives
22217 + * raw chksum result generated by the HW
22219 + uint16_t hw_chksum;
22221 + * Field unused by hardware - available for software
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)
22230 + uint64_t next_ptr:40;
22232 + /*****************************************************************
22234 + * HW WRITE: the following 64 bits are filled by HW when a packet arrives
22238 + * HW sets to the total number of bytes in the packet
22242 + * HW sets this to input physical port
22244 + uint64_t ipprt:6;
22247 + * HW sets this to what it thought the priority of the input packet was
22252 + * the group that the work queue entry will be scheduled to
22256 + * the type of the tag (ORDERED, ATOMIC, NULL)
22258 + uint64_t tag_type:3;
22260 + * the synchronization/ordering tag
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.
22269 + cvmx_pip_wqe_word2 word2;
22272 + * Pointer to the first segment of the packet.
22274 + union cvmx_buf_ptr packet_ptr;
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
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.
22287 + uint8_t packet_data[96];
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.
22296 +} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;
22298 +#endif /* __CVMX_WQE_H__ */
22300 +++ b/drivers/staging/octeon/ethernet-common.c
22302 +/**********************************************************************
22303 + * Author: Cavium Networks
22305 + * Contact: support@caviumnetworks.com
22306 + * This file is part of the OCTEON SDK
22308 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
22332 +#include <asm/atomic.h>
22333 +#include <asm/octeon/octeon.h>
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"
22342 +#include "cvmx-pip.h"
22343 +#include "cvmx-pko.h"
22344 +#include "cvmx-fau.h"
22345 +#include "cvmx-helper.h"
22347 +#include "cvmx-gmxx-defs.h"
22350 + * Get the low level ethernet statistics
22352 + * @dev: Device to get the statistics from
22353 + * Returns Pointer to the statistics
22355 +static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
22357 + cvmx_pip_port_status_t rx_status;
22358 + cvmx_pko_port_status_t tx_status;
22359 + struct octeon_ethernet *priv = netdev_priv(dev);
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));
22367 + cvmx_pip_get_port_status(priv->port, 1, &rx_status);
22368 + cvmx_pko_get_port_status(priv->port, 1, &tx_status);
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;
22380 + * The drop counter must be incremented atomically
22381 + * since the RX tasklet also increments it.
22383 +#ifdef CONFIG_64BIT
22384 + atomic64_add(rx_status.dropped_packets,
22385 + (atomic64_t *)&priv->stats.rx_dropped);
22387 + atomic_add(rx_status.dropped_packets,
22388 + (atomic_t *)&priv->stats.rx_dropped);
22392 + return &priv->stats;
22396 + * Set the multicast list. Currently unimplemented.
22398 + * @dev: Device to work on
22400 +static void cvm_oct_common_set_multicast_list(struct net_device *dev)
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);
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;
22412 + control.s.bcst = 1; /* Allow broadcast MAC addresses */
22414 + if (dev->mc_list || (dev->flags & IFF_ALLMULTI) ||
22415 + (dev->flags & IFF_PROMISC))
22416 + /* Force accept multicast packets */
22417 + control.s.mcst = 2;
22419 + /* Force reject multicat packets */
22420 + control.s.mcst = 1;
22422 + if (dev->flags & IFF_PROMISC)
22424 + * Reject matches if promisc. Since CAM is
22425 + * shut off, should accept everything.
22427 + control.s.cam_mode = 0;
22429 + /* Filter packets based on the CAM */
22430 + control.s.cam_mode = 1;
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);
22437 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
22439 + if (dev->flags & IFF_PROMISC)
22440 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
22441 + (index, interface), 0);
22443 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
22444 + (index, interface), 1);
22446 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22452 + * Set the hardware MAC address for a device
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
22458 +static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
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);
22465 + memcpy(dev->dev_addr, addr + 2, 6);
22467 + if ((interface < 2)
22468 + && (cvmx_helper_interface_get_mode(interface) !=
22469 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
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]);
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);
22481 + cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
22482 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
22484 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
22486 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
22488 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
22490 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
22492 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
22494 + cvm_oct_common_set_multicast_list(dev);
22495 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22502 + * Change the link MTU. Unimplemented
22504 + * @dev: Device to change
22505 + * @new_mtu: The new MTU
22507 + * Returns Zero on success
22509 +static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
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;
22517 + int vlan_bytes = 0;
22521 + * Limit the MTU to make sure the ethernet packets are between
22522 + * 64 bytes and 65535 bytes.
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);
22530 + dev->mtu = new_mtu;
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;
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),
22545 + * Set the hardware to truncate packets larger
22546 + * than the MTU and smaller the 64 bytes.
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);
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.
22560 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
22561 + (max_packet + 7) & ~7u);
22567 + * Per network device initialization
22569 + * @dev: Device to initialize
22570 + * Returns Zero on success
22572 +int cvm_oct_common_init(struct net_device *dev)
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
22583 + struct octeon_ethernet *priv = netdev_priv(dev);
22586 + * Force the interface to use the POW send if always_use_pow
22587 + * was specified or it is in the pow send list.
22589 + if ((pow_send_group != -1)
22590 + && (always_use_pow || strstr(pow_send_list, dev->name)))
22591 + priv->queue = -1;
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;
22598 + dev->hard_start_xmit = cvm_oct_xmit_pow;
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;
22613 + cvm_oct_mdio_setup_device(dev);
22614 + dev->set_mac_address(dev, mac);
22615 + dev->change_mtu(dev, dev->mtu);
22618 + * Zero out stats for port so we won't mistakenly show
22619 + * counters from the bootloader.
22621 + memset(dev->get_stats(dev), 0, sizeof(struct net_device_stats));
22626 +void cvm_oct_common_uninit(struct net_device *dev)
22628 + /* Currently nothing to do */
22631 +++ b/drivers/staging/octeon/ethernet-common.h
22633 +/*********************************************************************
22634 + * Author: Cavium Networks
22636 + * Contact: support@caviumnetworks.com
22637 + * This file is part of the OCTEON SDK
22639 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
22656 + * This file may also be available under a different license from Cavium.
22657 + * Contact Cavium Networks for more information
22658 +*********************************************************************/
22660 +int cvm_oct_common_init(struct net_device *dev);
22661 +void cvm_oct_common_uninit(struct net_device *dev);
22663 +++ b/drivers/staging/octeon/ethernet-defines.h
22665 +/**********************************************************************
22666 + * Author: Cavium Networks
22668 + * Contact: support@caviumnetworks.com
22669 + * This file is part of the OCTEON SDK
22671 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
22688 + * This file may also be available under a different license from Cavium.
22689 + * Contact Cavium Networks for more information
22690 +**********************************************************************/
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
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
22730 +#ifndef __ETHERNET_DEFINES_H__
22731 +#define __ETHERNET_DEFINES_H__
22733 +#include "cvmx-config.h"
22736 +#define OCTEON_ETHERNET_VERSION "1.9"
22738 +#ifndef CONFIG_CAVIUM_RESERVE32
22739 +#define CONFIG_CAVIUM_RESERVE32 0
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
22747 +#define USE_32BIT_SHARED 0
22748 +#define USE_SKBUFFS_IN_HW 1
22749 +#ifdef CONFIG_NETFILTER
22750 +#define REUSE_SKBUFFS_WITHOUT_FREE 0
22752 +#define REUSE_SKBUFFS_WITHOUT_FREE 1
22756 +/* Max interrupts per second per core */
22757 +#define INTERRUPT_LIMIT 10000
22759 +/* Don't limit the number of interrupts */
22760 +/*#define INTERRUPT_LIMIT 0 */
22761 +#define USE_HW_TCPUDP_CHECKSUM 1
22763 +#define USE_MULTICORE_RECEIVE 1
22765 +/* Enable Random Early Dropping under load */
22767 +#define USE_ASYNC_IOBDMA (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0)
22770 + * Allow SW based preamble removal at 10Mbps to workaround PHYs giving
22771 + * us bad preambles.
22773 +#define USE_10MBPS_PREAMBLE_WORKAROUND 1
22775 + * Use this to have all FPA frees also tell the L2 not to write data
22778 +#define DONT_WRITEBACK(x) (x)
22779 +/* Use this to not have FPA frees control L2 */
22780 +/*#define DONT_WRITEBACK(x) 0 */
22782 +/* Maximum number of packets to process per interrupt. */
22783 +#define MAX_RX_PACKETS 120
22784 +#define MAX_OUT_QUEUE_DEPTH 1000
22786 +#ifndef CONFIG_SMP
22787 +#undef USE_MULTICORE_RECEIVE
22788 +#define USE_MULTICORE_RECEIVE 0
22791 +#define IP_PROTOCOL_TCP 6
22792 +#define IP_PROTOCOL_UDP 0x11
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)
22798 +#endif /* __ETHERNET_DEFINES_H__ */
22800 +++ b/drivers/staging/octeon/ethernet-mdio.c
22802 +/**********************************************************************
22803 + * Author: Cavium Networks
22805 + * Contact: support@caviumnetworks.com
22806 + * This file is part of the OCTEON SDK
22808 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
22833 +#include <asm/octeon/octeon.h>
22835 +#include "ethernet-defines.h"
22836 +#include "octeon-ethernet.h"
22837 +#include "ethernet-mdio.h"
22839 +#include "cvmx-helper-board.h"
22841 +#include "cvmx-smix-defs.h"
22843 +DECLARE_MUTEX(mdio_sem);
22846 + * Perform an MII read. Called by the generic MII routines
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
22853 +static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location)
22855 + union cvmx_smix_cmd smi_cmd;
22856 + union cvmx_smix_rd_dat smi_rd;
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);
22865 + if (!in_interrupt())
22867 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0));
22868 + } while (smi_rd.s.pending);
22870 + if (smi_rd.s.val)
22871 + return smi_rd.s.dat;
22876 +static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id,
22883 + * Perform an MII write. Called by the generic MII routines
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
22890 +static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location,
22893 + union cvmx_smix_cmd smi_cmd;
22894 + union cvmx_smix_wr_dat smi_wr;
22897 + smi_wr.s.dat = val;
22898 + cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64);
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);
22907 + if (!in_interrupt())
22909 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0));
22910 + } while (smi_wr.s.pending);
22913 +static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id,
22914 + int location, int val)
22918 +static void cvm_oct_get_drvinfo(struct net_device *dev,
22919 + struct ethtool_drvinfo *info)
22921 + strcpy(info->driver, "cavium-ethernet");
22922 + strcpy(info->version, OCTEON_ETHERNET_VERSION);
22923 + strcpy(info->bus_info, "Builtin");
22926 +static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
22928 + struct octeon_ethernet *priv = netdev_priv(dev);
22932 + ret = mii_ethtool_gset(&priv->mii_info, cmd);
22938 +static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
22940 + struct octeon_ethernet *priv = netdev_priv(dev);
22944 + ret = mii_ethtool_sset(&priv->mii_info, cmd);
22950 +static int cvm_oct_nway_reset(struct net_device *dev)
22952 + struct octeon_ethernet *priv = netdev_priv(dev);
22956 + ret = mii_nway_restart(&priv->mii_info);
22962 +static u32 cvm_oct_get_link(struct net_device *dev)
22964 + struct octeon_ethernet *priv = netdev_priv(dev);
22968 + ret = mii_link_ok(&priv->mii_info);
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,
22985 + * IOCTL support for PHY control
22987 + * @dev: Device to change
22988 + * @rq: the request
22989 + * @cmd: the command
22990 + * Returns Zero on success
22992 +int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
22994 + struct octeon_ethernet *priv = netdev_priv(dev);
22995 + struct mii_ioctl_data *data = if_mii(rq);
22996 + unsigned int duplex_chg;
23000 + ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg);
23007 + * Setup the MDIO device structures
23009 + * @dev: Device to setup
23011 + * Returns Zero on success, negative on failure
23013 +int cvm_oct_mdio_setup_device(struct net_device *dev)
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;
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;
23034 +++ b/drivers/staging/octeon/ethernet-mdio.h
23036 +/*********************************************************************
23037 + * Author: Cavium Networks
23039 + * Contact: support@caviumnetworks.com
23040 + * This file is part of the OCTEON SDK
23042 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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 */
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);
23083 +++ b/drivers/staging/octeon/ethernet-mem.c
23085 +/**********************************************************************
23086 + * Author: Cavium Networks
23088 + * Contact: support@caviumnetworks.com
23089 + * This file is part of the OCTEON SDK
23091 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
23116 +#include <asm/octeon/octeon.h>
23118 +#include "ethernet-defines.h"
23120 +#include "cvmx-fpa.h"
23123 + * Fill the supplied hardware pool with skbuffs
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
23129 +static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements)
23131 + int freed = elements;
23134 + struct sk_buff *skb = dev_alloc_skb(size + 128);
23135 + if (unlikely(skb == NULL)) {
23137 + ("Failed to allocate skb for hardware pool %d\n",
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));
23147 + return elements - freed;
23151 + * Free the supplied hardware pool of skbuffs
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
23157 +static void cvm_oct_free_hw_skbuff(int pool, int size, int elements)
23162 + memory = cvmx_fpa_alloc(pool);
23164 + struct sk_buff *skb =
23165 + *(struct sk_buff **)(memory - sizeof(void *));
23167 + dev_kfree_skb(skb);
23169 + } while (memory);
23171 + if (elements < 0)
23172 + pr_warning("Freeing of pool %u had too many skbuffs (%d)\n",
23174 + else if (elements > 0)
23175 + pr_warning("Freeing of pool %u is missing %d skbuffs\n",
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.
23185 + * @pool: Pool to populate
23186 + * @size: Size of each buffer in the pool
23187 + * @elements: Number of buffers to allocate
23189 +static int cvm_oct_fill_hw_memory(int pool, int size, int elements)
23192 + int freed = elements;
23194 + if (USE_32BIT_SHARED) {
23195 + extern uint64_t octeon_reserve32_memory;
23198 + cvmx_bootmem_alloc_range(elements * size, 128,
23199 + octeon_reserve32_memory,
23200 + octeon_reserve32_memory +
23201 + (CONFIG_CAVIUM_RESERVE32 << 20) -
23203 + if (memory == NULL)
23204 + panic("Unable to allocate %u bytes for FPA pool %d\n",
23205 + elements * size, pool);
23207 + pr_notice("Memory range %p - %p reserved for "
23208 + "hardware\n", memory,
23209 + memory + elements * size - 1);
23212 + cvmx_fpa_free(memory, pool, 0);
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 "
23223 + elements * size, pool);
23226 + memory = (char *)(((unsigned long)memory + 127) & -128);
23227 + cvmx_fpa_free(memory, pool, 0);
23231 + return elements - freed;
23235 + * Free memory previously allocated with cvm_oct_fill_hw_memory
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
23241 +static void cvm_oct_free_hw_memory(int pool, int size, int elements)
23243 + if (USE_32BIT_SHARED) {
23244 + pr_warning("Warning: 32 shared memory is not freeable\n");
23248 + memory = cvmx_fpa_alloc(pool);
23251 + kfree(phys_to_virt(cvmx_ptr_to_phys(memory)));
23253 + } while (memory);
23255 + if (elements < 0)
23256 + pr_warning("Freeing of pool %u had too many "
23257 + "buffers (%d)\n",
23259 + else if (elements > 0)
23260 + pr_warning("Warning: Freeing of pool %u is "
23261 + "missing %d buffers\n",
23266 +int cvm_oct_mem_fill_fpa(int pool, int size, int elements)
23269 + if (USE_SKBUFFS_IN_HW)
23270 + freed = cvm_oct_fill_hw_skbuff(pool, size, elements);
23272 + freed = cvm_oct_fill_hw_memory(pool, size, elements);
23276 +void cvm_oct_mem_empty_fpa(int pool, int size, int elements)
23278 + if (USE_SKBUFFS_IN_HW)
23279 + cvm_oct_free_hw_skbuff(pool, size, elements);
23281 + cvm_oct_free_hw_memory(pool, size, elements);
23284 +++ b/drivers/staging/octeon/ethernet-mem.h
23286 +/*********************************************************************
23287 + * Author: Cavium Networks
23289 + * Contact: support@caviumnetworks.com
23290 + * This file is part of the OCTEON SDK
23292 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
23309 + * This file may also be available under a different license from Cavium.
23310 + * Contact Cavium Networks for more information
23311 +********************************************************************/
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);
23316 +++ b/drivers/staging/octeon/ethernet-proc.c
23318 +/**********************************************************************
23319 + * Author: Cavium Networks
23321 + * Contact: support@caviumnetworks.com
23322 + * This file is part of the OCTEON SDK
23324 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
23350 +#include <asm/octeon/octeon.h>
23352 +#include "octeon-ethernet.h"
23353 +#include "ethernet-defines.h"
23355 +#include "cvmx-helper.h"
23356 +#include "cvmx-pip.h"
23358 +static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev,
23359 + int phy_id, int offset)
23361 + struct octeon_ethernet *priv = netdev_priv(dev);
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);
23370 +static int cvm_oct_stats_switch_show(struct seq_file *m, void *v)
23372 + static const int ports[] = { 0, 1, 2, 3, 9, -1 };
23373 + struct net_device *dev = cvm_oct_device[0];
23376 + while (ports[index] != -1) {
23379 + struct octeon_ethernet *priv = netdev_priv(dev);
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,
23389 + (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32),
23390 + cvm_oct_stats_read_switch(dev, 0x1b,
23392 + (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32),
23393 + cvm_oct_stats_read_switch(dev, 0x1b, 0x08));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
23465 + * User is reading /proc/octeon_ethernet_stats
23471 +static int cvm_oct_stats_show(struct seq_file *m, void *v)
23473 + struct octeon_ethernet *priv;
23476 + for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
23478 + if (cvm_oct_device[port]) {
23479 + priv = netdev_priv(cvm_oct_device[port]);
23481 + seq_printf(m, "\nOcteon Port %d (%s)\n", port,
23482 + cvm_oct_device[port]->name);
23484 + "rx_packets: %12lu\t"
23485 + "tx_packets: %12lu\n",
23486 + priv->stats.rx_packets,
23487 + priv->stats.tx_packets);
23489 + "rx_bytes: %12lu\t"
23490 + "tx_bytes: %12lu\n",
23491 + priv->stats.rx_bytes, priv->stats.tx_bytes);
23493 + "rx_errors: %12lu\t"
23494 + "tx_errors: %12lu\n",
23495 + priv->stats.rx_errors,
23496 + priv->stats.tx_errors);
23498 + "rx_dropped: %12lu\t"
23499 + "tx_dropped: %12lu\n",
23500 + priv->stats.rx_dropped,
23501 + priv->stats.tx_dropped);
23503 + "rx_length_errors: %12lu\t"
23504 + "tx_aborted_errors: %12lu\n",
23505 + priv->stats.rx_length_errors,
23506 + priv->stats.tx_aborted_errors);
23508 + "rx_over_errors: %12lu\t"
23509 + "tx_carrier_errors: %12lu\n",
23510 + priv->stats.rx_over_errors,
23511 + priv->stats.tx_carrier_errors);
23513 + "rx_crc_errors: %12lu\t"
23514 + "tx_fifo_errors: %12lu\n",
23515 + priv->stats.rx_crc_errors,
23516 + priv->stats.tx_fifo_errors);
23518 + "rx_frame_errors: %12lu\t"
23519 + "tx_heartbeat_errors: %12lu\n",
23520 + priv->stats.rx_frame_errors,
23521 + priv->stats.tx_heartbeat_errors);
23523 + "rx_fifo_errors: %12lu\t"
23524 + "tx_window_errors: %12lu\n",
23525 + priv->stats.rx_fifo_errors,
23526 + priv->stats.tx_window_errors);
23528 + "rx_missed_errors: %12lu\t"
23529 + "multicast: %12lu\n",
23530 + priv->stats.rx_missed_errors,
23531 + priv->stats.multicast);
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);
23544 + * /proc/octeon_ethernet_stats was openned. Use the single_open iterator
23550 +static int cvm_oct_stats_open(struct inode *inode, struct file *file)
23552 + return single_open(file, cvm_oct_stats_show, NULL);
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,
23562 +void cvm_oct_proc_initialize(void)
23564 + struct proc_dir_entry *entry =
23565 + create_proc_entry("octeon_ethernet_stats", 0, NULL);
23567 + entry->proc_fops = &cvm_oct_stats_operations;
23570 +void cvm_oct_proc_shutdown(void)
23572 + remove_proc_entry("octeon_ethernet_stats", NULL);
23575 +++ b/drivers/staging/octeon/ethernet-proc.h
23577 +/*********************************************************************
23578 + * Author: Cavium Networks
23580 + * Contact: support@caviumnetworks.com
23581 + * This file is part of the OCTEON SDK
23583 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
23600 + * This file may also be available under a different license from Cavium.
23601 + * Contact Cavium Networks for more information
23602 +*********************************************************************/
23604 +void cvm_oct_proc_initialize(void);
23605 +void cvm_oct_proc_shutdown(void);
23607 +++ b/drivers/staging/octeon/ethernet-rgmii.c
23609 +/*********************************************************************
23610 + * Author: Cavium Networks
23612 + * Contact: support@caviumnetworks.com
23613 + * This file is part of the OCTEON SDK
23615 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
23640 +#include <asm/octeon/octeon.h>
23642 +#include "ethernet-defines.h"
23643 +#include "octeon-ethernet.h"
23644 +#include "ethernet-common.h"
23645 +#include "ethernet-util.h"
23647 +#include "cvmx-helper.h"
23649 +#include <asm/octeon/cvmx-ipd-defs.h>
23650 +#include <asm/octeon/cvmx-npi-defs.h>
23651 +#include "cvmx-gmxx-defs.h"
23653 +DEFINE_SPINLOCK(global_register_lock);
23655 +static int number_rgmii_ports;
23657 +static void cvm_oct_rgmii_poll(struct net_device *dev)
23659 + struct octeon_ethernet *priv = netdev_priv(dev);
23660 + unsigned long flags;
23661 + cvmx_helper_link_info_t link_info;
23664 + * Take the global register lock since we are going to touch
23665 + * registers that affect more than one port.
23667 + spin_lock_irqsave(&global_register_lock, flags);
23669 + link_info = cvmx_helper_link_get(priv->port);
23670 + if (link_info.u64 == priv->link_info) {
23673 + * If the 10Mbps preamble workaround is supported and we're
23674 + * at 10Mbps we may need to do some special checking.
23676 + if (USE_10MBPS_PREAMBLE_WORKAROUND && (link_info.s.speed == 10)) {
23679 + * Read the GMXX_RXX_INT_REG[PCTERR] bit and
23680 + * see if we are getting preamble errors.
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) {
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.
23698 + union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
23699 + union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
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);
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);
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",
23727 + spin_unlock_irqrestore(&global_register_lock, flags);
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) {
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);
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);
23760 + link_info = cvmx_helper_link_autoconf(priv->port);
23761 + priv->link_info = link_info.u64;
23762 + spin_unlock_irqrestore(&global_register_lock, flags);
23765 + if (link_info.s.link_up) {
23767 + if (!netif_carrier_ok(dev))
23768 + netif_carrier_on(dev);
23769 + if (priv->queue != -1)
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);
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",
23782 + if (netif_carrier_ok(dev))
23783 + netif_carrier_off(dev);
23784 + DEBUGPRINT("%s: Link down\n", dev->name);
23788 +static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id)
23790 + union cvmx_npi_rsl_int_blocks rsl_int_blocks;
23792 + irqreturn_t return_status = IRQ_NONE;
23794 + rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
23796 + /* Check and see if this interrupt was caused by the GMX0 block */
23797 + if (rsl_int_blocks.s.gmx0) {
23799 + int interface = 0;
23800 + /* Loop through every port of this interface */
23802 + index < cvmx_helper_ports_on_interface(interface);
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) {
23818 + struct net_device *dev =
23819 + cvm_oct_device[cvmx_helper_get_ipd_port
23820 + (interface, index)];
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;
23835 + /* Check and see if this interrupt was caused by the GMX1 block */
23836 + if (rsl_int_blocks.s.gmx1) {
23838 + int interface = 1;
23839 + /* Loop through every port of this interface */
23841 + index < cvmx_helper_ports_on_interface(interface);
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) {
23857 + struct net_device *dev =
23858 + cvm_oct_device[cvmx_helper_get_ipd_port
23859 + (interface, index)];
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;
23873 + return return_status;
23876 +static int cvm_oct_rgmii_open(struct net_device *dev)
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;
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);
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);
23897 +static int cvm_oct_rgmii_stop(struct net_device *dev)
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);
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);
23910 +int cvm_oct_rgmii_init(struct net_device *dev)
23912 + struct octeon_ethernet *priv = netdev_priv(dev);
23915 + cvm_oct_common_init(dev);
23916 + dev->open = cvm_oct_rgmii_open;
23917 + dev->stop = cvm_oct_rgmii_stop;
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
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);
23932 + number_rgmii_ports++;
23935 + * Only true RGMII ports need to be polled. In GMII mode, port
23936 + * 0 is really a RGMII port.
23938 + if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23939 + && (priv->port == 0))
23940 + || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
23942 + if (!octeon_is_simulation()) {
23944 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
23945 + int interface = INTERFACE(priv->port);
23946 + int index = INDEX(priv->port);
23949 + * Enable interrupts on inband status changes
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;
23967 +void cvm_oct_rgmii_uninit(struct net_device *dev)
23969 + struct octeon_ethernet *priv = netdev_priv(dev);
23970 + cvm_oct_common_uninit(dev);
23973 + * Only true RGMII ports need to be polled. In GMII mode, port
23974 + * 0 is really a RGMII port.
23976 + if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23977 + && (priv->port == 0))
23978 + || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
23980 + if (!octeon_is_simulation()) {
23982 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
23983 + int interface = INTERFACE(priv->port);
23984 + int index = INDEX(priv->port);
23987 + * Disable interrupts on inband status changes
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);
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);
24007 +++ b/drivers/staging/octeon/ethernet-rx.c
24009 +/**********************************************************************
24010 + * Author: Cavium Networks
24012 + * Contact: support@caviumnetworks.com
24013 + * This file is part of the OCTEON SDK
24015 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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 */
24054 +#include <asm/atomic.h>
24056 +#include <asm/octeon/octeon.h>
24058 +#include "ethernet-defines.h"
24059 +#include "octeon-ethernet.h"
24060 +#include "ethernet-mem.h"
24061 +#include "ethernet-util.h"
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"
24070 +#include "cvmx-gmxx-defs.h"
24072 +struct cvm_tasklet_wrapper {
24073 + struct tasklet_struct t;
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.
24082 +static struct cvm_tasklet_wrapper cvm_oct_tasklet[NR_CPUS];
24085 + * Interrupt handler. The interrupt occurs whenever the POW
24086 + * transitions from 0->1 packets in our group.
24093 +irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
24095 + /* Acknowledge the interrupt */
24096 + if (INTERRUPT_LIMIT)
24097 + cvmx_write_csr(CVMX_POW_WQ_INT, 1 << pow_receive_group);
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;
24106 +#ifdef CONFIG_NET_POLL_CONTROLLER
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
24113 + * @dev: Device to poll. Unused
24115 +void cvm_oct_poll_controller(struct net_device *dev)
24117 + preempt_disable();
24118 + tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
24119 + preempt_enable();
24124 + * This is called on receive errors, and determines if the packet
24125 + * can be dropped early-on in cvm_oct_tasklet_rx().
24127 + * @work: Work queue entry pointing to the packet.
24128 + * Returns Non-zero if the packet can be dropped, zero otherwise.
24130 +static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
24132 + if ((work->word2.snoip.err_code == 10) && (work->len <= 64)) {
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.
24140 + if (USE_10MBPS_PREAMBLE_WORKAROUND
24141 + && ((work->word2.snoip.err_code == 5)
24142 + || (work->word2.snoip.err_code == 7))) {
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.
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) {
24160 + cvmx_phys_to_ptr(work->packet_ptr.s.addr);
24163 + while (i < work->len - 1) {
24164 + if (*ptr != 0x55)
24170 + if (*ptr == 0xd5) {
24172 + DEBUGPRINT("Port %d received 0xd5 preamble\n", work->ipprt);
24174 + work->packet_ptr.s.addr += i + 1;
24175 + work->len -= i + 5;
24176 + } else if ((*ptr & 0xf) == 0xd) {
24178 + DEBUGPRINT("Port %d received 0x?d preamble\n", work->ipprt);
24180 + work->packet_ptr.s.addr += i;
24181 + work->len -= i + 4;
24182 + for (i = 0; i < work->len; i++) {
24184 + ((*ptr & 0xf0) >> 4) |
24185 + ((*(ptr + 1) & 0xf) << 4);
24189 + DEBUGPRINT("Port %d unknown preamble, packet "
24193 + cvmx_helper_dump_packet(work);
24195 + cvm_oct_free_work(work);
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);
24210 + * Tasklet function that is scheduled on a core when an interrupt occurs.
24214 +void cvm_oct_tasklet_rx(unsigned long unused)
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;
24222 + int packet_not_copied;
24224 + /* Prefetch cvm_oct_device since we know we need it soon */
24225 + prefetch(cvm_oct_device);
24227 + if (USE_ASYNC_IOBDMA) {
24228 + /* Save scratch in case userspace is using it */
24230 + old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
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);
24238 + if (USE_ASYNC_IOBDMA)
24239 + cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
24242 + struct sk_buff *skb = NULL;
24244 + cvmx_wqe_t *work;
24246 + if (USE_ASYNC_IOBDMA) {
24247 + work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);
24249 + if ((INTERRUPT_LIMIT == 0)
24250 + || likely(rx_count < MAX_RX_PACKETS))
24252 + cvmx_pow_work_request_sync
24253 + (CVMX_POW_NO_WAIT);
24258 + if (work == NULL)
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.
24266 + if (USE_ASYNC_IOBDMA) {
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);
24273 + cvmx_scratch_write64(CVMX_SCR_SCRATCH,
24274 + 0x8000000000000000ull);
24275 + cvmx_pow_tag_sw_null_nocheck();
24279 + skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1;
24280 + if (likely(skb_in_hw)) {
24283 + **)(cvm_oct_get_buffer_ptr(work->packet_ptr) -
24285 + prefetch(&skb->head);
24286 + prefetch(&skb->len);
24288 + prefetch(cvm_oct_device[work->ipprt]);
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))
24298 + * We can only use the zero copy path if skbuffs are
24299 + * in the FPA pool and the packet fits in a single
24302 + if (likely(skb_in_hw)) {
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
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;
24320 + * We have to copy the packet. First allocate
24321 + * an skbuff for it.
24323 + skb = dev_alloc_skb(work->len);
24325 + DEBUGPRINT("Port %d failed to allocate "
24326 + "skbuff, packet dropped\n",
24328 + cvm_oct_free_work(work);
24333 + * Check if we've received a packet that was
24334 + * entirely stored in the work entry. This is
24337 + if (unlikely(work->word2.s.bufs == 0)) {
24338 + uint8_t *ptr = work->packet_data;
24340 + if (likely(!work->word2.s.not_IP)) {
24342 + * The beginning of the packet
24343 + * moves for IP packets.
24345 + if (work->word2.s.is_v6)
24350 + memcpy(skb_put(skb, work->len), ptr, work->len);
24351 + /* No packet buffers to free */
24353 + int segments = work->word2.s.bufs;
24354 + union cvmx_buf_ptr segment_ptr =
24355 + work->packet_ptr;
24356 + int len = work->len;
24358 + while (segments--) {
24359 + union cvmx_buf_ptr next_ptr =
24360 + *(union cvmx_buf_ptr *)
24361 + cvmx_phys_to_ptr(segment_ptr.s.
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;
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
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.
24386 + /* Reduce the amount of bytes left
24388 + len -= segment_size;
24389 + segment_ptr = next_ptr;
24392 + packet_not_copied = 0;
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);
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);
24407 + (work->word2.s.not_IP
24408 + || work->word2.s.IP_exc
24409 + || work->word2.s.L4_error))
24410 + skb->ip_summed = CHECKSUM_NONE;
24412 + skb->ip_summed = CHECKSUM_UNNECESSARY;
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);
24420 + atomic_add(1, (atomic_t *)&priv->stats.rx_packets);
24421 + atomic_add(skb->len, (atomic_t *)&priv->stats.rx_bytes);
24424 + netif_receive_skb(skb);
24427 + * Drop any packet received for a
24428 + * device that isn't up.
24431 + DEBUGPRINT("%s: Device not up, packet dropped\n",
24434 +#ifdef CONFIG_64BIT
24435 + atomic64_add(1, (atomic64_t *)&priv->stats.rx_dropped);
24437 + atomic_add(1, (atomic_t *)&priv->stats.rx_dropped);
24439 + dev_kfree_skb_irq(skb);
24443 + * Drop any packet received for a device that
24446 + DEBUGPRINT("Port %d not controlled by Linux, packet "
24449 + dev_kfree_skb_irq(skb);
24452 + * Check to see if the skbuff and work share the same
24455 + if (USE_SKBUFFS_IN_HW && likely(packet_not_copied)) {
24457 + * This buffer needs to be replaced, increment
24458 + * the number of buffers we need to free by
24461 + cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
24464 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL,
24465 + DONT_WRITEBACK(1));
24467 + cvm_oct_free_work(work);
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);
24478 + if (USE_SKBUFFS_IN_HW) {
24479 + /* Refill the packet buffer pool */
24481 + cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
24483 + if (number_to_free > 0) {
24484 + cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
24485 + -number_to_free);
24487 + cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL,
24488 + CVMX_FPA_PACKET_POOL_SIZE,
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);
24499 +void cvm_oct_rx_initialize(void)
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);
24507 +void cvm_oct_rx_shutdown(void)
24510 + /* Shutdown all of the tasklets */
24511 + for (i = 0; i < NR_CPUS; i++)
24512 + tasklet_kill(&cvm_oct_tasklet[i].t);
24515 +++ b/drivers/staging/octeon/ethernet-rx.h
24517 +/*********************************************************************
24518 + * Author: Cavium Networks
24520 + * Contact: support@caviumnetworks.com
24521 + * This file is part of the OCTEON SDK
24523 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
24540 + * This file may also be available under a different license from Cavium.
24541 + * Contact Cavium Networks for more information
24542 +*********************************************************************/
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);
24548 +void cvm_oct_rx_initialize(void);
24549 +void cvm_oct_rx_shutdown(void);
24551 +++ b/drivers/staging/octeon/ethernet-sgmii.c
24553 +/**********************************************************************
24554 + * Author: Cavium Networks
24556 + * Contact: support@caviumnetworks.com
24557 + * This file is part of the OCTEON SDK
24559 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
24584 +#include <asm/octeon/octeon.h>
24586 +#include "ethernet-defines.h"
24587 +#include "octeon-ethernet.h"
24588 +#include "ethernet-util.h"
24589 +#include "ethernet-common.h"
24591 +#include "cvmx-helper.h"
24593 +#include "cvmx-gmxx-defs.h"
24595 +static int cvm_oct_sgmii_open(struct net_device *dev)
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;
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);
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);
24616 +static int cvm_oct_sgmii_stop(struct net_device *dev)
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);
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);
24629 +static void cvm_oct_sgmii_poll(struct net_device *dev)
24631 + struct octeon_ethernet *priv = netdev_priv(dev);
24632 + cvmx_helper_link_info_t link_info;
24634 + link_info = cvmx_helper_link_get(priv->port);
24635 + if (link_info.u64 == priv->link_info)
24638 + link_info = cvmx_helper_link_autoconf(priv->port);
24639 + priv->link_info = link_info.u64;
24642 + if (link_info.s.link_up) {
24644 + if (!netif_carrier_ok(dev))
24645 + netif_carrier_on(dev);
24646 + if (priv->queue != -1)
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);
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",
24658 + if (netif_carrier_ok(dev))
24659 + netif_carrier_off(dev);
24660 + DEBUGPRINT("%s: Link down\n", dev->name);
24664 +int cvm_oct_sgmii_init(struct net_device *dev)
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;
24671 + if (!octeon_is_simulation())
24672 + priv->poll = cvm_oct_sgmii_poll;
24674 + /* FIXME: Need autoneg logic */
24678 +void cvm_oct_sgmii_uninit(struct net_device *dev)
24680 + cvm_oct_common_uninit(dev);
24683 +++ b/drivers/staging/octeon/ethernet-spi.c
24685 +/**********************************************************************
24686 + * Author: Cavium Networks
24688 + * Contact: support@caviumnetworks.com
24689 + * This file is part of the OCTEON SDK
24691 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
24716 +#include <asm/octeon/octeon.h>
24718 +#include "ethernet-defines.h"
24719 +#include "octeon-ethernet.h"
24720 +#include "ethernet-common.h"
24721 +#include "ethernet-util.h"
24723 +#include "cvmx-spi.h"
24725 +#include <asm/octeon/cvmx-npi-defs.h>
24726 +#include "cvmx-spxx-defs.h"
24727 +#include "cvmx-stxx-defs.h"
24729 +static int number_spi_ports;
24730 +static int need_retrain[2] = { 0, 0 };
24732 +static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
24734 + irqreturn_t return_status = IRQ_NONE;
24735 + union cvmx_npi_rsl_int_blocks rsl_int_blocks;
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 */
24741 + union cvmx_spxx_int_reg spx_int_reg;
24742 + union cvmx_stxx_int_reg stx_int_reg;
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]) {
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");
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]) {
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 "
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 "
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");
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;
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;
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]) {
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");
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]) {
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 "
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 "
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");
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;
24900 + return return_status;
24903 +static void cvm_oct_spi_enable_error_reporting(int interface)
24905 + union cvmx_spxx_int_msk spxx_int_msk;
24906 + union cvmx_stxx_int_msk stxx_int_msk;
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);
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);
24933 +static void cvm_oct_spi_poll(struct net_device *dev)
24935 + static int spi4000_port;
24936 + struct octeon_ethernet *priv = netdev_priv(dev);
24939 + for (interface = 0; interface < 2; interface++) {
24941 + if ((priv->port == interface * 16) && need_retrain[interface]) {
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);
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
24958 + if (priv->port == spi4000_port) {
24960 + * This function does nothing if it is called on an
24961 + * interface without a SPI4000.
24963 + cvmx_spi4000_check_speed(interface, priv->port);
24965 + * Normal ordering increments. By decrementing
24966 + * we only match once per iteration.
24969 + if (spi4000_port < 0)
24970 + spi4000_port = 10;
24975 +int cvm_oct_spi_init(struct net_device *dev)
24978 + struct octeon_ethernet *priv = netdev_priv(dev);
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);
24984 + number_spi_ports++;
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;
24990 + cvm_oct_common_init(dev);
24994 +void cvm_oct_spi_uninit(struct net_device *dev)
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);
25005 + free_irq(8 + 46, &number_spi_ports);
25009 +++ b/drivers/staging/octeon/ethernet-tx.c
25011 +/*********************************************************************
25012 + * Author: Cavium Networks
25014 + * Contact: support@caviumnetworks.com
25015 + * This file is part of the OCTEON SDK
25017 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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 */
25054 +#include <asm/atomic.h>
25056 +#include <asm/octeon/octeon.h>
25058 +#include "ethernet-defines.h"
25059 +#include "octeon-ethernet.h"
25060 +#include "ethernet-util.h"
25062 +#include "cvmx-wqe.h"
25063 +#include "cvmx-fau.h"
25064 +#include "cvmx-pko.h"
25065 +#include "cvmx-helper.h"
25067 +#include "cvmx-gmxx-defs.h"
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)
25076 +#ifndef GET_SKBUFF_QOS
25077 +#define GET_SKBUFF_QOS(skb) 0
25081 + * Packet transmit
25083 + * @skb: Packet to send
25084 + * @dev: Device info structure
25085 + * Returns Always returns zero
25087 +int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
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;
25095 + struct octeon_ethernet *priv = netdev_priv(dev);
25097 + int32_t buffers_to_free;
25098 +#if REUSE_SKBUFFS_WITHOUT_FREE
25099 + unsigned char *fpa_head;
25103 + * Prefetch the private data structure. It is larger that one
25108 + /* Start off assuming no drop */
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.
25116 + if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
25117 + (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
25118 + qos = GET_SKBUFF_QOS(skb);
25121 + else if (qos >= cvmx_pko_get_num_queues(priv->port))
25126 + if (USE_ASYNC_IOBDMA) {
25127 + /* Save scratch in case userspace is using it */
25129 + old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
25130 + old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
25133 + * Assume we're going to be able t osend this
25134 + * packet. Fetch and increment the number of pending
25135 + * packets for output.
25137 + cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8,
25138 + FAU_NUM_PACKET_BUFFERS_TO_FREE,
25140 + cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
25141 + priv->fau + qos * 4, 1);
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
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);
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,
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;
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;
25187 + pko_command.s.dontfree = 1;
25188 + pko_command.s.reg0 = priv->fau + qos * 4;
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.
25199 +#if REUSE_SKBUFFS_WITHOUT_FREE
25200 + fpa_head = skb->head + 128 - ((unsigned long)skb->head & 0x7f);
25201 + if (unlikely(skb->data < fpa_head)) {
25203 + * printk("TX buffer beginning can't meet FPA
25204 + * alignment constraints\n");
25206 + goto dont_put_skbuff_in_hw;
25209 + ((skb_end_pointer(skb) - fpa_head) < CVMX_FPA_PACKET_POOL_SIZE)) {
25211 + printk("TX buffer isn't large enough for the FPA\n");
25213 + goto dont_put_skbuff_in_hw;
25215 + if (unlikely(skb_shared(skb))) {
25217 + printk("TX buffer sharing data with someone else\n");
25219 + goto dont_put_skbuff_in_hw;
25221 + if (unlikely(skb_cloned(skb))) {
25223 + printk("TX buffer has been cloned\n");
25225 + goto dont_put_skbuff_in_hw;
25227 + if (unlikely(skb_header_cloned(skb))) {
25229 + printk("TX buffer header has been cloned\n");
25231 + goto dont_put_skbuff_in_hw;
25233 + if (unlikely(skb->destructor)) {
25235 + printk("TX buffer has a destructor\n");
25237 + goto dont_put_skbuff_in_hw;
25239 + if (unlikely(skb_shinfo(skb)->nr_frags)) {
25241 + printk("TX buffer has fragments\n");
25243 + goto dont_put_skbuff_in_hw;
25246 + (skb->truesize !=
25247 + sizeof(*skb) + skb_end_pointer(skb) - skb->head)) {
25249 + printk("TX buffer truesize has been changed\n");
25251 + goto dont_put_skbuff_in_hw;
25255 + * We can use this buffer in the FPA. We don't need the FAU
25258 + pko_command.s.reg0 = 0;
25259 + pko_command.s.dontfree = 0;
25261 + hw_buffer.s.back = (skb->data - fpa_head) >> 7;
25262 + *(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
25265 + * The skbuff will be reused without ever being freed. We must
25266 + * cleanup a bunch of Linux stuff.
25268 + dst_release(skb->dst);
25270 +#ifdef CONFIG_XFRM
25271 + secpath_put(skb->sp);
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 */
25283 +dont_put_skbuff_in_hw:
25284 +#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
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;
25296 + if (USE_ASYNC_IOBDMA) {
25297 + /* Get the number of skbuffs in use by the hardware */
25299 + in_use = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
25300 + buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
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);
25309 + * If we're sending faster than the receive can free them then
25310 + * don't do the HW free.
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;
25317 + cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
25318 + CVMX_PKO_LOCK_CMD_QUEUE);
25320 + /* Drop this packet if we have too many already queued to the HW */
25322 + (skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) {
25324 + DEBUGPRINT("%s: Tx dropped. Too many queued\n", dev->name);
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);
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);
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++;
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);
25353 + cvmx_fau_atomic_add32
25354 + (FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
25355 + cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
25358 + /* Put this packet on the queue to be freed later */
25359 + skb_queue_tail(&priv->tx_free_list[qos], skb);
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);
25367 + * Check again now that we have the lock. It might
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);
25381 + * Packet transmit to the POW
25383 + * @skb: Packet to send
25384 + * @dev: Device info structure
25385 + * Returns Always returns zero
25387 +int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
25389 + struct octeon_ethernet *priv = netdev_priv(dev);
25390 + void *packet_buffer;
25391 + void *copy_location;
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",
25398 + priv->stats.tx_dropped++;
25399 + dev_kfree_skb(skb);
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",
25408 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
25409 + priv->stats.tx_dropped++;
25410 + dev_kfree_skb(skb);
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
25422 + copy_location = packet_buffer + sizeof(uint64_t);
25423 + copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6;
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
25431 + memcpy(copy_location, skb->data, skb->len);
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.
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;
25453 + if (skb->protocol == htons(ETH_P_IP)) {
25454 + work->word2.s.ip_offset = 14;
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 */
25461 + work->word2.s.tcp_or_udp =
25462 + (ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
25463 + || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP);
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;
25474 + work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0)
25475 + || (ip_hdr(skb)->frag_off ==
25478 + /* Assume Linux is sending a good packet */
25479 + work->word2.s.IP_exc = 0;
25481 + work->word2.s.is_bcast = (skb->pkt_type == PACKET_BROADCAST);
25482 + work->word2.s.is_mcast = (skb->pkt_type == PACKET_MULTICAST);
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;
25493 + * When copying the data, include 4 bytes of the
25494 + * ethernet header to align the same way hardware
25497 + memcpy(work->packet_data, skb->data + 10,
25498 + sizeof(work->packet_data));
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 */
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 */
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;
25519 + memcpy(work->packet_data, skb->data, sizeof(work->packet_data));
25522 + /* Submit the packet to the POW */
25523 + cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos,
25525 + priv->stats.tx_packets++;
25526 + priv->stats.tx_bytes += skb->len;
25527 + dev_kfree_skb(skb);
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.
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.
25547 + * Returns Zero on success, negative on failure.
25549 +int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
25550 + int do_free, int qos)
25552 + unsigned long flags;
25553 + union cvmx_buf_ptr hw_buffer;
25554 + cvmx_pko_command_word0_t pko_command;
25556 + struct octeon_ethernet *priv = netdev_priv(dev);
25557 + cvmx_wqe_t *work = work_queue_entry;
25559 + if (!(dev->flags & IFF_UP)) {
25560 + DEBUGPRINT("%s: Device not up\n", dev->name);
25562 + cvm_oct_free_work(work);
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)) {
25573 + else if (qos >= cvmx_pko_get_num_queues(priv->port))
25578 + /* Start off assuming no drop */
25581 + local_irq_save(flags);
25582 + cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
25583 + CVMX_PKO_LOCK_CMD_QUEUE);
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;
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;
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;
25603 + pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
25605 + /* Send the packet to the output queue */
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);
25613 + local_irq_restore(flags);
25615 + if (unlikely(dropped)) {
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));
25624 +EXPORT_SYMBOL(cvm_oct_transmit_qos);
25627 + * This function frees all skb that are currenty queued for TX.
25629 + * @dev: Device being shutdown
25631 +void cvm_oct_tx_shutdown(struct net_device *dev)
25633 + struct octeon_ethernet *priv = netdev_priv(dev);
25634 + unsigned long flags;
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);
25646 +++ b/drivers/staging/octeon/ethernet-tx.h
25648 +/*********************************************************************
25649 + * Author: Cavium Networks
25651 + * Contact: support@caviumnetworks.com
25652 + * This file is part of the OCTEON SDK
25654 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
25671 + * This file may also be available under a different license from Cavium.
25672 + * Contact Cavium Networks for more information
25673 +*********************************************************************/
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);
25681 +++ b/drivers/staging/octeon/ethernet-util.h
25683 +/**********************************************************************
25684 + * Author: Cavium Networks
25686 + * Contact: support@caviumnetworks.com
25687 + * This file is part of the OCTEON SDK
25689 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
25706 + * This file may also be available under a different license from Cavium.
25707 + * Contact Cavium Networks for more information
25708 +*********************************************************************/
25710 +#define DEBUGPRINT(format, ...) do { if (printk_ratelimit()) \
25711 + printk(format, ##__VA_ARGS__); \
25715 + * Given a packet data address, return a pointer to the
25716 + * beginning of the packet buffer.
25718 + * @packet_ptr: Packet data hardware address
25719 + * Returns Packet buffer pointer
25721 +static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr)
25723 + return cvmx_phys_to_ptr(((packet_ptr.s.addr >> 7) - packet_ptr.s.back)
25728 + * Given an IPD/PKO port number, return the logical interface it is
25731 + * @ipd_port: Port to check
25733 + * Returns Logical interface
25735 +static inline int INTERFACE(int ipd_port)
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 */
25741 + else if (ipd_port < 40) /* Interface 3 for loopback */
25743 + else if (ipd_port == 40) /* Non existant interface for POW0 */
25746 + panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);
25750 + * Given an IPD/PKO port number, return the port's index on a
25751 + * logical interface.
25753 + * @ipd_port: Port to check
25755 + * Returns Index into interface port list
25757 +static inline int INDEX(int ipd_port)
25759 + if (ipd_port < 32)
25760 + return ipd_port & 15;
25762 + return ipd_port & 3;
25765 +++ b/drivers/staging/octeon/ethernet-xaui.c
25767 +/**********************************************************************
25768 + * Author: Cavium Networks
25770 + * Contact: support@caviumnetworks.com
25771 + * This file is part of the OCTEON SDK
25773 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
25798 +#include <asm/octeon/octeon.h>
25800 +#include "ethernet-defines.h"
25801 +#include "octeon-ethernet.h"
25802 +#include "ethernet-common.h"
25803 +#include "ethernet-util.h"
25805 +#include "cvmx-helper.h"
25807 +#include "cvmx-gmxx-defs.h"
25809 +static int cvm_oct_xaui_open(struct net_device *dev)
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;
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);
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);
25829 +static int cvm_oct_xaui_stop(struct net_device *dev)
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);
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);
25842 +static void cvm_oct_xaui_poll(struct net_device *dev)
25844 + struct octeon_ethernet *priv = netdev_priv(dev);
25845 + cvmx_helper_link_info_t link_info;
25847 + link_info = cvmx_helper_link_get(priv->port);
25848 + if (link_info.u64 == priv->link_info)
25851 + link_info = cvmx_helper_link_autoconf(priv->port);
25852 + priv->link_info = link_info.u64;
25855 + if (link_info.s.link_up) {
25857 + if (!netif_carrier_ok(dev))
25858 + netif_carrier_on(dev);
25859 + if (priv->queue != -1)
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);
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",
25871 + if (netif_carrier_ok(dev))
25872 + netif_carrier_off(dev);
25873 + DEBUGPRINT("%s: Link down\n", dev->name);
25877 +int cvm_oct_xaui_init(struct net_device *dev)
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;
25884 + if (!octeon_is_simulation())
25885 + priv->poll = cvm_oct_xaui_poll;
25890 +void cvm_oct_xaui_uninit(struct net_device *dev)
25892 + cvm_oct_common_uninit(dev);
25895 +++ b/drivers/staging/octeon/ethernet.c
25897 +/**********************************************************************
25898 + * Author: Cavium Networks
25900 + * Contact: support@caviumnetworks.com
25901 + * This file is part of the OCTEON SDK
25903 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
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>
25931 +#include <net/dst.h>
25933 +#include <asm/octeon/octeon.h>
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"
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"
25950 +#include "cvmx-smix-defs.h"
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;
25956 +int num_packet_buffers = 1024;
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.");
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.");
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.");
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.");
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.");
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");
26009 + * Periodic timer to check auto negotiation
26011 +static struct timer_list cvm_oct_poll_timer;
26014 + * Array of every ethernet device owned by this driver indexed by
26015 + * the ipd input port number.
26017 +struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
26019 +extern struct semaphore mdio_sem;
26022 + * Periodic timer tick for slow management operations
26024 + * @arg: Device to check
26026 +static void cvm_do_timer(unsigned long arg)
26029 + if (port < CVMX_PIP_NUM_INPUT_PORTS) {
26030 + if (cvm_oct_device[port]) {
26031 + int queues_per_port;
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]);
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].
26049 + while (skb_queue_len
26050 + (&priv->tx_free_list[qos]) >
26051 + cvmx_fau_fetch_and_add32(priv->
26055 + dev_kfree_skb(__skb_dequeue
26059 + spin_unlock(&priv->tx_free_list[qos].
26063 + cvm_oct_device[port]->get_stats(cvm_oct_device[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);
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);
26078 + * Configure common hardware for all interfaces
26080 +static __init void cvm_oct_configure_common_hw(void)
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);
26094 + cvmx_helper_setup_red(num_packet_buffers / 4,
26095 + num_packet_buffers / 8);
26097 + /* Enable the MII interface */
26098 + if (!octeon_is_simulation())
26099 + cvmx_write_csr(CVMX_SMIX_EN(0), 1);
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",
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);
26115 + * Free a work queue entry received in a intercept callback.
26117 + * @work_queue_entry:
26118 + * Work queue entry to free
26119 + * Returns Zero on success, Negative on failure.
26121 +int cvm_oct_free_work(void *work_queue_entry)
26123 + cvmx_wqe_t *work = work_queue_entry;
26125 + int segments = work->word2.s.bufs;
26126 + union cvmx_buf_ptr segment_ptr = work->packet_ptr;
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 /
26136 + segment_ptr = next_ptr;
26138 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
26142 +EXPORT_SYMBOL(cvm_oct_free_work);
26145 + * Module/ driver initialization. Creates the linux network
26148 + * Returns Zero on success
26150 +static int __init cvm_oct_init_module(void)
26152 + int num_interfaces;
26154 + int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
26157 + pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
26159 + cvm_oct_proc_initialize();
26160 + cvm_oct_rx_initialize();
26161 + cvm_oct_configure_common_hw();
26163 + cvmx_helper_initialize_packet_io_global();
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);
26171 + for (port = cvmx_helper_get_ipd_port(interface, 0);
26172 + port < cvmx_helper_get_ipd_port(interface, num_ports);
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);
26183 + cvmx_helper_ipd_and_packet_input_enable();
26185 + memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
26188 + * Initialize the FAU used for counting packet buffers that
26189 + * need to be freed.
26191 + cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
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));
26198 + /* Initialize the device private structure. */
26199 + struct octeon_ethernet *priv = netdev_priv(dev);
26200 + memset(priv, 0, sizeof(struct octeon_ethernet));
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]);
26210 + if (register_netdev(dev) < 0) {
26211 + pr_err("Failed to register ethernet "
26212 + "device for POW\n");
26215 + cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
26216 + pr_info("%s: POW send group %d, receive "
26218 + dev->name, pow_send_group,
26219 + pow_receive_group);
26222 + pr_err("Failed to allocate ethernet device "
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);
26234 + for (port = cvmx_helper_get_ipd_port(interface, 0);
26235 + port < cvmx_helper_get_ipd_port(interface, num_ports);
26237 + struct octeon_ethernet *priv;
26238 + struct net_device *dev =
26239 + alloc_etherdev(sizeof(struct octeon_ethernet));
26241 + pr_err("Failed to allocate ethernet device "
26242 + "for port %d\n", port);
26245 + if (disable_core_queueing)
26246 + dev->tx_queue_len = 0;
26248 + /* Initialize the device private structure. */
26249 + priv = netdev_priv(dev);
26250 + memset(priv, 0, sizeof(struct octeon_ethernet));
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);
26260 + cvmx_fau_atomic_write32(priv->fau + qos * 4, 0);
26262 + switch (priv->imode) {
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:
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");
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");
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");
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");
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");
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");
26308 + if (!dev->init) {
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);
26316 + cvm_oct_device[priv->port] = dev;
26318 + cvmx_pko_get_num_queues(priv->port) *
26319 + sizeof(uint32_t);
26324 + if (INTERRUPT_LIMIT) {
26326 + * Set the POW timer rate to give an interrupt at most
26327 + * INTERRUPT_LIMIT times per second.
26329 + cvmx_write_csr(CVMX_POW_WQ_INT_PC,
26330 + octeon_bootinfo->eclock_hz / (INTERRUPT_LIMIT *
26334 + * Enable POW timer interrupt. It will count when
26335 + * there are packets available.
26337 + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
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);
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);
26354 + * Module / driver shutdown
26356 + * Returns Zero on success
26358 +static void __exit cvm_oct_cleanup_module(void)
26362 + /* Disable POW interrupt */
26363 + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
26365 + cvmx_ipd_disable();
26367 + /* Free the interrupt handler */
26368 + free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
26370 + del_timer(&cvm_oct_poll_timer);
26371 + cvm_oct_rx_shutdown();
26372 + cvmx_pko_disable();
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;
26384 + cvmx_pko_shutdown();
26385 + cvm_oct_proc_shutdown();
26387 + cvmx_ipd_free_ptr();
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);
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);
26405 +++ b/drivers/staging/octeon/octeon-ethernet.h
26407 +/**********************************************************************
26408 + * Author: Cavium Networks
26410 + * Contact: support@caviumnetworks.com
26411 + * This file is part of the OCTEON SDK
26413 + * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
26430 + * This file may also be available under a different license from Cavium.
26431 + * Contact Cavium Networks for more information
26432 +**********************************************************************/
26435 + * External interface for the Cavium Octeon ethernet driver.
26437 +#ifndef OCTEON_ETHERNET_H
26438 +#define OCTEON_ETHERNET_H
26441 + * This is the definition of the Ethernet driver's private
26442 + * driver state stored in netdev_priv(dev).
26444 +struct octeon_ethernet {
26445 + /* PKO hardware output port */
26447 + /* PKO hardware queue for the port */
26449 + /* Hardware fetch and add to count outstanding tx buffers */
26452 + * Type of port. This is one of the enums in
26453 + * cvmx_helper_interface_mode_t
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);
26469 + * Free a work queue entry received in a intercept callback.
26471 + * @work_queue_entry:
26472 + * Work queue entry to free
26473 + * Returns Zero on success, Negative on failure.
26475 +int cvm_oct_free_work(void *work_queue_entry);
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.
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.
26493 + * Returns Zero on success, negative on failure.
26495 +int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
26496 + int do_free, int qos);
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.
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.
26510 + * Returns Zero on success, negative on failure.
26512 +static inline int cvm_oct_transmit(struct net_device *dev,
26513 + void *work_queue_entry, int do_free)
26515 + return cvm_oct_transmit_qos(dev, work_queue_entry, do_free, 0);
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);
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[];