Root/target/linux/octeon/patches-2.6.30/011-octeon_ethernet_driver.patch

1The octeon-ethernet driver supports the sgmii, rgmii, spi, and xaui
2ports present on the Cavium OCTEON family of SOCs. These SOCs are
3multi-core mips64 processors with existing support over in arch/mips.
4
5The driver files can be categorized into three basic groups:
6
71) Register definitions, these are named cvmx-*-defs.h
8
92) Main driver code, these have names that don't start cvmx-.
10
113) Interface specific functions and other utility code, names starting
12with cvmx-
13
14Signed-off-by: David Daney <ddaney@caviumnetworks.com>
15---
16 drivers/staging/octeon/Kconfig | 12 +
17 drivers/staging/octeon/Makefile | 30 +
18 drivers/staging/octeon/cvmx-address.h | 274 +++
19 drivers/staging/octeon/cvmx-asxx-defs.h | 475 +++++
20 drivers/staging/octeon/cvmx-cmd-queue.c | 306 +++
21 drivers/staging/octeon/cvmx-cmd-queue.h | 617 ++++++
22 drivers/staging/octeon/cvmx-config.h | 169 ++
23 drivers/staging/octeon/cvmx-dbg-defs.h | 72 +
24 drivers/staging/octeon/cvmx-fau.h | 597 ++++++
25 drivers/staging/octeon/cvmx-fpa-defs.h | 403 ++++
26 drivers/staging/octeon/cvmx-fpa.c | 183 ++
27 drivers/staging/octeon/cvmx-fpa.h | 299 +++
28 drivers/staging/octeon/cvmx-gmxx-defs.h | 2529 +++++++++++++++++++++++
29 drivers/staging/octeon/cvmx-helper-board.c | 706 +++++++
30 drivers/staging/octeon/cvmx-helper-board.h | 180 ++
31 drivers/staging/octeon/cvmx-helper-fpa.c | 243 +++
32 drivers/staging/octeon/cvmx-helper-fpa.h | 64 +
33 drivers/staging/octeon/cvmx-helper-loop.c | 85 +
34 drivers/staging/octeon/cvmx-helper-loop.h | 59 +
35 drivers/staging/octeon/cvmx-helper-npi.c | 113 +
36 drivers/staging/octeon/cvmx-helper-npi.h | 60 +
37 drivers/staging/octeon/cvmx-helper-rgmii.c | 525 +++++
38 drivers/staging/octeon/cvmx-helper-rgmii.h | 110 +
39 drivers/staging/octeon/cvmx-helper-sgmii.c | 550 +++++
40 drivers/staging/octeon/cvmx-helper-sgmii.h | 104 +
41 drivers/staging/octeon/cvmx-helper-spi.c | 195 ++
42 drivers/staging/octeon/cvmx-helper-spi.h | 84 +
43 drivers/staging/octeon/cvmx-helper-util.c | 433 ++++
44 drivers/staging/octeon/cvmx-helper-util.h | 215 ++
45 drivers/staging/octeon/cvmx-helper-xaui.c | 348 ++++
46 drivers/staging/octeon/cvmx-helper-xaui.h | 103 +
47 drivers/staging/octeon/cvmx-helper.c | 1058 ++++++++++
48 drivers/staging/octeon/cvmx-helper.h | 227 ++
49 drivers/staging/octeon/cvmx-interrupt-decodes.c | 371 ++++
50 drivers/staging/octeon/cvmx-interrupt-rsl.c | 140 ++
51 drivers/staging/octeon/cvmx-ipd.h | 338 +++
52 drivers/staging/octeon/cvmx-mdio.h | 506 +++++
53 drivers/staging/octeon/cvmx-packet.h | 65 +
54 drivers/staging/octeon/cvmx-pcsx-defs.h | 370 ++++
55 drivers/staging/octeon/cvmx-pcsxx-defs.h | 316 +++
56 drivers/staging/octeon/cvmx-pip-defs.h | 1267 ++++++++++++
57 drivers/staging/octeon/cvmx-pip.h | 524 +++++
58 drivers/staging/octeon/cvmx-pko-defs.h | 1133 ++++++++++
59 drivers/staging/octeon/cvmx-pko.c | 506 +++++
60 drivers/staging/octeon/cvmx-pko.h | 610 ++++++
61 drivers/staging/octeon/cvmx-pow.h | 1982 ++++++++++++++++++
62 drivers/staging/octeon/cvmx-scratch.h | 139 ++
63 drivers/staging/octeon/cvmx-smix-defs.h | 178 ++
64 drivers/staging/octeon/cvmx-spi.c | 667 ++++++
65 drivers/staging/octeon/cvmx-spi.h | 269 +++
66 drivers/staging/octeon/cvmx-spxx-defs.h | 347 ++++
67 drivers/staging/octeon/cvmx-srxx-defs.h | 126 ++
68 drivers/staging/octeon/cvmx-stxx-defs.h | 292 +++
69 drivers/staging/octeon/cvmx-wqe.h | 397 ++++
70 drivers/staging/octeon/ethernet-common.c | 328 +++
71 drivers/staging/octeon/ethernet-common.h | 29 +
72 drivers/staging/octeon/ethernet-defines.h | 134 ++
73 drivers/staging/octeon/ethernet-mdio.c | 231 +++
74 drivers/staging/octeon/ethernet-mdio.h | 46 +
75 drivers/staging/octeon/ethernet-mem.c | 198 ++
76 drivers/staging/octeon/ethernet-mem.h | 29 +
77 drivers/staging/octeon/ethernet-proc.c | 256 +++
78 drivers/staging/octeon/ethernet-proc.h | 29 +
79 drivers/staging/octeon/ethernet-rgmii.c | 397 ++++
80 drivers/staging/octeon/ethernet-rx.c | 505 +++++
81 drivers/staging/octeon/ethernet-rx.h | 33 +
82 drivers/staging/octeon/ethernet-sgmii.c | 129 ++
83 drivers/staging/octeon/ethernet-spi.c | 323 +++
84 drivers/staging/octeon/ethernet-tx.c | 634 ++++++
85 drivers/staging/octeon/ethernet-tx.h | 32 +
86 drivers/staging/octeon/ethernet-util.h | 81 +
87 drivers/staging/octeon/ethernet-xaui.c | 127 ++
88 drivers/staging/octeon/ethernet.c | 507 +++++
89 drivers/staging/octeon/octeon-ethernet.h | 127 ++
90 74 files changed, 26146 insertions(+), 0 deletions(-)
91 create mode 100644 drivers/staging/octeon/Kconfig
92 create mode 100644 drivers/staging/octeon/Makefile
93 create mode 100644 drivers/staging/octeon/cvmx-address.h
94 create mode 100644 drivers/staging/octeon/cvmx-asxx-defs.h
95 create mode 100644 drivers/staging/octeon/cvmx-cmd-queue.c
96 create mode 100644 drivers/staging/octeon/cvmx-cmd-queue.h
97 create mode 100644 drivers/staging/octeon/cvmx-config.h
98 create mode 100644 drivers/staging/octeon/cvmx-dbg-defs.h
99 create mode 100644 drivers/staging/octeon/cvmx-fau.h
100 create mode 100644 drivers/staging/octeon/cvmx-fpa-defs.h
101 create mode 100644 drivers/staging/octeon/cvmx-fpa.c
102 create mode 100644 drivers/staging/octeon/cvmx-fpa.h
103 create mode 100644 drivers/staging/octeon/cvmx-gmxx-defs.h
104 create mode 100644 drivers/staging/octeon/cvmx-helper-board.c
105 create mode 100644 drivers/staging/octeon/cvmx-helper-board.h
106 create mode 100644 drivers/staging/octeon/cvmx-helper-fpa.c
107 create mode 100644 drivers/staging/octeon/cvmx-helper-fpa.h
108 create mode 100644 drivers/staging/octeon/cvmx-helper-loop.c
109 create mode 100644 drivers/staging/octeon/cvmx-helper-loop.h
110 create mode 100644 drivers/staging/octeon/cvmx-helper-npi.c
111 create mode 100644 drivers/staging/octeon/cvmx-helper-npi.h
112 create mode 100644 drivers/staging/octeon/cvmx-helper-rgmii.c
113 create mode 100644 drivers/staging/octeon/cvmx-helper-rgmii.h
114 create mode 100644 drivers/staging/octeon/cvmx-helper-sgmii.c
115 create mode 100644 drivers/staging/octeon/cvmx-helper-sgmii.h
116 create mode 100644 drivers/staging/octeon/cvmx-helper-spi.c
117 create mode 100644 drivers/staging/octeon/cvmx-helper-spi.h
118 create mode 100644 drivers/staging/octeon/cvmx-helper-util.c
119 create mode 100644 drivers/staging/octeon/cvmx-helper-util.h
120 create mode 100644 drivers/staging/octeon/cvmx-helper-xaui.c
121 create mode 100644 drivers/staging/octeon/cvmx-helper-xaui.h
122 create mode 100644 drivers/staging/octeon/cvmx-helper.c
123 create mode 100644 drivers/staging/octeon/cvmx-helper.h
124 create mode 100644 drivers/staging/octeon/cvmx-interrupt-decodes.c
125 create mode 100644 drivers/staging/octeon/cvmx-interrupt-rsl.c
126 create mode 100644 drivers/staging/octeon/cvmx-ipd.h
127 create mode 100644 drivers/staging/octeon/cvmx-mdio.h
128 create mode 100644 drivers/staging/octeon/cvmx-packet.h
129 create mode 100644 drivers/staging/octeon/cvmx-pcsx-defs.h
130 create mode 100644 drivers/staging/octeon/cvmx-pcsxx-defs.h
131 create mode 100644 drivers/staging/octeon/cvmx-pip-defs.h
132 create mode 100644 drivers/staging/octeon/cvmx-pip.h
133 create mode 100644 drivers/staging/octeon/cvmx-pko-defs.h
134 create mode 100644 drivers/staging/octeon/cvmx-pko.c
135 create mode 100644 drivers/staging/octeon/cvmx-pko.h
136 create mode 100644 drivers/staging/octeon/cvmx-pow.h
137 create mode 100644 drivers/staging/octeon/cvmx-scratch.h
138 create mode 100644 drivers/staging/octeon/cvmx-smix-defs.h
139 create mode 100644 drivers/staging/octeon/cvmx-spi.c
140 create mode 100644 drivers/staging/octeon/cvmx-spi.h
141 create mode 100644 drivers/staging/octeon/cvmx-spxx-defs.h
142 create mode 100644 drivers/staging/octeon/cvmx-srxx-defs.h
143 create mode 100644 drivers/staging/octeon/cvmx-stxx-defs.h
144 create mode 100644 drivers/staging/octeon/cvmx-wqe.h
145 create mode 100644 drivers/staging/octeon/ethernet-common.c
146 create mode 100644 drivers/staging/octeon/ethernet-common.h
147 create mode 100644 drivers/staging/octeon/ethernet-defines.h
148 create mode 100644 drivers/staging/octeon/ethernet-mdio.c
149 create mode 100644 drivers/staging/octeon/ethernet-mdio.h
150 create mode 100644 drivers/staging/octeon/ethernet-mem.c
151 create mode 100644 drivers/staging/octeon/ethernet-mem.h
152 create mode 100644 drivers/staging/octeon/ethernet-proc.c
153 create mode 100644 drivers/staging/octeon/ethernet-proc.h
154 create mode 100644 drivers/staging/octeon/ethernet-rgmii.c
155 create mode 100644 drivers/staging/octeon/ethernet-rx.c
156 create mode 100644 drivers/staging/octeon/ethernet-rx.h
157 create mode 100644 drivers/staging/octeon/ethernet-sgmii.c
158 create mode 100644 drivers/staging/octeon/ethernet-spi.c
159 create mode 100644 drivers/staging/octeon/ethernet-tx.c
160 create mode 100644 drivers/staging/octeon/ethernet-tx.h
161 create mode 100644 drivers/staging/octeon/ethernet-util.h
162 create mode 100644 drivers/staging/octeon/ethernet-xaui.c
163 create mode 100644 drivers/staging/octeon/ethernet.c
164 create mode 100644 drivers/staging/octeon/octeon-ethernet.h
165
166--- /dev/null
167+++ b/drivers/staging/octeon/Kconfig
168@@ -0,0 +1,12 @@
169+config OCTEON_ETHERNET
170+ tristate "Cavium Networks Octeon Ethernet support"
171+ depends on CPU_CAVIUM_OCTEON
172+ select MII
173+ help
174+ This driver supports the builtin ethernet ports on Cavium
175+ Networks' products in the Octeon family. This driver supports the
176+ CN3XXX and CN5XXX Octeon processors.
177+
178+ To compile this driver as a module, choose M here. The module
179+ will be called octeon-ethernet.
180+
181--- /dev/null
182+++ b/drivers/staging/octeon/Makefile
183@@ -0,0 +1,30 @@
184+# This file is subject to the terms and conditions of the GNU General Public
185+# License. See the file "COPYING" in the main directory of this archive
186+# for more details.
187+#
188+# Copyright (C) 2005-2009 Cavium Networks
189+#
190+
191+#
192+# Makefile for Cavium OCTEON on-board ethernet driver
193+#
194+
195+obj-${CONFIG_OCTEON_ETHERNET} := octeon-ethernet.o
196+
197+octeon-ethernet-objs := ethernet.o
198+octeon-ethernet-objs += ethernet-common.o
199+octeon-ethernet-objs += ethernet-mdio.o
200+octeon-ethernet-objs += ethernet-mem.o
201+octeon-ethernet-objs += ethernet-proc.o
202+octeon-ethernet-objs += ethernet-rgmii.o
203+octeon-ethernet-objs += ethernet-rx.o
204+octeon-ethernet-objs += ethernet-sgmii.o
205+octeon-ethernet-objs += ethernet-spi.o
206+octeon-ethernet-objs += ethernet-tx.o
207+octeon-ethernet-objs += ethernet-xaui.o
208+octeon-ethernet-objs += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \
209+ cvmx-helper-board.o cvmx-helper.o cvmx-helper-xaui.o \
210+ cvmx-helper-rgmii.o cvmx-helper-sgmii.o cvmx-helper-npi.o \
211+ cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \
212+ cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o
213+
214--- /dev/null
215+++ b/drivers/staging/octeon/cvmx-address.h
216@@ -0,0 +1,274 @@
217+/***********************license start***************
218+ * Author: Cavium Networks
219+ *
220+ * Contact: support@caviumnetworks.com
221+ * This file is part of the OCTEON SDK
222+ *
223+ * Copyright (c) 2003-2009 Cavium Networks
224+ *
225+ * This file is free software; you can redistribute it and/or modify
226+ * it under the terms of the GNU General Public License, Version 2, as
227+ * published by the Free Software Foundation.
228+ *
229+ * This file is distributed in the hope that it will be useful, but
230+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
231+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
232+ * NONINFRINGEMENT. See the GNU General Public License for more
233+ * details.
234+ *
235+ * You should have received a copy of the GNU General Public License
236+ * along with this file; if not, write to the Free Software
237+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
238+ * or visit http://www.gnu.org/licenses/.
239+ *
240+ * This file may also be available under a different license from Cavium.
241+ * Contact Cavium Networks for more information
242+ ***********************license end**************************************/
243+
244+/**
245+ * Typedefs and defines for working with Octeon physical addresses.
246+ *
247+ */
248+#ifndef __CVMX_ADDRESS_H__
249+#define __CVMX_ADDRESS_H__
250+
251+#if 0
252+typedef enum {
253+ CVMX_MIPS_SPACE_XKSEG = 3LL,
254+ CVMX_MIPS_SPACE_XKPHYS = 2LL,
255+ CVMX_MIPS_SPACE_XSSEG = 1LL,
256+ CVMX_MIPS_SPACE_XUSEG = 0LL
257+} cvmx_mips_space_t;
258+#endif
259+
260+typedef enum {
261+ CVMX_MIPS_XKSEG_SPACE_KSEG0 = 0LL,
262+ CVMX_MIPS_XKSEG_SPACE_KSEG1 = 1LL,
263+ CVMX_MIPS_XKSEG_SPACE_SSEG = 2LL,
264+ CVMX_MIPS_XKSEG_SPACE_KSEG3 = 3LL
265+} cvmx_mips_xkseg_space_t;
266+
267+/* decodes <14:13> of a kseg3 window address */
268+typedef enum {
269+ CVMX_ADD_WIN_SCR = 0L,
270+ /* see cvmx_add_win_dma_dec_t for further decode */
271+ CVMX_ADD_WIN_DMA = 1L,
272+ CVMX_ADD_WIN_UNUSED = 2L,
273+ CVMX_ADD_WIN_UNUSED2 = 3L
274+} cvmx_add_win_dec_t;
275+
276+/* decode within DMA space */
277+typedef enum {
278+ /*
279+ * Add store data to the write buffer entry, allocating it if
280+ * necessary.
281+ */
282+ CVMX_ADD_WIN_DMA_ADD = 0L,
283+ /* send out the write buffer entry to DRAM */
284+ CVMX_ADD_WIN_DMA_SENDMEM = 1L,
285+ /* store data must be normal DRAM memory space address in this case */
286+ /* send out the write buffer entry as an IOBDMA command */
287+ CVMX_ADD_WIN_DMA_SENDDMA = 2L,
288+ /* see CVMX_ADD_WIN_DMA_SEND_DEC for data contents */
289+ /* send out the write buffer entry as an IO write */
290+ CVMX_ADD_WIN_DMA_SENDIO = 3L,
291+ /* store data must be normal IO space address in this case */
292+ /* send out a single-tick command on the NCB bus */
293+ CVMX_ADD_WIN_DMA_SENDSINGLE = 4L,
294+ /* no write buffer data needed/used */
295+} cvmx_add_win_dma_dec_t;
296+
297+/*
298+ * Physical Address Decode
299+ *
300+ * Octeon-I HW never interprets this X (<39:36> reserved
301+ * for future expansion), software should set to 0.
302+ *
303+ * - 0x0 XXX0 0000 0000 to DRAM Cached
304+ * - 0x0 XXX0 0FFF FFFF
305+ *
306+ * - 0x0 XXX0 1000 0000 to Boot Bus Uncached (Converted to 0x1 00X0 1000 0000
307+ * - 0x0 XXX0 1FFF FFFF + EJTAG to 0x1 00X0 1FFF FFFF)
308+ *
309+ * - 0x0 XXX0 2000 0000 to DRAM Cached
310+ * - 0x0 XXXF FFFF FFFF
311+ *
312+ * - 0x1 00X0 0000 0000 to Boot Bus Uncached
313+ * - 0x1 00XF FFFF FFFF
314+ *
315+ * - 0x1 01X0 0000 0000 to Other NCB Uncached
316+ * - 0x1 FFXF FFFF FFFF devices
317+ *
318+ * Decode of all Octeon addresses
319+ */
320+typedef union {
321+
322+ uint64_t u64;
323+ /* mapped or unmapped virtual address */
324+ struct {
325+ uint64_t R:2;
326+ uint64_t offset:62;
327+ } sva;
328+
329+ /* mapped USEG virtual addresses (typically) */
330+ struct {
331+ uint64_t zeroes:33;
332+ uint64_t offset:31;
333+ } suseg;
334+
335+ /* mapped or unmapped virtual address */
336+ struct {
337+ uint64_t ones:33;
338+ uint64_t sp:2;
339+ uint64_t offset:29;
340+ } sxkseg;
341+
342+ /*
343+ * physical address accessed through xkphys unmapped virtual
344+ * address.
345+ */
346+ struct {
347+ uint64_t R:2; /* CVMX_MIPS_SPACE_XKPHYS in this case */
348+ uint64_t cca:3; /* ignored by octeon */
349+ uint64_t mbz:10;
350+ uint64_t pa:49; /* physical address */
351+ } sxkphys;
352+
353+ /* physical address */
354+ struct {
355+ uint64_t mbz:15;
356+ /* if set, the address is uncached and resides on MCB bus */
357+ uint64_t is_io:1;
358+ /*
359+ * the hardware ignores this field when is_io==0, else
360+ * device ID.
361+ */
362+ uint64_t did:8;
363+ /* the hardware ignores <39:36> in Octeon I */
364+ uint64_t unaddr:4;
365+ uint64_t offset:36;
366+ } sphys;
367+
368+ /* physical mem address */
369+ struct {
370+ /* techically, <47:40> are dont-cares */
371+ uint64_t zeroes:24;
372+ /* the hardware ignores <39:36> in Octeon I */
373+ uint64_t unaddr:4;
374+ uint64_t offset:36;
375+ } smem;
376+
377+ /* physical IO address */
378+ struct {
379+ uint64_t mem_region:2;
380+ uint64_t mbz:13;
381+ /* 1 in this case */
382+ uint64_t is_io:1;
383+ /*
384+ * The hardware ignores this field when is_io==0, else
385+ * device ID.
386+ */
387+ uint64_t did:8;
388+ /* the hardware ignores <39:36> in Octeon I */
389+ uint64_t unaddr:4;
390+ uint64_t offset:36;
391+ } sio;
392+
393+ /*
394+ * Scratchpad virtual address - accessed through a window at
395+ * the end of kseg3
396+ */
397+ struct {
398+ uint64_t ones:49;
399+ /* CVMX_ADD_WIN_SCR (0) in this case */
400+ cvmx_add_win_dec_t csrdec:2;
401+ uint64_t addr:13;
402+ } sscr;
403+
404+ /* there should only be stores to IOBDMA space, no loads */
405+ /*
406+ * IOBDMA virtual address - accessed through a window at the
407+ * end of kseg3
408+ */
409+ struct {
410+ uint64_t ones:49;
411+ uint64_t csrdec:2; /* CVMX_ADD_WIN_DMA (1) in this case */
412+ uint64_t unused2:3;
413+ uint64_t type:3;
414+ uint64_t addr:7;
415+ } sdma;
416+
417+ struct {
418+ uint64_t didspace:24;
419+ uint64_t unused:40;
420+ } sfilldidspace;
421+
422+} cvmx_addr_t;
423+
424+/* These macros for used by 32 bit applications */
425+
426+#define CVMX_MIPS32_SPACE_KSEG0 1l
427+#define CVMX_ADD_SEG32(segment, add) \
428+ (((int32_t)segment << 31) | (int32_t)(add))
429+
430+/*
431+ * Currently all IOs are performed using XKPHYS addressing. Linux uses
432+ * the CvmMemCtl register to enable XKPHYS addressing to IO space from
433+ * user mode. Future OSes may need to change the upper bits of IO
434+ * addresses. The following define controls the upper two bits for all
435+ * IO addresses generated by the simple executive library.
436+ */
437+#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
438+
439+/* These macros simplify the process of creating common IO addresses */
440+#define CVMX_ADD_SEG(segment, add) ((((uint64_t)segment) << 62) | (add))
441+#ifndef CVMX_ADD_IO_SEG
442+#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
443+#endif
444+#define CVMX_ADDR_DIDSPACE(did) (((CVMX_IO_SEG) << 22) | ((1ULL) << 8) | (did))
445+#define CVMX_ADDR_DID(did) (CVMX_ADDR_DIDSPACE(did) << 40)
446+#define CVMX_FULL_DID(did, subdid) (((did) << 3) | (subdid))
447+
448+ /* from include/ncb_rsl_id.v */
449+#define CVMX_OCT_DID_MIS 0ULL /* misc stuff */
450+#define CVMX_OCT_DID_GMX0 1ULL
451+#define CVMX_OCT_DID_GMX1 2ULL
452+#define CVMX_OCT_DID_PCI 3ULL
453+#define CVMX_OCT_DID_KEY 4ULL
454+#define CVMX_OCT_DID_FPA 5ULL
455+#define CVMX_OCT_DID_DFA 6ULL
456+#define CVMX_OCT_DID_ZIP 7ULL
457+#define CVMX_OCT_DID_RNG 8ULL
458+#define CVMX_OCT_DID_IPD 9ULL
459+#define CVMX_OCT_DID_PKT 10ULL
460+#define CVMX_OCT_DID_TIM 11ULL
461+#define CVMX_OCT_DID_TAG 12ULL
462+ /* the rest are not on the IO bus */
463+#define CVMX_OCT_DID_L2C 16ULL
464+#define CVMX_OCT_DID_LMC 17ULL
465+#define CVMX_OCT_DID_SPX0 18ULL
466+#define CVMX_OCT_DID_SPX1 19ULL
467+#define CVMX_OCT_DID_PIP 20ULL
468+#define CVMX_OCT_DID_ASX0 22ULL
469+#define CVMX_OCT_DID_ASX1 23ULL
470+#define CVMX_OCT_DID_IOB 30ULL
471+
472+#define CVMX_OCT_DID_PKT_SEND CVMX_FULL_DID(CVMX_OCT_DID_PKT, 2ULL)
473+#define CVMX_OCT_DID_TAG_SWTAG CVMX_FULL_DID(CVMX_OCT_DID_TAG, 0ULL)
474+#define CVMX_OCT_DID_TAG_TAG1 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 1ULL)
475+#define CVMX_OCT_DID_TAG_TAG2 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 2ULL)
476+#define CVMX_OCT_DID_TAG_TAG3 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 3ULL)
477+#define CVMX_OCT_DID_TAG_NULL_RD CVMX_FULL_DID(CVMX_OCT_DID_TAG, 4ULL)
478+#define CVMX_OCT_DID_TAG_CSR CVMX_FULL_DID(CVMX_OCT_DID_TAG, 7ULL)
479+#define CVMX_OCT_DID_FAU_FAI CVMX_FULL_DID(CVMX_OCT_DID_IOB, 0ULL)
480+#define CVMX_OCT_DID_TIM_CSR CVMX_FULL_DID(CVMX_OCT_DID_TIM, 0ULL)
481+#define CVMX_OCT_DID_KEY_RW CVMX_FULL_DID(CVMX_OCT_DID_KEY, 0ULL)
482+#define CVMX_OCT_DID_PCI_6 CVMX_FULL_DID(CVMX_OCT_DID_PCI, 6ULL)
483+#define CVMX_OCT_DID_MIS_BOO CVMX_FULL_DID(CVMX_OCT_DID_MIS, 0ULL)
484+#define CVMX_OCT_DID_PCI_RML CVMX_FULL_DID(CVMX_OCT_DID_PCI, 0ULL)
485+#define CVMX_OCT_DID_IPD_CSR CVMX_FULL_DID(CVMX_OCT_DID_IPD, 7ULL)
486+#define CVMX_OCT_DID_DFA_CSR CVMX_FULL_DID(CVMX_OCT_DID_DFA, 7ULL)
487+#define CVMX_OCT_DID_MIS_CSR CVMX_FULL_DID(CVMX_OCT_DID_MIS, 7ULL)
488+#define CVMX_OCT_DID_ZIP_CSR CVMX_FULL_DID(CVMX_OCT_DID_ZIP, 0ULL)
489+
490+#endif /* __CVMX_ADDRESS_H__ */
491--- /dev/null
492+++ b/drivers/staging/octeon/cvmx-asxx-defs.h
493@@ -0,0 +1,475 @@
494+/***********************license start***************
495+ * Author: Cavium Networks
496+ *
497+ * Contact: support@caviumnetworks.com
498+ * This file is part of the OCTEON SDK
499+ *
500+ * Copyright (c) 2003-2008 Cavium Networks
501+ *
502+ * This file is free software; you can redistribute it and/or modify
503+ * it under the terms of the GNU General Public License, Version 2, as
504+ * published by the Free Software Foundation.
505+ *
506+ * This file is distributed in the hope that it will be useful, but
507+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
508+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
509+ * NONINFRINGEMENT. See the GNU General Public License for more
510+ * details.
511+ *
512+ * You should have received a copy of the GNU General Public License
513+ * along with this file; if not, write to the Free Software
514+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
515+ * or visit http://www.gnu.org/licenses/.
516+ *
517+ * This file may also be available under a different license from Cavium.
518+ * Contact Cavium Networks for more information
519+ ***********************license end**************************************/
520+
521+#ifndef __CVMX_ASXX_DEFS_H__
522+#define __CVMX_ASXX_DEFS_H__
523+
524+#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) \
525+ CVMX_ADD_IO_SEG(0x00011800B0000180ull + (((block_id) & 0) * 0x8000000ull))
526+#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) \
527+ CVMX_ADD_IO_SEG(0x00011800B0000188ull + (((block_id) & 0) * 0x8000000ull))
528+#define CVMX_ASXX_INT_EN(block_id) \
529+ CVMX_ADD_IO_SEG(0x00011800B0000018ull + (((block_id) & 1) * 0x8000000ull))
530+#define CVMX_ASXX_INT_REG(block_id) \
531+ CVMX_ADD_IO_SEG(0x00011800B0000010ull + (((block_id) & 1) * 0x8000000ull))
532+#define CVMX_ASXX_MII_RX_DAT_SET(block_id) \
533+ CVMX_ADD_IO_SEG(0x00011800B0000190ull + (((block_id) & 0) * 0x8000000ull))
534+#define CVMX_ASXX_PRT_LOOP(block_id) \
535+ CVMX_ADD_IO_SEG(0x00011800B0000040ull + (((block_id) & 1) * 0x8000000ull))
536+#define CVMX_ASXX_RLD_BYPASS(block_id) \
537+ CVMX_ADD_IO_SEG(0x00011800B0000248ull + (((block_id) & 1) * 0x8000000ull))
538+#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) \
539+ CVMX_ADD_IO_SEG(0x00011800B0000250ull + (((block_id) & 1) * 0x8000000ull))
540+#define CVMX_ASXX_RLD_COMP(block_id) \
541+ CVMX_ADD_IO_SEG(0x00011800B0000220ull + (((block_id) & 1) * 0x8000000ull))
542+#define CVMX_ASXX_RLD_DATA_DRV(block_id) \
543+ CVMX_ADD_IO_SEG(0x00011800B0000218ull + (((block_id) & 1) * 0x8000000ull))
544+#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) \
545+ CVMX_ADD_IO_SEG(0x00011800B0000210ull + (((block_id) & 1) * 0x8000000ull))
546+#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) \
547+ CVMX_ADD_IO_SEG(0x00011800B0000230ull + (((block_id) & 1) * 0x8000000ull))
548+#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) \
549+ CVMX_ADD_IO_SEG(0x00011800B0000240ull + (((block_id) & 1) * 0x8000000ull))
550+#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) \
551+ CVMX_ADD_IO_SEG(0x00011800B0000228ull + (((block_id) & 1) * 0x8000000ull))
552+#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) \
553+ CVMX_ADD_IO_SEG(0x00011800B0000238ull + (((block_id) & 1) * 0x8000000ull))
554+#define CVMX_ASXX_RLD_SETTING(block_id) \
555+ CVMX_ADD_IO_SEG(0x00011800B0000258ull + (((block_id) & 1) * 0x8000000ull))
556+#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) \
557+ CVMX_ADD_IO_SEG(0x00011800B0000020ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
558+#define CVMX_ASXX_RX_PRT_EN(block_id) \
559+ CVMX_ADD_IO_SEG(0x00011800B0000000ull + (((block_id) & 1) * 0x8000000ull))
560+#define CVMX_ASXX_RX_WOL(block_id) \
561+ CVMX_ADD_IO_SEG(0x00011800B0000100ull + (((block_id) & 1) * 0x8000000ull))
562+#define CVMX_ASXX_RX_WOL_MSK(block_id) \
563+ CVMX_ADD_IO_SEG(0x00011800B0000108ull + (((block_id) & 1) * 0x8000000ull))
564+#define CVMX_ASXX_RX_WOL_POWOK(block_id) \
565+ CVMX_ADD_IO_SEG(0x00011800B0000118ull + (((block_id) & 1) * 0x8000000ull))
566+#define CVMX_ASXX_RX_WOL_SIG(block_id) \
567+ CVMX_ADD_IO_SEG(0x00011800B0000110ull + (((block_id) & 1) * 0x8000000ull))
568+#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) \
569+ CVMX_ADD_IO_SEG(0x00011800B0000048ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
570+#define CVMX_ASXX_TX_COMP_BYP(block_id) \
571+ CVMX_ADD_IO_SEG(0x00011800B0000068ull + (((block_id) & 1) * 0x8000000ull))
572+#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) \
573+ CVMX_ADD_IO_SEG(0x00011800B0000080ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
574+#define CVMX_ASXX_TX_PRT_EN(block_id) \
575+ CVMX_ADD_IO_SEG(0x00011800B0000008ull + (((block_id) & 1) * 0x8000000ull))
576+
577+union cvmx_asxx_gmii_rx_clk_set {
578+ uint64_t u64;
579+ struct cvmx_asxx_gmii_rx_clk_set_s {
580+ uint64_t reserved_5_63:59;
581+ uint64_t setting:5;
582+ } s;
583+ struct cvmx_asxx_gmii_rx_clk_set_s cn30xx;
584+ struct cvmx_asxx_gmii_rx_clk_set_s cn31xx;
585+ struct cvmx_asxx_gmii_rx_clk_set_s cn50xx;
586+};
587+
588+union cvmx_asxx_gmii_rx_dat_set {
589+ uint64_t u64;
590+ struct cvmx_asxx_gmii_rx_dat_set_s {
591+ uint64_t reserved_5_63:59;
592+ uint64_t setting:5;
593+ } s;
594+ struct cvmx_asxx_gmii_rx_dat_set_s cn30xx;
595+ struct cvmx_asxx_gmii_rx_dat_set_s cn31xx;
596+ struct cvmx_asxx_gmii_rx_dat_set_s cn50xx;
597+};
598+
599+union cvmx_asxx_int_en {
600+ uint64_t u64;
601+ struct cvmx_asxx_int_en_s {
602+ uint64_t reserved_12_63:52;
603+ uint64_t txpsh:4;
604+ uint64_t txpop:4;
605+ uint64_t ovrflw:4;
606+ } s;
607+ struct cvmx_asxx_int_en_cn30xx {
608+ uint64_t reserved_11_63:53;
609+ uint64_t txpsh:3;
610+ uint64_t reserved_7_7:1;
611+ uint64_t txpop:3;
612+ uint64_t reserved_3_3:1;
613+ uint64_t ovrflw:3;
614+ } cn30xx;
615+ struct cvmx_asxx_int_en_cn30xx cn31xx;
616+ struct cvmx_asxx_int_en_s cn38xx;
617+ struct cvmx_asxx_int_en_s cn38xxp2;
618+ struct cvmx_asxx_int_en_cn30xx cn50xx;
619+ struct cvmx_asxx_int_en_s cn58xx;
620+ struct cvmx_asxx_int_en_s cn58xxp1;
621+};
622+
623+union cvmx_asxx_int_reg {
624+ uint64_t u64;
625+ struct cvmx_asxx_int_reg_s {
626+ uint64_t reserved_12_63:52;
627+ uint64_t txpsh:4;
628+ uint64_t txpop:4;
629+ uint64_t ovrflw:4;
630+ } s;
631+ struct cvmx_asxx_int_reg_cn30xx {
632+ uint64_t reserved_11_63:53;
633+ uint64_t txpsh:3;
634+ uint64_t reserved_7_7:1;
635+ uint64_t txpop:3;
636+ uint64_t reserved_3_3:1;
637+ uint64_t ovrflw:3;
638+ } cn30xx;
639+ struct cvmx_asxx_int_reg_cn30xx cn31xx;
640+ struct cvmx_asxx_int_reg_s cn38xx;
641+ struct cvmx_asxx_int_reg_s cn38xxp2;
642+ struct cvmx_asxx_int_reg_cn30xx cn50xx;
643+ struct cvmx_asxx_int_reg_s cn58xx;
644+ struct cvmx_asxx_int_reg_s cn58xxp1;
645+};
646+
647+union cvmx_asxx_mii_rx_dat_set {
648+ uint64_t u64;
649+ struct cvmx_asxx_mii_rx_dat_set_s {
650+ uint64_t reserved_5_63:59;
651+ uint64_t setting:5;
652+ } s;
653+ struct cvmx_asxx_mii_rx_dat_set_s cn30xx;
654+ struct cvmx_asxx_mii_rx_dat_set_s cn50xx;
655+};
656+
657+union cvmx_asxx_prt_loop {
658+ uint64_t u64;
659+ struct cvmx_asxx_prt_loop_s {
660+ uint64_t reserved_8_63:56;
661+ uint64_t ext_loop:4;
662+ uint64_t int_loop:4;
663+ } s;
664+ struct cvmx_asxx_prt_loop_cn30xx {
665+ uint64_t reserved_7_63:57;
666+ uint64_t ext_loop:3;
667+ uint64_t reserved_3_3:1;
668+ uint64_t int_loop:3;
669+ } cn30xx;
670+ struct cvmx_asxx_prt_loop_cn30xx cn31xx;
671+ struct cvmx_asxx_prt_loop_s cn38xx;
672+ struct cvmx_asxx_prt_loop_s cn38xxp2;
673+ struct cvmx_asxx_prt_loop_cn30xx cn50xx;
674+ struct cvmx_asxx_prt_loop_s cn58xx;
675+ struct cvmx_asxx_prt_loop_s cn58xxp1;
676+};
677+
678+union cvmx_asxx_rld_bypass {
679+ uint64_t u64;
680+ struct cvmx_asxx_rld_bypass_s {
681+ uint64_t reserved_1_63:63;
682+ uint64_t bypass:1;
683+ } s;
684+ struct cvmx_asxx_rld_bypass_s cn38xx;
685+ struct cvmx_asxx_rld_bypass_s cn38xxp2;
686+ struct cvmx_asxx_rld_bypass_s cn58xx;
687+ struct cvmx_asxx_rld_bypass_s cn58xxp1;
688+};
689+
690+union cvmx_asxx_rld_bypass_setting {
691+ uint64_t u64;
692+ struct cvmx_asxx_rld_bypass_setting_s {
693+ uint64_t reserved_5_63:59;
694+ uint64_t setting:5;
695+ } s;
696+ struct cvmx_asxx_rld_bypass_setting_s cn38xx;
697+ struct cvmx_asxx_rld_bypass_setting_s cn38xxp2;
698+ struct cvmx_asxx_rld_bypass_setting_s cn58xx;
699+ struct cvmx_asxx_rld_bypass_setting_s cn58xxp1;
700+};
701+
702+union cvmx_asxx_rld_comp {
703+ uint64_t u64;
704+ struct cvmx_asxx_rld_comp_s {
705+ uint64_t reserved_9_63:55;
706+ uint64_t pctl:5;
707+ uint64_t nctl:4;
708+ } s;
709+ struct cvmx_asxx_rld_comp_cn38xx {
710+ uint64_t reserved_8_63:56;
711+ uint64_t pctl:4;
712+ uint64_t nctl:4;
713+ } cn38xx;
714+ struct cvmx_asxx_rld_comp_cn38xx cn38xxp2;
715+ struct cvmx_asxx_rld_comp_s cn58xx;
716+ struct cvmx_asxx_rld_comp_s cn58xxp1;
717+};
718+
719+union cvmx_asxx_rld_data_drv {
720+ uint64_t u64;
721+ struct cvmx_asxx_rld_data_drv_s {
722+ uint64_t reserved_8_63:56;
723+ uint64_t pctl:4;
724+ uint64_t nctl:4;
725+ } s;
726+ struct cvmx_asxx_rld_data_drv_s cn38xx;
727+ struct cvmx_asxx_rld_data_drv_s cn38xxp2;
728+ struct cvmx_asxx_rld_data_drv_s cn58xx;
729+ struct cvmx_asxx_rld_data_drv_s cn58xxp1;
730+};
731+
732+union cvmx_asxx_rld_fcram_mode {
733+ uint64_t u64;
734+ struct cvmx_asxx_rld_fcram_mode_s {
735+ uint64_t reserved_1_63:63;
736+ uint64_t mode:1;
737+ } s;
738+ struct cvmx_asxx_rld_fcram_mode_s cn38xx;
739+ struct cvmx_asxx_rld_fcram_mode_s cn38xxp2;
740+};
741+
742+union cvmx_asxx_rld_nctl_strong {
743+ uint64_t u64;
744+ struct cvmx_asxx_rld_nctl_strong_s {
745+ uint64_t reserved_5_63:59;
746+ uint64_t nctl:5;
747+ } s;
748+ struct cvmx_asxx_rld_nctl_strong_s cn38xx;
749+ struct cvmx_asxx_rld_nctl_strong_s cn38xxp2;
750+ struct cvmx_asxx_rld_nctl_strong_s cn58xx;
751+ struct cvmx_asxx_rld_nctl_strong_s cn58xxp1;
752+};
753+
754+union cvmx_asxx_rld_nctl_weak {
755+ uint64_t u64;
756+ struct cvmx_asxx_rld_nctl_weak_s {
757+ uint64_t reserved_5_63:59;
758+ uint64_t nctl:5;
759+ } s;
760+ struct cvmx_asxx_rld_nctl_weak_s cn38xx;
761+ struct cvmx_asxx_rld_nctl_weak_s cn38xxp2;
762+ struct cvmx_asxx_rld_nctl_weak_s cn58xx;
763+ struct cvmx_asxx_rld_nctl_weak_s cn58xxp1;
764+};
765+
766+union cvmx_asxx_rld_pctl_strong {
767+ uint64_t u64;
768+ struct cvmx_asxx_rld_pctl_strong_s {
769+ uint64_t reserved_5_63:59;
770+ uint64_t pctl:5;
771+ } s;
772+ struct cvmx_asxx_rld_pctl_strong_s cn38xx;
773+ struct cvmx_asxx_rld_pctl_strong_s cn38xxp2;
774+ struct cvmx_asxx_rld_pctl_strong_s cn58xx;
775+ struct cvmx_asxx_rld_pctl_strong_s cn58xxp1;
776+};
777+
778+union cvmx_asxx_rld_pctl_weak {
779+ uint64_t u64;
780+ struct cvmx_asxx_rld_pctl_weak_s {
781+ uint64_t reserved_5_63:59;
782+ uint64_t pctl:5;
783+ } s;
784+ struct cvmx_asxx_rld_pctl_weak_s cn38xx;
785+ struct cvmx_asxx_rld_pctl_weak_s cn38xxp2;
786+ struct cvmx_asxx_rld_pctl_weak_s cn58xx;
787+ struct cvmx_asxx_rld_pctl_weak_s cn58xxp1;
788+};
789+
790+union cvmx_asxx_rld_setting {
791+ uint64_t u64;
792+ struct cvmx_asxx_rld_setting_s {
793+ uint64_t reserved_13_63:51;
794+ uint64_t dfaset:5;
795+ uint64_t dfalag:1;
796+ uint64_t dfalead:1;
797+ uint64_t dfalock:1;
798+ uint64_t setting:5;
799+ } s;
800+ struct cvmx_asxx_rld_setting_cn38xx {
801+ uint64_t reserved_5_63:59;
802+ uint64_t setting:5;
803+ } cn38xx;
804+ struct cvmx_asxx_rld_setting_cn38xx cn38xxp2;
805+ struct cvmx_asxx_rld_setting_s cn58xx;
806+ struct cvmx_asxx_rld_setting_s cn58xxp1;
807+};
808+
809+union cvmx_asxx_rx_clk_setx {
810+ uint64_t u64;
811+ struct cvmx_asxx_rx_clk_setx_s {
812+ uint64_t reserved_5_63:59;
813+ uint64_t setting:5;
814+ } s;
815+ struct cvmx_asxx_rx_clk_setx_s cn30xx;
816+ struct cvmx_asxx_rx_clk_setx_s cn31xx;
817+ struct cvmx_asxx_rx_clk_setx_s cn38xx;
818+ struct cvmx_asxx_rx_clk_setx_s cn38xxp2;
819+ struct cvmx_asxx_rx_clk_setx_s cn50xx;
820+ struct cvmx_asxx_rx_clk_setx_s cn58xx;
821+ struct cvmx_asxx_rx_clk_setx_s cn58xxp1;
822+};
823+
824+union cvmx_asxx_rx_prt_en {
825+ uint64_t u64;
826+ struct cvmx_asxx_rx_prt_en_s {
827+ uint64_t reserved_4_63:60;
828+ uint64_t prt_en:4;
829+ } s;
830+ struct cvmx_asxx_rx_prt_en_cn30xx {
831+ uint64_t reserved_3_63:61;
832+ uint64_t prt_en:3;
833+ } cn30xx;
834+ struct cvmx_asxx_rx_prt_en_cn30xx cn31xx;
835+ struct cvmx_asxx_rx_prt_en_s cn38xx;
836+ struct cvmx_asxx_rx_prt_en_s cn38xxp2;
837+ struct cvmx_asxx_rx_prt_en_cn30xx cn50xx;
838+ struct cvmx_asxx_rx_prt_en_s cn58xx;
839+ struct cvmx_asxx_rx_prt_en_s cn58xxp1;
840+};
841+
842+union cvmx_asxx_rx_wol {
843+ uint64_t u64;
844+ struct cvmx_asxx_rx_wol_s {
845+ uint64_t reserved_2_63:62;
846+ uint64_t status:1;
847+ uint64_t enable:1;
848+ } s;
849+ struct cvmx_asxx_rx_wol_s cn38xx;
850+ struct cvmx_asxx_rx_wol_s cn38xxp2;
851+};
852+
853+union cvmx_asxx_rx_wol_msk {
854+ uint64_t u64;
855+ struct cvmx_asxx_rx_wol_msk_s {
856+ uint64_t msk:64;
857+ } s;
858+ struct cvmx_asxx_rx_wol_msk_s cn38xx;
859+ struct cvmx_asxx_rx_wol_msk_s cn38xxp2;
860+};
861+
862+union cvmx_asxx_rx_wol_powok {
863+ uint64_t u64;
864+ struct cvmx_asxx_rx_wol_powok_s {
865+ uint64_t reserved_1_63:63;
866+ uint64_t powerok:1;
867+ } s;
868+ struct cvmx_asxx_rx_wol_powok_s cn38xx;
869+ struct cvmx_asxx_rx_wol_powok_s cn38xxp2;
870+};
871+
872+union cvmx_asxx_rx_wol_sig {
873+ uint64_t u64;
874+ struct cvmx_asxx_rx_wol_sig_s {
875+ uint64_t reserved_32_63:32;
876+ uint64_t sig:32;
877+ } s;
878+ struct cvmx_asxx_rx_wol_sig_s cn38xx;
879+ struct cvmx_asxx_rx_wol_sig_s cn38xxp2;
880+};
881+
882+union cvmx_asxx_tx_clk_setx {
883+ uint64_t u64;
884+ struct cvmx_asxx_tx_clk_setx_s {
885+ uint64_t reserved_5_63:59;
886+ uint64_t setting:5;
887+ } s;
888+ struct cvmx_asxx_tx_clk_setx_s cn30xx;
889+ struct cvmx_asxx_tx_clk_setx_s cn31xx;
890+ struct cvmx_asxx_tx_clk_setx_s cn38xx;
891+ struct cvmx_asxx_tx_clk_setx_s cn38xxp2;
892+ struct cvmx_asxx_tx_clk_setx_s cn50xx;
893+ struct cvmx_asxx_tx_clk_setx_s cn58xx;
894+ struct cvmx_asxx_tx_clk_setx_s cn58xxp1;
895+};
896+
897+union cvmx_asxx_tx_comp_byp {
898+ uint64_t u64;
899+ struct cvmx_asxx_tx_comp_byp_s {
900+ uint64_t reserved_0_63:64;
901+ } s;
902+ struct cvmx_asxx_tx_comp_byp_cn30xx {
903+ uint64_t reserved_9_63:55;
904+ uint64_t bypass:1;
905+ uint64_t pctl:4;
906+ uint64_t nctl:4;
907+ } cn30xx;
908+ struct cvmx_asxx_tx_comp_byp_cn30xx cn31xx;
909+ struct cvmx_asxx_tx_comp_byp_cn38xx {
910+ uint64_t reserved_8_63:56;
911+ uint64_t pctl:4;
912+ uint64_t nctl:4;
913+ } cn38xx;
914+ struct cvmx_asxx_tx_comp_byp_cn38xx cn38xxp2;
915+ struct cvmx_asxx_tx_comp_byp_cn50xx {
916+ uint64_t reserved_17_63:47;
917+ uint64_t bypass:1;
918+ uint64_t reserved_13_15:3;
919+ uint64_t pctl:5;
920+ uint64_t reserved_5_7:3;
921+ uint64_t nctl:5;
922+ } cn50xx;
923+ struct cvmx_asxx_tx_comp_byp_cn58xx {
924+ uint64_t reserved_13_63:51;
925+ uint64_t pctl:5;
926+ uint64_t reserved_5_7:3;
927+ uint64_t nctl:5;
928+ } cn58xx;
929+ struct cvmx_asxx_tx_comp_byp_cn58xx cn58xxp1;
930+};
931+
932+union cvmx_asxx_tx_hi_waterx {
933+ uint64_t u64;
934+ struct cvmx_asxx_tx_hi_waterx_s {
935+ uint64_t reserved_4_63:60;
936+ uint64_t mark:4;
937+ } s;
938+ struct cvmx_asxx_tx_hi_waterx_cn30xx {
939+ uint64_t reserved_3_63:61;
940+ uint64_t mark:3;
941+ } cn30xx;
942+ struct cvmx_asxx_tx_hi_waterx_cn30xx cn31xx;
943+ struct cvmx_asxx_tx_hi_waterx_s cn38xx;
944+ struct cvmx_asxx_tx_hi_waterx_s cn38xxp2;
945+ struct cvmx_asxx_tx_hi_waterx_cn30xx cn50xx;
946+ struct cvmx_asxx_tx_hi_waterx_s cn58xx;
947+ struct cvmx_asxx_tx_hi_waterx_s cn58xxp1;
948+};
949+
950+union cvmx_asxx_tx_prt_en {
951+ uint64_t u64;
952+ struct cvmx_asxx_tx_prt_en_s {
953+ uint64_t reserved_4_63:60;
954+ uint64_t prt_en:4;
955+ } s;
956+ struct cvmx_asxx_tx_prt_en_cn30xx {
957+ uint64_t reserved_3_63:61;
958+ uint64_t prt_en:3;
959+ } cn30xx;
960+ struct cvmx_asxx_tx_prt_en_cn30xx cn31xx;
961+ struct cvmx_asxx_tx_prt_en_s cn38xx;
962+ struct cvmx_asxx_tx_prt_en_s cn38xxp2;
963+ struct cvmx_asxx_tx_prt_en_cn30xx cn50xx;
964+ struct cvmx_asxx_tx_prt_en_s cn58xx;
965+ struct cvmx_asxx_tx_prt_en_s cn58xxp1;
966+};
967+
968+#endif
969--- /dev/null
970+++ b/drivers/staging/octeon/cvmx-cmd-queue.c
971@@ -0,0 +1,306 @@
972+/***********************license start***************
973+ * Author: Cavium Networks
974+ *
975+ * Contact: support@caviumnetworks.com
976+ * This file is part of the OCTEON SDK
977+ *
978+ * Copyright (c) 2003-2008 Cavium Networks
979+ *
980+ * This file is free software; you can redistribute it and/or modify
981+ * it under the terms of the GNU General Public License, Version 2, as
982+ * published by the Free Software Foundation.
983+ *
984+ * This file is distributed in the hope that it will be useful, but
985+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
986+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
987+ * NONINFRINGEMENT. See the GNU General Public License for more
988+ * details.
989+ *
990+ * You should have received a copy of the GNU General Public License
991+ * along with this file; if not, write to the Free Software
992+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
993+ * or visit http://www.gnu.org/licenses/.
994+ *
995+ * This file may also be available under a different license from Cavium.
996+ * Contact Cavium Networks for more information
997+ ***********************license end**************************************/
998+
999+/*
1000+ * Support functions for managing command queues used for
1001+ * various hardware blocks.
1002+ */
1003+
1004+#include <linux/kernel.h>
1005+
1006+#include <asm/octeon/octeon.h>
1007+
1008+#include "cvmx-config.h"
1009+#include "cvmx-fpa.h"
1010+#include "cvmx-cmd-queue.h"
1011+
1012+#include <asm/octeon/cvmx-npei-defs.h>
1013+#include <asm/octeon/cvmx-pexp-defs.h>
1014+#include "cvmx-pko-defs.h"
1015+
1016+/**
1017+ * This application uses this pointer to access the global queue
1018+ * state. It points to a bootmem named block.
1019+ */
1020+__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr;
1021+
1022+/**
1023+ * Initialize the Global queue state pointer.
1024+ *
1025+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1026+ */
1027+static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void)
1028+{
1029+ char *alloc_name = "cvmx_cmd_queues";
1030+#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
1031+ extern uint64_t octeon_reserve32_memory;
1032+#endif
1033+
1034+ if (likely(__cvmx_cmd_queue_state_ptr))
1035+ return CVMX_CMD_QUEUE_SUCCESS;
1036+
1037+#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
1038+ if (octeon_reserve32_memory)
1039+ __cvmx_cmd_queue_state_ptr =
1040+ cvmx_bootmem_alloc_named_range(sizeof(*__cvmx_cmd_queue_state_ptr),
1041+ octeon_reserve32_memory,
1042+ octeon_reserve32_memory +
1043+ (CONFIG_CAVIUM_RESERVE32 <<
1044+ 20) - 1, 128, alloc_name);
1045+ else
1046+#endif
1047+ __cvmx_cmd_queue_state_ptr =
1048+ cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr),
1049+ 128,
1050+ alloc_name);
1051+ if (__cvmx_cmd_queue_state_ptr)
1052+ memset(__cvmx_cmd_queue_state_ptr, 0,
1053+ sizeof(*__cvmx_cmd_queue_state_ptr));
1054+ else {
1055+ struct cvmx_bootmem_named_block_desc *block_desc =
1056+ cvmx_bootmem_find_named_block(alloc_name);
1057+ if (block_desc)
1058+ __cvmx_cmd_queue_state_ptr =
1059+ cvmx_phys_to_ptr(block_desc->base_addr);
1060+ else {
1061+ cvmx_dprintf
1062+ ("ERROR: cvmx_cmd_queue_initialize: Unable to get named block %s.\n",
1063+ alloc_name);
1064+ return CVMX_CMD_QUEUE_NO_MEMORY;
1065+ }
1066+ }
1067+ return CVMX_CMD_QUEUE_SUCCESS;
1068+}
1069+
1070+/**
1071+ * Initialize a command queue for use. The initial FPA buffer is
1072+ * allocated and the hardware unit is configured to point to the
1073+ * new command queue.
1074+ *
1075+ * @queue_id: Hardware command queue to initialize.
1076+ * @max_depth: Maximum outstanding commands that can be queued.
1077+ * @fpa_pool: FPA pool the command queues should come from.
1078+ * @pool_size: Size of each buffer in the FPA pool (bytes)
1079+ *
1080+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1081+ */
1082+cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
1083+ int max_depth, int fpa_pool,
1084+ int pool_size)
1085+{
1086+ __cvmx_cmd_queue_state_t *qstate;
1087+ cvmx_cmd_queue_result_t result = __cvmx_cmd_queue_init_state_ptr();
1088+ if (result != CVMX_CMD_QUEUE_SUCCESS)
1089+ return result;
1090+
1091+ qstate = __cvmx_cmd_queue_get_state(queue_id);
1092+ if (qstate == NULL)
1093+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1094+
1095+ /*
1096+ * We artificially limit max_depth to 1<<20 words. It is an
1097+ * arbitrary limit.
1098+ */
1099+ if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH) {
1100+ if ((max_depth < 0) || (max_depth > 1 << 20))
1101+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1102+ } else if (max_depth != 0)
1103+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1104+
1105+ if ((fpa_pool < 0) || (fpa_pool > 7))
1106+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1107+ if ((pool_size < 128) || (pool_size > 65536))
1108+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1109+
1110+ /* See if someone else has already initialized the queue */
1111+ if (qstate->base_ptr_div128) {
1112+ if (max_depth != (int)qstate->max_depth) {
1113+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1114+ "Queue already initalized with different "
1115+ "max_depth (%d).\n",
1116+ (int)qstate->max_depth);
1117+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1118+ }
1119+ if (fpa_pool != qstate->fpa_pool) {
1120+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1121+ "Queue already initalized with different "
1122+ "FPA pool (%u).\n",
1123+ qstate->fpa_pool);
1124+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1125+ }
1126+ if ((pool_size >> 3) - 1 != qstate->pool_size_m1) {
1127+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1128+ "Queue already initalized with different "
1129+ "FPA pool size (%u).\n",
1130+ (qstate->pool_size_m1 + 1) << 3);
1131+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1132+ }
1133+ CVMX_SYNCWS;
1134+ return CVMX_CMD_QUEUE_ALREADY_SETUP;
1135+ } else {
1136+ union cvmx_fpa_ctl_status status;
1137+ void *buffer;
1138+
1139+ status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
1140+ if (!status.s.enb) {
1141+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1142+ "FPA is not enabled.\n");
1143+ return CVMX_CMD_QUEUE_NO_MEMORY;
1144+ }
1145+ buffer = cvmx_fpa_alloc(fpa_pool);
1146+ if (buffer == NULL) {
1147+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1148+ "Unable to allocate initial buffer.\n");
1149+ return CVMX_CMD_QUEUE_NO_MEMORY;
1150+ }
1151+
1152+ memset(qstate, 0, sizeof(*qstate));
1153+ qstate->max_depth = max_depth;
1154+ qstate->fpa_pool = fpa_pool;
1155+ qstate->pool_size_m1 = (pool_size >> 3) - 1;
1156+ qstate->base_ptr_div128 = cvmx_ptr_to_phys(buffer) / 128;
1157+ /*
1158+ * We zeroed the now serving field so we need to also
1159+ * zero the ticket.
1160+ */
1161+ __cvmx_cmd_queue_state_ptr->
1162+ ticket[__cvmx_cmd_queue_get_index(queue_id)] = 0;
1163+ CVMX_SYNCWS;
1164+ return CVMX_CMD_QUEUE_SUCCESS;
1165+ }
1166+}
1167+
1168+/**
1169+ * Shutdown a queue a free it's command buffers to the FPA. The
1170+ * hardware connected to the queue must be stopped before this
1171+ * function is called.
1172+ *
1173+ * @queue_id: Queue to shutdown
1174+ *
1175+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1176+ */
1177+cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id)
1178+{
1179+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1180+ if (qptr == NULL) {
1181+ cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Unable to "
1182+ "get queue information.\n");
1183+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1184+ }
1185+
1186+ if (cvmx_cmd_queue_length(queue_id) > 0) {
1187+ cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Queue still "
1188+ "has data in it.\n");
1189+ return CVMX_CMD_QUEUE_FULL;
1190+ }
1191+
1192+ __cvmx_cmd_queue_lock(queue_id, qptr);
1193+ if (qptr->base_ptr_div128) {
1194+ cvmx_fpa_free(cvmx_phys_to_ptr
1195+ ((uint64_t) qptr->base_ptr_div128 << 7),
1196+ qptr->fpa_pool, 0);
1197+ qptr->base_ptr_div128 = 0;
1198+ }
1199+ __cvmx_cmd_queue_unlock(qptr);
1200+
1201+ return CVMX_CMD_QUEUE_SUCCESS;
1202+}
1203+
1204+/**
1205+ * Return the number of command words pending in the queue. This
1206+ * function may be relatively slow for some hardware units.
1207+ *
1208+ * @queue_id: Hardware command queue to query
1209+ *
1210+ * Returns Number of outstanding commands
1211+ */
1212+int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id)
1213+{
1214+ if (CVMX_ENABLE_PARAMETER_CHECKING) {
1215+ if (__cvmx_cmd_queue_get_state(queue_id) == NULL)
1216+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1217+ }
1218+
1219+ /*
1220+ * The cast is here so gcc with check that all values in the
1221+ * cvmx_cmd_queue_id_t enumeration are here.
1222+ */
1223+ switch ((cvmx_cmd_queue_id_t) (queue_id & 0xff0000)) {
1224+ case CVMX_CMD_QUEUE_PKO_BASE:
1225+ /*
1226+ * FIXME: Need atomic lock on
1227+ * CVMX_PKO_REG_READ_IDX. Right now we are normally
1228+ * called with the queue lock, so that is a SLIGHT
1229+ * amount of protection.
1230+ */
1231+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue_id & 0xffff);
1232+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
1233+ union cvmx_pko_mem_debug9 debug9;
1234+ debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
1235+ return debug9.cn38xx.doorbell;
1236+ } else {
1237+ union cvmx_pko_mem_debug8 debug8;
1238+ debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
1239+ return debug8.cn58xx.doorbell;
1240+ }
1241+ case CVMX_CMD_QUEUE_ZIP:
1242+ case CVMX_CMD_QUEUE_DFA:
1243+ case CVMX_CMD_QUEUE_RAID:
1244+ /* FIXME: Implement other lengths */
1245+ return 0;
1246+ case CVMX_CMD_QUEUE_DMA_BASE:
1247+ {
1248+ union cvmx_npei_dmax_counts dmax_counts;
1249+ dmax_counts.u64 =
1250+ cvmx_read_csr(CVMX_PEXP_NPEI_DMAX_COUNTS
1251+ (queue_id & 0x7));
1252+ return dmax_counts.s.dbell;
1253+ }
1254+ case CVMX_CMD_QUEUE_END:
1255+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1256+ }
1257+ return CVMX_CMD_QUEUE_INVALID_PARAM;
1258+}
1259+
1260+/**
1261+ * Return the command buffer to be written to. The purpose of this
1262+ * function is to allow CVMX routine access t othe low level buffer
1263+ * for initial hardware setup. User applications should not call this
1264+ * function directly.
1265+ *
1266+ * @queue_id: Command queue to query
1267+ *
1268+ * Returns Command buffer or NULL on failure
1269+ */
1270+void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id)
1271+{
1272+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1273+ if (qptr && qptr->base_ptr_div128)
1274+ return cvmx_phys_to_ptr((uint64_t) qptr->base_ptr_div128 << 7);
1275+ else
1276+ return NULL;
1277+}
1278--- /dev/null
1279+++ b/drivers/staging/octeon/cvmx-cmd-queue.h
1280@@ -0,0 +1,617 @@
1281+/***********************license start***************
1282+ * Author: Cavium Networks
1283+ *
1284+ * Contact: support@caviumnetworks.com
1285+ * This file is part of the OCTEON SDK
1286+ *
1287+ * Copyright (c) 2003-2008 Cavium Networks
1288+ *
1289+ * This file is free software; you can redistribute it and/or modify
1290+ * it under the terms of the GNU General Public License, Version 2, as
1291+ * published by the Free Software Foundation.
1292+ *
1293+ * This file is distributed in the hope that it will be useful, but
1294+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
1295+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
1296+ * NONINFRINGEMENT. See the GNU General Public License for more
1297+ * details.
1298+ *
1299+ * You should have received a copy of the GNU General Public License
1300+ * along with this file; if not, write to the Free Software
1301+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1302+ * or visit http://www.gnu.org/licenses/.
1303+ *
1304+ * This file may also be available under a different license from Cavium.
1305+ * Contact Cavium Networks for more information
1306+ ***********************license end**************************************/
1307+
1308+/*
1309+ *
1310+ * Support functions for managing command queues used for
1311+ * various hardware blocks.
1312+ *
1313+ * The common command queue infrastructure abstracts out the
1314+ * software necessary for adding to Octeon's chained queue
1315+ * structures. These structures are used for commands to the
1316+ * PKO, ZIP, DFA, RAID, and DMA engine blocks. Although each
1317+ * hardware unit takes commands and CSRs of different types,
1318+ * they all use basic linked command buffers to store the
1319+ * pending request. In general, users of the CVMX API don't
1320+ * call cvmx-cmd-queue functions directly. Instead the hardware
1321+ * unit specific wrapper should be used. The wrappers perform
1322+ * unit specific validation and CSR writes to submit the
1323+ * commands.
1324+ *
1325+ * Even though most software will never directly interact with
1326+ * cvmx-cmd-queue, knowledge of its internal working can help
1327+ * in diagnosing performance problems and help with debugging.
1328+ *
1329+ * Command queue pointers are stored in a global named block
1330+ * called "cvmx_cmd_queues". Except for the PKO queues, each
1331+ * hardware queue is stored in its own cache line to reduce SMP
1332+ * contention on spin locks. The PKO queues are stored such that
1333+ * every 16th queue is next to each other in memory. This scheme
1334+ * allows for queues being in separate cache lines when there
1335+ * are low number of queues per port. With 16 queues per port,
1336+ * the first queue for each port is in the same cache area. The
1337+ * second queues for each port are in another area, etc. This
1338+ * allows software to implement very efficient lockless PKO with
1339+ * 16 queues per port using a minimum of cache lines per core.
1340+ * All queues for a given core will be isolated in the same
1341+ * cache area.
1342+ *
1343+ * In addition to the memory pointer layout, cvmx-cmd-queue
1344+ * provides an optimized fair ll/sc locking mechanism for the
1345+ * queues. The lock uses a "ticket / now serving" model to
1346+ * maintain fair order on contended locks. In addition, it uses
1347+ * predicted locking time to limit cache contention. When a core
1348+ * know it must wait in line for a lock, it spins on the
1349+ * internal cycle counter to completely eliminate any causes of
1350+ * bus traffic.
1351+ *
1352+ */
1353+
1354+#ifndef __CVMX_CMD_QUEUE_H__
1355+#define __CVMX_CMD_QUEUE_H__
1356+
1357+#include <linux/prefetch.h>
1358+
1359+#include "cvmx-fpa.h"
1360+/**
1361+ * By default we disable the max depth support. Most programs
1362+ * don't use it and it slows down the command queue processing
1363+ * significantly.
1364+ */
1365+#ifndef CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH
1366+#define CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH 0
1367+#endif
1368+
1369+/**
1370+ * Enumeration representing all hardware blocks that use command
1371+ * queues. Each hardware block has up to 65536 sub identifiers for
1372+ * multiple command queues. Not all chips support all hardware
1373+ * units.
1374+ */
1375+typedef enum {
1376+ CVMX_CMD_QUEUE_PKO_BASE = 0x00000,
1377+
1378+#define CVMX_CMD_QUEUE_PKO(queue) \
1379+ ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_PKO_BASE + (0xffff&(queue))))
1380+
1381+ CVMX_CMD_QUEUE_ZIP = 0x10000,
1382+ CVMX_CMD_QUEUE_DFA = 0x20000,
1383+ CVMX_CMD_QUEUE_RAID = 0x30000,
1384+ CVMX_CMD_QUEUE_DMA_BASE = 0x40000,
1385+
1386+#define CVMX_CMD_QUEUE_DMA(queue) \
1387+ ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_DMA_BASE + (0xffff&(queue))))
1388+
1389+ CVMX_CMD_QUEUE_END = 0x50000,
1390+} cvmx_cmd_queue_id_t;
1391+
1392+/**
1393+ * Command write operations can fail if the comamnd queue needs
1394+ * a new buffer and the associated FPA pool is empty. It can also
1395+ * fail if the number of queued command words reaches the maximum
1396+ * set at initialization.
1397+ */
1398+typedef enum {
1399+ CVMX_CMD_QUEUE_SUCCESS = 0,
1400+ CVMX_CMD_QUEUE_NO_MEMORY = -1,
1401+ CVMX_CMD_QUEUE_FULL = -2,
1402+ CVMX_CMD_QUEUE_INVALID_PARAM = -3,
1403+ CVMX_CMD_QUEUE_ALREADY_SETUP = -4,
1404+} cvmx_cmd_queue_result_t;
1405+
1406+typedef struct {
1407+ /* You have lock when this is your ticket */
1408+ uint8_t now_serving;
1409+ uint64_t unused1:24;
1410+ /* Maximum outstanding command words */
1411+ uint32_t max_depth;
1412+ /* FPA pool buffers come from */
1413+ uint64_t fpa_pool:3;
1414+ /* Top of command buffer pointer shifted 7 */
1415+ uint64_t base_ptr_div128:29;
1416+ uint64_t unused2:6;
1417+ /* FPA buffer size in 64bit words minus 1 */
1418+ uint64_t pool_size_m1:13;
1419+ /* Number of comamnds already used in buffer */
1420+ uint64_t index:13;
1421+} __cvmx_cmd_queue_state_t;
1422+
1423+/**
1424+ * This structure contains the global state of all comamnd queues.
1425+ * It is stored in a bootmem named block and shared by all
1426+ * applications running on Octeon. Tickets are stored in a differnet
1427+ * cahce line that queue information to reduce the contention on the
1428+ * ll/sc used to get a ticket. If this is not the case, the update
1429+ * of queue state causes the ll/sc to fail quite often.
1430+ */
1431+typedef struct {
1432+ uint64_t ticket[(CVMX_CMD_QUEUE_END >> 16) * 256];
1433+ __cvmx_cmd_queue_state_t state[(CVMX_CMD_QUEUE_END >> 16) * 256];
1434+} __cvmx_cmd_queue_all_state_t;
1435+
1436+/**
1437+ * Initialize a command queue for use. The initial FPA buffer is
1438+ * allocated and the hardware unit is configured to point to the
1439+ * new command queue.
1440+ *
1441+ * @queue_id: Hardware command queue to initialize.
1442+ * @max_depth: Maximum outstanding commands that can be queued.
1443+ * @fpa_pool: FPA pool the command queues should come from.
1444+ * @pool_size: Size of each buffer in the FPA pool (bytes)
1445+ *
1446+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1447+ */
1448+cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
1449+ int max_depth, int fpa_pool,
1450+ int pool_size);
1451+
1452+/**
1453+ * Shutdown a queue a free it's command buffers to the FPA. The
1454+ * hardware connected to the queue must be stopped before this
1455+ * function is called.
1456+ *
1457+ * @queue_id: Queue to shutdown
1458+ *
1459+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1460+ */
1461+cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id);
1462+
1463+/**
1464+ * Return the number of command words pending in the queue. This
1465+ * function may be relatively slow for some hardware units.
1466+ *
1467+ * @queue_id: Hardware command queue to query
1468+ *
1469+ * Returns Number of outstanding commands
1470+ */
1471+int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id);
1472+
1473+/**
1474+ * Return the command buffer to be written to. The purpose of this
1475+ * function is to allow CVMX routine access t othe low level buffer
1476+ * for initial hardware setup. User applications should not call this
1477+ * function directly.
1478+ *
1479+ * @queue_id: Command queue to query
1480+ *
1481+ * Returns Command buffer or NULL on failure
1482+ */
1483+void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id);
1484+
1485+/**
1486+ * Get the index into the state arrays for the supplied queue id.
1487+ *
1488+ * @queue_id: Queue ID to get an index for
1489+ *
1490+ * Returns Index into the state arrays
1491+ */
1492+static inline int __cvmx_cmd_queue_get_index(cvmx_cmd_queue_id_t queue_id)
1493+{
1494+ /*
1495+ * Warning: This code currently only works with devices that
1496+ * have 256 queues or less. Devices with more than 16 queues
1497+ * are layed out in memory to allow cores quick access to
1498+ * every 16th queue. This reduces cache thrashing when you are
1499+ * running 16 queues per port to support lockless operation.
1500+ */
1501+ int unit = queue_id >> 16;
1502+ int q = (queue_id >> 4) & 0xf;
1503+ int core = queue_id & 0xf;
1504+ return unit * 256 + core * 16 + q;
1505+}
1506+
1507+/**
1508+ * Lock the supplied queue so nobody else is updating it at the same
1509+ * time as us.
1510+ *
1511+ * @queue_id: Queue ID to lock
1512+ * @qptr: Pointer to the queue's global state
1513+ */
1514+static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id,
1515+ __cvmx_cmd_queue_state_t *qptr)
1516+{
1517+ extern __cvmx_cmd_queue_all_state_t
1518+ *__cvmx_cmd_queue_state_ptr;
1519+ int tmp;
1520+ int my_ticket;
1521+ prefetch(qptr);
1522+ asm volatile (
1523+ ".set push\n"
1524+ ".set noreorder\n"
1525+ "1:\n"
1526+ /* Atomic add one to ticket_ptr */
1527+ "ll %[my_ticket], %[ticket_ptr]\n"
1528+ /* and store the original value */
1529+ "li %[ticket], 1\n"
1530+ /* in my_ticket */
1531+ "baddu %[ticket], %[my_ticket]\n"
1532+ "sc %[ticket], %[ticket_ptr]\n"
1533+ "beqz %[ticket], 1b\n"
1534+ " nop\n"
1535+ /* Load the current now_serving ticket */
1536+ "lbu %[ticket], %[now_serving]\n"
1537+ "2:\n"
1538+ /* Jump out if now_serving == my_ticket */
1539+ "beq %[ticket], %[my_ticket], 4f\n"
1540+ /* Find out how many tickets are in front of me */
1541+ " subu %[ticket], %[my_ticket], %[ticket]\n"
1542+ /* Use tickets in front of me minus one to delay */
1543+ "subu %[ticket], 1\n"
1544+ /* Delay will be ((tickets in front)-1)*32 loops */
1545+ "cins %[ticket], %[ticket], 5, 7\n"
1546+ "3:\n"
1547+ /* Loop here until our ticket might be up */
1548+ "bnez %[ticket], 3b\n"
1549+ " subu %[ticket], 1\n"
1550+ /* Jump back up to check out ticket again */
1551+ "b 2b\n"
1552+ /* Load the current now_serving ticket */
1553+ " lbu %[ticket], %[now_serving]\n"
1554+ "4:\n"
1555+ ".set pop\n" :
1556+ [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]),
1557+ [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp),
1558+ [my_ticket] "=r"(my_ticket)
1559+ );
1560+}
1561+
1562+/**
1563+ * Unlock the queue, flushing all writes.
1564+ *
1565+ * @qptr: Queue to unlock
1566+ */
1567+static inline void __cvmx_cmd_queue_unlock(__cvmx_cmd_queue_state_t *qptr)
1568+{
1569+ qptr->now_serving++;
1570+ CVMX_SYNCWS;
1571+}
1572+
1573+/**
1574+ * Get the queue state structure for the given queue id
1575+ *
1576+ * @queue_id: Queue id to get
1577+ *
1578+ * Returns Queue structure or NULL on failure
1579+ */
1580+static inline __cvmx_cmd_queue_state_t
1581+ *__cvmx_cmd_queue_get_state(cvmx_cmd_queue_id_t queue_id)
1582+{
1583+ extern __cvmx_cmd_queue_all_state_t
1584+ *__cvmx_cmd_queue_state_ptr;
1585+ return &__cvmx_cmd_queue_state_ptr->
1586+ state[__cvmx_cmd_queue_get_index(queue_id)];
1587+}
1588+
1589+/**
1590+ * Write an arbitrary number of command words to a command queue.
1591+ * This is a generic function; the fixed number of comamnd word
1592+ * functions yield higher performance.
1593+ *
1594+ * @queue_id: Hardware command queue to write to
1595+ * @use_locking:
1596+ * Use internal locking to ensure exclusive access for queue
1597+ * updates. If you don't use this locking you must ensure
1598+ * exclusivity some other way. Locking is strongly recommended.
1599+ * @cmd_count: Number of command words to write
1600+ * @cmds: Array of comamnds to write
1601+ *
1602+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1603+ */
1604+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write(cvmx_cmd_queue_id_t
1605+ queue_id,
1606+ int use_locking,
1607+ int cmd_count,
1608+ uint64_t *cmds)
1609+{
1610+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1611+
1612+ /* Make sure nobody else is updating the same queue */
1613+ if (likely(use_locking))
1614+ __cvmx_cmd_queue_lock(queue_id, qptr);
1615+
1616+ /*
1617+ * If a max queue length was specified then make sure we don't
1618+ * exceed it. If any part of the command would be below the
1619+ * limit we allow it.
1620+ */
1621+ if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1622+ if (unlikely
1623+ (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1624+ if (likely(use_locking))
1625+ __cvmx_cmd_queue_unlock(qptr);
1626+ return CVMX_CMD_QUEUE_FULL;
1627+ }
1628+ }
1629+
1630+ /*
1631+ * Normally there is plenty of room in the current buffer for
1632+ * the command.
1633+ */
1634+ if (likely(qptr->index + cmd_count < qptr->pool_size_m1)) {
1635+ uint64_t *ptr =
1636+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1637+ base_ptr_div128 << 7);
1638+ ptr += qptr->index;
1639+ qptr->index += cmd_count;
1640+ while (cmd_count--)
1641+ *ptr++ = *cmds++;
1642+ } else {
1643+ uint64_t *ptr;
1644+ int count;
1645+ /*
1646+ * We need a new comamnd buffer. Fail if there isn't
1647+ * one available.
1648+ */
1649+ uint64_t *new_buffer =
1650+ (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1651+ if (unlikely(new_buffer == NULL)) {
1652+ if (likely(use_locking))
1653+ __cvmx_cmd_queue_unlock(qptr);
1654+ return CVMX_CMD_QUEUE_NO_MEMORY;
1655+ }
1656+ ptr =
1657+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1658+ base_ptr_div128 << 7);
1659+ /*
1660+ * Figure out how many command words will fit in this
1661+ * buffer. One location will be needed for the next
1662+ * buffer pointer.
1663+ */
1664+ count = qptr->pool_size_m1 - qptr->index;
1665+ ptr += qptr->index;
1666+ cmd_count -= count;
1667+ while (count--)
1668+ *ptr++ = *cmds++;
1669+ *ptr = cvmx_ptr_to_phys(new_buffer);
1670+ /*
1671+ * The current buffer is full and has a link to the
1672+ * next buffer. Time to write the rest of the commands
1673+ * into the new buffer.
1674+ */
1675+ qptr->base_ptr_div128 = *ptr >> 7;
1676+ qptr->index = cmd_count;
1677+ ptr = new_buffer;
1678+ while (cmd_count--)
1679+ *ptr++ = *cmds++;
1680+ }
1681+
1682+ /* All updates are complete. Release the lock and return */
1683+ if (likely(use_locking))
1684+ __cvmx_cmd_queue_unlock(qptr);
1685+ return CVMX_CMD_QUEUE_SUCCESS;
1686+}
1687+
1688+/**
1689+ * Simple function to write two command words to a command
1690+ * queue.
1691+ *
1692+ * @queue_id: Hardware command queue to write to
1693+ * @use_locking:
1694+ * Use internal locking to ensure exclusive access for queue
1695+ * updates. If you don't use this locking you must ensure
1696+ * exclusivity some other way. Locking is strongly recommended.
1697+ * @cmd1: Command
1698+ * @cmd2: Command
1699+ *
1700+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1701+ */
1702+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write2(cvmx_cmd_queue_id_t
1703+ queue_id,
1704+ int use_locking,
1705+ uint64_t cmd1,
1706+ uint64_t cmd2)
1707+{
1708+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1709+
1710+ /* Make sure nobody else is updating the same queue */
1711+ if (likely(use_locking))
1712+ __cvmx_cmd_queue_lock(queue_id, qptr);
1713+
1714+ /*
1715+ * If a max queue length was specified then make sure we don't
1716+ * exceed it. If any part of the command would be below the
1717+ * limit we allow it.
1718+ */
1719+ if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1720+ if (unlikely
1721+ (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1722+ if (likely(use_locking))
1723+ __cvmx_cmd_queue_unlock(qptr);
1724+ return CVMX_CMD_QUEUE_FULL;
1725+ }
1726+ }
1727+
1728+ /*
1729+ * Normally there is plenty of room in the current buffer for
1730+ * the command.
1731+ */
1732+ if (likely(qptr->index + 2 < qptr->pool_size_m1)) {
1733+ uint64_t *ptr =
1734+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1735+ base_ptr_div128 << 7);
1736+ ptr += qptr->index;
1737+ qptr->index += 2;
1738+ ptr[0] = cmd1;
1739+ ptr[1] = cmd2;
1740+ } else {
1741+ uint64_t *ptr;
1742+ /*
1743+ * Figure out how many command words will fit in this
1744+ * buffer. One location will be needed for the next
1745+ * buffer pointer.
1746+ */
1747+ int count = qptr->pool_size_m1 - qptr->index;
1748+ /*
1749+ * We need a new comamnd buffer. Fail if there isn't
1750+ * one available.
1751+ */
1752+ uint64_t *new_buffer =
1753+ (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1754+ if (unlikely(new_buffer == NULL)) {
1755+ if (likely(use_locking))
1756+ __cvmx_cmd_queue_unlock(qptr);
1757+ return CVMX_CMD_QUEUE_NO_MEMORY;
1758+ }
1759+ count--;
1760+ ptr =
1761+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1762+ base_ptr_div128 << 7);
1763+ ptr += qptr->index;
1764+ *ptr++ = cmd1;
1765+ if (likely(count))
1766+ *ptr++ = cmd2;
1767+ *ptr = cvmx_ptr_to_phys(new_buffer);
1768+ /*
1769+ * The current buffer is full and has a link to the
1770+ * next buffer. Time to write the rest of the commands
1771+ * into the new buffer.
1772+ */
1773+ qptr->base_ptr_div128 = *ptr >> 7;
1774+ qptr->index = 0;
1775+ if (unlikely(count == 0)) {
1776+ qptr->index = 1;
1777+ new_buffer[0] = cmd2;
1778+ }
1779+ }
1780+
1781+ /* All updates are complete. Release the lock and return */
1782+ if (likely(use_locking))
1783+ __cvmx_cmd_queue_unlock(qptr);
1784+ return CVMX_CMD_QUEUE_SUCCESS;
1785+}
1786+
1787+/**
1788+ * Simple function to write three command words to a command
1789+ * queue.
1790+ *
1791+ * @queue_id: Hardware command queue to write to
1792+ * @use_locking:
1793+ * Use internal locking to ensure exclusive access for queue
1794+ * updates. If you don't use this locking you must ensure
1795+ * exclusivity some other way. Locking is strongly recommended.
1796+ * @cmd1: Command
1797+ * @cmd2: Command
1798+ * @cmd3: Command
1799+ *
1800+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1801+ */
1802+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write3(cvmx_cmd_queue_id_t
1803+ queue_id,
1804+ int use_locking,
1805+ uint64_t cmd1,
1806+ uint64_t cmd2,
1807+ uint64_t cmd3)
1808+{
1809+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1810+
1811+ /* Make sure nobody else is updating the same queue */
1812+ if (likely(use_locking))
1813+ __cvmx_cmd_queue_lock(queue_id, qptr);
1814+
1815+ /*
1816+ * If a max queue length was specified then make sure we don't
1817+ * exceed it. If any part of the command would be below the
1818+ * limit we allow it.
1819+ */
1820+ if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1821+ if (unlikely
1822+ (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1823+ if (likely(use_locking))
1824+ __cvmx_cmd_queue_unlock(qptr);
1825+ return CVMX_CMD_QUEUE_FULL;
1826+ }
1827+ }
1828+
1829+ /*
1830+ * Normally there is plenty of room in the current buffer for
1831+ * the command.
1832+ */
1833+ if (likely(qptr->index + 3 < qptr->pool_size_m1)) {
1834+ uint64_t *ptr =
1835+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1836+ base_ptr_div128 << 7);
1837+ ptr += qptr->index;
1838+ qptr->index += 3;
1839+ ptr[0] = cmd1;
1840+ ptr[1] = cmd2;
1841+ ptr[2] = cmd3;
1842+ } else {
1843+ uint64_t *ptr;
1844+ /*
1845+ * Figure out how many command words will fit in this
1846+ * buffer. One location will be needed for the next
1847+ * buffer pointer
1848+ */
1849+ int count = qptr->pool_size_m1 - qptr->index;
1850+ /*
1851+ * We need a new comamnd buffer. Fail if there isn't
1852+ * one available
1853+ */
1854+ uint64_t *new_buffer =
1855+ (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1856+ if (unlikely(new_buffer == NULL)) {
1857+ if (likely(use_locking))
1858+ __cvmx_cmd_queue_unlock(qptr);
1859+ return CVMX_CMD_QUEUE_NO_MEMORY;
1860+ }
1861+ count--;
1862+ ptr =
1863+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1864+ base_ptr_div128 << 7);
1865+ ptr += qptr->index;
1866+ *ptr++ = cmd1;
1867+ if (count) {
1868+ *ptr++ = cmd2;
1869+ if (count > 1)
1870+ *ptr++ = cmd3;
1871+ }
1872+ *ptr = cvmx_ptr_to_phys(new_buffer);
1873+ /*
1874+ * The current buffer is full and has a link to the
1875+ * next buffer. Time to write the rest of the commands
1876+ * into the new buffer.
1877+ */
1878+ qptr->base_ptr_div128 = *ptr >> 7;
1879+ qptr->index = 0;
1880+ ptr = new_buffer;
1881+ if (count == 0) {
1882+ *ptr++ = cmd2;
1883+ qptr->index++;
1884+ }
1885+ if (count < 2) {
1886+ *ptr++ = cmd3;
1887+ qptr->index++;
1888+ }
1889+ }
1890+
1891+ /* All updates are complete. Release the lock and return */
1892+ if (likely(use_locking))
1893+ __cvmx_cmd_queue_unlock(qptr);
1894+ return CVMX_CMD_QUEUE_SUCCESS;
1895+}
1896+
1897+#endif /* __CVMX_CMD_QUEUE_H__ */
1898--- /dev/null
1899+++ b/drivers/staging/octeon/cvmx-config.h
1900@@ -0,0 +1,169 @@
1901+#ifndef __CVMX_CONFIG_H__
1902+#define __CVMX_CONFIG_H__
1903+
1904+/************************* Config Specific Defines ************************/
1905+#define CVMX_LLM_NUM_PORTS 1
1906+#define CVMX_NULL_POINTER_PROTECT 1
1907+#define CVMX_ENABLE_DEBUG_PRINTS 1
1908+/* PKO queues per port for interface 0 (ports 0-15) */
1909+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 1
1910+/* PKO queues per port for interface 1 (ports 16-31) */
1911+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 1
1912+/* Limit on the number of PKO ports enabled for interface 0 */
1913+#define CVMX_PKO_MAX_PORTS_INTERFACE0 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
1914+/* Limit on the number of PKO ports enabled for interface 1 */
1915+#define CVMX_PKO_MAX_PORTS_INTERFACE1 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
1916+/* PKO queues per port for PCI (ports 32-35) */
1917+#define CVMX_PKO_QUEUES_PER_PORT_PCI 1
1918+/* PKO queues per port for Loop devices (ports 36-39) */
1919+#define CVMX_PKO_QUEUES_PER_PORT_LOOP 1
1920+
1921+/************************* FPA allocation *********************************/
1922+/* Pool sizes in bytes, must be multiple of a cache line */
1923+#define CVMX_FPA_POOL_0_SIZE (16 * CVMX_CACHE_LINE_SIZE)
1924+#define CVMX_FPA_POOL_1_SIZE (1 * CVMX_CACHE_LINE_SIZE)
1925+#define CVMX_FPA_POOL_2_SIZE (8 * CVMX_CACHE_LINE_SIZE)
1926+#define CVMX_FPA_POOL_3_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1927+#define CVMX_FPA_POOL_4_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1928+#define CVMX_FPA_POOL_5_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1929+#define CVMX_FPA_POOL_6_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1930+#define CVMX_FPA_POOL_7_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1931+
1932+/* Pools in use */
1933+/* Packet buffers */
1934+#define CVMX_FPA_PACKET_POOL (0)
1935+#define CVMX_FPA_PACKET_POOL_SIZE CVMX_FPA_POOL_0_SIZE
1936+/* Work queue entrys */
1937+#define CVMX_FPA_WQE_POOL (1)
1938+#define CVMX_FPA_WQE_POOL_SIZE CVMX_FPA_POOL_1_SIZE
1939+/* PKO queue command buffers */
1940+#define CVMX_FPA_OUTPUT_BUFFER_POOL (2)
1941+#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE CVMX_FPA_POOL_2_SIZE
1942+
1943+/************************* FAU allocation ********************************/
1944+/* The fetch and add registers are allocated here. They are arranged
1945+ * in order of descending size so that all alignment constraints are
1946+ * automatically met. The enums are linked so that the following enum
1947+ * continues allocating where the previous one left off, so the
1948+ * numbering within each enum always starts with zero. The macros
1949+ * take care of the address increment size, so the values entered
1950+ * always increase by 1. FAU registers are accessed with byte
1951+ * addresses.
1952+ */
1953+
1954+#define CVMX_FAU_REG_64_ADDR(x) ((x << 3) + CVMX_FAU_REG_64_START)
1955+typedef enum {
1956+ CVMX_FAU_REG_64_START = 0,
1957+ CVMX_FAU_REG_64_END = CVMX_FAU_REG_64_ADDR(0),
1958+} cvmx_fau_reg_64_t;
1959+
1960+#define CVMX_FAU_REG_32_ADDR(x) ((x << 2) + CVMX_FAU_REG_32_START)
1961+typedef enum {
1962+ CVMX_FAU_REG_32_START = CVMX_FAU_REG_64_END,
1963+ CVMX_FAU_REG_32_END = CVMX_FAU_REG_32_ADDR(0),
1964+} cvmx_fau_reg_32_t;
1965+
1966+#define CVMX_FAU_REG_16_ADDR(x) ((x << 1) + CVMX_FAU_REG_16_START)
1967+typedef enum {
1968+ CVMX_FAU_REG_16_START = CVMX_FAU_REG_32_END,
1969+ CVMX_FAU_REG_16_END = CVMX_FAU_REG_16_ADDR(0),
1970+} cvmx_fau_reg_16_t;
1971+
1972+#define CVMX_FAU_REG_8_ADDR(x) ((x) + CVMX_FAU_REG_8_START)
1973+typedef enum {
1974+ CVMX_FAU_REG_8_START = CVMX_FAU_REG_16_END,
1975+ CVMX_FAU_REG_8_END = CVMX_FAU_REG_8_ADDR(0),
1976+} cvmx_fau_reg_8_t;
1977+
1978+/*
1979+ * The name CVMX_FAU_REG_AVAIL_BASE is provided to indicate the first
1980+ * available FAU address that is not allocated in cvmx-config.h. This
1981+ * is 64 bit aligned.
1982+ */
1983+#define CVMX_FAU_REG_AVAIL_BASE ((CVMX_FAU_REG_8_END + 0x7) & (~0x7ULL))
1984+#define CVMX_FAU_REG_END (2048)
1985+
1986+/********************** scratch memory allocation *************************/
1987+/* Scratchpad memory allocation. Note that these are byte memory
1988+ * addresses. Some uses of scratchpad (IOBDMA for example) require
1989+ * the use of 8-byte aligned addresses, so proper alignment needs to
1990+ * be taken into account.
1991+ */
1992+/* Generic scratch iobdma area */
1993+#define CVMX_SCR_SCRATCH (0)
1994+/* First location available after cvmx-config.h allocated region. */
1995+#define CVMX_SCR_REG_AVAIL_BASE (8)
1996+
1997+/*
1998+ * CVMX_HELPER_FIRST_MBUFF_SKIP is the number of bytes to reserve
1999+ * before the beginning of the packet. If necessary, override the
2000+ * default here. See the IPD section of the hardware manual for MBUFF
2001+ * SKIP details.
2002+ */
2003+#define CVMX_HELPER_FIRST_MBUFF_SKIP 184
2004+
2005+/*
2006+ * CVMX_HELPER_NOT_FIRST_MBUFF_SKIP is the number of bytes to reserve
2007+ * in each chained packet element. If necessary, override the default
2008+ * here.
2009+ */
2010+#define CVMX_HELPER_NOT_FIRST_MBUFF_SKIP 0
2011+
2012+/*
2013+ * CVMX_HELPER_ENABLE_BACK_PRESSURE controls whether back pressure is
2014+ * enabled for all input ports. This controls if IPD sends
2015+ * backpressure to all ports if Octeon's FPA pools don't have enough
2016+ * packet or work queue entries. Even when this is off, it is still
2017+ * possible to get backpressure from individual hardware ports. When
2018+ * configuring backpressure, also check
2019+ * CVMX_HELPER_DISABLE_*_BACKPRESSURE below. If necessary, override
2020+ * the default here.
2021+ */
2022+#define CVMX_HELPER_ENABLE_BACK_PRESSURE 1
2023+
2024+/*
2025+ * CVMX_HELPER_ENABLE_IPD controls if the IPD is enabled in the helper
2026+ * function. Once it is enabled the hardware starts accepting
2027+ * packets. You might want to skip the IPD enable if configuration
2028+ * changes are need from the default helper setup. If necessary,
2029+ * override the default here.
2030+ */
2031+#define CVMX_HELPER_ENABLE_IPD 0
2032+
2033+/*
2034+ * CVMX_HELPER_INPUT_TAG_TYPE selects the type of tag that the IPD assigns
2035+ * to incoming packets.
2036+ */
2037+#define CVMX_HELPER_INPUT_TAG_TYPE CVMX_POW_TAG_TYPE_ORDERED
2038+
2039+#define CVMX_ENABLE_PARAMETER_CHECKING 0
2040+
2041+/*
2042+ * The following select which fields are used by the PIP to generate
2043+ * the tag on INPUT
2044+ * 0: don't include
2045+ * 1: include
2046+ */
2047+#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP 0
2048+#define CVMX_HELPER_INPUT_TAG_IPV6_DST_IP 0
2049+#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT 0
2050+#define CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT 0
2051+#define CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER 0
2052+#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP 0
2053+#define CVMX_HELPER_INPUT_TAG_IPV4_DST_IP 0
2054+#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT 0
2055+#define CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT 0
2056+#define CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL 0
2057+#define CVMX_HELPER_INPUT_TAG_INPUT_PORT 1
2058+
2059+/* Select skip mode for input ports */
2060+#define CVMX_HELPER_INPUT_PORT_SKIP_MODE CVMX_PIP_PORT_CFG_MODE_SKIPL2
2061+
2062+/*
2063+ * Force backpressure to be disabled. This overrides all other
2064+ * backpressure configuration.
2065+ */
2066+#define CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 0
2067+
2068+#endif /* __CVMX_CONFIG_H__ */
2069+
2070--- /dev/null
2071+++ b/drivers/staging/octeon/cvmx-dbg-defs.h
2072@@ -0,0 +1,72 @@
2073+/***********************license start***************
2074+ * Author: Cavium Networks
2075+ *
2076+ * Contact: support@caviumnetworks.com
2077+ * This file is part of the OCTEON SDK
2078+ *
2079+ * Copyright (c) 2003-2008 Cavium Networks
2080+ *
2081+ * This file is free software; you can redistribute it and/or modify
2082+ * it under the terms of the GNU General Public License, Version 2, as
2083+ * published by the Free Software Foundation.
2084+ *
2085+ * This file is distributed in the hope that it will be useful, but
2086+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2087+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2088+ * NONINFRINGEMENT. See the GNU General Public License for more
2089+ * details.
2090+ *
2091+ * You should have received a copy of the GNU General Public License
2092+ * along with this file; if not, write to the Free Software
2093+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2094+ * or visit http://www.gnu.org/licenses/.
2095+ *
2096+ * This file may also be available under a different license from Cavium.
2097+ * Contact Cavium Networks for more information
2098+ ***********************license end**************************************/
2099+
2100+#ifndef __CVMX_DBG_DEFS_H__
2101+#define __CVMX_DBG_DEFS_H__
2102+
2103+#define CVMX_DBG_DATA \
2104+ CVMX_ADD_IO_SEG(0x00011F00000001E8ull)
2105+
2106+union cvmx_dbg_data {
2107+ uint64_t u64;
2108+ struct cvmx_dbg_data_s {
2109+ uint64_t reserved_23_63:41;
2110+ uint64_t c_mul:5;
2111+ uint64_t dsel_ext:1;
2112+ uint64_t data:17;
2113+ } s;
2114+ struct cvmx_dbg_data_cn30xx {
2115+ uint64_t reserved_31_63:33;
2116+ uint64_t pll_mul:3;
2117+ uint64_t reserved_23_27:5;
2118+ uint64_t c_mul:5;
2119+ uint64_t dsel_ext:1;
2120+ uint64_t data:17;
2121+ } cn30xx;
2122+ struct cvmx_dbg_data_cn30xx cn31xx;
2123+ struct cvmx_dbg_data_cn38xx {
2124+ uint64_t reserved_29_63:35;
2125+ uint64_t d_mul:4;
2126+ uint64_t dclk_mul2:1;
2127+ uint64_t cclk_div2:1;
2128+ uint64_t c_mul:5;
2129+ uint64_t dsel_ext:1;
2130+ uint64_t data:17;
2131+ } cn38xx;
2132+ struct cvmx_dbg_data_cn38xx cn38xxp2;
2133+ struct cvmx_dbg_data_cn30xx cn50xx;
2134+ struct cvmx_dbg_data_cn58xx {
2135+ uint64_t reserved_29_63:35;
2136+ uint64_t rem:6;
2137+ uint64_t c_mul:5;
2138+ uint64_t dsel_ext:1;
2139+ uint64_t data:17;
2140+ } cn58xx;
2141+ struct cvmx_dbg_data_cn58xx cn58xxp1;
2142+};
2143+
2144+#endif
2145--- /dev/null
2146+++ b/drivers/staging/octeon/cvmx-fau.h
2147@@ -0,0 +1,597 @@
2148+/***********************license start***************
2149+ * Author: Cavium Networks
2150+ *
2151+ * Contact: support@caviumnetworks.com
2152+ * This file is part of the OCTEON SDK
2153+ *
2154+ * Copyright (c) 2003-2008 Cavium Networks
2155+ *
2156+ * This file is free software; you can redistribute it and/or modify
2157+ * it under the terms of the GNU General Public License, Version 2, as
2158+ * published by the Free Software Foundation.
2159+ *
2160+ * This file is distributed in the hope that it will be useful, but
2161+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2162+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2163+ * NONINFRINGEMENT. See the GNU General Public License for more
2164+ * details.
2165+ *
2166+ * You should have received a copy of the GNU General Public License
2167+ * along with this file; if not, write to the Free Software
2168+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2169+ * or visit http://www.gnu.org/licenses/.
2170+ *
2171+ * This file may also be available under a different license from Cavium.
2172+ * Contact Cavium Networks for more information
2173+ ***********************license end**************************************/
2174+
2175+/*
2176+ * Interface to the hardware Fetch and Add Unit.
2177+ */
2178+
2179+#ifndef __CVMX_FAU_H__
2180+#define __CVMX_FAU_H__
2181+
2182+/*
2183+ * Octeon Fetch and Add Unit (FAU)
2184+ */
2185+
2186+#define CVMX_FAU_LOAD_IO_ADDRESS cvmx_build_io_address(0x1e, 0)
2187+#define CVMX_FAU_BITS_SCRADDR 63, 56
2188+#define CVMX_FAU_BITS_LEN 55, 48
2189+#define CVMX_FAU_BITS_INEVAL 35, 14
2190+#define CVMX_FAU_BITS_TAGWAIT 13, 13
2191+#define CVMX_FAU_BITS_NOADD 13, 13
2192+#define CVMX_FAU_BITS_SIZE 12, 11
2193+#define CVMX_FAU_BITS_REGISTER 10, 0
2194+
2195+typedef enum {
2196+ CVMX_FAU_OP_SIZE_8 = 0,
2197+ CVMX_FAU_OP_SIZE_16 = 1,
2198+ CVMX_FAU_OP_SIZE_32 = 2,
2199+ CVMX_FAU_OP_SIZE_64 = 3
2200+} cvmx_fau_op_size_t;
2201+
2202+/**
2203+ * Tagwait return definition. If a timeout occurs, the error
2204+ * bit will be set. Otherwise the value of the register before
2205+ * the update will be returned.
2206+ */
2207+typedef struct {
2208+ uint64_t error:1;
2209+ int64_t value:63;
2210+} cvmx_fau_tagwait64_t;
2211+
2212+/**
2213+ * Tagwait return definition. If a timeout occurs, the error
2214+ * bit will be set. Otherwise the value of the register before
2215+ * the update will be returned.
2216+ */
2217+typedef struct {
2218+ uint64_t error:1;
2219+ int32_t value:31;
2220+} cvmx_fau_tagwait32_t;
2221+
2222+/**
2223+ * Tagwait return definition. If a timeout occurs, the error
2224+ * bit will be set. Otherwise the value of the register before
2225+ * the update will be returned.
2226+ */
2227+typedef struct {
2228+ uint64_t error:1;
2229+ int16_t value:15;
2230+} cvmx_fau_tagwait16_t;
2231+
2232+/**
2233+ * Tagwait return definition. If a timeout occurs, the error
2234+ * bit will be set. Otherwise the value of the register before
2235+ * the update will be returned.
2236+ */
2237+typedef struct {
2238+ uint64_t error:1;
2239+ int8_t value:7;
2240+} cvmx_fau_tagwait8_t;
2241+
2242+/**
2243+ * Asynchronous tagwait return definition. If a timeout occurs,
2244+ * the error bit will be set. Otherwise the value of the
2245+ * register before the update will be returned.
2246+ */
2247+typedef union {
2248+ uint64_t u64;
2249+ struct {
2250+ uint64_t invalid:1;
2251+ uint64_t data:63; /* unpredictable if invalid is set */
2252+ } s;
2253+} cvmx_fau_async_tagwait_result_t;
2254+
2255+/**
2256+ * Builds a store I/O address for writing to the FAU
2257+ *
2258+ * @noadd: 0 = Store value is atomically added to the current value
2259+ * 1 = Store value is atomically written over the current value
2260+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2261+ * - Step by 2 for 16 bit access.
2262+ * - Step by 4 for 32 bit access.
2263+ * - Step by 8 for 64 bit access.
2264+ * Returns Address to store for atomic update
2265+ */
2266+static inline uint64_t __cvmx_fau_store_address(uint64_t noadd, uint64_t reg)
2267+{
2268+ return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
2269+ cvmx_build_bits(CVMX_FAU_BITS_NOADD, noadd) |
2270+ cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2271+}
2272+
2273+/**
2274+ * Builds a I/O address for accessing the FAU
2275+ *
2276+ * @tagwait: Should the atomic add wait for the current tag switch
2277+ * operation to complete.
2278+ * - 0 = Don't wait
2279+ * - 1 = Wait for tag switch to complete
2280+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2281+ * - Step by 2 for 16 bit access.
2282+ * - Step by 4 for 32 bit access.
2283+ * - Step by 8 for 64 bit access.
2284+ * @value: Signed value to add.
2285+ * Note: When performing 32 and 64 bit access, only the low
2286+ * 22 bits are available.
2287+ * Returns Address to read from for atomic update
2288+ */
2289+static inline uint64_t __cvmx_fau_atomic_address(uint64_t tagwait, uint64_t reg,
2290+ int64_t value)
2291+{
2292+ return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
2293+ cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
2294+ cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
2295+ cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2296+}
2297+
2298+/**
2299+ * Perform an atomic 64 bit add
2300+ *
2301+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2302+ * - Step by 8 for 64 bit access.
2303+ * @value: Signed value to add.
2304+ * Note: Only the low 22 bits are available.
2305+ * Returns Value of the register before the update
2306+ */
2307+static inline int64_t cvmx_fau_fetch_and_add64(cvmx_fau_reg_64_t reg,
2308+ int64_t value)
2309+{
2310+ return cvmx_read64_int64(__cvmx_fau_atomic_address(0, reg, value));
2311+}
2312+
2313+/**
2314+ * Perform an atomic 32 bit add
2315+ *
2316+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2317+ * - Step by 4 for 32 bit access.
2318+ * @value: Signed value to add.
2319+ * Note: Only the low 22 bits are available.
2320+ * Returns Value of the register before the update
2321+ */
2322+static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg_32_t reg,
2323+ int32_t value)
2324+{
2325+ return cvmx_read64_int32(__cvmx_fau_atomic_address(0, reg, value));
2326+}
2327+
2328+/**
2329+ * Perform an atomic 16 bit add
2330+ *
2331+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2332+ * - Step by 2 for 16 bit access.
2333+ * @value: Signed value to add.
2334+ * Returns Value of the register before the update
2335+ */
2336+static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg_16_t reg,
2337+ int16_t value)
2338+{
2339+ return cvmx_read64_int16(__cvmx_fau_atomic_address(0, reg, value));
2340+}
2341+
2342+/**
2343+ * Perform an atomic 8 bit add
2344+ *
2345+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2346+ * @value: Signed value to add.
2347+ * Returns Value of the register before the update
2348+ */
2349+static inline int8_t cvmx_fau_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
2350+{
2351+ return cvmx_read64_int8(__cvmx_fau_atomic_address(0, reg, value));
2352+}
2353+
2354+/**
2355+ * Perform an atomic 64 bit add after the current tag switch
2356+ * completes
2357+ *
2358+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2359+ * - Step by 8 for 64 bit access.
2360+ * @value: Signed value to add.
2361+ * Note: Only the low 22 bits are available.
2362+ * Returns If a timeout occurs, the error bit will be set. Otherwise
2363+ * the value of the register before the update will be
2364+ * returned
2365+ */
2366+static inline cvmx_fau_tagwait64_t
2367+cvmx_fau_tagwait_fetch_and_add64(cvmx_fau_reg_64_t reg, int64_t value)
2368+{
2369+ union {
2370+ uint64_t i64;
2371+ cvmx_fau_tagwait64_t t;
2372+ } result;
2373+ result.i64 =
2374+ cvmx_read64_int64(__cvmx_fau_atomic_address(1, reg, value));
2375+ return result.t;
2376+}
2377+
2378+/**
2379+ * Perform an atomic 32 bit add after the current tag switch
2380+ * completes
2381+ *
2382+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2383+ * - Step by 4 for 32 bit access.
2384+ * @value: Signed value to add.
2385+ * Note: Only the low 22 bits are available.
2386+ * Returns If a timeout occurs, the error bit will be set. Otherwise
2387+ * the value of the register before the update will be
2388+ * returned
2389+ */
2390+static inline cvmx_fau_tagwait32_t
2391+cvmx_fau_tagwait_fetch_and_add32(cvmx_fau_reg_32_t reg, int32_t value)
2392+{
2393+ union {
2394+ uint64_t i32;
2395+ cvmx_fau_tagwait32_t t;
2396+ } result;
2397+ result.i32 =
2398+ cvmx_read64_int32(__cvmx_fau_atomic_address(1, reg, value));
2399+ return result.t;
2400+}
2401+
2402+/**
2403+ * Perform an atomic 16 bit add after the current tag switch
2404+ * completes
2405+ *
2406+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2407+ * - Step by 2 for 16 bit access.
2408+ * @value: Signed value to add.
2409+ * Returns If a timeout occurs, the error bit will be set. Otherwise
2410+ * the value of the register before the update will be
2411+ * returned
2412+ */
2413+static inline cvmx_fau_tagwait16_t
2414+cvmx_fau_tagwait_fetch_and_add16(cvmx_fau_reg_16_t reg, int16_t value)
2415+{
2416+ union {
2417+ uint64_t i16;
2418+ cvmx_fau_tagwait16_t t;
2419+ } result;
2420+ result.i16 =
2421+ cvmx_read64_int16(__cvmx_fau_atomic_address(1, reg, value));
2422+ return result.t;
2423+}
2424+
2425+/**
2426+ * Perform an atomic 8 bit add after the current tag switch
2427+ * completes
2428+ *
2429+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2430+ * @value: Signed value to add.
2431+ * Returns If a timeout occurs, the error bit will be set. Otherwise
2432+ * the value of the register before the update will be
2433+ * returned
2434+ */
2435+static inline cvmx_fau_tagwait8_t
2436+cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
2437+{
2438+ union {
2439+ uint64_t i8;
2440+ cvmx_fau_tagwait8_t t;
2441+ } result;
2442+ result.i8 = cvmx_read64_int8(__cvmx_fau_atomic_address(1, reg, value));
2443+ return result.t;
2444+}
2445+
2446+/**
2447+ * Builds I/O data for async operations
2448+ *
2449+ * @scraddr: Scratch pad byte addres to write to. Must be 8 byte aligned
2450+ * @value: Signed value to add.
2451+ * Note: When performing 32 and 64 bit access, only the low
2452+ * 22 bits are available.
2453+ * @tagwait: Should the atomic add wait for the current tag switch
2454+ * operation to complete.
2455+ * - 0 = Don't wait
2456+ * - 1 = Wait for tag switch to complete
2457+ * @size: The size of the operation:
2458+ * - CVMX_FAU_OP_SIZE_8 (0) = 8 bits
2459+ * - CVMX_FAU_OP_SIZE_16 (1) = 16 bits
2460+ * - CVMX_FAU_OP_SIZE_32 (2) = 32 bits
2461+ * - CVMX_FAU_OP_SIZE_64 (3) = 64 bits
2462+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2463+ * - Step by 2 for 16 bit access.
2464+ * - Step by 4 for 32 bit access.
2465+ * - Step by 8 for 64 bit access.
2466+ * Returns Data to write using cvmx_send_single
2467+ */
2468+static inline uint64_t __cvmx_fau_iobdma_data(uint64_t scraddr, int64_t value,
2469+ uint64_t tagwait,
2470+ cvmx_fau_op_size_t size,
2471+ uint64_t reg)
2472+{
2473+ return CVMX_FAU_LOAD_IO_ADDRESS |
2474+ cvmx_build_bits(CVMX_FAU_BITS_SCRADDR, scraddr >> 3) |
2475+ cvmx_build_bits(CVMX_FAU_BITS_LEN, 1) |
2476+ cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
2477+ cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
2478+ cvmx_build_bits(CVMX_FAU_BITS_SIZE, size) |
2479+ cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2480+}
2481+
2482+/**
2483+ * Perform an async atomic 64 bit add. The old value is
2484+ * placed in the scratch memory at byte address scraddr.
2485+ *
2486+ * @scraddr: Scratch memory byte address to put response in.
2487+ * Must be 8 byte aligned.
2488+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2489+ * - Step by 8 for 64 bit access.
2490+ * @value: Signed value to add.
2491+ * Note: Only the low 22 bits are available.
2492+ * Returns Placed in the scratch pad register
2493+ */
2494+static inline void cvmx_fau_async_fetch_and_add64(uint64_t scraddr,
2495+ cvmx_fau_reg_64_t reg,
2496+ int64_t value)
2497+{
2498+ cvmx_send_single(__cvmx_fau_iobdma_data
2499+ (scraddr, value, 0, CVMX_FAU_OP_SIZE_64, reg));
2500+}
2501+
2502+/**
2503+ * Perform an async atomic 32 bit add. The old value is
2504+ * placed in the scratch memory at byte address scraddr.
2505+ *
2506+ * @scraddr: Scratch memory byte address to put response in.
2507+ * Must be 8 byte aligned.
2508+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2509+ * - Step by 4 for 32 bit access.
2510+ * @value: Signed value to add.
2511+ * Note: Only the low 22 bits are available.
2512+ * Returns Placed in the scratch pad register
2513+ */
2514+static inline void cvmx_fau_async_fetch_and_add32(uint64_t scraddr,
2515+ cvmx_fau_reg_32_t reg,
2516+ int32_t value)
2517+{
2518+ cvmx_send_single(__cvmx_fau_iobdma_data
2519+ (scraddr, value, 0, CVMX_FAU_OP_SIZE_32, reg));
2520+}
2521+
2522+/**
2523+ * Perform an async atomic 16 bit add. The old value is
2524+ * placed in the scratch memory at byte address scraddr.
2525+ *
2526+ * @scraddr: Scratch memory byte address to put response in.
2527+ * Must be 8 byte aligned.
2528+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2529+ * - Step by 2 for 16 bit access.
2530+ * @value: Signed value to add.
2531+ * Returns Placed in the scratch pad register
2532+ */
2533+static inline void cvmx_fau_async_fetch_and_add16(uint64_t scraddr,
2534+ cvmx_fau_reg_16_t reg,
2535+ int16_t value)
2536+{
2537+ cvmx_send_single(__cvmx_fau_iobdma_data
2538+ (scraddr, value, 0, CVMX_FAU_OP_SIZE_16, reg));
2539+}
2540+
2541+/**
2542+ * Perform an async atomic 8 bit add. The old value is
2543+ * placed in the scratch memory at byte address scraddr.
2544+ *
2545+ * @scraddr: Scratch memory byte address to put response in.
2546+ * Must be 8 byte aligned.
2547+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2548+ * @value: Signed value to add.
2549+ * Returns Placed in the scratch pad register
2550+ */
2551+static inline void cvmx_fau_async_fetch_and_add8(uint64_t scraddr,
2552+ cvmx_fau_reg_8_t reg,
2553+ int8_t value)
2554+{
2555+ cvmx_send_single(__cvmx_fau_iobdma_data
2556+ (scraddr, value, 0, CVMX_FAU_OP_SIZE_8, reg));
2557+}
2558+
2559+/**
2560+ * Perform an async atomic 64 bit add after the current tag
2561+ * switch completes.
2562+ *
2563+ * @scraddr: Scratch memory byte address to put response in. Must be
2564+ * 8 byte aligned. If a timeout occurs, the error bit (63)
2565+ * will be set. Otherwise the value of the register before
2566+ * the update will be returned
2567+ *
2568+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2569+ * - Step by 8 for 64 bit access.
2570+ * @value: Signed value to add.
2571+ * Note: Only the low 22 bits are available.
2572+ * Returns Placed in the scratch pad register
2573+ */
2574+static inline void cvmx_fau_async_tagwait_fetch_and_add64(uint64_t scraddr,
2575+ cvmx_fau_reg_64_t reg,
2576+ int64_t value)
2577+{
2578+ cvmx_send_single(__cvmx_fau_iobdma_data
2579+ (scraddr, value, 1, CVMX_FAU_OP_SIZE_64, reg));
2580+}
2581+
2582+/**
2583+ * Perform an async atomic 32 bit add after the current tag
2584+ * switch completes.
2585+ *
2586+ * @scraddr: Scratch memory byte address to put response in. Must be
2587+ * 8 byte aligned. If a timeout occurs, the error bit (63)
2588+ * will be set. Otherwise the value of the register before
2589+ * the update will be returned
2590+ *
2591+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2592+ * - Step by 4 for 32 bit access.
2593+ * @value: Signed value to add.
2594+ * Note: Only the low 22 bits are available.
2595+ * Returns Placed in the scratch pad register
2596+ */
2597+static inline void cvmx_fau_async_tagwait_fetch_and_add32(uint64_t scraddr,
2598+ cvmx_fau_reg_32_t reg,
2599+ int32_t value)
2600+{
2601+ cvmx_send_single(__cvmx_fau_iobdma_data
2602+ (scraddr, value, 1, CVMX_FAU_OP_SIZE_32, reg));
2603+}
2604+
2605+/**
2606+ * Perform an async atomic 16 bit add after the current tag
2607+ * switch completes.
2608+ *
2609+ * @scraddr: Scratch memory byte address to put response in. Must be
2610+ * 8 byte aligned. If a timeout occurs, the error bit (63)
2611+ * will be set. Otherwise the value of the register before
2612+ * the update will be returned
2613+ *
2614+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2615+ * - Step by 2 for 16 bit access.
2616+ * @value: Signed value to add.
2617+ *
2618+ * Returns Placed in the scratch pad register
2619+ */
2620+static inline void cvmx_fau_async_tagwait_fetch_and_add16(uint64_t scraddr,
2621+ cvmx_fau_reg_16_t reg,
2622+ int16_t value)
2623+{
2624+ cvmx_send_single(__cvmx_fau_iobdma_data
2625+ (scraddr, value, 1, CVMX_FAU_OP_SIZE_16, reg));
2626+}
2627+
2628+/**
2629+ * Perform an async atomic 8 bit add after the current tag
2630+ * switch completes.
2631+ *
2632+ * @scraddr: Scratch memory byte address to put response in. Must be
2633+ * 8 byte aligned. If a timeout occurs, the error bit (63)
2634+ * will be set. Otherwise the value of the register before
2635+ * the update will be returned
2636+ *
2637+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2638+ * @value: Signed value to add.
2639+ *
2640+ * Returns Placed in the scratch pad register
2641+ */
2642+static inline void cvmx_fau_async_tagwait_fetch_and_add8(uint64_t scraddr,
2643+ cvmx_fau_reg_8_t reg,
2644+ int8_t value)
2645+{
2646+ cvmx_send_single(__cvmx_fau_iobdma_data
2647+ (scraddr, value, 1, CVMX_FAU_OP_SIZE_8, reg));
2648+}
2649+
2650+/**
2651+ * Perform an atomic 64 bit add
2652+ *
2653+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2654+ * - Step by 8 for 64 bit access.
2655+ * @value: Signed value to add.
2656+ */
2657+static inline void cvmx_fau_atomic_add64(cvmx_fau_reg_64_t reg, int64_t value)
2658+{
2659+ cvmx_write64_int64(__cvmx_fau_store_address(0, reg), value);
2660+}
2661+
2662+/**
2663+ * Perform an atomic 32 bit add
2664+ *
2665+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2666+ * - Step by 4 for 32 bit access.
2667+ * @value: Signed value to add.
2668+ */
2669+static inline void cvmx_fau_atomic_add32(cvmx_fau_reg_32_t reg, int32_t value)
2670+{
2671+ cvmx_write64_int32(__cvmx_fau_store_address(0, reg), value);
2672+}
2673+
2674+/**
2675+ * Perform an atomic 16 bit add
2676+ *
2677+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2678+ * - Step by 2 for 16 bit access.
2679+ * @value: Signed value to add.
2680+ */
2681+static inline void cvmx_fau_atomic_add16(cvmx_fau_reg_16_t reg, int16_t value)
2682+{
2683+ cvmx_write64_int16(__cvmx_fau_store_address(0, reg), value);
2684+}
2685+
2686+/**
2687+ * Perform an atomic 8 bit add
2688+ *
2689+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2690+ * @value: Signed value to add.
2691+ */
2692+static inline void cvmx_fau_atomic_add8(cvmx_fau_reg_8_t reg, int8_t value)
2693+{
2694+ cvmx_write64_int8(__cvmx_fau_store_address(0, reg), value);
2695+}
2696+
2697+/**
2698+ * Perform an atomic 64 bit write
2699+ *
2700+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2701+ * - Step by 8 for 64 bit access.
2702+ * @value: Signed value to write.
2703+ */
2704+static inline void cvmx_fau_atomic_write64(cvmx_fau_reg_64_t reg, int64_t value)
2705+{
2706+ cvmx_write64_int64(__cvmx_fau_store_address(1, reg), value);
2707+}
2708+
2709+/**
2710+ * Perform an atomic 32 bit write
2711+ *
2712+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2713+ * - Step by 4 for 32 bit access.
2714+ * @value: Signed value to write.
2715+ */
2716+static inline void cvmx_fau_atomic_write32(cvmx_fau_reg_32_t reg, int32_t value)
2717+{
2718+ cvmx_write64_int32(__cvmx_fau_store_address(1, reg), value);
2719+}
2720+
2721+/**
2722+ * Perform an atomic 16 bit write
2723+ *
2724+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2725+ * - Step by 2 for 16 bit access.
2726+ * @value: Signed value to write.
2727+ */
2728+static inline void cvmx_fau_atomic_write16(cvmx_fau_reg_16_t reg, int16_t value)
2729+{
2730+ cvmx_write64_int16(__cvmx_fau_store_address(1, reg), value);
2731+}
2732+
2733+/**
2734+ * Perform an atomic 8 bit write
2735+ *
2736+ * @reg: FAU atomic register to access. 0 <= reg < 2048.
2737+ * @value: Signed value to write.
2738+ */
2739+static inline void cvmx_fau_atomic_write8(cvmx_fau_reg_8_t reg, int8_t value)
2740+{
2741+ cvmx_write64_int8(__cvmx_fau_store_address(1, reg), value);
2742+}
2743+
2744+#endif /* __CVMX_FAU_H__ */
2745--- /dev/null
2746+++ b/drivers/staging/octeon/cvmx-fpa-defs.h
2747@@ -0,0 +1,403 @@
2748+/***********************license start***************
2749+ * Author: Cavium Networks
2750+ *
2751+ * Contact: support@caviumnetworks.com
2752+ * This file is part of the OCTEON SDK
2753+ *
2754+ * Copyright (c) 2003-2008 Cavium Networks
2755+ *
2756+ * This file is free software; you can redistribute it and/or modify
2757+ * it under the terms of the GNU General Public License, Version 2, as
2758+ * published by the Free Software Foundation.
2759+ *
2760+ * This file is distributed in the hope that it will be useful, but
2761+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2762+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2763+ * NONINFRINGEMENT. See the GNU General Public License for more
2764+ * details.
2765+ *
2766+ * You should have received a copy of the GNU General Public License
2767+ * along with this file; if not, write to the Free Software
2768+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2769+ * or visit http://www.gnu.org/licenses/.
2770+ *
2771+ * This file may also be available under a different license from Cavium.
2772+ * Contact Cavium Networks for more information
2773+ ***********************license end**************************************/
2774+
2775+#ifndef __CVMX_FPA_DEFS_H__
2776+#define __CVMX_FPA_DEFS_H__
2777+
2778+#define CVMX_FPA_BIST_STATUS \
2779+ CVMX_ADD_IO_SEG(0x00011800280000E8ull)
2780+#define CVMX_FPA_CTL_STATUS \
2781+ CVMX_ADD_IO_SEG(0x0001180028000050ull)
2782+#define CVMX_FPA_FPF0_MARKS \
2783+ CVMX_ADD_IO_SEG(0x0001180028000000ull)
2784+#define CVMX_FPA_FPF0_SIZE \
2785+ CVMX_ADD_IO_SEG(0x0001180028000058ull)
2786+#define CVMX_FPA_FPF1_MARKS \
2787+ CVMX_ADD_IO_SEG(0x0001180028000008ull)
2788+#define CVMX_FPA_FPF2_MARKS \
2789+ CVMX_ADD_IO_SEG(0x0001180028000010ull)
2790+#define CVMX_FPA_FPF3_MARKS \
2791+ CVMX_ADD_IO_SEG(0x0001180028000018ull)
2792+#define CVMX_FPA_FPF4_MARKS \
2793+ CVMX_ADD_IO_SEG(0x0001180028000020ull)
2794+#define CVMX_FPA_FPF5_MARKS \
2795+ CVMX_ADD_IO_SEG(0x0001180028000028ull)
2796+#define CVMX_FPA_FPF6_MARKS \
2797+ CVMX_ADD_IO_SEG(0x0001180028000030ull)
2798+#define CVMX_FPA_FPF7_MARKS \
2799+ CVMX_ADD_IO_SEG(0x0001180028000038ull)
2800+#define CVMX_FPA_FPFX_MARKS(offset) \
2801+ CVMX_ADD_IO_SEG(0x0001180028000008ull + (((offset) & 7) * 8) - 8 * 1)
2802+#define CVMX_FPA_FPFX_SIZE(offset) \
2803+ CVMX_ADD_IO_SEG(0x0001180028000060ull + (((offset) & 7) * 8) - 8 * 1)
2804+#define CVMX_FPA_INT_ENB \
2805+ CVMX_ADD_IO_SEG(0x0001180028000048ull)
2806+#define CVMX_FPA_INT_SUM \
2807+ CVMX_ADD_IO_SEG(0x0001180028000040ull)
2808+#define CVMX_FPA_QUE0_PAGE_INDEX \
2809+ CVMX_ADD_IO_SEG(0x00011800280000F0ull)
2810+#define CVMX_FPA_QUE1_PAGE_INDEX \
2811+ CVMX_ADD_IO_SEG(0x00011800280000F8ull)
2812+#define CVMX_FPA_QUE2_PAGE_INDEX \
2813+ CVMX_ADD_IO_SEG(0x0001180028000100ull)
2814+#define CVMX_FPA_QUE3_PAGE_INDEX \
2815+ CVMX_ADD_IO_SEG(0x0001180028000108ull)
2816+#define CVMX_FPA_QUE4_PAGE_INDEX \
2817+ CVMX_ADD_IO_SEG(0x0001180028000110ull)
2818+#define CVMX_FPA_QUE5_PAGE_INDEX \
2819+ CVMX_ADD_IO_SEG(0x0001180028000118ull)
2820+#define CVMX_FPA_QUE6_PAGE_INDEX \
2821+ CVMX_ADD_IO_SEG(0x0001180028000120ull)
2822+#define CVMX_FPA_QUE7_PAGE_INDEX \
2823+ CVMX_ADD_IO_SEG(0x0001180028000128ull)
2824+#define CVMX_FPA_QUEX_AVAILABLE(offset) \
2825+ CVMX_ADD_IO_SEG(0x0001180028000098ull + (((offset) & 7) * 8))
2826+#define CVMX_FPA_QUEX_PAGE_INDEX(offset) \
2827+ CVMX_ADD_IO_SEG(0x00011800280000F0ull + (((offset) & 7) * 8))
2828+#define CVMX_FPA_QUE_ACT \
2829+ CVMX_ADD_IO_SEG(0x0001180028000138ull)
2830+#define CVMX_FPA_QUE_EXP \
2831+ CVMX_ADD_IO_SEG(0x0001180028000130ull)
2832+#define CVMX_FPA_WART_CTL \
2833+ CVMX_ADD_IO_SEG(0x00011800280000D8ull)
2834+#define CVMX_FPA_WART_STATUS \
2835+ CVMX_ADD_IO_SEG(0x00011800280000E0ull)
2836+
2837+union cvmx_fpa_bist_status {
2838+ uint64_t u64;
2839+ struct cvmx_fpa_bist_status_s {
2840+ uint64_t reserved_5_63:59;
2841+ uint64_t frd:1;
2842+ uint64_t fpf0:1;
2843+ uint64_t fpf1:1;
2844+ uint64_t ffr:1;
2845+ uint64_t fdr:1;
2846+ } s;
2847+ struct cvmx_fpa_bist_status_s cn30xx;
2848+ struct cvmx_fpa_bist_status_s cn31xx;
2849+ struct cvmx_fpa_bist_status_s cn38xx;
2850+ struct cvmx_fpa_bist_status_s cn38xxp2;
2851+ struct cvmx_fpa_bist_status_s cn50xx;
2852+ struct cvmx_fpa_bist_status_s cn52xx;
2853+ struct cvmx_fpa_bist_status_s cn52xxp1;
2854+ struct cvmx_fpa_bist_status_s cn56xx;
2855+ struct cvmx_fpa_bist_status_s cn56xxp1;
2856+ struct cvmx_fpa_bist_status_s cn58xx;
2857+ struct cvmx_fpa_bist_status_s cn58xxp1;
2858+};
2859+
2860+union cvmx_fpa_ctl_status {
2861+ uint64_t u64;
2862+ struct cvmx_fpa_ctl_status_s {
2863+ uint64_t reserved_18_63:46;
2864+ uint64_t reset:1;
2865+ uint64_t use_ldt:1;
2866+ uint64_t use_stt:1;
2867+ uint64_t enb:1;
2868+ uint64_t mem1_err:7;
2869+ uint64_t mem0_err:7;
2870+ } s;
2871+ struct cvmx_fpa_ctl_status_s cn30xx;
2872+ struct cvmx_fpa_ctl_status_s cn31xx;
2873+ struct cvmx_fpa_ctl_status_s cn38xx;
2874+ struct cvmx_fpa_ctl_status_s cn38xxp2;
2875+ struct cvmx_fpa_ctl_status_s cn50xx;
2876+ struct cvmx_fpa_ctl_status_s cn52xx;
2877+ struct cvmx_fpa_ctl_status_s cn52xxp1;
2878+ struct cvmx_fpa_ctl_status_s cn56xx;
2879+ struct cvmx_fpa_ctl_status_s cn56xxp1;
2880+ struct cvmx_fpa_ctl_status_s cn58xx;
2881+ struct cvmx_fpa_ctl_status_s cn58xxp1;
2882+};
2883+
2884+union cvmx_fpa_fpfx_marks {
2885+ uint64_t u64;
2886+ struct cvmx_fpa_fpfx_marks_s {
2887+ uint64_t reserved_22_63:42;
2888+ uint64_t fpf_wr:11;
2889+ uint64_t fpf_rd:11;
2890+ } s;
2891+ struct cvmx_fpa_fpfx_marks_s cn38xx;
2892+ struct cvmx_fpa_fpfx_marks_s cn38xxp2;
2893+ struct cvmx_fpa_fpfx_marks_s cn56xx;
2894+ struct cvmx_fpa_fpfx_marks_s cn56xxp1;
2895+ struct cvmx_fpa_fpfx_marks_s cn58xx;
2896+ struct cvmx_fpa_fpfx_marks_s cn58xxp1;
2897+};
2898+
2899+union cvmx_fpa_fpfx_size {
2900+ uint64_t u64;
2901+ struct cvmx_fpa_fpfx_size_s {
2902+ uint64_t reserved_11_63:53;
2903+ uint64_t fpf_siz:11;
2904+ } s;
2905+ struct cvmx_fpa_fpfx_size_s cn38xx;
2906+ struct cvmx_fpa_fpfx_size_s cn38xxp2;
2907+ struct cvmx_fpa_fpfx_size_s cn56xx;
2908+ struct cvmx_fpa_fpfx_size_s cn56xxp1;
2909+ struct cvmx_fpa_fpfx_size_s cn58xx;
2910+ struct cvmx_fpa_fpfx_size_s cn58xxp1;
2911+};
2912+
2913+union cvmx_fpa_fpf0_marks {
2914+ uint64_t u64;
2915+ struct cvmx_fpa_fpf0_marks_s {
2916+ uint64_t reserved_24_63:40;
2917+ uint64_t fpf_wr:12;
2918+ uint64_t fpf_rd:12;
2919+ } s;
2920+ struct cvmx_fpa_fpf0_marks_s cn38xx;
2921+ struct cvmx_fpa_fpf0_marks_s cn38xxp2;
2922+ struct cvmx_fpa_fpf0_marks_s cn56xx;
2923+ struct cvmx_fpa_fpf0_marks_s cn56xxp1;
2924+ struct cvmx_fpa_fpf0_marks_s cn58xx;
2925+ struct cvmx_fpa_fpf0_marks_s cn58xxp1;
2926+};
2927+
2928+union cvmx_fpa_fpf0_size {
2929+ uint64_t u64;
2930+ struct cvmx_fpa_fpf0_size_s {
2931+ uint64_t reserved_12_63:52;
2932+ uint64_t fpf_siz:12;
2933+ } s;
2934+ struct cvmx_fpa_fpf0_size_s cn38xx;
2935+ struct cvmx_fpa_fpf0_size_s cn38xxp2;
2936+ struct cvmx_fpa_fpf0_size_s cn56xx;
2937+ struct cvmx_fpa_fpf0_size_s cn56xxp1;
2938+ struct cvmx_fpa_fpf0_size_s cn58xx;
2939+ struct cvmx_fpa_fpf0_size_s cn58xxp1;
2940+};
2941+
2942+union cvmx_fpa_int_enb {
2943+ uint64_t u64;
2944+ struct cvmx_fpa_int_enb_s {
2945+ uint64_t reserved_28_63:36;
2946+ uint64_t q7_perr:1;
2947+ uint64_t q7_coff:1;
2948+ uint64_t q7_und:1;
2949+ uint64_t q6_perr:1;
2950+ uint64_t q6_coff:1;
2951+ uint64_t q6_und:1;
2952+ uint64_t q5_perr:1;
2953+ uint64_t q5_coff:1;
2954+ uint64_t q5_und:1;
2955+ uint64_t q4_perr:1;
2956+ uint64_t q4_coff:1;
2957+ uint64_t q4_und:1;
2958+ uint64_t q3_perr:1;
2959+ uint64_t q3_coff:1;
2960+ uint64_t q3_und:1;
2961+ uint64_t q2_perr:1;
2962+ uint64_t q2_coff:1;
2963+ uint64_t q2_und:1;
2964+ uint64_t q1_perr:1;
2965+ uint64_t q1_coff:1;
2966+ uint64_t q1_und:1;
2967+ uint64_t q0_perr:1;
2968+ uint64_t q0_coff:1;
2969+ uint64_t q0_und:1;
2970+ uint64_t fed1_dbe:1;
2971+ uint64_t fed1_sbe:1;
2972+ uint64_t fed0_dbe:1;
2973+ uint64_t fed0_sbe:1;
2974+ } s;
2975+ struct cvmx_fpa_int_enb_s cn30xx;
2976+ struct cvmx_fpa_int_enb_s cn31xx;
2977+ struct cvmx_fpa_int_enb_s cn38xx;
2978+ struct cvmx_fpa_int_enb_s cn38xxp2;
2979+ struct cvmx_fpa_int_enb_s cn50xx;
2980+ struct cvmx_fpa_int_enb_s cn52xx;
2981+ struct cvmx_fpa_int_enb_s cn52xxp1;
2982+ struct cvmx_fpa_int_enb_s cn56xx;
2983+ struct cvmx_fpa_int_enb_s cn56xxp1;
2984+ struct cvmx_fpa_int_enb_s cn58xx;
2985+ struct cvmx_fpa_int_enb_s cn58xxp1;
2986+};
2987+
2988+union cvmx_fpa_int_sum {
2989+ uint64_t u64;
2990+ struct cvmx_fpa_int_sum_s {
2991+ uint64_t reserved_28_63:36;
2992+ uint64_t q7_perr:1;
2993+ uint64_t q7_coff:1;
2994+ uint64_t q7_und:1;
2995+ uint64_t q6_perr:1;
2996+ uint64_t q6_coff:1;
2997+ uint64_t q6_und:1;
2998+ uint64_t q5_perr:1;
2999+ uint64_t q5_coff:1;
3000+ uint64_t q5_und:1;
3001+ uint64_t q4_perr:1;
3002+ uint64_t q4_coff:1;
3003+ uint64_t q4_und:1;
3004+ uint64_t q3_perr:1;
3005+ uint64_t q3_coff:1;
3006+ uint64_t q3_und:1;
3007+ uint64_t q2_perr:1;
3008+ uint64_t q2_coff:1;
3009+ uint64_t q2_und:1;
3010+ uint64_t q1_perr:1;
3011+ uint64_t q1_coff:1;
3012+ uint64_t q1_und:1;
3013+ uint64_t q0_perr:1;
3014+ uint64_t q0_coff:1;
3015+ uint64_t q0_und:1;
3016+ uint64_t fed1_dbe:1;
3017+ uint64_t fed1_sbe:1;
3018+ uint64_t fed0_dbe:1;
3019+ uint64_t fed0_sbe:1;
3020+ } s;
3021+ struct cvmx_fpa_int_sum_s cn30xx;
3022+ struct cvmx_fpa_int_sum_s cn31xx;
3023+ struct cvmx_fpa_int_sum_s cn38xx;
3024+ struct cvmx_fpa_int_sum_s cn38xxp2;
3025+ struct cvmx_fpa_int_sum_s cn50xx;
3026+ struct cvmx_fpa_int_sum_s cn52xx;
3027+ struct cvmx_fpa_int_sum_s cn52xxp1;
3028+ struct cvmx_fpa_int_sum_s cn56xx;
3029+ struct cvmx_fpa_int_sum_s cn56xxp1;
3030+ struct cvmx_fpa_int_sum_s cn58xx;
3031+ struct cvmx_fpa_int_sum_s cn58xxp1;
3032+};
3033+
3034+union cvmx_fpa_quex_available {
3035+ uint64_t u64;
3036+ struct cvmx_fpa_quex_available_s {
3037+ uint64_t reserved_29_63:35;
3038+ uint64_t que_siz:29;
3039+ } s;
3040+ struct cvmx_fpa_quex_available_s cn30xx;
3041+ struct cvmx_fpa_quex_available_s cn31xx;
3042+ struct cvmx_fpa_quex_available_s cn38xx;
3043+ struct cvmx_fpa_quex_available_s cn38xxp2;
3044+ struct cvmx_fpa_quex_available_s cn50xx;
3045+ struct cvmx_fpa_quex_available_s cn52xx;
3046+ struct cvmx_fpa_quex_available_s cn52xxp1;
3047+ struct cvmx_fpa_quex_available_s cn56xx;
3048+ struct cvmx_fpa_quex_available_s cn56xxp1;
3049+ struct cvmx_fpa_quex_available_s cn58xx;
3050+ struct cvmx_fpa_quex_available_s cn58xxp1;
3051+};
3052+
3053+union cvmx_fpa_quex_page_index {
3054+ uint64_t u64;
3055+ struct cvmx_fpa_quex_page_index_s {
3056+ uint64_t reserved_25_63:39;
3057+ uint64_t pg_num:25;
3058+ } s;
3059+ struct cvmx_fpa_quex_page_index_s cn30xx;
3060+ struct cvmx_fpa_quex_page_index_s cn31xx;
3061+ struct cvmx_fpa_quex_page_index_s cn38xx;
3062+ struct cvmx_fpa_quex_page_index_s cn38xxp2;
3063+ struct cvmx_fpa_quex_page_index_s cn50xx;
3064+ struct cvmx_fpa_quex_page_index_s cn52xx;
3065+ struct cvmx_fpa_quex_page_index_s cn52xxp1;
3066+ struct cvmx_fpa_quex_page_index_s cn56xx;
3067+ struct cvmx_fpa_quex_page_index_s cn56xxp1;
3068+ struct cvmx_fpa_quex_page_index_s cn58xx;
3069+ struct cvmx_fpa_quex_page_index_s cn58xxp1;
3070+};
3071+
3072+union cvmx_fpa_que_act {
3073+ uint64_t u64;
3074+ struct cvmx_fpa_que_act_s {
3075+ uint64_t reserved_29_63:35;
3076+ uint64_t act_que:3;
3077+ uint64_t act_indx:26;
3078+ } s;
3079+ struct cvmx_fpa_que_act_s cn30xx;
3080+ struct cvmx_fpa_que_act_s cn31xx;
3081+ struct cvmx_fpa_que_act_s cn38xx;
3082+ struct cvmx_fpa_que_act_s cn38xxp2;
3083+ struct cvmx_fpa_que_act_s cn50xx;
3084+ struct cvmx_fpa_que_act_s cn52xx;
3085+ struct cvmx_fpa_que_act_s cn52xxp1;
3086+ struct cvmx_fpa_que_act_s cn56xx;
3087+ struct cvmx_fpa_que_act_s cn56xxp1;
3088+ struct cvmx_fpa_que_act_s cn58xx;
3089+ struct cvmx_fpa_que_act_s cn58xxp1;
3090+};
3091+
3092+union cvmx_fpa_que_exp {
3093+ uint64_t u64;
3094+ struct cvmx_fpa_que_exp_s {
3095+ uint64_t reserved_29_63:35;
3096+ uint64_t exp_que:3;
3097+ uint64_t exp_indx:26;
3098+ } s;
3099+ struct cvmx_fpa_que_exp_s cn30xx;
3100+ struct cvmx_fpa_que_exp_s cn31xx;
3101+ struct cvmx_fpa_que_exp_s cn38xx;
3102+ struct cvmx_fpa_que_exp_s cn38xxp2;
3103+ struct cvmx_fpa_que_exp_s cn50xx;
3104+ struct cvmx_fpa_que_exp_s cn52xx;
3105+ struct cvmx_fpa_que_exp_s cn52xxp1;
3106+ struct cvmx_fpa_que_exp_s cn56xx;
3107+ struct cvmx_fpa_que_exp_s cn56xxp1;
3108+ struct cvmx_fpa_que_exp_s cn58xx;
3109+ struct cvmx_fpa_que_exp_s cn58xxp1;
3110+};
3111+
3112+union cvmx_fpa_wart_ctl {
3113+ uint64_t u64;
3114+ struct cvmx_fpa_wart_ctl_s {
3115+ uint64_t reserved_16_63:48;
3116+ uint64_t ctl:16;
3117+ } s;
3118+ struct cvmx_fpa_wart_ctl_s cn30xx;
3119+ struct cvmx_fpa_wart_ctl_s cn31xx;
3120+ struct cvmx_fpa_wart_ctl_s cn38xx;
3121+ struct cvmx_fpa_wart_ctl_s cn38xxp2;
3122+ struct cvmx_fpa_wart_ctl_s cn50xx;
3123+ struct cvmx_fpa_wart_ctl_s cn52xx;
3124+ struct cvmx_fpa_wart_ctl_s cn52xxp1;
3125+ struct cvmx_fpa_wart_ctl_s cn56xx;
3126+ struct cvmx_fpa_wart_ctl_s cn56xxp1;
3127+ struct cvmx_fpa_wart_ctl_s cn58xx;
3128+ struct cvmx_fpa_wart_ctl_s cn58xxp1;
3129+};
3130+
3131+union cvmx_fpa_wart_status {
3132+ uint64_t u64;
3133+ struct cvmx_fpa_wart_status_s {
3134+ uint64_t reserved_32_63:32;
3135+ uint64_t status:32;
3136+ } s;
3137+ struct cvmx_fpa_wart_status_s cn30xx;
3138+ struct cvmx_fpa_wart_status_s cn31xx;
3139+ struct cvmx_fpa_wart_status_s cn38xx;
3140+ struct cvmx_fpa_wart_status_s cn38xxp2;
3141+ struct cvmx_fpa_wart_status_s cn50xx;
3142+ struct cvmx_fpa_wart_status_s cn52xx;
3143+ struct cvmx_fpa_wart_status_s cn52xxp1;
3144+ struct cvmx_fpa_wart_status_s cn56xx;
3145+ struct cvmx_fpa_wart_status_s cn56xxp1;
3146+ struct cvmx_fpa_wart_status_s cn58xx;
3147+ struct cvmx_fpa_wart_status_s cn58xxp1;
3148+};
3149+
3150+#endif
3151--- /dev/null
3152+++ b/drivers/staging/octeon/cvmx-fpa.c
3153@@ -0,0 +1,183 @@
3154+/***********************license start***************
3155+ * Author: Cavium Networks
3156+ *
3157+ * Contact: support@caviumnetworks.com
3158+ * This file is part of the OCTEON SDK
3159+ *
3160+ * Copyright (c) 2003-2008 Cavium Networks
3161+ *
3162+ * This file is free software; you can redistribute it and/or modify
3163+ * it under the terms of the GNU General Public License, Version 2, as
3164+ * published by the Free Software Foundation.
3165+ *
3166+ * This file is distributed in the hope that it will be useful, but
3167+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3168+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3169+ * NONINFRINGEMENT. See the GNU General Public License for more
3170+ * details.
3171+ *
3172+ * You should have received a copy of the GNU General Public License
3173+ * along with this file; if not, write to the Free Software
3174+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3175+ * or visit http://www.gnu.org/licenses/.
3176+ *
3177+ * This file may also be available under a different license from Cavium.
3178+ * Contact Cavium Networks for more information
3179+ ***********************license end**************************************/
3180+
3181+/**
3182+ * @file
3183+ *
3184+ * Support library for the hardware Free Pool Allocator.
3185+ *
3186+ *
3187+ */
3188+
3189+#include "cvmx-config.h"
3190+#include "cvmx.h"
3191+#include "cvmx-fpa.h"
3192+#include "cvmx-ipd.h"
3193+
3194+/**
3195+ * Current state of all the pools. Use access functions
3196+ * instead of using it directly.
3197+ */
3198+CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
3199+
3200+/**
3201+ * Setup a FPA pool to control a new block of memory. The
3202+ * buffer pointer must be a physical address.
3203+ *
3204+ * @pool: Pool to initialize
3205+ * 0 <= pool < 8
3206+ * @name: Constant character string to name this pool.
3207+ * String is not copied.
3208+ * @buffer: Pointer to the block of memory to use. This must be
3209+ * accessable by all processors and external hardware.
3210+ * @block_size: Size for each block controlled by the FPA
3211+ * @num_blocks: Number of blocks
3212+ *
3213+ * Returns 0 on Success,
3214+ * -1 on failure
3215+ */
3216+int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
3217+ uint64_t block_size, uint64_t num_blocks)
3218+{
3219+ char *ptr;
3220+ if (!buffer) {
3221+ cvmx_dprintf
3222+ ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
3223+ return -1;
3224+ }
3225+ if (pool >= CVMX_FPA_NUM_POOLS) {
3226+ cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
3227+ return -1;
3228+ }
3229+
3230+ if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
3231+ cvmx_dprintf
3232+ ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
3233+ return -1;
3234+ }
3235+
3236+ if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
3237+ cvmx_dprintf
3238+ ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
3239+ return -1;
3240+ }
3241+
3242+ cvmx_fpa_pool_info[pool].name = name;
3243+ cvmx_fpa_pool_info[pool].size = block_size;
3244+ cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
3245+ cvmx_fpa_pool_info[pool].base = buffer;
3246+
3247+ ptr = (char *)buffer;
3248+ while (num_blocks--) {
3249+ cvmx_fpa_free(ptr, pool, 0);
3250+ ptr += block_size;
3251+ }
3252+ return 0;
3253+}
3254+
3255+/**
3256+ * Shutdown a Memory pool and validate that it had all of
3257+ * the buffers originally placed in it.
3258+ *
3259+ * @pool: Pool to shutdown
3260+ * Returns Zero on success
3261+ * - Positive is count of missing buffers
3262+ * - Negative is too many buffers or corrupted pointers
3263+ */
3264+uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
3265+{
3266+ uint64_t errors = 0;
3267+ uint64_t count = 0;
3268+ uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
3269+ uint64_t finish =
3270+ base +
3271+ cvmx_fpa_pool_info[pool].size *
3272+ cvmx_fpa_pool_info[pool].starting_element_count;
3273+ void *ptr;
3274+ uint64_t address;
3275+
3276+ count = 0;
3277+ do {
3278+ ptr = cvmx_fpa_alloc(pool);
3279+ if (ptr)
3280+ address = cvmx_ptr_to_phys(ptr);
3281+ else
3282+ address = 0;
3283+ if (address) {
3284+ if ((address >= base) && (address < finish) &&
3285+ (((address -
3286+ base) % cvmx_fpa_pool_info[pool].size) == 0)) {
3287+ count++;
3288+ } else {
3289+ cvmx_dprintf
3290+ ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
3291+ (unsigned long long)address,
3292+ cvmx_fpa_pool_info[pool].name, (int)pool);
3293+ errors++;
3294+ }
3295+ }
3296+ } while (address);
3297+
3298+#ifdef CVMX_ENABLE_PKO_FUNCTIONS
3299+ if (pool == 0)
3300+ cvmx_ipd_free_ptr();
3301+#endif
3302+
3303+ if (errors) {
3304+ cvmx_dprintf
3305+ ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n",
3306+ cvmx_fpa_pool_info[pool].name, (int)pool,
3307+ (unsigned long long)base, (unsigned long long)finish,
3308+ (unsigned long long)cvmx_fpa_pool_info[pool].size);
3309+ return -errors;
3310+ } else
3311+ return 0;
3312+}
3313+
3314+uint64_t cvmx_fpa_get_block_size(uint64_t pool)
3315+{
3316+ switch (pool) {
3317+ case 0:
3318+ return CVMX_FPA_POOL_0_SIZE;
3319+ case 1:
3320+ return CVMX_FPA_POOL_1_SIZE;
3321+ case 2:
3322+ return CVMX_FPA_POOL_2_SIZE;
3323+ case 3:
3324+ return CVMX_FPA_POOL_3_SIZE;
3325+ case 4:
3326+ return CVMX_FPA_POOL_4_SIZE;
3327+ case 5:
3328+ return CVMX_FPA_POOL_5_SIZE;
3329+ case 6:
3330+ return CVMX_FPA_POOL_6_SIZE;
3331+ case 7:
3332+ return CVMX_FPA_POOL_7_SIZE;
3333+ default:
3334+ return 0;
3335+ }
3336+}
3337--- /dev/null
3338+++ b/drivers/staging/octeon/cvmx-fpa.h
3339@@ -0,0 +1,299 @@
3340+/***********************license start***************
3341+ * Author: Cavium Networks
3342+ *
3343+ * Contact: support@caviumnetworks.com
3344+ * This file is part of the OCTEON SDK
3345+ *
3346+ * Copyright (c) 2003-2008 Cavium Networks
3347+ *
3348+ * This file is free software; you can redistribute it and/or modify
3349+ * it under the terms of the GNU General Public License, Version 2, as
3350+ * published by the Free Software Foundation.
3351+ *
3352+ * This file is distributed in the hope that it will be useful, but
3353+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3354+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3355+ * NONINFRINGEMENT. See the GNU General Public License for more
3356+ * details.
3357+ *
3358+ * You should have received a copy of the GNU General Public License
3359+ * along with this file; if not, write to the Free Software
3360+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3361+ * or visit http://www.gnu.org/licenses/.
3362+ *
3363+ * This file may also be available under a different license from Cavium.
3364+ * Contact Cavium Networks for more information
3365+ ***********************license end**************************************/
3366+
3367+/**
3368+ * @file
3369+ *
3370+ * Interface to the hardware Free Pool Allocator.
3371+ *
3372+ *
3373+ */
3374+
3375+#ifndef __CVMX_FPA_H__
3376+#define __CVMX_FPA_H__
3377+
3378+#include "cvmx-address.h"
3379+#include "cvmx-fpa-defs.h"
3380+
3381+#define CVMX_FPA_NUM_POOLS 8
3382+#define CVMX_FPA_MIN_BLOCK_SIZE 128
3383+#define CVMX_FPA_ALIGNMENT 128
3384+
3385+/**
3386+ * Structure describing the data format used for stores to the FPA.
3387+ */
3388+typedef union {
3389+ uint64_t u64;
3390+ struct {
3391+ /*
3392+ * the (64-bit word) location in scratchpad to write
3393+ * to (if len != 0)
3394+ */
3395+ uint64_t scraddr:8;
3396+ /* the number of words in the response (0 => no response) */
3397+ uint64_t len:8;
3398+ /* the ID of the device on the non-coherent bus */
3399+ uint64_t did:8;
3400+ /*
3401+ * the address that will appear in the first tick on
3402+ * the NCB bus.
3403+ */
3404+ uint64_t addr:40;
3405+ } s;
3406+} cvmx_fpa_iobdma_data_t;
3407+
3408+/**
3409+ * Structure describing the current state of a FPA pool.
3410+ */
3411+typedef struct {
3412+ /* Name it was created under */
3413+ const char *name;
3414+ /* Size of each block */
3415+ uint64_t size;
3416+ /* The base memory address of whole block */
3417+ void *base;
3418+ /* The number of elements in the pool at creation */
3419+ uint64_t starting_element_count;
3420+} cvmx_fpa_pool_info_t;
3421+
3422+/**
3423+ * Current state of all the pools. Use access functions
3424+ * instead of using it directly.
3425+ */
3426+extern cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
3427+
3428+/* CSR typedefs have been moved to cvmx-csr-*.h */
3429+
3430+/**
3431+ * Return the name of the pool
3432+ *
3433+ * @pool: Pool to get the name of
3434+ * Returns The name
3435+ */
3436+static inline const char *cvmx_fpa_get_name(uint64_t pool)
3437+{
3438+ return cvmx_fpa_pool_info[pool].name;
3439+}
3440+
3441+/**
3442+ * Return the base of the pool
3443+ *
3444+ * @pool: Pool to get the base of
3445+ * Returns The base
3446+ */
3447+static inline void *cvmx_fpa_get_base(uint64_t pool)
3448+{
3449+ return cvmx_fpa_pool_info[pool].base;
3450+}
3451+
3452+/**
3453+ * Check if a pointer belongs to an FPA pool. Return non-zero
3454+ * if the supplied pointer is inside the memory controlled by
3455+ * an FPA pool.
3456+ *
3457+ * @pool: Pool to check
3458+ * @ptr: Pointer to check
3459+ * Returns Non-zero if pointer is in the pool. Zero if not
3460+ */
3461+static inline int cvmx_fpa_is_member(uint64_t pool, void *ptr)
3462+{
3463+ return ((ptr >= cvmx_fpa_pool_info[pool].base) &&
3464+ ((char *)ptr <
3465+ ((char *)(cvmx_fpa_pool_info[pool].base)) +
3466+ cvmx_fpa_pool_info[pool].size *
3467+ cvmx_fpa_pool_info[pool].starting_element_count));
3468+}
3469+
3470+/**
3471+ * Enable the FPA for use. Must be performed after any CSR
3472+ * configuration but before any other FPA functions.
3473+ */
3474+static inline void cvmx_fpa_enable(void)
3475+{
3476+ union cvmx_fpa_ctl_status status;
3477+
3478+ status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
3479+ if (status.s.enb) {
3480+ cvmx_dprintf
3481+ ("Warning: Enabling FPA when FPA already enabled.\n");
3482+ }
3483+
3484+ /*
3485+ * Do runtime check as we allow pass1 compiled code to run on
3486+ * pass2 chips.
3487+ */
3488+ if (cvmx_octeon_is_pass1()) {
3489+ union cvmx_fpa_fpfx_marks marks;
3490+ int i;
3491+ for (i = 1; i < 8; i++) {
3492+ marks.u64 =
3493+ cvmx_read_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull);
3494+ marks.s.fpf_wr = 0xe0;
3495+ cvmx_write_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull,
3496+ marks.u64);
3497+ }
3498+
3499+ /* Enforce a 10 cycle delay between config and enable */
3500+ cvmx_wait(10);
3501+ }
3502+
3503+ /* FIXME: CVMX_FPA_CTL_STATUS read is unmodelled */
3504+ status.u64 = 0;
3505+ status.s.enb = 1;
3506+ cvmx_write_csr(CVMX_FPA_CTL_STATUS, status.u64);
3507+}
3508+
3509+/**
3510+ * Get a new block from the FPA
3511+ *
3512+ * @pool: Pool to get the block from
3513+ * Returns Pointer to the block or NULL on failure
3514+ */
3515+static inline void *cvmx_fpa_alloc(uint64_t pool)
3516+{
3517+ uint64_t address =
3518+ cvmx_read_csr(CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool)));
3519+ if (address)
3520+ return cvmx_phys_to_ptr(address);
3521+ else
3522+ return NULL;
3523+}
3524+
3525+/**
3526+ * Asynchronously get a new block from the FPA
3527+ *
3528+ * @scr_addr: Local scratch address to put response in. This is a byte address,
3529+ * but must be 8 byte aligned.
3530+ * @pool: Pool to get the block from
3531+ */
3532+static inline void cvmx_fpa_async_alloc(uint64_t scr_addr, uint64_t pool)
3533+{
3534+ cvmx_fpa_iobdma_data_t data;
3535+
3536+ /*
3537+ * Hardware only uses 64 bit alligned locations, so convert
3538+ * from byte address to 64-bit index
3539+ */
3540+ data.s.scraddr = scr_addr >> 3;
3541+ data.s.len = 1;
3542+ data.s.did = CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool);
3543+ data.s.addr = 0;
3544+ cvmx_send_single(data.u64);
3545+}
3546+
3547+/**
3548+ * Free a block allocated with a FPA pool. Does NOT provide memory
3549+ * ordering in cases where the memory block was modified by the core.
3550+ *
3551+ * @ptr: Block to free
3552+ * @pool: Pool to put it in
3553+ * @num_cache_lines:
3554+ * Cache lines to invalidate
3555+ */
3556+static inline void cvmx_fpa_free_nosync(void *ptr, uint64_t pool,
3557+ uint64_t num_cache_lines)
3558+{
3559+ cvmx_addr_t newptr;
3560+ newptr.u64 = cvmx_ptr_to_phys(ptr);
3561+ newptr.sfilldidspace.didspace =
3562+ CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool));
3563+ /* Prevent GCC from reordering around free */
3564+ barrier();
3565+ /* value written is number of cache lines not written back */
3566+ cvmx_write_io(newptr.u64, num_cache_lines);
3567+}
3568+
3569+/**
3570+ * Free a block allocated with a FPA pool. Provides required memory
3571+ * ordering in cases where memory block was modified by core.
3572+ *
3573+ * @ptr: Block to free
3574+ * @pool: Pool to put it in
3575+ * @num_cache_lines:
3576+ * Cache lines to invalidate
3577+ */
3578+static inline void cvmx_fpa_free(void *ptr, uint64_t pool,
3579+ uint64_t num_cache_lines)
3580+{
3581+ cvmx_addr_t newptr;
3582+ newptr.u64 = cvmx_ptr_to_phys(ptr);
3583+ newptr.sfilldidspace.didspace =
3584+ CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool));
3585+ /*
3586+ * Make sure that any previous writes to memory go out before
3587+ * we free this buffer. This also serves as a barrier to
3588+ * prevent GCC from reordering operations to after the
3589+ * free.
3590+ */
3591+ CVMX_SYNCWS;
3592+ /* value written is number of cache lines not written back */
3593+ cvmx_write_io(newptr.u64, num_cache_lines);
3594+}
3595+
3596+/**
3597+ * Setup a FPA pool to control a new block of memory.
3598+ * This can only be called once per pool. Make sure proper
3599+ * locking enforces this.
3600+ *
3601+ * @pool: Pool to initialize
3602+ * 0 <= pool < 8
3603+ * @name: Constant character string to name this pool.
3604+ * String is not copied.
3605+ * @buffer: Pointer to the block of memory to use. This must be
3606+ * accessable by all processors and external hardware.
3607+ * @block_size: Size for each block controlled by the FPA
3608+ * @num_blocks: Number of blocks
3609+ *
3610+ * Returns 0 on Success,
3611+ * -1 on failure
3612+ */
3613+extern int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
3614+ uint64_t block_size, uint64_t num_blocks);
3615+
3616+/**
3617+ * Shutdown a Memory pool and validate that it had all of
3618+ * the buffers originally placed in it. This should only be
3619+ * called by one processor after all hardware has finished
3620+ * using the pool.
3621+ *
3622+ * @pool: Pool to shutdown
3623+ * Returns Zero on success
3624+ * - Positive is count of missing buffers
3625+ * - Negative is too many buffers or corrupted pointers
3626+ */
3627+extern uint64_t cvmx_fpa_shutdown_pool(uint64_t pool);
3628+
3629+/**
3630+ * Get the size of blocks controlled by the pool
3631+ * This is resolved to a constant at compile time.
3632+ *
3633+ * @pool: Pool to access
3634+ * Returns Size of the block in bytes
3635+ */
3636+uint64_t cvmx_fpa_get_block_size(uint64_t pool);
3637+
3638+#endif /* __CVM_FPA_H__ */
3639--- /dev/null
3640+++ b/drivers/staging/octeon/cvmx-gmxx-defs.h
3641@@ -0,0 +1,2529 @@
3642+/***********************license start***************
3643+ * Author: Cavium Networks
3644+ *
3645+ * Contact: support@caviumnetworks.com
3646+ * This file is part of the OCTEON SDK
3647+ *
3648+ * Copyright (c) 2003-2008 Cavium Networks
3649+ *
3650+ * This file is free software; you can redistribute it and/or modify
3651+ * it under the terms of the GNU General Public License, Version 2, as
3652+ * published by the Free Software Foundation.
3653+ *
3654+ * This file is distributed in the hope that it will be useful, but
3655+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3656+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3657+ * NONINFRINGEMENT. See the GNU General Public License for more
3658+ * details.
3659+ *
3660+ * You should have received a copy of the GNU General Public License
3661+ * along with this file; if not, write to the Free Software
3662+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3663+ * or visit http://www.gnu.org/licenses/.
3664+ *
3665+ * This file may also be available under a different license from Cavium.
3666+ * Contact Cavium Networks for more information
3667+ ***********************license end**************************************/
3668+
3669+#ifndef __CVMX_GMXX_DEFS_H__
3670+#define __CVMX_GMXX_DEFS_H__
3671+
3672+#define CVMX_GMXX_BAD_REG(block_id) \
3673+ CVMX_ADD_IO_SEG(0x0001180008000518ull + (((block_id) & 1) * 0x8000000ull))
3674+#define CVMX_GMXX_BIST(block_id) \
3675+ CVMX_ADD_IO_SEG(0x0001180008000400ull + (((block_id) & 1) * 0x8000000ull))
3676+#define CVMX_GMXX_CLK_EN(block_id) \
3677+ CVMX_ADD_IO_SEG(0x00011800080007F0ull + (((block_id) & 1) * 0x8000000ull))
3678+#define CVMX_GMXX_HG2_CONTROL(block_id) \
3679+ CVMX_ADD_IO_SEG(0x0001180008000550ull + (((block_id) & 1) * 0x8000000ull))
3680+#define CVMX_GMXX_INF_MODE(block_id) \
3681+ CVMX_ADD_IO_SEG(0x00011800080007F8ull + (((block_id) & 1) * 0x8000000ull))
3682+#define CVMX_GMXX_NXA_ADR(block_id) \
3683+ CVMX_ADD_IO_SEG(0x0001180008000510ull + (((block_id) & 1) * 0x8000000ull))
3684+#define CVMX_GMXX_PRTX_CBFC_CTL(offset, block_id) \
3685+ CVMX_ADD_IO_SEG(0x0001180008000580ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3686+#define CVMX_GMXX_PRTX_CFG(offset, block_id) \
3687+ CVMX_ADD_IO_SEG(0x0001180008000010ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3688+#define CVMX_GMXX_RXX_ADR_CAM0(offset, block_id) \
3689+ CVMX_ADD_IO_SEG(0x0001180008000180ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3690+#define CVMX_GMXX_RXX_ADR_CAM1(offset, block_id) \
3691+ CVMX_ADD_IO_SEG(0x0001180008000188ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3692+#define CVMX_GMXX_RXX_ADR_CAM2(offset, block_id) \
3693+ CVMX_ADD_IO_SEG(0x0001180008000190ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3694+#define CVMX_GMXX_RXX_ADR_CAM3(offset, block_id) \
3695+ CVMX_ADD_IO_SEG(0x0001180008000198ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3696+#define CVMX_GMXX_RXX_ADR_CAM4(offset, block_id) \
3697+ CVMX_ADD_IO_SEG(0x00011800080001A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3698+#define CVMX_GMXX_RXX_ADR_CAM5(offset, block_id) \
3699+ CVMX_ADD_IO_SEG(0x00011800080001A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3700+#define CVMX_GMXX_RXX_ADR_CAM_EN(offset, block_id) \
3701+ CVMX_ADD_IO_SEG(0x0001180008000108ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3702+#define CVMX_GMXX_RXX_ADR_CTL(offset, block_id) \
3703+ CVMX_ADD_IO_SEG(0x0001180008000100ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3704+#define CVMX_GMXX_RXX_DECISION(offset, block_id) \
3705+ CVMX_ADD_IO_SEG(0x0001180008000040ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3706+#define CVMX_GMXX_RXX_FRM_CHK(offset, block_id) \
3707+ CVMX_ADD_IO_SEG(0x0001180008000020ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3708+#define CVMX_GMXX_RXX_FRM_CTL(offset, block_id) \
3709+ CVMX_ADD_IO_SEG(0x0001180008000018ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3710+#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) \
3711+ CVMX_ADD_IO_SEG(0x0001180008000030ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3712+#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) \
3713+ CVMX_ADD_IO_SEG(0x0001180008000028ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3714+#define CVMX_GMXX_RXX_IFG(offset, block_id) \
3715+ CVMX_ADD_IO_SEG(0x0001180008000058ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3716+#define CVMX_GMXX_RXX_INT_EN(offset, block_id) \
3717+ CVMX_ADD_IO_SEG(0x0001180008000008ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3718+#define CVMX_GMXX_RXX_INT_REG(offset, block_id) \
3719+ CVMX_ADD_IO_SEG(0x0001180008000000ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3720+#define CVMX_GMXX_RXX_JABBER(offset, block_id) \
3721+ CVMX_ADD_IO_SEG(0x0001180008000038ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3722+#define CVMX_GMXX_RXX_PAUSE_DROP_TIME(offset, block_id) \
3723+ CVMX_ADD_IO_SEG(0x0001180008000068ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3724+#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) \
3725+ CVMX_ADD_IO_SEG(0x0001180008000060ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3726+#define CVMX_GMXX_RXX_STATS_CTL(offset, block_id) \
3727+ CVMX_ADD_IO_SEG(0x0001180008000050ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3728+#define CVMX_GMXX_RXX_STATS_OCTS(offset, block_id) \
3729+ CVMX_ADD_IO_SEG(0x0001180008000088ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3730+#define CVMX_GMXX_RXX_STATS_OCTS_CTL(offset, block_id) \
3731+ CVMX_ADD_IO_SEG(0x0001180008000098ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3732+#define CVMX_GMXX_RXX_STATS_OCTS_DMAC(offset, block_id) \
3733+ CVMX_ADD_IO_SEG(0x00011800080000A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3734+#define CVMX_GMXX_RXX_STATS_OCTS_DRP(offset, block_id) \
3735+ CVMX_ADD_IO_SEG(0x00011800080000B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3736+#define CVMX_GMXX_RXX_STATS_PKTS(offset, block_id) \
3737+ CVMX_ADD_IO_SEG(0x0001180008000080ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3738+#define CVMX_GMXX_RXX_STATS_PKTS_BAD(offset, block_id) \
3739+ CVMX_ADD_IO_SEG(0x00011800080000C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3740+#define CVMX_GMXX_RXX_STATS_PKTS_CTL(offset, block_id) \
3741+ CVMX_ADD_IO_SEG(0x0001180008000090ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3742+#define CVMX_GMXX_RXX_STATS_PKTS_DMAC(offset, block_id) \
3743+ CVMX_ADD_IO_SEG(0x00011800080000A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3744+#define CVMX_GMXX_RXX_STATS_PKTS_DRP(offset, block_id) \
3745+ CVMX_ADD_IO_SEG(0x00011800080000B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3746+#define CVMX_GMXX_RXX_UDD_SKP(offset, block_id) \
3747+ CVMX_ADD_IO_SEG(0x0001180008000048ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3748+#define CVMX_GMXX_RX_BP_DROPX(offset, block_id) \
3749+ CVMX_ADD_IO_SEG(0x0001180008000420ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3750+#define CVMX_GMXX_RX_BP_OFFX(offset, block_id) \
3751+ CVMX_ADD_IO_SEG(0x0001180008000460ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3752+#define CVMX_GMXX_RX_BP_ONX(offset, block_id) \
3753+ CVMX_ADD_IO_SEG(0x0001180008000440ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3754+#define CVMX_GMXX_RX_HG2_STATUS(block_id) \
3755+ CVMX_ADD_IO_SEG(0x0001180008000548ull + (((block_id) & 1) * 0x8000000ull))
3756+#define CVMX_GMXX_RX_PASS_EN(block_id) \
3757+ CVMX_ADD_IO_SEG(0x00011800080005F8ull + (((block_id) & 1) * 0x8000000ull))
3758+#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) \
3759+ CVMX_ADD_IO_SEG(0x0001180008000600ull + (((offset) & 15) * 8) + (((block_id) & 1) * 0x8000000ull))
3760+#define CVMX_GMXX_RX_PRTS(block_id) \
3761+ CVMX_ADD_IO_SEG(0x0001180008000410ull + (((block_id) & 1) * 0x8000000ull))
3762+#define CVMX_GMXX_RX_PRT_INFO(block_id) \
3763+ CVMX_ADD_IO_SEG(0x00011800080004E8ull + (((block_id) & 1) * 0x8000000ull))
3764+#define CVMX_GMXX_RX_TX_STATUS(block_id) \
3765+ CVMX_ADD_IO_SEG(0x00011800080007E8ull + (((block_id) & 0) * 0x8000000ull))
3766+#define CVMX_GMXX_RX_XAUI_BAD_COL(block_id) \
3767+ CVMX_ADD_IO_SEG(0x0001180008000538ull + (((block_id) & 1) * 0x8000000ull))
3768+#define CVMX_GMXX_RX_XAUI_CTL(block_id) \
3769+ CVMX_ADD_IO_SEG(0x0001180008000530ull + (((block_id) & 1) * 0x8000000ull))
3770+#define CVMX_GMXX_SMACX(offset, block_id) \
3771+ CVMX_ADD_IO_SEG(0x0001180008000230ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3772+#define CVMX_GMXX_STAT_BP(block_id) \
3773+ CVMX_ADD_IO_SEG(0x0001180008000520ull + (((block_id) & 1) * 0x8000000ull))
3774+#define CVMX_GMXX_TXX_APPEND(offset, block_id) \
3775+ CVMX_ADD_IO_SEG(0x0001180008000218ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3776+#define CVMX_GMXX_TXX_BURST(offset, block_id) \
3777+ CVMX_ADD_IO_SEG(0x0001180008000228ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3778+#define CVMX_GMXX_TXX_CBFC_XOFF(offset, block_id) \
3779+ CVMX_ADD_IO_SEG(0x00011800080005A0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3780+#define CVMX_GMXX_TXX_CBFC_XON(offset, block_id) \
3781+ CVMX_ADD_IO_SEG(0x00011800080005C0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3782+#define CVMX_GMXX_TXX_CLK(offset, block_id) \
3783+ CVMX_ADD_IO_SEG(0x0001180008000208ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3784+#define CVMX_GMXX_TXX_CTL(offset, block_id) \
3785+ CVMX_ADD_IO_SEG(0x0001180008000270ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3786+#define CVMX_GMXX_TXX_MIN_PKT(offset, block_id) \
3787+ CVMX_ADD_IO_SEG(0x0001180008000240ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3788+#define CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(offset, block_id) \
3789+ CVMX_ADD_IO_SEG(0x0001180008000248ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3790+#define CVMX_GMXX_TXX_PAUSE_PKT_TIME(offset, block_id) \
3791+ CVMX_ADD_IO_SEG(0x0001180008000238ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3792+#define CVMX_GMXX_TXX_PAUSE_TOGO(offset, block_id) \
3793+ CVMX_ADD_IO_SEG(0x0001180008000258ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3794+#define CVMX_GMXX_TXX_PAUSE_ZERO(offset, block_id) \
3795+ CVMX_ADD_IO_SEG(0x0001180008000260ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3796+#define CVMX_GMXX_TXX_SGMII_CTL(offset, block_id) \
3797+ CVMX_ADD_IO_SEG(0x0001180008000300ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3798+#define CVMX_GMXX_TXX_SLOT(offset, block_id) \
3799+ CVMX_ADD_IO_SEG(0x0001180008000220ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3800+#define CVMX_GMXX_TXX_SOFT_PAUSE(offset, block_id) \
3801+ CVMX_ADD_IO_SEG(0x0001180008000250ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3802+#define CVMX_GMXX_TXX_STAT0(offset, block_id) \
3803+ CVMX_ADD_IO_SEG(0x0001180008000280ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3804+#define CVMX_GMXX_TXX_STAT1(offset, block_id) \
3805+ CVMX_ADD_IO_SEG(0x0001180008000288ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3806+#define CVMX_GMXX_TXX_STAT2(offset, block_id) \
3807+ CVMX_ADD_IO_SEG(0x0001180008000290ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3808+#define CVMX_GMXX_TXX_STAT3(offset, block_id) \
3809+ CVMX_ADD_IO_SEG(0x0001180008000298ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3810+#define CVMX_GMXX_TXX_STAT4(offset, block_id) \
3811+ CVMX_ADD_IO_SEG(0x00011800080002A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3812+#define CVMX_GMXX_TXX_STAT5(offset, block_id) \
3813+ CVMX_ADD_IO_SEG(0x00011800080002A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3814+#define CVMX_GMXX_TXX_STAT6(offset, block_id) \
3815+ CVMX_ADD_IO_SEG(0x00011800080002B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3816+#define CVMX_GMXX_TXX_STAT7(offset, block_id) \
3817+ CVMX_ADD_IO_SEG(0x00011800080002B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3818+#define CVMX_GMXX_TXX_STAT8(offset, block_id) \
3819+ CVMX_ADD_IO_SEG(0x00011800080002C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3820+#define CVMX_GMXX_TXX_STAT9(offset, block_id) \
3821+ CVMX_ADD_IO_SEG(0x00011800080002C8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3822+#define CVMX_GMXX_TXX_STATS_CTL(offset, block_id) \
3823+ CVMX_ADD_IO_SEG(0x0001180008000268ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3824+#define CVMX_GMXX_TXX_THRESH(offset, block_id) \
3825+ CVMX_ADD_IO_SEG(0x0001180008000210ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3826+#define CVMX_GMXX_TX_BP(block_id) \
3827+ CVMX_ADD_IO_SEG(0x00011800080004D0ull + (((block_id) & 1) * 0x8000000ull))
3828+#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) \
3829+ CVMX_ADD_IO_SEG(0x0001180008000780ull + (((offset) & 1) * 8) + (((block_id) & 0) * 0x0ull))
3830+#define CVMX_GMXX_TX_COL_ATTEMPT(block_id) \
3831+ CVMX_ADD_IO_SEG(0x0001180008000498ull + (((block_id) & 1) * 0x8000000ull))
3832+#define CVMX_GMXX_TX_CORRUPT(block_id) \
3833+ CVMX_ADD_IO_SEG(0x00011800080004D8ull + (((block_id) & 1) * 0x8000000ull))
3834+#define CVMX_GMXX_TX_HG2_REG1(block_id) \
3835+ CVMX_ADD_IO_SEG(0x0001180008000558ull + (((block_id) & 1) * 0x8000000ull))
3836+#define CVMX_GMXX_TX_HG2_REG2(block_id) \
3837+ CVMX_ADD_IO_SEG(0x0001180008000560ull + (((block_id) & 1) * 0x8000000ull))
3838+#define CVMX_GMXX_TX_IFG(block_id) \
3839+ CVMX_ADD_IO_SEG(0x0001180008000488ull + (((block_id) & 1) * 0x8000000ull))
3840+#define CVMX_GMXX_TX_INT_EN(block_id) \
3841+ CVMX_ADD_IO_SEG(0x0001180008000508ull + (((block_id) & 1) * 0x8000000ull))
3842+#define CVMX_GMXX_TX_INT_REG(block_id) \
3843+ CVMX_ADD_IO_SEG(0x0001180008000500ull + (((block_id) & 1) * 0x8000000ull))
3844+#define CVMX_GMXX_TX_JAM(block_id) \
3845+ CVMX_ADD_IO_SEG(0x0001180008000490ull + (((block_id) & 1) * 0x8000000ull))
3846+#define CVMX_GMXX_TX_LFSR(block_id) \
3847+ CVMX_ADD_IO_SEG(0x00011800080004F8ull + (((block_id) & 1) * 0x8000000ull))
3848+#define CVMX_GMXX_TX_OVR_BP(block_id) \
3849+ CVMX_ADD_IO_SEG(0x00011800080004C8ull + (((block_id) & 1) * 0x8000000ull))
3850+#define CVMX_GMXX_TX_PAUSE_PKT_DMAC(block_id) \
3851+ CVMX_ADD_IO_SEG(0x00011800080004A0ull + (((block_id) & 1) * 0x8000000ull))
3852+#define CVMX_GMXX_TX_PAUSE_PKT_TYPE(block_id) \
3853+ CVMX_ADD_IO_SEG(0x00011800080004A8ull + (((block_id) & 1) * 0x8000000ull))
3854+#define CVMX_GMXX_TX_PRTS(block_id) \
3855+ CVMX_ADD_IO_SEG(0x0001180008000480ull + (((block_id) & 1) * 0x8000000ull))
3856+#define CVMX_GMXX_TX_SPI_CTL(block_id) \
3857+ CVMX_ADD_IO_SEG(0x00011800080004C0ull + (((block_id) & 1) * 0x8000000ull))
3858+#define CVMX_GMXX_TX_SPI_DRAIN(block_id) \
3859+ CVMX_ADD_IO_SEG(0x00011800080004E0ull + (((block_id) & 1) * 0x8000000ull))
3860+#define CVMX_GMXX_TX_SPI_MAX(block_id) \
3861+ CVMX_ADD_IO_SEG(0x00011800080004B0ull + (((block_id) & 1) * 0x8000000ull))
3862+#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) \
3863+ CVMX_ADD_IO_SEG(0x0001180008000680ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
3864+#define CVMX_GMXX_TX_SPI_THRESH(block_id) \
3865+ CVMX_ADD_IO_SEG(0x00011800080004B8ull + (((block_id) & 1) * 0x8000000ull))
3866+#define CVMX_GMXX_TX_XAUI_CTL(block_id) \
3867+ CVMX_ADD_IO_SEG(0x0001180008000528ull + (((block_id) & 1) * 0x8000000ull))
3868+#define CVMX_GMXX_XAUI_EXT_LOOPBACK(block_id) \
3869+ CVMX_ADD_IO_SEG(0x0001180008000540ull + (((block_id) & 1) * 0x8000000ull))
3870+
3871+union cvmx_gmxx_bad_reg {
3872+ uint64_t u64;
3873+ struct cvmx_gmxx_bad_reg_s {
3874+ uint64_t reserved_31_63:33;
3875+ uint64_t inb_nxa:4;
3876+ uint64_t statovr:1;
3877+ uint64_t loststat:4;
3878+ uint64_t reserved_18_21:4;
3879+ uint64_t out_ovr:16;
3880+ uint64_t ncb_ovr:1;
3881+ uint64_t out_col:1;
3882+ } s;
3883+ struct cvmx_gmxx_bad_reg_cn30xx {
3884+ uint64_t reserved_31_63:33;
3885+ uint64_t inb_nxa:4;
3886+ uint64_t statovr:1;
3887+ uint64_t reserved_25_25:1;
3888+ uint64_t loststat:3;
3889+ uint64_t reserved_5_21:17;
3890+ uint64_t out_ovr:3;
3891+ uint64_t reserved_0_1:2;
3892+ } cn30xx;
3893+ struct cvmx_gmxx_bad_reg_cn30xx cn31xx;
3894+ struct cvmx_gmxx_bad_reg_s cn38xx;
3895+ struct cvmx_gmxx_bad_reg_s cn38xxp2;
3896+ struct cvmx_gmxx_bad_reg_cn30xx cn50xx;
3897+ struct cvmx_gmxx_bad_reg_cn52xx {
3898+ uint64_t reserved_31_63:33;
3899+ uint64_t inb_nxa:4;
3900+ uint64_t statovr:1;
3901+ uint64_t loststat:4;
3902+ uint64_t reserved_6_21:16;
3903+ uint64_t out_ovr:4;
3904+ uint64_t reserved_0_1:2;
3905+ } cn52xx;
3906+ struct cvmx_gmxx_bad_reg_cn52xx cn52xxp1;
3907+ struct cvmx_gmxx_bad_reg_cn52xx cn56xx;
3908+ struct cvmx_gmxx_bad_reg_cn52xx cn56xxp1;
3909+ struct cvmx_gmxx_bad_reg_s cn58xx;
3910+ struct cvmx_gmxx_bad_reg_s cn58xxp1;
3911+};
3912+
3913+union cvmx_gmxx_bist {
3914+ uint64_t u64;
3915+ struct cvmx_gmxx_bist_s {
3916+ uint64_t reserved_17_63:47;
3917+ uint64_t status:17;
3918+ } s;
3919+ struct cvmx_gmxx_bist_cn30xx {
3920+ uint64_t reserved_10_63:54;
3921+ uint64_t status:10;
3922+ } cn30xx;
3923+ struct cvmx_gmxx_bist_cn30xx cn31xx;
3924+ struct cvmx_gmxx_bist_cn30xx cn38xx;
3925+ struct cvmx_gmxx_bist_cn30xx cn38xxp2;
3926+ struct cvmx_gmxx_bist_cn50xx {
3927+ uint64_t reserved_12_63:52;
3928+ uint64_t status:12;
3929+ } cn50xx;
3930+ struct cvmx_gmxx_bist_cn52xx {
3931+ uint64_t reserved_16_63:48;
3932+ uint64_t status:16;
3933+ } cn52xx;
3934+ struct cvmx_gmxx_bist_cn52xx cn52xxp1;
3935+ struct cvmx_gmxx_bist_cn52xx cn56xx;
3936+ struct cvmx_gmxx_bist_cn52xx cn56xxp1;
3937+ struct cvmx_gmxx_bist_s cn58xx;
3938+ struct cvmx_gmxx_bist_s cn58xxp1;
3939+};
3940+
3941+union cvmx_gmxx_clk_en {
3942+ uint64_t u64;
3943+ struct cvmx_gmxx_clk_en_s {
3944+ uint64_t reserved_1_63:63;
3945+ uint64_t clk_en:1;
3946+ } s;
3947+ struct cvmx_gmxx_clk_en_s cn52xx;
3948+ struct cvmx_gmxx_clk_en_s cn52xxp1;
3949+ struct cvmx_gmxx_clk_en_s cn56xx;
3950+ struct cvmx_gmxx_clk_en_s cn56xxp1;
3951+};
3952+
3953+union cvmx_gmxx_hg2_control {
3954+ uint64_t u64;
3955+ struct cvmx_gmxx_hg2_control_s {
3956+ uint64_t reserved_19_63:45;
3957+ uint64_t hg2tx_en:1;
3958+ uint64_t hg2rx_en:1;
3959+ uint64_t phys_en:1;
3960+ uint64_t logl_en:16;
3961+ } s;
3962+ struct cvmx_gmxx_hg2_control_s cn52xx;
3963+ struct cvmx_gmxx_hg2_control_s cn52xxp1;
3964+ struct cvmx_gmxx_hg2_control_s cn56xx;
3965+};
3966+
3967+union cvmx_gmxx_inf_mode {
3968+ uint64_t u64;
3969+ struct cvmx_gmxx_inf_mode_s {
3970+ uint64_t reserved_10_63:54;
3971+ uint64_t speed:2;
3972+ uint64_t reserved_6_7:2;
3973+ uint64_t mode:2;
3974+ uint64_t reserved_3_3:1;
3975+ uint64_t p0mii:1;
3976+ uint64_t en:1;
3977+ uint64_t type:1;
3978+ } s;
3979+ struct cvmx_gmxx_inf_mode_cn30xx {
3980+ uint64_t reserved_3_63:61;
3981+ uint64_t p0mii:1;
3982+ uint64_t en:1;
3983+ uint64_t type:1;
3984+ } cn30xx;
3985+ struct cvmx_gmxx_inf_mode_cn31xx {
3986+ uint64_t reserved_2_63:62;
3987+ uint64_t en:1;
3988+ uint64_t type:1;
3989+ } cn31xx;
3990+ struct cvmx_gmxx_inf_mode_cn31xx cn38xx;
3991+ struct cvmx_gmxx_inf_mode_cn31xx cn38xxp2;
3992+ struct cvmx_gmxx_inf_mode_cn30xx cn50xx;
3993+ struct cvmx_gmxx_inf_mode_cn52xx {
3994+ uint64_t reserved_10_63:54;
3995+ uint64_t speed:2;
3996+ uint64_t reserved_6_7:2;
3997+ uint64_t mode:2;
3998+ uint64_t reserved_2_3:2;
3999+ uint64_t en:1;
4000+ uint64_t type:1;
4001+ } cn52xx;
4002+ struct cvmx_gmxx_inf_mode_cn52xx cn52xxp1;
4003+ struct cvmx_gmxx_inf_mode_cn52xx cn56xx;
4004+ struct cvmx_gmxx_inf_mode_cn52xx cn56xxp1;
4005+ struct cvmx_gmxx_inf_mode_cn31xx cn58xx;
4006+ struct cvmx_gmxx_inf_mode_cn31xx cn58xxp1;
4007+};
4008+
4009+union cvmx_gmxx_nxa_adr {
4010+ uint64_t u64;
4011+ struct cvmx_gmxx_nxa_adr_s {
4012+ uint64_t reserved_6_63:58;
4013+ uint64_t prt:6;
4014+ } s;
4015+ struct cvmx_gmxx_nxa_adr_s cn30xx;
4016+ struct cvmx_gmxx_nxa_adr_s cn31xx;
4017+ struct cvmx_gmxx_nxa_adr_s cn38xx;
4018+ struct cvmx_gmxx_nxa_adr_s cn38xxp2;
4019+ struct cvmx_gmxx_nxa_adr_s cn50xx;
4020+ struct cvmx_gmxx_nxa_adr_s cn52xx;
4021+ struct cvmx_gmxx_nxa_adr_s cn52xxp1;
4022+ struct cvmx_gmxx_nxa_adr_s cn56xx;
4023+ struct cvmx_gmxx_nxa_adr_s cn56xxp1;
4024+ struct cvmx_gmxx_nxa_adr_s cn58xx;
4025+ struct cvmx_gmxx_nxa_adr_s cn58xxp1;
4026+};
4027+
4028+union cvmx_gmxx_prtx_cbfc_ctl {
4029+ uint64_t u64;
4030+ struct cvmx_gmxx_prtx_cbfc_ctl_s {
4031+ uint64_t phys_en:16;
4032+ uint64_t logl_en:16;
4033+ uint64_t phys_bp:16;
4034+ uint64_t reserved_4_15:12;
4035+ uint64_t bck_en:1;
4036+ uint64_t drp_en:1;
4037+ uint64_t tx_en:1;
4038+ uint64_t rx_en:1;
4039+ } s;
4040+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn52xx;
4041+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn56xx;
4042+};
4043+
4044+union cvmx_gmxx_prtx_cfg {
4045+ uint64_t u64;
4046+ struct cvmx_gmxx_prtx_cfg_s {
4047+ uint64_t reserved_14_63:50;
4048+ uint64_t tx_idle:1;
4049+ uint64_t rx_idle:1;
4050+ uint64_t reserved_9_11:3;
4051+ uint64_t speed_msb:1;
4052+ uint64_t reserved_4_7:4;
4053+ uint64_t slottime:1;
4054+ uint64_t duplex:1;
4055+ uint64_t speed:1;
4056+ uint64_t en:1;
4057+ } s;
4058+ struct cvmx_gmxx_prtx_cfg_cn30xx {
4059+ uint64_t reserved_4_63:60;
4060+ uint64_t slottime:1;
4061+ uint64_t duplex:1;
4062+ uint64_t speed:1;
4063+ uint64_t en:1;
4064+ } cn30xx;
4065+ struct cvmx_gmxx_prtx_cfg_cn30xx cn31xx;
4066+ struct cvmx_gmxx_prtx_cfg_cn30xx cn38xx;
4067+ struct cvmx_gmxx_prtx_cfg_cn30xx cn38xxp2;
4068+ struct cvmx_gmxx_prtx_cfg_cn30xx cn50xx;
4069+ struct cvmx_gmxx_prtx_cfg_s cn52xx;
4070+ struct cvmx_gmxx_prtx_cfg_s cn52xxp1;
4071+ struct cvmx_gmxx_prtx_cfg_s cn56xx;
4072+ struct cvmx_gmxx_prtx_cfg_s cn56xxp1;
4073+ struct cvmx_gmxx_prtx_cfg_cn30xx cn58xx;
4074+ struct cvmx_gmxx_prtx_cfg_cn30xx cn58xxp1;
4075+};
4076+
4077+union cvmx_gmxx_rxx_adr_cam0 {
4078+ uint64_t u64;
4079+ struct cvmx_gmxx_rxx_adr_cam0_s {
4080+ uint64_t adr:64;
4081+ } s;
4082+ struct cvmx_gmxx_rxx_adr_cam0_s cn30xx;
4083+ struct cvmx_gmxx_rxx_adr_cam0_s cn31xx;
4084+ struct cvmx_gmxx_rxx_adr_cam0_s cn38xx;
4085+ struct cvmx_gmxx_rxx_adr_cam0_s cn38xxp2;
4086+ struct cvmx_gmxx_rxx_adr_cam0_s cn50xx;
4087+ struct cvmx_gmxx_rxx_adr_cam0_s cn52xx;
4088+ struct cvmx_gmxx_rxx_adr_cam0_s cn52xxp1;
4089+ struct cvmx_gmxx_rxx_adr_cam0_s cn56xx;
4090+ struct cvmx_gmxx_rxx_adr_cam0_s cn56xxp1;
4091+ struct cvmx_gmxx_rxx_adr_cam0_s cn58xx;
4092+ struct cvmx_gmxx_rxx_adr_cam0_s cn58xxp1;
4093+};
4094+
4095+union cvmx_gmxx_rxx_adr_cam1 {
4096+ uint64_t u64;
4097+ struct cvmx_gmxx_rxx_adr_cam1_s {
4098+ uint64_t adr:64;
4099+ } s;
4100+ struct cvmx_gmxx_rxx_adr_cam1_s cn30xx;
4101+ struct cvmx_gmxx_rxx_adr_cam1_s cn31xx;
4102+ struct cvmx_gmxx_rxx_adr_cam1_s cn38xx;
4103+ struct cvmx_gmxx_rxx_adr_cam1_s cn38xxp2;
4104+ struct cvmx_gmxx_rxx_adr_cam1_s cn50xx;
4105+ struct cvmx_gmxx_rxx_adr_cam1_s cn52xx;
4106+ struct cvmx_gmxx_rxx_adr_cam1_s cn52xxp1;
4107+ struct cvmx_gmxx_rxx_adr_cam1_s cn56xx;
4108+ struct cvmx_gmxx_rxx_adr_cam1_s cn56xxp1;
4109+ struct cvmx_gmxx_rxx_adr_cam1_s cn58xx;
4110+ struct cvmx_gmxx_rxx_adr_cam1_s cn58xxp1;
4111+};
4112+
4113+union cvmx_gmxx_rxx_adr_cam2 {
4114+ uint64_t u64;
4115+ struct cvmx_gmxx_rxx_adr_cam2_s {
4116+ uint64_t adr:64;
4117+ } s;
4118+ struct cvmx_gmxx_rxx_adr_cam2_s cn30xx;
4119+ struct cvmx_gmxx_rxx_adr_cam2_s cn31xx;
4120+ struct cvmx_gmxx_rxx_adr_cam2_s cn38xx;
4121+ struct cvmx_gmxx_rxx_adr_cam2_s cn38xxp2;
4122+ struct cvmx_gmxx_rxx_adr_cam2_s cn50xx;
4123+ struct cvmx_gmxx_rxx_adr_cam2_s cn52xx;
4124+ struct cvmx_gmxx_rxx_adr_cam2_s cn52xxp1;
4125+ struct cvmx_gmxx_rxx_adr_cam2_s cn56xx;
4126+ struct cvmx_gmxx_rxx_adr_cam2_s cn56xxp1;
4127+ struct cvmx_gmxx_rxx_adr_cam2_s cn58xx;
4128+ struct cvmx_gmxx_rxx_adr_cam2_s cn58xxp1;
4129+};
4130+
4131+union cvmx_gmxx_rxx_adr_cam3 {
4132+ uint64_t u64;
4133+ struct cvmx_gmxx_rxx_adr_cam3_s {
4134+ uint64_t adr:64;
4135+ } s;
4136+ struct cvmx_gmxx_rxx_adr_cam3_s cn30xx;
4137+ struct cvmx_gmxx_rxx_adr_cam3_s cn31xx;
4138+ struct cvmx_gmxx_rxx_adr_cam3_s cn38xx;
4139+ struct cvmx_gmxx_rxx_adr_cam3_s cn38xxp2;
4140+ struct cvmx_gmxx_rxx_adr_cam3_s cn50xx;
4141+ struct cvmx_gmxx_rxx_adr_cam3_s cn52xx;
4142+ struct cvmx_gmxx_rxx_adr_cam3_s cn52xxp1;
4143+ struct cvmx_gmxx_rxx_adr_cam3_s cn56xx;
4144+ struct cvmx_gmxx_rxx_adr_cam3_s cn56xxp1;
4145+ struct cvmx_gmxx_rxx_adr_cam3_s cn58xx;
4146+ struct cvmx_gmxx_rxx_adr_cam3_s cn58xxp1;
4147+};
4148+
4149+union cvmx_gmxx_rxx_adr_cam4 {
4150+ uint64_t u64;
4151+ struct cvmx_gmxx_rxx_adr_cam4_s {
4152+ uint64_t adr:64;
4153+ } s;
4154+ struct cvmx_gmxx_rxx_adr_cam4_s cn30xx;
4155+ struct cvmx_gmxx_rxx_adr_cam4_s cn31xx;
4156+ struct cvmx_gmxx_rxx_adr_cam4_s cn38xx;
4157+ struct cvmx_gmxx_rxx_adr_cam4_s cn38xxp2;
4158+ struct cvmx_gmxx_rxx_adr_cam4_s cn50xx;
4159+ struct cvmx_gmxx_rxx_adr_cam4_s cn52xx;
4160+ struct cvmx_gmxx_rxx_adr_cam4_s cn52xxp1;
4161+ struct cvmx_gmxx_rxx_adr_cam4_s cn56xx;
4162+ struct cvmx_gmxx_rxx_adr_cam4_s cn56xxp1;
4163+ struct cvmx_gmxx_rxx_adr_cam4_s cn58xx;
4164+ struct cvmx_gmxx_rxx_adr_cam4_s cn58xxp1;
4165+};
4166+
4167+union cvmx_gmxx_rxx_adr_cam5 {
4168+ uint64_t u64;
4169+ struct cvmx_gmxx_rxx_adr_cam5_s {
4170+ uint64_t adr:64;
4171+ } s;
4172+ struct cvmx_gmxx_rxx_adr_cam5_s cn30xx;
4173+ struct cvmx_gmxx_rxx_adr_cam5_s cn31xx;
4174+ struct cvmx_gmxx_rxx_adr_cam5_s cn38xx;
4175+ struct cvmx_gmxx_rxx_adr_cam5_s cn38xxp2;
4176+ struct cvmx_gmxx_rxx_adr_cam5_s cn50xx;
4177+ struct cvmx_gmxx_rxx_adr_cam5_s cn52xx;
4178+ struct cvmx_gmxx_rxx_adr_cam5_s cn52xxp1;
4179+ struct cvmx_gmxx_rxx_adr_cam5_s cn56xx;
4180+ struct cvmx_gmxx_rxx_adr_cam5_s cn56xxp1;
4181+ struct cvmx_gmxx_rxx_adr_cam5_s cn58xx;
4182+ struct cvmx_gmxx_rxx_adr_cam5_s cn58xxp1;
4183+};
4184+
4185+union cvmx_gmxx_rxx_adr_cam_en {
4186+ uint64_t u64;
4187+ struct cvmx_gmxx_rxx_adr_cam_en_s {
4188+ uint64_t reserved_8_63:56;
4189+ uint64_t en:8;
4190+ } s;
4191+ struct cvmx_gmxx_rxx_adr_cam_en_s cn30xx;
4192+ struct cvmx_gmxx_rxx_adr_cam_en_s cn31xx;
4193+ struct cvmx_gmxx_rxx_adr_cam_en_s cn38xx;
4194+ struct cvmx_gmxx_rxx_adr_cam_en_s cn38xxp2;
4195+ struct cvmx_gmxx_rxx_adr_cam_en_s cn50xx;
4196+ struct cvmx_gmxx_rxx_adr_cam_en_s cn52xx;
4197+ struct cvmx_gmxx_rxx_adr_cam_en_s cn52xxp1;
4198+ struct cvmx_gmxx_rxx_adr_cam_en_s cn56xx;
4199+ struct cvmx_gmxx_rxx_adr_cam_en_s cn56xxp1;
4200+ struct cvmx_gmxx_rxx_adr_cam_en_s cn58xx;
4201+ struct cvmx_gmxx_rxx_adr_cam_en_s cn58xxp1;
4202+};
4203+
4204+union cvmx_gmxx_rxx_adr_ctl {
4205+ uint64_t u64;
4206+ struct cvmx_gmxx_rxx_adr_ctl_s {
4207+ uint64_t reserved_4_63:60;
4208+ uint64_t cam_mode:1;
4209+ uint64_t mcst:2;
4210+ uint64_t bcst:1;
4211+ } s;
4212+ struct cvmx_gmxx_rxx_adr_ctl_s cn30xx;
4213+ struct cvmx_gmxx_rxx_adr_ctl_s cn31xx;
4214+ struct cvmx_gmxx_rxx_adr_ctl_s cn38xx;
4215+ struct cvmx_gmxx_rxx_adr_ctl_s cn38xxp2;
4216+ struct cvmx_gmxx_rxx_adr_ctl_s cn50xx;
4217+ struct cvmx_gmxx_rxx_adr_ctl_s cn52xx;
4218+ struct cvmx_gmxx_rxx_adr_ctl_s cn52xxp1;
4219+ struct cvmx_gmxx_rxx_adr_ctl_s cn56xx;
4220+ struct cvmx_gmxx_rxx_adr_ctl_s cn56xxp1;
4221+ struct cvmx_gmxx_rxx_adr_ctl_s cn58xx;
4222+ struct cvmx_gmxx_rxx_adr_ctl_s cn58xxp1;
4223+};
4224+
4225+union cvmx_gmxx_rxx_decision {
4226+ uint64_t u64;
4227+ struct cvmx_gmxx_rxx_decision_s {
4228+ uint64_t reserved_5_63:59;
4229+ uint64_t cnt:5;
4230+ } s;
4231+ struct cvmx_gmxx_rxx_decision_s cn30xx;
4232+ struct cvmx_gmxx_rxx_decision_s cn31xx;
4233+ struct cvmx_gmxx_rxx_decision_s cn38xx;
4234+ struct cvmx_gmxx_rxx_decision_s cn38xxp2;
4235+ struct cvmx_gmxx_rxx_decision_s cn50xx;
4236+ struct cvmx_gmxx_rxx_decision_s cn52xx;
4237+ struct cvmx_gmxx_rxx_decision_s cn52xxp1;
4238+ struct cvmx_gmxx_rxx_decision_s cn56xx;
4239+ struct cvmx_gmxx_rxx_decision_s cn56xxp1;
4240+ struct cvmx_gmxx_rxx_decision_s cn58xx;
4241+ struct cvmx_gmxx_rxx_decision_s cn58xxp1;
4242+};
4243+
4244+union cvmx_gmxx_rxx_frm_chk {
4245+ uint64_t u64;
4246+ struct cvmx_gmxx_rxx_frm_chk_s {
4247+ uint64_t reserved_10_63:54;
4248+ uint64_t niberr:1;
4249+ uint64_t skperr:1;
4250+ uint64_t rcverr:1;
4251+ uint64_t lenerr:1;
4252+ uint64_t alnerr:1;
4253+ uint64_t fcserr:1;
4254+ uint64_t jabber:1;
4255+ uint64_t maxerr:1;
4256+ uint64_t carext:1;
4257+ uint64_t minerr:1;
4258+ } s;
4259+ struct cvmx_gmxx_rxx_frm_chk_s cn30xx;
4260+ struct cvmx_gmxx_rxx_frm_chk_s cn31xx;
4261+ struct cvmx_gmxx_rxx_frm_chk_s cn38xx;
4262+ struct cvmx_gmxx_rxx_frm_chk_s cn38xxp2;
4263+ struct cvmx_gmxx_rxx_frm_chk_cn50xx {
4264+ uint64_t reserved_10_63:54;
4265+ uint64_t niberr:1;
4266+ uint64_t skperr:1;
4267+ uint64_t rcverr:1;
4268+ uint64_t reserved_6_6:1;
4269+ uint64_t alnerr:1;
4270+ uint64_t fcserr:1;
4271+ uint64_t jabber:1;
4272+ uint64_t reserved_2_2:1;
4273+ uint64_t carext:1;
4274+ uint64_t reserved_0_0:1;
4275+ } cn50xx;
4276+ struct cvmx_gmxx_rxx_frm_chk_cn52xx {
4277+ uint64_t reserved_9_63:55;
4278+ uint64_t skperr:1;
4279+ uint64_t rcverr:1;
4280+ uint64_t reserved_5_6:2;
4281+ uint64_t fcserr:1;
4282+ uint64_t jabber:1;
4283+ uint64_t reserved_2_2:1;
4284+ uint64_t carext:1;
4285+ uint64_t reserved_0_0:1;
4286+ } cn52xx;
4287+ struct cvmx_gmxx_rxx_frm_chk_cn52xx cn52xxp1;
4288+ struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xx;
4289+ struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xxp1;
4290+ struct cvmx_gmxx_rxx_frm_chk_s cn58xx;
4291+ struct cvmx_gmxx_rxx_frm_chk_s cn58xxp1;
4292+};
4293+
4294+union cvmx_gmxx_rxx_frm_ctl {
4295+ uint64_t u64;
4296+ struct cvmx_gmxx_rxx_frm_ctl_s {
4297+ uint64_t reserved_11_63:53;
4298+ uint64_t null_dis:1;
4299+ uint64_t pre_align:1;
4300+ uint64_t pad_len:1;
4301+ uint64_t vlan_len:1;
4302+ uint64_t pre_free:1;
4303+ uint64_t ctl_smac:1;
4304+ uint64_t ctl_mcst:1;
4305+ uint64_t ctl_bck:1;
4306+ uint64_t ctl_drp:1;
4307+ uint64_t pre_strp:1;
4308+ uint64_t pre_chk:1;
4309+ } s;
4310+ struct cvmx_gmxx_rxx_frm_ctl_cn30xx {
4311+ uint64_t reserved_9_63:55;
4312+ uint64_t pad_len:1;
4313+ uint64_t vlan_len:1;
4314+ uint64_t pre_free:1;
4315+ uint64_t ctl_smac:1;
4316+ uint64_t ctl_mcst:1;
4317+ uint64_t ctl_bck:1;
4318+ uint64_t ctl_drp:1;
4319+ uint64_t pre_strp:1;
4320+ uint64_t pre_chk:1;
4321+ } cn30xx;
4322+ struct cvmx_gmxx_rxx_frm_ctl_cn31xx {
4323+ uint64_t reserved_8_63:56;
4324+ uint64_t vlan_len:1;
4325+ uint64_t pre_free:1;
4326+ uint64_t ctl_smac:1;
4327+ uint64_t ctl_mcst:1;
4328+ uint64_t ctl_bck:1;
4329+ uint64_t ctl_drp:1;
4330+ uint64_t pre_strp:1;
4331+ uint64_t pre_chk:1;
4332+ } cn31xx;
4333+ struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn38xx;
4334+ struct cvmx_gmxx_rxx_frm_ctl_cn31xx cn38xxp2;
4335+ struct cvmx_gmxx_rxx_frm_ctl_cn50xx {
4336+ uint64_t reserved_11_63:53;
4337+ uint64_t null_dis:1;
4338+ uint64_t pre_align:1;
4339+ uint64_t reserved_7_8:2;
4340+ uint64_t pre_free:1;
4341+ uint64_t ctl_smac:1;
4342+ uint64_t ctl_mcst:1;
4343+ uint64_t ctl_bck:1;
4344+ uint64_t ctl_drp:1;
4345+ uint64_t pre_strp:1;
4346+ uint64_t pre_chk:1;
4347+ } cn50xx;
4348+ struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xx;
4349+ struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xxp1;
4350+ struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn56xx;
4351+ struct cvmx_gmxx_rxx_frm_ctl_cn56xxp1 {
4352+ uint64_t reserved_10_63:54;
4353+ uint64_t pre_align:1;
4354+ uint64_t reserved_7_8:2;
4355+ uint64_t pre_free:1;
4356+ uint64_t ctl_smac:1;
4357+ uint64_t ctl_mcst:1;
4358+ uint64_t ctl_bck:1;
4359+ uint64_t ctl_drp:1;
4360+ uint64_t pre_strp:1;
4361+ uint64_t pre_chk:1;
4362+ } cn56xxp1;
4363+ struct cvmx_gmxx_rxx_frm_ctl_s cn58xx;
4364+ struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn58xxp1;
4365+};
4366+
4367+union cvmx_gmxx_rxx_frm_max {
4368+ uint64_t u64;
4369+ struct cvmx_gmxx_rxx_frm_max_s {
4370+ uint64_t reserved_16_63:48;
4371+ uint64_t len:16;
4372+ } s;
4373+ struct cvmx_gmxx_rxx_frm_max_s cn30xx;
4374+ struct cvmx_gmxx_rxx_frm_max_s cn31xx;
4375+ struct cvmx_gmxx_rxx_frm_max_s cn38xx;
4376+ struct cvmx_gmxx_rxx_frm_max_s cn38xxp2;
4377+ struct cvmx_gmxx_rxx_frm_max_s cn58xx;
4378+ struct cvmx_gmxx_rxx_frm_max_s cn58xxp1;
4379+};
4380+
4381+union cvmx_gmxx_rxx_frm_min {
4382+ uint64_t u64;
4383+ struct cvmx_gmxx_rxx_frm_min_s {
4384+ uint64_t reserved_16_63:48;
4385+ uint64_t len:16;
4386+ } s;
4387+ struct cvmx_gmxx_rxx_frm_min_s cn30xx;
4388+ struct cvmx_gmxx_rxx_frm_min_s cn31xx;
4389+ struct cvmx_gmxx_rxx_frm_min_s cn38xx;
4390+ struct cvmx_gmxx_rxx_frm_min_s cn38xxp2;
4391+ struct cvmx_gmxx_rxx_frm_min_s cn58xx;
4392+ struct cvmx_gmxx_rxx_frm_min_s cn58xxp1;
4393+};
4394+
4395+union cvmx_gmxx_rxx_ifg {
4396+ uint64_t u64;
4397+ struct cvmx_gmxx_rxx_ifg_s {
4398+ uint64_t reserved_4_63:60;
4399+ uint64_t ifg:4;
4400+ } s;
4401+ struct cvmx_gmxx_rxx_ifg_s cn30xx;
4402+ struct cvmx_gmxx_rxx_ifg_s cn31xx;
4403+ struct cvmx_gmxx_rxx_ifg_s cn38xx;
4404+ struct cvmx_gmxx_rxx_ifg_s cn38xxp2;
4405+ struct cvmx_gmxx_rxx_ifg_s cn50xx;
4406+ struct cvmx_gmxx_rxx_ifg_s cn52xx;
4407+ struct cvmx_gmxx_rxx_ifg_s cn52xxp1;
4408+ struct cvmx_gmxx_rxx_ifg_s cn56xx;
4409+ struct cvmx_gmxx_rxx_ifg_s cn56xxp1;
4410+ struct cvmx_gmxx_rxx_ifg_s cn58xx;
4411+ struct cvmx_gmxx_rxx_ifg_s cn58xxp1;
4412+};
4413+
4414+union cvmx_gmxx_rxx_int_en {
4415+ uint64_t u64;
4416+ struct cvmx_gmxx_rxx_int_en_s {
4417+ uint64_t reserved_29_63:35;
4418+ uint64_t hg2cc:1;
4419+ uint64_t hg2fld:1;
4420+ uint64_t undat:1;
4421+ uint64_t uneop:1;
4422+ uint64_t unsop:1;
4423+ uint64_t bad_term:1;
4424+ uint64_t bad_seq:1;
4425+ uint64_t rem_fault:1;
4426+ uint64_t loc_fault:1;
4427+ uint64_t pause_drp:1;
4428+ uint64_t phy_dupx:1;
4429+ uint64_t phy_spd:1;
4430+ uint64_t phy_link:1;
4431+ uint64_t ifgerr:1;
4432+ uint64_t coldet:1;
4433+ uint64_t falerr:1;
4434+ uint64_t rsverr:1;
4435+ uint64_t pcterr:1;
4436+ uint64_t ovrerr:1;
4437+ uint64_t niberr:1;
4438+ uint64_t skperr:1;
4439+ uint64_t rcverr:1;
4440+ uint64_t lenerr:1;
4441+ uint64_t alnerr:1;
4442+ uint64_t fcserr:1;
4443+ uint64_t jabber:1;
4444+ uint64_t maxerr:1;
4445+ uint64_t carext:1;
4446+ uint64_t minerr:1;
4447+ } s;
4448+ struct cvmx_gmxx_rxx_int_en_cn30xx {
4449+ uint64_t reserved_19_63:45;
4450+ uint64_t phy_dupx:1;
4451+ uint64_t phy_spd:1;
4452+ uint64_t phy_link:1;
4453+ uint64_t ifgerr:1;
4454+ uint64_t coldet:1;
4455+ uint64_t falerr:1;
4456+ uint64_t rsverr:1;
4457+ uint64_t pcterr:1;
4458+ uint64_t ovrerr:1;
4459+ uint64_t niberr:1;
4460+ uint64_t skperr:1;
4461+ uint64_t rcverr:1;
4462+ uint64_t lenerr:1;
4463+ uint64_t alnerr:1;
4464+ uint64_t fcserr:1;
4465+ uint64_t jabber:1;
4466+ uint64_t maxerr:1;
4467+ uint64_t carext:1;
4468+ uint64_t minerr:1;
4469+ } cn30xx;
4470+ struct cvmx_gmxx_rxx_int_en_cn30xx cn31xx;
4471+ struct cvmx_gmxx_rxx_int_en_cn30xx cn38xx;
4472+ struct cvmx_gmxx_rxx_int_en_cn30xx cn38xxp2;
4473+ struct cvmx_gmxx_rxx_int_en_cn50xx {
4474+ uint64_t reserved_20_63:44;
4475+ uint64_t pause_drp:1;
4476+ uint64_t phy_dupx:1;
4477+ uint64_t phy_spd:1;
4478+ uint64_t phy_link:1;
4479+ uint64_t ifgerr:1;
4480+ uint64_t coldet:1;
4481+ uint64_t falerr:1;
4482+ uint64_t rsverr:1;
4483+ uint64_t pcterr:1;
4484+ uint64_t ovrerr:1;
4485+ uint64_t niberr:1;
4486+ uint64_t skperr:1;
4487+ uint64_t rcverr:1;
4488+ uint64_t reserved_6_6:1;
4489+ uint64_t alnerr:1;
4490+ uint64_t fcserr:1;
4491+ uint64_t jabber:1;
4492+ uint64_t reserved_2_2:1;
4493+ uint64_t carext:1;
4494+ uint64_t reserved_0_0:1;
4495+ } cn50xx;
4496+ struct cvmx_gmxx_rxx_int_en_cn52xx {
4497+ uint64_t reserved_29_63:35;
4498+ uint64_t hg2cc:1;
4499+ uint64_t hg2fld:1;
4500+ uint64_t undat:1;
4501+ uint64_t uneop:1;
4502+ uint64_t unsop:1;
4503+ uint64_t bad_term:1;
4504+ uint64_t bad_seq:1;
4505+ uint64_t rem_fault:1;
4506+ uint64_t loc_fault:1;
4507+ uint64_t pause_drp:1;
4508+ uint64_t reserved_16_18:3;
4509+ uint64_t ifgerr:1;
4510+ uint64_t coldet:1;
4511+ uint64_t falerr:1;
4512+ uint64_t rsverr:1;
4513+ uint64_t pcterr:1;
4514+ uint64_t ovrerr:1;
4515+ uint64_t reserved_9_9:1;
4516+ uint64_t skperr:1;
4517+ uint64_t rcverr:1;
4518+ uint64_t reserved_5_6:2;
4519+ uint64_t fcserr:1;
4520+ uint64_t jabber:1;
4521+ uint64_t reserved_2_2:1;
4522+ uint64_t carext:1;
4523+ uint64_t reserved_0_0:1;
4524+ } cn52xx;
4525+ struct cvmx_gmxx_rxx_int_en_cn52xx cn52xxp1;
4526+ struct cvmx_gmxx_rxx_int_en_cn52xx cn56xx;
4527+ struct cvmx_gmxx_rxx_int_en_cn56xxp1 {
4528+ uint64_t reserved_27_63:37;
4529+ uint64_t undat:1;
4530+ uint64_t uneop:1;
4531+ uint64_t unsop:1;
4532+ uint64_t bad_term:1;
4533+ uint64_t bad_seq:1;
4534+ uint64_t rem_fault:1;
4535+ uint64_t loc_fault:1;
4536+ uint64_t pause_drp:1;
4537+ uint64_t reserved_16_18:3;
4538+ uint64_t ifgerr:1;
4539+ uint64_t coldet:1;
4540+ uint64_t falerr:1;
4541+ uint64_t rsverr:1;
4542+ uint64_t pcterr:1;
4543+ uint64_t ovrerr:1;
4544+ uint64_t reserved_9_9:1;
4545+ uint64_t skperr:1;
4546+ uint64_t rcverr:1;
4547+ uint64_t reserved_5_6:2;
4548+ uint64_t fcserr:1;
4549+ uint64_t jabber:1;
4550+ uint64_t reserved_2_2:1;
4551+ uint64_t carext:1;
4552+ uint64_t reserved_0_0:1;
4553+ } cn56xxp1;
4554+ struct cvmx_gmxx_rxx_int_en_cn58xx {
4555+ uint64_t reserved_20_63:44;
4556+ uint64_t pause_drp:1;
4557+ uint64_t phy_dupx:1;
4558+ uint64_t phy_spd:1;
4559+ uint64_t phy_link:1;
4560+ uint64_t ifgerr:1;
4561+ uint64_t coldet:1;
4562+ uint64_t falerr:1;
4563+ uint64_t rsverr:1;
4564+ uint64_t pcterr:1;
4565+ uint64_t ovrerr:1;
4566+ uint64_t niberr:1;
4567+ uint64_t skperr:1;
4568+ uint64_t rcverr:1;
4569+ uint64_t lenerr:1;
4570+ uint64_t alnerr:1;
4571+ uint64_t fcserr:1;
4572+ uint64_t jabber:1;
4573+ uint64_t maxerr:1;
4574+ uint64_t carext:1;
4575+ uint64_t minerr:1;
4576+ } cn58xx;
4577+ struct cvmx_gmxx_rxx_int_en_cn58xx cn58xxp1;
4578+};
4579+
4580+union cvmx_gmxx_rxx_int_reg {
4581+ uint64_t u64;
4582+ struct cvmx_gmxx_rxx_int_reg_s {
4583+ uint64_t reserved_29_63:35;
4584+ uint64_t hg2cc:1;
4585+ uint64_t hg2fld:1;
4586+ uint64_t undat:1;
4587+ uint64_t uneop:1;
4588+ uint64_t unsop:1;
4589+ uint64_t bad_term:1;
4590+ uint64_t bad_seq:1;
4591+ uint64_t rem_fault:1;
4592+ uint64_t loc_fault:1;
4593+ uint64_t pause_drp:1;
4594+ uint64_t phy_dupx:1;
4595+ uint64_t phy_spd:1;
4596+ uint64_t phy_link:1;
4597+ uint64_t ifgerr:1;
4598+ uint64_t coldet:1;
4599+ uint64_t falerr:1;
4600+ uint64_t rsverr:1;
4601+ uint64_t pcterr:1;
4602+ uint64_t ovrerr:1;
4603+ uint64_t niberr:1;
4604+ uint64_t skperr:1;
4605+ uint64_t rcverr:1;
4606+ uint64_t lenerr:1;
4607+ uint64_t alnerr:1;
4608+ uint64_t fcserr:1;
4609+ uint64_t jabber:1;
4610+ uint64_t maxerr:1;
4611+ uint64_t carext:1;
4612+ uint64_t minerr:1;
4613+ } s;
4614+ struct cvmx_gmxx_rxx_int_reg_cn30xx {
4615+ uint64_t reserved_19_63:45;
4616+ uint64_t phy_dupx:1;
4617+ uint64_t phy_spd:1;
4618+ uint64_t phy_link:1;
4619+ uint64_t ifgerr:1;
4620+ uint64_t coldet:1;
4621+ uint64_t falerr:1;
4622+ uint64_t rsverr:1;
4623+ uint64_t pcterr:1;
4624+ uint64_t ovrerr:1;
4625+ uint64_t niberr:1;
4626+ uint64_t skperr:1;
4627+ uint64_t rcverr:1;
4628+ uint64_t lenerr:1;
4629+ uint64_t alnerr:1;
4630+ uint64_t fcserr:1;
4631+ uint64_t jabber:1;
4632+ uint64_t maxerr:1;
4633+ uint64_t carext:1;
4634+ uint64_t minerr:1;
4635+ } cn30xx;
4636+ struct cvmx_gmxx_rxx_int_reg_cn30xx cn31xx;
4637+ struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xx;
4638+ struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xxp2;
4639+ struct cvmx_gmxx_rxx_int_reg_cn50xx {
4640+ uint64_t reserved_20_63:44;
4641+ uint64_t pause_drp:1;
4642+ uint64_t phy_dupx:1;
4643+ uint64_t phy_spd:1;
4644+ uint64_t phy_link:1;
4645+ uint64_t ifgerr:1;
4646+ uint64_t coldet:1;
4647+ uint64_t falerr:1;
4648+ uint64_t rsverr:1;
4649+ uint64_t pcterr:1;
4650+ uint64_t ovrerr:1;
4651+ uint64_t niberr:1;
4652+ uint64_t skperr:1;
4653+ uint64_t rcverr:1;
4654+ uint64_t reserved_6_6:1;
4655+ uint64_t alnerr:1;
4656+ uint64_t fcserr:1;
4657+ uint64_t jabber:1;
4658+ uint64_t reserved_2_2:1;
4659+ uint64_t carext:1;
4660+ uint64_t reserved_0_0:1;
4661+ } cn50xx;
4662+ struct cvmx_gmxx_rxx_int_reg_cn52xx {
4663+ uint64_t reserved_29_63:35;
4664+ uint64_t hg2cc:1;
4665+ uint64_t hg2fld:1;
4666+ uint64_t undat:1;
4667+ uint64_t uneop:1;
4668+ uint64_t unsop:1;
4669+ uint64_t bad_term:1;
4670+ uint64_t bad_seq:1;
4671+ uint64_t rem_fault:1;
4672+ uint64_t loc_fault:1;
4673+ uint64_t pause_drp:1;
4674+ uint64_t reserved_16_18:3;
4675+ uint64_t ifgerr:1;
4676+ uint64_t coldet:1;
4677+ uint64_t falerr:1;
4678+ uint64_t rsverr:1;
4679+ uint64_t pcterr:1;
4680+ uint64_t ovrerr:1;
4681+ uint64_t reserved_9_9:1;
4682+ uint64_t skperr:1;
4683+ uint64_t rcverr:1;
4684+ uint64_t reserved_5_6:2;
4685+ uint64_t fcserr:1;
4686+ uint64_t jabber:1;
4687+ uint64_t reserved_2_2:1;
4688+ uint64_t carext:1;
4689+ uint64_t reserved_0_0:1;
4690+ } cn52xx;
4691+ struct cvmx_gmxx_rxx_int_reg_cn52xx cn52xxp1;
4692+ struct cvmx_gmxx_rxx_int_reg_cn52xx cn56xx;
4693+ struct cvmx_gmxx_rxx_int_reg_cn56xxp1 {
4694+ uint64_t reserved_27_63:37;
4695+ uint64_t undat:1;
4696+ uint64_t uneop:1;
4697+ uint64_t unsop:1;
4698+ uint64_t bad_term:1;
4699+ uint64_t bad_seq:1;
4700+ uint64_t rem_fault:1;
4701+ uint64_t loc_fault:1;
4702+ uint64_t pause_drp:1;
4703+ uint64_t reserved_16_18:3;
4704+ uint64_t ifgerr:1;
4705+ uint64_t coldet:1;
4706+ uint64_t falerr:1;
4707+ uint64_t rsverr:1;
4708+ uint64_t pcterr:1;
4709+ uint64_t ovrerr:1;
4710+ uint64_t reserved_9_9:1;
4711+ uint64_t skperr:1;
4712+ uint64_t rcverr:1;
4713+ uint64_t reserved_5_6:2;
4714+ uint64_t fcserr:1;
4715+ uint64_t jabber:1;
4716+ uint64_t reserved_2_2:1;
4717+ uint64_t carext:1;
4718+ uint64_t reserved_0_0:1;
4719+ } cn56xxp1;
4720+ struct cvmx_gmxx_rxx_int_reg_cn58xx {
4721+ uint64_t reserved_20_63:44;
4722+ uint64_t pause_drp:1;
4723+ uint64_t phy_dupx:1;
4724+ uint64_t phy_spd:1;
4725+ uint64_t phy_link:1;
4726+ uint64_t ifgerr:1;
4727+ uint64_t coldet:1;
4728+ uint64_t falerr:1;
4729+ uint64_t rsverr:1;
4730+ uint64_t pcterr:1;
4731+ uint64_t ovrerr:1;
4732+ uint64_t niberr:1;
4733+ uint64_t skperr:1;
4734+ uint64_t rcverr:1;
4735+ uint64_t lenerr:1;
4736+ uint64_t alnerr:1;
4737+ uint64_t fcserr:1;
4738+ uint64_t jabber:1;
4739+ uint64_t maxerr:1;
4740+ uint64_t carext:1;
4741+ uint64_t minerr:1;
4742+ } cn58xx;
4743+ struct cvmx_gmxx_rxx_int_reg_cn58xx cn58xxp1;
4744+};
4745+
4746+union cvmx_gmxx_rxx_jabber {
4747+ uint64_t u64;
4748+ struct cvmx_gmxx_rxx_jabber_s {
4749+ uint64_t reserved_16_63:48;
4750+ uint64_t cnt:16;
4751+ } s;
4752+ struct cvmx_gmxx_rxx_jabber_s cn30xx;
4753+ struct cvmx_gmxx_rxx_jabber_s cn31xx;
4754+ struct cvmx_gmxx_rxx_jabber_s cn38xx;
4755+ struct cvmx_gmxx_rxx_jabber_s cn38xxp2;
4756+ struct cvmx_gmxx_rxx_jabber_s cn50xx;
4757+ struct cvmx_gmxx_rxx_jabber_s cn52xx;
4758+ struct cvmx_gmxx_rxx_jabber_s cn52xxp1;
4759+ struct cvmx_gmxx_rxx_jabber_s cn56xx;
4760+ struct cvmx_gmxx_rxx_jabber_s cn56xxp1;
4761+ struct cvmx_gmxx_rxx_jabber_s cn58xx;
4762+ struct cvmx_gmxx_rxx_jabber_s cn58xxp1;
4763+};
4764+
4765+union cvmx_gmxx_rxx_pause_drop_time {
4766+ uint64_t u64;
4767+ struct cvmx_gmxx_rxx_pause_drop_time_s {
4768+ uint64_t reserved_16_63:48;
4769+ uint64_t status:16;
4770+ } s;
4771+ struct cvmx_gmxx_rxx_pause_drop_time_s cn50xx;
4772+ struct cvmx_gmxx_rxx_pause_drop_time_s cn52xx;
4773+ struct cvmx_gmxx_rxx_pause_drop_time_s cn52xxp1;
4774+ struct cvmx_gmxx_rxx_pause_drop_time_s cn56xx;
4775+ struct cvmx_gmxx_rxx_pause_drop_time_s cn56xxp1;
4776+ struct cvmx_gmxx_rxx_pause_drop_time_s cn58xx;
4777+ struct cvmx_gmxx_rxx_pause_drop_time_s cn58xxp1;
4778+};
4779+
4780+union cvmx_gmxx_rxx_rx_inbnd {
4781+ uint64_t u64;
4782+ struct cvmx_gmxx_rxx_rx_inbnd_s {
4783+ uint64_t reserved_4_63:60;
4784+ uint64_t duplex:1;
4785+ uint64_t speed:2;
4786+ uint64_t status:1;
4787+ } s;
4788+ struct cvmx_gmxx_rxx_rx_inbnd_s cn30xx;
4789+ struct cvmx_gmxx_rxx_rx_inbnd_s cn31xx;
4790+ struct cvmx_gmxx_rxx_rx_inbnd_s cn38xx;
4791+ struct cvmx_gmxx_rxx_rx_inbnd_s cn38xxp2;
4792+ struct cvmx_gmxx_rxx_rx_inbnd_s cn50xx;
4793+ struct cvmx_gmxx_rxx_rx_inbnd_s cn58xx;
4794+ struct cvmx_gmxx_rxx_rx_inbnd_s cn58xxp1;
4795+};
4796+
4797+union cvmx_gmxx_rxx_stats_ctl {
4798+ uint64_t u64;
4799+ struct cvmx_gmxx_rxx_stats_ctl_s {
4800+ uint64_t reserved_1_63:63;
4801+ uint64_t rd_clr:1;
4802+ } s;
4803+ struct cvmx_gmxx_rxx_stats_ctl_s cn30xx;
4804+ struct cvmx_gmxx_rxx_stats_ctl_s cn31xx;
4805+ struct cvmx_gmxx_rxx_stats_ctl_s cn38xx;
4806+ struct cvmx_gmxx_rxx_stats_ctl_s cn38xxp2;
4807+ struct cvmx_gmxx_rxx_stats_ctl_s cn50xx;
4808+ struct cvmx_gmxx_rxx_stats_ctl_s cn52xx;
4809+ struct cvmx_gmxx_rxx_stats_ctl_s cn52xxp1;
4810+ struct cvmx_gmxx_rxx_stats_ctl_s cn56xx;
4811+ struct cvmx_gmxx_rxx_stats_ctl_s cn56xxp1;
4812+ struct cvmx_gmxx_rxx_stats_ctl_s cn58xx;
4813+ struct cvmx_gmxx_rxx_stats_ctl_s cn58xxp1;
4814+};
4815+
4816+union cvmx_gmxx_rxx_stats_octs {
4817+ uint64_t u64;
4818+ struct cvmx_gmxx_rxx_stats_octs_s {
4819+ uint64_t reserved_48_63:16;
4820+ uint64_t cnt:48;
4821+ } s;
4822+ struct cvmx_gmxx_rxx_stats_octs_s cn30xx;
4823+ struct cvmx_gmxx_rxx_stats_octs_s cn31xx;
4824+ struct cvmx_gmxx_rxx_stats_octs_s cn38xx;
4825+ struct cvmx_gmxx_rxx_stats_octs_s cn38xxp2;
4826+ struct cvmx_gmxx_rxx_stats_octs_s cn50xx;
4827+ struct cvmx_gmxx_rxx_stats_octs_s cn52xx;
4828+ struct cvmx_gmxx_rxx_stats_octs_s cn52xxp1;
4829+ struct cvmx_gmxx_rxx_stats_octs_s cn56xx;
4830+ struct cvmx_gmxx_rxx_stats_octs_s cn56xxp1;
4831+ struct cvmx_gmxx_rxx_stats_octs_s cn58xx;
4832+ struct cvmx_gmxx_rxx_stats_octs_s cn58xxp1;
4833+};
4834+
4835+union cvmx_gmxx_rxx_stats_octs_ctl {
4836+ uint64_t u64;
4837+ struct cvmx_gmxx_rxx_stats_octs_ctl_s {
4838+ uint64_t reserved_48_63:16;
4839+ uint64_t cnt:48;
4840+ } s;
4841+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn30xx;
4842+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn31xx;
4843+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xx;
4844+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xxp2;
4845+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn50xx;
4846+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xx;
4847+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xxp1;
4848+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xx;
4849+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xxp1;
4850+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xx;
4851+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xxp1;
4852+};
4853+
4854+union cvmx_gmxx_rxx_stats_octs_dmac {
4855+ uint64_t u64;
4856+ struct cvmx_gmxx_rxx_stats_octs_dmac_s {
4857+ uint64_t reserved_48_63:16;
4858+ uint64_t cnt:48;
4859+ } s;
4860+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn30xx;
4861+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn31xx;
4862+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xx;
4863+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xxp2;
4864+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn50xx;
4865+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xx;
4866+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xxp1;
4867+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xx;
4868+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xxp1;
4869+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xx;
4870+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xxp1;
4871+};
4872+
4873+union cvmx_gmxx_rxx_stats_octs_drp {
4874+ uint64_t u64;
4875+ struct cvmx_gmxx_rxx_stats_octs_drp_s {
4876+ uint64_t reserved_48_63:16;
4877+ uint64_t cnt:48;
4878+ } s;
4879+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn30xx;
4880+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn31xx;
4881+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xx;
4882+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xxp2;
4883+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn50xx;
4884+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xx;
4885+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xxp1;
4886+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xx;
4887+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xxp1;
4888+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xx;
4889+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xxp1;
4890+};
4891+
4892+union cvmx_gmxx_rxx_stats_pkts {
4893+ uint64_t u64;
4894+ struct cvmx_gmxx_rxx_stats_pkts_s {
4895+ uint64_t reserved_32_63:32;
4896+ uint64_t cnt:32;
4897+ } s;
4898+ struct cvmx_gmxx_rxx_stats_pkts_s cn30xx;
4899+ struct cvmx_gmxx_rxx_stats_pkts_s cn31xx;
4900+ struct cvmx_gmxx_rxx_stats_pkts_s cn38xx;
4901+ struct cvmx_gmxx_rxx_stats_pkts_s cn38xxp2;
4902+ struct cvmx_gmxx_rxx_stats_pkts_s cn50xx;
4903+ struct cvmx_gmxx_rxx_stats_pkts_s cn52xx;
4904+ struct cvmx_gmxx_rxx_stats_pkts_s cn52xxp1;
4905+ struct cvmx_gmxx_rxx_stats_pkts_s cn56xx;
4906+ struct cvmx_gmxx_rxx_stats_pkts_s cn56xxp1;
4907+ struct cvmx_gmxx_rxx_stats_pkts_s cn58xx;
4908+ struct cvmx_gmxx_rxx_stats_pkts_s cn58xxp1;
4909+};
4910+
4911+union cvmx_gmxx_rxx_stats_pkts_bad {
4912+ uint64_t u64;
4913+ struct cvmx_gmxx_rxx_stats_pkts_bad_s {
4914+ uint64_t reserved_32_63:32;
4915+ uint64_t cnt:32;
4916+ } s;
4917+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn30xx;
4918+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn31xx;
4919+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xx;
4920+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xxp2;
4921+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn50xx;
4922+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xx;
4923+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xxp1;
4924+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xx;
4925+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xxp1;
4926+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xx;
4927+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xxp1;
4928+};
4929+
4930+union cvmx_gmxx_rxx_stats_pkts_ctl {
4931+ uint64_t u64;
4932+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s {
4933+ uint64_t reserved_32_63:32;
4934+ uint64_t cnt:32;
4935+ } s;
4936+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn30xx;
4937+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn31xx;
4938+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xx;
4939+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xxp2;
4940+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn50xx;
4941+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xx;
4942+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xxp1;
4943+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xx;
4944+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xxp1;
4945+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xx;
4946+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xxp1;
4947+};
4948+
4949+union cvmx_gmxx_rxx_stats_pkts_dmac {
4950+ uint64_t u64;
4951+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s {
4952+ uint64_t reserved_32_63:32;
4953+ uint64_t cnt:32;
4954+ } s;
4955+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn30xx;
4956+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn31xx;
4957+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xx;
4958+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xxp2;
4959+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn50xx;
4960+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xx;
4961+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xxp1;
4962+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xx;
4963+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xxp1;
4964+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xx;
4965+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xxp1;
4966+};
4967+
4968+union cvmx_gmxx_rxx_stats_pkts_drp {
4969+ uint64_t u64;
4970+ struct cvmx_gmxx_rxx_stats_pkts_drp_s {
4971+ uint64_t reserved_32_63:32;
4972+ uint64_t cnt:32;
4973+ } s;
4974+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn30xx;
4975+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn31xx;
4976+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xx;
4977+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xxp2;
4978+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn50xx;
4979+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xx;
4980+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xxp1;
4981+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xx;
4982+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xxp1;
4983+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xx;
4984+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xxp1;
4985+};
4986+
4987+union cvmx_gmxx_rxx_udd_skp {
4988+ uint64_t u64;
4989+ struct cvmx_gmxx_rxx_udd_skp_s {
4990+ uint64_t reserved_9_63:55;
4991+ uint64_t fcssel:1;
4992+ uint64_t reserved_7_7:1;
4993+ uint64_t len:7;
4994+ } s;
4995+ struct cvmx_gmxx_rxx_udd_skp_s cn30xx;
4996+ struct cvmx_gmxx_rxx_udd_skp_s cn31xx;
4997+ struct cvmx_gmxx_rxx_udd_skp_s cn38xx;
4998+ struct cvmx_gmxx_rxx_udd_skp_s cn38xxp2;
4999+ struct cvmx_gmxx_rxx_udd_skp_s cn50xx;
5000+ struct cvmx_gmxx_rxx_udd_skp_s cn52xx;
5001+ struct cvmx_gmxx_rxx_udd_skp_s cn52xxp1;
5002+ struct cvmx_gmxx_rxx_udd_skp_s cn56xx;
5003+ struct cvmx_gmxx_rxx_udd_skp_s cn56xxp1;
5004+ struct cvmx_gmxx_rxx_udd_skp_s cn58xx;
5005+ struct cvmx_gmxx_rxx_udd_skp_s cn58xxp1;
5006+};
5007+
5008+union cvmx_gmxx_rx_bp_dropx {
5009+ uint64_t u64;
5010+ struct cvmx_gmxx_rx_bp_dropx_s {
5011+ uint64_t reserved_6_63:58;
5012+ uint64_t mark:6;
5013+ } s;
5014+ struct cvmx_gmxx_rx_bp_dropx_s cn30xx;
5015+ struct cvmx_gmxx_rx_bp_dropx_s cn31xx;
5016+ struct cvmx_gmxx_rx_bp_dropx_s cn38xx;
5017+ struct cvmx_gmxx_rx_bp_dropx_s cn38xxp2;
5018+ struct cvmx_gmxx_rx_bp_dropx_s cn50xx;
5019+ struct cvmx_gmxx_rx_bp_dropx_s cn52xx;
5020+ struct cvmx_gmxx_rx_bp_dropx_s cn52xxp1;
5021+ struct cvmx_gmxx_rx_bp_dropx_s cn56xx;
5022+ struct cvmx_gmxx_rx_bp_dropx_s cn56xxp1;
5023+ struct cvmx_gmxx_rx_bp_dropx_s cn58xx;
5024+ struct cvmx_gmxx_rx_bp_dropx_s cn58xxp1;
5025+};
5026+
5027+union cvmx_gmxx_rx_bp_offx {
5028+ uint64_t u64;
5029+ struct cvmx_gmxx_rx_bp_offx_s {
5030+ uint64_t reserved_6_63:58;
5031+ uint64_t mark:6;
5032+ } s;
5033+ struct cvmx_gmxx_rx_bp_offx_s cn30xx;
5034+ struct cvmx_gmxx_rx_bp_offx_s cn31xx;
5035+ struct cvmx_gmxx_rx_bp_offx_s cn38xx;
5036+ struct cvmx_gmxx_rx_bp_offx_s cn38xxp2;
5037+ struct cvmx_gmxx_rx_bp_offx_s cn50xx;
5038+ struct cvmx_gmxx_rx_bp_offx_s cn52xx;
5039+ struct cvmx_gmxx_rx_bp_offx_s cn52xxp1;
5040+ struct cvmx_gmxx_rx_bp_offx_s cn56xx;
5041+ struct cvmx_gmxx_rx_bp_offx_s cn56xxp1;
5042+ struct cvmx_gmxx_rx_bp_offx_s cn58xx;
5043+ struct cvmx_gmxx_rx_bp_offx_s cn58xxp1;
5044+};
5045+
5046+union cvmx_gmxx_rx_bp_onx {
5047+ uint64_t u64;
5048+ struct cvmx_gmxx_rx_bp_onx_s {
5049+ uint64_t reserved_9_63:55;
5050+ uint64_t mark:9;
5051+ } s;
5052+ struct cvmx_gmxx_rx_bp_onx_s cn30xx;
5053+ struct cvmx_gmxx_rx_bp_onx_s cn31xx;
5054+ struct cvmx_gmxx_rx_bp_onx_s cn38xx;
5055+ struct cvmx_gmxx_rx_bp_onx_s cn38xxp2;
5056+ struct cvmx_gmxx_rx_bp_onx_s cn50xx;
5057+ struct cvmx_gmxx_rx_bp_onx_s cn52xx;
5058+ struct cvmx_gmxx_rx_bp_onx_s cn52xxp1;
5059+ struct cvmx_gmxx_rx_bp_onx_s cn56xx;
5060+ struct cvmx_gmxx_rx_bp_onx_s cn56xxp1;
5061+ struct cvmx_gmxx_rx_bp_onx_s cn58xx;
5062+ struct cvmx_gmxx_rx_bp_onx_s cn58xxp1;
5063+};
5064+
5065+union cvmx_gmxx_rx_hg2_status {
5066+ uint64_t u64;
5067+ struct cvmx_gmxx_rx_hg2_status_s {
5068+ uint64_t reserved_48_63:16;
5069+ uint64_t phtim2go:16;
5070+ uint64_t xof:16;
5071+ uint64_t lgtim2go:16;
5072+ } s;
5073+ struct cvmx_gmxx_rx_hg2_status_s cn52xx;
5074+ struct cvmx_gmxx_rx_hg2_status_s cn52xxp1;
5075+ struct cvmx_gmxx_rx_hg2_status_s cn56xx;
5076+};
5077+
5078+union cvmx_gmxx_rx_pass_en {
5079+ uint64_t u64;
5080+ struct cvmx_gmxx_rx_pass_en_s {
5081+ uint64_t reserved_16_63:48;
5082+ uint64_t en:16;
5083+ } s;
5084+ struct cvmx_gmxx_rx_pass_en_s cn38xx;
5085+ struct cvmx_gmxx_rx_pass_en_s cn38xxp2;
5086+ struct cvmx_gmxx_rx_pass_en_s cn58xx;
5087+ struct cvmx_gmxx_rx_pass_en_s cn58xxp1;
5088+};
5089+
5090+union cvmx_gmxx_rx_pass_mapx {
5091+ uint64_t u64;
5092+ struct cvmx_gmxx_rx_pass_mapx_s {
5093+ uint64_t reserved_4_63:60;
5094+ uint64_t dprt:4;
5095+ } s;
5096+ struct cvmx_gmxx_rx_pass_mapx_s cn38xx;
5097+ struct cvmx_gmxx_rx_pass_mapx_s cn38xxp2;
5098+ struct cvmx_gmxx_rx_pass_mapx_s cn58xx;
5099+ struct cvmx_gmxx_rx_pass_mapx_s cn58xxp1;
5100+};
5101+
5102+union cvmx_gmxx_rx_prt_info {
5103+ uint64_t u64;
5104+ struct cvmx_gmxx_rx_prt_info_s {
5105+ uint64_t reserved_32_63:32;
5106+ uint64_t drop:16;
5107+ uint64_t commit:16;
5108+ } s;
5109+ struct cvmx_gmxx_rx_prt_info_cn30xx {
5110+ uint64_t reserved_19_63:45;
5111+ uint64_t drop:3;
5112+ uint64_t reserved_3_15:13;
5113+ uint64_t commit:3;
5114+ } cn30xx;
5115+ struct cvmx_gmxx_rx_prt_info_cn30xx cn31xx;
5116+ struct cvmx_gmxx_rx_prt_info_s cn38xx;
5117+ struct cvmx_gmxx_rx_prt_info_cn30xx cn50xx;
5118+ struct cvmx_gmxx_rx_prt_info_cn52xx {
5119+ uint64_t reserved_20_63:44;
5120+ uint64_t drop:4;
5121+ uint64_t reserved_4_15:12;
5122+ uint64_t commit:4;
5123+ } cn52xx;
5124+ struct cvmx_gmxx_rx_prt_info_cn52xx cn52xxp1;
5125+ struct cvmx_gmxx_rx_prt_info_cn52xx cn56xx;
5126+ struct cvmx_gmxx_rx_prt_info_cn52xx cn56xxp1;
5127+ struct cvmx_gmxx_rx_prt_info_s cn58xx;
5128+ struct cvmx_gmxx_rx_prt_info_s cn58xxp1;
5129+};
5130+
5131+union cvmx_gmxx_rx_prts {
5132+ uint64_t u64;
5133+ struct cvmx_gmxx_rx_prts_s {
5134+ uint64_t reserved_3_63:61;
5135+ uint64_t prts:3;
5136+ } s;
5137+ struct cvmx_gmxx_rx_prts_s cn30xx;
5138+ struct cvmx_gmxx_rx_prts_s cn31xx;
5139+ struct cvmx_gmxx_rx_prts_s cn38xx;
5140+ struct cvmx_gmxx_rx_prts_s cn38xxp2;
5141+ struct cvmx_gmxx_rx_prts_s cn50xx;
5142+ struct cvmx_gmxx_rx_prts_s cn52xx;
5143+ struct cvmx_gmxx_rx_prts_s cn52xxp1;
5144+ struct cvmx_gmxx_rx_prts_s cn56xx;
5145+ struct cvmx_gmxx_rx_prts_s cn56xxp1;
5146+ struct cvmx_gmxx_rx_prts_s cn58xx;
5147+ struct cvmx_gmxx_rx_prts_s cn58xxp1;
5148+};
5149+
5150+union cvmx_gmxx_rx_tx_status {
5151+ uint64_t u64;
5152+ struct cvmx_gmxx_rx_tx_status_s {
5153+ uint64_t reserved_7_63:57;
5154+ uint64_t tx:3;
5155+ uint64_t reserved_3_3:1;
5156+ uint64_t rx:3;
5157+ } s;
5158+ struct cvmx_gmxx_rx_tx_status_s cn30xx;
5159+ struct cvmx_gmxx_rx_tx_status_s cn31xx;
5160+ struct cvmx_gmxx_rx_tx_status_s cn50xx;
5161+};
5162+
5163+union cvmx_gmxx_rx_xaui_bad_col {
5164+ uint64_t u64;
5165+ struct cvmx_gmxx_rx_xaui_bad_col_s {
5166+ uint64_t reserved_40_63:24;
5167+ uint64_t val:1;
5168+ uint64_t state:3;
5169+ uint64_t lane_rxc:4;
5170+ uint64_t lane_rxd:32;
5171+ } s;
5172+ struct cvmx_gmxx_rx_xaui_bad_col_s cn52xx;
5173+ struct cvmx_gmxx_rx_xaui_bad_col_s cn52xxp1;
5174+ struct cvmx_gmxx_rx_xaui_bad_col_s cn56xx;
5175+ struct cvmx_gmxx_rx_xaui_bad_col_s cn56xxp1;
5176+};
5177+
5178+union cvmx_gmxx_rx_xaui_ctl {
5179+ uint64_t u64;
5180+ struct cvmx_gmxx_rx_xaui_ctl_s {
5181+ uint64_t reserved_2_63:62;
5182+ uint64_t status:2;
5183+ } s;
5184+ struct cvmx_gmxx_rx_xaui_ctl_s cn52xx;
5185+ struct cvmx_gmxx_rx_xaui_ctl_s cn52xxp1;
5186+ struct cvmx_gmxx_rx_xaui_ctl_s cn56xx;
5187+ struct cvmx_gmxx_rx_xaui_ctl_s cn56xxp1;
5188+};
5189+
5190+union cvmx_gmxx_smacx {
5191+ uint64_t u64;
5192+ struct cvmx_gmxx_smacx_s {
5193+ uint64_t reserved_48_63:16;
5194+ uint64_t smac:48;
5195+ } s;
5196+ struct cvmx_gmxx_smacx_s cn30xx;
5197+ struct cvmx_gmxx_smacx_s cn31xx;
5198+ struct cvmx_gmxx_smacx_s cn38xx;
5199+ struct cvmx_gmxx_smacx_s cn38xxp2;
5200+ struct cvmx_gmxx_smacx_s cn50xx;
5201+ struct cvmx_gmxx_smacx_s cn52xx;
5202+ struct cvmx_gmxx_smacx_s cn52xxp1;
5203+ struct cvmx_gmxx_smacx_s cn56xx;
5204+ struct cvmx_gmxx_smacx_s cn56xxp1;
5205+ struct cvmx_gmxx_smacx_s cn58xx;
5206+ struct cvmx_gmxx_smacx_s cn58xxp1;
5207+};
5208+
5209+union cvmx_gmxx_stat_bp {
5210+ uint64_t u64;
5211+ struct cvmx_gmxx_stat_bp_s {
5212+ uint64_t reserved_17_63:47;
5213+ uint64_t bp:1;
5214+ uint64_t cnt:16;
5215+ } s;
5216+ struct cvmx_gmxx_stat_bp_s cn30xx;
5217+ struct cvmx_gmxx_stat_bp_s cn31xx;
5218+ struct cvmx_gmxx_stat_bp_s cn38xx;
5219+ struct cvmx_gmxx_stat_bp_s cn38xxp2;
5220+ struct cvmx_gmxx_stat_bp_s cn50xx;
5221+ struct cvmx_gmxx_stat_bp_s cn52xx;
5222+ struct cvmx_gmxx_stat_bp_s cn52xxp1;
5223+ struct cvmx_gmxx_stat_bp_s cn56xx;
5224+ struct cvmx_gmxx_stat_bp_s cn56xxp1;
5225+ struct cvmx_gmxx_stat_bp_s cn58xx;
5226+ struct cvmx_gmxx_stat_bp_s cn58xxp1;
5227+};
5228+
5229+union cvmx_gmxx_txx_append {
5230+ uint64_t u64;
5231+ struct cvmx_gmxx_txx_append_s {
5232+ uint64_t reserved_4_63:60;
5233+ uint64_t force_fcs:1;
5234+ uint64_t fcs:1;
5235+ uint64_t pad:1;
5236+ uint64_t preamble:1;
5237+ } s;
5238+ struct cvmx_gmxx_txx_append_s cn30xx;
5239+ struct cvmx_gmxx_txx_append_s cn31xx;
5240+ struct cvmx_gmxx_txx_append_s cn38xx;
5241+ struct cvmx_gmxx_txx_append_s cn38xxp2;
5242+ struct cvmx_gmxx_txx_append_s cn50xx;
5243+ struct cvmx_gmxx_txx_append_s cn52xx;
5244+ struct cvmx_gmxx_txx_append_s cn52xxp1;
5245+ struct cvmx_gmxx_txx_append_s cn56xx;
5246+ struct cvmx_gmxx_txx_append_s cn56xxp1;
5247+ struct cvmx_gmxx_txx_append_s cn58xx;
5248+ struct cvmx_gmxx_txx_append_s cn58xxp1;
5249+};
5250+
5251+union cvmx_gmxx_txx_burst {
5252+ uint64_t u64;
5253+ struct cvmx_gmxx_txx_burst_s {
5254+ uint64_t reserved_16_63:48;
5255+ uint64_t burst:16;
5256+ } s;
5257+ struct cvmx_gmxx_txx_burst_s cn30xx;
5258+ struct cvmx_gmxx_txx_burst_s cn31xx;
5259+ struct cvmx_gmxx_txx_burst_s cn38xx;
5260+ struct cvmx_gmxx_txx_burst_s cn38xxp2;
5261+ struct cvmx_gmxx_txx_burst_s cn50xx;
5262+ struct cvmx_gmxx_txx_burst_s cn52xx;
5263+ struct cvmx_gmxx_txx_burst_s cn52xxp1;
5264+ struct cvmx_gmxx_txx_burst_s cn56xx;
5265+ struct cvmx_gmxx_txx_burst_s cn56xxp1;
5266+ struct cvmx_gmxx_txx_burst_s cn58xx;
5267+ struct cvmx_gmxx_txx_burst_s cn58xxp1;
5268+};
5269+
5270+union cvmx_gmxx_txx_cbfc_xoff {
5271+ uint64_t u64;
5272+ struct cvmx_gmxx_txx_cbfc_xoff_s {
5273+ uint64_t reserved_16_63:48;
5274+ uint64_t xoff:16;
5275+ } s;
5276+ struct cvmx_gmxx_txx_cbfc_xoff_s cn52xx;
5277+ struct cvmx_gmxx_txx_cbfc_xoff_s cn56xx;
5278+};
5279+
5280+union cvmx_gmxx_txx_cbfc_xon {
5281+ uint64_t u64;
5282+ struct cvmx_gmxx_txx_cbfc_xon_s {
5283+ uint64_t reserved_16_63:48;
5284+ uint64_t xon:16;
5285+ } s;
5286+ struct cvmx_gmxx_txx_cbfc_xon_s cn52xx;
5287+ struct cvmx_gmxx_txx_cbfc_xon_s cn56xx;
5288+};
5289+
5290+union cvmx_gmxx_txx_clk {
5291+ uint64_t u64;
5292+ struct cvmx_gmxx_txx_clk_s {
5293+ uint64_t reserved_6_63:58;
5294+ uint64_t clk_cnt:6;
5295+ } s;
5296+ struct cvmx_gmxx_txx_clk_s cn30xx;
5297+ struct cvmx_gmxx_txx_clk_s cn31xx;
5298+ struct cvmx_gmxx_txx_clk_s cn38xx;
5299+ struct cvmx_gmxx_txx_clk_s cn38xxp2;
5300+ struct cvmx_gmxx_txx_clk_s cn50xx;
5301+ struct cvmx_gmxx_txx_clk_s cn58xx;
5302+ struct cvmx_gmxx_txx_clk_s cn58xxp1;
5303+};
5304+
5305+union cvmx_gmxx_txx_ctl {
5306+ uint64_t u64;
5307+ struct cvmx_gmxx_txx_ctl_s {
5308+ uint64_t reserved_2_63:62;
5309+ uint64_t xsdef_en:1;
5310+ uint64_t xscol_en:1;
5311+ } s;
5312+ struct cvmx_gmxx_txx_ctl_s cn30xx;
5313+ struct cvmx_gmxx_txx_ctl_s cn31xx;
5314+ struct cvmx_gmxx_txx_ctl_s cn38xx;
5315+ struct cvmx_gmxx_txx_ctl_s cn38xxp2;
5316+ struct cvmx_gmxx_txx_ctl_s cn50xx;
5317+ struct cvmx_gmxx_txx_ctl_s cn52xx;
5318+ struct cvmx_gmxx_txx_ctl_s cn52xxp1;
5319+ struct cvmx_gmxx_txx_ctl_s cn56xx;
5320+ struct cvmx_gmxx_txx_ctl_s cn56xxp1;
5321+ struct cvmx_gmxx_txx_ctl_s cn58xx;
5322+ struct cvmx_gmxx_txx_ctl_s cn58xxp1;
5323+};
5324+
5325+union cvmx_gmxx_txx_min_pkt {
5326+ uint64_t u64;
5327+ struct cvmx_gmxx_txx_min_pkt_s {
5328+ uint64_t reserved_8_63:56;
5329+ uint64_t min_size:8;
5330+ } s;
5331+ struct cvmx_gmxx_txx_min_pkt_s cn30xx;
5332+ struct cvmx_gmxx_txx_min_pkt_s cn31xx;
5333+ struct cvmx_gmxx_txx_min_pkt_s cn38xx;
5334+ struct cvmx_gmxx_txx_min_pkt_s cn38xxp2;
5335+ struct cvmx_gmxx_txx_min_pkt_s cn50xx;
5336+ struct cvmx_gmxx_txx_min_pkt_s cn52xx;
5337+ struct cvmx_gmxx_txx_min_pkt_s cn52xxp1;
5338+ struct cvmx_gmxx_txx_min_pkt_s cn56xx;
5339+ struct cvmx_gmxx_txx_min_pkt_s cn56xxp1;
5340+ struct cvmx_gmxx_txx_min_pkt_s cn58xx;
5341+ struct cvmx_gmxx_txx_min_pkt_s cn58xxp1;
5342+};
5343+
5344+union cvmx_gmxx_txx_pause_pkt_interval {
5345+ uint64_t u64;
5346+ struct cvmx_gmxx_txx_pause_pkt_interval_s {
5347+ uint64_t reserved_16_63:48;
5348+ uint64_t interval:16;
5349+ } s;
5350+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn30xx;
5351+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn31xx;
5352+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xx;
5353+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xxp2;
5354+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn50xx;
5355+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xx;
5356+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xxp1;
5357+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xx;
5358+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xxp1;
5359+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xx;
5360+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xxp1;
5361+};
5362+
5363+union cvmx_gmxx_txx_pause_pkt_time {
5364+ uint64_t u64;
5365+ struct cvmx_gmxx_txx_pause_pkt_time_s {
5366+ uint64_t reserved_16_63:48;
5367+ uint64_t time:16;
5368+ } s;
5369+ struct cvmx_gmxx_txx_pause_pkt_time_s cn30xx;
5370+ struct cvmx_gmxx_txx_pause_pkt_time_s cn31xx;
5371+ struct cvmx_gmxx_txx_pause_pkt_time_s cn38xx;
5372+ struct cvmx_gmxx_txx_pause_pkt_time_s cn38xxp2;
5373+ struct cvmx_gmxx_txx_pause_pkt_time_s cn50xx;
5374+ struct cvmx_gmxx_txx_pause_pkt_time_s cn52xx;
5375+ struct cvmx_gmxx_txx_pause_pkt_time_s cn52xxp1;
5376+ struct cvmx_gmxx_txx_pause_pkt_time_s cn56xx;
5377+ struct cvmx_gmxx_txx_pause_pkt_time_s cn56xxp1;
5378+ struct cvmx_gmxx_txx_pause_pkt_time_s cn58xx;
5379+ struct cvmx_gmxx_txx_pause_pkt_time_s cn58xxp1;
5380+};
5381+
5382+union cvmx_gmxx_txx_pause_togo {
5383+ uint64_t u64;
5384+ struct cvmx_gmxx_txx_pause_togo_s {
5385+ uint64_t reserved_32_63:32;
5386+ uint64_t msg_time:16;
5387+ uint64_t time:16;
5388+ } s;
5389+ struct cvmx_gmxx_txx_pause_togo_cn30xx {
5390+ uint64_t reserved_16_63:48;
5391+ uint64_t time:16;
5392+ } cn30xx;
5393+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn31xx;
5394+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xx;
5395+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xxp2;
5396+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn50xx;
5397+ struct cvmx_gmxx_txx_pause_togo_s cn52xx;
5398+ struct cvmx_gmxx_txx_pause_togo_s cn52xxp1;
5399+ struct cvmx_gmxx_txx_pause_togo_s cn56xx;
5400+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn56xxp1;
5401+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xx;
5402+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xxp1;
5403+};
5404+
5405+union cvmx_gmxx_txx_pause_zero {
5406+ uint64_t u64;
5407+ struct cvmx_gmxx_txx_pause_zero_s {
5408+ uint64_t reserved_1_63:63;
5409+ uint64_t send:1;
5410+ } s;
5411+ struct cvmx_gmxx_txx_pause_zero_s cn30xx;
5412+ struct cvmx_gmxx_txx_pause_zero_s cn31xx;
5413+ struct cvmx_gmxx_txx_pause_zero_s cn38xx;
5414+ struct cvmx_gmxx_txx_pause_zero_s cn38xxp2;
5415+ struct cvmx_gmxx_txx_pause_zero_s cn50xx;
5416+ struct cvmx_gmxx_txx_pause_zero_s cn52xx;
5417+ struct cvmx_gmxx_txx_pause_zero_s cn52xxp1;
5418+ struct cvmx_gmxx_txx_pause_zero_s cn56xx;
5419+ struct cvmx_gmxx_txx_pause_zero_s cn56xxp1;
5420+ struct cvmx_gmxx_txx_pause_zero_s cn58xx;
5421+ struct cvmx_gmxx_txx_pause_zero_s cn58xxp1;
5422+};
5423+
5424+union cvmx_gmxx_txx_sgmii_ctl {
5425+ uint64_t u64;
5426+ struct cvmx_gmxx_txx_sgmii_ctl_s {
5427+ uint64_t reserved_1_63:63;
5428+ uint64_t align:1;
5429+ } s;
5430+ struct cvmx_gmxx_txx_sgmii_ctl_s cn52xx;
5431+ struct cvmx_gmxx_txx_sgmii_ctl_s cn52xxp1;
5432+ struct cvmx_gmxx_txx_sgmii_ctl_s cn56xx;
5433+ struct cvmx_gmxx_txx_sgmii_ctl_s cn56xxp1;
5434+};
5435+
5436+union cvmx_gmxx_txx_slot {
5437+ uint64_t u64;
5438+ struct cvmx_gmxx_txx_slot_s {
5439+ uint64_t reserved_10_63:54;
5440+ uint64_t slot:10;
5441+ } s;
5442+ struct cvmx_gmxx_txx_slot_s cn30xx;
5443+ struct cvmx_gmxx_txx_slot_s cn31xx;
5444+ struct cvmx_gmxx_txx_slot_s cn38xx;
5445+ struct cvmx_gmxx_txx_slot_s cn38xxp2;
5446+ struct cvmx_gmxx_txx_slot_s cn50xx;
5447+ struct cvmx_gmxx_txx_slot_s cn52xx;
5448+ struct cvmx_gmxx_txx_slot_s cn52xxp1;
5449+ struct cvmx_gmxx_txx_slot_s cn56xx;
5450+ struct cvmx_gmxx_txx_slot_s cn56xxp1;
5451+ struct cvmx_gmxx_txx_slot_s cn58xx;
5452+ struct cvmx_gmxx_txx_slot_s cn58xxp1;
5453+};
5454+
5455+union cvmx_gmxx_txx_soft_pause {
5456+ uint64_t u64;
5457+ struct cvmx_gmxx_txx_soft_pause_s {
5458+ uint64_t reserved_16_63:48;
5459+ uint64_t time:16;
5460+ } s;
5461+ struct cvmx_gmxx_txx_soft_pause_s cn30xx;
5462+ struct cvmx_gmxx_txx_soft_pause_s cn31xx;
5463+ struct cvmx_gmxx_txx_soft_pause_s cn38xx;
5464+ struct cvmx_gmxx_txx_soft_pause_s cn38xxp2;
5465+ struct cvmx_gmxx_txx_soft_pause_s cn50xx;
5466+ struct cvmx_gmxx_txx_soft_pause_s cn52xx;
5467+ struct cvmx_gmxx_txx_soft_pause_s cn52xxp1;
5468+ struct cvmx_gmxx_txx_soft_pause_s cn56xx;
5469+ struct cvmx_gmxx_txx_soft_pause_s cn56xxp1;
5470+ struct cvmx_gmxx_txx_soft_pause_s cn58xx;
5471+ struct cvmx_gmxx_txx_soft_pause_s cn58xxp1;
5472+};
5473+
5474+union cvmx_gmxx_txx_stat0 {
5475+ uint64_t u64;
5476+ struct cvmx_gmxx_txx_stat0_s {
5477+ uint64_t xsdef:32;
5478+ uint64_t xscol:32;
5479+ } s;
5480+ struct cvmx_gmxx_txx_stat0_s cn30xx;
5481+ struct cvmx_gmxx_txx_stat0_s cn31xx;
5482+ struct cvmx_gmxx_txx_stat0_s cn38xx;
5483+ struct cvmx_gmxx_txx_stat0_s cn38xxp2;
5484+ struct cvmx_gmxx_txx_stat0_s cn50xx;
5485+ struct cvmx_gmxx_txx_stat0_s cn52xx;
5486+ struct cvmx_gmxx_txx_stat0_s cn52xxp1;
5487+ struct cvmx_gmxx_txx_stat0_s cn56xx;
5488+ struct cvmx_gmxx_txx_stat0_s cn56xxp1;
5489+ struct cvmx_gmxx_txx_stat0_s cn58xx;
5490+ struct cvmx_gmxx_txx_stat0_s cn58xxp1;
5491+};
5492+
5493+union cvmx_gmxx_txx_stat1 {
5494+ uint64_t u64;
5495+ struct cvmx_gmxx_txx_stat1_s {
5496+ uint64_t scol:32;
5497+ uint64_t mcol:32;
5498+ } s;
5499+ struct cvmx_gmxx_txx_stat1_s cn30xx;
5500+ struct cvmx_gmxx_txx_stat1_s cn31xx;
5501+ struct cvmx_gmxx_txx_stat1_s cn38xx;
5502+ struct cvmx_gmxx_txx_stat1_s cn38xxp2;
5503+ struct cvmx_gmxx_txx_stat1_s cn50xx;
5504+ struct cvmx_gmxx_txx_stat1_s cn52xx;
5505+ struct cvmx_gmxx_txx_stat1_s cn52xxp1;
5506+ struct cvmx_gmxx_txx_stat1_s cn56xx;
5507+ struct cvmx_gmxx_txx_stat1_s cn56xxp1;
5508+ struct cvmx_gmxx_txx_stat1_s cn58xx;
5509+ struct cvmx_gmxx_txx_stat1_s cn58xxp1;
5510+};
5511+
5512+union cvmx_gmxx_txx_stat2 {
5513+ uint64_t u64;
5514+ struct cvmx_gmxx_txx_stat2_s {
5515+ uint64_t reserved_48_63:16;
5516+ uint64_t octs:48;
5517+ } s;
5518+ struct cvmx_gmxx_txx_stat2_s cn30xx;
5519+ struct cvmx_gmxx_txx_stat2_s cn31xx;
5520+ struct cvmx_gmxx_txx_stat2_s cn38xx;
5521+ struct cvmx_gmxx_txx_stat2_s cn38xxp2;
5522+ struct cvmx_gmxx_txx_stat2_s cn50xx;
5523+ struct cvmx_gmxx_txx_stat2_s cn52xx;
5524+ struct cvmx_gmxx_txx_stat2_s cn52xxp1;
5525+ struct cvmx_gmxx_txx_stat2_s cn56xx;
5526+ struct cvmx_gmxx_txx_stat2_s cn56xxp1;
5527+ struct cvmx_gmxx_txx_stat2_s cn58xx;
5528+ struct cvmx_gmxx_txx_stat2_s cn58xxp1;
5529+};
5530+
5531+union cvmx_gmxx_txx_stat3 {
5532+ uint64_t u64;
5533+ struct cvmx_gmxx_txx_stat3_s {
5534+ uint64_t reserved_32_63:32;
5535+ uint64_t pkts:32;
5536+ } s;
5537+ struct cvmx_gmxx_txx_stat3_s cn30xx;
5538+ struct cvmx_gmxx_txx_stat3_s cn31xx;
5539+ struct cvmx_gmxx_txx_stat3_s cn38xx;
5540+ struct cvmx_gmxx_txx_stat3_s cn38xxp2;
5541+ struct cvmx_gmxx_txx_stat3_s cn50xx;
5542+ struct cvmx_gmxx_txx_stat3_s cn52xx;
5543+ struct cvmx_gmxx_txx_stat3_s cn52xxp1;
5544+ struct cvmx_gmxx_txx_stat3_s cn56xx;
5545+ struct cvmx_gmxx_txx_stat3_s cn56xxp1;
5546+ struct cvmx_gmxx_txx_stat3_s cn58xx;
5547+ struct cvmx_gmxx_txx_stat3_s cn58xxp1;
5548+};
5549+
5550+union cvmx_gmxx_txx_stat4 {
5551+ uint64_t u64;
5552+ struct cvmx_gmxx_txx_stat4_s {
5553+ uint64_t hist1:32;
5554+ uint64_t hist0:32;
5555+ } s;
5556+ struct cvmx_gmxx_txx_stat4_s cn30xx;
5557+ struct cvmx_gmxx_txx_stat4_s cn31xx;
5558+ struct cvmx_gmxx_txx_stat4_s cn38xx;
5559+ struct cvmx_gmxx_txx_stat4_s cn38xxp2;
5560+ struct cvmx_gmxx_txx_stat4_s cn50xx;
5561+ struct cvmx_gmxx_txx_stat4_s cn52xx;
5562+ struct cvmx_gmxx_txx_stat4_s cn52xxp1;
5563+ struct cvmx_gmxx_txx_stat4_s cn56xx;
5564+ struct cvmx_gmxx_txx_stat4_s cn56xxp1;
5565+ struct cvmx_gmxx_txx_stat4_s cn58xx;
5566+ struct cvmx_gmxx_txx_stat4_s cn58xxp1;
5567+};
5568+
5569+union cvmx_gmxx_txx_stat5 {
5570+ uint64_t u64;
5571+ struct cvmx_gmxx_txx_stat5_s {
5572+ uint64_t hist3:32;
5573+ uint64_t hist2:32;
5574+ } s;
5575+ struct cvmx_gmxx_txx_stat5_s cn30xx;
5576+ struct cvmx_gmxx_txx_stat5_s cn31xx;
5577+ struct cvmx_gmxx_txx_stat5_s cn38xx;
5578+ struct cvmx_gmxx_txx_stat5_s cn38xxp2;
5579+ struct cvmx_gmxx_txx_stat5_s cn50xx;
5580+ struct cvmx_gmxx_txx_stat5_s cn52xx;
5581+ struct cvmx_gmxx_txx_stat5_s cn52xxp1;
5582+ struct cvmx_gmxx_txx_stat5_s cn56xx;
5583+ struct cvmx_gmxx_txx_stat5_s cn56xxp1;
5584+ struct cvmx_gmxx_txx_stat5_s cn58xx;
5585+ struct cvmx_gmxx_txx_stat5_s cn58xxp1;
5586+};
5587+
5588+union cvmx_gmxx_txx_stat6 {
5589+ uint64_t u64;
5590+ struct cvmx_gmxx_txx_stat6_s {
5591+ uint64_t hist5:32;
5592+ uint64_t hist4:32;
5593+ } s;
5594+ struct cvmx_gmxx_txx_stat6_s cn30xx;
5595+ struct cvmx_gmxx_txx_stat6_s cn31xx;
5596+ struct cvmx_gmxx_txx_stat6_s cn38xx;
5597+ struct cvmx_gmxx_txx_stat6_s cn38xxp2;
5598+ struct cvmx_gmxx_txx_stat6_s cn50xx;
5599+ struct cvmx_gmxx_txx_stat6_s cn52xx;
5600+ struct cvmx_gmxx_txx_stat6_s cn52xxp1;
5601+ struct cvmx_gmxx_txx_stat6_s cn56xx;
5602+ struct cvmx_gmxx_txx_stat6_s cn56xxp1;
5603+ struct cvmx_gmxx_txx_stat6_s cn58xx;
5604+ struct cvmx_gmxx_txx_stat6_s cn58xxp1;
5605+};
5606+
5607+union cvmx_gmxx_txx_stat7 {
5608+ uint64_t u64;
5609+ struct cvmx_gmxx_txx_stat7_s {
5610+ uint64_t hist7:32;
5611+ uint64_t hist6:32;
5612+ } s;
5613+ struct cvmx_gmxx_txx_stat7_s cn30xx;
5614+ struct cvmx_gmxx_txx_stat7_s cn31xx;
5615+ struct cvmx_gmxx_txx_stat7_s cn38xx;
5616+ struct cvmx_gmxx_txx_stat7_s cn38xxp2;
5617+ struct cvmx_gmxx_txx_stat7_s cn50xx;
5618+ struct cvmx_gmxx_txx_stat7_s cn52xx;
5619+ struct cvmx_gmxx_txx_stat7_s cn52xxp1;
5620+ struct cvmx_gmxx_txx_stat7_s cn56xx;
5621+ struct cvmx_gmxx_txx_stat7_s cn56xxp1;
5622+ struct cvmx_gmxx_txx_stat7_s cn58xx;
5623+ struct cvmx_gmxx_txx_stat7_s cn58xxp1;
5624+};
5625+
5626+union cvmx_gmxx_txx_stat8 {
5627+ uint64_t u64;
5628+ struct cvmx_gmxx_txx_stat8_s {
5629+ uint64_t mcst:32;
5630+ uint64_t bcst:32;
5631+ } s;
5632+ struct cvmx_gmxx_txx_stat8_s cn30xx;
5633+ struct cvmx_gmxx_txx_stat8_s cn31xx;
5634+ struct cvmx_gmxx_txx_stat8_s cn38xx;
5635+ struct cvmx_gmxx_txx_stat8_s cn38xxp2;
5636+ struct cvmx_gmxx_txx_stat8_s cn50xx;
5637+ struct cvmx_gmxx_txx_stat8_s cn52xx;
5638+ struct cvmx_gmxx_txx_stat8_s cn52xxp1;
5639+ struct cvmx_gmxx_txx_stat8_s cn56xx;
5640+ struct cvmx_gmxx_txx_stat8_s cn56xxp1;
5641+ struct cvmx_gmxx_txx_stat8_s cn58xx;
5642+ struct cvmx_gmxx_txx_stat8_s cn58xxp1;
5643+};
5644+
5645+union cvmx_gmxx_txx_stat9 {
5646+ uint64_t u64;
5647+ struct cvmx_gmxx_txx_stat9_s {
5648+ uint64_t undflw:32;
5649+ uint64_t ctl:32;
5650+ } s;
5651+ struct cvmx_gmxx_txx_stat9_s cn30xx;
5652+ struct cvmx_gmxx_txx_stat9_s cn31xx;
5653+ struct cvmx_gmxx_txx_stat9_s cn38xx;
5654+ struct cvmx_gmxx_txx_stat9_s cn38xxp2;
5655+ struct cvmx_gmxx_txx_stat9_s cn50xx;
5656+ struct cvmx_gmxx_txx_stat9_s cn52xx;
5657+ struct cvmx_gmxx_txx_stat9_s cn52xxp1;
5658+ struct cvmx_gmxx_txx_stat9_s cn56xx;
5659+ struct cvmx_gmxx_txx_stat9_s cn56xxp1;
5660+ struct cvmx_gmxx_txx_stat9_s cn58xx;
5661+ struct cvmx_gmxx_txx_stat9_s cn58xxp1;
5662+};
5663+
5664+union cvmx_gmxx_txx_stats_ctl {
5665+ uint64_t u64;
5666+ struct cvmx_gmxx_txx_stats_ctl_s {
5667+ uint64_t reserved_1_63:63;
5668+ uint64_t rd_clr:1;
5669+ } s;
5670+ struct cvmx_gmxx_txx_stats_ctl_s cn30xx;
5671+ struct cvmx_gmxx_txx_stats_ctl_s cn31xx;
5672+ struct cvmx_gmxx_txx_stats_ctl_s cn38xx;
5673+ struct cvmx_gmxx_txx_stats_ctl_s cn38xxp2;
5674+ struct cvmx_gmxx_txx_stats_ctl_s cn50xx;
5675+ struct cvmx_gmxx_txx_stats_ctl_s cn52xx;
5676+ struct cvmx_gmxx_txx_stats_ctl_s cn52xxp1;
5677+ struct cvmx_gmxx_txx_stats_ctl_s cn56xx;
5678+ struct cvmx_gmxx_txx_stats_ctl_s cn56xxp1;
5679+ struct cvmx_gmxx_txx_stats_ctl_s cn58xx;
5680+ struct cvmx_gmxx_txx_stats_ctl_s cn58xxp1;
5681+};
5682+
5683+union cvmx_gmxx_txx_thresh {
5684+ uint64_t u64;
5685+ struct cvmx_gmxx_txx_thresh_s {
5686+ uint64_t reserved_9_63:55;
5687+ uint64_t cnt:9;
5688+ } s;
5689+ struct cvmx_gmxx_txx_thresh_cn30xx {
5690+ uint64_t reserved_7_63:57;
5691+ uint64_t cnt:7;
5692+ } cn30xx;
5693+ struct cvmx_gmxx_txx_thresh_cn30xx cn31xx;
5694+ struct cvmx_gmxx_txx_thresh_s cn38xx;
5695+ struct cvmx_gmxx_txx_thresh_s cn38xxp2;
5696+ struct cvmx_gmxx_txx_thresh_cn30xx cn50xx;
5697+ struct cvmx_gmxx_txx_thresh_s cn52xx;
5698+ struct cvmx_gmxx_txx_thresh_s cn52xxp1;
5699+ struct cvmx_gmxx_txx_thresh_s cn56xx;
5700+ struct cvmx_gmxx_txx_thresh_s cn56xxp1;
5701+ struct cvmx_gmxx_txx_thresh_s cn58xx;
5702+ struct cvmx_gmxx_txx_thresh_s cn58xxp1;
5703+};
5704+
5705+union cvmx_gmxx_tx_bp {
5706+ uint64_t u64;
5707+ struct cvmx_gmxx_tx_bp_s {
5708+ uint64_t reserved_4_63:60;
5709+ uint64_t bp:4;
5710+ } s;
5711+ struct cvmx_gmxx_tx_bp_cn30xx {
5712+ uint64_t reserved_3_63:61;
5713+ uint64_t bp:3;
5714+ } cn30xx;
5715+ struct cvmx_gmxx_tx_bp_cn30xx cn31xx;
5716+ struct cvmx_gmxx_tx_bp_s cn38xx;
5717+ struct cvmx_gmxx_tx_bp_s cn38xxp2;
5718+ struct cvmx_gmxx_tx_bp_cn30xx cn50xx;
5719+ struct cvmx_gmxx_tx_bp_s cn52xx;
5720+ struct cvmx_gmxx_tx_bp_s cn52xxp1;
5721+ struct cvmx_gmxx_tx_bp_s cn56xx;
5722+ struct cvmx_gmxx_tx_bp_s cn56xxp1;
5723+ struct cvmx_gmxx_tx_bp_s cn58xx;
5724+ struct cvmx_gmxx_tx_bp_s cn58xxp1;
5725+};
5726+
5727+union cvmx_gmxx_tx_clk_mskx {
5728+ uint64_t u64;
5729+ struct cvmx_gmxx_tx_clk_mskx_s {
5730+ uint64_t reserved_1_63:63;
5731+ uint64_t msk:1;
5732+ } s;
5733+ struct cvmx_gmxx_tx_clk_mskx_s cn30xx;
5734+ struct cvmx_gmxx_tx_clk_mskx_s cn50xx;
5735+};
5736+
5737+union cvmx_gmxx_tx_col_attempt {
5738+ uint64_t u64;
5739+ struct cvmx_gmxx_tx_col_attempt_s {
5740+ uint64_t reserved_5_63:59;
5741+ uint64_t limit:5;
5742+ } s;
5743+ struct cvmx_gmxx_tx_col_attempt_s cn30xx;
5744+ struct cvmx_gmxx_tx_col_attempt_s cn31xx;
5745+ struct cvmx_gmxx_tx_col_attempt_s cn38xx;
5746+ struct cvmx_gmxx_tx_col_attempt_s cn38xxp2;
5747+ struct cvmx_gmxx_tx_col_attempt_s cn50xx;
5748+ struct cvmx_gmxx_tx_col_attempt_s cn52xx;
5749+ struct cvmx_gmxx_tx_col_attempt_s cn52xxp1;
5750+ struct cvmx_gmxx_tx_col_attempt_s cn56xx;
5751+ struct cvmx_gmxx_tx_col_attempt_s cn56xxp1;
5752+ struct cvmx_gmxx_tx_col_attempt_s cn58xx;
5753+ struct cvmx_gmxx_tx_col_attempt_s cn58xxp1;
5754+};
5755+
5756+union cvmx_gmxx_tx_corrupt {
5757+ uint64_t u64;
5758+ struct cvmx_gmxx_tx_corrupt_s {
5759+ uint64_t reserved_4_63:60;
5760+ uint64_t corrupt:4;
5761+ } s;
5762+ struct cvmx_gmxx_tx_corrupt_cn30xx {
5763+ uint64_t reserved_3_63:61;
5764+ uint64_t corrupt:3;
5765+ } cn30xx;
5766+ struct cvmx_gmxx_tx_corrupt_cn30xx cn31xx;
5767+ struct cvmx_gmxx_tx_corrupt_s cn38xx;
5768+ struct cvmx_gmxx_tx_corrupt_s cn38xxp2;
5769+ struct cvmx_gmxx_tx_corrupt_cn30xx cn50xx;
5770+ struct cvmx_gmxx_tx_corrupt_s cn52xx;
5771+ struct cvmx_gmxx_tx_corrupt_s cn52xxp1;
5772+ struct cvmx_gmxx_tx_corrupt_s cn56xx;
5773+ struct cvmx_gmxx_tx_corrupt_s cn56xxp1;
5774+ struct cvmx_gmxx_tx_corrupt_s cn58xx;
5775+ struct cvmx_gmxx_tx_corrupt_s cn58xxp1;
5776+};
5777+
5778+union cvmx_gmxx_tx_hg2_reg1 {
5779+ uint64_t u64;
5780+ struct cvmx_gmxx_tx_hg2_reg1_s {
5781+ uint64_t reserved_16_63:48;
5782+ uint64_t tx_xof:16;
5783+ } s;
5784+ struct cvmx_gmxx_tx_hg2_reg1_s cn52xx;
5785+ struct cvmx_gmxx_tx_hg2_reg1_s cn52xxp1;
5786+ struct cvmx_gmxx_tx_hg2_reg1_s cn56xx;
5787+};
5788+
5789+union cvmx_gmxx_tx_hg2_reg2 {
5790+ uint64_t u64;
5791+ struct cvmx_gmxx_tx_hg2_reg2_s {
5792+ uint64_t reserved_16_63:48;
5793+ uint64_t tx_xon:16;
5794+ } s;
5795+ struct cvmx_gmxx_tx_hg2_reg2_s cn52xx;
5796+ struct cvmx_gmxx_tx_hg2_reg2_s cn52xxp1;
5797+ struct cvmx_gmxx_tx_hg2_reg2_s cn56xx;
5798+};
5799+
5800+union cvmx_gmxx_tx_ifg {
5801+ uint64_t u64;
5802+ struct cvmx_gmxx_tx_ifg_s {
5803+ uint64_t reserved_8_63:56;
5804+ uint64_t ifg2:4;
5805+ uint64_t ifg1:4;
5806+ } s;
5807+ struct cvmx_gmxx_tx_ifg_s cn30xx;
5808+ struct cvmx_gmxx_tx_ifg_s cn31xx;
5809+ struct cvmx_gmxx_tx_ifg_s cn38xx;
5810+ struct cvmx_gmxx_tx_ifg_s cn38xxp2;
5811+ struct cvmx_gmxx_tx_ifg_s cn50xx;
5812+ struct cvmx_gmxx_tx_ifg_s cn52xx;
5813+ struct cvmx_gmxx_tx_ifg_s cn52xxp1;
5814+ struct cvmx_gmxx_tx_ifg_s cn56xx;
5815+ struct cvmx_gmxx_tx_ifg_s cn56xxp1;
5816+ struct cvmx_gmxx_tx_ifg_s cn58xx;
5817+ struct cvmx_gmxx_tx_ifg_s cn58xxp1;
5818+};
5819+
5820+union cvmx_gmxx_tx_int_en {
5821+ uint64_t u64;
5822+ struct cvmx_gmxx_tx_int_en_s {
5823+ uint64_t reserved_20_63:44;
5824+ uint64_t late_col:4;
5825+ uint64_t xsdef:4;
5826+ uint64_t xscol:4;
5827+ uint64_t reserved_6_7:2;
5828+ uint64_t undflw:4;
5829+ uint64_t ncb_nxa:1;
5830+ uint64_t pko_nxa:1;
5831+ } s;
5832+ struct cvmx_gmxx_tx_int_en_cn30xx {
5833+ uint64_t reserved_19_63:45;
5834+ uint64_t late_col:3;
5835+ uint64_t reserved_15_15:1;
5836+ uint64_t xsdef:3;
5837+ uint64_t reserved_11_11:1;
5838+ uint64_t xscol:3;
5839+ uint64_t reserved_5_7:3;
5840+ uint64_t undflw:3;
5841+ uint64_t reserved_1_1:1;
5842+ uint64_t pko_nxa:1;
5843+ } cn30xx;
5844+ struct cvmx_gmxx_tx_int_en_cn31xx {
5845+ uint64_t reserved_15_63:49;
5846+ uint64_t xsdef:3;
5847+ uint64_t reserved_11_11:1;
5848+ uint64_t xscol:3;
5849+ uint64_t reserved_5_7:3;
5850+ uint64_t undflw:3;
5851+ uint64_t reserved_1_1:1;
5852+ uint64_t pko_nxa:1;
5853+ } cn31xx;
5854+ struct cvmx_gmxx_tx_int_en_s cn38xx;
5855+ struct cvmx_gmxx_tx_int_en_cn38xxp2 {
5856+ uint64_t reserved_16_63:48;
5857+ uint64_t xsdef:4;
5858+ uint64_t xscol:4;
5859+ uint64_t reserved_6_7:2;
5860+ uint64_t undflw:4;
5861+ uint64_t ncb_nxa:1;
5862+ uint64_t pko_nxa:1;
5863+ } cn38xxp2;
5864+ struct cvmx_gmxx_tx_int_en_cn30xx cn50xx;
5865+ struct cvmx_gmxx_tx_int_en_cn52xx {
5866+ uint64_t reserved_20_63:44;
5867+ uint64_t late_col:4;
5868+ uint64_t xsdef:4;
5869+ uint64_t xscol:4;
5870+ uint64_t reserved_6_7:2;
5871+ uint64_t undflw:4;
5872+ uint64_t reserved_1_1:1;
5873+ uint64_t pko_nxa:1;
5874+ } cn52xx;
5875+ struct cvmx_gmxx_tx_int_en_cn52xx cn52xxp1;
5876+ struct cvmx_gmxx_tx_int_en_cn52xx cn56xx;
5877+ struct cvmx_gmxx_tx_int_en_cn52xx cn56xxp1;
5878+ struct cvmx_gmxx_tx_int_en_s cn58xx;
5879+ struct cvmx_gmxx_tx_int_en_s cn58xxp1;
5880+};
5881+
5882+union cvmx_gmxx_tx_int_reg {
5883+ uint64_t u64;
5884+ struct cvmx_gmxx_tx_int_reg_s {
5885+ uint64_t reserved_20_63:44;
5886+ uint64_t late_col:4;
5887+ uint64_t xsdef:4;
5888+ uint64_t xscol:4;
5889+ uint64_t reserved_6_7:2;
5890+ uint64_t undflw:4;
5891+ uint64_t ncb_nxa:1;
5892+ uint64_t pko_nxa:1;
5893+ } s;
5894+ struct cvmx_gmxx_tx_int_reg_cn30xx {
5895+ uint64_t reserved_19_63:45;
5896+ uint64_t late_col:3;
5897+ uint64_t reserved_15_15:1;
5898+ uint64_t xsdef:3;
5899+ uint64_t reserved_11_11:1;
5900+ uint64_t xscol:3;
5901+ uint64_t reserved_5_7:3;
5902+ uint64_t undflw:3;
5903+ uint64_t reserved_1_1:1;
5904+ uint64_t pko_nxa:1;
5905+ } cn30xx;
5906+ struct cvmx_gmxx_tx_int_reg_cn31xx {
5907+ uint64_t reserved_15_63:49;
5908+ uint64_t xsdef:3;
5909+ uint64_t reserved_11_11:1;
5910+ uint64_t xscol:3;
5911+ uint64_t reserved_5_7:3;
5912+ uint64_t undflw:3;
5913+ uint64_t reserved_1_1:1;
5914+ uint64_t pko_nxa:1;
5915+ } cn31xx;
5916+ struct cvmx_gmxx_tx_int_reg_s cn38xx;
5917+ struct cvmx_gmxx_tx_int_reg_cn38xxp2 {
5918+ uint64_t reserved_16_63:48;
5919+ uint64_t xsdef:4;
5920+ uint64_t xscol:4;
5921+ uint64_t reserved_6_7:2;
5922+ uint64_t undflw:4;
5923+ uint64_t ncb_nxa:1;
5924+ uint64_t pko_nxa:1;
5925+ } cn38xxp2;
5926+ struct cvmx_gmxx_tx_int_reg_cn30xx cn50xx;
5927+ struct cvmx_gmxx_tx_int_reg_cn52xx {
5928+ uint64_t reserved_20_63:44;
5929+ uint64_t late_col:4;
5930+ uint64_t xsdef:4;
5931+ uint64_t xscol:4;
5932+ uint64_t reserved_6_7:2;
5933+ uint64_t undflw:4;
5934+ uint64_t reserved_1_1:1;
5935+ uint64_t pko_nxa:1;
5936+ } cn52xx;
5937+ struct cvmx_gmxx_tx_int_reg_cn52xx cn52xxp1;
5938+ struct cvmx_gmxx_tx_int_reg_cn52xx cn56xx;
5939+ struct cvmx_gmxx_tx_int_reg_cn52xx cn56xxp1;
5940+ struct cvmx_gmxx_tx_int_reg_s cn58xx;
5941+ struct cvmx_gmxx_tx_int_reg_s cn58xxp1;
5942+};
5943+
5944+union cvmx_gmxx_tx_jam {
5945+ uint64_t u64;
5946+ struct cvmx_gmxx_tx_jam_s {
5947+ uint64_t reserved_8_63:56;
5948+ uint64_t jam:8;
5949+ } s;
5950+ struct cvmx_gmxx_tx_jam_s cn30xx;
5951+ struct cvmx_gmxx_tx_jam_s cn31xx;
5952+ struct cvmx_gmxx_tx_jam_s cn38xx;
5953+ struct cvmx_gmxx_tx_jam_s cn38xxp2;
5954+ struct cvmx_gmxx_tx_jam_s cn50xx;
5955+ struct cvmx_gmxx_tx_jam_s cn52xx;
5956+ struct cvmx_gmxx_tx_jam_s cn52xxp1;
5957+ struct cvmx_gmxx_tx_jam_s cn56xx;
5958+ struct cvmx_gmxx_tx_jam_s cn56xxp1;
5959+ struct cvmx_gmxx_tx_jam_s cn58xx;
5960+ struct cvmx_gmxx_tx_jam_s cn58xxp1;
5961+};
5962+
5963+union cvmx_gmxx_tx_lfsr {
5964+ uint64_t u64;
5965+ struct cvmx_gmxx_tx_lfsr_s {
5966+ uint64_t reserved_16_63:48;
5967+ uint64_t lfsr:16;
5968+ } s;
5969+ struct cvmx_gmxx_tx_lfsr_s cn30xx;
5970+ struct cvmx_gmxx_tx_lfsr_s cn31xx;
5971+ struct cvmx_gmxx_tx_lfsr_s cn38xx;
5972+ struct cvmx_gmxx_tx_lfsr_s cn38xxp2;
5973+ struct cvmx_gmxx_tx_lfsr_s cn50xx;
5974+ struct cvmx_gmxx_tx_lfsr_s cn52xx;
5975+ struct cvmx_gmxx_tx_lfsr_s cn52xxp1;
5976+ struct cvmx_gmxx_tx_lfsr_s cn56xx;
5977+ struct cvmx_gmxx_tx_lfsr_s cn56xxp1;
5978+ struct cvmx_gmxx_tx_lfsr_s cn58xx;
5979+ struct cvmx_gmxx_tx_lfsr_s cn58xxp1;
5980+};
5981+
5982+union cvmx_gmxx_tx_ovr_bp {
5983+ uint64_t u64;
5984+ struct cvmx_gmxx_tx_ovr_bp_s {
5985+ uint64_t reserved_48_63:16;
5986+ uint64_t tx_prt_bp:16;
5987+ uint64_t reserved_12_31:20;
5988+ uint64_t en:4;
5989+ uint64_t bp:4;
5990+ uint64_t ign_full:4;
5991+ } s;
5992+ struct cvmx_gmxx_tx_ovr_bp_cn30xx {
5993+ uint64_t reserved_11_63:53;
5994+ uint64_t en:3;
5995+ uint64_t reserved_7_7:1;
5996+ uint64_t bp:3;
5997+ uint64_t reserved_3_3:1;
5998+ uint64_t ign_full:3;
5999+ } cn30xx;
6000+ struct cvmx_gmxx_tx_ovr_bp_cn30xx cn31xx;
6001+ struct cvmx_gmxx_tx_ovr_bp_cn38xx {
6002+ uint64_t reserved_12_63:52;
6003+ uint64_t en:4;
6004+ uint64_t bp:4;
6005+ uint64_t ign_full:4;
6006+ } cn38xx;
6007+ struct cvmx_gmxx_tx_ovr_bp_cn38xx cn38xxp2;
6008+ struct cvmx_gmxx_tx_ovr_bp_cn30xx cn50xx;
6009+ struct cvmx_gmxx_tx_ovr_bp_s cn52xx;
6010+ struct cvmx_gmxx_tx_ovr_bp_s cn52xxp1;
6011+ struct cvmx_gmxx_tx_ovr_bp_s cn56xx;
6012+ struct cvmx_gmxx_tx_ovr_bp_s cn56xxp1;
6013+ struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xx;
6014+ struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xxp1;
6015+};
6016+
6017+union cvmx_gmxx_tx_pause_pkt_dmac {
6018+ uint64_t u64;
6019+ struct cvmx_gmxx_tx_pause_pkt_dmac_s {
6020+ uint64_t reserved_48_63:16;
6021+ uint64_t dmac:48;
6022+ } s;
6023+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn30xx;
6024+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn31xx;
6025+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xx;
6026+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xxp2;
6027+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn50xx;
6028+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xx;
6029+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xxp1;
6030+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xx;
6031+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xxp1;
6032+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xx;
6033+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xxp1;
6034+};
6035+
6036+union cvmx_gmxx_tx_pause_pkt_type {
6037+ uint64_t u64;
6038+ struct cvmx_gmxx_tx_pause_pkt_type_s {
6039+ uint64_t reserved_16_63:48;
6040+ uint64_t type:16;
6041+ } s;
6042+ struct cvmx_gmxx_tx_pause_pkt_type_s cn30xx;
6043+ struct cvmx_gmxx_tx_pause_pkt_type_s cn31xx;
6044+ struct cvmx_gmxx_tx_pause_pkt_type_s cn38xx;
6045+ struct cvmx_gmxx_tx_pause_pkt_type_s cn38xxp2;
6046+ struct cvmx_gmxx_tx_pause_pkt_type_s cn50xx;
6047+ struct cvmx_gmxx_tx_pause_pkt_type_s cn52xx;
6048+ struct cvmx_gmxx_tx_pause_pkt_type_s cn52xxp1;
6049+ struct cvmx_gmxx_tx_pause_pkt_type_s cn56xx;
6050+ struct cvmx_gmxx_tx_pause_pkt_type_s cn56xxp1;
6051+ struct cvmx_gmxx_tx_pause_pkt_type_s cn58xx;
6052+ struct cvmx_gmxx_tx_pause_pkt_type_s cn58xxp1;
6053+};
6054+
6055+union cvmx_gmxx_tx_prts {
6056+ uint64_t u64;
6057+ struct cvmx_gmxx_tx_prts_s {
6058+ uint64_t reserved_5_63:59;
6059+ uint64_t prts:5;
6060+ } s;
6061+ struct cvmx_gmxx_tx_prts_s cn30xx;
6062+ struct cvmx_gmxx_tx_prts_s cn31xx;
6063+ struct cvmx_gmxx_tx_prts_s cn38xx;
6064+ struct cvmx_gmxx_tx_prts_s cn38xxp2;
6065+ struct cvmx_gmxx_tx_prts_s cn50xx;
6066+ struct cvmx_gmxx_tx_prts_s cn52xx;
6067+ struct cvmx_gmxx_tx_prts_s cn52xxp1;
6068+ struct cvmx_gmxx_tx_prts_s cn56xx;
6069+ struct cvmx_gmxx_tx_prts_s cn56xxp1;
6070+ struct cvmx_gmxx_tx_prts_s cn58xx;
6071+ struct cvmx_gmxx_tx_prts_s cn58xxp1;
6072+};
6073+
6074+union cvmx_gmxx_tx_spi_ctl {
6075+ uint64_t u64;
6076+ struct cvmx_gmxx_tx_spi_ctl_s {
6077+ uint64_t reserved_2_63:62;
6078+ uint64_t tpa_clr:1;
6079+ uint64_t cont_pkt:1;
6080+ } s;
6081+ struct cvmx_gmxx_tx_spi_ctl_s cn38xx;
6082+ struct cvmx_gmxx_tx_spi_ctl_s cn38xxp2;
6083+ struct cvmx_gmxx_tx_spi_ctl_s cn58xx;
6084+ struct cvmx_gmxx_tx_spi_ctl_s cn58xxp1;
6085+};
6086+
6087+union cvmx_gmxx_tx_spi_drain {
6088+ uint64_t u64;
6089+ struct cvmx_gmxx_tx_spi_drain_s {
6090+ uint64_t reserved_16_63:48;
6091+ uint64_t drain:16;
6092+ } s;
6093+ struct cvmx_gmxx_tx_spi_drain_s cn38xx;
6094+ struct cvmx_gmxx_tx_spi_drain_s cn58xx;
6095+ struct cvmx_gmxx_tx_spi_drain_s cn58xxp1;
6096+};
6097+
6098+union cvmx_gmxx_tx_spi_max {
6099+ uint64_t u64;
6100+ struct cvmx_gmxx_tx_spi_max_s {
6101+ uint64_t reserved_23_63:41;
6102+ uint64_t slice:7;
6103+ uint64_t max2:8;
6104+ uint64_t max1:8;
6105+ } s;
6106+ struct cvmx_gmxx_tx_spi_max_cn38xx {
6107+ uint64_t reserved_16_63:48;
6108+ uint64_t max2:8;
6109+ uint64_t max1:8;
6110+ } cn38xx;
6111+ struct cvmx_gmxx_tx_spi_max_cn38xx cn38xxp2;
6112+ struct cvmx_gmxx_tx_spi_max_s cn58xx;
6113+ struct cvmx_gmxx_tx_spi_max_s cn58xxp1;
6114+};
6115+
6116+union cvmx_gmxx_tx_spi_roundx {
6117+ uint64_t u64;
6118+ struct cvmx_gmxx_tx_spi_roundx_s {
6119+ uint64_t reserved_16_63:48;
6120+ uint64_t round:16;
6121+ } s;
6122+ struct cvmx_gmxx_tx_spi_roundx_s cn58xx;
6123+ struct cvmx_gmxx_tx_spi_roundx_s cn58xxp1;
6124+};
6125+
6126+union cvmx_gmxx_tx_spi_thresh {
6127+ uint64_t u64;
6128+ struct cvmx_gmxx_tx_spi_thresh_s {
6129+ uint64_t reserved_6_63:58;
6130+ uint64_t thresh:6;
6131+ } s;
6132+ struct cvmx_gmxx_tx_spi_thresh_s cn38xx;
6133+ struct cvmx_gmxx_tx_spi_thresh_s cn38xxp2;
6134+ struct cvmx_gmxx_tx_spi_thresh_s cn58xx;
6135+ struct cvmx_gmxx_tx_spi_thresh_s cn58xxp1;
6136+};
6137+
6138+union cvmx_gmxx_tx_xaui_ctl {
6139+ uint64_t u64;
6140+ struct cvmx_gmxx_tx_xaui_ctl_s {
6141+ uint64_t reserved_11_63:53;
6142+ uint64_t hg_pause_hgi:2;
6143+ uint64_t hg_en:1;
6144+ uint64_t reserved_7_7:1;
6145+ uint64_t ls_byp:1;
6146+ uint64_t ls:2;
6147+ uint64_t reserved_2_3:2;
6148+ uint64_t uni_en:1;
6149+ uint64_t dic_en:1;
6150+ } s;
6151+ struct cvmx_gmxx_tx_xaui_ctl_s cn52xx;
6152+ struct cvmx_gmxx_tx_xaui_ctl_s cn52xxp1;
6153+ struct cvmx_gmxx_tx_xaui_ctl_s cn56xx;
6154+ struct cvmx_gmxx_tx_xaui_ctl_s cn56xxp1;
6155+};
6156+
6157+union cvmx_gmxx_xaui_ext_loopback {
6158+ uint64_t u64;
6159+ struct cvmx_gmxx_xaui_ext_loopback_s {
6160+ uint64_t reserved_5_63:59;
6161+ uint64_t en:1;
6162+ uint64_t thresh:4;
6163+ } s;
6164+ struct cvmx_gmxx_xaui_ext_loopback_s cn52xx;
6165+ struct cvmx_gmxx_xaui_ext_loopback_s cn52xxp1;
6166+ struct cvmx_gmxx_xaui_ext_loopback_s cn56xx;
6167+ struct cvmx_gmxx_xaui_ext_loopback_s cn56xxp1;
6168+};
6169+
6170+#endif
6171--- /dev/null
6172+++ b/drivers/staging/octeon/cvmx-helper-board.c
6173@@ -0,0 +1,706 @@
6174+/***********************license start***************
6175+ * Author: Cavium Networks
6176+ *
6177+ * Contact: support@caviumnetworks.com
6178+ * This file is part of the OCTEON SDK
6179+ *
6180+ * Copyright (c) 2003-2008 Cavium Networks
6181+ *
6182+ * This file is free software; you can redistribute it and/or modify
6183+ * it under the terms of the GNU General Public License, Version 2, as
6184+ * published by the Free Software Foundation.
6185+ *
6186+ * This file is distributed in the hope that it will be useful, but
6187+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
6188+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
6189+ * NONINFRINGEMENT. See the GNU General Public License for more
6190+ * details.
6191+ *
6192+ * You should have received a copy of the GNU General Public License
6193+ * along with this file; if not, write to the Free Software
6194+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6195+ * or visit http://www.gnu.org/licenses/.
6196+ *
6197+ * This file may also be available under a different license from Cavium.
6198+ * Contact Cavium Networks for more information
6199+ ***********************license end**************************************/
6200+
6201+/*
6202+ *
6203+ * Helper functions to abstract board specific data about
6204+ * network ports from the rest of the cvmx-helper files.
6205+ */
6206+
6207+#include <asm/octeon/octeon.h>
6208+#include <asm/octeon/cvmx-bootinfo.h>
6209+
6210+#include "cvmx-config.h"
6211+
6212+#include "cvmx-mdio.h"
6213+
6214+#include "cvmx-helper.h"
6215+#include "cvmx-helper-util.h"
6216+#include "cvmx-helper-board.h"
6217+
6218+#include "cvmx-gmxx-defs.h"
6219+#include "cvmx-asxx-defs.h"
6220+
6221+/**
6222+ * cvmx_override_board_link_get(int ipd_port) is a function
6223+ * pointer. It is meant to allow customization of the process of
6224+ * talking to a PHY to determine link speed. It is called every
6225+ * time a PHY must be polled for link status. Users should set
6226+ * this pointer to a function before calling any cvmx-helper
6227+ * operations.
6228+ */
6229+cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port) =
6230+ NULL;
6231+
6232+/**
6233+ * Return the MII PHY address associated with the given IPD
6234+ * port. A result of -1 means there isn't a MII capable PHY
6235+ * connected to this port. On chips supporting multiple MII
6236+ * busses the bus number is encoded in bits <15:8>.
6237+ *
6238+ * This function must be modified for every new Octeon board.
6239+ * Internally it uses switch statements based on the cvmx_sysinfo
6240+ * data to determine board types and revisions. It replies on the
6241+ * fact that every Octeon board receives a unique board type
6242+ * enumeration from the bootloader.
6243+ *
6244+ * @ipd_port: Octeon IPD port to get the MII address for.
6245+ *
6246+ * Returns MII PHY address and bus number or -1.
6247+ */
6248+int cvmx_helper_board_get_mii_address(int ipd_port)
6249+{
6250+ switch (cvmx_sysinfo_get()->board_type) {
6251+ case CVMX_BOARD_TYPE_SIM:
6252+ /* Simulator doesn't have MII */
6253+ return -1;
6254+ case CVMX_BOARD_TYPE_EBT3000:
6255+ case CVMX_BOARD_TYPE_EBT5800:
6256+ case CVMX_BOARD_TYPE_THUNDER:
6257+ case CVMX_BOARD_TYPE_NICPRO2:
6258+ /* Interface 0 is SPI4, interface 1 is RGMII */
6259+ if ((ipd_port >= 16) && (ipd_port < 20))
6260+ return ipd_port - 16;
6261+ else
6262+ return -1;
6263+ case CVMX_BOARD_TYPE_KODAMA:
6264+ case CVMX_BOARD_TYPE_EBH3100:
6265+ case CVMX_BOARD_TYPE_HIKARI:
6266+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
6267+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6268+ case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
6269+ /*
6270+ * Port 0 is WAN connected to a PHY, Port 1 is GMII
6271+ * connected to a switch
6272+ */
6273+ if (ipd_port == 0)
6274+ return 4;
6275+ else if (ipd_port == 1)
6276+ return 9;
6277+ else
6278+ return -1;
6279+ case CVMX_BOARD_TYPE_NAC38:
6280+ /* Board has 8 RGMII ports PHYs are 0-7 */
6281+ if ((ipd_port >= 0) && (ipd_port < 4))
6282+ return ipd_port;
6283+ else if ((ipd_port >= 16) && (ipd_port < 20))
6284+ return ipd_port - 16 + 4;
6285+ else
6286+ return -1;
6287+ case CVMX_BOARD_TYPE_EBH3000:
6288+ /* Board has dual SPI4 and no PHYs */
6289+ return -1;
6290+ case CVMX_BOARD_TYPE_EBH5200:
6291+ case CVMX_BOARD_TYPE_EBH5201:
6292+ case CVMX_BOARD_TYPE_EBT5200:
6293+ /*
6294+ * Board has 4 SGMII ports. The PHYs start right after the MII
6295+ * ports MII0 = 0, MII1 = 1, SGMII = 2-5.
6296+ */
6297+ if ((ipd_port >= 0) && (ipd_port < 4))
6298+ return ipd_port + 2;
6299+ else
6300+ return -1;
6301+ case CVMX_BOARD_TYPE_EBH5600:
6302+ case CVMX_BOARD_TYPE_EBH5601:
6303+ case CVMX_BOARD_TYPE_EBH5610:
6304+ /*
6305+ * Board has 8 SGMII ports. 4 connect out, two connect
6306+ * to a switch, and 2 loop to each other
6307+ */
6308+ if ((ipd_port >= 0) && (ipd_port < 4))
6309+ return ipd_port + 1;
6310+ else
6311+ return -1;
6312+ case CVMX_BOARD_TYPE_CUST_NB5:
6313+ if (ipd_port == 2)
6314+ return 4;
6315+ else
6316+ return -1;
6317+ case CVMX_BOARD_TYPE_NIC_XLE_4G:
6318+ /* Board has 4 SGMII ports. connected QLM3(interface 1) */
6319+ if ((ipd_port >= 16) && (ipd_port < 20))
6320+ return ipd_port - 16 + 1;
6321+ else
6322+ return -1;
6323+ case CVMX_BOARD_TYPE_BBGW_REF:
6324+ /*
6325+ * No PHYs are connected to Octeon, everything is
6326+ * through switch.
6327+ */
6328+ return -1;
6329+ }
6330+
6331+ /* Some unknown board. Somebody forgot to update this function... */
6332+ cvmx_dprintf
6333+ ("cvmx_helper_board_get_mii_address: Unknown board type %d\n",
6334+ cvmx_sysinfo_get()->board_type);
6335+ return -1;
6336+}
6337+
6338+/**
6339+ * This function is the board specific method of determining an
6340+ * ethernet ports link speed. Most Octeon boards have Marvell PHYs
6341+ * and are handled by the fall through case. This function must be
6342+ * updated for boards that don't have the normal Marvell PHYs.
6343+ *
6344+ * This function must be modified for every new Octeon board.
6345+ * Internally it uses switch statements based on the cvmx_sysinfo
6346+ * data to determine board types and revisions. It relies on the
6347+ * fact that every Octeon board receives a unique board type
6348+ * enumeration from the bootloader.
6349+ *
6350+ * @ipd_port: IPD input port associated with the port we want to get link
6351+ * status for.
6352+ *
6353+ * Returns The ports link status. If the link isn't fully resolved, this must
6354+ * return zero.
6355+ */
6356+cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
6357+{
6358+ cvmx_helper_link_info_t result;
6359+ int phy_addr;
6360+ int is_broadcom_phy = 0;
6361+
6362+ /* Give the user a chance to override the processing of this function */
6363+ if (cvmx_override_board_link_get)
6364+ return cvmx_override_board_link_get(ipd_port);
6365+
6366+ /* Unless we fix it later, all links are defaulted to down */
6367+ result.u64 = 0;
6368+
6369+ /*
6370+ * This switch statement should handle all ports that either don't use
6371+ * Marvell PHYS, or don't support in-band status.
6372+ */
6373+ switch (cvmx_sysinfo_get()->board_type) {
6374+ case CVMX_BOARD_TYPE_SIM:
6375+ /* The simulator gives you a simulated 1Gbps full duplex link */
6376+ result.s.link_up = 1;
6377+ result.s.full_duplex = 1;
6378+ result.s.speed = 1000;
6379+ return result;
6380+ case CVMX_BOARD_TYPE_EBH3100:
6381+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
6382+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6383+ case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
6384+ /* Port 1 on these boards is always Gigabit */
6385+ if (ipd_port == 1) {
6386+ result.s.link_up = 1;
6387+ result.s.full_duplex = 1;
6388+ result.s.speed = 1000;
6389+ return result;
6390+ }
6391+ /* Fall through to the generic code below */
6392+ break;
6393+ case CVMX_BOARD_TYPE_CUST_NB5:
6394+ /* Port 1 on these boards is always Gigabit */
6395+ if (ipd_port == 1) {
6396+ result.s.link_up = 1;
6397+ result.s.full_duplex = 1;
6398+ result.s.speed = 1000;
6399+ return result;
6400+ } else /* The other port uses a broadcom PHY */
6401+ is_broadcom_phy = 1;
6402+ break;
6403+ case CVMX_BOARD_TYPE_BBGW_REF:
6404+ /* Port 1 on these boards is always Gigabit */
6405+ if (ipd_port == 2) {
6406+ /* Port 2 is not hooked up */
6407+ result.u64 = 0;
6408+ return result;
6409+ } else {
6410+ /* Ports 0 and 1 connect to the switch */
6411+ result.s.link_up = 1;
6412+ result.s.full_duplex = 1;
6413+ result.s.speed = 1000;
6414+ return result;
6415+ }
6416+ break;
6417+ }
6418+
6419+ phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
6420+ if (phy_addr != -1) {
6421+ if (is_broadcom_phy) {
6422+ /*
6423+ * Below we are going to read SMI/MDIO
6424+ * register 0x19 which works on Broadcom
6425+ * parts
6426+ */
6427+ int phy_status =
6428+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6429+ 0x19);
6430+ switch ((phy_status >> 8) & 0x7) {
6431+ case 0:
6432+ result.u64 = 0;
6433+ break;
6434+ case 1:
6435+ result.s.link_up = 1;
6436+ result.s.full_duplex = 0;
6437+ result.s.speed = 10;
6438+ break;
6439+ case 2:
6440+ result.s.link_up = 1;
6441+ result.s.full_duplex = 1;
6442+ result.s.speed = 10;
6443+ break;
6444+ case 3:
6445+ result.s.link_up = 1;
6446+ result.s.full_duplex = 0;
6447+ result.s.speed = 100;
6448+ break;
6449+ case 4:
6450+ result.s.link_up = 1;
6451+ result.s.full_duplex = 1;
6452+ result.s.speed = 100;
6453+ break;
6454+ case 5:
6455+ result.s.link_up = 1;
6456+ result.s.full_duplex = 1;
6457+ result.s.speed = 100;
6458+ break;
6459+ case 6:
6460+ result.s.link_up = 1;
6461+ result.s.full_duplex = 0;
6462+ result.s.speed = 1000;
6463+ break;
6464+ case 7:
6465+ result.s.link_up = 1;
6466+ result.s.full_duplex = 1;
6467+ result.s.speed = 1000;
6468+ break;
6469+ }
6470+ } else {
6471+ /*
6472+ * This code assumes we are using a Marvell
6473+ * Gigabit PHY. All the speed information can
6474+ * be read from register 17 in one
6475+ * go. Somebody using a different PHY will
6476+ * need to handle it above in the board
6477+ * specific area.
6478+ */
6479+ int phy_status =
6480+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17);
6481+
6482+ /*
6483+ * If the resolve bit 11 isn't set, see if
6484+ * autoneg is turned off (bit 12, reg 0). The
6485+ * resolve bit doesn't get set properly when
6486+ * autoneg is off, so force it.
6487+ */
6488+ if ((phy_status & (1 << 11)) == 0) {
6489+ int auto_status =
6490+ cvmx_mdio_read(phy_addr >> 8,
6491+ phy_addr & 0xff, 0);
6492+ if ((auto_status & (1 << 12)) == 0)
6493+ phy_status |= 1 << 11;
6494+ }
6495+
6496+ /*
6497+ * Only return a link if the PHY has finished
6498+ * auto negotiation and set the resolved bit
6499+ * (bit 11)
6500+ */
6501+ if (phy_status & (1 << 11)) {
6502+ result.s.link_up = 1;
6503+ result.s.full_duplex = ((phy_status >> 13) & 1);
6504+ switch ((phy_status >> 14) & 3) {
6505+ case 0: /* 10 Mbps */
6506+ result.s.speed = 10;
6507+ break;
6508+ case 1: /* 100 Mbps */
6509+ result.s.speed = 100;
6510+ break;
6511+ case 2: /* 1 Gbps */
6512+ result.s.speed = 1000;
6513+ break;
6514+ case 3: /* Illegal */
6515+ result.u64 = 0;
6516+ break;
6517+ }
6518+ }
6519+ }
6520+ } else if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
6521+ || OCTEON_IS_MODEL(OCTEON_CN58XX)
6522+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
6523+ /*
6524+ * We don't have a PHY address, so attempt to use
6525+ * in-band status. It is really important that boards
6526+ * not supporting in-band status never get
6527+ * here. Reading broken in-band status tends to do bad
6528+ * things
6529+ */
6530+ union cvmx_gmxx_rxx_rx_inbnd inband_status;
6531+ int interface = cvmx_helper_get_interface_num(ipd_port);
6532+ int index = cvmx_helper_get_interface_index_num(ipd_port);
6533+ inband_status.u64 =
6534+ cvmx_read_csr(CVMX_GMXX_RXX_RX_INBND(index, interface));
6535+
6536+ result.s.link_up = inband_status.s.status;
6537+ result.s.full_duplex = inband_status.s.duplex;
6538+ switch (inband_status.s.speed) {
6539+ case 0: /* 10 Mbps */
6540+ result.s.speed = 10;
6541+ break;
6542+ case 1: /* 100 Mbps */
6543+ result.s.speed = 100;
6544+ break;
6545+ case 2: /* 1 Gbps */
6546+ result.s.speed = 1000;
6547+ break;
6548+ case 3: /* Illegal */
6549+ result.u64 = 0;
6550+ break;
6551+ }
6552+ } else {
6553+ /*
6554+ * We don't have a PHY address and we don't have
6555+ * in-band status. There is no way to determine the
6556+ * link speed. Return down assuming this port isn't
6557+ * wired
6558+ */
6559+ result.u64 = 0;
6560+ }
6561+
6562+ /* If link is down, return all fields as zero. */
6563+ if (!result.s.link_up)
6564+ result.u64 = 0;
6565+
6566+ return result;
6567+}
6568+
6569+/**
6570+ * This function as a board specific method of changing the PHY
6571+ * speed, duplex, and auto-negotiation. This programs the PHY and
6572+ * not Octeon. This can be used to force Octeon's links to
6573+ * specific settings.
6574+ *
6575+ * @phy_addr: The address of the PHY to program
6576+ * @enable_autoneg:
6577+ * Non zero if you want to enable auto-negotiation.
6578+ * @link_info: Link speed to program. If the speed is zero and auto-negotiation
6579+ * is enabled, all possible negotiation speeds are advertised.
6580+ *
6581+ * Returns Zero on success, negative on failure
6582+ */
6583+int cvmx_helper_board_link_set_phy(int phy_addr,
6584+ cvmx_helper_board_set_phy_link_flags_types_t
6585+ link_flags,
6586+ cvmx_helper_link_info_t link_info)
6587+{
6588+
6589+ /* Set the flow control settings based on link_flags */
6590+ if ((link_flags & set_phy_link_flags_flow_control_mask) !=
6591+ set_phy_link_flags_flow_control_dont_touch) {
6592+ cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6593+ reg_autoneg_adver.u16 =
6594+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6595+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6596+ reg_autoneg_adver.s.asymmetric_pause =
6597+ (link_flags & set_phy_link_flags_flow_control_mask) ==
6598+ set_phy_link_flags_flow_control_enable;
6599+ reg_autoneg_adver.s.pause =
6600+ (link_flags & set_phy_link_flags_flow_control_mask) ==
6601+ set_phy_link_flags_flow_control_enable;
6602+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6603+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6604+ reg_autoneg_adver.u16);
6605+ }
6606+
6607+ /* If speed isn't set and autoneg is on advertise all supported modes */
6608+ if ((link_flags & set_phy_link_flags_autoneg)
6609+ && (link_info.s.speed == 0)) {
6610+ cvmx_mdio_phy_reg_control_t reg_control;
6611+ cvmx_mdio_phy_reg_status_t reg_status;
6612+ cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6613+ cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
6614+ cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
6615+
6616+ reg_status.u16 =
6617+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6618+ CVMX_MDIO_PHY_REG_STATUS);
6619+ reg_autoneg_adver.u16 =
6620+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6621+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6622+ reg_autoneg_adver.s.advert_100base_t4 =
6623+ reg_status.s.capable_100base_t4;
6624+ reg_autoneg_adver.s.advert_10base_tx_full =
6625+ reg_status.s.capable_10_full;
6626+ reg_autoneg_adver.s.advert_10base_tx_half =
6627+ reg_status.s.capable_10_half;
6628+ reg_autoneg_adver.s.advert_100base_tx_full =
6629+ reg_status.s.capable_100base_x_full;
6630+ reg_autoneg_adver.s.advert_100base_tx_half =
6631+ reg_status.s.capable_100base_x_half;
6632+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6633+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6634+ reg_autoneg_adver.u16);
6635+ if (reg_status.s.capable_extended_status) {
6636+ reg_extended_status.u16 =
6637+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6638+ CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
6639+ reg_control_1000.u16 =
6640+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6641+ CVMX_MDIO_PHY_REG_CONTROL_1000);
6642+ reg_control_1000.s.advert_1000base_t_full =
6643+ reg_extended_status.s.capable_1000base_t_full;
6644+ reg_control_1000.s.advert_1000base_t_half =
6645+ reg_extended_status.s.capable_1000base_t_half;
6646+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6647+ CVMX_MDIO_PHY_REG_CONTROL_1000,
6648+ reg_control_1000.u16);
6649+ }
6650+ reg_control.u16 =
6651+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6652+ CVMX_MDIO_PHY_REG_CONTROL);
6653+ reg_control.s.autoneg_enable = 1;
6654+ reg_control.s.restart_autoneg = 1;
6655+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6656+ CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6657+ } else if ((link_flags & set_phy_link_flags_autoneg)) {
6658+ cvmx_mdio_phy_reg_control_t reg_control;
6659+ cvmx_mdio_phy_reg_status_t reg_status;
6660+ cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6661+ cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
6662+ cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
6663+
6664+ reg_status.u16 =
6665+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6666+ CVMX_MDIO_PHY_REG_STATUS);
6667+ reg_autoneg_adver.u16 =
6668+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6669+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6670+ reg_autoneg_adver.s.advert_100base_t4 = 0;
6671+ reg_autoneg_adver.s.advert_10base_tx_full = 0;
6672+ reg_autoneg_adver.s.advert_10base_tx_half = 0;
6673+ reg_autoneg_adver.s.advert_100base_tx_full = 0;
6674+ reg_autoneg_adver.s.advert_100base_tx_half = 0;
6675+ if (reg_status.s.capable_extended_status) {
6676+ reg_extended_status.u16 =
6677+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6678+ CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
6679+ reg_control_1000.u16 =
6680+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6681+ CVMX_MDIO_PHY_REG_CONTROL_1000);
6682+ reg_control_1000.s.advert_1000base_t_full = 0;
6683+ reg_control_1000.s.advert_1000base_t_half = 0;
6684+ }
6685+ switch (link_info.s.speed) {
6686+ case 10:
6687+ reg_autoneg_adver.s.advert_10base_tx_full =
6688+ link_info.s.full_duplex;
6689+ reg_autoneg_adver.s.advert_10base_tx_half =
6690+ !link_info.s.full_duplex;
6691+ break;
6692+ case 100:
6693+ reg_autoneg_adver.s.advert_100base_tx_full =
6694+ link_info.s.full_duplex;
6695+ reg_autoneg_adver.s.advert_100base_tx_half =
6696+ !link_info.s.full_duplex;
6697+ break;
6698+ case 1000:
6699+ reg_control_1000.s.advert_1000base_t_full =
6700+ link_info.s.full_duplex;
6701+ reg_control_1000.s.advert_1000base_t_half =
6702+ !link_info.s.full_duplex;
6703+ break;
6704+ }
6705+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6706+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6707+ reg_autoneg_adver.u16);
6708+ if (reg_status.s.capable_extended_status)
6709+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6710+ CVMX_MDIO_PHY_REG_CONTROL_1000,
6711+ reg_control_1000.u16);
6712+ reg_control.u16 =
6713+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6714+ CVMX_MDIO_PHY_REG_CONTROL);
6715+ reg_control.s.autoneg_enable = 1;
6716+ reg_control.s.restart_autoneg = 1;
6717+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6718+ CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6719+ } else {
6720+ cvmx_mdio_phy_reg_control_t reg_control;
6721+ reg_control.u16 =
6722+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6723+ CVMX_MDIO_PHY_REG_CONTROL);
6724+ reg_control.s.autoneg_enable = 0;
6725+ reg_control.s.restart_autoneg = 1;
6726+ reg_control.s.duplex = link_info.s.full_duplex;
6727+ if (link_info.s.speed == 1000) {
6728+ reg_control.s.speed_msb = 1;
6729+ reg_control.s.speed_lsb = 0;
6730+ } else if (link_info.s.speed == 100) {
6731+ reg_control.s.speed_msb = 0;
6732+ reg_control.s.speed_lsb = 1;
6733+ } else if (link_info.s.speed == 10) {
6734+ reg_control.s.speed_msb = 0;
6735+ reg_control.s.speed_lsb = 0;
6736+ }
6737+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6738+ CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6739+ }
6740+ return 0;
6741+}
6742+
6743+/**
6744+ * This function is called by cvmx_helper_interface_probe() after it
6745+ * determines the number of ports Octeon can support on a specific
6746+ * interface. This function is the per board location to override
6747+ * this value. It is called with the number of ports Octeon might
6748+ * support and should return the number of actual ports on the
6749+ * board.
6750+ *
6751+ * This function must be modifed for every new Octeon board.
6752+ * Internally it uses switch statements based on the cvmx_sysinfo
6753+ * data to determine board types and revisions. It relys on the
6754+ * fact that every Octeon board receives a unique board type
6755+ * enumeration from the bootloader.
6756+ *
6757+ * @interface: Interface to probe
6758+ * @supported_ports:
6759+ * Number of ports Octeon supports.
6760+ *
6761+ * Returns Number of ports the actual board supports. Many times this will
6762+ * simple be "support_ports".
6763+ */
6764+int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
6765+{
6766+ switch (cvmx_sysinfo_get()->board_type) {
6767+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6768+ if (interface == 0)
6769+ return 2;
6770+ break;
6771+ case CVMX_BOARD_TYPE_BBGW_REF:
6772+ if (interface == 0)
6773+ return 2;
6774+ break;
6775+ case CVMX_BOARD_TYPE_NIC_XLE_4G:
6776+ if (interface == 0)
6777+ return 0;
6778+ break;
6779+ /* The 2nd interface on the EBH5600 is connected to the Marvel switch,
6780+ which we don't support. Disable ports connected to it */
6781+ case CVMX_BOARD_TYPE_EBH5600:
6782+ if (interface == 1)
6783+ return 0;
6784+ break;
6785+ }
6786+ return supported_ports;
6787+}
6788+
6789+/**
6790+ * Enable packet input/output from the hardware. This function is
6791+ * called after by cvmx_helper_packet_hardware_enable() to
6792+ * perform board specific initialization. For most boards
6793+ * nothing is needed.
6794+ *
6795+ * @interface: Interface to enable
6796+ *
6797+ * Returns Zero on success, negative on failure
6798+ */
6799+int __cvmx_helper_board_hardware_enable(int interface)
6800+{
6801+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5) {
6802+ if (interface == 0) {
6803+ /* Different config for switch port */
6804+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0);
6805+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
6806+ /*
6807+ * Boards with gigabit WAN ports need a
6808+ * different setting that is compatible with
6809+ * 100 Mbit settings
6810+ */
6811+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface),
6812+ 0xc);
6813+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface),
6814+ 0xc);
6815+ }
6816+ } else if (cvmx_sysinfo_get()->board_type ==
6817+ CVMX_BOARD_TYPE_CN3010_EVB_HS5) {
6818+ /*
6819+ * Broadcom PHYs require differnet ASX
6820+ * clocks. Unfortunately many boards don't define a
6821+ * new board Id and simply mangle the
6822+ * CN3010_EVB_HS5
6823+ */
6824+ if (interface == 0) {
6825+ /*
6826+ * Some boards use a hacked up bootloader that
6827+ * identifies them as CN3010_EVB_HS5
6828+ * evaluation boards. This leads to all kinds
6829+ * of configuration problems. Detect one
6830+ * case, and print warning, while trying to do
6831+ * the right thing.
6832+ */
6833+ int phy_addr = cvmx_helper_board_get_mii_address(0);
6834+ if (phy_addr != -1) {
6835+ int phy_identifier =
6836+ cvmx_mdio_read(phy_addr >> 8,
6837+ phy_addr & 0xff, 0x2);
6838+ /* Is it a Broadcom PHY? */
6839+ if (phy_identifier == 0x0143) {
6840+ cvmx_dprintf("\n");
6841+ cvmx_dprintf("ERROR:\n");
6842+ cvmx_dprintf
6843+ ("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n");
6844+ cvmx_dprintf
6845+ ("ERROR: The board type is mis-configured, and software malfunctions are likely.\n");
6846+ cvmx_dprintf
6847+ ("ERROR: All boards require a unique board type to identify them.\n");
6848+ cvmx_dprintf("ERROR:\n");
6849+ cvmx_dprintf("\n");
6850+ cvmx_wait(1000000000);
6851+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX
6852+ (0, interface), 5);
6853+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX
6854+ (0, interface), 5);
6855+ }
6856+ }
6857+ }
6858+ }
6859+ return 0;
6860+}
6861+
6862+cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void)
6863+{
6864+ switch (cvmx_sysinfo_get()->board_type) {
6865+ case CVMX_BOARD_TYPE_BBGW_REF:
6866+ return USB_CLOCK_TYPE_CRYSTAL_12;
6867+ }
6868+ return USB_CLOCK_TYPE_REF_48;
6869+}
6870+
6871+int __cvmx_helper_board_usb_get_num_ports(int supported_ports)
6872+{
6873+ switch (cvmx_sysinfo_get()->board_type) {
6874+ case CVMX_BOARD_TYPE_NIC_XLE_4G:
6875+ return 0;
6876+ }
6877+
6878+ return supported_ports;
6879+}
6880--- /dev/null
6881+++ b/drivers/staging/octeon/cvmx-helper-board.h
6882@@ -0,0 +1,180 @@
6883+/***********************license start***************
6884+ * Author: Cavium Networks
6885+ *
6886+ * Contact: support@caviumnetworks.com
6887+ * This file is part of the OCTEON SDK
6888+ *
6889+ * Copyright (c) 2003-2008 Cavium Networks
6890+ *
6891+ * This file is free software; you can redistribute it and/or modify
6892+ * it under the terms of the GNU General Public License, Version 2, as
6893+ * published by the Free Software Foundation.
6894+ *
6895+ * This file is distributed in the hope that it will be useful, but
6896+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
6897+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
6898+ * NONINFRINGEMENT. See the GNU General Public License for more
6899+ * details.
6900+ *
6901+ * You should have received a copy of the GNU General Public License
6902+ * along with this file; if not, write to the Free Software
6903+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6904+ * or visit http://www.gnu.org/licenses/.
6905+ *
6906+ * This file may also be available under a different license from Cavium.
6907+ * Contact Cavium Networks for more information
6908+ ***********************license end**************************************/
6909+
6910+/**
6911+ *
6912+ * Helper functions to abstract board specific data about
6913+ * network ports from the rest of the cvmx-helper files.
6914+ *
6915+ */
6916+#ifndef __CVMX_HELPER_BOARD_H__
6917+#define __CVMX_HELPER_BOARD_H__
6918+
6919+#include "cvmx-helper.h"
6920+
6921+typedef enum {
6922+ USB_CLOCK_TYPE_REF_12,
6923+ USB_CLOCK_TYPE_REF_24,
6924+ USB_CLOCK_TYPE_REF_48,
6925+ USB_CLOCK_TYPE_CRYSTAL_12,
6926+} cvmx_helper_board_usb_clock_types_t;
6927+
6928+typedef enum {
6929+ set_phy_link_flags_autoneg = 0x1,
6930+ set_phy_link_flags_flow_control_dont_touch = 0x0 << 1,
6931+ set_phy_link_flags_flow_control_enable = 0x1 << 1,
6932+ set_phy_link_flags_flow_control_disable = 0x2 << 1,
6933+ set_phy_link_flags_flow_control_mask = 0x3 << 1, /* Mask for 2 bit wide flow control field */
6934+} cvmx_helper_board_set_phy_link_flags_types_t;
6935+
6936+/**
6937+ * cvmx_override_board_link_get(int ipd_port) is a function
6938+ * pointer. It is meant to allow customization of the process of
6939+ * talking to a PHY to determine link speed. It is called every
6940+ * time a PHY must be polled for link status. Users should set
6941+ * this pointer to a function before calling any cvmx-helper
6942+ * operations.
6943+ */
6944+extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port);
6945+
6946+/**
6947+ * Return the MII PHY address associated with the given IPD
6948+ * port. A result of -1 means there isn't a MII capable PHY
6949+ * connected to this port. On chips supporting multiple MII
6950+ * busses the bus number is encoded in bits <15:8>.
6951+ *
6952+ * This function must be modifed for every new Octeon board.
6953+ * Internally it uses switch statements based on the cvmx_sysinfo
6954+ * data to determine board types and revisions. It relys on the
6955+ * fact that every Octeon board receives a unique board type
6956+ * enumeration from the bootloader.
6957+ *
6958+ * @ipd_port: Octeon IPD port to get the MII address for.
6959+ *
6960+ * Returns MII PHY address and bus number or -1.
6961+ */
6962+extern int cvmx_helper_board_get_mii_address(int ipd_port);
6963+
6964+/**
6965+ * This function as a board specific method of changing the PHY
6966+ * speed, duplex, and autonegotiation. This programs the PHY and
6967+ * not Octeon. This can be used to force Octeon's links to
6968+ * specific settings.
6969+ *
6970+ * @phy_addr: The address of the PHY to program
6971+ * @link_flags:
6972+ * Flags to control autonegotiation. Bit 0 is autonegotiation
6973+ * enable/disable to maintain backware compatability.
6974+ * @link_info: Link speed to program. If the speed is zero and autonegotiation
6975+ * is enabled, all possible negotiation speeds are advertised.
6976+ *
6977+ * Returns Zero on success, negative on failure
6978+ */
6979+int cvmx_helper_board_link_set_phy(int phy_addr,
6980+ cvmx_helper_board_set_phy_link_flags_types_t
6981+ link_flags,
6982+ cvmx_helper_link_info_t link_info);
6983+
6984+/**
6985+ * This function is the board specific method of determining an
6986+ * ethernet ports link speed. Most Octeon boards have Marvell PHYs
6987+ * and are handled by the fall through case. This function must be
6988+ * updated for boards that don't have the normal Marvell PHYs.
6989+ *
6990+ * This function must be modifed for every new Octeon board.
6991+ * Internally it uses switch statements based on the cvmx_sysinfo
6992+ * data to determine board types and revisions. It relys on the
6993+ * fact that every Octeon board receives a unique board type
6994+ * enumeration from the bootloader.
6995+ *
6996+ * @ipd_port: IPD input port associated with the port we want to get link
6997+ * status for.
6998+ *
6999+ * Returns The ports link status. If the link isn't fully resolved, this must
7000+ * return zero.
7001+ */
7002+extern cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port);
7003+
7004+/**
7005+ * This function is called by cvmx_helper_interface_probe() after it
7006+ * determines the number of ports Octeon can support on a specific
7007+ * interface. This function is the per board location to override
7008+ * this value. It is called with the number of ports Octeon might
7009+ * support and should return the number of actual ports on the
7010+ * board.
7011+ *
7012+ * This function must be modifed for every new Octeon board.
7013+ * Internally it uses switch statements based on the cvmx_sysinfo
7014+ * data to determine board types and revisions. It relys on the
7015+ * fact that every Octeon board receives a unique board type
7016+ * enumeration from the bootloader.
7017+ *
7018+ * @interface: Interface to probe
7019+ * @supported_ports:
7020+ * Number of ports Octeon supports.
7021+ *
7022+ * Returns Number of ports the actual board supports. Many times this will
7023+ * simple be "support_ports".
7024+ */
7025+extern int __cvmx_helper_board_interface_probe(int interface,
7026+ int supported_ports);
7027+
7028+/**
7029+ * Enable packet input/output from the hardware. This function is
7030+ * called after by cvmx_helper_packet_hardware_enable() to
7031+ * perform board specific initialization. For most boards
7032+ * nothing is needed.
7033+ *
7034+ * @interface: Interface to enable
7035+ *
7036+ * Returns Zero on success, negative on failure
7037+ */
7038+extern int __cvmx_helper_board_hardware_enable(int interface);
7039+
7040+/**
7041+ * Gets the clock type used for the USB block based on board type.
7042+ * Used by the USB code for auto configuration of clock type.
7043+ *
7044+ * Returns USB clock type enumeration
7045+ */
7046+cvmx_helper_board_usb_clock_types_t
7047+__cvmx_helper_board_usb_get_clock_type(void);
7048+
7049+/**
7050+ * Adjusts the number of available USB ports on Octeon based on board
7051+ * specifics.
7052+ *
7053+ * @supported_ports: expected number of ports based on chip type;
7054+ *
7055+ *
7056+ * Returns number of available usb ports, based on board specifics.
7057+ * Return value is supported_ports if function does not
7058+ * override.
7059+ */
7060+int __cvmx_helper_board_usb_get_num_ports(int supported_ports);
7061+
7062+#endif /* __CVMX_HELPER_BOARD_H__ */
7063--- /dev/null
7064+++ b/drivers/staging/octeon/cvmx-helper-fpa.c
7065@@ -0,0 +1,243 @@
7066+/***********************license start***************
7067+ * Author: Cavium Networks
7068+ *
7069+ * Contact: support@caviumnetworks.com
7070+ * This file is part of the OCTEON SDK
7071+ *
7072+ * Copyright (c) 2003-2008 Cavium Networks
7073+ *
7074+ * This file is free software; you can redistribute it and/or modify
7075+ * it under the terms of the GNU General Public License, Version 2, as
7076+ * published by the Free Software Foundation.
7077+ *
7078+ * This file is distributed in the hope that it will be useful, but
7079+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7080+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7081+ * NONINFRINGEMENT. See the GNU General Public License for more
7082+ * details.
7083+ *
7084+ * You should have received a copy of the GNU General Public License
7085+ * along with this file; if not, write to the Free Software
7086+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7087+ * or visit http://www.gnu.org/licenses/.
7088+ *
7089+ * This file may also be available under a different license from Cavium.
7090+ * Contact Cavium Networks for more information
7091+ ***********************license end**************************************/
7092+
7093+/**
7094+ * @file
7095+ *
7096+ * Helper functions for FPA setup.
7097+ *
7098+ */
7099+#include "executive-config.h"
7100+#include "cvmx-config.h"
7101+#include "cvmx.h"
7102+#include "cvmx-bootmem.h"
7103+#include "cvmx-fpa.h"
7104+#include "cvmx-helper-fpa.h"
7105+
7106+/**
7107+ * Allocate memory for and initialize a single FPA pool.
7108+ *
7109+ * @pool: Pool to initialize
7110+ * @buffer_size: Size of buffers to allocate in bytes
7111+ * @buffers: Number of buffers to put in the pool. Zero is allowed
7112+ * @name: String name of the pool for debugging purposes
7113+ * Returns Zero on success, non-zero on failure
7114+ */
7115+static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size,
7116+ uint64_t buffers, const char *name)
7117+{
7118+ uint64_t current_num;
7119+ void *memory;
7120+ uint64_t align = CVMX_CACHE_LINE_SIZE;
7121+
7122+ /*
7123+ * Align the allocation so that power of 2 size buffers are
7124+ * naturally aligned.
7125+ */
7126+ while (align < buffer_size)
7127+ align = align << 1;
7128+
7129+ if (buffers == 0)
7130+ return 0;
7131+
7132+ current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool));
7133+ if (current_num) {
7134+ cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. "
7135+ "Skipping setup.\n",
7136+ pool, name, (unsigned long long)current_num);
7137+ return 0;
7138+ }
7139+
7140+ memory = cvmx_bootmem_alloc(buffer_size * buffers, align);
7141+ if (memory == NULL) {
7142+ cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n",
7143+ pool, name);
7144+ return -1;
7145+ }
7146+ cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers);
7147+ return 0;
7148+}
7149+
7150+/**
7151+ * Allocate memory and initialize the FPA pools using memory
7152+ * from cvmx-bootmem. Specifying zero for the number of
7153+ * buffers will cause that FPA pool to not be setup. This is
7154+ * useful if you aren't using some of the hardware and want
7155+ * to save memory. Use cvmx_helper_initialize_fpa instead of
7156+ * this function directly.
7157+ *
7158+ * @pip_pool: Should always be CVMX_FPA_PACKET_POOL
7159+ * @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE
7160+ * @pip_buffers:
7161+ * Number of packet buffers.
7162+ * @wqe_pool: Should always be CVMX_FPA_WQE_POOL
7163+ * @wqe_size: Should always be CVMX_FPA_WQE_POOL_SIZE
7164+ * @wqe_entries:
7165+ * Number of work queue entries
7166+ * @pko_pool: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL
7167+ * @pko_size: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
7168+ * @pko_buffers:
7169+ * PKO Command buffers. You should at minimum have two per
7170+ * each PKO queue.
7171+ * @tim_pool: Should always be CVMX_FPA_TIMER_POOL
7172+ * @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE
7173+ * @tim_buffers:
7174+ * TIM ring buffer command queues. At least two per timer bucket
7175+ * is recommened.
7176+ * @dfa_pool: Should always be CVMX_FPA_DFA_POOL
7177+ * @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE
7178+ * @dfa_buffers:
7179+ * DFA command buffer. A relatively small (32 for example)
7180+ * number should work.
7181+ * Returns Zero on success, non-zero if out of memory
7182+ */
7183+static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size,
7184+ int pip_buffers, int wqe_pool,
7185+ int wqe_size, int wqe_entries,
7186+ int pko_pool, int pko_size,
7187+ int pko_buffers, int tim_pool,
7188+ int tim_size, int tim_buffers,
7189+ int dfa_pool, int dfa_size,
7190+ int dfa_buffers)
7191+{
7192+ int status;
7193+
7194+ cvmx_fpa_enable();
7195+
7196+ if ((pip_buffers > 0) && (pip_buffers <= 64))
7197+ cvmx_dprintf
7198+ ("Warning: %d packet buffers may not be enough for hardware"
7199+ " prefetch. 65 or more is recommended.\n", pip_buffers);
7200+
7201+ if (pip_pool >= 0) {
7202+ status =
7203+ __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size,
7204+ pip_buffers,
7205+ "Packet Buffers");
7206+ if (status)
7207+ return status;
7208+ }
7209+
7210+ if (wqe_pool >= 0) {
7211+ status =
7212+ __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size,
7213+ wqe_entries,
7214+ "Work Queue Entries");
7215+ if (status)
7216+ return status;
7217+ }
7218+
7219+ if (pko_pool >= 0) {
7220+ status =
7221+ __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size,
7222+ pko_buffers,
7223+ "PKO Command Buffers");
7224+ if (status)
7225+ return status;
7226+ }
7227+
7228+ if (tim_pool >= 0) {
7229+ status =
7230+ __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size,
7231+ tim_buffers,
7232+ "TIM Command Buffers");
7233+ if (status)
7234+ return status;
7235+ }
7236+
7237+ if (dfa_pool >= 0) {
7238+ status =
7239+ __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size,
7240+ dfa_buffers,
7241+ "DFA Command Buffers");
7242+ if (status)
7243+ return status;
7244+ }
7245+
7246+ return 0;
7247+}
7248+
7249+/**
7250+ * Allocate memory and initialize the FPA pools using memory
7251+ * from cvmx-bootmem. Sizes of each element in the pools is
7252+ * controlled by the cvmx-config.h header file. Specifying
7253+ * zero for any parameter will cause that FPA pool to not be
7254+ * setup. This is useful if you aren't using some of the
7255+ * hardware and want to save memory.
7256+ *
7257+ * @packet_buffers:
7258+ * Number of packet buffers to allocate
7259+ * @work_queue_entries:
7260+ * Number of work queue entries
7261+ * @pko_buffers:
7262+ * PKO Command buffers. You should at minimum have two per
7263+ * each PKO queue.
7264+ * @tim_buffers:
7265+ * TIM ring buffer command queues. At least two per timer bucket
7266+ * is recommened.
7267+ * @dfa_buffers:
7268+ * DFA command buffer. A relatively small (32 for example)
7269+ * number should work.
7270+ * Returns Zero on success, non-zero if out of memory
7271+ */
7272+int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries,
7273+ int pko_buffers, int tim_buffers,
7274+ int dfa_buffers)
7275+{
7276+#ifndef CVMX_FPA_PACKET_POOL
7277+#define CVMX_FPA_PACKET_POOL -1
7278+#define CVMX_FPA_PACKET_POOL_SIZE 0
7279+#endif
7280+#ifndef CVMX_FPA_WQE_POOL
7281+#define CVMX_FPA_WQE_POOL -1
7282+#define CVMX_FPA_WQE_POOL_SIZE 0
7283+#endif
7284+#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL
7285+#define CVMX_FPA_OUTPUT_BUFFER_POOL -1
7286+#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0
7287+#endif
7288+#ifndef CVMX_FPA_TIMER_POOL
7289+#define CVMX_FPA_TIMER_POOL -1
7290+#define CVMX_FPA_TIMER_POOL_SIZE 0
7291+#endif
7292+#ifndef CVMX_FPA_DFA_POOL
7293+#define CVMX_FPA_DFA_POOL -1
7294+#define CVMX_FPA_DFA_POOL_SIZE 0
7295+#endif
7296+ return __cvmx_helper_initialize_fpa(CVMX_FPA_PACKET_POOL,
7297+ CVMX_FPA_PACKET_POOL_SIZE,
7298+ packet_buffers, CVMX_FPA_WQE_POOL,
7299+ CVMX_FPA_WQE_POOL_SIZE,
7300+ work_queue_entries,
7301+ CVMX_FPA_OUTPUT_BUFFER_POOL,
7302+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
7303+ pko_buffers, CVMX_FPA_TIMER_POOL,
7304+ CVMX_FPA_TIMER_POOL_SIZE,
7305+ tim_buffers, CVMX_FPA_DFA_POOL,
7306+ CVMX_FPA_DFA_POOL_SIZE,
7307+ dfa_buffers);
7308+}
7309--- /dev/null
7310+++ b/drivers/staging/octeon/cvmx-helper-fpa.h
7311@@ -0,0 +1,64 @@
7312+/***********************license start***************
7313+ * Author: Cavium Networks
7314+ *
7315+ * Contact: support@caviumnetworks.com
7316+ * This file is part of the OCTEON SDK
7317+ *
7318+ * Copyright (c) 2003-2008 Cavium Networks
7319+ *
7320+ * This file is free software; you can redistribute it and/or modify
7321+ * it under the terms of the GNU General Public License, Version 2, as
7322+ * published by the Free Software Foundation.
7323+ *
7324+ * This file is distributed in the hope that it will be useful, but
7325+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7326+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7327+ * NONINFRINGEMENT. See the GNU General Public License for more
7328+ * details.
7329+ *
7330+ * You should have received a copy of the GNU General Public License
7331+ * along with this file; if not, write to the Free Software
7332+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7333+ * or visit http://www.gnu.org/licenses/.
7334+ *
7335+ * This file may also be available under a different license from Cavium.
7336+ * Contact Cavium Networks for more information
7337+ ***********************license end**************************************/
7338+
7339+/**
7340+ * @file
7341+ *
7342+ * Helper functions for FPA setup.
7343+ *
7344+ */
7345+#ifndef __CVMX_HELPER_H_FPA__
7346+#define __CVMX_HELPER_H_FPA__
7347+
7348+/**
7349+ * Allocate memory and initialize the FPA pools using memory
7350+ * from cvmx-bootmem. Sizes of each element in the pools is
7351+ * controlled by the cvmx-config.h header file. Specifying
7352+ * zero for any parameter will cause that FPA pool to not be
7353+ * setup. This is useful if you aren't using some of the
7354+ * hardware and want to save memory.
7355+ *
7356+ * @packet_buffers:
7357+ * Number of packet buffers to allocate
7358+ * @work_queue_entries:
7359+ * Number of work queue entries
7360+ * @pko_buffers:
7361+ * PKO Command buffers. You should at minimum have two per
7362+ * each PKO queue.
7363+ * @tim_buffers:
7364+ * TIM ring buffer command queues. At least two per timer bucket
7365+ * is recommened.
7366+ * @dfa_buffers:
7367+ * DFA command buffer. A relatively small (32 for example)
7368+ * number should work.
7369+ * Returns Zero on success, non-zero if out of memory
7370+ */
7371+extern int cvmx_helper_initialize_fpa(int packet_buffers,
7372+ int work_queue_entries, int pko_buffers,
7373+ int tim_buffers, int dfa_buffers);
7374+
7375+#endif /* __CVMX_HELPER_H__ */
7376--- /dev/null
7377+++ b/drivers/staging/octeon/cvmx-helper-loop.c
7378@@ -0,0 +1,85 @@
7379+/***********************license start***************
7380+ * Author: Cavium Networks
7381+ *
7382+ * Contact: support@caviumnetworks.com
7383+ * This file is part of the OCTEON SDK
7384+ *
7385+ * Copyright (c) 2003-2008 Cavium Networks
7386+ *
7387+ * This file is free software; you can redistribute it and/or modify
7388+ * it under the terms of the GNU General Public License, Version 2, as
7389+ * published by the Free Software Foundation.
7390+ *
7391+ * This file is distributed in the hope that it will be useful, but
7392+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7393+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7394+ * NONINFRINGEMENT. See the GNU General Public License for more
7395+ * details.
7396+ *
7397+ * You should have received a copy of the GNU General Public License
7398+ * along with this file; if not, write to the Free Software
7399+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7400+ * or visit http://www.gnu.org/licenses/.
7401+ *
7402+ * This file may also be available under a different license from Cavium.
7403+ * Contact Cavium Networks for more information
7404+ ***********************license end**************************************/
7405+
7406+/*
7407+ * Functions for LOOP initialization, configuration,
7408+ * and monitoring.
7409+ */
7410+#include <asm/octeon/octeon.h>
7411+
7412+#include "cvmx-config.h"
7413+
7414+#include "cvmx-helper.h"
7415+#include "cvmx-pip-defs.h"
7416+
7417+/**
7418+ * Probe a LOOP interface and determine the number of ports
7419+ * connected to it. The LOOP interface should still be down
7420+ * after this call.
7421+ *
7422+ * @interface: Interface to probe
7423+ *
7424+ * Returns Number of ports on the interface. Zero to disable.
7425+ */
7426+int __cvmx_helper_loop_probe(int interface)
7427+{
7428+ union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
7429+ int num_ports = 4;
7430+ int port;
7431+
7432+ /* We need to disable length checking so packet < 64 bytes and jumbo
7433+ frames don't get errors */
7434+ for (port = 0; port < num_ports; port++) {
7435+ union cvmx_pip_prt_cfgx port_cfg;
7436+ int ipd_port = cvmx_helper_get_ipd_port(interface, port);
7437+ port_cfg.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
7438+ port_cfg.s.maxerr_en = 0;
7439+ port_cfg.s.minerr_en = 0;
7440+ cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_cfg.u64);
7441+ }
7442+
7443+ /* Disable FCS stripping for loopback ports */
7444+ ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
7445+ ipd_sub_port_fcs.s.port_bit2 = 0;
7446+ cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
7447+ return num_ports;
7448+}
7449+
7450+/**
7451+ * Bringup and enable a LOOP interface. After this call packet
7452+ * I/O should be fully functional. This is called with IPD
7453+ * enabled but PKO disabled.
7454+ *
7455+ * @interface: Interface to bring up
7456+ *
7457+ * Returns Zero on success, negative on failure
7458+ */
7459+int __cvmx_helper_loop_enable(int interface)
7460+{
7461+ /* Do nothing. */
7462+ return 0;
7463+}
7464--- /dev/null
7465+++ b/drivers/staging/octeon/cvmx-helper-loop.h
7466@@ -0,0 +1,59 @@
7467+/***********************license start***************
7468+ * Author: Cavium Networks
7469+ *
7470+ * Contact: support@caviumnetworks.com
7471+ * This file is part of the OCTEON SDK
7472+ *
7473+ * Copyright (c) 2003-2008 Cavium Networks
7474+ *
7475+ * This file is free software; you can redistribute it and/or modify
7476+ * it under the terms of the GNU General Public License, Version 2, as published by
7477+ * the Free Software Foundation.
7478+ *
7479+ * This file is distributed in the hope that it will be useful,
7480+ * but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
7481+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
7482+ * See the GNU General Public License for more details.
7483+ *
7484+ * You should have received a copy of the GNU General Public License
7485+ * along with this file; if not, write to the Free Software
7486+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7487+ * or visit http://www.gnu.org/licenses/.
7488+ *
7489+ * This file may also be available under a different license from Cavium.
7490+ * Contact Cavium Networks for more information
7491+ ***********************license end**************************************/
7492+
7493+/**
7494+ * @file
7495+ *
7496+ * Functions for LOOP initialization, configuration,
7497+ * and monitoring.
7498+ *
7499+ */
7500+#ifndef __CVMX_HELPER_LOOP_H__
7501+#define __CVMX_HELPER_LOOP_H__
7502+
7503+/**
7504+ * Probe a LOOP interface and determine the number of ports
7505+ * connected to it. The LOOP interface should still be down after
7506+ * this call.
7507+ *
7508+ * @interface: Interface to probe
7509+ *
7510+ * Returns Number of ports on the interface. Zero to disable.
7511+ */
7512+extern int __cvmx_helper_loop_probe(int interface);
7513+
7514+/**
7515+ * Bringup and enable a LOOP interface. After this call packet
7516+ * I/O should be fully functional. This is called with IPD
7517+ * enabled but PKO disabled.
7518+ *
7519+ * @interface: Interface to bring up
7520+ *
7521+ * Returns Zero on success, negative on failure
7522+ */
7523+extern int __cvmx_helper_loop_enable(int interface);
7524+
7525+#endif
7526--- /dev/null
7527+++ b/drivers/staging/octeon/cvmx-helper-npi.c
7528@@ -0,0 +1,113 @@
7529+/***********************license start***************
7530+ * Author: Cavium Networks
7531+ *
7532+ * Contact: support@caviumnetworks.com
7533+ * This file is part of the OCTEON SDK
7534+ *
7535+ * Copyright (c) 2003-2008 Cavium Networks
7536+ *
7537+ * This file is free software; you can redistribute it and/or modify
7538+ * it under the terms of the GNU General Public License, Version 2, as
7539+ * published by the Free Software Foundation.
7540+ *
7541+ * This file is distributed in the hope that it will be useful, but
7542+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7543+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7544+ * NONINFRINGEMENT. See the GNU General Public License for more
7545+ * details.
7546+ *
7547+ * You should have received a copy of the GNU General Public License
7548+ * along with this file; if not, write to the Free Software
7549+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7550+ * or visit http://www.gnu.org/licenses/.
7551+ *
7552+ * This file may also be available under a different license from Cavium.
7553+ * Contact Cavium Networks for more information
7554+ ***********************license end**************************************/
7555+
7556+/*
7557+ * Functions for NPI initialization, configuration,
7558+ * and monitoring.
7559+ */
7560+#include <asm/octeon/octeon.h>
7561+
7562+#include "cvmx-config.h"
7563+
7564+#include "cvmx-helper.h"
7565+
7566+#include "cvmx-pip-defs.h"
7567+
7568+/**
7569+ * Probe a NPI interface and determine the number of ports
7570+ * connected to it. The NPI interface should still be down
7571+ * after this call.
7572+ *
7573+ * @interface: Interface to probe
7574+ *
7575+ * Returns Number of ports on the interface. Zero to disable.
7576+ */
7577+int __cvmx_helper_npi_probe(int interface)
7578+{
7579+#if CVMX_PKO_QUEUES_PER_PORT_PCI > 0
7580+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
7581+ return 4;
7582+ else if (OCTEON_IS_MODEL(OCTEON_CN56XX)
7583+ && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
7584+ /* The packet engines didn't exist before pass 2 */
7585+ return 4;
7586+ else if (OCTEON_IS_MODEL(OCTEON_CN52XX)
7587+ && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X))
7588+ /* The packet engines didn't exist before pass 2 */
7589+ return 4;
7590+#if 0
7591+ /*
7592+ * Technically CN30XX, CN31XX, and CN50XX contain packet
7593+ * engines, but nobody ever uses them. Since this is the case,
7594+ * we disable them here.
7595+ */
7596+ else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7597+ || OCTEON_IS_MODEL(OCTEON_CN50XX))
7598+ return 2;
7599+ else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
7600+ return 1;
7601+#endif
7602+#endif
7603+ return 0;
7604+}
7605+
7606+/**
7607+ * Bringup and enable a NPI interface. After this call packet
7608+ * I/O should be fully functional. This is called with IPD
7609+ * enabled but PKO disabled.
7610+ *
7611+ * @interface: Interface to bring up
7612+ *
7613+ * Returns Zero on success, negative on failure
7614+ */
7615+int __cvmx_helper_npi_enable(int interface)
7616+{
7617+ /*
7618+ * On CN50XX, CN52XX, and CN56XX we need to disable length
7619+ * checking so packet < 64 bytes and jumbo frames don't get
7620+ * errors.
7621+ */
7622+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
7623+ !OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7624+ int num_ports = cvmx_helper_ports_on_interface(interface);
7625+ int port;
7626+ for (port = 0; port < num_ports; port++) {
7627+ union cvmx_pip_prt_cfgx port_cfg;
7628+ int ipd_port =
7629+ cvmx_helper_get_ipd_port(interface, port);
7630+ port_cfg.u64 =
7631+ cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
7632+ port_cfg.s.maxerr_en = 0;
7633+ port_cfg.s.minerr_en = 0;
7634+ cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port),
7635+ port_cfg.u64);
7636+ }
7637+ }
7638+
7639+ /* Enables are controlled by the remote host, so nothing to do here */
7640+ return 0;
7641+}
7642--- /dev/null
7643+++ b/drivers/staging/octeon/cvmx-helper-npi.h
7644@@ -0,0 +1,60 @@
7645+/***********************license start***************
7646+ * Author: Cavium Networks
7647+ *
7648+ * Contact: support@caviumnetworks.com
7649+ * This file is part of the OCTEON SDK
7650+ *
7651+ * Copyright (c) 2003-2008 Cavium Networks
7652+ *
7653+ * This file is free software; you can redistribute it and/or modify
7654+ * it under the terms of the GNU General Public License, Version 2, as
7655+ * published by the Free Software Foundation.
7656+ *
7657+ * This file is distributed in the hope that it will be useful, but
7658+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7659+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7660+ * NONINFRINGEMENT. See the GNU General Public License for more
7661+ * details.
7662+ *
7663+ * You should have received a copy of the GNU General Public License
7664+ * along with this file; if not, write to the Free Software
7665+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7666+ * or visit http://www.gnu.org/licenses/.
7667+ *
7668+ * This file may also be available under a different license from Cavium.
7669+ * Contact Cavium Networks for more information
7670+ ***********************license end**************************************/
7671+
7672+/**
7673+ * @file
7674+ *
7675+ * Functions for NPI initialization, configuration,
7676+ * and monitoring.
7677+ *
7678+ */
7679+#ifndef __CVMX_HELPER_NPI_H__
7680+#define __CVMX_HELPER_NPI_H__
7681+
7682+/**
7683+ * Probe a NPI interface and determine the number of ports
7684+ * connected to it. The NPI interface should still be down after
7685+ * this call.
7686+ *
7687+ * @interface: Interface to probe
7688+ *
7689+ * Returns Number of ports on the interface. Zero to disable.
7690+ */
7691+extern int __cvmx_helper_npi_probe(int interface);
7692+
7693+/**
7694+ * Bringup and enable a NPI interface. After this call packet
7695+ * I/O should be fully functional. This is called with IPD
7696+ * enabled but PKO disabled.
7697+ *
7698+ * @interface: Interface to bring up
7699+ *
7700+ * Returns Zero on success, negative on failure
7701+ */
7702+extern int __cvmx_helper_npi_enable(int interface);
7703+
7704+#endif
7705--- /dev/null
7706+++ b/drivers/staging/octeon/cvmx-helper-rgmii.c
7707@@ -0,0 +1,525 @@
7708+/***********************license start***************
7709+ * Author: Cavium Networks
7710+ *
7711+ * Contact: support@caviumnetworks.com
7712+ * This file is part of the OCTEON SDK
7713+ *
7714+ * Copyright (c) 2003-2008 Cavium Networks
7715+ *
7716+ * This file is free software; you can redistribute it and/or modify
7717+ * it under the terms of the GNU General Public License, Version 2, as
7718+ * published by the Free Software Foundation.
7719+ *
7720+ * This file is distributed in the hope that it will be useful, but
7721+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7722+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7723+ * NONINFRINGEMENT. See the GNU General Public License for more
7724+ * details.
7725+ *
7726+ * You should have received a copy of the GNU General Public License
7727+ * along with this file; if not, write to the Free Software
7728+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7729+ * or visit http://www.gnu.org/licenses/.
7730+ *
7731+ * This file may also be available under a different license from Cavium.
7732+ * Contact Cavium Networks for more information
7733+ ***********************license end**************************************/
7734+
7735+/*
7736+ * Functions for RGMII/GMII/MII initialization, configuration,
7737+ * and monitoring.
7738+ */
7739+#include <asm/octeon/octeon.h>
7740+
7741+#include "cvmx-config.h"
7742+
7743+
7744+#include "cvmx-mdio.h"
7745+#include "cvmx-pko.h"
7746+#include "cvmx-helper.h"
7747+#include "cvmx-helper-board.h"
7748+
7749+#include <asm/octeon/cvmx-npi-defs.h>
7750+#include "cvmx-gmxx-defs.h"
7751+#include "cvmx-asxx-defs.h"
7752+#include "cvmx-dbg-defs.h"
7753+
7754+void __cvmx_interrupt_gmxx_enable(int interface);
7755+void __cvmx_interrupt_asxx_enable(int block);
7756+
7757+/**
7758+ * Probe RGMII ports and determine the number present
7759+ *
7760+ * @interface: Interface to probe
7761+ *
7762+ * Returns Number of RGMII/GMII/MII ports (0-4).
7763+ */
7764+int __cvmx_helper_rgmii_probe(int interface)
7765+{
7766+ int num_ports = 0;
7767+ union cvmx_gmxx_inf_mode mode;
7768+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
7769+
7770+ if (mode.s.type) {
7771+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)
7772+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7773+ cvmx_dprintf("ERROR: RGMII initialize called in "
7774+ "SPI interface\n");
7775+ } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7776+ || OCTEON_IS_MODEL(OCTEON_CN30XX)
7777+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7778+ /*
7779+ * On these chips "type" says we're in
7780+ * GMII/MII mode. This limits us to 2 ports
7781+ */
7782+ num_ports = 2;
7783+ } else {
7784+ cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
7785+ __func__);
7786+ }
7787+ } else {
7788+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)
7789+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7790+ num_ports = 4;
7791+ } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7792+ || OCTEON_IS_MODEL(OCTEON_CN30XX)
7793+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7794+ num_ports = 3;
7795+ } else {
7796+ cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
7797+ __func__);
7798+ }
7799+ }
7800+ return num_ports;
7801+}
7802+
7803+/**
7804+ * Put an RGMII interface in loopback mode. Internal packets sent
7805+ * out will be received back again on the same port. Externally
7806+ * received packets will echo back out.
7807+ *
7808+ * @port: IPD port number to loop.
7809+ */
7810+void cvmx_helper_rgmii_internal_loopback(int port)
7811+{
7812+ int interface = (port >> 4) & 1;
7813+ int index = port & 0xf;
7814+ uint64_t tmp;
7815+
7816+ union cvmx_gmxx_prtx_cfg gmx_cfg;
7817+ gmx_cfg.u64 = 0;
7818+ gmx_cfg.s.duplex = 1;
7819+ gmx_cfg.s.slottime = 1;
7820+ gmx_cfg.s.speed = 1;
7821+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
7822+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
7823+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
7824+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
7825+ tmp = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
7826+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), (1 << index) | tmp);
7827+ tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface));
7828+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), (1 << index) | tmp);
7829+ tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface));
7830+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), (1 << index) | tmp);
7831+ gmx_cfg.s.en = 1;
7832+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
7833+}
7834+
7835+/**
7836+ * Workaround ASX setup errata with CN38XX pass1
7837+ *
7838+ * @interface: Interface to setup
7839+ * @port: Port to setup (0..3)
7840+ * @cpu_clock_hz:
7841+ * Chip frequency in Hertz
7842+ *
7843+ * Returns Zero on success, negative on failure
7844+ */
7845+static int __cvmx_helper_errata_asx_pass1(int interface, int port,
7846+ int cpu_clock_hz)
7847+{
7848+ /* Set hi water mark as per errata GMX-4 */
7849+ if (cpu_clock_hz >= 325000000 && cpu_clock_hz < 375000000)
7850+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 12);
7851+ else if (cpu_clock_hz >= 375000000 && cpu_clock_hz < 437000000)
7852+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 11);
7853+ else if (cpu_clock_hz >= 437000000 && cpu_clock_hz < 550000000)
7854+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 10);
7855+ else if (cpu_clock_hz >= 550000000 && cpu_clock_hz < 687000000)
7856+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 9);
7857+ else
7858+ cvmx_dprintf("Illegal clock frequency (%d). "
7859+ "CVMX_ASXX_TX_HI_WATERX not set\n", cpu_clock_hz);
7860+ return 0;
7861+}
7862+
7863+/**
7864+ * Configure all of the ASX, GMX, and PKO regsiters required
7865+ * to get RGMII to function on the supplied interface.
7866+ *
7867+ * @interface: PKO Interface to configure (0 or 1)
7868+ *
7869+ * Returns Zero on success
7870+ */
7871+int __cvmx_helper_rgmii_enable(int interface)
7872+{
7873+ int num_ports = cvmx_helper_ports_on_interface(interface);
7874+ int port;
7875+ struct cvmx_sysinfo *sys_info_ptr = cvmx_sysinfo_get();
7876+ union cvmx_gmxx_inf_mode mode;
7877+ union cvmx_asxx_tx_prt_en asx_tx;
7878+ union cvmx_asxx_rx_prt_en asx_rx;
7879+
7880+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
7881+
7882+ if (mode.s.en == 0)
7883+ return -1;
7884+ if ((OCTEON_IS_MODEL(OCTEON_CN38XX) ||
7885+ OCTEON_IS_MODEL(OCTEON_CN58XX)) && mode.s.type == 1)
7886+ /* Ignore SPI interfaces */
7887+ return -1;
7888+
7889+ /* Configure the ASX registers needed to use the RGMII ports */
7890+ asx_tx.u64 = 0;
7891+ asx_tx.s.prt_en = cvmx_build_mask(num_ports);
7892+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), asx_tx.u64);
7893+
7894+ asx_rx.u64 = 0;
7895+ asx_rx.s.prt_en = cvmx_build_mask(num_ports);
7896+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), asx_rx.u64);
7897+
7898+ /* Configure the GMX registers needed to use the RGMII ports */
7899+ for (port = 0; port < num_ports; port++) {
7900+ /* Setting of CVMX_GMXX_TXX_THRESH has been moved to
7901+ __cvmx_helper_setup_gmx() */
7902+
7903+ if (cvmx_octeon_is_pass1())
7904+ __cvmx_helper_errata_asx_pass1(interface, port,
7905+ sys_info_ptr->
7906+ cpu_clock_hz);
7907+ else {
7908+ /*
7909+ * Configure more flexible RGMII preamble
7910+ * checking. Pass 1 doesn't support this
7911+ * feature.
7912+ */
7913+ union cvmx_gmxx_rxx_frm_ctl frm_ctl;
7914+ frm_ctl.u64 =
7915+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
7916+ (port, interface));
7917+ /* New field, so must be compile time */
7918+ frm_ctl.s.pre_free = 1;
7919+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(port, interface),
7920+ frm_ctl.u64);
7921+ }
7922+
7923+ /*
7924+ * Each pause frame transmitted will ask for about 10M
7925+ * bit times before resume. If buffer space comes
7926+ * available before that time has expired, an XON
7927+ * pause frame (0 time) will be transmitted to restart
7928+ * the flow.
7929+ */
7930+ cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_TIME(port, interface),
7931+ 20000);
7932+ cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL
7933+ (port, interface), 19000);
7934+
7935+ if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7936+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
7937+ 16);
7938+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
7939+ 16);
7940+ } else {
7941+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
7942+ 24);
7943+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
7944+ 24);
7945+ }
7946+ }
7947+
7948+ __cvmx_helper_setup_gmx(interface, num_ports);
7949+
7950+ /* enable the ports now */
7951+ for (port = 0; port < num_ports; port++) {
7952+ union cvmx_gmxx_prtx_cfg gmx_cfg;
7953+ cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port
7954+ (interface, port));
7955+ gmx_cfg.u64 =
7956+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(port, interface));
7957+ gmx_cfg.s.en = 1;
7958+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(port, interface),
7959+ gmx_cfg.u64);
7960+ }
7961+ __cvmx_interrupt_asxx_enable(interface);
7962+ __cvmx_interrupt_gmxx_enable(interface);
7963+
7964+ return 0;
7965+}
7966+
7967+/**
7968+ * Return the link state of an IPD/PKO port as returned by
7969+ * auto negotiation. The result of this function may not match
7970+ * Octeon's link config if auto negotiation has changed since
7971+ * the last call to cvmx_helper_link_set().
7972+ *
7973+ * @ipd_port: IPD/PKO port to query
7974+ *
7975+ * Returns Link state
7976+ */
7977+cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port)
7978+{
7979+ int interface = cvmx_helper_get_interface_num(ipd_port);
7980+ int index = cvmx_helper_get_interface_index_num(ipd_port);
7981+ union cvmx_asxx_prt_loop asxx_prt_loop;
7982+
7983+ asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
7984+ if (asxx_prt_loop.s.int_loop & (1 << index)) {
7985+ /* Force 1Gbps full duplex on internal loopback */
7986+ cvmx_helper_link_info_t result;
7987+ result.u64 = 0;
7988+ result.s.full_duplex = 1;
7989+ result.s.link_up = 1;
7990+ result.s.speed = 1000;
7991+ return result;
7992+ } else
7993+ return __cvmx_helper_board_link_get(ipd_port);
7994+}
7995+
7996+/**
7997+ * Configure an IPD/PKO port for the specified link state. This
7998+ * function does not influence auto negotiation at the PHY level.
7999+ * The passed link state must always match the link state returned
8000+ * by cvmx_helper_link_get(). It is normally best to use
8001+ * cvmx_helper_link_autoconf() instead.
8002+ *
8003+ * @ipd_port: IPD/PKO port to configure
8004+ * @link_info: The new link state
8005+ *
8006+ * Returns Zero on success, negative on failure
8007+ */
8008+int __cvmx_helper_rgmii_link_set(int ipd_port,
8009+ cvmx_helper_link_info_t link_info)
8010+{
8011+ int result = 0;
8012+ int interface = cvmx_helper_get_interface_num(ipd_port);
8013+ int index = cvmx_helper_get_interface_index_num(ipd_port);
8014+ union cvmx_gmxx_prtx_cfg original_gmx_cfg;
8015+ union cvmx_gmxx_prtx_cfg new_gmx_cfg;
8016+ union cvmx_pko_mem_queue_qos pko_mem_queue_qos;
8017+ union cvmx_pko_mem_queue_qos pko_mem_queue_qos_save[16];
8018+ union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp;
8019+ union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp_save;
8020+ int i;
8021+
8022+ /* Ignore speed sets in the simulator */
8023+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
8024+ return 0;
8025+
8026+ /* Read the current settings so we know the current enable state */
8027+ original_gmx_cfg.u64 =
8028+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8029+ new_gmx_cfg = original_gmx_cfg;
8030+
8031+ /* Disable the lowest level RX */
8032+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8033+ cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) &
8034+ ~(1 << index));
8035+
8036+ /* Disable all queues so that TX should become idle */
8037+ for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
8038+ int queue = cvmx_pko_get_base_queue(ipd_port) + i;
8039+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue);
8040+ pko_mem_queue_qos.u64 = cvmx_read_csr(CVMX_PKO_MEM_QUEUE_QOS);
8041+ pko_mem_queue_qos.s.pid = ipd_port;
8042+ pko_mem_queue_qos.s.qid = queue;
8043+ pko_mem_queue_qos_save[i] = pko_mem_queue_qos;
8044+ pko_mem_queue_qos.s.qos_mask = 0;
8045+ cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS, pko_mem_queue_qos.u64);
8046+ }
8047+
8048+ /* Disable backpressure */
8049+ gmx_tx_ovr_bp.u64 = cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface));
8050+ gmx_tx_ovr_bp_save = gmx_tx_ovr_bp;
8051+ gmx_tx_ovr_bp.s.bp &= ~(1 << index);
8052+ gmx_tx_ovr_bp.s.en |= 1 << index;
8053+ cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp.u64);
8054+ cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface));
8055+
8056+ /*
8057+ * Poll the GMX state machine waiting for it to become
8058+ * idle. Preferably we should only change speed when it is
8059+ * idle. If it doesn't become idle we will still do the speed
8060+ * change, but there is a slight chance that GMX will
8061+ * lockup.
8062+ */
8063+ cvmx_write_csr(CVMX_NPI_DBG_SELECT,
8064+ interface * 0x800 + index * 0x100 + 0x880);
8065+ CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 7,
8066+ ==, 0, 10000);
8067+ CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 0xf,
8068+ ==, 0, 10000);
8069+
8070+ /* Disable the port before we make any changes */
8071+ new_gmx_cfg.s.en = 0;
8072+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8073+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8074+
8075+ /* Set full/half duplex */
8076+ if (cvmx_octeon_is_pass1())
8077+ /* Half duplex is broken for 38XX Pass 1 */
8078+ new_gmx_cfg.s.duplex = 1;
8079+ else if (!link_info.s.link_up)
8080+ /* Force full duplex on down links */
8081+ new_gmx_cfg.s.duplex = 1;
8082+ else
8083+ new_gmx_cfg.s.duplex = link_info.s.full_duplex;
8084+
8085+ /* Set the link speed. Anything unknown is set to 1Gbps */
8086+ if (link_info.s.speed == 10) {
8087+ new_gmx_cfg.s.slottime = 0;
8088+ new_gmx_cfg.s.speed = 0;
8089+ } else if (link_info.s.speed == 100) {
8090+ new_gmx_cfg.s.slottime = 0;
8091+ new_gmx_cfg.s.speed = 0;
8092+ } else {
8093+ new_gmx_cfg.s.slottime = 1;
8094+ new_gmx_cfg.s.speed = 1;
8095+ }
8096+
8097+ /* Adjust the clocks */
8098+ if (link_info.s.speed == 10) {
8099+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 50);
8100+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40);
8101+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8102+ } else if (link_info.s.speed == 100) {
8103+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 5);
8104+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40);
8105+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8106+ } else {
8107+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
8108+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
8109+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
8110+ }
8111+
8112+ if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
8113+ if ((link_info.s.speed == 10) || (link_info.s.speed == 100)) {
8114+ union cvmx_gmxx_inf_mode mode;
8115+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
8116+
8117+ /*
8118+ * Port .en .type .p0mii Configuration
8119+ * ---- --- ----- ------ -----------------------------------------
8120+ * X 0 X X All links are disabled.
8121+ * 0 1 X 0 Port 0 is RGMII
8122+ * 0 1 X 1 Port 0 is MII
8123+ * 1 1 0 X Ports 1 and 2 are configured as RGMII ports.
8124+ * 1 1 1 X Port 1: GMII/MII; Port 2: disabled. GMII or
8125+ * MII port is selected by GMX_PRT1_CFG[SPEED].
8126+ */
8127+
8128+ /* In MII mode, CLK_CNT = 1. */
8129+ if (((index == 0) && (mode.s.p0mii == 1))
8130+ || ((index != 0) && (mode.s.type == 1))) {
8131+ cvmx_write_csr(CVMX_GMXX_TXX_CLK
8132+ (index, interface), 1);
8133+ }
8134+ }
8135+ }
8136+
8137+ /* Do a read to make sure all setup stuff is complete */
8138+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8139+
8140+ /* Save the new GMX setting without enabling the port */
8141+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8142+
8143+ /* Enable the lowest level RX */
8144+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8145+ cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) | (1 <<
8146+ index));
8147+
8148+ /* Re-enable the TX path */
8149+ for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
8150+ int queue = cvmx_pko_get_base_queue(ipd_port) + i;
8151+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue);
8152+ cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS,
8153+ pko_mem_queue_qos_save[i].u64);
8154+ }
8155+
8156+ /* Restore backpressure */
8157+ cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp_save.u64);
8158+
8159+ /* Restore the GMX enable state. Port config is complete */
8160+ new_gmx_cfg.s.en = original_gmx_cfg.s.en;
8161+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8162+
8163+ return result;
8164+}
8165+
8166+/**
8167+ * Configure a port for internal and/or external loopback. Internal loopback
8168+ * causes packets sent by the port to be received by Octeon. External loopback
8169+ * causes packets received from the wire to sent out again.
8170+ *
8171+ * @ipd_port: IPD/PKO port to loopback.
8172+ * @enable_internal:
8173+ * Non zero if you want internal loopback
8174+ * @enable_external:
8175+ * Non zero if you want external loopback
8176+ *
8177+ * Returns Zero on success, negative on failure.
8178+ */
8179+int __cvmx_helper_rgmii_configure_loopback(int ipd_port, int enable_internal,
8180+ int enable_external)
8181+{
8182+ int interface = cvmx_helper_get_interface_num(ipd_port);
8183+ int index = cvmx_helper_get_interface_index_num(ipd_port);
8184+ int original_enable;
8185+ union cvmx_gmxx_prtx_cfg gmx_cfg;
8186+ union cvmx_asxx_prt_loop asxx_prt_loop;
8187+
8188+ /* Read the current enable state and save it */
8189+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8190+ original_enable = gmx_cfg.s.en;
8191+ /* Force port to be disabled */
8192+ gmx_cfg.s.en = 0;
8193+ if (enable_internal) {
8194+ /* Force speed if we're doing internal loopback */
8195+ gmx_cfg.s.duplex = 1;
8196+ gmx_cfg.s.slottime = 1;
8197+ gmx_cfg.s.speed = 1;
8198+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
8199+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
8200+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
8201+ }
8202+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
8203+
8204+ /* Set the loopback bits */
8205+ asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
8206+ if (enable_internal)
8207+ asxx_prt_loop.s.int_loop |= 1 << index;
8208+ else
8209+ asxx_prt_loop.s.int_loop &= ~(1 << index);
8210+ if (enable_external)
8211+ asxx_prt_loop.s.ext_loop |= 1 << index;
8212+ else
8213+ asxx_prt_loop.s.ext_loop &= ~(1 << index);
8214+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), asxx_prt_loop.u64);
8215+
8216+ /* Force enables in internal loopback */
8217+ if (enable_internal) {
8218+ uint64_t tmp;
8219+ tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface));
8220+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface),
8221+ (1 << index) | tmp);
8222+ tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface));
8223+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8224+ (1 << index) | tmp);
8225+ original_enable = 1;
8226+ }
8227+
8228+ /* Restore the enable state */
8229+ gmx_cfg.s.en = original_enable;
8230+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
8231+ return 0;
8232+}
8233--- /dev/null
8234+++ b/drivers/staging/octeon/cvmx-helper-rgmii.h
8235@@ -0,0 +1,110 @@
8236+/***********************license start***************
8237+ * Author: Cavium Networks
8238+ *
8239+ * Contact: support@caviumnetworks.com
8240+ * This file is part of the OCTEON SDK
8241+ *
8242+ * Copyright (c) 2003-2008 Cavium Networks
8243+ *
8244+ * This file is free software; you can redistribute it and/or modify
8245+ * it under the terms of the GNU General Public License, Version 2, as
8246+ * published by the Free Software Foundation.
8247+ *
8248+ * This file is distributed in the hope that it will be useful, but
8249+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8250+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8251+ * NONINFRINGEMENT. See the GNU General Public License for more
8252+ * details.
8253+ *
8254+ * You should have received a copy of the GNU General Public License
8255+ * along with this file; if not, write to the Free Software
8256+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8257+ * or visit http://www.gnu.org/licenses/.
8258+ *
8259+ * This file may also be available under a different license from Cavium.
8260+ * Contact Cavium Networks for more information
8261+ ***********************license end**************************************/
8262+
8263+/**
8264+ * @file
8265+ *
8266+ * Functions for RGMII/GMII/MII initialization, configuration,
8267+ * and monitoring.
8268+ *
8269+ */
8270+#ifndef __CVMX_HELPER_RGMII_H__
8271+#define __CVMX_HELPER_RGMII_H__
8272+
8273+/**
8274+ * Probe RGMII ports and determine the number present
8275+ *
8276+ * @interface: Interface to probe
8277+ *
8278+ * Returns Number of RGMII/GMII/MII ports (0-4).
8279+ */
8280+extern int __cvmx_helper_rgmii_probe(int interface);
8281+
8282+/**
8283+ * Put an RGMII interface in loopback mode. Internal packets sent
8284+ * out will be received back again on the same port. Externally
8285+ * received packets will echo back out.
8286+ *
8287+ * @port: IPD port number to loop.
8288+ */
8289+extern void cvmx_helper_rgmii_internal_loopback(int port);
8290+
8291+/**
8292+ * Configure all of the ASX, GMX, and PKO regsiters required
8293+ * to get RGMII to function on the supplied interface.
8294+ *
8295+ * @interface: PKO Interface to configure (0 or 1)
8296+ *
8297+ * Returns Zero on success
8298+ */
8299+extern int __cvmx_helper_rgmii_enable(int interface);
8300+
8301+/**
8302+ * Return the link state of an IPD/PKO port as returned by
8303+ * auto negotiation. The result of this function may not match
8304+ * Octeon's link config if auto negotiation has changed since
8305+ * the last call to cvmx_helper_link_set().
8306+ *
8307+ * @ipd_port: IPD/PKO port to query
8308+ *
8309+ * Returns Link state
8310+ */
8311+extern cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port);
8312+
8313+/**
8314+ * Configure an IPD/PKO port for the specified link state. This
8315+ * function does not influence auto negotiation at the PHY level.
8316+ * The passed link state must always match the link state returned
8317+ * by cvmx_helper_link_get(). It is normally best to use
8318+ * cvmx_helper_link_autoconf() instead.
8319+ *
8320+ * @ipd_port: IPD/PKO port to configure
8321+ * @link_info: The new link state
8322+ *
8323+ * Returns Zero on success, negative on failure
8324+ */
8325+extern int __cvmx_helper_rgmii_link_set(int ipd_port,
8326+ cvmx_helper_link_info_t link_info);
8327+
8328+/**
8329+ * Configure a port for internal and/or external loopback. Internal loopback
8330+ * causes packets sent by the port to be received by Octeon. External loopback
8331+ * causes packets received from the wire to sent out again.
8332+ *
8333+ * @ipd_port: IPD/PKO port to loopback.
8334+ * @enable_internal:
8335+ * Non zero if you want internal loopback
8336+ * @enable_external:
8337+ * Non zero if you want external loopback
8338+ *
8339+ * Returns Zero on success, negative on failure.
8340+ */
8341+extern int __cvmx_helper_rgmii_configure_loopback(int ipd_port,
8342+ int enable_internal,
8343+ int enable_external);
8344+
8345+#endif
8346--- /dev/null
8347+++ b/drivers/staging/octeon/cvmx-helper-sgmii.c
8348@@ -0,0 +1,550 @@
8349+/***********************license start***************
8350+ * Author: Cavium Networks
8351+ *
8352+ * Contact: support@caviumnetworks.com
8353+ * This file is part of the OCTEON SDK
8354+ *
8355+ * Copyright (c) 2003-2008 Cavium Networks
8356+ *
8357+ * This file is free software; you can redistribute it and/or modify
8358+ * it under the terms of the GNU General Public License, Version 2, as
8359+ * published by the Free Software Foundation.
8360+ *
8361+ * This file is distributed in the hope that it will be useful, but
8362+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8363+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8364+ * NONINFRINGEMENT. See the GNU General Public License for more
8365+ * details.
8366+ *
8367+ * You should have received a copy of the GNU General Public License
8368+ * along with this file; if not, write to the Free Software
8369+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8370+ * or visit http://www.gnu.org/licenses/.
8371+ *
8372+ * This file may also be available under a different license from Cavium.
8373+ * Contact Cavium Networks for more information
8374+ ***********************license end**************************************/
8375+
8376+/*
8377+ * Functions for SGMII initialization, configuration,
8378+ * and monitoring.
8379+ */
8380+
8381+#include <asm/octeon/octeon.h>
8382+
8383+#include "cvmx-config.h"
8384+
8385+#include "cvmx-mdio.h"
8386+#include "cvmx-helper.h"
8387+#include "cvmx-helper-board.h"
8388+
8389+#include "cvmx-gmxx-defs.h"
8390+#include "cvmx-pcsx-defs.h"
8391+
8392+void __cvmx_interrupt_gmxx_enable(int interface);
8393+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
8394+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
8395+
8396+/**
8397+ * Perform initialization required only once for an SGMII port.
8398+ *
8399+ * @interface: Interface to init
8400+ * @index: Index of prot on the interface
8401+ *
8402+ * Returns Zero on success, negative on failure
8403+ */
8404+static int __cvmx_helper_sgmii_hardware_init_one_time(int interface, int index)
8405+{
8406+ const uint64_t clock_mhz = cvmx_sysinfo_get()->cpu_clock_hz / 1000000;
8407+ union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
8408+ union cvmx_pcsx_linkx_timer_count_reg pcsx_linkx_timer_count_reg;
8409+ union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8410+
8411+ /* Disable GMX */
8412+ gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8413+ gmxx_prtx_cfg.s.en = 0;
8414+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8415+
8416+ /*
8417+ * Write PCS*_LINK*_TIMER_COUNT_REG[COUNT] with the
8418+ * appropriate value. 1000BASE-X specifies a 10ms
8419+ * interval. SGMII specifies a 1.6ms interval.
8420+ */
8421+ pcs_misc_ctl_reg.u64 =
8422+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8423+ pcsx_linkx_timer_count_reg.u64 =
8424+ cvmx_read_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface));
8425+ if (pcs_misc_ctl_reg.s.mode) {
8426+ /* 1000BASE-X */
8427+ pcsx_linkx_timer_count_reg.s.count =
8428+ (10000ull * clock_mhz) >> 10;
8429+ } else {
8430+ /* SGMII */
8431+ pcsx_linkx_timer_count_reg.s.count =
8432+ (1600ull * clock_mhz) >> 10;
8433+ }
8434+ cvmx_write_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface),
8435+ pcsx_linkx_timer_count_reg.u64);
8436+
8437+ /*
8438+ * Write the advertisement register to be used as the
8439+ * tx_Config_Reg<D15:D0> of the autonegotiation. In
8440+ * 1000BASE-X mode, tx_Config_Reg<D15:D0> is PCS*_AN*_ADV_REG.
8441+ * In SGMII PHY mode, tx_Config_Reg<D15:D0> is
8442+ * PCS*_SGM*_AN_ADV_REG. In SGMII MAC mode,
8443+ * tx_Config_Reg<D15:D0> is the fixed value 0x4001, so this
8444+ * step can be skipped.
8445+ */
8446+ if (pcs_misc_ctl_reg.s.mode) {
8447+ /* 1000BASE-X */
8448+ union cvmx_pcsx_anx_adv_reg pcsx_anx_adv_reg;
8449+ pcsx_anx_adv_reg.u64 =
8450+ cvmx_read_csr(CVMX_PCSX_ANX_ADV_REG(index, interface));
8451+ pcsx_anx_adv_reg.s.rem_flt = 0;
8452+ pcsx_anx_adv_reg.s.pause = 3;
8453+ pcsx_anx_adv_reg.s.hfd = 1;
8454+ pcsx_anx_adv_reg.s.fd = 1;
8455+ cvmx_write_csr(CVMX_PCSX_ANX_ADV_REG(index, interface),
8456+ pcsx_anx_adv_reg.u64);
8457+ } else {
8458+ union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8459+ pcsx_miscx_ctl_reg.u64 =
8460+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8461+ if (pcsx_miscx_ctl_reg.s.mac_phy) {
8462+ /* PHY Mode */
8463+ union cvmx_pcsx_sgmx_an_adv_reg pcsx_sgmx_an_adv_reg;
8464+ pcsx_sgmx_an_adv_reg.u64 =
8465+ cvmx_read_csr(CVMX_PCSX_SGMX_AN_ADV_REG
8466+ (index, interface));
8467+ pcsx_sgmx_an_adv_reg.s.link = 1;
8468+ pcsx_sgmx_an_adv_reg.s.dup = 1;
8469+ pcsx_sgmx_an_adv_reg.s.speed = 2;
8470+ cvmx_write_csr(CVMX_PCSX_SGMX_AN_ADV_REG
8471+ (index, interface),
8472+ pcsx_sgmx_an_adv_reg.u64);
8473+ } else {
8474+ /* MAC Mode - Nothing to do */
8475+ }
8476+ }
8477+ return 0;
8478+}
8479+
8480+/**
8481+ * Initialize the SERTES link for the first time or after a loss
8482+ * of link.
8483+ *
8484+ * @interface: Interface to init
8485+ * @index: Index of prot on the interface
8486+ *
8487+ * Returns Zero on success, negative on failure
8488+ */
8489+static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index)
8490+{
8491+ union cvmx_pcsx_mrx_control_reg control_reg;
8492+
8493+ /*
8494+ * Take PCS through a reset sequence.
8495+ * PCS*_MR*_CONTROL_REG[PWR_DN] should be cleared to zero.
8496+ * Write PCS*_MR*_CONTROL_REG[RESET]=1 (while not changing the
8497+ * value of the other PCS*_MR*_CONTROL_REG bits). Read
8498+ * PCS*_MR*_CONTROL_REG[RESET] until it changes value to
8499+ * zero.
8500+ */
8501+ control_reg.u64 =
8502+ cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8503+ if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
8504+ control_reg.s.reset = 1;
8505+ cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8506+ control_reg.u64);
8507+ if (CVMX_WAIT_FOR_FIELD64
8508+ (CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8509+ union cvmx_pcsx_mrx_control_reg, reset, ==, 0, 10000)) {
8510+ cvmx_dprintf("SGMII%d: Timeout waiting for port %d "
8511+ "to finish reset\n",
8512+ interface, index);
8513+ return -1;
8514+ }
8515+ }
8516+
8517+ /*
8518+ * Write PCS*_MR*_CONTROL_REG[RST_AN]=1 to ensure a fresh
8519+ * sgmii negotiation starts.
8520+ */
8521+ control_reg.s.rst_an = 1;
8522+ control_reg.s.an_en = 1;
8523+ control_reg.s.pwr_dn = 0;
8524+ cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8525+ control_reg.u64);
8526+
8527+ /*
8528+ * Wait for PCS*_MR*_STATUS_REG[AN_CPT] to be set, indicating
8529+ * that sgmii autonegotiation is complete. In MAC mode this
8530+ * isn't an ethernet link, but a link between Octeon and the
8531+ * PHY.
8532+ */
8533+ if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
8534+ CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_STATUS_REG(index, interface),
8535+ union cvmx_pcsx_mrx_status_reg, an_cpt, ==, 1,
8536+ 10000)) {
8537+ /* cvmx_dprintf("SGMII%d: Port %d link timeout\n", interface, index); */
8538+ return -1;
8539+ }
8540+ return 0;
8541+}
8542+
8543+/**
8544+ * Configure an SGMII link to the specified speed after the SERTES
8545+ * link is up.
8546+ *
8547+ * @interface: Interface to init
8548+ * @index: Index of prot on the interface
8549+ * @link_info: Link state to configure
8550+ *
8551+ * Returns Zero on success, negative on failure
8552+ */
8553+static int __cvmx_helper_sgmii_hardware_init_link_speed(int interface,
8554+ int index,
8555+ cvmx_helper_link_info_t
8556+ link_info)
8557+{
8558+ int is_enabled;
8559+ union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8560+ union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8561+
8562+ /* Disable GMX before we make any changes. Remember the enable state */
8563+ gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8564+ is_enabled = gmxx_prtx_cfg.s.en;
8565+ gmxx_prtx_cfg.s.en = 0;
8566+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8567+
8568+ /* Wait for GMX to be idle */
8569+ if (CVMX_WAIT_FOR_FIELD64
8570+ (CVMX_GMXX_PRTX_CFG(index, interface), union cvmx_gmxx_prtx_cfg,
8571+ rx_idle, ==, 1, 10000)
8572+ || CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface),
8573+ union cvmx_gmxx_prtx_cfg, tx_idle, ==, 1,
8574+ 10000)) {
8575+ cvmx_dprintf
8576+ ("SGMII%d: Timeout waiting for port %d to be idle\n",
8577+ interface, index);
8578+ return -1;
8579+ }
8580+
8581+ /* Read GMX CFG again to make sure the disable completed */
8582+ gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8583+
8584+ /*
8585+ * Get the misc control for PCS. We will need to set the
8586+ * duplication amount.
8587+ */
8588+ pcsx_miscx_ctl_reg.u64 =
8589+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8590+
8591+ /*
8592+ * Use GMXENO to force the link down if the status we get says
8593+ * it should be down.
8594+ */
8595+ pcsx_miscx_ctl_reg.s.gmxeno = !link_info.s.link_up;
8596+
8597+ /* Only change the duplex setting if the link is up */
8598+ if (link_info.s.link_up)
8599+ gmxx_prtx_cfg.s.duplex = link_info.s.full_duplex;
8600+
8601+ /* Do speed based setting for GMX */
8602+ switch (link_info.s.speed) {
8603+ case 10:
8604+ gmxx_prtx_cfg.s.speed = 0;
8605+ gmxx_prtx_cfg.s.speed_msb = 1;
8606+ gmxx_prtx_cfg.s.slottime = 0;
8607+ /* Setting from GMX-603 */
8608+ pcsx_miscx_ctl_reg.s.samp_pt = 25;
8609+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
8610+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8611+ break;
8612+ case 100:
8613+ gmxx_prtx_cfg.s.speed = 0;
8614+ gmxx_prtx_cfg.s.speed_msb = 0;
8615+ gmxx_prtx_cfg.s.slottime = 0;
8616+ pcsx_miscx_ctl_reg.s.samp_pt = 0x5;
8617+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
8618+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8619+ break;
8620+ case 1000:
8621+ gmxx_prtx_cfg.s.speed = 1;
8622+ gmxx_prtx_cfg.s.speed_msb = 0;
8623+ gmxx_prtx_cfg.s.slottime = 1;
8624+ pcsx_miscx_ctl_reg.s.samp_pt = 1;
8625+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 512);
8626+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 8192);
8627+ break;
8628+ default:
8629+ break;
8630+ }
8631+
8632+ /* Write the new misc control for PCS */
8633+ cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
8634+ pcsx_miscx_ctl_reg.u64);
8635+
8636+ /* Write the new GMX settings with the port still disabled */
8637+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8638+
8639+ /* Read GMX CFG again to make sure the config completed */
8640+ gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8641+
8642+ /* Restore the enabled / disabled state */
8643+ gmxx_prtx_cfg.s.en = is_enabled;
8644+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8645+
8646+ return 0;
8647+}
8648+
8649+/**
8650+ * Bring up the SGMII interface to be ready for packet I/O but
8651+ * leave I/O disabled using the GMX override. This function
8652+ * follows the bringup documented in 10.6.3 of the manual.
8653+ *
8654+ * @interface: Interface to bringup
8655+ * @num_ports: Number of ports on the interface
8656+ *
8657+ * Returns Zero on success, negative on failure
8658+ */
8659+static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
8660+{
8661+ int index;
8662+
8663+ __cvmx_helper_setup_gmx(interface, num_ports);
8664+
8665+ for (index = 0; index < num_ports; index++) {
8666+ int ipd_port = cvmx_helper_get_ipd_port(interface, index);
8667+ __cvmx_helper_sgmii_hardware_init_one_time(interface, index);
8668+ __cvmx_helper_sgmii_link_set(ipd_port,
8669+ __cvmx_helper_sgmii_link_get
8670+ (ipd_port));
8671+
8672+ }
8673+
8674+ return 0;
8675+}
8676+
8677+/**
8678+ * Probe a SGMII interface and determine the number of ports
8679+ * connected to it. The SGMII interface should still be down after
8680+ * this call.
8681+ *
8682+ * @interface: Interface to probe
8683+ *
8684+ * Returns Number of ports on the interface. Zero to disable.
8685+ */
8686+int __cvmx_helper_sgmii_probe(int interface)
8687+{
8688+ union cvmx_gmxx_inf_mode mode;
8689+
8690+ /*
8691+ * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
8692+ * interface needs to be enabled before IPD otherwise per port
8693+ * backpressure may not work properly
8694+ */
8695+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
8696+ mode.s.en = 1;
8697+ cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
8698+ return 4;
8699+}
8700+
8701+/**
8702+ * Bringup and enable a SGMII interface. After this call packet
8703+ * I/O should be fully functional. This is called with IPD
8704+ * enabled but PKO disabled.
8705+ *
8706+ * @interface: Interface to bring up
8707+ *
8708+ * Returns Zero on success, negative on failure
8709+ */
8710+int __cvmx_helper_sgmii_enable(int interface)
8711+{
8712+ int num_ports = cvmx_helper_ports_on_interface(interface);
8713+ int index;
8714+
8715+ __cvmx_helper_sgmii_hardware_init(interface, num_ports);
8716+
8717+ for (index = 0; index < num_ports; index++) {
8718+ union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8719+ gmxx_prtx_cfg.u64 =
8720+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8721+ gmxx_prtx_cfg.s.en = 1;
8722+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
8723+ gmxx_prtx_cfg.u64);
8724+ __cvmx_interrupt_pcsx_intx_en_reg_enable(index, interface);
8725+ }
8726+ __cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
8727+ __cvmx_interrupt_gmxx_enable(interface);
8728+ return 0;
8729+}
8730+
8731+/**
8732+ * Return the link state of an IPD/PKO port as returned by
8733+ * auto negotiation. The result of this function may not match
8734+ * Octeon's link config if auto negotiation has changed since
8735+ * the last call to cvmx_helper_link_set().
8736+ *
8737+ * @ipd_port: IPD/PKO port to query
8738+ *
8739+ * Returns Link state
8740+ */
8741+cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port)
8742+{
8743+ cvmx_helper_link_info_t result;
8744+ union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
8745+ int interface = cvmx_helper_get_interface_num(ipd_port);
8746+ int index = cvmx_helper_get_interface_index_num(ipd_port);
8747+ union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
8748+
8749+ result.u64 = 0;
8750+
8751+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
8752+ /* The simulator gives you a simulated 1Gbps full duplex link */
8753+ result.s.link_up = 1;
8754+ result.s.full_duplex = 1;
8755+ result.s.speed = 1000;
8756+ return result;
8757+ }
8758+
8759+ pcsx_mrx_control_reg.u64 =
8760+ cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8761+ if (pcsx_mrx_control_reg.s.loopbck1) {
8762+ /* Force 1Gbps full duplex link for internal loopback */
8763+ result.s.link_up = 1;
8764+ result.s.full_duplex = 1;
8765+ result.s.speed = 1000;
8766+ return result;
8767+ }
8768+
8769+ pcs_misc_ctl_reg.u64 =
8770+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8771+ if (pcs_misc_ctl_reg.s.mode) {
8772+ /* 1000BASE-X */
8773+ /* FIXME */
8774+ } else {
8775+ union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8776+ pcsx_miscx_ctl_reg.u64 =
8777+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8778+ if (pcsx_miscx_ctl_reg.s.mac_phy) {
8779+ /* PHY Mode */
8780+ union cvmx_pcsx_mrx_status_reg pcsx_mrx_status_reg;
8781+ union cvmx_pcsx_anx_results_reg pcsx_anx_results_reg;
8782+
8783+ /*
8784+ * Don't bother continuing if the SERTES low
8785+ * level link is down
8786+ */
8787+ pcsx_mrx_status_reg.u64 =
8788+ cvmx_read_csr(CVMX_PCSX_MRX_STATUS_REG
8789+ (index, interface));
8790+ if (pcsx_mrx_status_reg.s.lnk_st == 0) {
8791+ if (__cvmx_helper_sgmii_hardware_init_link
8792+ (interface, index) != 0)
8793+ return result;
8794+ }
8795+
8796+ /* Read the autoneg results */
8797+ pcsx_anx_results_reg.u64 =
8798+ cvmx_read_csr(CVMX_PCSX_ANX_RESULTS_REG
8799+ (index, interface));
8800+ if (pcsx_anx_results_reg.s.an_cpt) {
8801+ /*
8802+ * Auto negotiation is complete. Set
8803+ * status accordingly.
8804+ */
8805+ result.s.full_duplex =
8806+ pcsx_anx_results_reg.s.dup;
8807+ result.s.link_up =
8808+ pcsx_anx_results_reg.s.link_ok;
8809+ switch (pcsx_anx_results_reg.s.spd) {
8810+ case 0:
8811+ result.s.speed = 10;
8812+ break;
8813+ case 1:
8814+ result.s.speed = 100;
8815+ break;
8816+ case 2:
8817+ result.s.speed = 1000;
8818+ break;
8819+ default:
8820+ result.s.speed = 0;
8821+ result.s.link_up = 0;
8822+ break;
8823+ }
8824+ } else {
8825+ /*
8826+ * Auto negotiation isn't
8827+ * complete. Return link down.
8828+ */
8829+ result.s.speed = 0;
8830+ result.s.link_up = 0;
8831+ }
8832+ } else { /* MAC Mode */
8833+
8834+ result = __cvmx_helper_board_link_get(ipd_port);
8835+ }
8836+ }
8837+ return result;
8838+}
8839+
8840+/**
8841+ * Configure an IPD/PKO port for the specified link state. This
8842+ * function does not influence auto negotiation at the PHY level.
8843+ * The passed link state must always match the link state returned
8844+ * by cvmx_helper_link_get(). It is normally best to use
8845+ * cvmx_helper_link_autoconf() instead.
8846+ *
8847+ * @ipd_port: IPD/PKO port to configure
8848+ * @link_info: The new link state
8849+ *
8850+ * Returns Zero on success, negative on failure
8851+ */
8852+int __cvmx_helper_sgmii_link_set(int ipd_port,
8853+ cvmx_helper_link_info_t link_info)
8854+{
8855+ int interface = cvmx_helper_get_interface_num(ipd_port);
8856+ int index = cvmx_helper_get_interface_index_num(ipd_port);
8857+ __cvmx_helper_sgmii_hardware_init_link(interface, index);
8858+ return __cvmx_helper_sgmii_hardware_init_link_speed(interface, index,
8859+ link_info);
8860+}
8861+
8862+/**
8863+ * Configure a port for internal and/or external loopback. Internal
8864+ * loopback causes packets sent by the port to be received by
8865+ * Octeon. External loopback causes packets received from the wire to
8866+ * sent out again.
8867+ *
8868+ * @ipd_port: IPD/PKO port to loopback.
8869+ * @enable_internal:
8870+ * Non zero if you want internal loopback
8871+ * @enable_external:
8872+ * Non zero if you want external loopback
8873+ *
8874+ * Returns Zero on success, negative on failure.
8875+ */
8876+int __cvmx_helper_sgmii_configure_loopback(int ipd_port, int enable_internal,
8877+ int enable_external)
8878+{
8879+ int interface = cvmx_helper_get_interface_num(ipd_port);
8880+ int index = cvmx_helper_get_interface_index_num(ipd_port);
8881+ union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
8882+ union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8883+
8884+ pcsx_mrx_control_reg.u64 =
8885+ cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8886+ pcsx_mrx_control_reg.s.loopbck1 = enable_internal;
8887+ cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8888+ pcsx_mrx_control_reg.u64);
8889+
8890+ pcsx_miscx_ctl_reg.u64 =
8891+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8892+ pcsx_miscx_ctl_reg.s.loopbck2 = enable_external;
8893+ cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
8894+ pcsx_miscx_ctl_reg.u64);
8895+
8896+ __cvmx_helper_sgmii_hardware_init_link(interface, index);
8897+ return 0;
8898+}
8899--- /dev/null
8900+++ b/drivers/staging/octeon/cvmx-helper-sgmii.h
8901@@ -0,0 +1,104 @@
8902+/***********************license start***************
8903+ * Author: Cavium Networks
8904+ *
8905+ * Contact: support@caviumnetworks.com
8906+ * This file is part of the OCTEON SDK
8907+ *
8908+ * Copyright (c) 2003-2008 Cavium Networks
8909+ *
8910+ * This file is free software; you can redistribute it and/or modify
8911+ * it under the terms of the GNU General Public License, Version 2, as
8912+ * published by the Free Software Foundation.
8913+ *
8914+ * This file is distributed in the hope that it will be useful, but
8915+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8916+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8917+ * NONINFRINGEMENT. See the GNU General Public License for more
8918+ * details.
8919+ *
8920+ * You should have received a copy of the GNU General Public License
8921+ * along with this file; if not, write to the Free Software
8922+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8923+ * or visit http://www.gnu.org/licenses/.
8924+ *
8925+ * This file may also be available under a different license from Cavium.
8926+ * Contact Cavium Networks for more information
8927+ ***********************license end**************************************/
8928+
8929+/**
8930+ * @file
8931+ *
8932+ * Functions for SGMII initialization, configuration,
8933+ * and monitoring.
8934+ *
8935+ */
8936+#ifndef __CVMX_HELPER_SGMII_H__
8937+#define __CVMX_HELPER_SGMII_H__
8938+
8939+/**
8940+ * Probe a SGMII interface and determine the number of ports
8941+ * connected to it. The SGMII interface should still be down after
8942+ * this call.
8943+ *
8944+ * @interface: Interface to probe
8945+ *
8946+ * Returns Number of ports on the interface. Zero to disable.
8947+ */
8948+extern int __cvmx_helper_sgmii_probe(int interface);
8949+
8950+/**
8951+ * Bringup and enable a SGMII interface. After this call packet
8952+ * I/O should be fully functional. This is called with IPD
8953+ * enabled but PKO disabled.
8954+ *
8955+ * @interface: Interface to bring up
8956+ *
8957+ * Returns Zero on success, negative on failure
8958+ */
8959+extern int __cvmx_helper_sgmii_enable(int interface);
8960+
8961+/**
8962+ * Return the link state of an IPD/PKO port as returned by
8963+ * auto negotiation. The result of this function may not match
8964+ * Octeon's link config if auto negotiation has changed since
8965+ * the last call to cvmx_helper_link_set().
8966+ *
8967+ * @ipd_port: IPD/PKO port to query
8968+ *
8969+ * Returns Link state
8970+ */
8971+extern cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port);
8972+
8973+/**
8974+ * Configure an IPD/PKO port for the specified link state. This
8975+ * function does not influence auto negotiation at the PHY level.
8976+ * The passed link state must always match the link state returned
8977+ * by cvmx_helper_link_get(). It is normally best to use
8978+ * cvmx_helper_link_autoconf() instead.
8979+ *
8980+ * @ipd_port: IPD/PKO port to configure
8981+ * @link_info: The new link state
8982+ *
8983+ * Returns Zero on success, negative on failure
8984+ */
8985+extern int __cvmx_helper_sgmii_link_set(int ipd_port,
8986+ cvmx_helper_link_info_t link_info);
8987+
8988+/**
8989+ * Configure a port for internal and/or external loopback. Internal loopback
8990+ * causes packets sent by the port to be received by Octeon. External loopback
8991+ * causes packets received from the wire to sent out again.
8992+ *
8993+ * @ipd_port: IPD/PKO port to loopback.
8994+ * @enable_internal:
8995+ * Non zero if you want internal loopback
8996+ * @enable_external:
8997+ * Non zero if you want external loopback
8998+ *
8999+ * Returns Zero on success, negative on failure.
9000+ */
9001+extern int __cvmx_helper_sgmii_configure_loopback(int ipd_port,
9002+ int enable_internal,
9003+ int enable_external);
9004+
9005+#endif
9006--- /dev/null
9007+++ b/drivers/staging/octeon/cvmx-helper-spi.c
9008@@ -0,0 +1,195 @@
9009+/***********************license start***************
9010+ * Author: Cavium Networks
9011+ *
9012+ * Contact: support@caviumnetworks.com
9013+ * This file is part of the OCTEON SDK
9014+ *
9015+ * Copyright (c) 2003-2008 Cavium Networks
9016+ *
9017+ * This file is free software; you can redistribute it and/or modify
9018+ * it under the terms of the GNU General Public License, Version 2, as
9019+ * published by the Free Software Foundation.
9020+ *
9021+ * This file is distributed in the hope that it will be useful, but
9022+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9023+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9024+ * NONINFRINGEMENT. See the GNU General Public License for more
9025+ * details.
9026+ *
9027+ * You should have received a copy of the GNU General Public License
9028+ * along with this file; if not, write to the Free Software
9029+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9030+ * or visit http://www.gnu.org/licenses/.
9031+ *
9032+ * This file may also be available under a different license from Cavium.
9033+ * Contact Cavium Networks for more information
9034+ ***********************license end**************************************/
9035+
9036+void __cvmx_interrupt_gmxx_enable(int interface);
9037+void __cvmx_interrupt_spxx_int_msk_enable(int index);
9038+void __cvmx_interrupt_stxx_int_msk_enable(int index);
9039+
9040+/*
9041+ * Functions for SPI initialization, configuration,
9042+ * and monitoring.
9043+ */
9044+#include <asm/octeon/octeon.h>
9045+
9046+#include "cvmx-config.h"
9047+#include "cvmx-spi.h"
9048+#include "cvmx-helper.h"
9049+
9050+#include "cvmx-pip-defs.h"
9051+#include "cvmx-pko-defs.h"
9052+
9053+/*
9054+ * CVMX_HELPER_SPI_TIMEOUT is used to determine how long the SPI
9055+ * initialization routines wait for SPI training. You can override the
9056+ * value using executive-config.h if necessary.
9057+ */
9058+#ifndef CVMX_HELPER_SPI_TIMEOUT
9059+#define CVMX_HELPER_SPI_TIMEOUT 10
9060+#endif
9061+
9062+/**
9063+ * Probe a SPI interface and determine the number of ports
9064+ * connected to it. The SPI interface should still be down after
9065+ * this call.
9066+ *
9067+ * @interface: Interface to probe
9068+ *
9069+ * Returns Number of ports on the interface. Zero to disable.
9070+ */
9071+int __cvmx_helper_spi_probe(int interface)
9072+{
9073+ int num_ports = 0;
9074+
9075+ if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
9076+ cvmx_spi4000_is_present(interface)) {
9077+ num_ports = 10;
9078+ } else {
9079+ union cvmx_pko_reg_crc_enable enable;
9080+ num_ports = 16;
9081+ /*
9082+ * Unlike the SPI4000, most SPI devices don't
9083+ * automatically put on the L2 CRC. For everything
9084+ * except for the SPI4000 have PKO append the L2 CRC
9085+ * to the packet.
9086+ */
9087+ enable.u64 = cvmx_read_csr(CVMX_PKO_REG_CRC_ENABLE);
9088+ enable.s.enable |= 0xffff << (interface * 16);
9089+ cvmx_write_csr(CVMX_PKO_REG_CRC_ENABLE, enable.u64);
9090+ }
9091+ __cvmx_helper_setup_gmx(interface, num_ports);
9092+ return num_ports;
9093+}
9094+
9095+/**
9096+ * Bringup and enable a SPI interface. After this call packet I/O
9097+ * should be fully functional. This is called with IPD enabled but
9098+ * PKO disabled.
9099+ *
9100+ * @interface: Interface to bring up
9101+ *
9102+ * Returns Zero on success, negative on failure
9103+ */
9104+int __cvmx_helper_spi_enable(int interface)
9105+{
9106+ /*
9107+ * Normally the ethernet L2 CRC is checked and stripped in the
9108+ * GMX block. When you are using SPI, this isn' the case and
9109+ * IPD needs to check the L2 CRC.
9110+ */
9111+ int num_ports = cvmx_helper_ports_on_interface(interface);
9112+ int ipd_port;
9113+ for (ipd_port = interface * 16; ipd_port < interface * 16 + num_ports;
9114+ ipd_port++) {
9115+ union cvmx_pip_prt_cfgx port_config;
9116+ port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
9117+ port_config.s.crc_en = 1;
9118+ cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_config.u64);
9119+ }
9120+
9121+ if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
9122+ cvmx_spi_start_interface(interface, CVMX_SPI_MODE_DUPLEX,
9123+ CVMX_HELPER_SPI_TIMEOUT, num_ports);
9124+ if (cvmx_spi4000_is_present(interface))
9125+ cvmx_spi4000_initialize(interface);
9126+ }
9127+ __cvmx_interrupt_spxx_int_msk_enable(interface);
9128+ __cvmx_interrupt_stxx_int_msk_enable(interface);
9129+ __cvmx_interrupt_gmxx_enable(interface);
9130+ return 0;
9131+}
9132+
9133+/**
9134+ * Return the link state of an IPD/PKO port as returned by
9135+ * auto negotiation. The result of this function may not match
9136+ * Octeon's link config if auto negotiation has changed since
9137+ * the last call to cvmx_helper_link_set().
9138+ *
9139+ * @ipd_port: IPD/PKO port to query
9140+ *
9141+ * Returns Link state
9142+ */
9143+cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port)
9144+{
9145+ cvmx_helper_link_info_t result;
9146+ int interface = cvmx_helper_get_interface_num(ipd_port);
9147+ int index = cvmx_helper_get_interface_index_num(ipd_port);
9148+ result.u64 = 0;
9149+
9150+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
9151+ /* The simulator gives you a simulated full duplex link */
9152+ result.s.link_up = 1;
9153+ result.s.full_duplex = 1;
9154+ result.s.speed = 10000;
9155+ } else if (cvmx_spi4000_is_present(interface)) {
9156+ union cvmx_gmxx_rxx_rx_inbnd inband =
9157+ cvmx_spi4000_check_speed(interface, index);
9158+ result.s.link_up = inband.s.status;
9159+ result.s.full_duplex = inband.s.duplex;
9160+ switch (inband.s.speed) {
9161+ case 0: /* 10 Mbps */
9162+ result.s.speed = 10;
9163+ break;
9164+ case 1: /* 100 Mbps */
9165+ result.s.speed = 100;
9166+ break;
9167+ case 2: /* 1 Gbps */
9168+ result.s.speed = 1000;
9169+ break;
9170+ case 3: /* Illegal */
9171+ result.s.speed = 0;
9172+ result.s.link_up = 0;
9173+ break;
9174+ }
9175+ } else {
9176+ /* For generic SPI we can't determine the link, just return some
9177+ sane results */
9178+ result.s.link_up = 1;
9179+ result.s.full_duplex = 1;
9180+ result.s.speed = 10000;
9181+ }
9182+ return result;
9183+}
9184+
9185+/**
9186+ * Configure an IPD/PKO port for the specified link state. This
9187+ * function does not influence auto negotiation at the PHY level.
9188+ * The passed link state must always match the link state returned
9189+ * by cvmx_helper_link_get(). It is normally best to use
9190+ * cvmx_helper_link_autoconf() instead.
9191+ *
9192+ * @ipd_port: IPD/PKO port to configure
9193+ * @link_info: The new link state
9194+ *
9195+ * Returns Zero on success, negative on failure
9196+ */
9197+int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
9198+{
9199+ /* Nothing to do. If we have a SPI4000 then the setup was already performed
9200+ by cvmx_spi4000_check_speed(). If not then there isn't any link
9201+ info */
9202+ return 0;
9203+}
9204--- /dev/null
9205+++ b/drivers/staging/octeon/cvmx-helper-spi.h
9206@@ -0,0 +1,84 @@
9207+/***********************license start***************
9208+ * Author: Cavium Networks
9209+ *
9210+ * Contact: support@caviumnetworks.com
9211+ * This file is part of the OCTEON SDK
9212+ *
9213+ * Copyright (c) 2003-2008 Cavium Networks
9214+ *
9215+ * This file is free software; you can redistribute it and/or modify
9216+ * it under the terms of the GNU General Public License, Version 2, as
9217+ * published by the Free Software Foundation.
9218+ *
9219+ * This file is distributed in the hope that it will be useful, but
9220+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9221+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9222+ * NONINFRINGEMENT. See the GNU General Public License for more
9223+ * details.
9224+ *
9225+ * You should have received a copy of the GNU General Public License
9226+ * along with this file; if not, write to the Free Software
9227+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9228+ * or visit http://www.gnu.org/licenses/.
9229+ *
9230+ * This file may also be available under a different license from Cavium.
9231+ * Contact Cavium Networks for more information
9232+ ***********************license end**************************************/
9233+
9234+/*
9235+ * Functions for SPI initialization, configuration,
9236+ * and monitoring.
9237+ */
9238+#ifndef __CVMX_HELPER_SPI_H__
9239+#define __CVMX_HELPER_SPI_H__
9240+
9241+/**
9242+ * Probe a SPI interface and determine the number of ports
9243+ * connected to it. The SPI interface should still be down after
9244+ * this call.
9245+ *
9246+ * @interface: Interface to probe
9247+ *
9248+ * Returns Number of ports on the interface. Zero to disable.
9249+ */
9250+extern int __cvmx_helper_spi_probe(int interface);
9251+
9252+/**
9253+ * Bringup and enable a SPI interface. After this call packet I/O
9254+ * should be fully functional. This is called with IPD enabled but
9255+ * PKO disabled.
9256+ *
9257+ * @interface: Interface to bring up
9258+ *
9259+ * Returns Zero on success, negative on failure
9260+ */
9261+extern int __cvmx_helper_spi_enable(int interface);
9262+
9263+/**
9264+ * Return the link state of an IPD/PKO port as returned by
9265+ * auto negotiation. The result of this function may not match
9266+ * Octeon's link config if auto negotiation has changed since
9267+ * the last call to cvmx_helper_link_set().
9268+ *
9269+ * @ipd_port: IPD/PKO port to query
9270+ *
9271+ * Returns Link state
9272+ */
9273+extern cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port);
9274+
9275+/**
9276+ * Configure an IPD/PKO port for the specified link state. This
9277+ * function does not influence auto negotiation at the PHY level.
9278+ * The passed link state must always match the link state returned
9279+ * by cvmx_helper_link_get(). It is normally best to use
9280+ * cvmx_helper_link_autoconf() instead.
9281+ *
9282+ * @ipd_port: IPD/PKO port to configure
9283+ * @link_info: The new link state
9284+ *
9285+ * Returns Zero on success, negative on failure
9286+ */
9287+extern int __cvmx_helper_spi_link_set(int ipd_port,
9288+ cvmx_helper_link_info_t link_info);
9289+
9290+#endif
9291--- /dev/null
9292+++ b/drivers/staging/octeon/cvmx-helper-util.c
9293@@ -0,0 +1,433 @@
9294+/***********************license start***************
9295+ * Author: Cavium Networks
9296+ *
9297+ * Contact: support@caviumnetworks.com
9298+ * This file is part of the OCTEON SDK
9299+ *
9300+ * Copyright (c) 2003-2008 Cavium Networks
9301+ *
9302+ * This file is free software; you can redistribute it and/or modify
9303+ * it under the terms of the GNU General Public License, Version 2, as
9304+ * published by the Free Software Foundation.
9305+ *
9306+ * This file is distributed in the hope that it will be useful, but
9307+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9308+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9309+ * NONINFRINGEMENT. See the GNU General Public License for more
9310+ * details.
9311+ *
9312+ * You should have received a copy of the GNU General Public License
9313+ * along with this file; if not, write to the Free Software
9314+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9315+ * or visit http://www.gnu.org/licenses/.
9316+ *
9317+ * This file may also be available under a different license from Cavium.
9318+ * Contact Cavium Networks for more information
9319+ ***********************license end**************************************/
9320+
9321+/*
9322+ * Small helper utilities.
9323+ */
9324+#include <linux/kernel.h>
9325+
9326+#include <asm/octeon/octeon.h>
9327+
9328+#include "cvmx-config.h"
9329+
9330+#include "cvmx-fpa.h"
9331+#include "cvmx-pip.h"
9332+#include "cvmx-pko.h"
9333+#include "cvmx-ipd.h"
9334+#include "cvmx-spi.h"
9335+
9336+#include "cvmx-helper.h"
9337+#include "cvmx-helper-util.h"
9338+
9339+#include <asm/octeon/cvmx-ipd-defs.h>
9340+
9341+/**
9342+ * Convert a interface mode into a human readable string
9343+ *
9344+ * @mode: Mode to convert
9345+ *
9346+ * Returns String
9347+ */
9348+const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t
9349+ mode)
9350+{
9351+ switch (mode) {
9352+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
9353+ return "DISABLED";
9354+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
9355+ return "RGMII";
9356+ case CVMX_HELPER_INTERFACE_MODE_GMII:
9357+ return "GMII";
9358+ case CVMX_HELPER_INTERFACE_MODE_SPI:
9359+ return "SPI";
9360+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
9361+ return "PCIE";
9362+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
9363+ return "XAUI";
9364+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
9365+ return "SGMII";
9366+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
9367+ return "PICMG";
9368+ case CVMX_HELPER_INTERFACE_MODE_NPI:
9369+ return "NPI";
9370+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
9371+ return "LOOP";
9372+ }
9373+ return "UNKNOWN";
9374+}
9375+
9376+/**
9377+ * Debug routine to dump the packet structure to the console
9378+ *
9379+ * @work: Work queue entry containing the packet to dump
9380+ * Returns
9381+ */
9382+int cvmx_helper_dump_packet(cvmx_wqe_t *work)
9383+{
9384+ uint64_t count;
9385+ uint64_t remaining_bytes;
9386+ union cvmx_buf_ptr buffer_ptr;
9387+ uint64_t start_of_buffer;
9388+ uint8_t *data_address;
9389+ uint8_t *end_of_data;
9390+
9391+ cvmx_dprintf("Packet Length: %u\n", work->len);
9392+ cvmx_dprintf(" Input Port: %u\n", work->ipprt);
9393+ cvmx_dprintf(" QoS: %u\n", work->qos);
9394+ cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs);
9395+
9396+ if (work->word2.s.bufs == 0) {
9397+ union cvmx_ipd_wqe_fpa_queue wqe_pool;
9398+ wqe_pool.u64 = cvmx_read_csr(CVMX_IPD_WQE_FPA_QUEUE);
9399+ buffer_ptr.u64 = 0;
9400+ buffer_ptr.s.pool = wqe_pool.s.wqe_pool;
9401+ buffer_ptr.s.size = 128;
9402+ buffer_ptr.s.addr = cvmx_ptr_to_phys(work->packet_data);
9403+ if (likely(!work->word2.s.not_IP)) {
9404+ union cvmx_pip_ip_offset pip_ip_offset;
9405+ pip_ip_offset.u64 = cvmx_read_csr(CVMX_PIP_IP_OFFSET);
9406+ buffer_ptr.s.addr +=
9407+ (pip_ip_offset.s.offset << 3) -
9408+ work->word2.s.ip_offset;
9409+ buffer_ptr.s.addr += (work->word2.s.is_v6 ^ 1) << 2;
9410+ } else {
9411+ /*
9412+ * WARNING: This code assumes that the packet
9413+ * is not RAW. If it was, we would use
9414+ * PIP_GBL_CFG[RAW_SHF] instead of
9415+ * PIP_GBL_CFG[NIP_SHF].
9416+ */
9417+ union cvmx_pip_gbl_cfg pip_gbl_cfg;
9418+ pip_gbl_cfg.u64 = cvmx_read_csr(CVMX_PIP_GBL_CFG);
9419+ buffer_ptr.s.addr += pip_gbl_cfg.s.nip_shf;
9420+ }
9421+ } else
9422+ buffer_ptr = work->packet_ptr;
9423+ remaining_bytes = work->len;
9424+
9425+ while (remaining_bytes) {
9426+ start_of_buffer =
9427+ ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9428+ cvmx_dprintf(" Buffer Start:%llx\n",
9429+ (unsigned long long)start_of_buffer);
9430+ cvmx_dprintf(" Buffer I : %u\n", buffer_ptr.s.i);
9431+ cvmx_dprintf(" Buffer Back: %u\n", buffer_ptr.s.back);
9432+ cvmx_dprintf(" Buffer Pool: %u\n", buffer_ptr.s.pool);
9433+ cvmx_dprintf(" Buffer Data: %llx\n",
9434+ (unsigned long long)buffer_ptr.s.addr);
9435+ cvmx_dprintf(" Buffer Size: %u\n", buffer_ptr.s.size);
9436+
9437+ cvmx_dprintf("\t\t");
9438+ data_address = (uint8_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr);
9439+ end_of_data = data_address + buffer_ptr.s.size;
9440+ count = 0;
9441+ while (data_address < end_of_data) {
9442+ if (remaining_bytes == 0)
9443+ break;
9444+ else
9445+ remaining_bytes--;
9446+ cvmx_dprintf("%02x", (unsigned int)*data_address);
9447+ data_address++;
9448+ if (remaining_bytes && (count == 7)) {
9449+ cvmx_dprintf("\n\t\t");
9450+ count = 0;
9451+ } else
9452+ count++;
9453+ }
9454+ cvmx_dprintf("\n");
9455+
9456+ if (remaining_bytes)
9457+ buffer_ptr = *(union cvmx_buf_ptr *)
9458+ cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9459+ }
9460+ return 0;
9461+}
9462+
9463+/**
9464+ * Setup Random Early Drop on a specific input queue
9465+ *
9466+ * @queue: Input queue to setup RED on (0-7)
9467+ * @pass_thresh:
9468+ * Packets will begin slowly dropping when there are less than
9469+ * this many packet buffers free in FPA 0.
9470+ * @drop_thresh:
9471+ * All incomming packets will be dropped when there are less
9472+ * than this many free packet buffers in FPA 0.
9473+ * Returns Zero on success. Negative on failure
9474+ */
9475+int cvmx_helper_setup_red_queue(int queue, int pass_thresh, int drop_thresh)
9476+{
9477+ union cvmx_ipd_qosx_red_marks red_marks;
9478+ union cvmx_ipd_red_quex_param red_param;
9479+
9480+ /* Set RED to begin dropping packets when there are pass_thresh buffers
9481+ left. It will linearly drop more packets until reaching drop_thresh
9482+ buffers */
9483+ red_marks.u64 = 0;
9484+ red_marks.s.drop = drop_thresh;
9485+ red_marks.s.pass = pass_thresh;
9486+ cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64);
9487+
9488+ /* Use the actual queue 0 counter, not the average */
9489+ red_param.u64 = 0;
9490+ red_param.s.prb_con =
9491+ (255ul << 24) / (red_marks.s.pass - red_marks.s.drop);
9492+ red_param.s.avg_con = 1;
9493+ red_param.s.new_con = 255;
9494+ red_param.s.use_pcnt = 1;
9495+ cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64);
9496+ return 0;
9497+}
9498+
9499+/**
9500+ * Setup Random Early Drop to automatically begin dropping packets.
9501+ *
9502+ * @pass_thresh:
9503+ * Packets will begin slowly dropping when there are less than
9504+ * this many packet buffers free in FPA 0.
9505+ * @drop_thresh:
9506+ * All incomming packets will be dropped when there are less
9507+ * than this many free packet buffers in FPA 0.
9508+ * Returns Zero on success. Negative on failure
9509+ */
9510+int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
9511+{
9512+ union cvmx_ipd_portx_bp_page_cnt page_cnt;
9513+ union cvmx_ipd_bp_prt_red_end ipd_bp_prt_red_end;
9514+ union cvmx_ipd_red_port_enable red_port_enable;
9515+ int queue;
9516+ int interface;
9517+ int port;
9518+
9519+ /* Disable backpressure based on queued buffers. It needs SW support */
9520+ page_cnt.u64 = 0;
9521+ page_cnt.s.bp_enb = 0;
9522+ page_cnt.s.page_cnt = 100;
9523+ for (interface = 0; interface < 2; interface++) {
9524+ for (port = cvmx_helper_get_first_ipd_port(interface);
9525+ port < cvmx_helper_get_last_ipd_port(interface); port++)
9526+ cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port),
9527+ page_cnt.u64);
9528+ }
9529+
9530+ for (queue = 0; queue < 8; queue++)
9531+ cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh);
9532+
9533+ /* Shutoff the dropping based on the per port page count. SW isn't
9534+ decrementing it right now */
9535+ ipd_bp_prt_red_end.u64 = 0;
9536+ ipd_bp_prt_red_end.s.prt_enb = 0;
9537+ cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64);
9538+
9539+ red_port_enable.u64 = 0;
9540+ red_port_enable.s.prt_enb = 0xfffffffffull;
9541+ red_port_enable.s.avg_dly = 10000;
9542+ red_port_enable.s.prb_dly = 10000;
9543+ cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64);
9544+
9545+ return 0;
9546+}
9547+
9548+/**
9549+ * Setup the common GMX settings that determine the number of
9550+ * ports. These setting apply to almost all configurations of all
9551+ * chips.
9552+ *
9553+ * @interface: Interface to configure
9554+ * @num_ports: Number of ports on the interface
9555+ *
9556+ * Returns Zero on success, negative on failure
9557+ */
9558+int __cvmx_helper_setup_gmx(int interface, int num_ports)
9559+{
9560+ union cvmx_gmxx_tx_prts gmx_tx_prts;
9561+ union cvmx_gmxx_rx_prts gmx_rx_prts;
9562+ union cvmx_pko_reg_gmx_port_mode pko_mode;
9563+ union cvmx_gmxx_txx_thresh gmx_tx_thresh;
9564+ int index;
9565+
9566+ /* Tell GMX the number of TX ports on this interface */
9567+ gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface));
9568+ gmx_tx_prts.s.prts = num_ports;
9569+ cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64);
9570+
9571+ /* Tell GMX the number of RX ports on this interface. This only
9572+ ** applies to *GMII and XAUI ports */
9573+ if (cvmx_helper_interface_get_mode(interface) ==
9574+ CVMX_HELPER_INTERFACE_MODE_RGMII
9575+ || cvmx_helper_interface_get_mode(interface) ==
9576+ CVMX_HELPER_INTERFACE_MODE_SGMII
9577+ || cvmx_helper_interface_get_mode(interface) ==
9578+ CVMX_HELPER_INTERFACE_MODE_GMII
9579+ || cvmx_helper_interface_get_mode(interface) ==
9580+ CVMX_HELPER_INTERFACE_MODE_XAUI) {
9581+ if (num_ports > 4) {
9582+ cvmx_dprintf("__cvmx_helper_setup_gmx: Illegal "
9583+ "num_ports\n");
9584+ return -1;
9585+ }
9586+
9587+ gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface));
9588+ gmx_rx_prts.s.prts = num_ports;
9589+ cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64);
9590+ }
9591+
9592+ /* Skip setting CVMX_PKO_REG_GMX_PORT_MODE on 30XX, 31XX, and 50XX */
9593+ if (!OCTEON_IS_MODEL(OCTEON_CN30XX) && !OCTEON_IS_MODEL(OCTEON_CN31XX)
9594+ && !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
9595+ /* Tell PKO the number of ports on this interface */
9596+ pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE);
9597+ if (interface == 0) {
9598+ if (num_ports == 1)
9599+ pko_mode.s.mode0 = 4;
9600+ else if (num_ports == 2)
9601+ pko_mode.s.mode0 = 3;
9602+ else if (num_ports <= 4)
9603+ pko_mode.s.mode0 = 2;
9604+ else if (num_ports <= 8)
9605+ pko_mode.s.mode0 = 1;
9606+ else
9607+ pko_mode.s.mode0 = 0;
9608+ } else {
9609+ if (num_ports == 1)
9610+ pko_mode.s.mode1 = 4;
9611+ else if (num_ports == 2)
9612+ pko_mode.s.mode1 = 3;
9613+ else if (num_ports <= 4)
9614+ pko_mode.s.mode1 = 2;
9615+ else if (num_ports <= 8)
9616+ pko_mode.s.mode1 = 1;
9617+ else
9618+ pko_mode.s.mode1 = 0;
9619+ }
9620+ cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64);
9621+ }
9622+
9623+ /*
9624+ * Set GMX to buffer as much data as possible before starting
9625+ * transmit. This reduces the chances that we have a TX under
9626+ * run due to memory contention. Any packet that fits entirely
9627+ * in the GMX FIFO can never have an under run regardless of
9628+ * memory load.
9629+ */
9630+ gmx_tx_thresh.u64 = cvmx_read_csr(CVMX_GMXX_TXX_THRESH(0, interface));
9631+ if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX)
9632+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
9633+ /* These chips have a fixed max threshold of 0x40 */
9634+ gmx_tx_thresh.s.cnt = 0x40;
9635+ } else {
9636+ /* Choose the max value for the number of ports */
9637+ if (num_ports <= 1)
9638+ gmx_tx_thresh.s.cnt = 0x100 / 1;
9639+ else if (num_ports == 2)
9640+ gmx_tx_thresh.s.cnt = 0x100 / 2;
9641+ else
9642+ gmx_tx_thresh.s.cnt = 0x100 / 4;
9643+ }
9644+ /*
9645+ * SPI and XAUI can have lots of ports but the GMX hardware
9646+ * only ever has a max of 4.
9647+ */
9648+ if (num_ports > 4)
9649+ num_ports = 4;
9650+ for (index = 0; index < num_ports; index++)
9651+ cvmx_write_csr(CVMX_GMXX_TXX_THRESH(index, interface),
9652+ gmx_tx_thresh.u64);
9653+
9654+ return 0;
9655+}
9656+
9657+/**
9658+ * Returns the IPD/PKO port number for a port on teh given
9659+ * interface.
9660+ *
9661+ * @interface: Interface to use
9662+ * @port: Port on the interface
9663+ *
9664+ * Returns IPD/PKO port number
9665+ */
9666+int cvmx_helper_get_ipd_port(int interface, int port)
9667+{
9668+ switch (interface) {
9669+ case 0:
9670+ return port;
9671+ case 1:
9672+ return port + 16;
9673+ case 2:
9674+ return port + 32;
9675+ case 3:
9676+ return port + 36;
9677+ }
9678+ return -1;
9679+}
9680+
9681+/**
9682+ * Returns the interface number for an IPD/PKO port number.
9683+ *
9684+ * @ipd_port: IPD/PKO port number
9685+ *
9686+ * Returns Interface number
9687+ */
9688+int cvmx_helper_get_interface_num(int ipd_port)
9689+{
9690+ if (ipd_port < 16)
9691+ return 0;
9692+ else if (ipd_port < 32)
9693+ return 1;
9694+ else if (ipd_port < 36)
9695+ return 2;
9696+ else if (ipd_port < 40)
9697+ return 3;
9698+ else
9699+ cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "
9700+ "port number\n");
9701+
9702+ return -1;
9703+}
9704+
9705+/**
9706+ * Returns the interface index number for an IPD/PKO port
9707+ * number.
9708+ *
9709+ * @ipd_port: IPD/PKO port number
9710+ *
9711+ * Returns Interface index number
9712+ */
9713+int cvmx_helper_get_interface_index_num(int ipd_port)
9714+{
9715+ if (ipd_port < 32)
9716+ return ipd_port & 15;
9717+ else if (ipd_port < 36)
9718+ return ipd_port & 3;
9719+ else if (ipd_port < 40)
9720+ return ipd_port & 3;
9721+ else
9722+ cvmx_dprintf("cvmx_helper_get_interface_index_num: "
9723+ "Illegal IPD port number\n");
9724+
9725+ return -1;
9726+}
9727--- /dev/null
9728+++ b/drivers/staging/octeon/cvmx-helper-util.h
9729@@ -0,0 +1,215 @@
9730+/***********************license start***************
9731+ * Author: Cavium Networks
9732+ *
9733+ * Contact: support@caviumnetworks.com
9734+ * This file is part of the OCTEON SDK
9735+ *
9736+ * Copyright (c) 2003-2008 Cavium Networks
9737+ *
9738+ * This file is free software; you can redistribute it and/or modify
9739+ * it under the terms of the GNU General Public License, Version 2, as
9740+ * published by the Free Software Foundation.
9741+ *
9742+ * This file is distributed in the hope that it will be useful, but
9743+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9744+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9745+ * NONINFRINGEMENT. See the GNU General Public License for more
9746+ * details.
9747+ *
9748+ * You should have received a copy of the GNU General Public License
9749+ * along with this file; if not, write to the Free Software
9750+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9751+ * or visit http://www.gnu.org/licenses/.
9752+ *
9753+ * This file may also be available under a different license from Cavium.
9754+ * Contact Cavium Networks for more information
9755+ ***********************license end**************************************/
9756+
9757+/*
9758+ *
9759+ * Small helper utilities.
9760+ *
9761+ */
9762+
9763+#ifndef __CVMX_HELPER_UTIL_H__
9764+#define __CVMX_HELPER_UTIL_H__
9765+
9766+/**
9767+ * Convert a interface mode into a human readable string
9768+ *
9769+ * @mode: Mode to convert
9770+ *
9771+ * Returns String
9772+ */
9773+extern const char
9774+ *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode);
9775+
9776+/**
9777+ * Debug routine to dump the packet structure to the console
9778+ *
9779+ * @work: Work queue entry containing the packet to dump
9780+ * Returns
9781+ */
9782+extern int cvmx_helper_dump_packet(cvmx_wqe_t *work);
9783+
9784+/**
9785+ * Setup Random Early Drop on a specific input queue
9786+ *
9787+ * @queue: Input queue to setup RED on (0-7)
9788+ * @pass_thresh:
9789+ * Packets will begin slowly dropping when there are less than
9790+ * this many packet buffers free in FPA 0.
9791+ * @drop_thresh:
9792+ * All incomming packets will be dropped when there are less
9793+ * than this many free packet buffers in FPA 0.
9794+ * Returns Zero on success. Negative on failure
9795+ */
9796+extern int cvmx_helper_setup_red_queue(int queue, int pass_thresh,
9797+ int drop_thresh);
9798+
9799+/**
9800+ * Setup Random Early Drop to automatically begin dropping packets.
9801+ *
9802+ * @pass_thresh:
9803+ * Packets will begin slowly dropping when there are less than
9804+ * this many packet buffers free in FPA 0.
9805+ * @drop_thresh:
9806+ * All incomming packets will be dropped when there are less
9807+ * than this many free packet buffers in FPA 0.
9808+ * Returns Zero on success. Negative on failure
9809+ */
9810+extern int cvmx_helper_setup_red(int pass_thresh, int drop_thresh);
9811+
9812+/**
9813+ * Get the version of the CVMX libraries.
9814+ *
9815+ * Returns Version string. Note this buffer is allocated statically
9816+ * and will be shared by all callers.
9817+ */
9818+extern const char *cvmx_helper_get_version(void);
9819+
9820+/**
9821+ * Setup the common GMX settings that determine the number of
9822+ * ports. These setting apply to almost all configurations of all
9823+ * chips.
9824+ *
9825+ * @interface: Interface to configure
9826+ * @num_ports: Number of ports on the interface
9827+ *
9828+ * Returns Zero on success, negative on failure
9829+ */
9830+extern int __cvmx_helper_setup_gmx(int interface, int num_ports);
9831+
9832+/**
9833+ * Returns the IPD/PKO port number for a port on the given
9834+ * interface.
9835+ *
9836+ * @interface: Interface to use
9837+ * @port: Port on the interface
9838+ *
9839+ * Returns IPD/PKO port number
9840+ */
9841+extern int cvmx_helper_get_ipd_port(int interface, int port);
9842+
9843+/**
9844+ * Returns the IPD/PKO port number for the first port on the given
9845+ * interface.
9846+ *
9847+ * @interface: Interface to use
9848+ *
9849+ * Returns IPD/PKO port number
9850+ */
9851+static inline int cvmx_helper_get_first_ipd_port(int interface)
9852+{
9853+ return cvmx_helper_get_ipd_port(interface, 0);
9854+}
9855+
9856+/**
9857+ * Returns the IPD/PKO port number for the last port on the given
9858+ * interface.
9859+ *
9860+ * @interface: Interface to use
9861+ *
9862+ * Returns IPD/PKO port number
9863+ */
9864+static inline int cvmx_helper_get_last_ipd_port(int interface)
9865+{
9866+ extern int cvmx_helper_ports_on_interface(int interface);
9867+
9868+ return cvmx_helper_get_first_ipd_port(interface) +
9869+ cvmx_helper_ports_on_interface(interface) - 1;
9870+}
9871+
9872+/**
9873+ * Free the packet buffers contained in a work queue entry.
9874+ * The work queue entry is not freed.
9875+ *
9876+ * @work: Work queue entry with packet to free
9877+ */
9878+static inline void cvmx_helper_free_packet_data(cvmx_wqe_t *work)
9879+{
9880+ uint64_t number_buffers;
9881+ union cvmx_buf_ptr buffer_ptr;
9882+ union cvmx_buf_ptr next_buffer_ptr;
9883+ uint64_t start_of_buffer;
9884+
9885+ number_buffers = work->word2.s.bufs;
9886+ if (number_buffers == 0)
9887+ return;
9888+ buffer_ptr = work->packet_ptr;
9889+
9890+ /*
9891+ * Since the number of buffers is not zero, we know this is
9892+ * not a dynamic short packet. We need to check if it is a
9893+ * packet received with IPD_CTL_STATUS[NO_WPTR]. If this is
9894+ * true, we need to free all buffers except for the first
9895+ * one. The caller doesn't expect their WQE pointer to be
9896+ * freed
9897+ */
9898+ start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9899+ if (cvmx_ptr_to_phys(work) == start_of_buffer) {
9900+ next_buffer_ptr =
9901+ *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9902+ buffer_ptr = next_buffer_ptr;
9903+ number_buffers--;
9904+ }
9905+
9906+ while (number_buffers--) {
9907+ /*
9908+ * Remember the back pointer is in cache lines, not
9909+ * 64bit words
9910+ */
9911+ start_of_buffer =
9912+ ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9913+ /*
9914+ * Read pointer to next buffer before we free the
9915+ * current buffer.
9916+ */
9917+ next_buffer_ptr =
9918+ *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9919+ cvmx_fpa_free(cvmx_phys_to_ptr(start_of_buffer),
9920+ buffer_ptr.s.pool, 0);
9921+ buffer_ptr = next_buffer_ptr;
9922+ }
9923+}
9924+
9925+/**
9926+ * Returns the interface number for an IPD/PKO port number.
9927+ *
9928+ * @ipd_port: IPD/PKO port number
9929+ *
9930+ * Returns Interface number
9931+ */
9932+extern int cvmx_helper_get_interface_num(int ipd_port);
9933+
9934+/**
9935+ * Returns the interface index number for an IPD/PKO port
9936+ * number.
9937+ *
9938+ * @ipd_port: IPD/PKO port number
9939+ *
9940+ * Returns Interface index number
9941+ */
9942+extern int cvmx_helper_get_interface_index_num(int ipd_port);
9943+
9944+#endif /* __CVMX_HELPER_H__ */
9945--- /dev/null
9946+++ b/drivers/staging/octeon/cvmx-helper-xaui.c
9947@@ -0,0 +1,348 @@
9948+/***********************license start***************
9949+ * Author: Cavium Networks
9950+ *
9951+ * Contact: support@caviumnetworks.com
9952+ * This file is part of the OCTEON SDK
9953+ *
9954+ * Copyright (c) 2003-2008 Cavium Networks
9955+ *
9956+ * This file is free software; you can redistribute it and/or modify
9957+ * it under the terms of the GNU General Public License, Version 2, as
9958+ * published by the Free Software Foundation.
9959+ *
9960+ * This file is distributed in the hope that it will be useful, but
9961+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9962+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9963+ * NONINFRINGEMENT. See the GNU General Public License for more
9964+ * details.
9965+ *
9966+ * You should have received a copy of the GNU General Public License
9967+ * along with this file; if not, write to the Free Software
9968+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9969+ * or visit http://www.gnu.org/licenses/.
9970+ *
9971+ * This file may also be available under a different license from Cavium.
9972+ * Contact Cavium Networks for more information
9973+ ***********************license end**************************************/
9974+
9975+/*
9976+ * Functions for XAUI initialization, configuration,
9977+ * and monitoring.
9978+ *
9979+ */
9980+
9981+#include <asm/octeon/octeon.h>
9982+
9983+#include "cvmx-config.h"
9984+
9985+#include "cvmx-helper.h"
9986+
9987+#include "cvmx-pko-defs.h"
9988+#include "cvmx-gmxx-defs.h"
9989+#include "cvmx-pcsxx-defs.h"
9990+
9991+void __cvmx_interrupt_gmxx_enable(int interface);
9992+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
9993+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
9994+/**
9995+ * Probe a XAUI interface and determine the number of ports
9996+ * connected to it. The XAUI interface should still be down
9997+ * after this call.
9998+ *
9999+ * @interface: Interface to probe
10000+ *
10001+ * Returns Number of ports on the interface. Zero to disable.
10002+ */
10003+int __cvmx_helper_xaui_probe(int interface)
10004+{
10005+ int i;
10006+ union cvmx_gmxx_hg2_control gmx_hg2_control;
10007+ union cvmx_gmxx_inf_mode mode;
10008+
10009+ /*
10010+ * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
10011+ * interface needs to be enabled before IPD otherwise per port
10012+ * backpressure may not work properly.
10013+ */
10014+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
10015+ mode.s.en = 1;
10016+ cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
10017+
10018+ __cvmx_helper_setup_gmx(interface, 1);
10019+
10020+ /*
10021+ * Setup PKO to support 16 ports for HiGig2 virtual
10022+ * ports. We're pointing all of the PKO packet ports for this
10023+ * interface to the XAUI. This allows us to use HiGig2
10024+ * backpressure per port.
10025+ */
10026+ for (i = 0; i < 16; i++) {
10027+ union cvmx_pko_mem_port_ptrs pko_mem_port_ptrs;
10028+ pko_mem_port_ptrs.u64 = 0;
10029+ /*
10030+ * We set each PKO port to have equal priority in a
10031+ * round robin fashion.
10032+ */
10033+ pko_mem_port_ptrs.s.static_p = 0;
10034+ pko_mem_port_ptrs.s.qos_mask = 0xff;
10035+ /* All PKO ports map to the same XAUI hardware port */
10036+ pko_mem_port_ptrs.s.eid = interface * 4;
10037+ pko_mem_port_ptrs.s.pid = interface * 16 + i;
10038+ cvmx_write_csr(CVMX_PKO_MEM_PORT_PTRS, pko_mem_port_ptrs.u64);
10039+ }
10040+
10041+ /* If HiGig2 is enabled return 16 ports, otherwise return 1 port */
10042+ gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface));
10043+ if (gmx_hg2_control.s.hg2tx_en)
10044+ return 16;
10045+ else
10046+ return 1;
10047+}
10048+
10049+/**
10050+ * Bringup and enable a XAUI interface. After this call packet
10051+ * I/O should be fully functional. This is called with IPD
10052+ * enabled but PKO disabled.
10053+ *
10054+ * @interface: Interface to bring up
10055+ *
10056+ * Returns Zero on success, negative on failure
10057+ */
10058+int __cvmx_helper_xaui_enable(int interface)
10059+{
10060+ union cvmx_gmxx_prtx_cfg gmx_cfg;
10061+ union cvmx_pcsxx_control1_reg xauiCtl;
10062+ union cvmx_pcsxx_misc_ctl_reg xauiMiscCtl;
10063+ union cvmx_gmxx_tx_xaui_ctl gmxXauiTxCtl;
10064+ union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
10065+ union cvmx_gmxx_tx_int_en gmx_tx_int_en;
10066+ union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
10067+
10068+ /* (1) Interface has already been enabled. */
10069+
10070+ /* (2) Disable GMX. */
10071+ xauiMiscCtl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface));
10072+ xauiMiscCtl.s.gmxeno = 1;
10073+ cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
10074+
10075+ /* (3) Disable GMX and PCSX interrupts. */
10076+ gmx_rx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_EN(0, interface));
10077+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
10078+ gmx_tx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_TX_INT_EN(interface));
10079+ cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
10080+ pcsx_int_en_reg.u64 = cvmx_read_csr(CVMX_PCSXX_INT_EN_REG(interface));
10081+ cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
10082+
10083+ /* (4) Bring up the PCSX and GMX reconciliation layer. */
10084+ /* (4)a Set polarity and lane swapping. */
10085+ /* (4)b */
10086+ gmxXauiTxCtl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10087+ /* Enable better IFG packing and improves performance */
10088+ gmxXauiTxCtl.s.dic_en = 1;
10089+ gmxXauiTxCtl.s.uni_en = 0;
10090+ cvmx_write_csr(CVMX_GMXX_TX_XAUI_CTL(interface), gmxXauiTxCtl.u64);
10091+
10092+ /* (4)c Aply reset sequence */
10093+ xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
10094+ xauiCtl.s.lo_pwr = 0;
10095+ xauiCtl.s.reset = 1;
10096+ cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
10097+
10098+ /* Wait for PCS to come out of reset */
10099+ if (CVMX_WAIT_FOR_FIELD64
10100+ (CVMX_PCSXX_CONTROL1_REG(interface), union cvmx_pcsxx_control1_reg,
10101+ reset, ==, 0, 10000))
10102+ return -1;
10103+ /* Wait for PCS to be aligned */
10104+ if (CVMX_WAIT_FOR_FIELD64
10105+ (CVMX_PCSXX_10GBX_STATUS_REG(interface),
10106+ union cvmx_pcsxx_10gbx_status_reg, alignd, ==, 1, 10000))
10107+ return -1;
10108+ /* Wait for RX to be ready */
10109+ if (CVMX_WAIT_FOR_FIELD64
10110+ (CVMX_GMXX_RX_XAUI_CTL(interface), union cvmx_gmxx_rx_xaui_ctl,
10111+ status, ==, 0, 10000))
10112+ return -1;
10113+
10114+ /* (6) Configure GMX */
10115+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10116+ gmx_cfg.s.en = 0;
10117+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10118+
10119+ /* Wait for GMX RX to be idle */
10120+ if (CVMX_WAIT_FOR_FIELD64
10121+ (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
10122+ rx_idle, ==, 1, 10000))
10123+ return -1;
10124+ /* Wait for GMX TX to be idle */
10125+ if (CVMX_WAIT_FOR_FIELD64
10126+ (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
10127+ tx_idle, ==, 1, 10000))
10128+ return -1;
10129+
10130+ /* GMX configure */
10131+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10132+ gmx_cfg.s.speed = 1;
10133+ gmx_cfg.s.speed_msb = 0;
10134+ gmx_cfg.s.slottime = 1;
10135+ cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), 1);
10136+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(0, interface), 512);
10137+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(0, interface), 8192);
10138+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10139+
10140+ /* (7) Clear out any error state */
10141+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(0, interface),
10142+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(0, interface)));
10143+ cvmx_write_csr(CVMX_GMXX_TX_INT_REG(interface),
10144+ cvmx_read_csr(CVMX_GMXX_TX_INT_REG(interface)));
10145+ cvmx_write_csr(CVMX_PCSXX_INT_REG(interface),
10146+ cvmx_read_csr(CVMX_PCSXX_INT_REG(interface)));
10147+
10148+ /* Wait for receive link */
10149+ if (CVMX_WAIT_FOR_FIELD64
10150+ (CVMX_PCSXX_STATUS1_REG(interface), union cvmx_pcsxx_status1_reg,
10151+ rcv_lnk, ==, 1, 10000))
10152+ return -1;
10153+ if (CVMX_WAIT_FOR_FIELD64
10154+ (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
10155+ xmtflt, ==, 0, 10000))
10156+ return -1;
10157+ if (CVMX_WAIT_FOR_FIELD64
10158+ (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
10159+ rcvflt, ==, 0, 10000))
10160+ return -1;
10161+
10162+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), gmx_rx_int_en.u64);
10163+ cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
10164+ cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64);
10165+
10166+ cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port(interface, 0));
10167+
10168+ /* (8) Enable packet reception */
10169+ xauiMiscCtl.s.gmxeno = 0;
10170+ cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
10171+
10172+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10173+ gmx_cfg.s.en = 1;
10174+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10175+
10176+ __cvmx_interrupt_pcsx_intx_en_reg_enable(0, interface);
10177+ __cvmx_interrupt_pcsx_intx_en_reg_enable(1, interface);
10178+ __cvmx_interrupt_pcsx_intx_en_reg_enable(2, interface);
10179+ __cvmx_interrupt_pcsx_intx_en_reg_enable(3, interface);
10180+ __cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
10181+ __cvmx_interrupt_gmxx_enable(interface);
10182+
10183+ return 0;
10184+}
10185+
10186+/**
10187+ * Return the link state of an IPD/PKO port as returned by
10188+ * auto negotiation. The result of this function may not match
10189+ * Octeon's link config if auto negotiation has changed since
10190+ * the last call to cvmx_helper_link_set().
10191+ *
10192+ * @ipd_port: IPD/PKO port to query
10193+ *
10194+ * Returns Link state
10195+ */
10196+cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port)
10197+{
10198+ int interface = cvmx_helper_get_interface_num(ipd_port);
10199+ union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
10200+ union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
10201+ union cvmx_pcsxx_status1_reg pcsxx_status1_reg;
10202+ cvmx_helper_link_info_t result;
10203+
10204+ gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10205+ gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
10206+ pcsxx_status1_reg.u64 =
10207+ cvmx_read_csr(CVMX_PCSXX_STATUS1_REG(interface));
10208+ result.u64 = 0;
10209+
10210+ /* Only return a link if both RX and TX are happy */
10211+ if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0) &&
10212+ (pcsxx_status1_reg.s.rcv_lnk == 1)) {
10213+ result.s.link_up = 1;
10214+ result.s.full_duplex = 1;
10215+ result.s.speed = 10000;
10216+ } else {
10217+ /* Disable GMX and PCSX interrupts. */
10218+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
10219+ cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
10220+ cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
10221+ }
10222+ return result;
10223+}
10224+
10225+/**
10226+ * Configure an IPD/PKO port for the specified link state. This
10227+ * function does not influence auto negotiation at the PHY level.
10228+ * The passed link state must always match the link state returned
10229+ * by cvmx_helper_link_get(). It is normally best to use
10230+ * cvmx_helper_link_autoconf() instead.
10231+ *
10232+ * @ipd_port: IPD/PKO port to configure
10233+ * @link_info: The new link state
10234+ *
10235+ * Returns Zero on success, negative on failure
10236+ */
10237+int __cvmx_helper_xaui_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
10238+{
10239+ int interface = cvmx_helper_get_interface_num(ipd_port);
10240+ union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
10241+ union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
10242+
10243+ gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10244+ gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
10245+
10246+ /* If the link shouldn't be up, then just return */
10247+ if (!link_info.s.link_up)
10248+ return 0;
10249+
10250+ /* Do nothing if both RX and TX are happy */
10251+ if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0))
10252+ return 0;
10253+
10254+ /* Bring the link up */
10255+ return __cvmx_helper_xaui_enable(interface);
10256+}
10257+
10258+/**
10259+ * Configure a port for internal and/or external loopback. Internal loopback
10260+ * causes packets sent by the port to be received by Octeon. External loopback
10261+ * causes packets received from the wire to sent out again.
10262+ *
10263+ * @ipd_port: IPD/PKO port to loopback.
10264+ * @enable_internal:
10265+ * Non zero if you want internal loopback
10266+ * @enable_external:
10267+ * Non zero if you want external loopback
10268+ *
10269+ * Returns Zero on success, negative on failure.
10270+ */
10271+extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
10272+ int enable_internal,
10273+ int enable_external)
10274+{
10275+ int interface = cvmx_helper_get_interface_num(ipd_port);
10276+ union cvmx_pcsxx_control1_reg pcsxx_control1_reg;
10277+ union cvmx_gmxx_xaui_ext_loopback gmxx_xaui_ext_loopback;
10278+
10279+ /* Set the internal loop */
10280+ pcsxx_control1_reg.u64 =
10281+ cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
10282+ pcsxx_control1_reg.s.loopbck1 = enable_internal;
10283+ cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface),
10284+ pcsxx_control1_reg.u64);
10285+
10286+ /* Set the external loop */
10287+ gmxx_xaui_ext_loopback.u64 =
10288+ cvmx_read_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface));
10289+ gmxx_xaui_ext_loopback.s.en = enable_external;
10290+ cvmx_write_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface),
10291+ gmxx_xaui_ext_loopback.u64);
10292+
10293+ /* Take the link through a reset */
10294+ return __cvmx_helper_xaui_enable(interface);
10295+}
10296--- /dev/null
10297+++ b/drivers/staging/octeon/cvmx-helper-xaui.h
10298@@ -0,0 +1,103 @@
10299+/***********************license start***************
10300+ * Author: Cavium Networks
10301+ *
10302+ * Contact: support@caviumnetworks.com
10303+ * This file is part of the OCTEON SDK
10304+ *
10305+ * Copyright (c) 2003-2008 Cavium Networks
10306+ *
10307+ * This file is free software; you can redistribute it and/or modify
10308+ * it under the terms of the GNU General Public License, Version 2, as
10309+ * published by the Free Software Foundation.
10310+ *
10311+ * This file is distributed in the hope that it will be useful, but
10312+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
10313+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
10314+ * NONINFRINGEMENT. See the GNU General Public License for more
10315+ * details.
10316+ *
10317+ * You should have received a copy of the GNU General Public License
10318+ * along with this file; if not, write to the Free Software
10319+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10320+ * or visit http://www.gnu.org/licenses/.
10321+ *
10322+ * This file may also be available under a different license from Cavium.
10323+ * Contact Cavium Networks for more information
10324+ ***********************license end**************************************/
10325+
10326+/**
10327+ * @file
10328+ *
10329+ * Functions for XAUI initialization, configuration,
10330+ * and monitoring.
10331+ *
10332+ */
10333+#ifndef __CVMX_HELPER_XAUI_H__
10334+#define __CVMX_HELPER_XAUI_H__
10335+
10336+/**
10337+ * Probe a XAUI interface and determine the number of ports
10338+ * connected to it. The XAUI interface should still be down
10339+ * after this call.
10340+ *
10341+ * @interface: Interface to probe
10342+ *
10343+ * Returns Number of ports on the interface. Zero to disable.
10344+ */
10345+extern int __cvmx_helper_xaui_probe(int interface);
10346+
10347+/**
10348+ * Bringup and enable a XAUI interface. After this call packet
10349+ * I/O should be fully functional. This is called with IPD
10350+ * enabled but PKO disabled.
10351+ *
10352+ * @interface: Interface to bring up
10353+ *
10354+ * Returns Zero on success, negative on failure
10355+ */
10356+extern int __cvmx_helper_xaui_enable(int interface);
10357+
10358+/**
10359+ * Return the link state of an IPD/PKO port as returned by
10360+ * auto negotiation. The result of this function may not match
10361+ * Octeon's link config if auto negotiation has changed since
10362+ * the last call to cvmx_helper_link_set().
10363+ *
10364+ * @ipd_port: IPD/PKO port to query
10365+ *
10366+ * Returns Link state
10367+ */
10368+extern cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port);
10369+
10370+/**
10371+ * Configure an IPD/PKO port for the specified link state. This
10372+ * function does not influence auto negotiation at the PHY level.
10373+ * The passed link state must always match the link state returned
10374+ * by cvmx_helper_link_get(). It is normally best to use
10375+ * cvmx_helper_link_autoconf() instead.
10376+ *
10377+ * @ipd_port: IPD/PKO port to configure
10378+ * @link_info: The new link state
10379+ *
10380+ * Returns Zero on success, negative on failure
10381+ */
10382+extern int __cvmx_helper_xaui_link_set(int ipd_port,
10383+ cvmx_helper_link_info_t link_info);
10384+
10385+/**
10386+ * Configure a port for internal and/or external loopback. Internal loopback
10387+ * causes packets sent by the port to be received by Octeon. External loopback
10388+ * causes packets received from the wire to sent out again.
10389+ *
10390+ * @ipd_port: IPD/PKO port to loopback.
10391+ * @enable_internal:
10392+ * Non zero if you want internal loopback
10393+ * @enable_external:
10394+ * Non zero if you want external loopback
10395+ *
10396+ * Returns Zero on success, negative on failure.
10397+ */
10398+extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
10399+ int enable_internal,
10400+ int enable_external);
10401+#endif
10402--- /dev/null
10403+++ b/drivers/staging/octeon/cvmx-helper.c
10404@@ -0,0 +1,1058 @@
10405+/***********************license start***************
10406+ * Author: Cavium Networks
10407+ *
10408+ * Contact: support@caviumnetworks.com
10409+ * This file is part of the OCTEON SDK
10410+ *
10411+ * Copyright (c) 2003-2008 Cavium Networks
10412+ *
10413+ * This file is free software; you can redistribute it and/or modify
10414+ * it under the terms of the GNU General Public License, Version 2, as
10415+ * published by the Free Software Foundation.
10416+ *
10417+ * This file is distributed in the hope that it will be useful, but
10418+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
10419+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
10420+ * NONINFRINGEMENT. See the GNU General Public License for more
10421+ * details.
10422+ *
10423+ * You should have received a copy of the GNU General Public License
10424+ * along with this file; if not, write to the Free Software
10425+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10426+ * or visit http://www.gnu.org/licenses/.
10427+ *
10428+ * This file may also be available under a different license from Cavium.
10429+ * Contact Cavium Networks for more information
10430+ ***********************license end**************************************/
10431+
10432+/*
10433+ *
10434+ * Helper functions for common, but complicated tasks.
10435+ *
10436+ */
10437+#include <asm/octeon/octeon.h>
10438+
10439+#include "cvmx-config.h"
10440+
10441+#include "cvmx-fpa.h"
10442+#include "cvmx-pip.h"
10443+#include "cvmx-pko.h"
10444+#include "cvmx-ipd.h"
10445+#include "cvmx-spi.h"
10446+#include "cvmx-helper.h"
10447+#include "cvmx-helper-board.h"
10448+
10449+#include "cvmx-pip-defs.h"
10450+#include "cvmx-smix-defs.h"
10451+#include "cvmx-asxx-defs.h"
10452+
10453+/**
10454+ * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
10455+ * priorities[16]) is a function pointer. It is meant to allow
10456+ * customization of the PKO queue priorities based on the port
10457+ * number. Users should set this pointer to a function before
10458+ * calling any cvmx-helper operations.
10459+ */
10460+void (*cvmx_override_pko_queue_priority) (int pko_port,
10461+ uint64_t priorities[16]);
10462+
10463+/**
10464+ * cvmx_override_ipd_port_setup(int ipd_port) is a function
10465+ * pointer. It is meant to allow customization of the IPD port
10466+ * setup before packet input/output comes online. It is called
10467+ * after cvmx-helper does the default IPD configuration, but
10468+ * before IPD is enabled. Users should set this pointer to a
10469+ * function before calling any cvmx-helper operations.
10470+ */
10471+void (*cvmx_override_ipd_port_setup) (int ipd_port);
10472+
10473+/* Port count per interface */
10474+static int interface_port_count[4] = { 0, 0, 0, 0 };
10475+
10476+/* Port last configured link info index by IPD/PKO port */
10477+static cvmx_helper_link_info_t
10478+ port_link_info[CVMX_PIP_NUM_INPUT_PORTS];
10479+
10480+/**
10481+ * Return the number of interfaces the chip has. Each interface
10482+ * may have multiple ports. Most chips support two interfaces,
10483+ * but the CNX0XX and CNX1XX are exceptions. These only support
10484+ * one interface.
10485+ *
10486+ * Returns Number of interfaces on chip
10487+ */
10488+int cvmx_helper_get_number_of_interfaces(void)
10489+{
10490+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
10491+ return 4;
10492+ else
10493+ return 3;
10494+}
10495+
10496+/**
10497+ * Return the number of ports on an interface. Depending on the
10498+ * chip and configuration, this can be 1-16. A value of 0
10499+ * specifies that the interface doesn't exist or isn't usable.
10500+ *
10501+ * @interface: Interface to get the port count for
10502+ *
10503+ * Returns Number of ports on interface. Can be Zero.
10504+ */
10505+int cvmx_helper_ports_on_interface(int interface)
10506+{
10507+ return interface_port_count[interface];
10508+}
10509+
10510+/**
10511+ * Get the operating mode of an interface. Depending on the Octeon
10512+ * chip and configuration, this function returns an enumeration
10513+ * of the type of packet I/O supported by an interface.
10514+ *
10515+ * @interface: Interface to probe
10516+ *
10517+ * Returns Mode of the interface. Unknown or unsupported interfaces return
10518+ * DISABLED.
10519+ */
10520+cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
10521+{
10522+ union cvmx_gmxx_inf_mode mode;
10523+ if (interface == 2)
10524+ return CVMX_HELPER_INTERFACE_MODE_NPI;
10525+
10526+ if (interface == 3) {
10527+ if (OCTEON_IS_MODEL(OCTEON_CN56XX)
10528+ || OCTEON_IS_MODEL(OCTEON_CN52XX))
10529+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
10530+ else
10531+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10532+ }
10533+
10534+ if (interface == 0
10535+ && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
10536+ && cvmx_sysinfo_get()->board_rev_major == 1) {
10537+ /*
10538+ * Lie about interface type of CN3005 board. This
10539+ * board has a switch on port 1 like the other
10540+ * evaluation boards, but it is connected over RGMII
10541+ * instead of GMII. Report GMII mode so that the
10542+ * speed is forced to 1 Gbit full duplex. Other than
10543+ * some initial configuration (which does not use the
10544+ * output of this function) there is no difference in
10545+ * setup between GMII and RGMII modes.
10546+ */
10547+ return CVMX_HELPER_INTERFACE_MODE_GMII;
10548+ }
10549+
10550+ /* Interface 1 is always disabled on CN31XX and CN30XX */
10551+ if ((interface == 1)
10552+ && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
10553+ || OCTEON_IS_MODEL(OCTEON_CN50XX)
10554+ || OCTEON_IS_MODEL(OCTEON_CN52XX)))
10555+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10556+
10557+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
10558+
10559+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
10560+ switch (mode.cn56xx.mode) {
10561+ case 0:
10562+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10563+ case 1:
10564+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
10565+ case 2:
10566+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
10567+ case 3:
10568+ return CVMX_HELPER_INTERFACE_MODE_PICMG;
10569+ default:
10570+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10571+ }
10572+ } else {
10573+ if (!mode.s.en)
10574+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10575+
10576+ if (mode.s.type) {
10577+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)
10578+ || OCTEON_IS_MODEL(OCTEON_CN58XX))
10579+ return CVMX_HELPER_INTERFACE_MODE_SPI;
10580+ else
10581+ return CVMX_HELPER_INTERFACE_MODE_GMII;
10582+ } else
10583+ return CVMX_HELPER_INTERFACE_MODE_RGMII;
10584+ }
10585+}
10586+
10587+/**
10588+ * Configure the IPD/PIP tagging and QoS options for a specific
10589+ * port. This function determines the POW work queue entry
10590+ * contents for a port. The setup performed here is controlled by
10591+ * the defines in executive-config.h.
10592+ *
10593+ * @ipd_port: Port to configure. This follows the IPD numbering, not the
10594+ * per interface numbering
10595+ *
10596+ * Returns Zero on success, negative on failure
10597+ */
10598+static int __cvmx_helper_port_setup_ipd(int ipd_port)
10599+{
10600+ union cvmx_pip_prt_cfgx port_config;
10601+ union cvmx_pip_prt_tagx tag_config;
10602+
10603+ port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
10604+ tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
10605+
10606+ /* Have each port go to a different POW queue */
10607+ port_config.s.qos = ipd_port & 0x7;
10608+
10609+ /* Process the headers and place the IP header in the work queue */
10610+ port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
10611+
10612+ tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
10613+ tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
10614+ tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
10615+ tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
10616+ tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
10617+ tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
10618+ tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
10619+ tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
10620+ tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
10621+ tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
10622+ tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
10623+ tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10624+ tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10625+ tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10626+ tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10627+ tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10628+ /* Put all packets in group 0. Other groups can be used by the app */
10629+ tag_config.s.grp = 0;
10630+
10631+ cvmx_pip_config_port(ipd_port, port_config, tag_config);
10632+
10633+ /* Give the user a chance to override our setting for each port */
10634+ if (cvmx_override_ipd_port_setup)
10635+ cvmx_override_ipd_port_setup(ipd_port);
10636+
10637+ return 0;
10638+}
10639+
10640+/**
10641+ * This function probes an interface to determine the actual
10642+ * number of hardware ports connected to it. It doesn't setup the
10643+ * ports or enable them. The main goal here is to set the global
10644+ * interface_port_count[interface] correctly. Hardware setup of the
10645+ * ports will be performed later.
10646+ *
10647+ * @interface: Interface to probe
10648+ *
10649+ * Returns Zero on success, negative on failure
10650+ */
10651+int cvmx_helper_interface_probe(int interface)
10652+{
10653+ /* At this stage in the game we don't want packets to be moving yet.
10654+ The following probe calls should perform hardware setup
10655+ needed to determine port counts. Receive must still be disabled */
10656+ switch (cvmx_helper_interface_get_mode(interface)) {
10657+ /* These types don't support ports to IPD/PKO */
10658+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10659+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
10660+ interface_port_count[interface] = 0;
10661+ break;
10662+ /* XAUI is a single high speed port */
10663+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
10664+ interface_port_count[interface] =
10665+ __cvmx_helper_xaui_probe(interface);
10666+ break;
10667+ /*
10668+ * RGMII/GMII/MII are all treated about the same. Most
10669+ * functions refer to these ports as RGMII.
10670+ */
10671+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
10672+ case CVMX_HELPER_INTERFACE_MODE_GMII:
10673+ interface_port_count[interface] =
10674+ __cvmx_helper_rgmii_probe(interface);
10675+ break;
10676+ /*
10677+ * SPI4 can have 1-16 ports depending on the device at
10678+ * the other end.
10679+ */
10680+ case CVMX_HELPER_INTERFACE_MODE_SPI:
10681+ interface_port_count[interface] =
10682+ __cvmx_helper_spi_probe(interface);
10683+ break;
10684+ /*
10685+ * SGMII can have 1-4 ports depending on how many are
10686+ * hooked up.
10687+ */
10688+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
10689+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
10690+ interface_port_count[interface] =
10691+ __cvmx_helper_sgmii_probe(interface);
10692+ break;
10693+ /* PCI target Network Packet Interface */
10694+ case CVMX_HELPER_INTERFACE_MODE_NPI:
10695+ interface_port_count[interface] =
10696+ __cvmx_helper_npi_probe(interface);
10697+ break;
10698+ /*
10699+ * Special loopback only ports. These are not the same
10700+ * as other ports in loopback mode.
10701+ */
10702+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
10703+ interface_port_count[interface] =
10704+ __cvmx_helper_loop_probe(interface);
10705+ break;
10706+ }
10707+
10708+ interface_port_count[interface] =
10709+ __cvmx_helper_board_interface_probe(interface,
10710+ interface_port_count
10711+ [interface]);
10712+
10713+ /* Make sure all global variables propagate to other cores */
10714+ CVMX_SYNCWS;
10715+
10716+ return 0;
10717+}
10718+
10719+/**
10720+ * Setup the IPD/PIP for the ports on an interface. Packet
10721+ * classification and tagging are set for every port on the
10722+ * interface. The number of ports on the interface must already
10723+ * have been probed.
10724+ *
10725+ * @interface: Interface to setup IPD/PIP for
10726+ *
10727+ * Returns Zero on success, negative on failure
10728+ */
10729+static int __cvmx_helper_interface_setup_ipd(int interface)
10730+{
10731+ int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
10732+ int num_ports = interface_port_count[interface];
10733+
10734+ while (num_ports--) {
10735+ __cvmx_helper_port_setup_ipd(ipd_port);
10736+ ipd_port++;
10737+ }
10738+ return 0;
10739+}
10740+
10741+/**
10742+ * Setup global setting for IPD/PIP not related to a specific
10743+ * interface or port. This must be called before IPD is enabled.
10744+ *
10745+ * Returns Zero on success, negative on failure.
10746+ */
10747+static int __cvmx_helper_global_setup_ipd(void)
10748+{
10749+ /* Setup the global packet input options */
10750+ cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8,
10751+ CVMX_HELPER_FIRST_MBUFF_SKIP / 8,
10752+ CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8,
10753+ /* The +8 is to account for the next ptr */
10754+ (CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128,
10755+ /* The +8 is to account for the next ptr */
10756+ (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128,
10757+ CVMX_FPA_WQE_POOL,
10758+ CVMX_IPD_OPC_MODE_STT,
10759+ CVMX_HELPER_ENABLE_BACK_PRESSURE);
10760+ return 0;
10761+}
10762+
10763+/**
10764+ * Setup the PKO for the ports on an interface. The number of
10765+ * queues per port and the priority of each PKO output queue
10766+ * is set here. PKO must be disabled when this function is called.
10767+ *
10768+ * @interface: Interface to setup PKO for
10769+ *
10770+ * Returns Zero on success, negative on failure
10771+ */
10772+static int __cvmx_helper_interface_setup_pko(int interface)
10773+{
10774+ /*
10775+ * Each packet output queue has an associated priority. The
10776+ * higher the priority, the more often it can send a packet. A
10777+ * priority of 8 means it can send in all 8 rounds of
10778+ * contention. We're going to make each queue one less than
10779+ * the last. The vector of priorities has been extended to
10780+ * support CN5xxx CPUs, where up to 16 queues can be
10781+ * associated to a port. To keep backward compatibility we
10782+ * don't change the initial 8 priorities and replicate them in
10783+ * the second half. With per-core PKO queues (PKO lockless
10784+ * operation) all queues have the same priority.
10785+ */
10786+ uint64_t priorities[16] =
10787+ { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
10788+
10789+ /*
10790+ * Setup the IPD/PIP and PKO for the ports discovered
10791+ * above. Here packet classification, tagging and output
10792+ * priorities are set.
10793+ */
10794+ int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
10795+ int num_ports = interface_port_count[interface];
10796+ while (num_ports--) {
10797+ /*
10798+ * Give the user a chance to override the per queue
10799+ * priorities.
10800+ */
10801+ if (cvmx_override_pko_queue_priority)
10802+ cvmx_override_pko_queue_priority(ipd_port, priorities);
10803+
10804+ cvmx_pko_config_port(ipd_port,
10805+ cvmx_pko_get_base_queue_per_core(ipd_port,
10806+ 0),
10807+ cvmx_pko_get_num_queues(ipd_port),
10808+ priorities);
10809+ ipd_port++;
10810+ }
10811+ return 0;
10812+}
10813+
10814+/**
10815+ * Setup global setting for PKO not related to a specific
10816+ * interface or port. This must be called before PKO is enabled.
10817+ *
10818+ * Returns Zero on success, negative on failure.
10819+ */
10820+static int __cvmx_helper_global_setup_pko(void)
10821+{
10822+ /*
10823+ * Disable tagwait FAU timeout. This needs to be done before
10824+ * anyone might start packet output using tags.
10825+ */
10826+ union cvmx_iob_fau_timeout fau_to;
10827+ fau_to.u64 = 0;
10828+ fau_to.s.tout_val = 0xfff;
10829+ fau_to.s.tout_enb = 0;
10830+ cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
10831+ return 0;
10832+}
10833+
10834+/**
10835+ * Setup global backpressure setting.
10836+ *
10837+ * Returns Zero on success, negative on failure
10838+ */
10839+static int __cvmx_helper_global_setup_backpressure(void)
10840+{
10841+#if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
10842+ /* Disable backpressure if configured to do so */
10843+ /* Disable backpressure (pause frame) generation */
10844+ int num_interfaces = cvmx_helper_get_number_of_interfaces();
10845+ int interface;
10846+ for (interface = 0; interface < num_interfaces; interface++) {
10847+ switch (cvmx_helper_interface_get_mode(interface)) {
10848+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10849+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
10850+ case CVMX_HELPER_INTERFACE_MODE_NPI:
10851+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
10852+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
10853+ break;
10854+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
10855+ case CVMX_HELPER_INTERFACE_MODE_GMII:
10856+ case CVMX_HELPER_INTERFACE_MODE_SPI:
10857+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
10858+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
10859+ cvmx_gmx_set_backpressure_override(interface, 0xf);
10860+ break;
10861+ }
10862+ }
10863+#endif
10864+
10865+ return 0;
10866+}
10867+
10868+/**
10869+ * Enable packet input/output from the hardware. This function is
10870+ * called after all internal setup is complete and IPD is enabled.
10871+ * After this function completes, packets will be accepted from the
10872+ * hardware ports. PKO should still be disabled to make sure packets
10873+ * aren't sent out partially setup hardware.
10874+ *
10875+ * @interface: Interface to enable
10876+ *
10877+ * Returns Zero on success, negative on failure
10878+ */
10879+static int __cvmx_helper_packet_hardware_enable(int interface)
10880+{
10881+ int result = 0;
10882+ switch (cvmx_helper_interface_get_mode(interface)) {
10883+ /* These types don't support ports to IPD/PKO */
10884+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10885+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
10886+ /* Nothing to do */
10887+ break;
10888+ /* XAUI is a single high speed port */
10889+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
10890+ result = __cvmx_helper_xaui_enable(interface);
10891+ break;
10892+ /*
10893+ * RGMII/GMII/MII are all treated about the same. Most
10894+ * functions refer to these ports as RGMII
10895+ */
10896+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
10897+ case CVMX_HELPER_INTERFACE_MODE_GMII:
10898+ result = __cvmx_helper_rgmii_enable(interface);
10899+ break;
10900+ /*
10901+ * SPI4 can have 1-16 ports depending on the device at
10902+ * the other end
10903+ */
10904+ case CVMX_HELPER_INTERFACE_MODE_SPI:
10905+ result = __cvmx_helper_spi_enable(interface);
10906+ break;
10907+ /*
10908+ * SGMII can have 1-4 ports depending on how many are
10909+ * hooked up
10910+ */
10911+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
10912+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
10913+ result = __cvmx_helper_sgmii_enable(interface);
10914+ break;
10915+ /* PCI target Network Packet Interface */
10916+ case CVMX_HELPER_INTERFACE_MODE_NPI:
10917+ result = __cvmx_helper_npi_enable(interface);
10918+ break;
10919+ /*
10920+ * Special loopback only ports. These are not the same
10921+ * as other ports in loopback mode
10922+ */
10923+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
10924+ result = __cvmx_helper_loop_enable(interface);
10925+ break;
10926+ }
10927+ result |= __cvmx_helper_board_hardware_enable(interface);
10928+ return result;
10929+}
10930+
10931+/**
10932+ * Function to adjust internal IPD pointer alignments
10933+ *
10934+ * Returns 0 on success
10935+ * !0 on failure
10936+ */
10937+int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
10938+{
10939+#define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
10940+ (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
10941+#define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
10942+ (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
10943+#define FIX_IPD_OUTPORT 0
10944+ /* Ports 0-15 are interface 0, 16-31 are interface 1 */
10945+#define INTERFACE(port) (port >> 4)
10946+#define INDEX(port) (port & 0xf)
10947+ uint64_t *p64;
10948+ cvmx_pko_command_word0_t pko_command;
10949+ union cvmx_buf_ptr g_buffer, pkt_buffer;
10950+ cvmx_wqe_t *work;
10951+ int size, num_segs = 0, wqe_pcnt, pkt_pcnt;
10952+ union cvmx_gmxx_prtx_cfg gmx_cfg;
10953+ int retry_cnt;
10954+ int retry_loop_cnt;
10955+ int mtu;
10956+ int i;
10957+ cvmx_helper_link_info_t link_info;
10958+
10959+ /* Save values for restore at end */
10960+ uint64_t prtx_cfg =
10961+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG
10962+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
10963+ uint64_t tx_ptr_en =
10964+ cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
10965+ uint64_t rx_ptr_en =
10966+ cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
10967+ uint64_t rxx_jabber =
10968+ cvmx_read_csr(CVMX_GMXX_RXX_JABBER
10969+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
10970+ uint64_t frame_max =
10971+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
10972+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
10973+
10974+ /* Configure port to gig FDX as required for loopback mode */
10975+ cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
10976+
10977+ /*
10978+ * Disable reception on all ports so if traffic is present it
10979+ * will not interfere.
10980+ */
10981+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
10982+
10983+ cvmx_wait(100000000ull);
10984+
10985+ for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) {
10986+ retry_cnt = 100000;
10987+ wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
10988+ pkt_pcnt = (wqe_pcnt >> 7) & 0x7f;
10989+ wqe_pcnt &= 0x7f;
10990+
10991+ num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
10992+
10993+ if (num_segs == 0)
10994+ goto fix_ipd_exit;
10995+
10996+ num_segs += 1;
10997+
10998+ size =
10999+ FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES +
11000+ ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) -
11001+ (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2);
11002+
11003+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
11004+ 1 << INDEX(FIX_IPD_OUTPORT));
11005+ CVMX_SYNC;
11006+
11007+ g_buffer.u64 = 0;
11008+ g_buffer.s.addr =
11009+ cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL));
11010+ if (g_buffer.s.addr == 0) {
11011+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11012+ "buffer allocation failure.\n");
11013+ goto fix_ipd_exit;
11014+ }
11015+
11016+ g_buffer.s.pool = CVMX_FPA_WQE_POOL;
11017+ g_buffer.s.size = num_segs;
11018+
11019+ pkt_buffer.u64 = 0;
11020+ pkt_buffer.s.addr =
11021+ cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL));
11022+ if (pkt_buffer.s.addr == 0) {
11023+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11024+ "buffer allocation failure.\n");
11025+ goto fix_ipd_exit;
11026+ }
11027+ pkt_buffer.s.i = 1;
11028+ pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL;
11029+ pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES;
11030+
11031+ p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr);
11032+ p64[0] = 0xffffffffffff0000ull;
11033+ p64[1] = 0x08004510ull;
11034+ p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull;
11035+ p64[3] = 0x3a5fc0a81073c0a8ull;
11036+
11037+ for (i = 0; i < num_segs; i++) {
11038+ if (i > 0)
11039+ pkt_buffer.s.size =
11040+ FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
11041+
11042+ if (i == (num_segs - 1))
11043+ pkt_buffer.s.i = 0;
11044+
11045+ *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
11046+ 8 * i) = pkt_buffer.u64;
11047+ }
11048+
11049+ /* Build the PKO command */
11050+ pko_command.u64 = 0;
11051+ pko_command.s.segs = num_segs;
11052+ pko_command.s.total_bytes = size;
11053+ pko_command.s.dontfree = 0;
11054+ pko_command.s.gather = 1;
11055+
11056+ gmx_cfg.u64 =
11057+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG
11058+ (INDEX(FIX_IPD_OUTPORT),
11059+ INTERFACE(FIX_IPD_OUTPORT)));
11060+ gmx_cfg.s.en = 1;
11061+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG
11062+ (INDEX(FIX_IPD_OUTPORT),
11063+ INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64);
11064+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11065+ 1 << INDEX(FIX_IPD_OUTPORT));
11066+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11067+ 1 << INDEX(FIX_IPD_OUTPORT));
11068+
11069+ mtu =
11070+ cvmx_read_csr(CVMX_GMXX_RXX_JABBER
11071+ (INDEX(FIX_IPD_OUTPORT),
11072+ INTERFACE(FIX_IPD_OUTPORT)));
11073+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER
11074+ (INDEX(FIX_IPD_OUTPORT),
11075+ INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
11076+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
11077+ (INDEX(FIX_IPD_OUTPORT),
11078+ INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
11079+
11080+ cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT,
11081+ cvmx_pko_get_base_queue
11082+ (FIX_IPD_OUTPORT),
11083+ CVMX_PKO_LOCK_CMD_QUEUE);
11084+ cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT,
11085+ cvmx_pko_get_base_queue
11086+ (FIX_IPD_OUTPORT), pko_command,
11087+ g_buffer, CVMX_PKO_LOCK_CMD_QUEUE);
11088+
11089+ CVMX_SYNC;
11090+
11091+ do {
11092+ work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
11093+ retry_cnt--;
11094+ } while ((work == NULL) && (retry_cnt > 0));
11095+
11096+ if (!retry_cnt)
11097+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11098+ "get_work() timeout occured.\n");
11099+
11100+ /* Free packet */
11101+ if (work)
11102+ cvmx_helper_free_packet_data(work);
11103+ }
11104+
11105+fix_ipd_exit:
11106+
11107+ /* Return CSR configs to saved values */
11108+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG
11109+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11110+ prtx_cfg);
11111+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11112+ tx_ptr_en);
11113+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11114+ rx_ptr_en);
11115+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER
11116+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11117+ rxx_jabber);
11118+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
11119+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11120+ frame_max);
11121+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0);
11122+ /* Set link to down so autonegotiation will set it up again */
11123+ link_info.u64 = 0;
11124+ cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info);
11125+
11126+ /*
11127+ * Bring the link back up as autonegotiation is not done in
11128+ * user applications.
11129+ */
11130+ cvmx_helper_link_autoconf(FIX_IPD_OUTPORT);
11131+
11132+ CVMX_SYNC;
11133+ if (num_segs)
11134+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
11135+
11136+ return !!num_segs;
11137+
11138+}
11139+
11140+/**
11141+ * Called after all internal packet IO paths are setup. This
11142+ * function enables IPD/PIP and begins packet input and output.
11143+ *
11144+ * Returns Zero on success, negative on failure
11145+ */
11146+int cvmx_helper_ipd_and_packet_input_enable(void)
11147+{
11148+ int num_interfaces;
11149+ int interface;
11150+
11151+ /* Enable IPD */
11152+ cvmx_ipd_enable();
11153+
11154+ /*
11155+ * Time to enable hardware ports packet input and output. Note
11156+ * that at this point IPD/PIP must be fully functional and PKO
11157+ * must be disabled
11158+ */
11159+ num_interfaces = cvmx_helper_get_number_of_interfaces();
11160+ for (interface = 0; interface < num_interfaces; interface++) {
11161+ if (cvmx_helper_ports_on_interface(interface) > 0)
11162+ __cvmx_helper_packet_hardware_enable(interface);
11163+ }
11164+
11165+ /* Finally enable PKO now that the entire path is up and running */
11166+ cvmx_pko_enable();
11167+
11168+ if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
11169+ || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1))
11170+ && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
11171+ __cvmx_helper_errata_fix_ipd_ptr_alignment();
11172+ return 0;
11173+}
11174+
11175+/**
11176+ * Initialize the PIP, IPD, and PKO hardware to support
11177+ * simple priority based queues for the ethernet ports. Each
11178+ * port is configured with a number of priority queues based
11179+ * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
11180+ * priority than the previous.
11181+ *
11182+ * Returns Zero on success, non-zero on failure
11183+ */
11184+int cvmx_helper_initialize_packet_io_global(void)
11185+{
11186+ int result = 0;
11187+ int interface;
11188+ union cvmx_l2c_cfg l2c_cfg;
11189+ union cvmx_smix_en smix_en;
11190+ const int num_interfaces = cvmx_helper_get_number_of_interfaces();
11191+
11192+ /*
11193+ * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to
11194+ * be disabled.
11195+ */
11196+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
11197+ __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
11198+
11199+ /*
11200+ * Tell L2 to give the IOB statically higher priority compared
11201+ * to the cores. This avoids conditions where IO blocks might
11202+ * be starved under very high L2 loads.
11203+ */
11204+ l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
11205+ l2c_cfg.s.lrf_arb_mode = 0;
11206+ l2c_cfg.s.rfb_arb_mode = 0;
11207+ cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
11208+
11209+ /* Make sure SMI/MDIO is enabled so we can query PHYs */
11210+ smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
11211+ if (!smix_en.s.en) {
11212+ smix_en.s.en = 1;
11213+ cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
11214+ }
11215+
11216+ /* Newer chips actually have two SMI/MDIO interfaces */
11217+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
11218+ !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
11219+ !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
11220+ smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
11221+ if (!smix_en.s.en) {
11222+ smix_en.s.en = 1;
11223+ cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
11224+ }
11225+ }
11226+
11227+ cvmx_pko_initialize_global();
11228+ for (interface = 0; interface < num_interfaces; interface++) {
11229+ result |= cvmx_helper_interface_probe(interface);
11230+ if (cvmx_helper_ports_on_interface(interface) > 0)
11231+ cvmx_dprintf("Interface %d has %d ports (%s)\n",
11232+ interface,
11233+ cvmx_helper_ports_on_interface(interface),
11234+ cvmx_helper_interface_mode_to_string
11235+ (cvmx_helper_interface_get_mode
11236+ (interface)));
11237+ result |= __cvmx_helper_interface_setup_ipd(interface);
11238+ result |= __cvmx_helper_interface_setup_pko(interface);
11239+ }
11240+
11241+ result |= __cvmx_helper_global_setup_ipd();
11242+ result |= __cvmx_helper_global_setup_pko();
11243+
11244+ /* Enable any flow control and backpressure */
11245+ result |= __cvmx_helper_global_setup_backpressure();
11246+
11247+#if CVMX_HELPER_ENABLE_IPD
11248+ result |= cvmx_helper_ipd_and_packet_input_enable();
11249+#endif
11250+ return result;
11251+}
11252+
11253+/**
11254+ * Does core local initialization for packet io
11255+ *
11256+ * Returns Zero on success, non-zero on failure
11257+ */
11258+int cvmx_helper_initialize_packet_io_local(void)
11259+{
11260+ return cvmx_pko_initialize_local();
11261+}
11262+
11263+/**
11264+ * Auto configure an IPD/PKO port link state and speed. This
11265+ * function basically does the equivalent of:
11266+ * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
11267+ *
11268+ * @ipd_port: IPD/PKO port to auto configure
11269+ *
11270+ * Returns Link state after configure
11271+ */
11272+cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
11273+{
11274+ cvmx_helper_link_info_t link_info;
11275+ int interface = cvmx_helper_get_interface_num(ipd_port);
11276+ int index = cvmx_helper_get_interface_index_num(ipd_port);
11277+
11278+ if (index >= cvmx_helper_ports_on_interface(interface)) {
11279+ link_info.u64 = 0;
11280+ return link_info;
11281+ }
11282+
11283+ link_info = cvmx_helper_link_get(ipd_port);
11284+ if (link_info.u64 == port_link_info[ipd_port].u64)
11285+ return link_info;
11286+
11287+ /* If we fail to set the link speed, port_link_info will not change */
11288+ cvmx_helper_link_set(ipd_port, link_info);
11289+
11290+ /*
11291+ * port_link_info should be the current value, which will be
11292+ * different than expect if cvmx_helper_link_set() failed.
11293+ */
11294+ return port_link_info[ipd_port];
11295+}
11296+
11297+/**
11298+ * Return the link state of an IPD/PKO port as returned by
11299+ * auto negotiation. The result of this function may not match
11300+ * Octeon's link config if auto negotiation has changed since
11301+ * the last call to cvmx_helper_link_set().
11302+ *
11303+ * @ipd_port: IPD/PKO port to query
11304+ *
11305+ * Returns Link state
11306+ */
11307+cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
11308+{
11309+ cvmx_helper_link_info_t result;
11310+ int interface = cvmx_helper_get_interface_num(ipd_port);
11311+ int index = cvmx_helper_get_interface_index_num(ipd_port);
11312+
11313+ /* The default result will be a down link unless the code below
11314+ changes it */
11315+ result.u64 = 0;
11316+
11317+ if (index >= cvmx_helper_ports_on_interface(interface))
11318+ return result;
11319+
11320+ switch (cvmx_helper_interface_get_mode(interface)) {
11321+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11322+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
11323+ /* Network links are not supported */
11324+ break;
11325+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
11326+ result = __cvmx_helper_xaui_link_get(ipd_port);
11327+ break;
11328+ case CVMX_HELPER_INTERFACE_MODE_GMII:
11329+ if (index == 0)
11330+ result = __cvmx_helper_rgmii_link_get(ipd_port);
11331+ else {
11332+ result.s.full_duplex = 1;
11333+ result.s.link_up = 1;
11334+ result.s.speed = 1000;
11335+ }
11336+ break;
11337+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
11338+ result = __cvmx_helper_rgmii_link_get(ipd_port);
11339+ break;
11340+ case CVMX_HELPER_INTERFACE_MODE_SPI:
11341+ result = __cvmx_helper_spi_link_get(ipd_port);
11342+ break;
11343+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
11344+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
11345+ result = __cvmx_helper_sgmii_link_get(ipd_port);
11346+ break;
11347+ case CVMX_HELPER_INTERFACE_MODE_NPI:
11348+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
11349+ /* Network links are not supported */
11350+ break;
11351+ }
11352+ return result;
11353+}
11354+
11355+/**
11356+ * Configure an IPD/PKO port for the specified link state. This
11357+ * function does not influence auto negotiation at the PHY level.
11358+ * The passed link state must always match the link state returned
11359+ * by cvmx_helper_link_get(). It is normally best to use
11360+ * cvmx_helper_link_autoconf() instead.
11361+ *
11362+ * @ipd_port: IPD/PKO port to configure
11363+ * @link_info: The new link state
11364+ *
11365+ * Returns Zero on success, negative on failure
11366+ */
11367+int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
11368+{
11369+ int result = -1;
11370+ int interface = cvmx_helper_get_interface_num(ipd_port);
11371+ int index = cvmx_helper_get_interface_index_num(ipd_port);
11372+
11373+ if (index >= cvmx_helper_ports_on_interface(interface))
11374+ return -1;
11375+
11376+ switch (cvmx_helper_interface_get_mode(interface)) {
11377+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11378+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
11379+ break;
11380+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
11381+ result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
11382+ break;
11383+ /*
11384+ * RGMII/GMII/MII are all treated about the same. Most
11385+ * functions refer to these ports as RGMII.
11386+ */
11387+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
11388+ case CVMX_HELPER_INTERFACE_MODE_GMII:
11389+ result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
11390+ break;
11391+ case CVMX_HELPER_INTERFACE_MODE_SPI:
11392+ result = __cvmx_helper_spi_link_set(ipd_port, link_info);
11393+ break;
11394+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
11395+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
11396+ result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
11397+ break;
11398+ case CVMX_HELPER_INTERFACE_MODE_NPI:
11399+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
11400+ break;
11401+ }
11402+ /* Set the port_link_info here so that the link status is updated
11403+ no matter how cvmx_helper_link_set is called. We don't change
11404+ the value if link_set failed */
11405+ if (result == 0)
11406+ port_link_info[ipd_port].u64 = link_info.u64;
11407+ return result;
11408+}
11409+
11410+/**
11411+ * Configure a port for internal and/or external loopback. Internal loopback
11412+ * causes packets sent by the port to be received by Octeon. External loopback
11413+ * causes packets received from the wire to sent out again.
11414+ *
11415+ * @ipd_port: IPD/PKO port to loopback.
11416+ * @enable_internal:
11417+ * Non zero if you want internal loopback
11418+ * @enable_external:
11419+ * Non zero if you want external loopback
11420+ *
11421+ * Returns Zero on success, negative on failure.
11422+ */
11423+int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
11424+ int enable_external)
11425+{
11426+ int result = -1;
11427+ int interface = cvmx_helper_get_interface_num(ipd_port);
11428+ int index = cvmx_helper_get_interface_index_num(ipd_port);
11429+
11430+ if (index >= cvmx_helper_ports_on_interface(interface))
11431+ return -1;
11432+
11433+ switch (cvmx_helper_interface_get_mode(interface)) {
11434+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11435+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
11436+ case CVMX_HELPER_INTERFACE_MODE_SPI:
11437+ case CVMX_HELPER_INTERFACE_MODE_NPI:
11438+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
11439+ break;
11440+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
11441+ result =
11442+ __cvmx_helper_xaui_configure_loopback(ipd_port,
11443+ enable_internal,
11444+ enable_external);
11445+ break;
11446+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
11447+ case CVMX_HELPER_INTERFACE_MODE_GMII:
11448+ result =
11449+ __cvmx_helper_rgmii_configure_loopback(ipd_port,
11450+ enable_internal,
11451+ enable_external);
11452+ break;
11453+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
11454+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
11455+ result =
11456+ __cvmx_helper_sgmii_configure_loopback(ipd_port,
11457+ enable_internal,
11458+ enable_external);
11459+ break;
11460+ }
11461+ return result;
11462+}
11463--- /dev/null
11464+++ b/drivers/staging/octeon/cvmx-helper.h
11465@@ -0,0 +1,227 @@
11466+/***********************license start***************
11467+ * Author: Cavium Networks
11468+ *
11469+ * Contact: support@caviumnetworks.com
11470+ * This file is part of the OCTEON SDK
11471+ *
11472+ * Copyright (c) 2003-2008 Cavium Networks
11473+ *
11474+ * This file is free software; you can redistribute it and/or modify
11475+ * it under the terms of the GNU General Public License, Version 2, as
11476+ * published by the Free Software Foundation.
11477+ *
11478+ * This file is distributed in the hope that it will be useful, but
11479+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
11480+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
11481+ * NONINFRINGEMENT. See the GNU General Public License for more
11482+ * details.
11483+ *
11484+ * You should have received a copy of the GNU General Public License
11485+ * along with this file; if not, write to the Free Software
11486+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11487+ * or visit http://www.gnu.org/licenses/.
11488+ *
11489+ * This file may also be available under a different license from Cavium.
11490+ * Contact Cavium Networks for more information
11491+ ***********************license end**************************************/
11492+
11493+/*
11494+ *
11495+ * Helper functions for common, but complicated tasks.
11496+ *
11497+ */
11498+
11499+#ifndef __CVMX_HELPER_H__
11500+#define __CVMX_HELPER_H__
11501+
11502+#include "cvmx-config.h"
11503+#include "cvmx-fpa.h"
11504+#include "cvmx-wqe.h"
11505+
11506+typedef enum {
11507+ CVMX_HELPER_INTERFACE_MODE_DISABLED,
11508+ CVMX_HELPER_INTERFACE_MODE_RGMII,
11509+ CVMX_HELPER_INTERFACE_MODE_GMII,
11510+ CVMX_HELPER_INTERFACE_MODE_SPI,
11511+ CVMX_HELPER_INTERFACE_MODE_PCIE,
11512+ CVMX_HELPER_INTERFACE_MODE_XAUI,
11513+ CVMX_HELPER_INTERFACE_MODE_SGMII,
11514+ CVMX_HELPER_INTERFACE_MODE_PICMG,
11515+ CVMX_HELPER_INTERFACE_MODE_NPI,
11516+ CVMX_HELPER_INTERFACE_MODE_LOOP,
11517+} cvmx_helper_interface_mode_t;
11518+
11519+typedef union {
11520+ uint64_t u64;
11521+ struct {
11522+ uint64_t reserved_20_63:44;
11523+ uint64_t link_up:1; /**< Is the physical link up? */
11524+ uint64_t full_duplex:1; /**< 1 if the link is full duplex */
11525+ uint64_t speed:18; /**< Speed of the link in Mbps */
11526+ } s;
11527+} cvmx_helper_link_info_t;
11528+
11529+#include "cvmx-helper-fpa.h"
11530+
11531+#include <asm/octeon/cvmx-helper-errata.h>
11532+#include "cvmx-helper-loop.h"
11533+#include "cvmx-helper-npi.h"
11534+#include "cvmx-helper-rgmii.h"
11535+#include "cvmx-helper-sgmii.h"
11536+#include "cvmx-helper-spi.h"
11537+#include "cvmx-helper-util.h"
11538+#include "cvmx-helper-xaui.h"
11539+
11540+/**
11541+ * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
11542+ * priorities[16]) is a function pointer. It is meant to allow
11543+ * customization of the PKO queue priorities based on the port
11544+ * number. Users should set this pointer to a function before
11545+ * calling any cvmx-helper operations.
11546+ */
11547+extern void (*cvmx_override_pko_queue_priority) (int pko_port,
11548+ uint64_t priorities[16]);
11549+
11550+/**
11551+ * cvmx_override_ipd_port_setup(int ipd_port) is a function
11552+ * pointer. It is meant to allow customization of the IPD port
11553+ * setup before packet input/output comes online. It is called
11554+ * after cvmx-helper does the default IPD configuration, but
11555+ * before IPD is enabled. Users should set this pointer to a
11556+ * function before calling any cvmx-helper operations.
11557+ */
11558+extern void (*cvmx_override_ipd_port_setup) (int ipd_port);
11559+
11560+/**
11561+ * This function enables the IPD and also enables the packet interfaces.
11562+ * The packet interfaces (RGMII and SPI) must be enabled after the
11563+ * IPD. This should be called by the user program after any additional
11564+ * IPD configuration changes are made if CVMX_HELPER_ENABLE_IPD
11565+ * is not set in the executive-config.h file.
11566+ *
11567+ * Returns 0 on success
11568+ * -1 on failure
11569+ */
11570+extern int cvmx_helper_ipd_and_packet_input_enable(void);
11571+
11572+/**
11573+ * Initialize the PIP, IPD, and PKO hardware to support
11574+ * simple priority based queues for the ethernet ports. Each
11575+ * port is configured with a number of priority queues based
11576+ * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
11577+ * priority than the previous.
11578+ *
11579+ * Returns Zero on success, non-zero on failure
11580+ */
11581+extern int cvmx_helper_initialize_packet_io_global(void);
11582+
11583+/**
11584+ * Does core local initialization for packet io
11585+ *
11586+ * Returns Zero on success, non-zero on failure
11587+ */
11588+extern int cvmx_helper_initialize_packet_io_local(void);
11589+
11590+/**
11591+ * Returns the number of ports on the given interface.
11592+ * The interface must be initialized before the port count
11593+ * can be returned.
11594+ *
11595+ * @interface: Which interface to return port count for.
11596+ *
11597+ * Returns Port count for interface
11598+ * -1 for uninitialized interface
11599+ */
11600+extern int cvmx_helper_ports_on_interface(int interface);
11601+
11602+/**
11603+ * Return the number of interfaces the chip has. Each interface
11604+ * may have multiple ports. Most chips support two interfaces,
11605+ * but the CNX0XX and CNX1XX are exceptions. These only support
11606+ * one interface.
11607+ *
11608+ * Returns Number of interfaces on chip
11609+ */
11610+extern int cvmx_helper_get_number_of_interfaces(void);
11611+
11612+/**
11613+ * Get the operating mode of an interface. Depending on the Octeon
11614+ * chip and configuration, this function returns an enumeration
11615+ * of the type of packet I/O supported by an interface.
11616+ *
11617+ * @interface: Interface to probe
11618+ *
11619+ * Returns Mode of the interface. Unknown or unsupported interfaces return
11620+ * DISABLED.
11621+ */
11622+extern cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int
11623+ interface);
11624+
11625+/**
11626+ * Auto configure an IPD/PKO port link state and speed. This
11627+ * function basically does the equivalent of:
11628+ * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
11629+ *
11630+ * @ipd_port: IPD/PKO port to auto configure
11631+ *
11632+ * Returns Link state after configure
11633+ */
11634+extern cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port);
11635+
11636+/**
11637+ * Return the link state of an IPD/PKO port as returned by
11638+ * auto negotiation. The result of this function may not match
11639+ * Octeon's link config if auto negotiation has changed since
11640+ * the last call to cvmx_helper_link_set().
11641+ *
11642+ * @ipd_port: IPD/PKO port to query
11643+ *
11644+ * Returns Link state
11645+ */
11646+extern cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port);
11647+
11648+/**
11649+ * Configure an IPD/PKO port for the specified link state. This
11650+ * function does not influence auto negotiation at the PHY level.
11651+ * The passed link state must always match the link state returned
11652+ * by cvmx_helper_link_get(). It is normally best to use
11653+ * cvmx_helper_link_autoconf() instead.
11654+ *
11655+ * @ipd_port: IPD/PKO port to configure
11656+ * @link_info: The new link state
11657+ *
11658+ * Returns Zero on success, negative on failure
11659+ */
11660+extern int cvmx_helper_link_set(int ipd_port,
11661+ cvmx_helper_link_info_t link_info);
11662+
11663+/**
11664+ * This function probes an interface to determine the actual
11665+ * number of hardware ports connected to it. It doesn't setup the
11666+ * ports or enable them. The main goal here is to set the global
11667+ * interface_port_count[interface] correctly. Hardware setup of the
11668+ * ports will be performed later.
11669+ *
11670+ * @interface: Interface to probe
11671+ *
11672+ * Returns Zero on success, negative on failure
11673+ */
11674+extern int cvmx_helper_interface_probe(int interface);
11675+
11676+/**
11677+ * Configure a port for internal and/or external loopback. Internal loopback
11678+ * causes packets sent by the port to be received by Octeon. External loopback
11679+ * causes packets received from the wire to sent out again.
11680+ *
11681+ * @ipd_port: IPD/PKO port to loopback.
11682+ * @enable_internal:
11683+ * Non zero if you want internal loopback
11684+ * @enable_external:
11685+ * Non zero if you want external loopback
11686+ *
11687+ * Returns Zero on success, negative on failure.
11688+ */
11689+extern int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
11690+ int enable_external);
11691+
11692+#endif /* __CVMX_HELPER_H__ */
11693--- /dev/null
11694+++ b/drivers/staging/octeon/cvmx-interrupt-decodes.c
11695@@ -0,0 +1,371 @@
11696+/***********************license start***************
11697+ * Author: Cavium Networks
11698+ *
11699+ * Contact: support@caviumnetworks.com
11700+ * This file is part of the OCTEON SDK
11701+ *
11702+ * Copyright (c) 2003-2009 Cavium Networks
11703+ *
11704+ * This file is free software; you can redistribute it and/or modify
11705+ * it under the terms of the GNU General Public License, Version 2, as
11706+ * published by the Free Software Foundation.
11707+ *
11708+ * This file is distributed in the hope that it will be useful, but
11709+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
11710+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
11711+ * NONINFRINGEMENT. See the GNU General Public License for more
11712+ * details.
11713+ *
11714+ * You should have received a copy of the GNU General Public License
11715+ * along with this file; if not, write to the Free Software
11716+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11717+ * or visit http://www.gnu.org/licenses/.
11718+ *
11719+ * This file may also be available under a different license from Cavium.
11720+ * Contact Cavium Networks for more information
11721+ ***********************license end**************************************/
11722+
11723+/*
11724+ *
11725+ * Automatically generated functions useful for enabling
11726+ * and decoding RSL_INT_BLOCKS interrupts.
11727+ *
11728+ */
11729+
11730+#include <asm/octeon/octeon.h>
11731+
11732+#include "cvmx-gmxx-defs.h"
11733+#include "cvmx-pcsx-defs.h"
11734+#include "cvmx-pcsxx-defs.h"
11735+#include "cvmx-spxx-defs.h"
11736+#include "cvmx-stxx-defs.h"
11737+
11738+#ifndef PRINT_ERROR
11739+#define PRINT_ERROR(format, ...)
11740+#endif
11741+
11742+
11743+/**
11744+ * __cvmx_interrupt_gmxx_rxx_int_en_enable enables all interrupt bits in cvmx_gmxx_rxx_int_en_t
11745+ */
11746+void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block)
11747+{
11748+ union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
11749+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, block),
11750+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, block)));
11751+ gmx_rx_int_en.u64 = 0;
11752+ if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
11753+ /* Skipping gmx_rx_int_en.s.reserved_29_63 */
11754+ gmx_rx_int_en.s.hg2cc = 1;
11755+ gmx_rx_int_en.s.hg2fld = 1;
11756+ gmx_rx_int_en.s.undat = 1;
11757+ gmx_rx_int_en.s.uneop = 1;
11758+ gmx_rx_int_en.s.unsop = 1;
11759+ gmx_rx_int_en.s.bad_term = 1;
11760+ gmx_rx_int_en.s.bad_seq = 1;
11761+ gmx_rx_int_en.s.rem_fault = 1;
11762+ gmx_rx_int_en.s.loc_fault = 1;
11763+ gmx_rx_int_en.s.pause_drp = 1;
11764+ /* Skipping gmx_rx_int_en.s.reserved_16_18 */
11765+ /*gmx_rx_int_en.s.ifgerr = 1; */
11766+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11767+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11768+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11769+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11770+ gmx_rx_int_en.s.ovrerr = 1;
11771+ /* Skipping gmx_rx_int_en.s.reserved_9_9 */
11772+ gmx_rx_int_en.s.skperr = 1;
11773+ gmx_rx_int_en.s.rcverr = 1;
11774+ /* Skipping gmx_rx_int_en.s.reserved_5_6 */
11775+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11776+ gmx_rx_int_en.s.jabber = 1;
11777+ /* Skipping gmx_rx_int_en.s.reserved_2_2 */
11778+ gmx_rx_int_en.s.carext = 1;
11779+ /* Skipping gmx_rx_int_en.s.reserved_0_0 */
11780+ }
11781+ if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
11782+ /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11783+ /*gmx_rx_int_en.s.phy_dupx = 1; */
11784+ /*gmx_rx_int_en.s.phy_spd = 1; */
11785+ /*gmx_rx_int_en.s.phy_link = 1; */
11786+ /*gmx_rx_int_en.s.ifgerr = 1; */
11787+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11788+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11789+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11790+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11791+ gmx_rx_int_en.s.ovrerr = 1;
11792+ gmx_rx_int_en.s.niberr = 1;
11793+ gmx_rx_int_en.s.skperr = 1;
11794+ gmx_rx_int_en.s.rcverr = 1;
11795+ /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11796+ gmx_rx_int_en.s.alnerr = 1;
11797+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11798+ gmx_rx_int_en.s.jabber = 1;
11799+ gmx_rx_int_en.s.maxerr = 1;
11800+ gmx_rx_int_en.s.carext = 1;
11801+ gmx_rx_int_en.s.minerr = 1;
11802+ }
11803+ if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
11804+ /* Skipping gmx_rx_int_en.s.reserved_20_63 */
11805+ gmx_rx_int_en.s.pause_drp = 1;
11806+ /*gmx_rx_int_en.s.phy_dupx = 1; */
11807+ /*gmx_rx_int_en.s.phy_spd = 1; */
11808+ /*gmx_rx_int_en.s.phy_link = 1; */
11809+ /*gmx_rx_int_en.s.ifgerr = 1; */
11810+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11811+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11812+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11813+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11814+ gmx_rx_int_en.s.ovrerr = 1;
11815+ gmx_rx_int_en.s.niberr = 1;
11816+ gmx_rx_int_en.s.skperr = 1;
11817+ gmx_rx_int_en.s.rcverr = 1;
11818+ /* Skipping gmx_rx_int_en.s.reserved_6_6 */
11819+ gmx_rx_int_en.s.alnerr = 1;
11820+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11821+ gmx_rx_int_en.s.jabber = 1;
11822+ /* Skipping gmx_rx_int_en.s.reserved_2_2 */
11823+ gmx_rx_int_en.s.carext = 1;
11824+ /* Skipping gmx_rx_int_en.s.reserved_0_0 */
11825+ }
11826+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
11827+ /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11828+ /*gmx_rx_int_en.s.phy_dupx = 1; */
11829+ /*gmx_rx_int_en.s.phy_spd = 1; */
11830+ /*gmx_rx_int_en.s.phy_link = 1; */
11831+ /*gmx_rx_int_en.s.ifgerr = 1; */
11832+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11833+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11834+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11835+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11836+ gmx_rx_int_en.s.ovrerr = 1;
11837+ gmx_rx_int_en.s.niberr = 1;
11838+ gmx_rx_int_en.s.skperr = 1;
11839+ gmx_rx_int_en.s.rcverr = 1;
11840+ /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11841+ gmx_rx_int_en.s.alnerr = 1;
11842+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11843+ gmx_rx_int_en.s.jabber = 1;
11844+ gmx_rx_int_en.s.maxerr = 1;
11845+ gmx_rx_int_en.s.carext = 1;
11846+ gmx_rx_int_en.s.minerr = 1;
11847+ }
11848+ if (OCTEON_IS_MODEL(OCTEON_CN31XX)) {
11849+ /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11850+ /*gmx_rx_int_en.s.phy_dupx = 1; */
11851+ /*gmx_rx_int_en.s.phy_spd = 1; */
11852+ /*gmx_rx_int_en.s.phy_link = 1; */
11853+ /*gmx_rx_int_en.s.ifgerr = 1; */
11854+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11855+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11856+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11857+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11858+ gmx_rx_int_en.s.ovrerr = 1;
11859+ gmx_rx_int_en.s.niberr = 1;
11860+ gmx_rx_int_en.s.skperr = 1;
11861+ gmx_rx_int_en.s.rcverr = 1;
11862+ /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11863+ gmx_rx_int_en.s.alnerr = 1;
11864+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11865+ gmx_rx_int_en.s.jabber = 1;
11866+ gmx_rx_int_en.s.maxerr = 1;
11867+ gmx_rx_int_en.s.carext = 1;
11868+ gmx_rx_int_en.s.minerr = 1;
11869+ }
11870+ if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
11871+ /* Skipping gmx_rx_int_en.s.reserved_20_63 */
11872+ gmx_rx_int_en.s.pause_drp = 1;
11873+ /*gmx_rx_int_en.s.phy_dupx = 1; */
11874+ /*gmx_rx_int_en.s.phy_spd = 1; */
11875+ /*gmx_rx_int_en.s.phy_link = 1; */
11876+ /*gmx_rx_int_en.s.ifgerr = 1; */
11877+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11878+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11879+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11880+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11881+ gmx_rx_int_en.s.ovrerr = 1;
11882+ gmx_rx_int_en.s.niberr = 1;
11883+ gmx_rx_int_en.s.skperr = 1;
11884+ gmx_rx_int_en.s.rcverr = 1;
11885+ /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11886+ gmx_rx_int_en.s.alnerr = 1;
11887+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11888+ gmx_rx_int_en.s.jabber = 1;
11889+ gmx_rx_int_en.s.maxerr = 1;
11890+ gmx_rx_int_en.s.carext = 1;
11891+ gmx_rx_int_en.s.minerr = 1;
11892+ }
11893+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
11894+ /* Skipping gmx_rx_int_en.s.reserved_29_63 */
11895+ gmx_rx_int_en.s.hg2cc = 1;
11896+ gmx_rx_int_en.s.hg2fld = 1;
11897+ gmx_rx_int_en.s.undat = 1;
11898+ gmx_rx_int_en.s.uneop = 1;
11899+ gmx_rx_int_en.s.unsop = 1;
11900+ gmx_rx_int_en.s.bad_term = 1;
11901+ gmx_rx_int_en.s.bad_seq = 0;
11902+ gmx_rx_int_en.s.rem_fault = 1;
11903+ gmx_rx_int_en.s.loc_fault = 0;
11904+ gmx_rx_int_en.s.pause_drp = 1;
11905+ /* Skipping gmx_rx_int_en.s.reserved_16_18 */
11906+ /*gmx_rx_int_en.s.ifgerr = 1; */
11907+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11908+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11909+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11910+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11911+ gmx_rx_int_en.s.ovrerr = 1;
11912+ /* Skipping gmx_rx_int_en.s.reserved_9_9 */
11913+ gmx_rx_int_en.s.skperr = 1;
11914+ gmx_rx_int_en.s.rcverr = 1;
11915+ /* Skipping gmx_rx_int_en.s.reserved_5_6 */
11916+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11917+ gmx_rx_int_en.s.jabber = 1;
11918+ /* Skipping gmx_rx_int_en.s.reserved_2_2 */
11919+ gmx_rx_int_en.s.carext = 1;
11920+ /* Skipping gmx_rx_int_en.s.reserved_0_0 */
11921+ }
11922+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, block), gmx_rx_int_en.u64);
11923+}
11924+/**
11925+ * __cvmx_interrupt_pcsx_intx_en_reg_enable enables all interrupt bits in cvmx_pcsx_intx_en_reg_t
11926+ */
11927+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block)
11928+{
11929+ union cvmx_pcsx_intx_en_reg pcs_int_en_reg;
11930+ cvmx_write_csr(CVMX_PCSX_INTX_REG(index, block),
11931+ cvmx_read_csr(CVMX_PCSX_INTX_REG(index, block)));
11932+ pcs_int_en_reg.u64 = 0;
11933+ if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
11934+ /* Skipping pcs_int_en_reg.s.reserved_12_63 */
11935+ /*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */
11936+ pcs_int_en_reg.s.sync_bad_en = 1;
11937+ pcs_int_en_reg.s.an_bad_en = 1;
11938+ pcs_int_en_reg.s.rxlock_en = 1;
11939+ pcs_int_en_reg.s.rxbad_en = 1;
11940+ /*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */
11941+ pcs_int_en_reg.s.txbad_en = 1;
11942+ pcs_int_en_reg.s.txfifo_en = 1;
11943+ pcs_int_en_reg.s.txfifu_en = 1;
11944+ pcs_int_en_reg.s.an_err_en = 1;
11945+ /*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */
11946+ /*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */
11947+ }
11948+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
11949+ /* Skipping pcs_int_en_reg.s.reserved_12_63 */
11950+ /*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */
11951+ pcs_int_en_reg.s.sync_bad_en = 1;
11952+ pcs_int_en_reg.s.an_bad_en = 1;
11953+ pcs_int_en_reg.s.rxlock_en = 1;
11954+ pcs_int_en_reg.s.rxbad_en = 1;
11955+ /*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */
11956+ pcs_int_en_reg.s.txbad_en = 1;
11957+ pcs_int_en_reg.s.txfifo_en = 1;
11958+ pcs_int_en_reg.s.txfifu_en = 1;
11959+ pcs_int_en_reg.s.an_err_en = 1;
11960+ /*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */
11961+ /*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */
11962+ }
11963+ cvmx_write_csr(CVMX_PCSX_INTX_EN_REG(index, block), pcs_int_en_reg.u64);
11964+}
11965+/**
11966+ * __cvmx_interrupt_pcsxx_int_en_reg_enable enables all interrupt bits in cvmx_pcsxx_int_en_reg_t
11967+ */
11968+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index)
11969+{
11970+ union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
11971+ cvmx_write_csr(CVMX_PCSXX_INT_REG(index),
11972+ cvmx_read_csr(CVMX_PCSXX_INT_REG(index)));
11973+ pcsx_int_en_reg.u64 = 0;
11974+ if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
11975+ /* Skipping pcsx_int_en_reg.s.reserved_6_63 */
11976+ pcsx_int_en_reg.s.algnlos_en = 1;
11977+ pcsx_int_en_reg.s.synlos_en = 1;
11978+ pcsx_int_en_reg.s.bitlckls_en = 1;
11979+ pcsx_int_en_reg.s.rxsynbad_en = 1;
11980+ pcsx_int_en_reg.s.rxbad_en = 1;
11981+ pcsx_int_en_reg.s.txflt_en = 1;
11982+ }
11983+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
11984+ /* Skipping pcsx_int_en_reg.s.reserved_6_63 */
11985+ pcsx_int_en_reg.s.algnlos_en = 1;
11986+ pcsx_int_en_reg.s.synlos_en = 1;
11987+ pcsx_int_en_reg.s.bitlckls_en = 0; /* Happens if XAUI module is not installed */
11988+ pcsx_int_en_reg.s.rxsynbad_en = 1;
11989+ pcsx_int_en_reg.s.rxbad_en = 1;
11990+ pcsx_int_en_reg.s.txflt_en = 1;
11991+ }
11992+ cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(index), pcsx_int_en_reg.u64);
11993+}
11994+
11995+/**
11996+ * __cvmx_interrupt_spxx_int_msk_enable enables all interrupt bits in cvmx_spxx_int_msk_t
11997+ */
11998+void __cvmx_interrupt_spxx_int_msk_enable(int index)
11999+{
12000+ union cvmx_spxx_int_msk spx_int_msk;
12001+ cvmx_write_csr(CVMX_SPXX_INT_REG(index),
12002+ cvmx_read_csr(CVMX_SPXX_INT_REG(index)));
12003+ spx_int_msk.u64 = 0;
12004+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
12005+ /* Skipping spx_int_msk.s.reserved_12_63 */
12006+ spx_int_msk.s.calerr = 1;
12007+ spx_int_msk.s.syncerr = 1;
12008+ spx_int_msk.s.diperr = 1;
12009+ spx_int_msk.s.tpaovr = 1;
12010+ spx_int_msk.s.rsverr = 1;
12011+ spx_int_msk.s.drwnng = 1;
12012+ spx_int_msk.s.clserr = 1;
12013+ spx_int_msk.s.spiovr = 1;
12014+ /* Skipping spx_int_msk.s.reserved_2_3 */
12015+ spx_int_msk.s.abnorm = 1;
12016+ spx_int_msk.s.prtnxa = 1;
12017+ }
12018+ if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12019+ /* Skipping spx_int_msk.s.reserved_12_63 */
12020+ spx_int_msk.s.calerr = 1;
12021+ spx_int_msk.s.syncerr = 1;
12022+ spx_int_msk.s.diperr = 1;
12023+ spx_int_msk.s.tpaovr = 1;
12024+ spx_int_msk.s.rsverr = 1;
12025+ spx_int_msk.s.drwnng = 1;
12026+ spx_int_msk.s.clserr = 1;
12027+ spx_int_msk.s.spiovr = 1;
12028+ /* Skipping spx_int_msk.s.reserved_2_3 */
12029+ spx_int_msk.s.abnorm = 1;
12030+ spx_int_msk.s.prtnxa = 1;
12031+ }
12032+ cvmx_write_csr(CVMX_SPXX_INT_MSK(index), spx_int_msk.u64);
12033+}
12034+/**
12035+ * __cvmx_interrupt_stxx_int_msk_enable enables all interrupt bits in cvmx_stxx_int_msk_t
12036+ */
12037+void __cvmx_interrupt_stxx_int_msk_enable(int index)
12038+{
12039+ union cvmx_stxx_int_msk stx_int_msk;
12040+ cvmx_write_csr(CVMX_STXX_INT_REG(index),
12041+ cvmx_read_csr(CVMX_STXX_INT_REG(index)));
12042+ stx_int_msk.u64 = 0;
12043+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
12044+ /* Skipping stx_int_msk.s.reserved_8_63 */
12045+ stx_int_msk.s.frmerr = 1;
12046+ stx_int_msk.s.unxfrm = 1;
12047+ stx_int_msk.s.nosync = 1;
12048+ stx_int_msk.s.diperr = 1;
12049+ stx_int_msk.s.datovr = 1;
12050+ stx_int_msk.s.ovrbst = 1;
12051+ stx_int_msk.s.calpar1 = 1;
12052+ stx_int_msk.s.calpar0 = 1;
12053+ }
12054+ if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12055+ /* Skipping stx_int_msk.s.reserved_8_63 */
12056+ stx_int_msk.s.frmerr = 1;
12057+ stx_int_msk.s.unxfrm = 1;
12058+ stx_int_msk.s.nosync = 1;
12059+ stx_int_msk.s.diperr = 1;
12060+ stx_int_msk.s.datovr = 1;
12061+ stx_int_msk.s.ovrbst = 1;
12062+ stx_int_msk.s.calpar1 = 1;
12063+ stx_int_msk.s.calpar0 = 1;
12064+ }
12065+ cvmx_write_csr(CVMX_STXX_INT_MSK(index), stx_int_msk.u64);
12066+}
12067--- /dev/null
12068+++ b/drivers/staging/octeon/cvmx-interrupt-rsl.c
12069@@ -0,0 +1,140 @@
12070+/***********************license start***************
12071+ * Author: Cavium Networks
12072+ *
12073+ * Contact: support@caviumnetworks.com
12074+ * This file is part of the OCTEON SDK
12075+ *
12076+ * Copyright (c) 2003-2008 Cavium Networks
12077+ *
12078+ * This file is free software; you can redistribute it and/or modify
12079+ * it under the terms of the GNU General Public License, Version 2, as
12080+ * published by the Free Software Foundation.
12081+ *
12082+ * This file is distributed in the hope that it will be useful, but
12083+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12084+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12085+ * NONINFRINGEMENT. See the GNU General Public License for more
12086+ * details.
12087+ *
12088+ * You should have received a copy of the GNU General Public License
12089+ * along with this file; if not, write to the Free Software
12090+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12091+ * or visit http://www.gnu.org/licenses/.
12092+ *
12093+ * This file may also be available under a different license from Cavium.
12094+ * Contact Cavium Networks for more information
12095+ ***********************license end**************************************/
12096+
12097+/*
12098+ * Utility functions to decode Octeon's RSL_INT_BLOCKS
12099+ * interrupts into error messages.
12100+ */
12101+
12102+#include <asm/octeon/octeon.h>
12103+
12104+#include "cvmx-asxx-defs.h"
12105+#include "cvmx-gmxx-defs.h"
12106+
12107+#ifndef PRINT_ERROR
12108+#define PRINT_ERROR(format, ...)
12109+#endif
12110+
12111+void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block);
12112+
12113+/**
12114+ * Enable ASX error interrupts that exist on CN3XXX, CN50XX, and
12115+ * CN58XX.
12116+ *
12117+ * @block: Interface to enable 0-1
12118+ */
12119+void __cvmx_interrupt_asxx_enable(int block)
12120+{
12121+ int mask;
12122+ union cvmx_asxx_int_en csr;
12123+ /*
12124+ * CN38XX and CN58XX have two interfaces with 4 ports per
12125+ * interface. All other chips have a max of 3 ports on
12126+ * interface 0
12127+ */
12128+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
12129+ mask = 0xf; /* Set enables for 4 ports */
12130+ else
12131+ mask = 0x7; /* Set enables for 3 ports */
12132+
12133+ /* Enable interface interrupts */
12134+ csr.u64 = cvmx_read_csr(CVMX_ASXX_INT_EN(block));
12135+ csr.s.txpsh = mask;
12136+ csr.s.txpop = mask;
12137+ csr.s.ovrflw = mask;
12138+ cvmx_write_csr(CVMX_ASXX_INT_EN(block), csr.u64);
12139+}
12140+/**
12141+ * Enable GMX error reporting for the supplied interface
12142+ *
12143+ * @interface: Interface to enable
12144+ */
12145+void __cvmx_interrupt_gmxx_enable(int interface)
12146+{
12147+ union cvmx_gmxx_inf_mode mode;
12148+ union cvmx_gmxx_tx_int_en gmx_tx_int_en;
12149+ int num_ports;
12150+ int index;
12151+
12152+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
12153+
12154+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
12155+ if (mode.s.en) {
12156+ switch (mode.cn56xx.mode) {
12157+ case 1: /* XAUI */
12158+ num_ports = 1;
12159+ break;
12160+ case 2: /* SGMII */
12161+ case 3: /* PICMG */
12162+ num_ports = 4;
12163+ break;
12164+ default: /* Disabled */
12165+ num_ports = 0;
12166+ break;
12167+ }
12168+ } else
12169+ num_ports = 0;
12170+ } else {
12171+ if (mode.s.en) {
12172+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)
12173+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12174+ /*
12175+ * SPI on CN38XX and CN58XX report all
12176+ * errors through port 0. RGMII needs
12177+ * to check all 4 ports
12178+ */
12179+ if (mode.s.type)
12180+ num_ports = 1;
12181+ else
12182+ num_ports = 4;
12183+ } else {
12184+ /*
12185+ * CN30XX, CN31XX, and CN50XX have two
12186+ * or three ports. GMII and MII has 2,
12187+ * RGMII has three
12188+ */
12189+ if (mode.s.type)
12190+ num_ports = 2;
12191+ else
12192+ num_ports = 3;
12193+ }
12194+ } else
12195+ num_ports = 0;
12196+ }
12197+
12198+ gmx_tx_int_en.u64 = 0;
12199+ if (num_ports) {
12200+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)
12201+ || OCTEON_IS_MODEL(OCTEON_CN58XX))
12202+ gmx_tx_int_en.s.ncb_nxa = 1;
12203+ gmx_tx_int_en.s.pko_nxa = 1;
12204+ }
12205+ gmx_tx_int_en.s.undflw = (1 << num_ports) - 1;
12206+ cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
12207+ for (index = 0; index < num_ports; index++)
12208+ __cvmx_interrupt_gmxx_rxx_int_en_enable(index, interface);
12209+}
12210--- /dev/null
12211+++ b/drivers/staging/octeon/cvmx-ipd.h
12212@@ -0,0 +1,338 @@
12213+/***********************license start***************
12214+ * Author: Cavium Networks
12215+ *
12216+ * Contact: support@caviumnetworks.com
12217+ * This file is part of the OCTEON SDK
12218+ *
12219+ * Copyright (c) 2003-2008 Cavium Networks
12220+ *
12221+ * This file is free software; you can redistribute it and/or modify
12222+ * it under the terms of the GNU General Public License, Version 2, as
12223+ * published by the Free Software Foundation.
12224+ *
12225+ * This file is distributed in the hope that it will be useful, but
12226+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12227+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12228+ * NONINFRINGEMENT. See the GNU General Public License for more
12229+ * details.
12230+ *
12231+ * You should have received a copy of the GNU General Public License
12232+ * along with this file; if not, write to the Free Software
12233+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12234+ * or visit http://www.gnu.org/licenses/.
12235+ *
12236+ * This file may also be available under a different license from Cavium.
12237+ * Contact Cavium Networks for more information
12238+ ***********************license end**************************************/
12239+
12240+/**
12241+ *
12242+ * Interface to the hardware Input Packet Data unit.
12243+ */
12244+
12245+#ifndef __CVMX_IPD_H__
12246+#define __CVMX_IPD_H__
12247+
12248+#include <asm/octeon/octeon-feature.h>
12249+
12250+#include <asm/octeon/cvmx-ipd-defs.h>
12251+
12252+enum cvmx_ipd_mode {
12253+ CVMX_IPD_OPC_MODE_STT = 0LL, /* All blocks DRAM, not cached in L2 */
12254+ CVMX_IPD_OPC_MODE_STF = 1LL, /* All bloccks into L2 */
12255+ CVMX_IPD_OPC_MODE_STF1_STT = 2LL, /* 1st block L2, rest DRAM */
12256+ CVMX_IPD_OPC_MODE_STF2_STT = 3LL /* 1st, 2nd blocks L2, rest DRAM */
12257+};
12258+
12259+#ifndef CVMX_ENABLE_LEN_M8_FIX
12260+#define CVMX_ENABLE_LEN_M8_FIX 0
12261+#endif
12262+
12263+/* CSR typedefs have been moved to cvmx-csr-*.h */
12264+typedef union cvmx_ipd_1st_mbuff_skip cvmx_ipd_mbuff_first_skip_t;
12265+typedef union cvmx_ipd_1st_next_ptr_back cvmx_ipd_first_next_ptr_back_t;
12266+
12267+typedef cvmx_ipd_mbuff_first_skip_t cvmx_ipd_mbuff_not_first_skip_t;
12268+typedef cvmx_ipd_first_next_ptr_back_t cvmx_ipd_second_next_ptr_back_t;
12269+
12270+/**
12271+ * Configure IPD
12272+ *
12273+ * @mbuff_size: Packets buffer size in 8 byte words
12274+ * @first_mbuff_skip:
12275+ * Number of 8 byte words to skip in the first buffer
12276+ * @not_first_mbuff_skip:
12277+ * Number of 8 byte words to skip in each following buffer
12278+ * @first_back: Must be same as first_mbuff_skip / 128
12279+ * @second_back:
12280+ * Must be same as not_first_mbuff_skip / 128
12281+ * @wqe_fpa_pool:
12282+ * FPA pool to get work entries from
12283+ * @cache_mode:
12284+ * @back_pres_enable_flag:
12285+ * Enable or disable port back pressure
12286+ */
12287+static inline void cvmx_ipd_config(uint64_t mbuff_size,
12288+ uint64_t first_mbuff_skip,
12289+ uint64_t not_first_mbuff_skip,
12290+ uint64_t first_back,
12291+ uint64_t second_back,
12292+ uint64_t wqe_fpa_pool,
12293+ enum cvmx_ipd_mode cache_mode,
12294+ uint64_t back_pres_enable_flag)
12295+{
12296+ cvmx_ipd_mbuff_first_skip_t first_skip;
12297+ cvmx_ipd_mbuff_not_first_skip_t not_first_skip;
12298+ union cvmx_ipd_packet_mbuff_size size;
12299+ cvmx_ipd_first_next_ptr_back_t first_back_struct;
12300+ cvmx_ipd_second_next_ptr_back_t second_back_struct;
12301+ union cvmx_ipd_wqe_fpa_queue wqe_pool;
12302+ union cvmx_ipd_ctl_status ipd_ctl_reg;
12303+
12304+ first_skip.u64 = 0;
12305+ first_skip.s.skip_sz = first_mbuff_skip;
12306+ cvmx_write_csr(CVMX_IPD_1ST_MBUFF_SKIP, first_skip.u64);
12307+
12308+ not_first_skip.u64 = 0;
12309+ not_first_skip.s.skip_sz = not_first_mbuff_skip;
12310+ cvmx_write_csr(CVMX_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.u64);
12311+
12312+ size.u64 = 0;
12313+ size.s.mb_size = mbuff_size;
12314+ cvmx_write_csr(CVMX_IPD_PACKET_MBUFF_SIZE, size.u64);
12315+
12316+ first_back_struct.u64 = 0;
12317+ first_back_struct.s.back = first_back;
12318+ cvmx_write_csr(CVMX_IPD_1st_NEXT_PTR_BACK, first_back_struct.u64);
12319+
12320+ second_back_struct.u64 = 0;
12321+ second_back_struct.s.back = second_back;
12322+ cvmx_write_csr(CVMX_IPD_2nd_NEXT_PTR_BACK, second_back_struct.u64);
12323+
12324+ wqe_pool.u64 = 0;
12325+ wqe_pool.s.wqe_pool = wqe_fpa_pool;
12326+ cvmx_write_csr(CVMX_IPD_WQE_FPA_QUEUE, wqe_pool.u64);
12327+
12328+ ipd_ctl_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12329+ ipd_ctl_reg.s.opc_mode = cache_mode;
12330+ ipd_ctl_reg.s.pbp_en = back_pres_enable_flag;
12331+ cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_reg.u64);
12332+
12333+ /* Note: the example RED code that used to be here has been moved to
12334+ cvmx_helper_setup_red */
12335+}
12336+
12337+/**
12338+ * Enable IPD
12339+ */
12340+static inline void cvmx_ipd_enable(void)
12341+{
12342+ union cvmx_ipd_ctl_status ipd_reg;
12343+ ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12344+ if (ipd_reg.s.ipd_en) {
12345+ cvmx_dprintf
12346+ ("Warning: Enabling IPD when IPD already enabled.\n");
12347+ }
12348+ ipd_reg.s.ipd_en = 1;
12349+#if CVMX_ENABLE_LEN_M8_FIX
12350+ if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
12351+ ipd_reg.s.len_m8 = TRUE;
12352+#endif
12353+ cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
12354+}
12355+
12356+/**
12357+ * Disable IPD
12358+ */
12359+static inline void cvmx_ipd_disable(void)
12360+{
12361+ union cvmx_ipd_ctl_status ipd_reg;
12362+ ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12363+ ipd_reg.s.ipd_en = 0;
12364+ cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
12365+}
12366+
12367+/**
12368+ * Supportive function for cvmx_fpa_shutdown_pool.
12369+ */
12370+static inline void cvmx_ipd_free_ptr(void)
12371+{
12372+ /* Only CN38XXp{1,2} cannot read pointer out of the IPD */
12373+ if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)
12374+ && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
12375+ int no_wptr = 0;
12376+ union cvmx_ipd_ptr_count ipd_ptr_count;
12377+ ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
12378+
12379+ /* Handle Work Queue Entry in cn56xx and cn52xx */
12380+ if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
12381+ union cvmx_ipd_ctl_status ipd_ctl_status;
12382+ ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12383+ if (ipd_ctl_status.s.no_wptr)
12384+ no_wptr = 1;
12385+ }
12386+
12387+ /* Free the prefetched WQE */
12388+ if (ipd_ptr_count.s.wqev_cnt) {
12389+ union cvmx_ipd_wqe_ptr_valid ipd_wqe_ptr_valid;
12390+ ipd_wqe_ptr_valid.u64 =
12391+ cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID);
12392+ if (no_wptr)
12393+ cvmx_fpa_free(cvmx_phys_to_ptr
12394+ ((uint64_t) ipd_wqe_ptr_valid.s.
12395+ ptr << 7), CVMX_FPA_PACKET_POOL,
12396+ 0);
12397+ else
12398+ cvmx_fpa_free(cvmx_phys_to_ptr
12399+ ((uint64_t) ipd_wqe_ptr_valid.s.
12400+ ptr << 7), CVMX_FPA_WQE_POOL, 0);
12401+ }
12402+
12403+ /* Free all WQE in the fifo */
12404+ if (ipd_ptr_count.s.wqe_pcnt) {
12405+ int i;
12406+ union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
12407+ ipd_pwp_ptr_fifo_ctl.u64 =
12408+ cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12409+ for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
12410+ ipd_pwp_ptr_fifo_ctl.s.cena = 0;
12411+ ipd_pwp_ptr_fifo_ctl.s.raddr =
12412+ ipd_pwp_ptr_fifo_ctl.s.max_cnts +
12413+ (ipd_pwp_ptr_fifo_ctl.s.wraddr +
12414+ i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
12415+ cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12416+ ipd_pwp_ptr_fifo_ctl.u64);
12417+ ipd_pwp_ptr_fifo_ctl.u64 =
12418+ cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12419+ if (no_wptr)
12420+ cvmx_fpa_free(cvmx_phys_to_ptr
12421+ ((uint64_t)
12422+ ipd_pwp_ptr_fifo_ctl.s.
12423+ ptr << 7),
12424+ CVMX_FPA_PACKET_POOL, 0);
12425+ else
12426+ cvmx_fpa_free(cvmx_phys_to_ptr
12427+ ((uint64_t)
12428+ ipd_pwp_ptr_fifo_ctl.s.
12429+ ptr << 7),
12430+ CVMX_FPA_WQE_POOL, 0);
12431+ }
12432+ ipd_pwp_ptr_fifo_ctl.s.cena = 1;
12433+ cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12434+ ipd_pwp_ptr_fifo_ctl.u64);
12435+ }
12436+
12437+ /* Free the prefetched packet */
12438+ if (ipd_ptr_count.s.pktv_cnt) {
12439+ union cvmx_ipd_pkt_ptr_valid ipd_pkt_ptr_valid;
12440+ ipd_pkt_ptr_valid.u64 =
12441+ cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID);
12442+ cvmx_fpa_free(cvmx_phys_to_ptr
12443+ (ipd_pkt_ptr_valid.s.ptr << 7),
12444+ CVMX_FPA_PACKET_POOL, 0);
12445+ }
12446+
12447+ /* Free the per port prefetched packets */
12448+ if (1) {
12449+ int i;
12450+ union cvmx_ipd_prc_port_ptr_fifo_ctl
12451+ ipd_prc_port_ptr_fifo_ctl;
12452+ ipd_prc_port_ptr_fifo_ctl.u64 =
12453+ cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
12454+
12455+ for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
12456+ i++) {
12457+ ipd_prc_port_ptr_fifo_ctl.s.cena = 0;
12458+ ipd_prc_port_ptr_fifo_ctl.s.raddr =
12459+ i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
12460+ cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
12461+ ipd_prc_port_ptr_fifo_ctl.u64);
12462+ ipd_prc_port_ptr_fifo_ctl.u64 =
12463+ cvmx_read_csr
12464+ (CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
12465+ cvmx_fpa_free(cvmx_phys_to_ptr
12466+ ((uint64_t)
12467+ ipd_prc_port_ptr_fifo_ctl.s.
12468+ ptr << 7), CVMX_FPA_PACKET_POOL,
12469+ 0);
12470+ }
12471+ ipd_prc_port_ptr_fifo_ctl.s.cena = 1;
12472+ cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
12473+ ipd_prc_port_ptr_fifo_ctl.u64);
12474+ }
12475+
12476+ /* Free all packets in the holding fifo */
12477+ if (ipd_ptr_count.s.pfif_cnt) {
12478+ int i;
12479+ union cvmx_ipd_prc_hold_ptr_fifo_ctl
12480+ ipd_prc_hold_ptr_fifo_ctl;
12481+
12482+ ipd_prc_hold_ptr_fifo_ctl.u64 =
12483+ cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
12484+
12485+ for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
12486+ ipd_prc_hold_ptr_fifo_ctl.s.cena = 0;
12487+ ipd_prc_hold_ptr_fifo_ctl.s.raddr =
12488+ (ipd_prc_hold_ptr_fifo_ctl.s.praddr +
12489+ i) % ipd_prc_hold_ptr_fifo_ctl.s.max_pkt;
12490+ cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
12491+ ipd_prc_hold_ptr_fifo_ctl.u64);
12492+ ipd_prc_hold_ptr_fifo_ctl.u64 =
12493+ cvmx_read_csr
12494+ (CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
12495+ cvmx_fpa_free(cvmx_phys_to_ptr
12496+ ((uint64_t)
12497+ ipd_prc_hold_ptr_fifo_ctl.s.
12498+ ptr << 7), CVMX_FPA_PACKET_POOL,
12499+ 0);
12500+ }
12501+ ipd_prc_hold_ptr_fifo_ctl.s.cena = 1;
12502+ cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
12503+ ipd_prc_hold_ptr_fifo_ctl.u64);
12504+ }
12505+
12506+ /* Free all packets in the fifo */
12507+ if (ipd_ptr_count.s.pkt_pcnt) {
12508+ int i;
12509+ union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
12510+ ipd_pwp_ptr_fifo_ctl.u64 =
12511+ cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12512+
12513+ for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
12514+ ipd_pwp_ptr_fifo_ctl.s.cena = 0;
12515+ ipd_pwp_ptr_fifo_ctl.s.raddr =
12516+ (ipd_pwp_ptr_fifo_ctl.s.praddr +
12517+ i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
12518+ cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12519+ ipd_pwp_ptr_fifo_ctl.u64);
12520+ ipd_pwp_ptr_fifo_ctl.u64 =
12521+ cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12522+ cvmx_fpa_free(cvmx_phys_to_ptr
12523+ ((uint64_t) ipd_pwp_ptr_fifo_ctl.
12524+ s.ptr << 7),
12525+ CVMX_FPA_PACKET_POOL, 0);
12526+ }
12527+ ipd_pwp_ptr_fifo_ctl.s.cena = 1;
12528+ cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12529+ ipd_pwp_ptr_fifo_ctl.u64);
12530+ }
12531+
12532+ /* Reset the IPD to get all buffers out of it */
12533+ {
12534+ union cvmx_ipd_ctl_status ipd_ctl_status;
12535+ ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12536+ ipd_ctl_status.s.reset = 1;
12537+ cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);
12538+ }
12539+
12540+ /* Reset the PIP */
12541+ {
12542+ union cvmx_pip_sft_rst pip_sft_rst;
12543+ pip_sft_rst.u64 = cvmx_read_csr(CVMX_PIP_SFT_RST);
12544+ pip_sft_rst.s.rst = 1;
12545+ cvmx_write_csr(CVMX_PIP_SFT_RST, pip_sft_rst.u64);
12546+ }
12547+ }
12548+}
12549+
12550+#endif /* __CVMX_IPD_H__ */
12551--- /dev/null
12552+++ b/drivers/staging/octeon/cvmx-mdio.h
12553@@ -0,0 +1,506 @@
12554+/***********************license start***************
12555+ * Author: Cavium Networks
12556+ *
12557+ * Contact: support@caviumnetworks.com
12558+ * This file is part of the OCTEON SDK
12559+ *
12560+ * Copyright (c) 2003-2008 Cavium Networks
12561+ *
12562+ * This file is free software; you can redistribute it and/or modify
12563+ * it under the terms of the GNU General Public License, Version 2, as
12564+ * published by the Free Software Foundation.
12565+ *
12566+ * This file is distributed in the hope that it will be useful, but
12567+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12568+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12569+ * NONINFRINGEMENT. See the GNU General Public License for more
12570+ * details.
12571+ *
12572+ * You should have received a copy of the GNU General Public License
12573+ * along with this file; if not, write to the Free Software
12574+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12575+ * or visit http://www.gnu.org/licenses/.
12576+ *
12577+ * This file may also be available under a different license from Cavium.
12578+ * Contact Cavium Networks for more information
12579+ ***********************license end**************************************/
12580+
12581+/*
12582+ *
12583+ * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3
12584+ * clause 22 and clause 45 operations.
12585+ *
12586+ */
12587+
12588+#ifndef __CVMX_MIO_H__
12589+#define __CVMX_MIO_H__
12590+
12591+#include "cvmx-smix-defs.h"
12592+
12593+/**
12594+ * PHY register 0 from the 802.3 spec
12595+ */
12596+#define CVMX_MDIO_PHY_REG_CONTROL 0
12597+typedef union {
12598+ uint16_t u16;
12599+ struct {
12600+ uint16_t reset:1;
12601+ uint16_t loopback:1;
12602+ uint16_t speed_lsb:1;
12603+ uint16_t autoneg_enable:1;
12604+ uint16_t power_down:1;
12605+ uint16_t isolate:1;
12606+ uint16_t restart_autoneg:1;
12607+ uint16_t duplex:1;
12608+ uint16_t collision_test:1;
12609+ uint16_t speed_msb:1;
12610+ uint16_t unidirectional_enable:1;
12611+ uint16_t reserved_0_4:5;
12612+ } s;
12613+} cvmx_mdio_phy_reg_control_t;
12614+
12615+/**
12616+ * PHY register 1 from the 802.3 spec
12617+ */
12618+#define CVMX_MDIO_PHY_REG_STATUS 1
12619+typedef union {
12620+ uint16_t u16;
12621+ struct {
12622+ uint16_t capable_100base_t4:1;
12623+ uint16_t capable_100base_x_full:1;
12624+ uint16_t capable_100base_x_half:1;
12625+ uint16_t capable_10_full:1;
12626+ uint16_t capable_10_half:1;
12627+ uint16_t capable_100base_t2_full:1;
12628+ uint16_t capable_100base_t2_half:1;
12629+ uint16_t capable_extended_status:1;
12630+ uint16_t capable_unidirectional:1;
12631+ uint16_t capable_mf_preamble_suppression:1;
12632+ uint16_t autoneg_complete:1;
12633+ uint16_t remote_fault:1;
12634+ uint16_t capable_autoneg:1;
12635+ uint16_t link_status:1;
12636+ uint16_t jabber_detect:1;
12637+ uint16_t capable_extended_registers:1;
12638+
12639+ } s;
12640+} cvmx_mdio_phy_reg_status_t;
12641+
12642+/**
12643+ * PHY register 2 from the 802.3 spec
12644+ */
12645+#define CVMX_MDIO_PHY_REG_ID1 2
12646+typedef union {
12647+ uint16_t u16;
12648+ struct {
12649+ uint16_t oui_bits_3_18;
12650+ } s;
12651+} cvmx_mdio_phy_reg_id1_t;
12652+
12653+/**
12654+ * PHY register 3 from the 802.3 spec
12655+ */
12656+#define CVMX_MDIO_PHY_REG_ID2 3
12657+typedef union {
12658+ uint16_t u16;
12659+ struct {
12660+ uint16_t oui_bits_19_24:6;
12661+ uint16_t model:6;
12662+ uint16_t revision:4;
12663+ } s;
12664+} cvmx_mdio_phy_reg_id2_t;
12665+
12666+/**
12667+ * PHY register 4 from the 802.3 spec
12668+ */
12669+#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4
12670+typedef union {
12671+ uint16_t u16;
12672+ struct {
12673+ uint16_t next_page:1;
12674+ uint16_t reserved_14:1;
12675+ uint16_t remote_fault:1;
12676+ uint16_t reserved_12:1;
12677+ uint16_t asymmetric_pause:1;
12678+ uint16_t pause:1;
12679+ uint16_t advert_100base_t4:1;
12680+ uint16_t advert_100base_tx_full:1;
12681+ uint16_t advert_100base_tx_half:1;
12682+ uint16_t advert_10base_tx_full:1;
12683+ uint16_t advert_10base_tx_half:1;
12684+ uint16_t selector:5;
12685+ } s;
12686+} cvmx_mdio_phy_reg_autoneg_adver_t;
12687+
12688+/**
12689+ * PHY register 5 from the 802.3 spec
12690+ */
12691+#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5
12692+typedef union {
12693+ uint16_t u16;
12694+ struct {
12695+ uint16_t next_page:1;
12696+ uint16_t ack:1;
12697+ uint16_t remote_fault:1;
12698+ uint16_t reserved_12:1;
12699+ uint16_t asymmetric_pause:1;
12700+ uint16_t pause:1;
12701+ uint16_t advert_100base_t4:1;
12702+ uint16_t advert_100base_tx_full:1;
12703+ uint16_t advert_100base_tx_half:1;
12704+ uint16_t advert_10base_tx_full:1;
12705+ uint16_t advert_10base_tx_half:1;
12706+ uint16_t selector:5;
12707+ } s;
12708+} cvmx_mdio_phy_reg_link_partner_ability_t;
12709+
12710+/**
12711+ * PHY register 6 from the 802.3 spec
12712+ */
12713+#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6
12714+typedef union {
12715+ uint16_t u16;
12716+ struct {
12717+ uint16_t reserved_5_15:11;
12718+ uint16_t parallel_detection_fault:1;
12719+ uint16_t link_partner_next_page_capable:1;
12720+ uint16_t local_next_page_capable:1;
12721+ uint16_t page_received:1;
12722+ uint16_t link_partner_autoneg_capable:1;
12723+
12724+ } s;
12725+} cvmx_mdio_phy_reg_autoneg_expansion_t;
12726+
12727+/**
12728+ * PHY register 9 from the 802.3 spec
12729+ */
12730+#define CVMX_MDIO_PHY_REG_CONTROL_1000 9
12731+typedef union {
12732+ uint16_t u16;
12733+ struct {
12734+ uint16_t test_mode:3;
12735+ uint16_t manual_master_slave:1;
12736+ uint16_t master:1;
12737+ uint16_t port_type:1;
12738+ uint16_t advert_1000base_t_full:1;
12739+ uint16_t advert_1000base_t_half:1;
12740+ uint16_t reserved_0_7:8;
12741+ } s;
12742+} cvmx_mdio_phy_reg_control_1000_t;
12743+
12744+/**
12745+ * PHY register 10 from the 802.3 spec
12746+ */
12747+#define CVMX_MDIO_PHY_REG_STATUS_1000 10
12748+typedef union {
12749+ uint16_t u16;
12750+ struct {
12751+ uint16_t master_slave_fault:1;
12752+ uint16_t is_master:1;
12753+ uint16_t local_receiver_ok:1;
12754+ uint16_t remote_receiver_ok:1;
12755+ uint16_t remote_capable_1000base_t_full:1;
12756+ uint16_t remote_capable_1000base_t_half:1;
12757+ uint16_t reserved_8_9:2;
12758+ uint16_t idle_error_count:8;
12759+ } s;
12760+} cvmx_mdio_phy_reg_status_1000_t;
12761+
12762+/**
12763+ * PHY register 15 from the 802.3 spec
12764+ */
12765+#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15
12766+typedef union {
12767+ uint16_t u16;
12768+ struct {
12769+ uint16_t capable_1000base_x_full:1;
12770+ uint16_t capable_1000base_x_half:1;
12771+ uint16_t capable_1000base_t_full:1;
12772+ uint16_t capable_1000base_t_half:1;
12773+ uint16_t reserved_0_11:12;
12774+ } s;
12775+} cvmx_mdio_phy_reg_extended_status_t;
12776+
12777+/**
12778+ * PHY register 13 from the 802.3 spec
12779+ */
12780+#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13
12781+typedef union {
12782+ uint16_t u16;
12783+ struct {
12784+ uint16_t function:2;
12785+ uint16_t reserved_5_13:9;
12786+ uint16_t devad:5;
12787+ } s;
12788+} cvmx_mdio_phy_reg_mmd_control_t;
12789+
12790+/**
12791+ * PHY register 14 from the 802.3 spec
12792+ */
12793+#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14
12794+typedef union {
12795+ uint16_t u16;
12796+ struct {
12797+ uint16_t address_data:16;
12798+ } s;
12799+} cvmx_mdio_phy_reg_mmd_address_data_t;
12800+
12801+/* Operating request encodings. */
12802+#define MDIO_CLAUSE_22_WRITE 0
12803+#define MDIO_CLAUSE_22_READ 1
12804+
12805+#define MDIO_CLAUSE_45_ADDRESS 0
12806+#define MDIO_CLAUSE_45_WRITE 1
12807+#define MDIO_CLAUSE_45_READ_INC 2
12808+#define MDIO_CLAUSE_45_READ 3
12809+
12810+/* MMD identifiers, mostly for accessing devices withing XENPAK modules. */
12811+#define CVMX_MMD_DEVICE_PMA_PMD 1
12812+#define CVMX_MMD_DEVICE_WIS 2
12813+#define CVMX_MMD_DEVICE_PCS 3
12814+#define CVMX_MMD_DEVICE_PHY_XS 4
12815+#define CVMX_MMD_DEVICE_DTS_XS 5
12816+#define CVMX_MMD_DEVICE_TC 6
12817+#define CVMX_MMD_DEVICE_CL22_EXT 29
12818+#define CVMX_MMD_DEVICE_VENDOR_1 30
12819+#define CVMX_MMD_DEVICE_VENDOR_2 31
12820+
12821+/* Helper function to put MDIO interface into clause 45 mode */
12822+static inline void __cvmx_mdio_set_clause45_mode(int bus_id)
12823+{
12824+ union cvmx_smix_clk smi_clk;
12825+ /* Put bus into clause 45 mode */
12826+ smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
12827+ smi_clk.s.mode = 1;
12828+ smi_clk.s.preamble = 1;
12829+ cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
12830+}
12831+
12832+/* Helper function to put MDIO interface into clause 22 mode */
12833+static inline void __cvmx_mdio_set_clause22_mode(int bus_id)
12834+{
12835+ union cvmx_smix_clk smi_clk;
12836+ /* Put bus into clause 22 mode */
12837+ smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
12838+ smi_clk.s.mode = 0;
12839+ cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
12840+}
12841+
12842+/**
12843+ * Perform an MII read. This function is used to read PHY
12844+ * registers controlling auto negotiation.
12845+ *
12846+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
12847+ * support multiple busses.
12848+ * @phy_id: The MII phy id
12849+ * @location: Register location to read
12850+ *
12851+ * Returns Result from the read or -1 on failure
12852+ */
12853+static inline int cvmx_mdio_read(int bus_id, int phy_id, int location)
12854+{
12855+ union cvmx_smix_cmd smi_cmd;
12856+ union cvmx_smix_rd_dat smi_rd;
12857+ int timeout = 1000;
12858+
12859+ if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12860+ __cvmx_mdio_set_clause22_mode(bus_id);
12861+
12862+ smi_cmd.u64 = 0;
12863+ smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ;
12864+ smi_cmd.s.phy_adr = phy_id;
12865+ smi_cmd.s.reg_adr = location;
12866+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12867+
12868+ do {
12869+ cvmx_wait(1000);
12870+ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
12871+ } while (smi_rd.s.pending && timeout--);
12872+
12873+ if (smi_rd.s.val)
12874+ return smi_rd.s.dat;
12875+ else
12876+ return -1;
12877+}
12878+
12879+/**
12880+ * Perform an MII write. This function is used to write PHY
12881+ * registers controlling auto negotiation.
12882+ *
12883+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
12884+ * support multiple busses.
12885+ * @phy_id: The MII phy id
12886+ * @location: Register location to write
12887+ * @val: Value to write
12888+ *
12889+ * Returns -1 on error
12890+ * 0 on success
12891+ */
12892+static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val)
12893+{
12894+ union cvmx_smix_cmd smi_cmd;
12895+ union cvmx_smix_wr_dat smi_wr;
12896+ int timeout = 1000;
12897+
12898+ if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12899+ __cvmx_mdio_set_clause22_mode(bus_id);
12900+
12901+ smi_wr.u64 = 0;
12902+ smi_wr.s.dat = val;
12903+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
12904+
12905+ smi_cmd.u64 = 0;
12906+ smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE;
12907+ smi_cmd.s.phy_adr = phy_id;
12908+ smi_cmd.s.reg_adr = location;
12909+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12910+
12911+ do {
12912+ cvmx_wait(1000);
12913+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
12914+ } while (smi_wr.s.pending && --timeout);
12915+ if (timeout <= 0)
12916+ return -1;
12917+
12918+ return 0;
12919+}
12920+
12921+/**
12922+ * Perform an IEEE 802.3 clause 45 MII read. This function is used to
12923+ * read PHY registers controlling auto negotiation.
12924+ *
12925+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
12926+ * support multiple busses.
12927+ * @phy_id: The MII phy id
12928+ * @device: MDIO Managable Device (MMD) id
12929+ * @location: Register location to read
12930+ *
12931+ * Returns Result from the read or -1 on failure
12932+ */
12933+
12934+static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
12935+ int location)
12936+{
12937+ union cvmx_smix_cmd smi_cmd;
12938+ union cvmx_smix_rd_dat smi_rd;
12939+ union cvmx_smix_wr_dat smi_wr;
12940+ int timeout = 1000;
12941+
12942+ if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12943+ return -1;
12944+
12945+ __cvmx_mdio_set_clause45_mode(bus_id);
12946+
12947+ smi_wr.u64 = 0;
12948+ smi_wr.s.dat = location;
12949+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
12950+
12951+ smi_cmd.u64 = 0;
12952+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
12953+ smi_cmd.s.phy_adr = phy_id;
12954+ smi_cmd.s.reg_adr = device;
12955+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12956+
12957+ do {
12958+ cvmx_wait(1000);
12959+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
12960+ } while (smi_wr.s.pending && --timeout);
12961+ if (timeout <= 0) {
12962+ cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
12963+ "device %2d register %2d TIME OUT(address)\n",
12964+ bus_id, phy_id, device, location);
12965+ return -1;
12966+ }
12967+
12968+ smi_cmd.u64 = 0;
12969+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ;
12970+ smi_cmd.s.phy_adr = phy_id;
12971+ smi_cmd.s.reg_adr = device;
12972+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12973+
12974+ do {
12975+ cvmx_wait(1000);
12976+ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
12977+ } while (smi_rd.s.pending && timeout--);
12978+
12979+ if (timeout <= 0) {
12980+ cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
12981+ "device %2d register %2d TIME OUT(data)\n",
12982+ bus_id, phy_id, device, location);
12983+ return -1;
12984+ }
12985+
12986+ if (smi_rd.s.val)
12987+ return smi_rd.s.dat;
12988+ else {
12989+ cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
12990+ "device %2d register %2d INVALID READ\n",
12991+ bus_id, phy_id, device, location);
12992+ return -1;
12993+ }
12994+}
12995+
12996+/**
12997+ * Perform an IEEE 802.3 clause 45 MII write. This function is used to
12998+ * write PHY registers controlling auto negotiation.
12999+ *
13000+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
13001+ * support multiple busses.
13002+ * @phy_id: The MII phy id
13003+ * @device: MDIO Managable Device (MMD) id
13004+ * @location: Register location to write
13005+ * @val: Value to write
13006+ *
13007+ * Returns -1 on error
13008+ * 0 on success
13009+ */
13010+static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device,
13011+ int location, int val)
13012+{
13013+ union cvmx_smix_cmd smi_cmd;
13014+ union cvmx_smix_wr_dat smi_wr;
13015+ int timeout = 1000;
13016+
13017+ if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
13018+ return -1;
13019+
13020+ __cvmx_mdio_set_clause45_mode(bus_id);
13021+
13022+ smi_wr.u64 = 0;
13023+ smi_wr.s.dat = location;
13024+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
13025+
13026+ smi_cmd.u64 = 0;
13027+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
13028+ smi_cmd.s.phy_adr = phy_id;
13029+ smi_cmd.s.reg_adr = device;
13030+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13031+
13032+ do {
13033+ cvmx_wait(1000);
13034+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13035+ } while (smi_wr.s.pending && --timeout);
13036+ if (timeout <= 0)
13037+ return -1;
13038+
13039+ smi_wr.u64 = 0;
13040+ smi_wr.s.dat = val;
13041+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
13042+
13043+ smi_cmd.u64 = 0;
13044+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE;
13045+ smi_cmd.s.phy_adr = phy_id;
13046+ smi_cmd.s.reg_adr = device;
13047+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13048+
13049+ do {
13050+ cvmx_wait(1000);
13051+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13052+ } while (smi_wr.s.pending && --timeout);
13053+ if (timeout <= 0)
13054+ return -1;
13055+
13056+ return 0;
13057+}
13058+
13059+#endif
13060--- /dev/null
13061+++ b/drivers/staging/octeon/cvmx-packet.h
13062@@ -0,0 +1,65 @@
13063+/***********************license start***************
13064+ * Author: Cavium Networks
13065+ *
13066+ * Contact: support@caviumnetworks.com
13067+ * This file is part of the OCTEON SDK
13068+ *
13069+ * Copyright (c) 2003-2008 Cavium Networks
13070+ *
13071+ * This file is free software; you can redistribute it and/or modify
13072+ * it under the terms of the GNU General Public License, Version 2, as
13073+ * published by the Free Software Foundation.
13074+ *
13075+ * This file is distributed in the hope that it will be useful, but
13076+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13077+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13078+ * NONINFRINGEMENT. See the GNU General Public License for more
13079+ * details.
13080+ *
13081+ * You should have received a copy of the GNU General Public License
13082+ * along with this file; if not, write to the Free Software
13083+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13084+ * or visit http://www.gnu.org/licenses/.
13085+ *
13086+ * This file may also be available under a different license from Cavium.
13087+ * Contact Cavium Networks for more information
13088+ ***********************license end**************************************/
13089+
13090+/**
13091+ *
13092+ * Packet buffer defines.
13093+ */
13094+
13095+#ifndef __CVMX_PACKET_H__
13096+#define __CVMX_PACKET_H__
13097+
13098+/**
13099+ * This structure defines a buffer pointer on Octeon
13100+ */
13101+union cvmx_buf_ptr {
13102+ void *ptr;
13103+ uint64_t u64;
13104+ struct {
13105+ /*
13106+ * if set, invert the "free" pick of the overall
13107+ * packet. HW always sets this bit to 0 on inbound
13108+ * packet
13109+ */
13110+ uint64_t i:1;
13111+ /*
13112+ * Indicates the amount to back up to get to the
13113+ * buffer start in cache lines. In most cases this is
13114+ * less than one complete cache line, so the value is
13115+ * zero.
13116+ */
13117+ uint64_t back:4;
13118+ /* The pool that the buffer came from / goes to */
13119+ uint64_t pool:3;
13120+ /* The size of the segment pointed to by addr (in bytes) */
13121+ uint64_t size:16;
13122+ /* Pointer to the first byte of the data, NOT buffer */
13123+ uint64_t addr:40;
13124+ } s;
13125+};
13126+
13127+#endif /* __CVMX_PACKET_H__ */
13128--- /dev/null
13129+++ b/drivers/staging/octeon/cvmx-pcsx-defs.h
13130@@ -0,0 +1,370 @@
13131+/***********************license start***************
13132+ * Author: Cavium Networks
13133+ *
13134+ * Contact: support@caviumnetworks.com
13135+ * This file is part of the OCTEON SDK
13136+ *
13137+ * Copyright (c) 2003-2008 Cavium Networks
13138+ *
13139+ * This file is free software; you can redistribute it and/or modify
13140+ * it under the terms of the GNU General Public License, Version 2, as
13141+ * published by the Free Software Foundation.
13142+ *
13143+ * This file is distributed in the hope that it will be useful, but
13144+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13145+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13146+ * NONINFRINGEMENT. See the GNU General Public License for more
13147+ * details.
13148+ *
13149+ * You should have received a copy of the GNU General Public License
13150+ * along with this file; if not, write to the Free Software
13151+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13152+ * or visit http://www.gnu.org/licenses/.
13153+ *
13154+ * This file may also be available under a different license from Cavium.
13155+ * Contact Cavium Networks for more information
13156+ ***********************license end**************************************/
13157+
13158+#ifndef __CVMX_PCSX_DEFS_H__
13159+#define __CVMX_PCSX_DEFS_H__
13160+
13161+#define CVMX_PCSX_ANX_ADV_REG(offset, block_id) \
13162+ CVMX_ADD_IO_SEG(0x00011800B0001010ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13163+#define CVMX_PCSX_ANX_EXT_ST_REG(offset, block_id) \
13164+ CVMX_ADD_IO_SEG(0x00011800B0001028ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13165+#define CVMX_PCSX_ANX_LP_ABIL_REG(offset, block_id) \
13166+ CVMX_ADD_IO_SEG(0x00011800B0001018ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13167+#define CVMX_PCSX_ANX_RESULTS_REG(offset, block_id) \
13168+ CVMX_ADD_IO_SEG(0x00011800B0001020ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13169+#define CVMX_PCSX_INTX_EN_REG(offset, block_id) \
13170+ CVMX_ADD_IO_SEG(0x00011800B0001088ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13171+#define CVMX_PCSX_INTX_REG(offset, block_id) \
13172+ CVMX_ADD_IO_SEG(0x00011800B0001080ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13173+#define CVMX_PCSX_LINKX_TIMER_COUNT_REG(offset, block_id) \
13174+ CVMX_ADD_IO_SEG(0x00011800B0001040ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13175+#define CVMX_PCSX_LOG_ANLX_REG(offset, block_id) \
13176+ CVMX_ADD_IO_SEG(0x00011800B0001090ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13177+#define CVMX_PCSX_MISCX_CTL_REG(offset, block_id) \
13178+ CVMX_ADD_IO_SEG(0x00011800B0001078ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13179+#define CVMX_PCSX_MRX_CONTROL_REG(offset, block_id) \
13180+ CVMX_ADD_IO_SEG(0x00011800B0001000ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13181+#define CVMX_PCSX_MRX_STATUS_REG(offset, block_id) \
13182+ CVMX_ADD_IO_SEG(0x00011800B0001008ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13183+#define CVMX_PCSX_RXX_STATES_REG(offset, block_id) \
13184+ CVMX_ADD_IO_SEG(0x00011800B0001058ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13185+#define CVMX_PCSX_RXX_SYNC_REG(offset, block_id) \
13186+ CVMX_ADD_IO_SEG(0x00011800B0001050ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13187+#define CVMX_PCSX_SGMX_AN_ADV_REG(offset, block_id) \
13188+ CVMX_ADD_IO_SEG(0x00011800B0001068ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13189+#define CVMX_PCSX_SGMX_LP_ADV_REG(offset, block_id) \
13190+ CVMX_ADD_IO_SEG(0x00011800B0001070ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13191+#define CVMX_PCSX_TXX_STATES_REG(offset, block_id) \
13192+ CVMX_ADD_IO_SEG(0x00011800B0001060ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13193+#define CVMX_PCSX_TX_RXX_POLARITY_REG(offset, block_id) \
13194+ CVMX_ADD_IO_SEG(0x00011800B0001048ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13195+
13196+union cvmx_pcsx_anx_adv_reg {
13197+ uint64_t u64;
13198+ struct cvmx_pcsx_anx_adv_reg_s {
13199+ uint64_t reserved_16_63:48;
13200+ uint64_t np:1;
13201+ uint64_t reserved_14_14:1;
13202+ uint64_t rem_flt:2;
13203+ uint64_t reserved_9_11:3;
13204+ uint64_t pause:2;
13205+ uint64_t hfd:1;
13206+ uint64_t fd:1;
13207+ uint64_t reserved_0_4:5;
13208+ } s;
13209+ struct cvmx_pcsx_anx_adv_reg_s cn52xx;
13210+ struct cvmx_pcsx_anx_adv_reg_s cn52xxp1;
13211+ struct cvmx_pcsx_anx_adv_reg_s cn56xx;
13212+ struct cvmx_pcsx_anx_adv_reg_s cn56xxp1;
13213+};
13214+
13215+union cvmx_pcsx_anx_ext_st_reg {
13216+ uint64_t u64;
13217+ struct cvmx_pcsx_anx_ext_st_reg_s {
13218+ uint64_t reserved_16_63:48;
13219+ uint64_t thou_xfd:1;
13220+ uint64_t thou_xhd:1;
13221+ uint64_t thou_tfd:1;
13222+ uint64_t thou_thd:1;
13223+ uint64_t reserved_0_11:12;
13224+ } s;
13225+ struct cvmx_pcsx_anx_ext_st_reg_s cn52xx;
13226+ struct cvmx_pcsx_anx_ext_st_reg_s cn52xxp1;
13227+ struct cvmx_pcsx_anx_ext_st_reg_s cn56xx;
13228+ struct cvmx_pcsx_anx_ext_st_reg_s cn56xxp1;
13229+};
13230+
13231+union cvmx_pcsx_anx_lp_abil_reg {
13232+ uint64_t u64;
13233+ struct cvmx_pcsx_anx_lp_abil_reg_s {
13234+ uint64_t reserved_16_63:48;
13235+ uint64_t np:1;
13236+ uint64_t ack:1;
13237+ uint64_t rem_flt:2;
13238+ uint64_t reserved_9_11:3;
13239+ uint64_t pause:2;
13240+ uint64_t hfd:1;
13241+ uint64_t fd:1;
13242+ uint64_t reserved_0_4:5;
13243+ } s;
13244+ struct cvmx_pcsx_anx_lp_abil_reg_s cn52xx;
13245+ struct cvmx_pcsx_anx_lp_abil_reg_s cn52xxp1;
13246+ struct cvmx_pcsx_anx_lp_abil_reg_s cn56xx;
13247+ struct cvmx_pcsx_anx_lp_abil_reg_s cn56xxp1;
13248+};
13249+
13250+union cvmx_pcsx_anx_results_reg {
13251+ uint64_t u64;
13252+ struct cvmx_pcsx_anx_results_reg_s {
13253+ uint64_t reserved_7_63:57;
13254+ uint64_t pause:2;
13255+ uint64_t spd:2;
13256+ uint64_t an_cpt:1;
13257+ uint64_t dup:1;
13258+ uint64_t link_ok:1;
13259+ } s;
13260+ struct cvmx_pcsx_anx_results_reg_s cn52xx;
13261+ struct cvmx_pcsx_anx_results_reg_s cn52xxp1;
13262+ struct cvmx_pcsx_anx_results_reg_s cn56xx;
13263+ struct cvmx_pcsx_anx_results_reg_s cn56xxp1;
13264+};
13265+
13266+union cvmx_pcsx_intx_en_reg {
13267+ uint64_t u64;
13268+ struct cvmx_pcsx_intx_en_reg_s {
13269+ uint64_t reserved_12_63:52;
13270+ uint64_t dup:1;
13271+ uint64_t sync_bad_en:1;
13272+ uint64_t an_bad_en:1;
13273+ uint64_t rxlock_en:1;
13274+ uint64_t rxbad_en:1;
13275+ uint64_t rxerr_en:1;
13276+ uint64_t txbad_en:1;
13277+ uint64_t txfifo_en:1;
13278+ uint64_t txfifu_en:1;
13279+ uint64_t an_err_en:1;
13280+ uint64_t xmit_en:1;
13281+ uint64_t lnkspd_en:1;
13282+ } s;
13283+ struct cvmx_pcsx_intx_en_reg_s cn52xx;
13284+ struct cvmx_pcsx_intx_en_reg_s cn52xxp1;
13285+ struct cvmx_pcsx_intx_en_reg_s cn56xx;
13286+ struct cvmx_pcsx_intx_en_reg_s cn56xxp1;
13287+};
13288+
13289+union cvmx_pcsx_intx_reg {
13290+ uint64_t u64;
13291+ struct cvmx_pcsx_intx_reg_s {
13292+ uint64_t reserved_12_63:52;
13293+ uint64_t dup:1;
13294+ uint64_t sync_bad:1;
13295+ uint64_t an_bad:1;
13296+ uint64_t rxlock:1;
13297+ uint64_t rxbad:1;
13298+ uint64_t rxerr:1;
13299+ uint64_t txbad:1;
13300+ uint64_t txfifo:1;
13301+ uint64_t txfifu:1;
13302+ uint64_t an_err:1;
13303+ uint64_t xmit:1;
13304+ uint64_t lnkspd:1;
13305+ } s;
13306+ struct cvmx_pcsx_intx_reg_s cn52xx;
13307+ struct cvmx_pcsx_intx_reg_s cn52xxp1;
13308+ struct cvmx_pcsx_intx_reg_s cn56xx;
13309+ struct cvmx_pcsx_intx_reg_s cn56xxp1;
13310+};
13311+
13312+union cvmx_pcsx_linkx_timer_count_reg {
13313+ uint64_t u64;
13314+ struct cvmx_pcsx_linkx_timer_count_reg_s {
13315+ uint64_t reserved_16_63:48;
13316+ uint64_t count:16;
13317+ } s;
13318+ struct cvmx_pcsx_linkx_timer_count_reg_s cn52xx;
13319+ struct cvmx_pcsx_linkx_timer_count_reg_s cn52xxp1;
13320+ struct cvmx_pcsx_linkx_timer_count_reg_s cn56xx;
13321+ struct cvmx_pcsx_linkx_timer_count_reg_s cn56xxp1;
13322+};
13323+
13324+union cvmx_pcsx_log_anlx_reg {
13325+ uint64_t u64;
13326+ struct cvmx_pcsx_log_anlx_reg_s {
13327+ uint64_t reserved_4_63:60;
13328+ uint64_t lafifovfl:1;
13329+ uint64_t la_en:1;
13330+ uint64_t pkt_sz:2;
13331+ } s;
13332+ struct cvmx_pcsx_log_anlx_reg_s cn52xx;
13333+ struct cvmx_pcsx_log_anlx_reg_s cn52xxp1;
13334+ struct cvmx_pcsx_log_anlx_reg_s cn56xx;
13335+ struct cvmx_pcsx_log_anlx_reg_s cn56xxp1;
13336+};
13337+
13338+union cvmx_pcsx_miscx_ctl_reg {
13339+ uint64_t u64;
13340+ struct cvmx_pcsx_miscx_ctl_reg_s {
13341+ uint64_t reserved_13_63:51;
13342+ uint64_t sgmii:1;
13343+ uint64_t gmxeno:1;
13344+ uint64_t loopbck2:1;
13345+ uint64_t mac_phy:1;
13346+ uint64_t mode:1;
13347+ uint64_t an_ovrd:1;
13348+ uint64_t samp_pt:7;
13349+ } s;
13350+ struct cvmx_pcsx_miscx_ctl_reg_s cn52xx;
13351+ struct cvmx_pcsx_miscx_ctl_reg_s cn52xxp1;
13352+ struct cvmx_pcsx_miscx_ctl_reg_s cn56xx;
13353+ struct cvmx_pcsx_miscx_ctl_reg_s cn56xxp1;
13354+};
13355+
13356+union cvmx_pcsx_mrx_control_reg {
13357+ uint64_t u64;
13358+ struct cvmx_pcsx_mrx_control_reg_s {
13359+ uint64_t reserved_16_63:48;
13360+ uint64_t reset:1;
13361+ uint64_t loopbck1:1;
13362+ uint64_t spdlsb:1;
13363+ uint64_t an_en:1;
13364+ uint64_t pwr_dn:1;
13365+ uint64_t reserved_10_10:1;
13366+ uint64_t rst_an:1;
13367+ uint64_t dup:1;
13368+ uint64_t coltst:1;
13369+ uint64_t spdmsb:1;
13370+ uint64_t uni:1;
13371+ uint64_t reserved_0_4:5;
13372+ } s;
13373+ struct cvmx_pcsx_mrx_control_reg_s cn52xx;
13374+ struct cvmx_pcsx_mrx_control_reg_s cn52xxp1;
13375+ struct cvmx_pcsx_mrx_control_reg_s cn56xx;
13376+ struct cvmx_pcsx_mrx_control_reg_s cn56xxp1;
13377+};
13378+
13379+union cvmx_pcsx_mrx_status_reg {
13380+ uint64_t u64;
13381+ struct cvmx_pcsx_mrx_status_reg_s {
13382+ uint64_t reserved_16_63:48;
13383+ uint64_t hun_t4:1;
13384+ uint64_t hun_xfd:1;
13385+ uint64_t hun_xhd:1;
13386+ uint64_t ten_fd:1;
13387+ uint64_t ten_hd:1;
13388+ uint64_t hun_t2fd:1;
13389+ uint64_t hun_t2hd:1;
13390+ uint64_t ext_st:1;
13391+ uint64_t reserved_7_7:1;
13392+ uint64_t prb_sup:1;
13393+ uint64_t an_cpt:1;
13394+ uint64_t rm_flt:1;
13395+ uint64_t an_abil:1;
13396+ uint64_t lnk_st:1;
13397+ uint64_t reserved_1_1:1;
13398+ uint64_t extnd:1;
13399+ } s;
13400+ struct cvmx_pcsx_mrx_status_reg_s cn52xx;
13401+ struct cvmx_pcsx_mrx_status_reg_s cn52xxp1;
13402+ struct cvmx_pcsx_mrx_status_reg_s cn56xx;
13403+ struct cvmx_pcsx_mrx_status_reg_s cn56xxp1;
13404+};
13405+
13406+union cvmx_pcsx_rxx_states_reg {
13407+ uint64_t u64;
13408+ struct cvmx_pcsx_rxx_states_reg_s {
13409+ uint64_t reserved_16_63:48;
13410+ uint64_t rx_bad:1;
13411+ uint64_t rx_st:5;
13412+ uint64_t sync_bad:1;
13413+ uint64_t sync:4;
13414+ uint64_t an_bad:1;
13415+ uint64_t an_st:4;
13416+ } s;
13417+ struct cvmx_pcsx_rxx_states_reg_s cn52xx;
13418+ struct cvmx_pcsx_rxx_states_reg_s cn52xxp1;
13419+ struct cvmx_pcsx_rxx_states_reg_s cn56xx;
13420+ struct cvmx_pcsx_rxx_states_reg_s cn56xxp1;
13421+};
13422+
13423+union cvmx_pcsx_rxx_sync_reg {
13424+ uint64_t u64;
13425+ struct cvmx_pcsx_rxx_sync_reg_s {
13426+ uint64_t reserved_2_63:62;
13427+ uint64_t sync:1;
13428+ uint64_t bit_lock:1;
13429+ } s;
13430+ struct cvmx_pcsx_rxx_sync_reg_s cn52xx;
13431+ struct cvmx_pcsx_rxx_sync_reg_s cn52xxp1;
13432+ struct cvmx_pcsx_rxx_sync_reg_s cn56xx;
13433+ struct cvmx_pcsx_rxx_sync_reg_s cn56xxp1;
13434+};
13435+
13436+union cvmx_pcsx_sgmx_an_adv_reg {
13437+ uint64_t u64;
13438+ struct cvmx_pcsx_sgmx_an_adv_reg_s {
13439+ uint64_t reserved_16_63:48;
13440+ uint64_t link:1;
13441+ uint64_t ack:1;
13442+ uint64_t reserved_13_13:1;
13443+ uint64_t dup:1;
13444+ uint64_t speed:2;
13445+ uint64_t reserved_1_9:9;
13446+ uint64_t one:1;
13447+ } s;
13448+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xx;
13449+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xxp1;
13450+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xx;
13451+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xxp1;
13452+};
13453+
13454+union cvmx_pcsx_sgmx_lp_adv_reg {
13455+ uint64_t u64;
13456+ struct cvmx_pcsx_sgmx_lp_adv_reg_s {
13457+ uint64_t reserved_16_63:48;
13458+ uint64_t link:1;
13459+ uint64_t reserved_13_14:2;
13460+ uint64_t dup:1;
13461+ uint64_t speed:2;
13462+ uint64_t reserved_1_9:9;
13463+ uint64_t one:1;
13464+ } s;
13465+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xx;
13466+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xxp1;
13467+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xx;
13468+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xxp1;
13469+};
13470+
13471+union cvmx_pcsx_txx_states_reg {
13472+ uint64_t u64;
13473+ struct cvmx_pcsx_txx_states_reg_s {
13474+ uint64_t reserved_7_63:57;
13475+ uint64_t xmit:2;
13476+ uint64_t tx_bad:1;
13477+ uint64_t ord_st:4;
13478+ } s;
13479+ struct cvmx_pcsx_txx_states_reg_s cn52xx;
13480+ struct cvmx_pcsx_txx_states_reg_s cn52xxp1;
13481+ struct cvmx_pcsx_txx_states_reg_s cn56xx;
13482+ struct cvmx_pcsx_txx_states_reg_s cn56xxp1;
13483+};
13484+
13485+union cvmx_pcsx_tx_rxx_polarity_reg {
13486+ uint64_t u64;
13487+ struct cvmx_pcsx_tx_rxx_polarity_reg_s {
13488+ uint64_t reserved_4_63:60;
13489+ uint64_t rxovrd:1;
13490+ uint64_t autorxpl:1;
13491+ uint64_t rxplrt:1;
13492+ uint64_t txplrt:1;
13493+ } s;
13494+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xx;
13495+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xxp1;
13496+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xx;
13497+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xxp1;
13498+};
13499+
13500+#endif
13501--- /dev/null
13502+++ b/drivers/staging/octeon/cvmx-pcsxx-defs.h
13503@@ -0,0 +1,316 @@
13504+/***********************license start***************
13505+ * Author: Cavium Networks
13506+ *
13507+ * Contact: support@caviumnetworks.com
13508+ * This file is part of the OCTEON SDK
13509+ *
13510+ * Copyright (c) 2003-2008 Cavium Networks
13511+ *
13512+ * This file is free software; you can redistribute it and/or modify
13513+ * it under the terms of the GNU General Public License, Version 2, as
13514+ * published by the Free Software Foundation.
13515+ *
13516+ * This file is distributed in the hope that it will be useful, but
13517+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13518+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13519+ * NONINFRINGEMENT. See the GNU General Public License for more
13520+ * details.
13521+ *
13522+ * You should have received a copy of the GNU General Public License
13523+ * along with this file; if not, write to the Free Software
13524+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13525+ * or visit http://www.gnu.org/licenses/.
13526+ *
13527+ * This file may also be available under a different license from Cavium.
13528+ * Contact Cavium Networks for more information
13529+ ***********************license end**************************************/
13530+
13531+#ifndef __CVMX_PCSXX_DEFS_H__
13532+#define __CVMX_PCSXX_DEFS_H__
13533+
13534+#define CVMX_PCSXX_10GBX_STATUS_REG(block_id) \
13535+ CVMX_ADD_IO_SEG(0x00011800B0000828ull + (((block_id) & 1) * 0x8000000ull))
13536+#define CVMX_PCSXX_BIST_STATUS_REG(block_id) \
13537+ CVMX_ADD_IO_SEG(0x00011800B0000870ull + (((block_id) & 1) * 0x8000000ull))
13538+#define CVMX_PCSXX_BIT_LOCK_STATUS_REG(block_id) \
13539+ CVMX_ADD_IO_SEG(0x00011800B0000850ull + (((block_id) & 1) * 0x8000000ull))
13540+#define CVMX_PCSXX_CONTROL1_REG(block_id) \
13541+ CVMX_ADD_IO_SEG(0x00011800B0000800ull + (((block_id) & 1) * 0x8000000ull))
13542+#define CVMX_PCSXX_CONTROL2_REG(block_id) \
13543+ CVMX_ADD_IO_SEG(0x00011800B0000818ull + (((block_id) & 1) * 0x8000000ull))
13544+#define CVMX_PCSXX_INT_EN_REG(block_id) \
13545+ CVMX_ADD_IO_SEG(0x00011800B0000860ull + (((block_id) & 1) * 0x8000000ull))
13546+#define CVMX_PCSXX_INT_REG(block_id) \
13547+ CVMX_ADD_IO_SEG(0x00011800B0000858ull + (((block_id) & 1) * 0x8000000ull))
13548+#define CVMX_PCSXX_LOG_ANL_REG(block_id) \
13549+ CVMX_ADD_IO_SEG(0x00011800B0000868ull + (((block_id) & 1) * 0x8000000ull))
13550+#define CVMX_PCSXX_MISC_CTL_REG(block_id) \
13551+ CVMX_ADD_IO_SEG(0x00011800B0000848ull + (((block_id) & 1) * 0x8000000ull))
13552+#define CVMX_PCSXX_RX_SYNC_STATES_REG(block_id) \
13553+ CVMX_ADD_IO_SEG(0x00011800B0000838ull + (((block_id) & 1) * 0x8000000ull))
13554+#define CVMX_PCSXX_SPD_ABIL_REG(block_id) \
13555+ CVMX_ADD_IO_SEG(0x00011800B0000810ull + (((block_id) & 1) * 0x8000000ull))
13556+#define CVMX_PCSXX_STATUS1_REG(block_id) \
13557+ CVMX_ADD_IO_SEG(0x00011800B0000808ull + (((block_id) & 1) * 0x8000000ull))
13558+#define CVMX_PCSXX_STATUS2_REG(block_id) \
13559+ CVMX_ADD_IO_SEG(0x00011800B0000820ull + (((block_id) & 1) * 0x8000000ull))
13560+#define CVMX_PCSXX_TX_RX_POLARITY_REG(block_id) \
13561+ CVMX_ADD_IO_SEG(0x00011800B0000840ull + (((block_id) & 1) * 0x8000000ull))
13562+#define CVMX_PCSXX_TX_RX_STATES_REG(block_id) \
13563+ CVMX_ADD_IO_SEG(0x00011800B0000830ull + (((block_id) & 1) * 0x8000000ull))
13564+
13565+union cvmx_pcsxx_10gbx_status_reg {
13566+ uint64_t u64;
13567+ struct cvmx_pcsxx_10gbx_status_reg_s {
13568+ uint64_t reserved_13_63:51;
13569+ uint64_t alignd:1;
13570+ uint64_t pattst:1;
13571+ uint64_t reserved_4_10:7;
13572+ uint64_t l3sync:1;
13573+ uint64_t l2sync:1;
13574+ uint64_t l1sync:1;
13575+ uint64_t l0sync:1;
13576+ } s;
13577+ struct cvmx_pcsxx_10gbx_status_reg_s cn52xx;
13578+ struct cvmx_pcsxx_10gbx_status_reg_s cn52xxp1;
13579+ struct cvmx_pcsxx_10gbx_status_reg_s cn56xx;
13580+ struct cvmx_pcsxx_10gbx_status_reg_s cn56xxp1;
13581+};
13582+
13583+union cvmx_pcsxx_bist_status_reg {
13584+ uint64_t u64;
13585+ struct cvmx_pcsxx_bist_status_reg_s {
13586+ uint64_t reserved_1_63:63;
13587+ uint64_t bist_status:1;
13588+ } s;
13589+ struct cvmx_pcsxx_bist_status_reg_s cn52xx;
13590+ struct cvmx_pcsxx_bist_status_reg_s cn52xxp1;
13591+ struct cvmx_pcsxx_bist_status_reg_s cn56xx;
13592+ struct cvmx_pcsxx_bist_status_reg_s cn56xxp1;
13593+};
13594+
13595+union cvmx_pcsxx_bit_lock_status_reg {
13596+ uint64_t u64;
13597+ struct cvmx_pcsxx_bit_lock_status_reg_s {
13598+ uint64_t reserved_4_63:60;
13599+ uint64_t bitlck3:1;
13600+ uint64_t bitlck2:1;
13601+ uint64_t bitlck1:1;
13602+ uint64_t bitlck0:1;
13603+ } s;
13604+ struct cvmx_pcsxx_bit_lock_status_reg_s cn52xx;
13605+ struct cvmx_pcsxx_bit_lock_status_reg_s cn52xxp1;
13606+ struct cvmx_pcsxx_bit_lock_status_reg_s cn56xx;
13607+ struct cvmx_pcsxx_bit_lock_status_reg_s cn56xxp1;
13608+};
13609+
13610+union cvmx_pcsxx_control1_reg {
13611+ uint64_t u64;
13612+ struct cvmx_pcsxx_control1_reg_s {
13613+ uint64_t reserved_16_63:48;
13614+ uint64_t reset:1;
13615+ uint64_t loopbck1:1;
13616+ uint64_t spdsel1:1;
13617+ uint64_t reserved_12_12:1;
13618+ uint64_t lo_pwr:1;
13619+ uint64_t reserved_7_10:4;
13620+ uint64_t spdsel0:1;
13621+ uint64_t spd:4;
13622+ uint64_t reserved_0_1:2;
13623+ } s;
13624+ struct cvmx_pcsxx_control1_reg_s cn52xx;
13625+ struct cvmx_pcsxx_control1_reg_s cn52xxp1;
13626+ struct cvmx_pcsxx_control1_reg_s cn56xx;
13627+ struct cvmx_pcsxx_control1_reg_s cn56xxp1;
13628+};
13629+
13630+union cvmx_pcsxx_control2_reg {
13631+ uint64_t u64;
13632+ struct cvmx_pcsxx_control2_reg_s {
13633+ uint64_t reserved_2_63:62;
13634+ uint64_t type:2;
13635+ } s;
13636+ struct cvmx_pcsxx_control2_reg_s cn52xx;
13637+ struct cvmx_pcsxx_control2_reg_s cn52xxp1;
13638+ struct cvmx_pcsxx_control2_reg_s cn56xx;
13639+ struct cvmx_pcsxx_control2_reg_s cn56xxp1;
13640+};
13641+
13642+union cvmx_pcsxx_int_en_reg {
13643+ uint64_t u64;
13644+ struct cvmx_pcsxx_int_en_reg_s {
13645+ uint64_t reserved_6_63:58;
13646+ uint64_t algnlos_en:1;
13647+ uint64_t synlos_en:1;
13648+ uint64_t bitlckls_en:1;
13649+ uint64_t rxsynbad_en:1;
13650+ uint64_t rxbad_en:1;
13651+ uint64_t txflt_en:1;
13652+ } s;
13653+ struct cvmx_pcsxx_int_en_reg_s cn52xx;
13654+ struct cvmx_pcsxx_int_en_reg_s cn52xxp1;
13655+ struct cvmx_pcsxx_int_en_reg_s cn56xx;
13656+ struct cvmx_pcsxx_int_en_reg_s cn56xxp1;
13657+};
13658+
13659+union cvmx_pcsxx_int_reg {
13660+ uint64_t u64;
13661+ struct cvmx_pcsxx_int_reg_s {
13662+ uint64_t reserved_6_63:58;
13663+ uint64_t algnlos:1;
13664+ uint64_t synlos:1;
13665+ uint64_t bitlckls:1;
13666+ uint64_t rxsynbad:1;
13667+ uint64_t rxbad:1;
13668+ uint64_t txflt:1;
13669+ } s;
13670+ struct cvmx_pcsxx_int_reg_s cn52xx;
13671+ struct cvmx_pcsxx_int_reg_s cn52xxp1;
13672+ struct cvmx_pcsxx_int_reg_s cn56xx;
13673+ struct cvmx_pcsxx_int_reg_s cn56xxp1;
13674+};
13675+
13676+union cvmx_pcsxx_log_anl_reg {
13677+ uint64_t u64;
13678+ struct cvmx_pcsxx_log_anl_reg_s {
13679+ uint64_t reserved_7_63:57;
13680+ uint64_t enc_mode:1;
13681+ uint64_t drop_ln:2;
13682+ uint64_t lafifovfl:1;
13683+ uint64_t la_en:1;
13684+ uint64_t pkt_sz:2;
13685+ } s;
13686+ struct cvmx_pcsxx_log_anl_reg_s cn52xx;
13687+ struct cvmx_pcsxx_log_anl_reg_s cn52xxp1;
13688+ struct cvmx_pcsxx_log_anl_reg_s cn56xx;
13689+ struct cvmx_pcsxx_log_anl_reg_s cn56xxp1;
13690+};
13691+
13692+union cvmx_pcsxx_misc_ctl_reg {
13693+ uint64_t u64;
13694+ struct cvmx_pcsxx_misc_ctl_reg_s {
13695+ uint64_t reserved_4_63:60;
13696+ uint64_t tx_swap:1;
13697+ uint64_t rx_swap:1;
13698+ uint64_t xaui:1;
13699+ uint64_t gmxeno:1;
13700+ } s;
13701+ struct cvmx_pcsxx_misc_ctl_reg_s cn52xx;
13702+ struct cvmx_pcsxx_misc_ctl_reg_s cn52xxp1;
13703+ struct cvmx_pcsxx_misc_ctl_reg_s cn56xx;
13704+ struct cvmx_pcsxx_misc_ctl_reg_s cn56xxp1;
13705+};
13706+
13707+union cvmx_pcsxx_rx_sync_states_reg {
13708+ uint64_t u64;
13709+ struct cvmx_pcsxx_rx_sync_states_reg_s {
13710+ uint64_t reserved_16_63:48;
13711+ uint64_t sync3st:4;
13712+ uint64_t sync2st:4;
13713+ uint64_t sync1st:4;
13714+ uint64_t sync0st:4;
13715+ } s;
13716+ struct cvmx_pcsxx_rx_sync_states_reg_s cn52xx;
13717+ struct cvmx_pcsxx_rx_sync_states_reg_s cn52xxp1;
13718+ struct cvmx_pcsxx_rx_sync_states_reg_s cn56xx;
13719+ struct cvmx_pcsxx_rx_sync_states_reg_s cn56xxp1;
13720+};
13721+
13722+union cvmx_pcsxx_spd_abil_reg {
13723+ uint64_t u64;
13724+ struct cvmx_pcsxx_spd_abil_reg_s {
13725+ uint64_t reserved_2_63:62;
13726+ uint64_t tenpasst:1;
13727+ uint64_t tengb:1;
13728+ } s;
13729+ struct cvmx_pcsxx_spd_abil_reg_s cn52xx;
13730+ struct cvmx_pcsxx_spd_abil_reg_s cn52xxp1;
13731+ struct cvmx_pcsxx_spd_abil_reg_s cn56xx;
13732+ struct cvmx_pcsxx_spd_abil_reg_s cn56xxp1;
13733+};
13734+
13735+union cvmx_pcsxx_status1_reg {
13736+ uint64_t u64;
13737+ struct cvmx_pcsxx_status1_reg_s {
13738+ uint64_t reserved_8_63:56;
13739+ uint64_t flt:1;
13740+ uint64_t reserved_3_6:4;
13741+ uint64_t rcv_lnk:1;
13742+ uint64_t lpable:1;
13743+ uint64_t reserved_0_0:1;
13744+ } s;
13745+ struct cvmx_pcsxx_status1_reg_s cn52xx;
13746+ struct cvmx_pcsxx_status1_reg_s cn52xxp1;
13747+ struct cvmx_pcsxx_status1_reg_s cn56xx;
13748+ struct cvmx_pcsxx_status1_reg_s cn56xxp1;
13749+};
13750+
13751+union cvmx_pcsxx_status2_reg {
13752+ uint64_t u64;
13753+ struct cvmx_pcsxx_status2_reg_s {
13754+ uint64_t reserved_16_63:48;
13755+ uint64_t dev:2;
13756+ uint64_t reserved_12_13:2;
13757+ uint64_t xmtflt:1;
13758+ uint64_t rcvflt:1;
13759+ uint64_t reserved_3_9:7;
13760+ uint64_t tengb_w:1;
13761+ uint64_t tengb_x:1;
13762+ uint64_t tengb_r:1;
13763+ } s;
13764+ struct cvmx_pcsxx_status2_reg_s cn52xx;
13765+ struct cvmx_pcsxx_status2_reg_s cn52xxp1;
13766+ struct cvmx_pcsxx_status2_reg_s cn56xx;
13767+ struct cvmx_pcsxx_status2_reg_s cn56xxp1;
13768+};
13769+
13770+union cvmx_pcsxx_tx_rx_polarity_reg {
13771+ uint64_t u64;
13772+ struct cvmx_pcsxx_tx_rx_polarity_reg_s {
13773+ uint64_t reserved_10_63:54;
13774+ uint64_t xor_rxplrt:4;
13775+ uint64_t xor_txplrt:4;
13776+ uint64_t rxplrt:1;
13777+ uint64_t txplrt:1;
13778+ } s;
13779+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn52xx;
13780+ struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 {
13781+ uint64_t reserved_2_63:62;
13782+ uint64_t rxplrt:1;
13783+ uint64_t txplrt:1;
13784+ } cn52xxp1;
13785+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn56xx;
13786+ struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 cn56xxp1;
13787+};
13788+
13789+union cvmx_pcsxx_tx_rx_states_reg {
13790+ uint64_t u64;
13791+ struct cvmx_pcsxx_tx_rx_states_reg_s {
13792+ uint64_t reserved_14_63:50;
13793+ uint64_t term_err:1;
13794+ uint64_t syn3bad:1;
13795+ uint64_t syn2bad:1;
13796+ uint64_t syn1bad:1;
13797+ uint64_t syn0bad:1;
13798+ uint64_t rxbad:1;
13799+ uint64_t algn_st:3;
13800+ uint64_t rx_st:2;
13801+ uint64_t tx_st:3;
13802+ } s;
13803+ struct cvmx_pcsxx_tx_rx_states_reg_s cn52xx;
13804+ struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 {
13805+ uint64_t reserved_13_63:51;
13806+ uint64_t syn3bad:1;
13807+ uint64_t syn2bad:1;
13808+ uint64_t syn1bad:1;
13809+ uint64_t syn0bad:1;
13810+ uint64_t rxbad:1;
13811+ uint64_t algn_st:3;
13812+ uint64_t rx_st:2;
13813+ uint64_t tx_st:3;
13814+ } cn52xxp1;
13815+ struct cvmx_pcsxx_tx_rx_states_reg_s cn56xx;
13816+ struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 cn56xxp1;
13817+};
13818+
13819+#endif
13820--- /dev/null
13821+++ b/drivers/staging/octeon/cvmx-pip-defs.h
13822@@ -0,0 +1,1267 @@
13823+/***********************license start***************
13824+ * Author: Cavium Networks
13825+ *
13826+ * Contact: support@caviumnetworks.com
13827+ * This file is part of the OCTEON SDK
13828+ *
13829+ * Copyright (c) 2003-2008 Cavium Networks
13830+ *
13831+ * This file is free software; you can redistribute it and/or modify
13832+ * it under the terms of the GNU General Public License, Version 2, as
13833+ * published by the Free Software Foundation.
13834+ *
13835+ * This file is distributed in the hope that it will be useful, but
13836+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13837+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13838+ * NONINFRINGEMENT. See the GNU General Public License for more
13839+ * details.
13840+ *
13841+ * You should have received a copy of the GNU General Public License
13842+ * along with this file; if not, write to the Free Software
13843+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13844+ * or visit http://www.gnu.org/licenses/.
13845+ *
13846+ * This file may also be available under a different license from Cavium.
13847+ * Contact Cavium Networks for more information
13848+ ***********************license end**************************************/
13849+
13850+#ifndef __CVMX_PIP_DEFS_H__
13851+#define __CVMX_PIP_DEFS_H__
13852+
13853+/*
13854+ * Enumeration representing the amount of packet processing
13855+ * and validation performed by the input hardware.
13856+ */
13857+enum cvmx_pip_port_parse_mode {
13858+ /*
13859+ * Packet input doesn't perform any processing of the input
13860+ * packet.
13861+ */
13862+ CVMX_PIP_PORT_CFG_MODE_NONE = 0ull,
13863+ /*
13864+ * Full packet processing is performed with pointer starting
13865+ * at the L2 (ethernet MAC) header.
13866+ */
13867+ CVMX_PIP_PORT_CFG_MODE_SKIPL2 = 1ull,
13868+ /*
13869+ * Input packets are assumed to be IP. Results from non IP
13870+ * packets is undefined. Pointers reference the beginning of
13871+ * the IP header.
13872+ */
13873+ CVMX_PIP_PORT_CFG_MODE_SKIPIP = 2ull
13874+};
13875+
13876+#define CVMX_PIP_BCK_PRS \
13877+ CVMX_ADD_IO_SEG(0x00011800A0000038ull)
13878+#define CVMX_PIP_BIST_STATUS \
13879+ CVMX_ADD_IO_SEG(0x00011800A0000000ull)
13880+#define CVMX_PIP_CRC_CTLX(offset) \
13881+ CVMX_ADD_IO_SEG(0x00011800A0000040ull + (((offset) & 1) * 8))
13882+#define CVMX_PIP_CRC_IVX(offset) \
13883+ CVMX_ADD_IO_SEG(0x00011800A0000050ull + (((offset) & 1) * 8))
13884+#define CVMX_PIP_DEC_IPSECX(offset) \
13885+ CVMX_ADD_IO_SEG(0x00011800A0000080ull + (((offset) & 3) * 8))
13886+#define CVMX_PIP_DSA_SRC_GRP \
13887+ CVMX_ADD_IO_SEG(0x00011800A0000190ull)
13888+#define CVMX_PIP_DSA_VID_GRP \
13889+ CVMX_ADD_IO_SEG(0x00011800A0000198ull)
13890+#define CVMX_PIP_FRM_LEN_CHKX(offset) \
13891+ CVMX_ADD_IO_SEG(0x00011800A0000180ull + (((offset) & 1) * 8))
13892+#define CVMX_PIP_GBL_CFG \
13893+ CVMX_ADD_IO_SEG(0x00011800A0000028ull)
13894+#define CVMX_PIP_GBL_CTL \
13895+ CVMX_ADD_IO_SEG(0x00011800A0000020ull)
13896+#define CVMX_PIP_HG_PRI_QOS \
13897+ CVMX_ADD_IO_SEG(0x00011800A00001A0ull)
13898+#define CVMX_PIP_INT_EN \
13899+ CVMX_ADD_IO_SEG(0x00011800A0000010ull)
13900+#define CVMX_PIP_INT_REG \
13901+ CVMX_ADD_IO_SEG(0x00011800A0000008ull)
13902+#define CVMX_PIP_IP_OFFSET \
13903+ CVMX_ADD_IO_SEG(0x00011800A0000060ull)
13904+#define CVMX_PIP_PRT_CFGX(offset) \
13905+ CVMX_ADD_IO_SEG(0x00011800A0000200ull + (((offset) & 63) * 8))
13906+#define CVMX_PIP_PRT_TAGX(offset) \
13907+ CVMX_ADD_IO_SEG(0x00011800A0000400ull + (((offset) & 63) * 8))
13908+#define CVMX_PIP_QOS_DIFFX(offset) \
13909+ CVMX_ADD_IO_SEG(0x00011800A0000600ull + (((offset) & 63) * 8))
13910+#define CVMX_PIP_QOS_VLANX(offset) \
13911+ CVMX_ADD_IO_SEG(0x00011800A00000C0ull + (((offset) & 7) * 8))
13912+#define CVMX_PIP_QOS_WATCHX(offset) \
13913+ CVMX_ADD_IO_SEG(0x00011800A0000100ull + (((offset) & 7) * 8))
13914+#define CVMX_PIP_RAW_WORD \
13915+ CVMX_ADD_IO_SEG(0x00011800A00000B0ull)
13916+#define CVMX_PIP_SFT_RST \
13917+ CVMX_ADD_IO_SEG(0x00011800A0000030ull)
13918+#define CVMX_PIP_STAT0_PRTX(offset) \
13919+ CVMX_ADD_IO_SEG(0x00011800A0000800ull + (((offset) & 63) * 80))
13920+#define CVMX_PIP_STAT1_PRTX(offset) \
13921+ CVMX_ADD_IO_SEG(0x00011800A0000808ull + (((offset) & 63) * 80))
13922+#define CVMX_PIP_STAT2_PRTX(offset) \
13923+ CVMX_ADD_IO_SEG(0x00011800A0000810ull + (((offset) & 63) * 80))
13924+#define CVMX_PIP_STAT3_PRTX(offset) \
13925+ CVMX_ADD_IO_SEG(0x00011800A0000818ull + (((offset) & 63) * 80))
13926+#define CVMX_PIP_STAT4_PRTX(offset) \
13927+ CVMX_ADD_IO_SEG(0x00011800A0000820ull + (((offset) & 63) * 80))
13928+#define CVMX_PIP_STAT5_PRTX(offset) \
13929+ CVMX_ADD_IO_SEG(0x00011800A0000828ull + (((offset) & 63) * 80))
13930+#define CVMX_PIP_STAT6_PRTX(offset) \
13931+ CVMX_ADD_IO_SEG(0x00011800A0000830ull + (((offset) & 63) * 80))
13932+#define CVMX_PIP_STAT7_PRTX(offset) \
13933+ CVMX_ADD_IO_SEG(0x00011800A0000838ull + (((offset) & 63) * 80))
13934+#define CVMX_PIP_STAT8_PRTX(offset) \
13935+ CVMX_ADD_IO_SEG(0x00011800A0000840ull + (((offset) & 63) * 80))
13936+#define CVMX_PIP_STAT9_PRTX(offset) \
13937+ CVMX_ADD_IO_SEG(0x00011800A0000848ull + (((offset) & 63) * 80))
13938+#define CVMX_PIP_STAT_CTL \
13939+ CVMX_ADD_IO_SEG(0x00011800A0000018ull)
13940+#define CVMX_PIP_STAT_INB_ERRSX(offset) \
13941+ CVMX_ADD_IO_SEG(0x00011800A0001A10ull + (((offset) & 63) * 32))
13942+#define CVMX_PIP_STAT_INB_OCTSX(offset) \
13943+ CVMX_ADD_IO_SEG(0x00011800A0001A08ull + (((offset) & 63) * 32))
13944+#define CVMX_PIP_STAT_INB_PKTSX(offset) \
13945+ CVMX_ADD_IO_SEG(0x00011800A0001A00ull + (((offset) & 63) * 32))
13946+#define CVMX_PIP_TAG_INCX(offset) \
13947+ CVMX_ADD_IO_SEG(0x00011800A0001800ull + (((offset) & 63) * 8))
13948+#define CVMX_PIP_TAG_MASK \
13949+ CVMX_ADD_IO_SEG(0x00011800A0000070ull)
13950+#define CVMX_PIP_TAG_SECRET \
13951+ CVMX_ADD_IO_SEG(0x00011800A0000068ull)
13952+#define CVMX_PIP_TODO_ENTRY \
13953+ CVMX_ADD_IO_SEG(0x00011800A0000078ull)
13954+
13955+union cvmx_pip_bck_prs {
13956+ uint64_t u64;
13957+ struct cvmx_pip_bck_prs_s {
13958+ uint64_t bckprs:1;
13959+ uint64_t reserved_13_62:50;
13960+ uint64_t hiwater:5;
13961+ uint64_t reserved_5_7:3;
13962+ uint64_t lowater:5;
13963+ } s;
13964+ struct cvmx_pip_bck_prs_s cn38xx;
13965+ struct cvmx_pip_bck_prs_s cn38xxp2;
13966+ struct cvmx_pip_bck_prs_s cn56xx;
13967+ struct cvmx_pip_bck_prs_s cn56xxp1;
13968+ struct cvmx_pip_bck_prs_s cn58xx;
13969+ struct cvmx_pip_bck_prs_s cn58xxp1;
13970+};
13971+
13972+union cvmx_pip_bist_status {
13973+ uint64_t u64;
13974+ struct cvmx_pip_bist_status_s {
13975+ uint64_t reserved_18_63:46;
13976+ uint64_t bist:18;
13977+ } s;
13978+ struct cvmx_pip_bist_status_s cn30xx;
13979+ struct cvmx_pip_bist_status_s cn31xx;
13980+ struct cvmx_pip_bist_status_s cn38xx;
13981+ struct cvmx_pip_bist_status_s cn38xxp2;
13982+ struct cvmx_pip_bist_status_cn50xx {
13983+ uint64_t reserved_17_63:47;
13984+ uint64_t bist:17;
13985+ } cn50xx;
13986+ struct cvmx_pip_bist_status_s cn52xx;
13987+ struct cvmx_pip_bist_status_s cn52xxp1;
13988+ struct cvmx_pip_bist_status_s cn56xx;
13989+ struct cvmx_pip_bist_status_s cn56xxp1;
13990+ struct cvmx_pip_bist_status_s cn58xx;
13991+ struct cvmx_pip_bist_status_s cn58xxp1;
13992+};
13993+
13994+union cvmx_pip_crc_ctlx {
13995+ uint64_t u64;
13996+ struct cvmx_pip_crc_ctlx_s {
13997+ uint64_t reserved_2_63:62;
13998+ uint64_t invres:1;
13999+ uint64_t reflect:1;
14000+ } s;
14001+ struct cvmx_pip_crc_ctlx_s cn38xx;
14002+ struct cvmx_pip_crc_ctlx_s cn38xxp2;
14003+ struct cvmx_pip_crc_ctlx_s cn58xx;
14004+ struct cvmx_pip_crc_ctlx_s cn58xxp1;
14005+};
14006+
14007+union cvmx_pip_crc_ivx {
14008+ uint64_t u64;
14009+ struct cvmx_pip_crc_ivx_s {
14010+ uint64_t reserved_32_63:32;
14011+ uint64_t iv:32;
14012+ } s;
14013+ struct cvmx_pip_crc_ivx_s cn38xx;
14014+ struct cvmx_pip_crc_ivx_s cn38xxp2;
14015+ struct cvmx_pip_crc_ivx_s cn58xx;
14016+ struct cvmx_pip_crc_ivx_s cn58xxp1;
14017+};
14018+
14019+union cvmx_pip_dec_ipsecx {
14020+ uint64_t u64;
14021+ struct cvmx_pip_dec_ipsecx_s {
14022+ uint64_t reserved_18_63:46;
14023+ uint64_t tcp:1;
14024+ uint64_t udp:1;
14025+ uint64_t dprt:16;
14026+ } s;
14027+ struct cvmx_pip_dec_ipsecx_s cn30xx;
14028+ struct cvmx_pip_dec_ipsecx_s cn31xx;
14029+ struct cvmx_pip_dec_ipsecx_s cn38xx;
14030+ struct cvmx_pip_dec_ipsecx_s cn38xxp2;
14031+ struct cvmx_pip_dec_ipsecx_s cn50xx;
14032+ struct cvmx_pip_dec_ipsecx_s cn52xx;
14033+ struct cvmx_pip_dec_ipsecx_s cn52xxp1;
14034+ struct cvmx_pip_dec_ipsecx_s cn56xx;
14035+ struct cvmx_pip_dec_ipsecx_s cn56xxp1;
14036+ struct cvmx_pip_dec_ipsecx_s cn58xx;
14037+ struct cvmx_pip_dec_ipsecx_s cn58xxp1;
14038+};
14039+
14040+union cvmx_pip_dsa_src_grp {
14041+ uint64_t u64;
14042+ struct cvmx_pip_dsa_src_grp_s {
14043+ uint64_t map15:4;
14044+ uint64_t map14:4;
14045+ uint64_t map13:4;
14046+ uint64_t map12:4;
14047+ uint64_t map11:4;
14048+ uint64_t map10:4;
14049+ uint64_t map9:4;
14050+ uint64_t map8:4;
14051+ uint64_t map7:4;
14052+ uint64_t map6:4;
14053+ uint64_t map5:4;
14054+ uint64_t map4:4;
14055+ uint64_t map3:4;
14056+ uint64_t map2:4;
14057+ uint64_t map1:4;
14058+ uint64_t map0:4;
14059+ } s;
14060+ struct cvmx_pip_dsa_src_grp_s cn52xx;
14061+ struct cvmx_pip_dsa_src_grp_s cn52xxp1;
14062+ struct cvmx_pip_dsa_src_grp_s cn56xx;
14063+};
14064+
14065+union cvmx_pip_dsa_vid_grp {
14066+ uint64_t u64;
14067+ struct cvmx_pip_dsa_vid_grp_s {
14068+ uint64_t map15:4;
14069+ uint64_t map14:4;
14070+ uint64_t map13:4;
14071+ uint64_t map12:4;
14072+ uint64_t map11:4;
14073+ uint64_t map10:4;
14074+ uint64_t map9:4;
14075+ uint64_t map8:4;
14076+ uint64_t map7:4;
14077+ uint64_t map6:4;
14078+ uint64_t map5:4;
14079+ uint64_t map4:4;
14080+ uint64_t map3:4;
14081+ uint64_t map2:4;
14082+ uint64_t map1:4;
14083+ uint64_t map0:4;
14084+ } s;
14085+ struct cvmx_pip_dsa_vid_grp_s cn52xx;
14086+ struct cvmx_pip_dsa_vid_grp_s cn52xxp1;
14087+ struct cvmx_pip_dsa_vid_grp_s cn56xx;
14088+};
14089+
14090+union cvmx_pip_frm_len_chkx {
14091+ uint64_t u64;
14092+ struct cvmx_pip_frm_len_chkx_s {
14093+ uint64_t reserved_32_63:32;
14094+ uint64_t maxlen:16;
14095+ uint64_t minlen:16;
14096+ } s;
14097+ struct cvmx_pip_frm_len_chkx_s cn50xx;
14098+ struct cvmx_pip_frm_len_chkx_s cn52xx;
14099+ struct cvmx_pip_frm_len_chkx_s cn52xxp1;
14100+ struct cvmx_pip_frm_len_chkx_s cn56xx;
14101+ struct cvmx_pip_frm_len_chkx_s cn56xxp1;
14102+};
14103+
14104+union cvmx_pip_gbl_cfg {
14105+ uint64_t u64;
14106+ struct cvmx_pip_gbl_cfg_s {
14107+ uint64_t reserved_19_63:45;
14108+ uint64_t tag_syn:1;
14109+ uint64_t ip6_udp:1;
14110+ uint64_t max_l2:1;
14111+ uint64_t reserved_11_15:5;
14112+ uint64_t raw_shf:3;
14113+ uint64_t reserved_3_7:5;
14114+ uint64_t nip_shf:3;
14115+ } s;
14116+ struct cvmx_pip_gbl_cfg_s cn30xx;
14117+ struct cvmx_pip_gbl_cfg_s cn31xx;
14118+ struct cvmx_pip_gbl_cfg_s cn38xx;
14119+ struct cvmx_pip_gbl_cfg_s cn38xxp2;
14120+ struct cvmx_pip_gbl_cfg_s cn50xx;
14121+ struct cvmx_pip_gbl_cfg_s cn52xx;
14122+ struct cvmx_pip_gbl_cfg_s cn52xxp1;
14123+ struct cvmx_pip_gbl_cfg_s cn56xx;
14124+ struct cvmx_pip_gbl_cfg_s cn56xxp1;
14125+ struct cvmx_pip_gbl_cfg_s cn58xx;
14126+ struct cvmx_pip_gbl_cfg_s cn58xxp1;
14127+};
14128+
14129+union cvmx_pip_gbl_ctl {
14130+ uint64_t u64;
14131+ struct cvmx_pip_gbl_ctl_s {
14132+ uint64_t reserved_27_63:37;
14133+ uint64_t dsa_grp_tvid:1;
14134+ uint64_t dsa_grp_scmd:1;
14135+ uint64_t dsa_grp_sid:1;
14136+ uint64_t reserved_21_23:3;
14137+ uint64_t ring_en:1;
14138+ uint64_t reserved_17_19:3;
14139+ uint64_t ignrs:1;
14140+ uint64_t vs_wqe:1;
14141+ uint64_t vs_qos:1;
14142+ uint64_t l2_mal:1;
14143+ uint64_t tcp_flag:1;
14144+ uint64_t l4_len:1;
14145+ uint64_t l4_chk:1;
14146+ uint64_t l4_prt:1;
14147+ uint64_t l4_mal:1;
14148+ uint64_t reserved_6_7:2;
14149+ uint64_t ip6_eext:2;
14150+ uint64_t ip4_opts:1;
14151+ uint64_t ip_hop:1;
14152+ uint64_t ip_mal:1;
14153+ uint64_t ip_chk:1;
14154+ } s;
14155+ struct cvmx_pip_gbl_ctl_cn30xx {
14156+ uint64_t reserved_17_63:47;
14157+ uint64_t ignrs:1;
14158+ uint64_t vs_wqe:1;
14159+ uint64_t vs_qos:1;
14160+ uint64_t l2_mal:1;
14161+ uint64_t tcp_flag:1;
14162+ uint64_t l4_len:1;
14163+ uint64_t l4_chk:1;
14164+ uint64_t l4_prt:1;
14165+ uint64_t l4_mal:1;
14166+ uint64_t reserved_6_7:2;
14167+ uint64_t ip6_eext:2;
14168+ uint64_t ip4_opts:1;
14169+ uint64_t ip_hop:1;
14170+ uint64_t ip_mal:1;
14171+ uint64_t ip_chk:1;
14172+ } cn30xx;
14173+ struct cvmx_pip_gbl_ctl_cn30xx cn31xx;
14174+ struct cvmx_pip_gbl_ctl_cn30xx cn38xx;
14175+ struct cvmx_pip_gbl_ctl_cn30xx cn38xxp2;
14176+ struct cvmx_pip_gbl_ctl_cn30xx cn50xx;
14177+ struct cvmx_pip_gbl_ctl_s cn52xx;
14178+ struct cvmx_pip_gbl_ctl_s cn52xxp1;
14179+ struct cvmx_pip_gbl_ctl_s cn56xx;
14180+ struct cvmx_pip_gbl_ctl_cn56xxp1 {
14181+ uint64_t reserved_21_63:43;
14182+ uint64_t ring_en:1;
14183+ uint64_t reserved_17_19:3;
14184+ uint64_t ignrs:1;
14185+ uint64_t vs_wqe:1;
14186+ uint64_t vs_qos:1;
14187+ uint64_t l2_mal:1;
14188+ uint64_t tcp_flag:1;
14189+ uint64_t l4_len:1;
14190+ uint64_t l4_chk:1;
14191+ uint64_t l4_prt:1;
14192+ uint64_t l4_mal:1;
14193+ uint64_t reserved_6_7:2;
14194+ uint64_t ip6_eext:2;
14195+ uint64_t ip4_opts:1;
14196+ uint64_t ip_hop:1;
14197+ uint64_t ip_mal:1;
14198+ uint64_t ip_chk:1;
14199+ } cn56xxp1;
14200+ struct cvmx_pip_gbl_ctl_cn30xx cn58xx;
14201+ struct cvmx_pip_gbl_ctl_cn30xx cn58xxp1;
14202+};
14203+
14204+union cvmx_pip_hg_pri_qos {
14205+ uint64_t u64;
14206+ struct cvmx_pip_hg_pri_qos_s {
14207+ uint64_t reserved_11_63:53;
14208+ uint64_t qos:3;
14209+ uint64_t reserved_6_7:2;
14210+ uint64_t pri:6;
14211+ } s;
14212+ struct cvmx_pip_hg_pri_qos_s cn52xx;
14213+ struct cvmx_pip_hg_pri_qos_s cn52xxp1;
14214+ struct cvmx_pip_hg_pri_qos_s cn56xx;
14215+};
14216+
14217+union cvmx_pip_int_en {
14218+ uint64_t u64;
14219+ struct cvmx_pip_int_en_s {
14220+ uint64_t reserved_13_63:51;
14221+ uint64_t punyerr:1;
14222+ uint64_t lenerr:1;
14223+ uint64_t maxerr:1;
14224+ uint64_t minerr:1;
14225+ uint64_t beperr:1;
14226+ uint64_t feperr:1;
14227+ uint64_t todoovr:1;
14228+ uint64_t skprunt:1;
14229+ uint64_t badtag:1;
14230+ uint64_t prtnxa:1;
14231+ uint64_t bckprs:1;
14232+ uint64_t crcerr:1;
14233+ uint64_t pktdrp:1;
14234+ } s;
14235+ struct cvmx_pip_int_en_cn30xx {
14236+ uint64_t reserved_9_63:55;
14237+ uint64_t beperr:1;
14238+ uint64_t feperr:1;
14239+ uint64_t todoovr:1;
14240+ uint64_t skprunt:1;
14241+ uint64_t badtag:1;
14242+ uint64_t prtnxa:1;
14243+ uint64_t bckprs:1;
14244+ uint64_t crcerr:1;
14245+ uint64_t pktdrp:1;
14246+ } cn30xx;
14247+ struct cvmx_pip_int_en_cn30xx cn31xx;
14248+ struct cvmx_pip_int_en_cn30xx cn38xx;
14249+ struct cvmx_pip_int_en_cn30xx cn38xxp2;
14250+ struct cvmx_pip_int_en_cn50xx {
14251+ uint64_t reserved_12_63:52;
14252+ uint64_t lenerr:1;
14253+ uint64_t maxerr:1;
14254+ uint64_t minerr:1;
14255+ uint64_t beperr:1;
14256+ uint64_t feperr:1;
14257+ uint64_t todoovr:1;
14258+ uint64_t skprunt:1;
14259+ uint64_t badtag:1;
14260+ uint64_t prtnxa:1;
14261+ uint64_t bckprs:1;
14262+ uint64_t reserved_1_1:1;
14263+ uint64_t pktdrp:1;
14264+ } cn50xx;
14265+ struct cvmx_pip_int_en_cn52xx {
14266+ uint64_t reserved_13_63:51;
14267+ uint64_t punyerr:1;
14268+ uint64_t lenerr:1;
14269+ uint64_t maxerr:1;
14270+ uint64_t minerr:1;
14271+ uint64_t beperr:1;
14272+ uint64_t feperr:1;
14273+ uint64_t todoovr:1;
14274+ uint64_t skprunt:1;
14275+ uint64_t badtag:1;
14276+ uint64_t prtnxa:1;
14277+ uint64_t bckprs:1;
14278+ uint64_t reserved_1_1:1;
14279+ uint64_t pktdrp:1;
14280+ } cn52xx;
14281+ struct cvmx_pip_int_en_cn52xx cn52xxp1;
14282+ struct cvmx_pip_int_en_s cn56xx;
14283+ struct cvmx_pip_int_en_cn56xxp1 {
14284+ uint64_t reserved_12_63:52;
14285+ uint64_t lenerr:1;
14286+ uint64_t maxerr:1;
14287+ uint64_t minerr:1;
14288+ uint64_t beperr:1;
14289+ uint64_t feperr:1;
14290+ uint64_t todoovr:1;
14291+ uint64_t skprunt:1;
14292+ uint64_t badtag:1;
14293+ uint64_t prtnxa:1;
14294+ uint64_t bckprs:1;
14295+ uint64_t crcerr:1;
14296+ uint64_t pktdrp:1;
14297+ } cn56xxp1;
14298+ struct cvmx_pip_int_en_cn58xx {
14299+ uint64_t reserved_13_63:51;
14300+ uint64_t punyerr:1;
14301+ uint64_t reserved_9_11:3;
14302+ uint64_t beperr:1;
14303+ uint64_t feperr:1;
14304+ uint64_t todoovr:1;
14305+ uint64_t skprunt:1;
14306+ uint64_t badtag:1;
14307+ uint64_t prtnxa:1;
14308+ uint64_t bckprs:1;
14309+ uint64_t crcerr:1;
14310+ uint64_t pktdrp:1;
14311+ } cn58xx;
14312+ struct cvmx_pip_int_en_cn30xx cn58xxp1;
14313+};
14314+
14315+union cvmx_pip_int_reg {
14316+ uint64_t u64;
14317+ struct cvmx_pip_int_reg_s {
14318+ uint64_t reserved_13_63:51;
14319+ uint64_t punyerr:1;
14320+ uint64_t lenerr:1;
14321+ uint64_t maxerr:1;
14322+ uint64_t minerr:1;
14323+ uint64_t beperr:1;
14324+ uint64_t feperr:1;
14325+ uint64_t todoovr:1;
14326+ uint64_t skprunt:1;
14327+ uint64_t badtag:1;
14328+ uint64_t prtnxa:1;
14329+ uint64_t bckprs:1;
14330+ uint64_t crcerr:1;
14331+ uint64_t pktdrp:1;
14332+ } s;
14333+ struct cvmx_pip_int_reg_cn30xx {
14334+ uint64_t reserved_9_63:55;
14335+ uint64_t beperr:1;
14336+ uint64_t feperr:1;
14337+ uint64_t todoovr:1;
14338+ uint64_t skprunt:1;
14339+ uint64_t badtag:1;
14340+ uint64_t prtnxa:1;
14341+ uint64_t bckprs:1;
14342+ uint64_t crcerr:1;
14343+ uint64_t pktdrp:1;
14344+ } cn30xx;
14345+ struct cvmx_pip_int_reg_cn30xx cn31xx;
14346+ struct cvmx_pip_int_reg_cn30xx cn38xx;
14347+ struct cvmx_pip_int_reg_cn30xx cn38xxp2;
14348+ struct cvmx_pip_int_reg_cn50xx {
14349+ uint64_t reserved_12_63:52;
14350+ uint64_t lenerr:1;
14351+ uint64_t maxerr:1;
14352+ uint64_t minerr:1;
14353+ uint64_t beperr:1;
14354+ uint64_t feperr:1;
14355+ uint64_t todoovr:1;
14356+ uint64_t skprunt:1;
14357+ uint64_t badtag:1;
14358+ uint64_t prtnxa:1;
14359+ uint64_t bckprs:1;
14360+ uint64_t reserved_1_1:1;
14361+ uint64_t pktdrp:1;
14362+ } cn50xx;
14363+ struct cvmx_pip_int_reg_cn52xx {
14364+ uint64_t reserved_13_63:51;
14365+ uint64_t punyerr:1;
14366+ uint64_t lenerr:1;
14367+ uint64_t maxerr:1;
14368+ uint64_t minerr:1;
14369+ uint64_t beperr:1;
14370+ uint64_t feperr:1;
14371+ uint64_t todoovr:1;
14372+ uint64_t skprunt:1;
14373+ uint64_t badtag:1;
14374+ uint64_t prtnxa:1;
14375+ uint64_t bckprs:1;
14376+ uint64_t reserved_1_1:1;
14377+ uint64_t pktdrp:1;
14378+ } cn52xx;
14379+ struct cvmx_pip_int_reg_cn52xx cn52xxp1;
14380+ struct cvmx_pip_int_reg_s cn56xx;
14381+ struct cvmx_pip_int_reg_cn56xxp1 {
14382+ uint64_t reserved_12_63:52;
14383+ uint64_t lenerr:1;
14384+ uint64_t maxerr:1;
14385+ uint64_t minerr:1;
14386+ uint64_t beperr:1;
14387+ uint64_t feperr:1;
14388+ uint64_t todoovr:1;
14389+ uint64_t skprunt:1;
14390+ uint64_t badtag:1;
14391+ uint64_t prtnxa:1;
14392+ uint64_t bckprs:1;
14393+ uint64_t crcerr:1;
14394+ uint64_t pktdrp:1;
14395+ } cn56xxp1;
14396+ struct cvmx_pip_int_reg_cn58xx {
14397+ uint64_t reserved_13_63:51;
14398+ uint64_t punyerr:1;
14399+ uint64_t reserved_9_11:3;
14400+ uint64_t beperr:1;
14401+ uint64_t feperr:1;
14402+ uint64_t todoovr:1;
14403+ uint64_t skprunt:1;
14404+ uint64_t badtag:1;
14405+ uint64_t prtnxa:1;
14406+ uint64_t bckprs:1;
14407+ uint64_t crcerr:1;
14408+ uint64_t pktdrp:1;
14409+ } cn58xx;
14410+ struct cvmx_pip_int_reg_cn30xx cn58xxp1;
14411+};
14412+
14413+union cvmx_pip_ip_offset {
14414+ uint64_t u64;
14415+ struct cvmx_pip_ip_offset_s {
14416+ uint64_t reserved_3_63:61;
14417+ uint64_t offset:3;
14418+ } s;
14419+ struct cvmx_pip_ip_offset_s cn30xx;
14420+ struct cvmx_pip_ip_offset_s cn31xx;
14421+ struct cvmx_pip_ip_offset_s cn38xx;
14422+ struct cvmx_pip_ip_offset_s cn38xxp2;
14423+ struct cvmx_pip_ip_offset_s cn50xx;
14424+ struct cvmx_pip_ip_offset_s cn52xx;
14425+ struct cvmx_pip_ip_offset_s cn52xxp1;
14426+ struct cvmx_pip_ip_offset_s cn56xx;
14427+ struct cvmx_pip_ip_offset_s cn56xxp1;
14428+ struct cvmx_pip_ip_offset_s cn58xx;
14429+ struct cvmx_pip_ip_offset_s cn58xxp1;
14430+};
14431+
14432+union cvmx_pip_prt_cfgx {
14433+ uint64_t u64;
14434+ struct cvmx_pip_prt_cfgx_s {
14435+ uint64_t reserved_53_63:11;
14436+ uint64_t pad_len:1;
14437+ uint64_t vlan_len:1;
14438+ uint64_t lenerr_en:1;
14439+ uint64_t maxerr_en:1;
14440+ uint64_t minerr_en:1;
14441+ uint64_t grp_wat_47:4;
14442+ uint64_t qos_wat_47:4;
14443+ uint64_t reserved_37_39:3;
14444+ uint64_t rawdrp:1;
14445+ uint64_t tag_inc:2;
14446+ uint64_t dyn_rs:1;
14447+ uint64_t inst_hdr:1;
14448+ uint64_t grp_wat:4;
14449+ uint64_t hg_qos:1;
14450+ uint64_t qos:3;
14451+ uint64_t qos_wat:4;
14452+ uint64_t qos_vsel:1;
14453+ uint64_t qos_vod:1;
14454+ uint64_t qos_diff:1;
14455+ uint64_t qos_vlan:1;
14456+ uint64_t reserved_13_15:3;
14457+ uint64_t crc_en:1;
14458+ uint64_t higig_en:1;
14459+ uint64_t dsa_en:1;
14460+ uint64_t mode:2;
14461+ uint64_t reserved_7_7:1;
14462+ uint64_t skip:7;
14463+ } s;
14464+ struct cvmx_pip_prt_cfgx_cn30xx {
14465+ uint64_t reserved_37_63:27;
14466+ uint64_t rawdrp:1;
14467+ uint64_t tag_inc:2;
14468+ uint64_t dyn_rs:1;
14469+ uint64_t inst_hdr:1;
14470+ uint64_t grp_wat:4;
14471+ uint64_t reserved_27_27:1;
14472+ uint64_t qos:3;
14473+ uint64_t qos_wat:4;
14474+ uint64_t reserved_18_19:2;
14475+ uint64_t qos_diff:1;
14476+ uint64_t qos_vlan:1;
14477+ uint64_t reserved_10_15:6;
14478+ uint64_t mode:2;
14479+ uint64_t reserved_7_7:1;
14480+ uint64_t skip:7;
14481+ } cn30xx;
14482+ struct cvmx_pip_prt_cfgx_cn30xx cn31xx;
14483+ struct cvmx_pip_prt_cfgx_cn38xx {
14484+ uint64_t reserved_37_63:27;
14485+ uint64_t rawdrp:1;
14486+ uint64_t tag_inc:2;
14487+ uint64_t dyn_rs:1;
14488+ uint64_t inst_hdr:1;
14489+ uint64_t grp_wat:4;
14490+ uint64_t reserved_27_27:1;
14491+ uint64_t qos:3;
14492+ uint64_t qos_wat:4;
14493+ uint64_t reserved_18_19:2;
14494+ uint64_t qos_diff:1;
14495+ uint64_t qos_vlan:1;
14496+ uint64_t reserved_13_15:3;
14497+ uint64_t crc_en:1;
14498+ uint64_t reserved_10_11:2;
14499+ uint64_t mode:2;
14500+ uint64_t reserved_7_7:1;
14501+ uint64_t skip:7;
14502+ } cn38xx;
14503+ struct cvmx_pip_prt_cfgx_cn38xx cn38xxp2;
14504+ struct cvmx_pip_prt_cfgx_cn50xx {
14505+ uint64_t reserved_53_63:11;
14506+ uint64_t pad_len:1;
14507+ uint64_t vlan_len:1;
14508+ uint64_t lenerr_en:1;
14509+ uint64_t maxerr_en:1;
14510+ uint64_t minerr_en:1;
14511+ uint64_t grp_wat_47:4;
14512+ uint64_t qos_wat_47:4;
14513+ uint64_t reserved_37_39:3;
14514+ uint64_t rawdrp:1;
14515+ uint64_t tag_inc:2;
14516+ uint64_t dyn_rs:1;
14517+ uint64_t inst_hdr:1;
14518+ uint64_t grp_wat:4;
14519+ uint64_t reserved_27_27:1;
14520+ uint64_t qos:3;
14521+ uint64_t qos_wat:4;
14522+ uint64_t reserved_19_19:1;
14523+ uint64_t qos_vod:1;
14524+ uint64_t qos_diff:1;
14525+ uint64_t qos_vlan:1;
14526+ uint64_t reserved_13_15:3;
14527+ uint64_t crc_en:1;
14528+ uint64_t reserved_10_11:2;
14529+ uint64_t mode:2;
14530+ uint64_t reserved_7_7:1;
14531+ uint64_t skip:7;
14532+ } cn50xx;
14533+ struct cvmx_pip_prt_cfgx_s cn52xx;
14534+ struct cvmx_pip_prt_cfgx_s cn52xxp1;
14535+ struct cvmx_pip_prt_cfgx_s cn56xx;
14536+ struct cvmx_pip_prt_cfgx_cn50xx cn56xxp1;
14537+ struct cvmx_pip_prt_cfgx_cn58xx {
14538+ uint64_t reserved_37_63:27;
14539+ uint64_t rawdrp:1;
14540+ uint64_t tag_inc:2;
14541+ uint64_t dyn_rs:1;
14542+ uint64_t inst_hdr:1;
14543+ uint64_t grp_wat:4;
14544+ uint64_t reserved_27_27:1;
14545+ uint64_t qos:3;
14546+ uint64_t qos_wat:4;
14547+ uint64_t reserved_19_19:1;
14548+ uint64_t qos_vod:1;
14549+ uint64_t qos_diff:1;
14550+ uint64_t qos_vlan:1;
14551+ uint64_t reserved_13_15:3;
14552+ uint64_t crc_en:1;
14553+ uint64_t reserved_10_11:2;
14554+ uint64_t mode:2;
14555+ uint64_t reserved_7_7:1;
14556+ uint64_t skip:7;
14557+ } cn58xx;
14558+ struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1;
14559+};
14560+
14561+union cvmx_pip_prt_tagx {
14562+ uint64_t u64;
14563+ struct cvmx_pip_prt_tagx_s {
14564+ uint64_t reserved_40_63:24;
14565+ uint64_t grptagbase:4;
14566+ uint64_t grptagmask:4;
14567+ uint64_t grptag:1;
14568+ uint64_t grptag_mskip:1;
14569+ uint64_t tag_mode:2;
14570+ uint64_t inc_vs:2;
14571+ uint64_t inc_vlan:1;
14572+ uint64_t inc_prt_flag:1;
14573+ uint64_t ip6_dprt_flag:1;
14574+ uint64_t ip4_dprt_flag:1;
14575+ uint64_t ip6_sprt_flag:1;
14576+ uint64_t ip4_sprt_flag:1;
14577+ uint64_t ip6_nxth_flag:1;
14578+ uint64_t ip4_pctl_flag:1;
14579+ uint64_t ip6_dst_flag:1;
14580+ uint64_t ip4_dst_flag:1;
14581+ uint64_t ip6_src_flag:1;
14582+ uint64_t ip4_src_flag:1;
14583+ uint64_t tcp6_tag_type:2;
14584+ uint64_t tcp4_tag_type:2;
14585+ uint64_t ip6_tag_type:2;
14586+ uint64_t ip4_tag_type:2;
14587+ uint64_t non_tag_type:2;
14588+ uint64_t grp:4;
14589+ } s;
14590+ struct cvmx_pip_prt_tagx_cn30xx {
14591+ uint64_t reserved_40_63:24;
14592+ uint64_t grptagbase:4;
14593+ uint64_t grptagmask:4;
14594+ uint64_t grptag:1;
14595+ uint64_t reserved_30_30:1;
14596+ uint64_t tag_mode:2;
14597+ uint64_t inc_vs:2;
14598+ uint64_t inc_vlan:1;
14599+ uint64_t inc_prt_flag:1;
14600+ uint64_t ip6_dprt_flag:1;
14601+ uint64_t ip4_dprt_flag:1;
14602+ uint64_t ip6_sprt_flag:1;
14603+ uint64_t ip4_sprt_flag:1;
14604+ uint64_t ip6_nxth_flag:1;
14605+ uint64_t ip4_pctl_flag:1;
14606+ uint64_t ip6_dst_flag:1;
14607+ uint64_t ip4_dst_flag:1;
14608+ uint64_t ip6_src_flag:1;
14609+ uint64_t ip4_src_flag:1;
14610+ uint64_t tcp6_tag_type:2;
14611+ uint64_t tcp4_tag_type:2;
14612+ uint64_t ip6_tag_type:2;
14613+ uint64_t ip4_tag_type:2;
14614+ uint64_t non_tag_type:2;
14615+ uint64_t grp:4;
14616+ } cn30xx;
14617+ struct cvmx_pip_prt_tagx_cn30xx cn31xx;
14618+ struct cvmx_pip_prt_tagx_cn30xx cn38xx;
14619+ struct cvmx_pip_prt_tagx_cn30xx cn38xxp2;
14620+ struct cvmx_pip_prt_tagx_s cn50xx;
14621+ struct cvmx_pip_prt_tagx_s cn52xx;
14622+ struct cvmx_pip_prt_tagx_s cn52xxp1;
14623+ struct cvmx_pip_prt_tagx_s cn56xx;
14624+ struct cvmx_pip_prt_tagx_s cn56xxp1;
14625+ struct cvmx_pip_prt_tagx_cn30xx cn58xx;
14626+ struct cvmx_pip_prt_tagx_cn30xx cn58xxp1;
14627+};
14628+
14629+union cvmx_pip_qos_diffx {
14630+ uint64_t u64;
14631+ struct cvmx_pip_qos_diffx_s {
14632+ uint64_t reserved_3_63:61;
14633+ uint64_t qos:3;
14634+ } s;
14635+ struct cvmx_pip_qos_diffx_s cn30xx;
14636+ struct cvmx_pip_qos_diffx_s cn31xx;
14637+ struct cvmx_pip_qos_diffx_s cn38xx;
14638+ struct cvmx_pip_qos_diffx_s cn38xxp2;
14639+ struct cvmx_pip_qos_diffx_s cn50xx;
14640+ struct cvmx_pip_qos_diffx_s cn52xx;
14641+ struct cvmx_pip_qos_diffx_s cn52xxp1;
14642+ struct cvmx_pip_qos_diffx_s cn56xx;
14643+ struct cvmx_pip_qos_diffx_s cn56xxp1;
14644+ struct cvmx_pip_qos_diffx_s cn58xx;
14645+ struct cvmx_pip_qos_diffx_s cn58xxp1;
14646+};
14647+
14648+union cvmx_pip_qos_vlanx {
14649+ uint64_t u64;
14650+ struct cvmx_pip_qos_vlanx_s {
14651+ uint64_t reserved_7_63:57;
14652+ uint64_t qos1:3;
14653+ uint64_t reserved_3_3:1;
14654+ uint64_t qos:3;
14655+ } s;
14656+ struct cvmx_pip_qos_vlanx_cn30xx {
14657+ uint64_t reserved_3_63:61;
14658+ uint64_t qos:3;
14659+ } cn30xx;
14660+ struct cvmx_pip_qos_vlanx_cn30xx cn31xx;
14661+ struct cvmx_pip_qos_vlanx_cn30xx cn38xx;
14662+ struct cvmx_pip_qos_vlanx_cn30xx cn38xxp2;
14663+ struct cvmx_pip_qos_vlanx_cn30xx cn50xx;
14664+ struct cvmx_pip_qos_vlanx_s cn52xx;
14665+ struct cvmx_pip_qos_vlanx_s cn52xxp1;
14666+ struct cvmx_pip_qos_vlanx_s cn56xx;
14667+ struct cvmx_pip_qos_vlanx_cn30xx cn56xxp1;
14668+ struct cvmx_pip_qos_vlanx_cn30xx cn58xx;
14669+ struct cvmx_pip_qos_vlanx_cn30xx cn58xxp1;
14670+};
14671+
14672+union cvmx_pip_qos_watchx {
14673+ uint64_t u64;
14674+ struct cvmx_pip_qos_watchx_s {
14675+ uint64_t reserved_48_63:16;
14676+ uint64_t mask:16;
14677+ uint64_t reserved_28_31:4;
14678+ uint64_t grp:4;
14679+ uint64_t reserved_23_23:1;
14680+ uint64_t qos:3;
14681+ uint64_t reserved_19_19:1;
14682+ uint64_t match_type:3;
14683+ uint64_t match_value:16;
14684+ } s;
14685+ struct cvmx_pip_qos_watchx_cn30xx {
14686+ uint64_t reserved_48_63:16;
14687+ uint64_t mask:16;
14688+ uint64_t reserved_28_31:4;
14689+ uint64_t grp:4;
14690+ uint64_t reserved_23_23:1;
14691+ uint64_t qos:3;
14692+ uint64_t reserved_18_19:2;
14693+ uint64_t match_type:2;
14694+ uint64_t match_value:16;
14695+ } cn30xx;
14696+ struct cvmx_pip_qos_watchx_cn30xx cn31xx;
14697+ struct cvmx_pip_qos_watchx_cn30xx cn38xx;
14698+ struct cvmx_pip_qos_watchx_cn30xx cn38xxp2;
14699+ struct cvmx_pip_qos_watchx_s cn50xx;
14700+ struct cvmx_pip_qos_watchx_s cn52xx;
14701+ struct cvmx_pip_qos_watchx_s cn52xxp1;
14702+ struct cvmx_pip_qos_watchx_s cn56xx;
14703+ struct cvmx_pip_qos_watchx_s cn56xxp1;
14704+ struct cvmx_pip_qos_watchx_cn30xx cn58xx;
14705+ struct cvmx_pip_qos_watchx_cn30xx cn58xxp1;
14706+};
14707+
14708+union cvmx_pip_raw_word {
14709+ uint64_t u64;
14710+ struct cvmx_pip_raw_word_s {
14711+ uint64_t reserved_56_63:8;
14712+ uint64_t word:56;
14713+ } s;
14714+ struct cvmx_pip_raw_word_s cn30xx;
14715+ struct cvmx_pip_raw_word_s cn31xx;
14716+ struct cvmx_pip_raw_word_s cn38xx;
14717+ struct cvmx_pip_raw_word_s cn38xxp2;
14718+ struct cvmx_pip_raw_word_s cn50xx;
14719+ struct cvmx_pip_raw_word_s cn52xx;
14720+ struct cvmx_pip_raw_word_s cn52xxp1;
14721+ struct cvmx_pip_raw_word_s cn56xx;
14722+ struct cvmx_pip_raw_word_s cn56xxp1;
14723+ struct cvmx_pip_raw_word_s cn58xx;
14724+ struct cvmx_pip_raw_word_s cn58xxp1;
14725+};
14726+
14727+union cvmx_pip_sft_rst {
14728+ uint64_t u64;
14729+ struct cvmx_pip_sft_rst_s {
14730+ uint64_t reserved_1_63:63;
14731+ uint64_t rst:1;
14732+ } s;
14733+ struct cvmx_pip_sft_rst_s cn30xx;
14734+ struct cvmx_pip_sft_rst_s cn31xx;
14735+ struct cvmx_pip_sft_rst_s cn38xx;
14736+ struct cvmx_pip_sft_rst_s cn50xx;
14737+ struct cvmx_pip_sft_rst_s cn52xx;
14738+ struct cvmx_pip_sft_rst_s cn52xxp1;
14739+ struct cvmx_pip_sft_rst_s cn56xx;
14740+ struct cvmx_pip_sft_rst_s cn56xxp1;
14741+ struct cvmx_pip_sft_rst_s cn58xx;
14742+ struct cvmx_pip_sft_rst_s cn58xxp1;
14743+};
14744+
14745+union cvmx_pip_stat0_prtx {
14746+ uint64_t u64;
14747+ struct cvmx_pip_stat0_prtx_s {
14748+ uint64_t drp_pkts:32;
14749+ uint64_t drp_octs:32;
14750+ } s;
14751+ struct cvmx_pip_stat0_prtx_s cn30xx;
14752+ struct cvmx_pip_stat0_prtx_s cn31xx;
14753+ struct cvmx_pip_stat0_prtx_s cn38xx;
14754+ struct cvmx_pip_stat0_prtx_s cn38xxp2;
14755+ struct cvmx_pip_stat0_prtx_s cn50xx;
14756+ struct cvmx_pip_stat0_prtx_s cn52xx;
14757+ struct cvmx_pip_stat0_prtx_s cn52xxp1;
14758+ struct cvmx_pip_stat0_prtx_s cn56xx;
14759+ struct cvmx_pip_stat0_prtx_s cn56xxp1;
14760+ struct cvmx_pip_stat0_prtx_s cn58xx;
14761+ struct cvmx_pip_stat0_prtx_s cn58xxp1;
14762+};
14763+
14764+union cvmx_pip_stat1_prtx {
14765+ uint64_t u64;
14766+ struct cvmx_pip_stat1_prtx_s {
14767+ uint64_t reserved_48_63:16;
14768+ uint64_t octs:48;
14769+ } s;
14770+ struct cvmx_pip_stat1_prtx_s cn30xx;
14771+ struct cvmx_pip_stat1_prtx_s cn31xx;
14772+ struct cvmx_pip_stat1_prtx_s cn38xx;
14773+ struct cvmx_pip_stat1_prtx_s cn38xxp2;
14774+ struct cvmx_pip_stat1_prtx_s cn50xx;
14775+ struct cvmx_pip_stat1_prtx_s cn52xx;
14776+ struct cvmx_pip_stat1_prtx_s cn52xxp1;
14777+ struct cvmx_pip_stat1_prtx_s cn56xx;
14778+ struct cvmx_pip_stat1_prtx_s cn56xxp1;
14779+ struct cvmx_pip_stat1_prtx_s cn58xx;
14780+ struct cvmx_pip_stat1_prtx_s cn58xxp1;
14781+};
14782+
14783+union cvmx_pip_stat2_prtx {
14784+ uint64_t u64;
14785+ struct cvmx_pip_stat2_prtx_s {
14786+ uint64_t pkts:32;
14787+ uint64_t raw:32;
14788+ } s;
14789+ struct cvmx_pip_stat2_prtx_s cn30xx;
14790+ struct cvmx_pip_stat2_prtx_s cn31xx;
14791+ struct cvmx_pip_stat2_prtx_s cn38xx;
14792+ struct cvmx_pip_stat2_prtx_s cn38xxp2;
14793+ struct cvmx_pip_stat2_prtx_s cn50xx;
14794+ struct cvmx_pip_stat2_prtx_s cn52xx;
14795+ struct cvmx_pip_stat2_prtx_s cn52xxp1;
14796+ struct cvmx_pip_stat2_prtx_s cn56xx;
14797+ struct cvmx_pip_stat2_prtx_s cn56xxp1;
14798+ struct cvmx_pip_stat2_prtx_s cn58xx;
14799+ struct cvmx_pip_stat2_prtx_s cn58xxp1;
14800+};
14801+
14802+union cvmx_pip_stat3_prtx {
14803+ uint64_t u64;
14804+ struct cvmx_pip_stat3_prtx_s {
14805+ uint64_t bcst:32;
14806+ uint64_t mcst:32;
14807+ } s;
14808+ struct cvmx_pip_stat3_prtx_s cn30xx;
14809+ struct cvmx_pip_stat3_prtx_s cn31xx;
14810+ struct cvmx_pip_stat3_prtx_s cn38xx;
14811+ struct cvmx_pip_stat3_prtx_s cn38xxp2;
14812+ struct cvmx_pip_stat3_prtx_s cn50xx;
14813+ struct cvmx_pip_stat3_prtx_s cn52xx;
14814+ struct cvmx_pip_stat3_prtx_s cn52xxp1;
14815+ struct cvmx_pip_stat3_prtx_s cn56xx;
14816+ struct cvmx_pip_stat3_prtx_s cn56xxp1;
14817+ struct cvmx_pip_stat3_prtx_s cn58xx;
14818+ struct cvmx_pip_stat3_prtx_s cn58xxp1;
14819+};
14820+
14821+union cvmx_pip_stat4_prtx {
14822+ uint64_t u64;
14823+ struct cvmx_pip_stat4_prtx_s {
14824+ uint64_t h65to127:32;
14825+ uint64_t h64:32;
14826+ } s;
14827+ struct cvmx_pip_stat4_prtx_s cn30xx;
14828+ struct cvmx_pip_stat4_prtx_s cn31xx;
14829+ struct cvmx_pip_stat4_prtx_s cn38xx;
14830+ struct cvmx_pip_stat4_prtx_s cn38xxp2;
14831+ struct cvmx_pip_stat4_prtx_s cn50xx;
14832+ struct cvmx_pip_stat4_prtx_s cn52xx;
14833+ struct cvmx_pip_stat4_prtx_s cn52xxp1;
14834+ struct cvmx_pip_stat4_prtx_s cn56xx;
14835+ struct cvmx_pip_stat4_prtx_s cn56xxp1;
14836+ struct cvmx_pip_stat4_prtx_s cn58xx;
14837+ struct cvmx_pip_stat4_prtx_s cn58xxp1;
14838+};
14839+
14840+union cvmx_pip_stat5_prtx {
14841+ uint64_t u64;
14842+ struct cvmx_pip_stat5_prtx_s {
14843+ uint64_t h256to511:32;
14844+ uint64_t h128to255:32;
14845+ } s;
14846+ struct cvmx_pip_stat5_prtx_s cn30xx;
14847+ struct cvmx_pip_stat5_prtx_s cn31xx;
14848+ struct cvmx_pip_stat5_prtx_s cn38xx;
14849+ struct cvmx_pip_stat5_prtx_s cn38xxp2;
14850+ struct cvmx_pip_stat5_prtx_s cn50xx;
14851+ struct cvmx_pip_stat5_prtx_s cn52xx;
14852+ struct cvmx_pip_stat5_prtx_s cn52xxp1;
14853+ struct cvmx_pip_stat5_prtx_s cn56xx;
14854+ struct cvmx_pip_stat5_prtx_s cn56xxp1;
14855+ struct cvmx_pip_stat5_prtx_s cn58xx;
14856+ struct cvmx_pip_stat5_prtx_s cn58xxp1;
14857+};
14858+
14859+union cvmx_pip_stat6_prtx {
14860+ uint64_t u64;
14861+ struct cvmx_pip_stat6_prtx_s {
14862+ uint64_t h1024to1518:32;
14863+ uint64_t h512to1023:32;
14864+ } s;
14865+ struct cvmx_pip_stat6_prtx_s cn30xx;
14866+ struct cvmx_pip_stat6_prtx_s cn31xx;
14867+ struct cvmx_pip_stat6_prtx_s cn38xx;
14868+ struct cvmx_pip_stat6_prtx_s cn38xxp2;
14869+ struct cvmx_pip_stat6_prtx_s cn50xx;
14870+ struct cvmx_pip_stat6_prtx_s cn52xx;
14871+ struct cvmx_pip_stat6_prtx_s cn52xxp1;
14872+ struct cvmx_pip_stat6_prtx_s cn56xx;
14873+ struct cvmx_pip_stat6_prtx_s cn56xxp1;
14874+ struct cvmx_pip_stat6_prtx_s cn58xx;
14875+ struct cvmx_pip_stat6_prtx_s cn58xxp1;
14876+};
14877+
14878+union cvmx_pip_stat7_prtx {
14879+ uint64_t u64;
14880+ struct cvmx_pip_stat7_prtx_s {
14881+ uint64_t fcs:32;
14882+ uint64_t h1519:32;
14883+ } s;
14884+ struct cvmx_pip_stat7_prtx_s cn30xx;
14885+ struct cvmx_pip_stat7_prtx_s cn31xx;
14886+ struct cvmx_pip_stat7_prtx_s cn38xx;
14887+ struct cvmx_pip_stat7_prtx_s cn38xxp2;
14888+ struct cvmx_pip_stat7_prtx_s cn50xx;
14889+ struct cvmx_pip_stat7_prtx_s cn52xx;
14890+ struct cvmx_pip_stat7_prtx_s cn52xxp1;
14891+ struct cvmx_pip_stat7_prtx_s cn56xx;
14892+ struct cvmx_pip_stat7_prtx_s cn56xxp1;
14893+ struct cvmx_pip_stat7_prtx_s cn58xx;
14894+ struct cvmx_pip_stat7_prtx_s cn58xxp1;
14895+};
14896+
14897+union cvmx_pip_stat8_prtx {
14898+ uint64_t u64;
14899+ struct cvmx_pip_stat8_prtx_s {
14900+ uint64_t frag:32;
14901+ uint64_t undersz:32;
14902+ } s;
14903+ struct cvmx_pip_stat8_prtx_s cn30xx;
14904+ struct cvmx_pip_stat8_prtx_s cn31xx;
14905+ struct cvmx_pip_stat8_prtx_s cn38xx;
14906+ struct cvmx_pip_stat8_prtx_s cn38xxp2;
14907+ struct cvmx_pip_stat8_prtx_s cn50xx;
14908+ struct cvmx_pip_stat8_prtx_s cn52xx;
14909+ struct cvmx_pip_stat8_prtx_s cn52xxp1;
14910+ struct cvmx_pip_stat8_prtx_s cn56xx;
14911+ struct cvmx_pip_stat8_prtx_s cn56xxp1;
14912+ struct cvmx_pip_stat8_prtx_s cn58xx;
14913+ struct cvmx_pip_stat8_prtx_s cn58xxp1;
14914+};
14915+
14916+union cvmx_pip_stat9_prtx {
14917+ uint64_t u64;
14918+ struct cvmx_pip_stat9_prtx_s {
14919+ uint64_t jabber:32;
14920+ uint64_t oversz:32;
14921+ } s;
14922+ struct cvmx_pip_stat9_prtx_s cn30xx;
14923+ struct cvmx_pip_stat9_prtx_s cn31xx;
14924+ struct cvmx_pip_stat9_prtx_s cn38xx;
14925+ struct cvmx_pip_stat9_prtx_s cn38xxp2;
14926+ struct cvmx_pip_stat9_prtx_s cn50xx;
14927+ struct cvmx_pip_stat9_prtx_s cn52xx;
14928+ struct cvmx_pip_stat9_prtx_s cn52xxp1;
14929+ struct cvmx_pip_stat9_prtx_s cn56xx;
14930+ struct cvmx_pip_stat9_prtx_s cn56xxp1;
14931+ struct cvmx_pip_stat9_prtx_s cn58xx;
14932+ struct cvmx_pip_stat9_prtx_s cn58xxp1;
14933+};
14934+
14935+union cvmx_pip_stat_ctl {
14936+ uint64_t u64;
14937+ struct cvmx_pip_stat_ctl_s {
14938+ uint64_t reserved_1_63:63;
14939+ uint64_t rdclr:1;
14940+ } s;
14941+ struct cvmx_pip_stat_ctl_s cn30xx;
14942+ struct cvmx_pip_stat_ctl_s cn31xx;
14943+ struct cvmx_pip_stat_ctl_s cn38xx;
14944+ struct cvmx_pip_stat_ctl_s cn38xxp2;
14945+ struct cvmx_pip_stat_ctl_s cn50xx;
14946+ struct cvmx_pip_stat_ctl_s cn52xx;
14947+ struct cvmx_pip_stat_ctl_s cn52xxp1;
14948+ struct cvmx_pip_stat_ctl_s cn56xx;
14949+ struct cvmx_pip_stat_ctl_s cn56xxp1;
14950+ struct cvmx_pip_stat_ctl_s cn58xx;
14951+ struct cvmx_pip_stat_ctl_s cn58xxp1;
14952+};
14953+
14954+union cvmx_pip_stat_inb_errsx {
14955+ uint64_t u64;
14956+ struct cvmx_pip_stat_inb_errsx_s {
14957+ uint64_t reserved_16_63:48;
14958+ uint64_t errs:16;
14959+ } s;
14960+ struct cvmx_pip_stat_inb_errsx_s cn30xx;
14961+ struct cvmx_pip_stat_inb_errsx_s cn31xx;
14962+ struct cvmx_pip_stat_inb_errsx_s cn38xx;
14963+ struct cvmx_pip_stat_inb_errsx_s cn38xxp2;
14964+ struct cvmx_pip_stat_inb_errsx_s cn50xx;
14965+ struct cvmx_pip_stat_inb_errsx_s cn52xx;
14966+ struct cvmx_pip_stat_inb_errsx_s cn52xxp1;
14967+ struct cvmx_pip_stat_inb_errsx_s cn56xx;
14968+ struct cvmx_pip_stat_inb_errsx_s cn56xxp1;
14969+ struct cvmx_pip_stat_inb_errsx_s cn58xx;
14970+ struct cvmx_pip_stat_inb_errsx_s cn58xxp1;
14971+};
14972+
14973+union cvmx_pip_stat_inb_octsx {
14974+ uint64_t u64;
14975+ struct cvmx_pip_stat_inb_octsx_s {
14976+ uint64_t reserved_48_63:16;
14977+ uint64_t octs:48;
14978+ } s;
14979+ struct cvmx_pip_stat_inb_octsx_s cn30xx;
14980+ struct cvmx_pip_stat_inb_octsx_s cn31xx;
14981+ struct cvmx_pip_stat_inb_octsx_s cn38xx;
14982+ struct cvmx_pip_stat_inb_octsx_s cn38xxp2;
14983+ struct cvmx_pip_stat_inb_octsx_s cn50xx;
14984+ struct cvmx_pip_stat_inb_octsx_s cn52xx;
14985+ struct cvmx_pip_stat_inb_octsx_s cn52xxp1;
14986+ struct cvmx_pip_stat_inb_octsx_s cn56xx;
14987+ struct cvmx_pip_stat_inb_octsx_s cn56xxp1;
14988+ struct cvmx_pip_stat_inb_octsx_s cn58xx;
14989+ struct cvmx_pip_stat_inb_octsx_s cn58xxp1;
14990+};
14991+
14992+union cvmx_pip_stat_inb_pktsx {
14993+ uint64_t u64;
14994+ struct cvmx_pip_stat_inb_pktsx_s {
14995+ uint64_t reserved_32_63:32;
14996+ uint64_t pkts:32;
14997+ } s;
14998+ struct cvmx_pip_stat_inb_pktsx_s cn30xx;
14999+ struct cvmx_pip_stat_inb_pktsx_s cn31xx;
15000+ struct cvmx_pip_stat_inb_pktsx_s cn38xx;
15001+ struct cvmx_pip_stat_inb_pktsx_s cn38xxp2;
15002+ struct cvmx_pip_stat_inb_pktsx_s cn50xx;
15003+ struct cvmx_pip_stat_inb_pktsx_s cn52xx;
15004+ struct cvmx_pip_stat_inb_pktsx_s cn52xxp1;
15005+ struct cvmx_pip_stat_inb_pktsx_s cn56xx;
15006+ struct cvmx_pip_stat_inb_pktsx_s cn56xxp1;
15007+ struct cvmx_pip_stat_inb_pktsx_s cn58xx;
15008+ struct cvmx_pip_stat_inb_pktsx_s cn58xxp1;
15009+};
15010+
15011+union cvmx_pip_tag_incx {
15012+ uint64_t u64;
15013+ struct cvmx_pip_tag_incx_s {
15014+ uint64_t reserved_8_63:56;
15015+ uint64_t en:8;
15016+ } s;
15017+ struct cvmx_pip_tag_incx_s cn30xx;
15018+ struct cvmx_pip_tag_incx_s cn31xx;
15019+ struct cvmx_pip_tag_incx_s cn38xx;
15020+ struct cvmx_pip_tag_incx_s cn38xxp2;
15021+ struct cvmx_pip_tag_incx_s cn50xx;
15022+ struct cvmx_pip_tag_incx_s cn52xx;
15023+ struct cvmx_pip_tag_incx_s cn52xxp1;
15024+ struct cvmx_pip_tag_incx_s cn56xx;
15025+ struct cvmx_pip_tag_incx_s cn56xxp1;
15026+ struct cvmx_pip_tag_incx_s cn58xx;
15027+ struct cvmx_pip_tag_incx_s cn58xxp1;
15028+};
15029+
15030+union cvmx_pip_tag_mask {
15031+ uint64_t u64;
15032+ struct cvmx_pip_tag_mask_s {
15033+ uint64_t reserved_16_63:48;
15034+ uint64_t mask:16;
15035+ } s;
15036+ struct cvmx_pip_tag_mask_s cn30xx;
15037+ struct cvmx_pip_tag_mask_s cn31xx;
15038+ struct cvmx_pip_tag_mask_s cn38xx;
15039+ struct cvmx_pip_tag_mask_s cn38xxp2;
15040+ struct cvmx_pip_tag_mask_s cn50xx;
15041+ struct cvmx_pip_tag_mask_s cn52xx;
15042+ struct cvmx_pip_tag_mask_s cn52xxp1;
15043+ struct cvmx_pip_tag_mask_s cn56xx;
15044+ struct cvmx_pip_tag_mask_s cn56xxp1;
15045+ struct cvmx_pip_tag_mask_s cn58xx;
15046+ struct cvmx_pip_tag_mask_s cn58xxp1;
15047+};
15048+
15049+union cvmx_pip_tag_secret {
15050+ uint64_t u64;
15051+ struct cvmx_pip_tag_secret_s {
15052+ uint64_t reserved_32_63:32;
15053+ uint64_t dst:16;
15054+ uint64_t src:16;
15055+ } s;
15056+ struct cvmx_pip_tag_secret_s cn30xx;
15057+ struct cvmx_pip_tag_secret_s cn31xx;
15058+ struct cvmx_pip_tag_secret_s cn38xx;
15059+ struct cvmx_pip_tag_secret_s cn38xxp2;
15060+ struct cvmx_pip_tag_secret_s cn50xx;
15061+ struct cvmx_pip_tag_secret_s cn52xx;
15062+ struct cvmx_pip_tag_secret_s cn52xxp1;
15063+ struct cvmx_pip_tag_secret_s cn56xx;
15064+ struct cvmx_pip_tag_secret_s cn56xxp1;
15065+ struct cvmx_pip_tag_secret_s cn58xx;
15066+ struct cvmx_pip_tag_secret_s cn58xxp1;
15067+};
15068+
15069+union cvmx_pip_todo_entry {
15070+ uint64_t u64;
15071+ struct cvmx_pip_todo_entry_s {
15072+ uint64_t val:1;
15073+ uint64_t reserved_62_62:1;
15074+ uint64_t entry:62;
15075+ } s;
15076+ struct cvmx_pip_todo_entry_s cn30xx;
15077+ struct cvmx_pip_todo_entry_s cn31xx;
15078+ struct cvmx_pip_todo_entry_s cn38xx;
15079+ struct cvmx_pip_todo_entry_s cn38xxp2;
15080+ struct cvmx_pip_todo_entry_s cn50xx;
15081+ struct cvmx_pip_todo_entry_s cn52xx;
15082+ struct cvmx_pip_todo_entry_s cn52xxp1;
15083+ struct cvmx_pip_todo_entry_s cn56xx;
15084+ struct cvmx_pip_todo_entry_s cn56xxp1;
15085+ struct cvmx_pip_todo_entry_s cn58xx;
15086+ struct cvmx_pip_todo_entry_s cn58xxp1;
15087+};
15088+
15089+#endif
15090--- /dev/null
15091+++ b/drivers/staging/octeon/cvmx-pip.h
15092@@ -0,0 +1,524 @@
15093+/***********************license start***************
15094+ * Author: Cavium Networks
15095+ *
15096+ * Contact: support@caviumnetworks.com
15097+ * This file is part of the OCTEON SDK
15098+ *
15099+ * Copyright (c) 2003-2008 Cavium Networks
15100+ *
15101+ * This file is free software; you can redistribute it and/or modify
15102+ * it under the terms of the GNU General Public License, Version 2, as
15103+ * published by the Free Software Foundation.
15104+ *
15105+ * This file is distributed in the hope that it will be useful, but
15106+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15107+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
15108+ * NONINFRINGEMENT. See the GNU General Public License for more
15109+ * details.
15110+ *
15111+ * You should have received a copy of the GNU General Public License
15112+ * along with this file; if not, write to the Free Software
15113+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15114+ * or visit http://www.gnu.org/licenses/.
15115+ *
15116+ * This file may also be available under a different license from Cavium.
15117+ * Contact Cavium Networks for more information
15118+ ***********************license end**************************************/
15119+
15120+/*
15121+ * Interface to the hardware Packet Input Processing unit.
15122+ *
15123+ */
15124+
15125+#ifndef __CVMX_PIP_H__
15126+#define __CVMX_PIP_H__
15127+
15128+#include "cvmx-wqe.h"
15129+#include "cvmx-fpa.h"
15130+#include "cvmx-pip-defs.h"
15131+
15132+#define CVMX_PIP_NUM_INPUT_PORTS 40
15133+#define CVMX_PIP_NUM_WATCHERS 4
15134+
15135+/*
15136+ * Encodes the different error and exception codes
15137+ */
15138+typedef enum {
15139+ CVMX_PIP_L4_NO_ERR = 0ull,
15140+ /*
15141+ * 1 = TCP (UDP) packet not long enough to cover TCP (UDP)
15142+ * header
15143+ */
15144+ CVMX_PIP_L4_MAL_ERR = 1ull,
15145+ /* 2 = TCP/UDP checksum failure */
15146+ CVMX_PIP_CHK_ERR = 2ull,
15147+ /*
15148+ * 3 = TCP/UDP length check (TCP/UDP length does not match IP
15149+ * length).
15150+ */
15151+ CVMX_PIP_L4_LENGTH_ERR = 3ull,
15152+ /* 4 = illegal TCP/UDP port (either source or dest port is zero) */
15153+ CVMX_PIP_BAD_PRT_ERR = 4ull,
15154+ /* 8 = TCP flags = FIN only */
15155+ CVMX_PIP_TCP_FLG8_ERR = 8ull,
15156+ /* 9 = TCP flags = 0 */
15157+ CVMX_PIP_TCP_FLG9_ERR = 9ull,
15158+ /* 10 = TCP flags = FIN+RST+* */
15159+ CVMX_PIP_TCP_FLG10_ERR = 10ull,
15160+ /* 11 = TCP flags = SYN+URG+* */
15161+ CVMX_PIP_TCP_FLG11_ERR = 11ull,
15162+ /* 12 = TCP flags = SYN+RST+* */
15163+ CVMX_PIP_TCP_FLG12_ERR = 12ull,
15164+ /* 13 = TCP flags = SYN+FIN+* */
15165+ CVMX_PIP_TCP_FLG13_ERR = 13ull
15166+} cvmx_pip_l4_err_t;
15167+
15168+typedef enum {
15169+
15170+ CVMX_PIP_IP_NO_ERR = 0ull,
15171+ /* 1 = not IPv4 or IPv6 */
15172+ CVMX_PIP_NOT_IP = 1ull,
15173+ /* 2 = IPv4 header checksum violation */
15174+ CVMX_PIP_IPV4_HDR_CHK = 2ull,
15175+ /* 3 = malformed (packet not long enough to cover IP hdr) */
15176+ CVMX_PIP_IP_MAL_HDR = 3ull,
15177+ /* 4 = malformed (packet not long enough to cover len in IP hdr) */
15178+ CVMX_PIP_IP_MAL_PKT = 4ull,
15179+ /* 5 = TTL / hop count equal zero */
15180+ CVMX_PIP_TTL_HOP = 5ull,
15181+ /* 6 = IPv4 options / IPv6 early extension headers */
15182+ CVMX_PIP_OPTS = 6ull
15183+} cvmx_pip_ip_exc_t;
15184+
15185+/**
15186+ * NOTES
15187+ * late collision (data received before collision)
15188+ * late collisions cannot be detected by the receiver
15189+ * they would appear as JAM bits which would appear as bad FCS
15190+ * or carrier extend error which is CVMX_PIP_EXTEND_ERR
15191+ */
15192+typedef enum {
15193+ /* No error */
15194+ CVMX_PIP_RX_NO_ERR = 0ull,
15195+ /* RGM+SPI 1 = partially received packet (buffering/bandwidth
15196+ * not adequate) */
15197+ CVMX_PIP_PARTIAL_ERR = 1ull,
15198+ /* RGM+SPI 2 = receive packet too large and truncated */
15199+ CVMX_PIP_JABBER_ERR = 2ull,
15200+ /*
15201+ * RGM 3 = max frame error (pkt len > max frame len) (with FCS
15202+ * error)
15203+ */
15204+ CVMX_PIP_OVER_FCS_ERR = 3ull,
15205+ /* RGM+SPI 4 = max frame error (pkt len > max frame len) */
15206+ CVMX_PIP_OVER_ERR = 4ull,
15207+ /*
15208+ * RGM 5 = nibble error (data not byte multiple - 100M and 10M
15209+ * only)
15210+ */
15211+ CVMX_PIP_ALIGN_ERR = 5ull,
15212+ /*
15213+ * RGM 6 = min frame error (pkt len < min frame len) (with FCS
15214+ * error)
15215+ */
15216+ CVMX_PIP_UNDER_FCS_ERR = 6ull,
15217+ /* RGM 7 = FCS error */
15218+ CVMX_PIP_GMX_FCS_ERR = 7ull,
15219+ /* RGM+SPI 8 = min frame error (pkt len < min frame len) */
15220+ CVMX_PIP_UNDER_ERR = 8ull,
15221+ /* RGM 9 = Frame carrier extend error */
15222+ CVMX_PIP_EXTEND_ERR = 9ull,
15223+ /*
15224+ * RGM 10 = length mismatch (len did not match len in L2
15225+ * length/type)
15226+ */
15227+ CVMX_PIP_LENGTH_ERR = 10ull,
15228+ /* RGM 11 = Frame error (some or all data bits marked err) */
15229+ CVMX_PIP_DAT_ERR = 11ull,
15230+ /* SPI 11 = DIP4 error */
15231+ CVMX_PIP_DIP_ERR = 11ull,
15232+ /*
15233+ * RGM 12 = packet was not large enough to pass the skipper -
15234+ * no inspection could occur.
15235+ */
15236+ CVMX_PIP_SKIP_ERR = 12ull,
15237+ /*
15238+ * RGM 13 = studder error (data not repeated - 100M and 10M
15239+ * only)
15240+ */
15241+ CVMX_PIP_NIBBLE_ERR = 13ull,
15242+ /* RGM+SPI 16 = FCS error */
15243+ CVMX_PIP_PIP_FCS = 16L,
15244+ /*
15245+ * RGM+SPI+PCI 17 = packet was not large enough to pass the
15246+ * skipper - no inspection could occur.
15247+ */
15248+ CVMX_PIP_PIP_SKIP_ERR = 17L,
15249+ /*
15250+ * RGM+SPI+PCI 18 = malformed l2 (packet not long enough to
15251+ * cover L2 hdr).
15252+ */
15253+ CVMX_PIP_PIP_L2_MAL_HDR = 18L
15254+ /*
15255+ * NOTES: xx = late collision (data received before collision)
15256+ * late collisions cannot be detected by the receiver
15257+ * they would appear as JAM bits which would appear as
15258+ * bad FCS or carrier extend error which is
15259+ * CVMX_PIP_EXTEND_ERR
15260+ */
15261+} cvmx_pip_rcv_err_t;
15262+
15263+/**
15264+ * This defines the err_code field errors in the work Q entry
15265+ */
15266+typedef union {
15267+ cvmx_pip_l4_err_t l4_err;
15268+ cvmx_pip_ip_exc_t ip_exc;
15269+ cvmx_pip_rcv_err_t rcv_err;
15270+} cvmx_pip_err_t;
15271+
15272+/**
15273+ * Status statistics for a port
15274+ */
15275+typedef struct {
15276+ /* Inbound octets marked to be dropped by the IPD */
15277+ uint32_t dropped_octets;
15278+ /* Inbound packets marked to be dropped by the IPD */
15279+ uint32_t dropped_packets;
15280+ /* RAW PCI Packets received by PIP per port */
15281+ uint32_t pci_raw_packets;
15282+ /* Number of octets processed by PIP */
15283+ uint32_t octets;
15284+ /* Number of packets processed by PIP */
15285+ uint32_t packets;
15286+ /*
15287+ * Number of indentified L2 multicast packets. Does not
15288+ * include broadcast packets. Only includes packets whose
15289+ * parse mode is SKIP_TO_L2
15290+ */
15291+ uint32_t multicast_packets;
15292+ /*
15293+ * Number of indentified L2 broadcast packets. Does not
15294+ * include multicast packets. Only includes packets whose
15295+ * parse mode is SKIP_TO_L2
15296+ */
15297+ uint32_t broadcast_packets;
15298+ /* Number of 64B packets */
15299+ uint32_t len_64_packets;
15300+ /* Number of 65-127B packets */
15301+ uint32_t len_65_127_packets;
15302+ /* Number of 128-255B packets */
15303+ uint32_t len_128_255_packets;
15304+ /* Number of 256-511B packets */
15305+ uint32_t len_256_511_packets;
15306+ /* Number of 512-1023B packets */
15307+ uint32_t len_512_1023_packets;
15308+ /* Number of 1024-1518B packets */
15309+ uint32_t len_1024_1518_packets;
15310+ /* Number of 1519-max packets */
15311+ uint32_t len_1519_max_packets;
15312+ /* Number of packets with FCS or Align opcode errors */
15313+ uint32_t fcs_align_err_packets;
15314+ /* Number of packets with length < min */
15315+ uint32_t runt_packets;
15316+ /* Number of packets with length < min and FCS error */
15317+ uint32_t runt_crc_packets;
15318+ /* Number of packets with length > max */
15319+ uint32_t oversize_packets;
15320+ /* Number of packets with length > max and FCS error */
15321+ uint32_t oversize_crc_packets;
15322+ /* Number of packets without GMX/SPX/PCI errors received by PIP */
15323+ uint32_t inb_packets;
15324+ /*
15325+ * Total number of octets from all packets received by PIP,
15326+ * including CRC
15327+ */
15328+ uint64_t inb_octets;
15329+ /* Number of packets with GMX/SPX/PCI errors received by PIP */
15330+ uint16_t inb_errors;
15331+} cvmx_pip_port_status_t;
15332+
15333+/**
15334+ * Definition of the PIP custom header that can be prepended
15335+ * to a packet by external hardware.
15336+ */
15337+typedef union {
15338+ uint64_t u64;
15339+ struct {
15340+ /*
15341+ * Documented as R - Set if the Packet is RAWFULL. If
15342+ * set, this header must be the full 8 bytes.
15343+ */
15344+ uint64_t rawfull:1;
15345+ /* Must be zero */
15346+ uint64_t reserved0:5;
15347+ /* PIP parse mode for this packet */
15348+ uint64_t parse_mode:2;
15349+ /* Must be zero */
15350+ uint64_t reserved1:1;
15351+ /*
15352+ * Skip amount, including this header, to the
15353+ * beginning of the packet
15354+ */
15355+ uint64_t skip_len:7;
15356+ /* Must be zero */
15357+ uint64_t reserved2:6;
15358+ /* POW input queue for this packet */
15359+ uint64_t qos:3;
15360+ /* POW input group for this packet */
15361+ uint64_t grp:4;
15362+ /*
15363+ * Flag to store this packet in the work queue entry,
15364+ * if possible
15365+ */
15366+ uint64_t rs:1;
15367+ /* POW input tag type */
15368+ uint64_t tag_type:2;
15369+ /* POW input tag */
15370+ uint64_t tag:32;
15371+ } s;
15372+} cvmx_pip_pkt_inst_hdr_t;
15373+
15374+/* CSR typedefs have been moved to cvmx-csr-*.h */
15375+
15376+/**
15377+ * Configure an ethernet input port
15378+ *
15379+ * @port_num: Port number to configure
15380+ * @port_cfg: Port hardware configuration
15381+ * @port_tag_cfg:
15382+ * Port POW tagging configuration
15383+ */
15384+static inline void cvmx_pip_config_port(uint64_t port_num,
15385+ union cvmx_pip_prt_cfgx port_cfg,
15386+ union cvmx_pip_prt_tagx port_tag_cfg)
15387+{
15388+ cvmx_write_csr(CVMX_PIP_PRT_CFGX(port_num), port_cfg.u64);
15389+ cvmx_write_csr(CVMX_PIP_PRT_TAGX(port_num), port_tag_cfg.u64);
15390+}
15391+#if 0
15392+/**
15393+ * @deprecated This function is a thin wrapper around the Pass1 version
15394+ * of the CVMX_PIP_QOS_WATCHX CSR; Pass2 has added a field for
15395+ * setting the group that is incompatible with this function,
15396+ * the preferred upgrade path is to use the CSR directly.
15397+ *
15398+ * Configure the global QoS packet watchers. Each watcher is
15399+ * capable of matching a field in a packet to determine the
15400+ * QoS queue for scheduling.
15401+ *
15402+ * @watcher: Watcher number to configure (0 - 3).
15403+ * @match_type: Watcher match type
15404+ * @match_value:
15405+ * Value the watcher will match against
15406+ * @qos: QoS queue for packets matching this watcher
15407+ */
15408+static inline void cvmx_pip_config_watcher(uint64_t watcher,
15409+ cvmx_pip_qos_watch_types match_type,
15410+ uint64_t match_value, uint64_t qos)
15411+{
15412+ cvmx_pip_port_watcher_cfg_t watcher_config;
15413+
15414+ watcher_config.u64 = 0;
15415+ watcher_config.s.match_type = match_type;
15416+ watcher_config.s.match_value = match_value;
15417+ watcher_config.s.qos = qos;
15418+
15419+ cvmx_write_csr(CVMX_PIP_QOS_WATCHX(watcher), watcher_config.u64);
15420+}
15421+#endif
15422+/**
15423+ * Configure the VLAN priority to QoS queue mapping.
15424+ *
15425+ * @vlan_priority:
15426+ * VLAN priority (0-7)
15427+ * @qos: QoS queue for packets matching this watcher
15428+ */
15429+static inline void cvmx_pip_config_vlan_qos(uint64_t vlan_priority,
15430+ uint64_t qos)
15431+{
15432+ union cvmx_pip_qos_vlanx pip_qos_vlanx;
15433+ pip_qos_vlanx.u64 = 0;
15434+ pip_qos_vlanx.s.qos = qos;
15435+ cvmx_write_csr(CVMX_PIP_QOS_VLANX(vlan_priority), pip_qos_vlanx.u64);
15436+}
15437+
15438+/**
15439+ * Configure the Diffserv to QoS queue mapping.
15440+ *
15441+ * @diffserv: Diffserv field value (0-63)
15442+ * @qos: QoS queue for packets matching this watcher
15443+ */
15444+static inline void cvmx_pip_config_diffserv_qos(uint64_t diffserv, uint64_t qos)
15445+{
15446+ union cvmx_pip_qos_diffx pip_qos_diffx;
15447+ pip_qos_diffx.u64 = 0;
15448+ pip_qos_diffx.s.qos = qos;
15449+ cvmx_write_csr(CVMX_PIP_QOS_DIFFX(diffserv), pip_qos_diffx.u64);
15450+}
15451+
15452+/**
15453+ * Get the status counters for a port.
15454+ *
15455+ * @port_num: Port number to get statistics for.
15456+ * @clear: Set to 1 to clear the counters after they are read
15457+ * @status: Where to put the results.
15458+ */
15459+static inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear,
15460+ cvmx_pip_port_status_t *status)
15461+{
15462+ union cvmx_pip_stat_ctl pip_stat_ctl;
15463+ union cvmx_pip_stat0_prtx stat0;
15464+ union cvmx_pip_stat1_prtx stat1;
15465+ union cvmx_pip_stat2_prtx stat2;
15466+ union cvmx_pip_stat3_prtx stat3;
15467+ union cvmx_pip_stat4_prtx stat4;
15468+ union cvmx_pip_stat5_prtx stat5;
15469+ union cvmx_pip_stat6_prtx stat6;
15470+ union cvmx_pip_stat7_prtx stat7;
15471+ union cvmx_pip_stat8_prtx stat8;
15472+ union cvmx_pip_stat9_prtx stat9;
15473+ union cvmx_pip_stat_inb_pktsx pip_stat_inb_pktsx;
15474+ union cvmx_pip_stat_inb_octsx pip_stat_inb_octsx;
15475+ union cvmx_pip_stat_inb_errsx pip_stat_inb_errsx;
15476+
15477+ pip_stat_ctl.u64 = 0;
15478+ pip_stat_ctl.s.rdclr = clear;
15479+ cvmx_write_csr(CVMX_PIP_STAT_CTL, pip_stat_ctl.u64);
15480+
15481+ stat0.u64 = cvmx_read_csr(CVMX_PIP_STAT0_PRTX(port_num));
15482+ stat1.u64 = cvmx_read_csr(CVMX_PIP_STAT1_PRTX(port_num));
15483+ stat2.u64 = cvmx_read_csr(CVMX_PIP_STAT2_PRTX(port_num));
15484+ stat3.u64 = cvmx_read_csr(CVMX_PIP_STAT3_PRTX(port_num));
15485+ stat4.u64 = cvmx_read_csr(CVMX_PIP_STAT4_PRTX(port_num));
15486+ stat5.u64 = cvmx_read_csr(CVMX_PIP_STAT5_PRTX(port_num));
15487+ stat6.u64 = cvmx_read_csr(CVMX_PIP_STAT6_PRTX(port_num));
15488+ stat7.u64 = cvmx_read_csr(CVMX_PIP_STAT7_PRTX(port_num));
15489+ stat8.u64 = cvmx_read_csr(CVMX_PIP_STAT8_PRTX(port_num));
15490+ stat9.u64 = cvmx_read_csr(CVMX_PIP_STAT9_PRTX(port_num));
15491+ pip_stat_inb_pktsx.u64 =
15492+ cvmx_read_csr(CVMX_PIP_STAT_INB_PKTSX(port_num));
15493+ pip_stat_inb_octsx.u64 =
15494+ cvmx_read_csr(CVMX_PIP_STAT_INB_OCTSX(port_num));
15495+ pip_stat_inb_errsx.u64 =
15496+ cvmx_read_csr(CVMX_PIP_STAT_INB_ERRSX(port_num));
15497+
15498+ status->dropped_octets = stat0.s.drp_octs;
15499+ status->dropped_packets = stat0.s.drp_pkts;
15500+ status->octets = stat1.s.octs;
15501+ status->pci_raw_packets = stat2.s.raw;
15502+ status->packets = stat2.s.pkts;
15503+ status->multicast_packets = stat3.s.mcst;
15504+ status->broadcast_packets = stat3.s.bcst;
15505+ status->len_64_packets = stat4.s.h64;
15506+ status->len_65_127_packets = stat4.s.h65to127;
15507+ status->len_128_255_packets = stat5.s.h128to255;
15508+ status->len_256_511_packets = stat5.s.h256to511;
15509+ status->len_512_1023_packets = stat6.s.h512to1023;
15510+ status->len_1024_1518_packets = stat6.s.h1024to1518;
15511+ status->len_1519_max_packets = stat7.s.h1519;
15512+ status->fcs_align_err_packets = stat7.s.fcs;
15513+ status->runt_packets = stat8.s.undersz;
15514+ status->runt_crc_packets = stat8.s.frag;
15515+ status->oversize_packets = stat9.s.oversz;
15516+ status->oversize_crc_packets = stat9.s.jabber;
15517+ status->inb_packets = pip_stat_inb_pktsx.s.pkts;
15518+ status->inb_octets = pip_stat_inb_octsx.s.octs;
15519+ status->inb_errors = pip_stat_inb_errsx.s.errs;
15520+
15521+ if (cvmx_octeon_is_pass1()) {
15522+ /*
15523+ * Kludge to fix Octeon Pass 1 errata - Drop counts
15524+ * don't work.
15525+ */
15526+ if (status->inb_packets > status->packets)
15527+ status->dropped_packets =
15528+ status->inb_packets - status->packets;
15529+ else
15530+ status->dropped_packets = 0;
15531+ if (status->inb_octets - status->inb_packets * 4 >
15532+ status->octets)
15533+ status->dropped_octets =
15534+ status->inb_octets - status->inb_packets * 4 -
15535+ status->octets;
15536+ else
15537+ status->dropped_octets = 0;
15538+ }
15539+}
15540+
15541+/**
15542+ * Configure the hardware CRC engine
15543+ *
15544+ * @interface: Interface to configure (0 or 1)
15545+ * @invert_result:
15546+ * Invert the result of the CRC
15547+ * @reflect: Reflect
15548+ * @initialization_vector:
15549+ * CRC initialization vector
15550+ */
15551+static inline void cvmx_pip_config_crc(uint64_t interface,
15552+ uint64_t invert_result, uint64_t reflect,
15553+ uint32_t initialization_vector)
15554+{
15555+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
15556+ union cvmx_pip_crc_ctlx config;
15557+ union cvmx_pip_crc_ivx pip_crc_ivx;
15558+
15559+ config.u64 = 0;
15560+ config.s.invres = invert_result;
15561+ config.s.reflect = reflect;
15562+ cvmx_write_csr(CVMX_PIP_CRC_CTLX(interface), config.u64);
15563+
15564+ pip_crc_ivx.u64 = 0;
15565+ pip_crc_ivx.s.iv = initialization_vector;
15566+ cvmx_write_csr(CVMX_PIP_CRC_IVX(interface), pip_crc_ivx.u64);
15567+ }
15568+}
15569+
15570+/**
15571+ * Clear all bits in a tag mask. This should be called on
15572+ * startup before any calls to cvmx_pip_tag_mask_set. Each bit
15573+ * set in the final mask represent a byte used in the packet for
15574+ * tag generation.
15575+ *
15576+ * @mask_index: Which tag mask to clear (0..3)
15577+ */
15578+static inline void cvmx_pip_tag_mask_clear(uint64_t mask_index)
15579+{
15580+ uint64_t index;
15581+ union cvmx_pip_tag_incx pip_tag_incx;
15582+ pip_tag_incx.u64 = 0;
15583+ pip_tag_incx.s.en = 0;
15584+ for (index = mask_index * 16; index < (mask_index + 1) * 16; index++)
15585+ cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
15586+}
15587+
15588+/**
15589+ * Sets a range of bits in the tag mask. The tag mask is used
15590+ * when the cvmx_pip_port_tag_cfg_t tag_mode is non zero.
15591+ * There are four separate masks that can be configured.
15592+ *
15593+ * @mask_index: Which tag mask to modify (0..3)
15594+ * @offset: Offset into the bitmask to set bits at. Use the GCC macro
15595+ * offsetof() to determine the offsets into packet headers.
15596+ * For example, offsetof(ethhdr, protocol) returns the offset
15597+ * of the ethernet protocol field. The bitmask selects which
15598+ * bytes to include the the tag, with bit offset X selecting
15599+ * byte at offset X from the beginning of the packet data.
15600+ * @len: Number of bytes to include. Usually this is the sizeof()
15601+ * the field.
15602+ */
15603+static inline void cvmx_pip_tag_mask_set(uint64_t mask_index, uint64_t offset,
15604+ uint64_t len)
15605+{
15606+ while (len--) {
15607+ union cvmx_pip_tag_incx pip_tag_incx;
15608+ uint64_t index = mask_index * 16 + offset / 8;
15609+ pip_tag_incx.u64 = cvmx_read_csr(CVMX_PIP_TAG_INCX(index));
15610+ pip_tag_incx.s.en |= 0x80 >> (offset & 0x7);
15611+ cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
15612+ offset++;
15613+ }
15614+}
15615+
15616+#endif /* __CVMX_PIP_H__ */
15617--- /dev/null
15618+++ b/drivers/staging/octeon/cvmx-pko-defs.h
15619@@ -0,0 +1,1133 @@
15620+/***********************license start***************
15621+ * Author: Cavium Networks
15622+ *
15623+ * Contact: support@caviumnetworks.com
15624+ * This file is part of the OCTEON SDK
15625+ *
15626+ * Copyright (c) 2003-2008 Cavium Networks
15627+ *
15628+ * This file is free software; you can redistribute it and/or modify
15629+ * it under the terms of the GNU General Public License, Version 2, as
15630+ * published by the Free Software Foundation.
15631+ *
15632+ * This file is distributed in the hope that it will be useful, but
15633+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15634+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
15635+ * NONINFRINGEMENT. See the GNU General Public License for more
15636+ * details.
15637+ *
15638+ * You should have received a copy of the GNU General Public License
15639+ * along with this file; if not, write to the Free Software
15640+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15641+ * or visit http://www.gnu.org/licenses/.
15642+ *
15643+ * This file may also be available under a different license from Cavium.
15644+ * Contact Cavium Networks for more information
15645+ ***********************license end**************************************/
15646+
15647+#ifndef __CVMX_PKO_DEFS_H__
15648+#define __CVMX_PKO_DEFS_H__
15649+
15650+#define CVMX_PKO_MEM_COUNT0 \
15651+ CVMX_ADD_IO_SEG(0x0001180050001080ull)
15652+#define CVMX_PKO_MEM_COUNT1 \
15653+ CVMX_ADD_IO_SEG(0x0001180050001088ull)
15654+#define CVMX_PKO_MEM_DEBUG0 \
15655+ CVMX_ADD_IO_SEG(0x0001180050001100ull)
15656+#define CVMX_PKO_MEM_DEBUG1 \
15657+ CVMX_ADD_IO_SEG(0x0001180050001108ull)
15658+#define CVMX_PKO_MEM_DEBUG10 \
15659+ CVMX_ADD_IO_SEG(0x0001180050001150ull)
15660+#define CVMX_PKO_MEM_DEBUG11 \
15661+ CVMX_ADD_IO_SEG(0x0001180050001158ull)
15662+#define CVMX_PKO_MEM_DEBUG12 \
15663+ CVMX_ADD_IO_SEG(0x0001180050001160ull)
15664+#define CVMX_PKO_MEM_DEBUG13 \
15665+ CVMX_ADD_IO_SEG(0x0001180050001168ull)
15666+#define CVMX_PKO_MEM_DEBUG14 \
15667+ CVMX_ADD_IO_SEG(0x0001180050001170ull)
15668+#define CVMX_PKO_MEM_DEBUG2 \
15669+ CVMX_ADD_IO_SEG(0x0001180050001110ull)
15670+#define CVMX_PKO_MEM_DEBUG3 \
15671+ CVMX_ADD_IO_SEG(0x0001180050001118ull)
15672+#define CVMX_PKO_MEM_DEBUG4 \
15673+ CVMX_ADD_IO_SEG(0x0001180050001120ull)
15674+#define CVMX_PKO_MEM_DEBUG5 \
15675+ CVMX_ADD_IO_SEG(0x0001180050001128ull)
15676+#define CVMX_PKO_MEM_DEBUG6 \
15677+ CVMX_ADD_IO_SEG(0x0001180050001130ull)
15678+#define CVMX_PKO_MEM_DEBUG7 \
15679+ CVMX_ADD_IO_SEG(0x0001180050001138ull)
15680+#define CVMX_PKO_MEM_DEBUG8 \
15681+ CVMX_ADD_IO_SEG(0x0001180050001140ull)
15682+#define CVMX_PKO_MEM_DEBUG9 \
15683+ CVMX_ADD_IO_SEG(0x0001180050001148ull)
15684+#define CVMX_PKO_MEM_PORT_PTRS \
15685+ CVMX_ADD_IO_SEG(0x0001180050001010ull)
15686+#define CVMX_PKO_MEM_PORT_QOS \
15687+ CVMX_ADD_IO_SEG(0x0001180050001018ull)
15688+#define CVMX_PKO_MEM_PORT_RATE0 \
15689+ CVMX_ADD_IO_SEG(0x0001180050001020ull)
15690+#define CVMX_PKO_MEM_PORT_RATE1 \
15691+ CVMX_ADD_IO_SEG(0x0001180050001028ull)
15692+#define CVMX_PKO_MEM_QUEUE_PTRS \
15693+ CVMX_ADD_IO_SEG(0x0001180050001000ull)
15694+#define CVMX_PKO_MEM_QUEUE_QOS \
15695+ CVMX_ADD_IO_SEG(0x0001180050001008ull)
15696+#define CVMX_PKO_REG_BIST_RESULT \
15697+ CVMX_ADD_IO_SEG(0x0001180050000080ull)
15698+#define CVMX_PKO_REG_CMD_BUF \
15699+ CVMX_ADD_IO_SEG(0x0001180050000010ull)
15700+#define CVMX_PKO_REG_CRC_CTLX(offset) \
15701+ CVMX_ADD_IO_SEG(0x0001180050000028ull + (((offset) & 1) * 8))
15702+#define CVMX_PKO_REG_CRC_ENABLE \
15703+ CVMX_ADD_IO_SEG(0x0001180050000020ull)
15704+#define CVMX_PKO_REG_CRC_IVX(offset) \
15705+ CVMX_ADD_IO_SEG(0x0001180050000038ull + (((offset) & 1) * 8))
15706+#define CVMX_PKO_REG_DEBUG0 \
15707+ CVMX_ADD_IO_SEG(0x0001180050000098ull)
15708+#define CVMX_PKO_REG_DEBUG1 \
15709+ CVMX_ADD_IO_SEG(0x00011800500000A0ull)
15710+#define CVMX_PKO_REG_DEBUG2 \
15711+ CVMX_ADD_IO_SEG(0x00011800500000A8ull)
15712+#define CVMX_PKO_REG_DEBUG3 \
15713+ CVMX_ADD_IO_SEG(0x00011800500000B0ull)
15714+#define CVMX_PKO_REG_ENGINE_INFLIGHT \
15715+ CVMX_ADD_IO_SEG(0x0001180050000050ull)
15716+#define CVMX_PKO_REG_ENGINE_THRESH \
15717+ CVMX_ADD_IO_SEG(0x0001180050000058ull)
15718+#define CVMX_PKO_REG_ERROR \
15719+ CVMX_ADD_IO_SEG(0x0001180050000088ull)
15720+#define CVMX_PKO_REG_FLAGS \
15721+ CVMX_ADD_IO_SEG(0x0001180050000000ull)
15722+#define CVMX_PKO_REG_GMX_PORT_MODE \
15723+ CVMX_ADD_IO_SEG(0x0001180050000018ull)
15724+#define CVMX_PKO_REG_INT_MASK \
15725+ CVMX_ADD_IO_SEG(0x0001180050000090ull)
15726+#define CVMX_PKO_REG_QUEUE_MODE \
15727+ CVMX_ADD_IO_SEG(0x0001180050000048ull)
15728+#define CVMX_PKO_REG_QUEUE_PTRS1 \
15729+ CVMX_ADD_IO_SEG(0x0001180050000100ull)
15730+#define CVMX_PKO_REG_READ_IDX \
15731+ CVMX_ADD_IO_SEG(0x0001180050000008ull)
15732+
15733+union cvmx_pko_mem_count0 {
15734+ uint64_t u64;
15735+ struct cvmx_pko_mem_count0_s {
15736+ uint64_t reserved_32_63:32;
15737+ uint64_t count:32;
15738+ } s;
15739+ struct cvmx_pko_mem_count0_s cn30xx;
15740+ struct cvmx_pko_mem_count0_s cn31xx;
15741+ struct cvmx_pko_mem_count0_s cn38xx;
15742+ struct cvmx_pko_mem_count0_s cn38xxp2;
15743+ struct cvmx_pko_mem_count0_s cn50xx;
15744+ struct cvmx_pko_mem_count0_s cn52xx;
15745+ struct cvmx_pko_mem_count0_s cn52xxp1;
15746+ struct cvmx_pko_mem_count0_s cn56xx;
15747+ struct cvmx_pko_mem_count0_s cn56xxp1;
15748+ struct cvmx_pko_mem_count0_s cn58xx;
15749+ struct cvmx_pko_mem_count0_s cn58xxp1;
15750+};
15751+
15752+union cvmx_pko_mem_count1 {
15753+ uint64_t u64;
15754+ struct cvmx_pko_mem_count1_s {
15755+ uint64_t reserved_48_63:16;
15756+ uint64_t count:48;
15757+ } s;
15758+ struct cvmx_pko_mem_count1_s cn30xx;
15759+ struct cvmx_pko_mem_count1_s cn31xx;
15760+ struct cvmx_pko_mem_count1_s cn38xx;
15761+ struct cvmx_pko_mem_count1_s cn38xxp2;
15762+ struct cvmx_pko_mem_count1_s cn50xx;
15763+ struct cvmx_pko_mem_count1_s cn52xx;
15764+ struct cvmx_pko_mem_count1_s cn52xxp1;
15765+ struct cvmx_pko_mem_count1_s cn56xx;
15766+ struct cvmx_pko_mem_count1_s cn56xxp1;
15767+ struct cvmx_pko_mem_count1_s cn58xx;
15768+ struct cvmx_pko_mem_count1_s cn58xxp1;
15769+};
15770+
15771+union cvmx_pko_mem_debug0 {
15772+ uint64_t u64;
15773+ struct cvmx_pko_mem_debug0_s {
15774+ uint64_t fau:28;
15775+ uint64_t cmd:14;
15776+ uint64_t segs:6;
15777+ uint64_t size:16;
15778+ } s;
15779+ struct cvmx_pko_mem_debug0_s cn30xx;
15780+ struct cvmx_pko_mem_debug0_s cn31xx;
15781+ struct cvmx_pko_mem_debug0_s cn38xx;
15782+ struct cvmx_pko_mem_debug0_s cn38xxp2;
15783+ struct cvmx_pko_mem_debug0_s cn50xx;
15784+ struct cvmx_pko_mem_debug0_s cn52xx;
15785+ struct cvmx_pko_mem_debug0_s cn52xxp1;
15786+ struct cvmx_pko_mem_debug0_s cn56xx;
15787+ struct cvmx_pko_mem_debug0_s cn56xxp1;
15788+ struct cvmx_pko_mem_debug0_s cn58xx;
15789+ struct cvmx_pko_mem_debug0_s cn58xxp1;
15790+};
15791+
15792+union cvmx_pko_mem_debug1 {
15793+ uint64_t u64;
15794+ struct cvmx_pko_mem_debug1_s {
15795+ uint64_t i:1;
15796+ uint64_t back:4;
15797+ uint64_t pool:3;
15798+ uint64_t size:16;
15799+ uint64_t ptr:40;
15800+ } s;
15801+ struct cvmx_pko_mem_debug1_s cn30xx;
15802+ struct cvmx_pko_mem_debug1_s cn31xx;
15803+ struct cvmx_pko_mem_debug1_s cn38xx;
15804+ struct cvmx_pko_mem_debug1_s cn38xxp2;
15805+ struct cvmx_pko_mem_debug1_s cn50xx;
15806+ struct cvmx_pko_mem_debug1_s cn52xx;
15807+ struct cvmx_pko_mem_debug1_s cn52xxp1;
15808+ struct cvmx_pko_mem_debug1_s cn56xx;
15809+ struct cvmx_pko_mem_debug1_s cn56xxp1;
15810+ struct cvmx_pko_mem_debug1_s cn58xx;
15811+ struct cvmx_pko_mem_debug1_s cn58xxp1;
15812+};
15813+
15814+union cvmx_pko_mem_debug10 {
15815+ uint64_t u64;
15816+ struct cvmx_pko_mem_debug10_s {
15817+ uint64_t reserved_0_63:64;
15818+ } s;
15819+ struct cvmx_pko_mem_debug10_cn30xx {
15820+ uint64_t fau:28;
15821+ uint64_t cmd:14;
15822+ uint64_t segs:6;
15823+ uint64_t size:16;
15824+ } cn30xx;
15825+ struct cvmx_pko_mem_debug10_cn30xx cn31xx;
15826+ struct cvmx_pko_mem_debug10_cn30xx cn38xx;
15827+ struct cvmx_pko_mem_debug10_cn30xx cn38xxp2;
15828+ struct cvmx_pko_mem_debug10_cn50xx {
15829+ uint64_t reserved_49_63:15;
15830+ uint64_t ptrs1:17;
15831+ uint64_t reserved_17_31:15;
15832+ uint64_t ptrs2:17;
15833+ } cn50xx;
15834+ struct cvmx_pko_mem_debug10_cn50xx cn52xx;
15835+ struct cvmx_pko_mem_debug10_cn50xx cn52xxp1;
15836+ struct cvmx_pko_mem_debug10_cn50xx cn56xx;
15837+ struct cvmx_pko_mem_debug10_cn50xx cn56xxp1;
15838+ struct cvmx_pko_mem_debug10_cn50xx cn58xx;
15839+ struct cvmx_pko_mem_debug10_cn50xx cn58xxp1;
15840+};
15841+
15842+union cvmx_pko_mem_debug11 {
15843+ uint64_t u64;
15844+ struct cvmx_pko_mem_debug11_s {
15845+ uint64_t i:1;
15846+ uint64_t back:4;
15847+ uint64_t pool:3;
15848+ uint64_t size:16;
15849+ uint64_t reserved_0_39:40;
15850+ } s;
15851+ struct cvmx_pko_mem_debug11_cn30xx {
15852+ uint64_t i:1;
15853+ uint64_t back:4;
15854+ uint64_t pool:3;
15855+ uint64_t size:16;
15856+ uint64_t ptr:40;
15857+ } cn30xx;
15858+ struct cvmx_pko_mem_debug11_cn30xx cn31xx;
15859+ struct cvmx_pko_mem_debug11_cn30xx cn38xx;
15860+ struct cvmx_pko_mem_debug11_cn30xx cn38xxp2;
15861+ struct cvmx_pko_mem_debug11_cn50xx {
15862+ uint64_t reserved_23_63:41;
15863+ uint64_t maj:1;
15864+ uint64_t uid:3;
15865+ uint64_t sop:1;
15866+ uint64_t len:1;
15867+ uint64_t chk:1;
15868+ uint64_t cnt:13;
15869+ uint64_t mod:3;
15870+ } cn50xx;
15871+ struct cvmx_pko_mem_debug11_cn50xx cn52xx;
15872+ struct cvmx_pko_mem_debug11_cn50xx cn52xxp1;
15873+ struct cvmx_pko_mem_debug11_cn50xx cn56xx;
15874+ struct cvmx_pko_mem_debug11_cn50xx cn56xxp1;
15875+ struct cvmx_pko_mem_debug11_cn50xx cn58xx;
15876+ struct cvmx_pko_mem_debug11_cn50xx cn58xxp1;
15877+};
15878+
15879+union cvmx_pko_mem_debug12 {
15880+ uint64_t u64;
15881+ struct cvmx_pko_mem_debug12_s {
15882+ uint64_t reserved_0_63:64;
15883+ } s;
15884+ struct cvmx_pko_mem_debug12_cn30xx {
15885+ uint64_t data:64;
15886+ } cn30xx;
15887+ struct cvmx_pko_mem_debug12_cn30xx cn31xx;
15888+ struct cvmx_pko_mem_debug12_cn30xx cn38xx;
15889+ struct cvmx_pko_mem_debug12_cn30xx cn38xxp2;
15890+ struct cvmx_pko_mem_debug12_cn50xx {
15891+ uint64_t fau:28;
15892+ uint64_t cmd:14;
15893+ uint64_t segs:6;
15894+ uint64_t size:16;
15895+ } cn50xx;
15896+ struct cvmx_pko_mem_debug12_cn50xx cn52xx;
15897+ struct cvmx_pko_mem_debug12_cn50xx cn52xxp1;
15898+ struct cvmx_pko_mem_debug12_cn50xx cn56xx;
15899+ struct cvmx_pko_mem_debug12_cn50xx cn56xxp1;
15900+ struct cvmx_pko_mem_debug12_cn50xx cn58xx;
15901+ struct cvmx_pko_mem_debug12_cn50xx cn58xxp1;
15902+};
15903+
15904+union cvmx_pko_mem_debug13 {
15905+ uint64_t u64;
15906+ struct cvmx_pko_mem_debug13_s {
15907+ uint64_t i:1;
15908+ uint64_t back:4;
15909+ uint64_t pool:3;
15910+ uint64_t reserved_0_55:56;
15911+ } s;
15912+ struct cvmx_pko_mem_debug13_cn30xx {
15913+ uint64_t reserved_51_63:13;
15914+ uint64_t widx:17;
15915+ uint64_t ridx2:17;
15916+ uint64_t widx2:17;
15917+ } cn30xx;
15918+ struct cvmx_pko_mem_debug13_cn30xx cn31xx;
15919+ struct cvmx_pko_mem_debug13_cn30xx cn38xx;
15920+ struct cvmx_pko_mem_debug13_cn30xx cn38xxp2;
15921+ struct cvmx_pko_mem_debug13_cn50xx {
15922+ uint64_t i:1;
15923+ uint64_t back:4;
15924+ uint64_t pool:3;
15925+ uint64_t size:16;
15926+ uint64_t ptr:40;
15927+ } cn50xx;
15928+ struct cvmx_pko_mem_debug13_cn50xx cn52xx;
15929+ struct cvmx_pko_mem_debug13_cn50xx cn52xxp1;
15930+ struct cvmx_pko_mem_debug13_cn50xx cn56xx;
15931+ struct cvmx_pko_mem_debug13_cn50xx cn56xxp1;
15932+ struct cvmx_pko_mem_debug13_cn50xx cn58xx;
15933+ struct cvmx_pko_mem_debug13_cn50xx cn58xxp1;
15934+};
15935+
15936+union cvmx_pko_mem_debug14 {
15937+ uint64_t u64;
15938+ struct cvmx_pko_mem_debug14_s {
15939+ uint64_t reserved_0_63:64;
15940+ } s;
15941+ struct cvmx_pko_mem_debug14_cn30xx {
15942+ uint64_t reserved_17_63:47;
15943+ uint64_t ridx:17;
15944+ } cn30xx;
15945+ struct cvmx_pko_mem_debug14_cn30xx cn31xx;
15946+ struct cvmx_pko_mem_debug14_cn30xx cn38xx;
15947+ struct cvmx_pko_mem_debug14_cn30xx cn38xxp2;
15948+ struct cvmx_pko_mem_debug14_cn52xx {
15949+ uint64_t data:64;
15950+ } cn52xx;
15951+ struct cvmx_pko_mem_debug14_cn52xx cn52xxp1;
15952+ struct cvmx_pko_mem_debug14_cn52xx cn56xx;
15953+ struct cvmx_pko_mem_debug14_cn52xx cn56xxp1;
15954+};
15955+
15956+union cvmx_pko_mem_debug2 {
15957+ uint64_t u64;
15958+ struct cvmx_pko_mem_debug2_s {
15959+ uint64_t i:1;
15960+ uint64_t back:4;
15961+ uint64_t pool:3;
15962+ uint64_t size:16;
15963+ uint64_t ptr:40;
15964+ } s;
15965+ struct cvmx_pko_mem_debug2_s cn30xx;
15966+ struct cvmx_pko_mem_debug2_s cn31xx;
15967+ struct cvmx_pko_mem_debug2_s cn38xx;
15968+ struct cvmx_pko_mem_debug2_s cn38xxp2;
15969+ struct cvmx_pko_mem_debug2_s cn50xx;
15970+ struct cvmx_pko_mem_debug2_s cn52xx;
15971+ struct cvmx_pko_mem_debug2_s cn52xxp1;
15972+ struct cvmx_pko_mem_debug2_s cn56xx;
15973+ struct cvmx_pko_mem_debug2_s cn56xxp1;
15974+ struct cvmx_pko_mem_debug2_s cn58xx;
15975+ struct cvmx_pko_mem_debug2_s cn58xxp1;
15976+};
15977+
15978+union cvmx_pko_mem_debug3 {
15979+ uint64_t u64;
15980+ struct cvmx_pko_mem_debug3_s {
15981+ uint64_t reserved_0_63:64;
15982+ } s;
15983+ struct cvmx_pko_mem_debug3_cn30xx {
15984+ uint64_t i:1;
15985+ uint64_t back:4;
15986+ uint64_t pool:3;
15987+ uint64_t size:16;
15988+ uint64_t ptr:40;
15989+ } cn30xx;
15990+ struct cvmx_pko_mem_debug3_cn30xx cn31xx;
15991+ struct cvmx_pko_mem_debug3_cn30xx cn38xx;
15992+ struct cvmx_pko_mem_debug3_cn30xx cn38xxp2;
15993+ struct cvmx_pko_mem_debug3_cn50xx {
15994+ uint64_t data:64;
15995+ } cn50xx;
15996+ struct cvmx_pko_mem_debug3_cn50xx cn52xx;
15997+ struct cvmx_pko_mem_debug3_cn50xx cn52xxp1;
15998+ struct cvmx_pko_mem_debug3_cn50xx cn56xx;
15999+ struct cvmx_pko_mem_debug3_cn50xx cn56xxp1;
16000+ struct cvmx_pko_mem_debug3_cn50xx cn58xx;
16001+ struct cvmx_pko_mem_debug3_cn50xx cn58xxp1;
16002+};
16003+
16004+union cvmx_pko_mem_debug4 {
16005+ uint64_t u64;
16006+ struct cvmx_pko_mem_debug4_s {
16007+ uint64_t reserved_0_63:64;
16008+ } s;
16009+ struct cvmx_pko_mem_debug4_cn30xx {
16010+ uint64_t data:64;
16011+ } cn30xx;
16012+ struct cvmx_pko_mem_debug4_cn30xx cn31xx;
16013+ struct cvmx_pko_mem_debug4_cn30xx cn38xx;
16014+ struct cvmx_pko_mem_debug4_cn30xx cn38xxp2;
16015+ struct cvmx_pko_mem_debug4_cn50xx {
16016+ uint64_t cmnd_segs:3;
16017+ uint64_t cmnd_siz:16;
16018+ uint64_t cmnd_off:6;
16019+ uint64_t uid:3;
16020+ uint64_t dread_sop:1;
16021+ uint64_t init_dwrite:1;
16022+ uint64_t chk_once:1;
16023+ uint64_t chk_mode:1;
16024+ uint64_t active:1;
16025+ uint64_t static_p:1;
16026+ uint64_t qos:3;
16027+ uint64_t qcb_ridx:5;
16028+ uint64_t qid_off_max:4;
16029+ uint64_t qid_off:4;
16030+ uint64_t qid_base:8;
16031+ uint64_t wait:1;
16032+ uint64_t minor:2;
16033+ uint64_t major:3;
16034+ } cn50xx;
16035+ struct cvmx_pko_mem_debug4_cn52xx {
16036+ uint64_t curr_siz:8;
16037+ uint64_t curr_off:16;
16038+ uint64_t cmnd_segs:6;
16039+ uint64_t cmnd_siz:16;
16040+ uint64_t cmnd_off:6;
16041+ uint64_t uid:2;
16042+ uint64_t dread_sop:1;
16043+ uint64_t init_dwrite:1;
16044+ uint64_t chk_once:1;
16045+ uint64_t chk_mode:1;
16046+ uint64_t wait:1;
16047+ uint64_t minor:2;
16048+ uint64_t major:3;
16049+ } cn52xx;
16050+ struct cvmx_pko_mem_debug4_cn52xx cn52xxp1;
16051+ struct cvmx_pko_mem_debug4_cn52xx cn56xx;
16052+ struct cvmx_pko_mem_debug4_cn52xx cn56xxp1;
16053+ struct cvmx_pko_mem_debug4_cn50xx cn58xx;
16054+ struct cvmx_pko_mem_debug4_cn50xx cn58xxp1;
16055+};
16056+
16057+union cvmx_pko_mem_debug5 {
16058+ uint64_t u64;
16059+ struct cvmx_pko_mem_debug5_s {
16060+ uint64_t reserved_0_63:64;
16061+ } s;
16062+ struct cvmx_pko_mem_debug5_cn30xx {
16063+ uint64_t dwri_mod:1;
16064+ uint64_t dwri_sop:1;
16065+ uint64_t dwri_len:1;
16066+ uint64_t dwri_cnt:13;
16067+ uint64_t cmnd_siz:16;
16068+ uint64_t uid:1;
16069+ uint64_t xfer_wor:1;
16070+ uint64_t xfer_dwr:1;
16071+ uint64_t cbuf_fre:1;
16072+ uint64_t reserved_27_27:1;
16073+ uint64_t chk_mode:1;
16074+ uint64_t active:1;
16075+ uint64_t qos:3;
16076+ uint64_t qcb_ridx:5;
16077+ uint64_t qid_off:3;
16078+ uint64_t qid_base:7;
16079+ uint64_t wait:1;
16080+ uint64_t minor:2;
16081+ uint64_t major:4;
16082+ } cn30xx;
16083+ struct cvmx_pko_mem_debug5_cn30xx cn31xx;
16084+ struct cvmx_pko_mem_debug5_cn30xx cn38xx;
16085+ struct cvmx_pko_mem_debug5_cn30xx cn38xxp2;
16086+ struct cvmx_pko_mem_debug5_cn50xx {
16087+ uint64_t curr_ptr:29;
16088+ uint64_t curr_siz:16;
16089+ uint64_t curr_off:16;
16090+ uint64_t cmnd_segs:3;
16091+ } cn50xx;
16092+ struct cvmx_pko_mem_debug5_cn52xx {
16093+ uint64_t reserved_54_63:10;
16094+ uint64_t nxt_inflt:6;
16095+ uint64_t curr_ptr:40;
16096+ uint64_t curr_siz:8;
16097+ } cn52xx;
16098+ struct cvmx_pko_mem_debug5_cn52xx cn52xxp1;
16099+ struct cvmx_pko_mem_debug5_cn52xx cn56xx;
16100+ struct cvmx_pko_mem_debug5_cn52xx cn56xxp1;
16101+ struct cvmx_pko_mem_debug5_cn50xx cn58xx;
16102+ struct cvmx_pko_mem_debug5_cn50xx cn58xxp1;
16103+};
16104+
16105+union cvmx_pko_mem_debug6 {
16106+ uint64_t u64;
16107+ struct cvmx_pko_mem_debug6_s {
16108+ uint64_t reserved_37_63:27;
16109+ uint64_t qid_offres:4;
16110+ uint64_t qid_offths:4;
16111+ uint64_t preempter:1;
16112+ uint64_t preemptee:1;
16113+ uint64_t preempted:1;
16114+ uint64_t active:1;
16115+ uint64_t statc:1;
16116+ uint64_t qos:3;
16117+ uint64_t qcb_ridx:5;
16118+ uint64_t qid_offmax:4;
16119+ uint64_t reserved_0_11:12;
16120+ } s;
16121+ struct cvmx_pko_mem_debug6_cn30xx {
16122+ uint64_t reserved_11_63:53;
16123+ uint64_t qid_offm:3;
16124+ uint64_t static_p:1;
16125+ uint64_t work_min:3;
16126+ uint64_t dwri_chk:1;
16127+ uint64_t dwri_uid:1;
16128+ uint64_t dwri_mod:2;
16129+ } cn30xx;
16130+ struct cvmx_pko_mem_debug6_cn30xx cn31xx;
16131+ struct cvmx_pko_mem_debug6_cn30xx cn38xx;
16132+ struct cvmx_pko_mem_debug6_cn30xx cn38xxp2;
16133+ struct cvmx_pko_mem_debug6_cn50xx {
16134+ uint64_t reserved_11_63:53;
16135+ uint64_t curr_ptr:11;
16136+ } cn50xx;
16137+ struct cvmx_pko_mem_debug6_cn52xx {
16138+ uint64_t reserved_37_63:27;
16139+ uint64_t qid_offres:4;
16140+ uint64_t qid_offths:4;
16141+ uint64_t preempter:1;
16142+ uint64_t preemptee:1;
16143+ uint64_t preempted:1;
16144+ uint64_t active:1;
16145+ uint64_t statc:1;
16146+ uint64_t qos:3;
16147+ uint64_t qcb_ridx:5;
16148+ uint64_t qid_offmax:4;
16149+ uint64_t qid_off:4;
16150+ uint64_t qid_base:8;
16151+ } cn52xx;
16152+ struct cvmx_pko_mem_debug6_cn52xx cn52xxp1;
16153+ struct cvmx_pko_mem_debug6_cn52xx cn56xx;
16154+ struct cvmx_pko_mem_debug6_cn52xx cn56xxp1;
16155+ struct cvmx_pko_mem_debug6_cn50xx cn58xx;
16156+ struct cvmx_pko_mem_debug6_cn50xx cn58xxp1;
16157+};
16158+
16159+union cvmx_pko_mem_debug7 {
16160+ uint64_t u64;
16161+ struct cvmx_pko_mem_debug7_s {
16162+ uint64_t qos:5;
16163+ uint64_t tail:1;
16164+ uint64_t reserved_0_57:58;
16165+ } s;
16166+ struct cvmx_pko_mem_debug7_cn30xx {
16167+ uint64_t reserved_58_63:6;
16168+ uint64_t dwb:9;
16169+ uint64_t start:33;
16170+ uint64_t size:16;
16171+ } cn30xx;
16172+ struct cvmx_pko_mem_debug7_cn30xx cn31xx;
16173+ struct cvmx_pko_mem_debug7_cn30xx cn38xx;
16174+ struct cvmx_pko_mem_debug7_cn30xx cn38xxp2;
16175+ struct cvmx_pko_mem_debug7_cn50xx {
16176+ uint64_t qos:5;
16177+ uint64_t tail:1;
16178+ uint64_t buf_siz:13;
16179+ uint64_t buf_ptr:33;
16180+ uint64_t qcb_widx:6;
16181+ uint64_t qcb_ridx:6;
16182+ } cn50xx;
16183+ struct cvmx_pko_mem_debug7_cn50xx cn52xx;
16184+ struct cvmx_pko_mem_debug7_cn50xx cn52xxp1;
16185+ struct cvmx_pko_mem_debug7_cn50xx cn56xx;
16186+ struct cvmx_pko_mem_debug7_cn50xx cn56xxp1;
16187+ struct cvmx_pko_mem_debug7_cn50xx cn58xx;
16188+ struct cvmx_pko_mem_debug7_cn50xx cn58xxp1;
16189+};
16190+
16191+union cvmx_pko_mem_debug8 {
16192+ uint64_t u64;
16193+ struct cvmx_pko_mem_debug8_s {
16194+ uint64_t reserved_59_63:5;
16195+ uint64_t tail:1;
16196+ uint64_t buf_siz:13;
16197+ uint64_t reserved_0_44:45;
16198+ } s;
16199+ struct cvmx_pko_mem_debug8_cn30xx {
16200+ uint64_t qos:5;
16201+ uint64_t tail:1;
16202+ uint64_t buf_siz:13;
16203+ uint64_t buf_ptr:33;
16204+ uint64_t qcb_widx:6;
16205+ uint64_t qcb_ridx:6;
16206+ } cn30xx;
16207+ struct cvmx_pko_mem_debug8_cn30xx cn31xx;
16208+ struct cvmx_pko_mem_debug8_cn30xx cn38xx;
16209+ struct cvmx_pko_mem_debug8_cn30xx cn38xxp2;
16210+ struct cvmx_pko_mem_debug8_cn50xx {
16211+ uint64_t reserved_28_63:36;
16212+ uint64_t doorbell:20;
16213+ uint64_t reserved_6_7:2;
16214+ uint64_t static_p:1;
16215+ uint64_t s_tail:1;
16216+ uint64_t static_q:1;
16217+ uint64_t qos:3;
16218+ } cn50xx;
16219+ struct cvmx_pko_mem_debug8_cn52xx {
16220+ uint64_t reserved_29_63:35;
16221+ uint64_t preempter:1;
16222+ uint64_t doorbell:20;
16223+ uint64_t reserved_7_7:1;
16224+ uint64_t preemptee:1;
16225+ uint64_t static_p:1;
16226+ uint64_t s_tail:1;
16227+ uint64_t static_q:1;
16228+ uint64_t qos:3;
16229+ } cn52xx;
16230+ struct cvmx_pko_mem_debug8_cn52xx cn52xxp1;
16231+ struct cvmx_pko_mem_debug8_cn52xx cn56xx;
16232+ struct cvmx_pko_mem_debug8_cn52xx cn56xxp1;
16233+ struct cvmx_pko_mem_debug8_cn50xx cn58xx;
16234+ struct cvmx_pko_mem_debug8_cn50xx cn58xxp1;
16235+};
16236+
16237+union cvmx_pko_mem_debug9 {
16238+ uint64_t u64;
16239+ struct cvmx_pko_mem_debug9_s {
16240+ uint64_t reserved_49_63:15;
16241+ uint64_t ptrs0:17;
16242+ uint64_t reserved_0_31:32;
16243+ } s;
16244+ struct cvmx_pko_mem_debug9_cn30xx {
16245+ uint64_t reserved_28_63:36;
16246+ uint64_t doorbell:20;
16247+ uint64_t reserved_5_7:3;
16248+ uint64_t s_tail:1;
16249+ uint64_t static_q:1;
16250+ uint64_t qos:3;
16251+ } cn30xx;
16252+ struct cvmx_pko_mem_debug9_cn30xx cn31xx;
16253+ struct cvmx_pko_mem_debug9_cn38xx {
16254+ uint64_t reserved_28_63:36;
16255+ uint64_t doorbell:20;
16256+ uint64_t reserved_6_7:2;
16257+ uint64_t static_p:1;
16258+ uint64_t s_tail:1;
16259+ uint64_t static_q:1;
16260+ uint64_t qos:3;
16261+ } cn38xx;
16262+ struct cvmx_pko_mem_debug9_cn38xx cn38xxp2;
16263+ struct cvmx_pko_mem_debug9_cn50xx {
16264+ uint64_t reserved_49_63:15;
16265+ uint64_t ptrs0:17;
16266+ uint64_t reserved_17_31:15;
16267+ uint64_t ptrs3:17;
16268+ } cn50xx;
16269+ struct cvmx_pko_mem_debug9_cn50xx cn52xx;
16270+ struct cvmx_pko_mem_debug9_cn50xx cn52xxp1;
16271+ struct cvmx_pko_mem_debug9_cn50xx cn56xx;
16272+ struct cvmx_pko_mem_debug9_cn50xx cn56xxp1;
16273+ struct cvmx_pko_mem_debug9_cn50xx cn58xx;
16274+ struct cvmx_pko_mem_debug9_cn50xx cn58xxp1;
16275+};
16276+
16277+union cvmx_pko_mem_port_ptrs {
16278+ uint64_t u64;
16279+ struct cvmx_pko_mem_port_ptrs_s {
16280+ uint64_t reserved_62_63:2;
16281+ uint64_t static_p:1;
16282+ uint64_t qos_mask:8;
16283+ uint64_t reserved_16_52:37;
16284+ uint64_t bp_port:6;
16285+ uint64_t eid:4;
16286+ uint64_t pid:6;
16287+ } s;
16288+ struct cvmx_pko_mem_port_ptrs_s cn52xx;
16289+ struct cvmx_pko_mem_port_ptrs_s cn52xxp1;
16290+ struct cvmx_pko_mem_port_ptrs_s cn56xx;
16291+ struct cvmx_pko_mem_port_ptrs_s cn56xxp1;
16292+};
16293+
16294+union cvmx_pko_mem_port_qos {
16295+ uint64_t u64;
16296+ struct cvmx_pko_mem_port_qos_s {
16297+ uint64_t reserved_61_63:3;
16298+ uint64_t qos_mask:8;
16299+ uint64_t reserved_10_52:43;
16300+ uint64_t eid:4;
16301+ uint64_t pid:6;
16302+ } s;
16303+ struct cvmx_pko_mem_port_qos_s cn52xx;
16304+ struct cvmx_pko_mem_port_qos_s cn52xxp1;
16305+ struct cvmx_pko_mem_port_qos_s cn56xx;
16306+ struct cvmx_pko_mem_port_qos_s cn56xxp1;
16307+};
16308+
16309+union cvmx_pko_mem_port_rate0 {
16310+ uint64_t u64;
16311+ struct cvmx_pko_mem_port_rate0_s {
16312+ uint64_t reserved_51_63:13;
16313+ uint64_t rate_word:19;
16314+ uint64_t rate_pkt:24;
16315+ uint64_t reserved_6_7:2;
16316+ uint64_t pid:6;
16317+ } s;
16318+ struct cvmx_pko_mem_port_rate0_s cn52xx;
16319+ struct cvmx_pko_mem_port_rate0_s cn52xxp1;
16320+ struct cvmx_pko_mem_port_rate0_s cn56xx;
16321+ struct cvmx_pko_mem_port_rate0_s cn56xxp1;
16322+};
16323+
16324+union cvmx_pko_mem_port_rate1 {
16325+ uint64_t u64;
16326+ struct cvmx_pko_mem_port_rate1_s {
16327+ uint64_t reserved_32_63:32;
16328+ uint64_t rate_lim:24;
16329+ uint64_t reserved_6_7:2;
16330+ uint64_t pid:6;
16331+ } s;
16332+ struct cvmx_pko_mem_port_rate1_s cn52xx;
16333+ struct cvmx_pko_mem_port_rate1_s cn52xxp1;
16334+ struct cvmx_pko_mem_port_rate1_s cn56xx;
16335+ struct cvmx_pko_mem_port_rate1_s cn56xxp1;
16336+};
16337+
16338+union cvmx_pko_mem_queue_ptrs {
16339+ uint64_t u64;
16340+ struct cvmx_pko_mem_queue_ptrs_s {
16341+ uint64_t s_tail:1;
16342+ uint64_t static_p:1;
16343+ uint64_t static_q:1;
16344+ uint64_t qos_mask:8;
16345+ uint64_t buf_ptr:36;
16346+ uint64_t tail:1;
16347+ uint64_t index:3;
16348+ uint64_t port:6;
16349+ uint64_t queue:7;
16350+ } s;
16351+ struct cvmx_pko_mem_queue_ptrs_s cn30xx;
16352+ struct cvmx_pko_mem_queue_ptrs_s cn31xx;
16353+ struct cvmx_pko_mem_queue_ptrs_s cn38xx;
16354+ struct cvmx_pko_mem_queue_ptrs_s cn38xxp2;
16355+ struct cvmx_pko_mem_queue_ptrs_s cn50xx;
16356+ struct cvmx_pko_mem_queue_ptrs_s cn52xx;
16357+ struct cvmx_pko_mem_queue_ptrs_s cn52xxp1;
16358+ struct cvmx_pko_mem_queue_ptrs_s cn56xx;
16359+ struct cvmx_pko_mem_queue_ptrs_s cn56xxp1;
16360+ struct cvmx_pko_mem_queue_ptrs_s cn58xx;
16361+ struct cvmx_pko_mem_queue_ptrs_s cn58xxp1;
16362+};
16363+
16364+union cvmx_pko_mem_queue_qos {
16365+ uint64_t u64;
16366+ struct cvmx_pko_mem_queue_qos_s {
16367+ uint64_t reserved_61_63:3;
16368+ uint64_t qos_mask:8;
16369+ uint64_t reserved_13_52:40;
16370+ uint64_t pid:6;
16371+ uint64_t qid:7;
16372+ } s;
16373+ struct cvmx_pko_mem_queue_qos_s cn30xx;
16374+ struct cvmx_pko_mem_queue_qos_s cn31xx;
16375+ struct cvmx_pko_mem_queue_qos_s cn38xx;
16376+ struct cvmx_pko_mem_queue_qos_s cn38xxp2;
16377+ struct cvmx_pko_mem_queue_qos_s cn50xx;
16378+ struct cvmx_pko_mem_queue_qos_s cn52xx;
16379+ struct cvmx_pko_mem_queue_qos_s cn52xxp1;
16380+ struct cvmx_pko_mem_queue_qos_s cn56xx;
16381+ struct cvmx_pko_mem_queue_qos_s cn56xxp1;
16382+ struct cvmx_pko_mem_queue_qos_s cn58xx;
16383+ struct cvmx_pko_mem_queue_qos_s cn58xxp1;
16384+};
16385+
16386+union cvmx_pko_reg_bist_result {
16387+ uint64_t u64;
16388+ struct cvmx_pko_reg_bist_result_s {
16389+ uint64_t reserved_0_63:64;
16390+ } s;
16391+ struct cvmx_pko_reg_bist_result_cn30xx {
16392+ uint64_t reserved_27_63:37;
16393+ uint64_t psb2:5;
16394+ uint64_t count:1;
16395+ uint64_t rif:1;
16396+ uint64_t wif:1;
16397+ uint64_t ncb:1;
16398+ uint64_t out:1;
16399+ uint64_t crc:1;
16400+ uint64_t chk:1;
16401+ uint64_t qsb:2;
16402+ uint64_t qcb:2;
16403+ uint64_t pdb:4;
16404+ uint64_t psb:7;
16405+ } cn30xx;
16406+ struct cvmx_pko_reg_bist_result_cn30xx cn31xx;
16407+ struct cvmx_pko_reg_bist_result_cn30xx cn38xx;
16408+ struct cvmx_pko_reg_bist_result_cn30xx cn38xxp2;
16409+ struct cvmx_pko_reg_bist_result_cn50xx {
16410+ uint64_t reserved_33_63:31;
16411+ uint64_t csr:1;
16412+ uint64_t iob:1;
16413+ uint64_t out_crc:1;
16414+ uint64_t out_ctl:3;
16415+ uint64_t out_sta:1;
16416+ uint64_t out_wif:1;
16417+ uint64_t prt_chk:3;
16418+ uint64_t prt_nxt:1;
16419+ uint64_t prt_psb:6;
16420+ uint64_t ncb_inb:2;
16421+ uint64_t prt_qcb:2;
16422+ uint64_t prt_qsb:3;
16423+ uint64_t dat_dat:4;
16424+ uint64_t dat_ptr:4;
16425+ } cn50xx;
16426+ struct cvmx_pko_reg_bist_result_cn52xx {
16427+ uint64_t reserved_35_63:29;
16428+ uint64_t csr:1;
16429+ uint64_t iob:1;
16430+ uint64_t out_dat:1;
16431+ uint64_t out_ctl:3;
16432+ uint64_t out_sta:1;
16433+ uint64_t out_wif:1;
16434+ uint64_t prt_chk:3;
16435+ uint64_t prt_nxt:1;
16436+ uint64_t prt_psb:8;
16437+ uint64_t ncb_inb:2;
16438+ uint64_t prt_qcb:2;
16439+ uint64_t prt_qsb:3;
16440+ uint64_t prt_ctl:2;
16441+ uint64_t dat_dat:2;
16442+ uint64_t dat_ptr:4;
16443+ } cn52xx;
16444+ struct cvmx_pko_reg_bist_result_cn52xx cn52xxp1;
16445+ struct cvmx_pko_reg_bist_result_cn52xx cn56xx;
16446+ struct cvmx_pko_reg_bist_result_cn52xx cn56xxp1;
16447+ struct cvmx_pko_reg_bist_result_cn50xx cn58xx;
16448+ struct cvmx_pko_reg_bist_result_cn50xx cn58xxp1;
16449+};
16450+
16451+union cvmx_pko_reg_cmd_buf {
16452+ uint64_t u64;
16453+ struct cvmx_pko_reg_cmd_buf_s {
16454+ uint64_t reserved_23_63:41;
16455+ uint64_t pool:3;
16456+ uint64_t reserved_13_19:7;
16457+ uint64_t size:13;
16458+ } s;
16459+ struct cvmx_pko_reg_cmd_buf_s cn30xx;
16460+ struct cvmx_pko_reg_cmd_buf_s cn31xx;
16461+ struct cvmx_pko_reg_cmd_buf_s cn38xx;
16462+ struct cvmx_pko_reg_cmd_buf_s cn38xxp2;
16463+ struct cvmx_pko_reg_cmd_buf_s cn50xx;
16464+ struct cvmx_pko_reg_cmd_buf_s cn52xx;
16465+ struct cvmx_pko_reg_cmd_buf_s cn52xxp1;
16466+ struct cvmx_pko_reg_cmd_buf_s cn56xx;
16467+ struct cvmx_pko_reg_cmd_buf_s cn56xxp1;
16468+ struct cvmx_pko_reg_cmd_buf_s cn58xx;
16469+ struct cvmx_pko_reg_cmd_buf_s cn58xxp1;
16470+};
16471+
16472+union cvmx_pko_reg_crc_ctlx {
16473+ uint64_t u64;
16474+ struct cvmx_pko_reg_crc_ctlx_s {
16475+ uint64_t reserved_2_63:62;
16476+ uint64_t invres:1;
16477+ uint64_t refin:1;
16478+ } s;
16479+ struct cvmx_pko_reg_crc_ctlx_s cn38xx;
16480+ struct cvmx_pko_reg_crc_ctlx_s cn38xxp2;
16481+ struct cvmx_pko_reg_crc_ctlx_s cn58xx;
16482+ struct cvmx_pko_reg_crc_ctlx_s cn58xxp1;
16483+};
16484+
16485+union cvmx_pko_reg_crc_enable {
16486+ uint64_t u64;
16487+ struct cvmx_pko_reg_crc_enable_s {
16488+ uint64_t reserved_32_63:32;
16489+ uint64_t enable:32;
16490+ } s;
16491+ struct cvmx_pko_reg_crc_enable_s cn38xx;
16492+ struct cvmx_pko_reg_crc_enable_s cn38xxp2;
16493+ struct cvmx_pko_reg_crc_enable_s cn58xx;
16494+ struct cvmx_pko_reg_crc_enable_s cn58xxp1;
16495+};
16496+
16497+union cvmx_pko_reg_crc_ivx {
16498+ uint64_t u64;
16499+ struct cvmx_pko_reg_crc_ivx_s {
16500+ uint64_t reserved_32_63:32;
16501+ uint64_t iv:32;
16502+ } s;
16503+ struct cvmx_pko_reg_crc_ivx_s cn38xx;
16504+ struct cvmx_pko_reg_crc_ivx_s cn38xxp2;
16505+ struct cvmx_pko_reg_crc_ivx_s cn58xx;
16506+ struct cvmx_pko_reg_crc_ivx_s cn58xxp1;
16507+};
16508+
16509+union cvmx_pko_reg_debug0 {
16510+ uint64_t u64;
16511+ struct cvmx_pko_reg_debug0_s {
16512+ uint64_t asserts:64;
16513+ } s;
16514+ struct cvmx_pko_reg_debug0_cn30xx {
16515+ uint64_t reserved_17_63:47;
16516+ uint64_t asserts:17;
16517+ } cn30xx;
16518+ struct cvmx_pko_reg_debug0_cn30xx cn31xx;
16519+ struct cvmx_pko_reg_debug0_cn30xx cn38xx;
16520+ struct cvmx_pko_reg_debug0_cn30xx cn38xxp2;
16521+ struct cvmx_pko_reg_debug0_s cn50xx;
16522+ struct cvmx_pko_reg_debug0_s cn52xx;
16523+ struct cvmx_pko_reg_debug0_s cn52xxp1;
16524+ struct cvmx_pko_reg_debug0_s cn56xx;
16525+ struct cvmx_pko_reg_debug0_s cn56xxp1;
16526+ struct cvmx_pko_reg_debug0_s cn58xx;
16527+ struct cvmx_pko_reg_debug0_s cn58xxp1;
16528+};
16529+
16530+union cvmx_pko_reg_debug1 {
16531+ uint64_t u64;
16532+ struct cvmx_pko_reg_debug1_s {
16533+ uint64_t asserts:64;
16534+ } s;
16535+ struct cvmx_pko_reg_debug1_s cn50xx;
16536+ struct cvmx_pko_reg_debug1_s cn52xx;
16537+ struct cvmx_pko_reg_debug1_s cn52xxp1;
16538+ struct cvmx_pko_reg_debug1_s cn56xx;
16539+ struct cvmx_pko_reg_debug1_s cn56xxp1;
16540+ struct cvmx_pko_reg_debug1_s cn58xx;
16541+ struct cvmx_pko_reg_debug1_s cn58xxp1;
16542+};
16543+
16544+union cvmx_pko_reg_debug2 {
16545+ uint64_t u64;
16546+ struct cvmx_pko_reg_debug2_s {
16547+ uint64_t asserts:64;
16548+ } s;
16549+ struct cvmx_pko_reg_debug2_s cn50xx;
16550+ struct cvmx_pko_reg_debug2_s cn52xx;
16551+ struct cvmx_pko_reg_debug2_s cn52xxp1;
16552+ struct cvmx_pko_reg_debug2_s cn56xx;
16553+ struct cvmx_pko_reg_debug2_s cn56xxp1;
16554+ struct cvmx_pko_reg_debug2_s cn58xx;
16555+ struct cvmx_pko_reg_debug2_s cn58xxp1;
16556+};
16557+
16558+union cvmx_pko_reg_debug3 {
16559+ uint64_t u64;
16560+ struct cvmx_pko_reg_debug3_s {
16561+ uint64_t asserts:64;
16562+ } s;
16563+ struct cvmx_pko_reg_debug3_s cn50xx;
16564+ struct cvmx_pko_reg_debug3_s cn52xx;
16565+ struct cvmx_pko_reg_debug3_s cn52xxp1;
16566+ struct cvmx_pko_reg_debug3_s cn56xx;
16567+ struct cvmx_pko_reg_debug3_s cn56xxp1;
16568+ struct cvmx_pko_reg_debug3_s cn58xx;
16569+ struct cvmx_pko_reg_debug3_s cn58xxp1;
16570+};
16571+
16572+union cvmx_pko_reg_engine_inflight {
16573+ uint64_t u64;
16574+ struct cvmx_pko_reg_engine_inflight_s {
16575+ uint64_t reserved_40_63:24;
16576+ uint64_t engine9:4;
16577+ uint64_t engine8:4;
16578+ uint64_t engine7:4;
16579+ uint64_t engine6:4;
16580+ uint64_t engine5:4;
16581+ uint64_t engine4:4;
16582+ uint64_t engine3:4;
16583+ uint64_t engine2:4;
16584+ uint64_t engine1:4;
16585+ uint64_t engine0:4;
16586+ } s;
16587+ struct cvmx_pko_reg_engine_inflight_s cn52xx;
16588+ struct cvmx_pko_reg_engine_inflight_s cn52xxp1;
16589+ struct cvmx_pko_reg_engine_inflight_s cn56xx;
16590+ struct cvmx_pko_reg_engine_inflight_s cn56xxp1;
16591+};
16592+
16593+union cvmx_pko_reg_engine_thresh {
16594+ uint64_t u64;
16595+ struct cvmx_pko_reg_engine_thresh_s {
16596+ uint64_t reserved_10_63:54;
16597+ uint64_t mask:10;
16598+ } s;
16599+ struct cvmx_pko_reg_engine_thresh_s cn52xx;
16600+ struct cvmx_pko_reg_engine_thresh_s cn52xxp1;
16601+ struct cvmx_pko_reg_engine_thresh_s cn56xx;
16602+ struct cvmx_pko_reg_engine_thresh_s cn56xxp1;
16603+};
16604+
16605+union cvmx_pko_reg_error {
16606+ uint64_t u64;
16607+ struct cvmx_pko_reg_error_s {
16608+ uint64_t reserved_3_63:61;
16609+ uint64_t currzero:1;
16610+ uint64_t doorbell:1;
16611+ uint64_t parity:1;
16612+ } s;
16613+ struct cvmx_pko_reg_error_cn30xx {
16614+ uint64_t reserved_2_63:62;
16615+ uint64_t doorbell:1;
16616+ uint64_t parity:1;
16617+ } cn30xx;
16618+ struct cvmx_pko_reg_error_cn30xx cn31xx;
16619+ struct cvmx_pko_reg_error_cn30xx cn38xx;
16620+ struct cvmx_pko_reg_error_cn30xx cn38xxp2;
16621+ struct cvmx_pko_reg_error_s cn50xx;
16622+ struct cvmx_pko_reg_error_s cn52xx;
16623+ struct cvmx_pko_reg_error_s cn52xxp1;
16624+ struct cvmx_pko_reg_error_s cn56xx;
16625+ struct cvmx_pko_reg_error_s cn56xxp1;
16626+ struct cvmx_pko_reg_error_s cn58xx;
16627+ struct cvmx_pko_reg_error_s cn58xxp1;
16628+};
16629+
16630+union cvmx_pko_reg_flags {
16631+ uint64_t u64;
16632+ struct cvmx_pko_reg_flags_s {
16633+ uint64_t reserved_4_63:60;
16634+ uint64_t reset:1;
16635+ uint64_t store_be:1;
16636+ uint64_t ena_dwb:1;
16637+ uint64_t ena_pko:1;
16638+ } s;
16639+ struct cvmx_pko_reg_flags_s cn30xx;
16640+ struct cvmx_pko_reg_flags_s cn31xx;
16641+ struct cvmx_pko_reg_flags_s cn38xx;
16642+ struct cvmx_pko_reg_flags_s cn38xxp2;
16643+ struct cvmx_pko_reg_flags_s cn50xx;
16644+ struct cvmx_pko_reg_flags_s cn52xx;
16645+ struct cvmx_pko_reg_flags_s cn52xxp1;
16646+ struct cvmx_pko_reg_flags_s cn56xx;
16647+ struct cvmx_pko_reg_flags_s cn56xxp1;
16648+ struct cvmx_pko_reg_flags_s cn58xx;
16649+ struct cvmx_pko_reg_flags_s cn58xxp1;
16650+};
16651+
16652+union cvmx_pko_reg_gmx_port_mode {
16653+ uint64_t u64;
16654+ struct cvmx_pko_reg_gmx_port_mode_s {
16655+ uint64_t reserved_6_63:58;
16656+ uint64_t mode1:3;
16657+ uint64_t mode0:3;
16658+ } s;
16659+ struct cvmx_pko_reg_gmx_port_mode_s cn30xx;
16660+ struct cvmx_pko_reg_gmx_port_mode_s cn31xx;
16661+ struct cvmx_pko_reg_gmx_port_mode_s cn38xx;
16662+ struct cvmx_pko_reg_gmx_port_mode_s cn38xxp2;
16663+ struct cvmx_pko_reg_gmx_port_mode_s cn50xx;
16664+ struct cvmx_pko_reg_gmx_port_mode_s cn52xx;
16665+ struct cvmx_pko_reg_gmx_port_mode_s cn52xxp1;
16666+ struct cvmx_pko_reg_gmx_port_mode_s cn56xx;
16667+ struct cvmx_pko_reg_gmx_port_mode_s cn56xxp1;
16668+ struct cvmx_pko_reg_gmx_port_mode_s cn58xx;
16669+ struct cvmx_pko_reg_gmx_port_mode_s cn58xxp1;
16670+};
16671+
16672+union cvmx_pko_reg_int_mask {
16673+ uint64_t u64;
16674+ struct cvmx_pko_reg_int_mask_s {
16675+ uint64_t reserved_3_63:61;
16676+ uint64_t currzero:1;
16677+ uint64_t doorbell:1;
16678+ uint64_t parity:1;
16679+ } s;
16680+ struct cvmx_pko_reg_int_mask_cn30xx {
16681+ uint64_t reserved_2_63:62;
16682+ uint64_t doorbell:1;
16683+ uint64_t parity:1;
16684+ } cn30xx;
16685+ struct cvmx_pko_reg_int_mask_cn30xx cn31xx;
16686+ struct cvmx_pko_reg_int_mask_cn30xx cn38xx;
16687+ struct cvmx_pko_reg_int_mask_cn30xx cn38xxp2;
16688+ struct cvmx_pko_reg_int_mask_s cn50xx;
16689+ struct cvmx_pko_reg_int_mask_s cn52xx;
16690+ struct cvmx_pko_reg_int_mask_s cn52xxp1;
16691+ struct cvmx_pko_reg_int_mask_s cn56xx;
16692+ struct cvmx_pko_reg_int_mask_s cn56xxp1;
16693+ struct cvmx_pko_reg_int_mask_s cn58xx;
16694+ struct cvmx_pko_reg_int_mask_s cn58xxp1;
16695+};
16696+
16697+union cvmx_pko_reg_queue_mode {
16698+ uint64_t u64;
16699+ struct cvmx_pko_reg_queue_mode_s {
16700+ uint64_t reserved_2_63:62;
16701+ uint64_t mode:2;
16702+ } s;
16703+ struct cvmx_pko_reg_queue_mode_s cn30xx;
16704+ struct cvmx_pko_reg_queue_mode_s cn31xx;
16705+ struct cvmx_pko_reg_queue_mode_s cn38xx;
16706+ struct cvmx_pko_reg_queue_mode_s cn38xxp2;
16707+ struct cvmx_pko_reg_queue_mode_s cn50xx;
16708+ struct cvmx_pko_reg_queue_mode_s cn52xx;
16709+ struct cvmx_pko_reg_queue_mode_s cn52xxp1;
16710+ struct cvmx_pko_reg_queue_mode_s cn56xx;
16711+ struct cvmx_pko_reg_queue_mode_s cn56xxp1;
16712+ struct cvmx_pko_reg_queue_mode_s cn58xx;
16713+ struct cvmx_pko_reg_queue_mode_s cn58xxp1;
16714+};
16715+
16716+union cvmx_pko_reg_queue_ptrs1 {
16717+ uint64_t u64;
16718+ struct cvmx_pko_reg_queue_ptrs1_s {
16719+ uint64_t reserved_2_63:62;
16720+ uint64_t idx3:1;
16721+ uint64_t qid7:1;
16722+ } s;
16723+ struct cvmx_pko_reg_queue_ptrs1_s cn50xx;
16724+ struct cvmx_pko_reg_queue_ptrs1_s cn52xx;
16725+ struct cvmx_pko_reg_queue_ptrs1_s cn52xxp1;
16726+ struct cvmx_pko_reg_queue_ptrs1_s cn56xx;
16727+ struct cvmx_pko_reg_queue_ptrs1_s cn56xxp1;
16728+ struct cvmx_pko_reg_queue_ptrs1_s cn58xx;
16729+ struct cvmx_pko_reg_queue_ptrs1_s cn58xxp1;
16730+};
16731+
16732+union cvmx_pko_reg_read_idx {
16733+ uint64_t u64;
16734+ struct cvmx_pko_reg_read_idx_s {
16735+ uint64_t reserved_16_63:48;
16736+ uint64_t inc:8;
16737+ uint64_t index:8;
16738+ } s;
16739+ struct cvmx_pko_reg_read_idx_s cn30xx;
16740+ struct cvmx_pko_reg_read_idx_s cn31xx;
16741+ struct cvmx_pko_reg_read_idx_s cn38xx;
16742+ struct cvmx_pko_reg_read_idx_s cn38xxp2;
16743+ struct cvmx_pko_reg_read_idx_s cn50xx;
16744+ struct cvmx_pko_reg_read_idx_s cn52xx;
16745+ struct cvmx_pko_reg_read_idx_s cn52xxp1;
16746+ struct cvmx_pko_reg_read_idx_s cn56xx;
16747+ struct cvmx_pko_reg_read_idx_s cn56xxp1;
16748+ struct cvmx_pko_reg_read_idx_s cn58xx;
16749+ struct cvmx_pko_reg_read_idx_s cn58xxp1;
16750+};
16751+
16752+#endif
16753--- /dev/null
16754+++ b/drivers/staging/octeon/cvmx-pko.c
16755@@ -0,0 +1,506 @@
16756+/***********************license start***************
16757+ * Author: Cavium Networks
16758+ *
16759+ * Contact: support@caviumnetworks.com
16760+ * This file is part of the OCTEON SDK
16761+ *
16762+ * Copyright (c) 2003-2008 Cavium Networks
16763+ *
16764+ * This file is free software; you can redistribute it and/or modify
16765+ * it under the terms of the GNU General Public License, Version 2, as
16766+ * published by the Free Software Foundation.
16767+ *
16768+ * This file is distributed in the hope that it will be useful, but
16769+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
16770+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16771+ * NONINFRINGEMENT. See the GNU General Public License for more
16772+ * details.
16773+ *
16774+ * You should have received a copy of the GNU General Public License
16775+ * along with this file; if not, write to the Free Software
16776+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16777+ * or visit http://www.gnu.org/licenses/.
16778+ *
16779+ * This file may also be available under a different license from Cavium.
16780+ * Contact Cavium Networks for more information
16781+ ***********************license end**************************************/
16782+
16783+/*
16784+ * Support library for the hardware Packet Output unit.
16785+ */
16786+
16787+#include <asm/octeon/octeon.h>
16788+
16789+#include "cvmx-config.h"
16790+#include "cvmx-pko.h"
16791+#include "cvmx-helper.h"
16792+
16793+/**
16794+ * Internal state of packet output
16795+ */
16796+
16797+/**
16798+ * Call before any other calls to initialize the packet
16799+ * output system. This does chip global config, and should only be
16800+ * done by one core.
16801+ */
16802+
16803+void cvmx_pko_initialize_global(void)
16804+{
16805+ int i;
16806+ uint64_t priority = 8;
16807+ union cvmx_pko_reg_cmd_buf config;
16808+
16809+ /*
16810+ * Set the size of the PKO command buffers to an odd number of
16811+ * 64bit words. This allows the normal two word send to stay
16812+ * aligned and never span a comamnd word buffer.
16813+ */
16814+ config.u64 = 0;
16815+ config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL;
16816+ config.s.size = CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE / 8 - 1;
16817+
16818+ cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);
16819+
16820+ for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++)
16821+ cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1,
16822+ &priority);
16823+
16824+ /*
16825+ * If we aren't using all of the queues optimize PKO's
16826+ * internal memory.
16827+ */
16828+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)
16829+ || OCTEON_IS_MODEL(OCTEON_CN56XX)
16830+ || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
16831+ int num_interfaces = cvmx_helper_get_number_of_interfaces();
16832+ int last_port =
16833+ cvmx_helper_get_last_ipd_port(num_interfaces - 1);
16834+ int max_queues =
16835+ cvmx_pko_get_base_queue(last_port) +
16836+ cvmx_pko_get_num_queues(last_port);
16837+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
16838+ if (max_queues <= 32)
16839+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
16840+ else if (max_queues <= 64)
16841+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
16842+ } else {
16843+ if (max_queues <= 64)
16844+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
16845+ else if (max_queues <= 128)
16846+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
16847+ }
16848+ }
16849+}
16850+
16851+/**
16852+ * This function does per-core initialization required by the PKO routines.
16853+ * This must be called on all cores that will do packet output, and must
16854+ * be called after the FPA has been initialized and filled with pages.
16855+ *
16856+ * Returns 0 on success
16857+ * !0 on failure
16858+ */
16859+int cvmx_pko_initialize_local(void)
16860+{
16861+ /* Nothing to do */
16862+ return 0;
16863+}
16864+
16865+/**
16866+ * Enables the packet output hardware. It must already be
16867+ * configured.
16868+ */
16869+void cvmx_pko_enable(void)
16870+{
16871+ union cvmx_pko_reg_flags flags;
16872+
16873+ flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
16874+ if (flags.s.ena_pko)
16875+ cvmx_dprintf
16876+ ("Warning: Enabling PKO when PKO already enabled.\n");
16877+
16878+ flags.s.ena_dwb = 1;
16879+ flags.s.ena_pko = 1;
16880+ /*
16881+ * always enable big endian for 3-word command. Does nothing
16882+ * for 2-word.
16883+ */
16884+ flags.s.store_be = 1;
16885+ cvmx_write_csr(CVMX_PKO_REG_FLAGS, flags.u64);
16886+}
16887+
16888+/**
16889+ * Disables the packet output. Does not affect any configuration.
16890+ */
16891+void cvmx_pko_disable(void)
16892+{
16893+ union cvmx_pko_reg_flags pko_reg_flags;
16894+ pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
16895+ pko_reg_flags.s.ena_pko = 0;
16896+ cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
16897+}
16898+
16899+
16900+/**
16901+ * Reset the packet output.
16902+ */
16903+static void __cvmx_pko_reset(void)
16904+{
16905+ union cvmx_pko_reg_flags pko_reg_flags;
16906+ pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
16907+ pko_reg_flags.s.reset = 1;
16908+ cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
16909+}
16910+
16911+/**
16912+ * Shutdown and free resources required by packet output.
16913+ */
16914+void cvmx_pko_shutdown(void)
16915+{
16916+ union cvmx_pko_mem_queue_ptrs config;
16917+ int queue;
16918+
16919+ cvmx_pko_disable();
16920+
16921+ for (queue = 0; queue < CVMX_PKO_MAX_OUTPUT_QUEUES; queue++) {
16922+ config.u64 = 0;
16923+ config.s.tail = 1;
16924+ config.s.index = 0;
16925+ config.s.port = CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID;
16926+ config.s.queue = queue & 0x7f;
16927+ config.s.qos_mask = 0;
16928+ config.s.buf_ptr = 0;
16929+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
16930+ union cvmx_pko_reg_queue_ptrs1 config1;
16931+ config1.u64 = 0;
16932+ config1.s.qid7 = queue >> 7;
16933+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
16934+ }
16935+ cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
16936+ cvmx_cmd_queue_shutdown(CVMX_CMD_QUEUE_PKO(queue));
16937+ }
16938+ __cvmx_pko_reset();
16939+}
16940+
16941+/**
16942+ * Configure a output port and the associated queues for use.
16943+ *
16944+ * @port: Port to configure.
16945+ * @base_queue: First queue number to associate with this port.
16946+ * @num_queues: Number of queues to associate with this port
16947+ * @priority: Array of priority levels for each queue. Values are
16948+ * allowed to be 0-8. A value of 8 get 8 times the traffic
16949+ * of a value of 1. A value of 0 indicates that no rounds
16950+ * will be participated in. These priorities can be changed
16951+ * on the fly while the pko is enabled. A priority of 9
16952+ * indicates that static priority should be used. If static
16953+ * priority is used all queues with static priority must be
16954+ * contiguous starting at the base_queue, and lower numbered
16955+ * queues have higher priority than higher numbered queues.
16956+ * There must be num_queues elements in the array.
16957+ */
16958+cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue,
16959+ uint64_t num_queues,
16960+ const uint64_t priority[])
16961+{
16962+ cvmx_pko_status_t result_code;
16963+ uint64_t queue;
16964+ union cvmx_pko_mem_queue_ptrs config;
16965+ union cvmx_pko_reg_queue_ptrs1 config1;
16966+ int static_priority_base = -1;
16967+ int static_priority_end = -1;
16968+
16969+ if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS)
16970+ && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) {
16971+ cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid port %llu\n",
16972+ (unsigned long long)port);
16973+ return CVMX_PKO_INVALID_PORT;
16974+ }
16975+
16976+ if (base_queue + num_queues > CVMX_PKO_MAX_OUTPUT_QUEUES) {
16977+ cvmx_dprintf
16978+ ("ERROR: cvmx_pko_config_port: Invalid queue range %llu\n",
16979+ (unsigned long long)(base_queue + num_queues));
16980+ return CVMX_PKO_INVALID_QUEUE;
16981+ }
16982+
16983+ if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
16984+ /*
16985+ * Validate the static queue priority setup and set
16986+ * static_priority_base and static_priority_end
16987+ * accordingly.
16988+ */
16989+ for (queue = 0; queue < num_queues; queue++) {
16990+ /* Find first queue of static priority */
16991+ if (static_priority_base == -1
16992+ && priority[queue] ==
16993+ CVMX_PKO_QUEUE_STATIC_PRIORITY)
16994+ static_priority_base = queue;
16995+ /* Find last queue of static priority */
16996+ if (static_priority_base != -1
16997+ && static_priority_end == -1
16998+ && priority[queue] != CVMX_PKO_QUEUE_STATIC_PRIORITY
16999+ && queue)
17000+ static_priority_end = queue - 1;
17001+ else if (static_priority_base != -1
17002+ && static_priority_end == -1
17003+ && queue == num_queues - 1)
17004+ /* all queues are static priority */
17005+ static_priority_end = queue;
17006+ /*
17007+ * Check to make sure all static priority
17008+ * queues are contiguous. Also catches some
17009+ * cases of static priorites not starting at
17010+ * queue 0.
17011+ */
17012+ if (static_priority_end != -1
17013+ && (int)queue > static_priority_end
17014+ && priority[queue] ==
17015+ CVMX_PKO_QUEUE_STATIC_PRIORITY) {
17016+ cvmx_dprintf("ERROR: cvmx_pko_config_port: "
17017+ "Static priority queues aren't "
17018+ "contiguous or don't start at "
17019+ "base queue. q: %d, eq: %d\n",
17020+ (int)queue, static_priority_end);
17021+ return CVMX_PKO_INVALID_PRIORITY;
17022+ }
17023+ }
17024+ if (static_priority_base > 0) {
17025+ cvmx_dprintf("ERROR: cvmx_pko_config_port: Static "
17026+ "priority queues don't start at base "
17027+ "queue. sq: %d\n",
17028+ static_priority_base);
17029+ return CVMX_PKO_INVALID_PRIORITY;
17030+ }
17031+#if 0
17032+ cvmx_dprintf("Port %d: Static priority queue base: %d, "
17033+ "end: %d\n", port,
17034+ static_priority_base, static_priority_end);
17035+#endif
17036+ }
17037+ /*
17038+ * At this point, static_priority_base and static_priority_end
17039+ * are either both -1, or are valid start/end queue
17040+ * numbers.
17041+ */
17042+
17043+ result_code = CVMX_PKO_SUCCESS;
17044+
17045+#ifdef PKO_DEBUG
17046+ cvmx_dprintf("num queues: %d (%lld,%lld)\n", num_queues,
17047+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE0,
17048+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE1);
17049+#endif
17050+
17051+ for (queue = 0; queue < num_queues; queue++) {
17052+ uint64_t *buf_ptr = NULL;
17053+
17054+ config1.u64 = 0;
17055+ config1.s.idx3 = queue >> 3;
17056+ config1.s.qid7 = (base_queue + queue) >> 7;
17057+
17058+ config.u64 = 0;
17059+ config.s.tail = queue == (num_queues - 1);
17060+ config.s.index = queue;
17061+ config.s.port = port;
17062+ config.s.queue = base_queue + queue;
17063+
17064+ if (!cvmx_octeon_is_pass1()) {
17065+ config.s.static_p = static_priority_base >= 0;
17066+ config.s.static_q = (int)queue <= static_priority_end;
17067+ config.s.s_tail = (int)queue == static_priority_end;
17068+ }
17069+ /*
17070+ * Convert the priority into an enable bit field. Try
17071+ * to space the bits out evenly so the packet don't
17072+ * get grouped up
17073+ */
17074+ switch ((int)priority[queue]) {
17075+ case 0:
17076+ config.s.qos_mask = 0x00;
17077+ break;
17078+ case 1:
17079+ config.s.qos_mask = 0x01;
17080+ break;
17081+ case 2:
17082+ config.s.qos_mask = 0x11;
17083+ break;
17084+ case 3:
17085+ config.s.qos_mask = 0x49;
17086+ break;
17087+ case 4:
17088+ config.s.qos_mask = 0x55;
17089+ break;
17090+ case 5:
17091+ config.s.qos_mask = 0x57;
17092+ break;
17093+ case 6:
17094+ config.s.qos_mask = 0x77;
17095+ break;
17096+ case 7:
17097+ config.s.qos_mask = 0x7f;
17098+ break;
17099+ case 8:
17100+ config.s.qos_mask = 0xff;
17101+ break;
17102+ case CVMX_PKO_QUEUE_STATIC_PRIORITY:
17103+ /* Pass 1 will fall through to the error case */
17104+ if (!cvmx_octeon_is_pass1()) {
17105+ config.s.qos_mask = 0xff;
17106+ break;
17107+ }
17108+ default:
17109+ cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid "
17110+ "priority %llu\n",
17111+ (unsigned long long)priority[queue]);
17112+ config.s.qos_mask = 0xff;
17113+ result_code = CVMX_PKO_INVALID_PRIORITY;
17114+ break;
17115+ }
17116+
17117+ if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
17118+ cvmx_cmd_queue_result_t cmd_res =
17119+ cvmx_cmd_queue_initialize(CVMX_CMD_QUEUE_PKO
17120+ (base_queue + queue),
17121+ CVMX_PKO_MAX_QUEUE_DEPTH,
17122+ CVMX_FPA_OUTPUT_BUFFER_POOL,
17123+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
17124+ -
17125+ CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST
17126+ * 8);
17127+ if (cmd_res != CVMX_CMD_QUEUE_SUCCESS) {
17128+ switch (cmd_res) {
17129+ case CVMX_CMD_QUEUE_NO_MEMORY:
17130+ cvmx_dprintf("ERROR: "
17131+ "cvmx_pko_config_port: "
17132+ "Unable to allocate "
17133+ "output buffer.\n");
17134+ return CVMX_PKO_NO_MEMORY;
17135+ case CVMX_CMD_QUEUE_ALREADY_SETUP:
17136+ cvmx_dprintf
17137+ ("ERROR: cvmx_pko_config_port: Port already setup.\n");
17138+ return CVMX_PKO_PORT_ALREADY_SETUP;
17139+ case CVMX_CMD_QUEUE_INVALID_PARAM:
17140+ default:
17141+ cvmx_dprintf
17142+ ("ERROR: cvmx_pko_config_port: Command queue initialization failed.\n");
17143+ return CVMX_PKO_CMD_QUEUE_INIT_ERROR;
17144+ }
17145+ }
17146+
17147+ buf_ptr =
17148+ (uint64_t *)
17149+ cvmx_cmd_queue_buffer(CVMX_CMD_QUEUE_PKO
17150+ (base_queue + queue));
17151+ config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr);
17152+ } else
17153+ config.s.buf_ptr = 0;
17154+
17155+ CVMX_SYNCWS;
17156+
17157+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX))
17158+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
17159+ cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
17160+ }
17161+
17162+ return result_code;
17163+}
17164+
17165+#ifdef PKO_DEBUG
17166+/**
17167+ * Show map of ports -> queues for different cores.
17168+ */
17169+void cvmx_pko_show_queue_map()
17170+{
17171+ int core, port;
17172+ int pko_output_ports = 36;
17173+
17174+ cvmx_dprintf("port");
17175+ for (port = 0; port < pko_output_ports; port++)
17176+ cvmx_dprintf("%3d ", port);
17177+ cvmx_dprintf("\n");
17178+
17179+ for (core = 0; core < CVMX_MAX_CORES; core++) {
17180+ cvmx_dprintf("\n%2d: ", core);
17181+ for (port = 0; port < pko_output_ports; port++) {
17182+ cvmx_dprintf("%3d ",
17183+ cvmx_pko_get_base_queue_per_core(port,
17184+ core));
17185+ }
17186+ }
17187+ cvmx_dprintf("\n");
17188+}
17189+#endif
17190+
17191+/**
17192+ * Rate limit a PKO port to a max packets/sec. This function is only
17193+ * supported on CN51XX and higher, excluding CN58XX.
17194+ *
17195+ * @port: Port to rate limit
17196+ * @packets_s: Maximum packet/sec
17197+ * @burst: Maximum number of packets to burst in a row before rate
17198+ * limiting cuts in.
17199+ *
17200+ * Returns Zero on success, negative on failure
17201+ */
17202+int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst)
17203+{
17204+ union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
17205+ union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
17206+
17207+ pko_mem_port_rate0.u64 = 0;
17208+ pko_mem_port_rate0.s.pid = port;
17209+ pko_mem_port_rate0.s.rate_pkt =
17210+ cvmx_sysinfo_get()->cpu_clock_hz / packets_s / 16;
17211+ /* No cost per word since we are limited by packets/sec, not bits/sec */
17212+ pko_mem_port_rate0.s.rate_word = 0;
17213+
17214+ pko_mem_port_rate1.u64 = 0;
17215+ pko_mem_port_rate1.s.pid = port;
17216+ pko_mem_port_rate1.s.rate_lim =
17217+ ((uint64_t) pko_mem_port_rate0.s.rate_pkt * burst) >> 8;
17218+
17219+ cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
17220+ cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
17221+ return 0;
17222+}
17223+
17224+/**
17225+ * Rate limit a PKO port to a max bits/sec. This function is only
17226+ * supported on CN51XX and higher, excluding CN58XX.
17227+ *
17228+ * @port: Port to rate limit
17229+ * @bits_s: PKO rate limit in bits/sec
17230+ * @burst: Maximum number of bits to burst before rate
17231+ * limiting cuts in.
17232+ *
17233+ * Returns Zero on success, negative on failure
17234+ */
17235+int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst)
17236+{
17237+ union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
17238+ union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
17239+ uint64_t clock_rate = cvmx_sysinfo_get()->cpu_clock_hz;
17240+ uint64_t tokens_per_bit = clock_rate * 16 / bits_s;
17241+
17242+ pko_mem_port_rate0.u64 = 0;
17243+ pko_mem_port_rate0.s.pid = port;
17244+ /*
17245+ * Each packet has a 12 bytes of interframe gap, an 8 byte
17246+ * preamble, and a 4 byte CRC. These are not included in the
17247+ * per word count. Multiply by 8 to covert to bits and divide
17248+ * by 256 for limit granularity.
17249+ */
17250+ pko_mem_port_rate0.s.rate_pkt = (12 + 8 + 4) * 8 * tokens_per_bit / 256;
17251+ /* Each 8 byte word has 64bits */
17252+ pko_mem_port_rate0.s.rate_word = 64 * tokens_per_bit;
17253+
17254+ pko_mem_port_rate1.u64 = 0;
17255+ pko_mem_port_rate1.s.pid = port;
17256+ pko_mem_port_rate1.s.rate_lim = tokens_per_bit * burst / 256;
17257+
17258+ cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
17259+ cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
17260+ return 0;
17261+}
17262--- /dev/null
17263+++ b/drivers/staging/octeon/cvmx-pko.h
17264@@ -0,0 +1,610 @@
17265+/***********************license start***************
17266+ * Author: Cavium Networks
17267+ *
17268+ * Contact: support@caviumnetworks.com
17269+ * This file is part of the OCTEON SDK
17270+ *
17271+ * Copyright (c) 2003-2008 Cavium Networks
17272+ *
17273+ * This file is free software; you can redistribute it and/or modify
17274+ * it under the terms of the GNU General Public License, Version 2, as
17275+ * published by the Free Software Foundation.
17276+ *
17277+ * This file is distributed in the hope that it will be useful, but
17278+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
17279+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
17280+ * NONINFRINGEMENT. See the GNU General Public License for more
17281+ * details.
17282+ *
17283+ * You should have received a copy of the GNU General Public License
17284+ * along with this file; if not, write to the Free Software
17285+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17286+ * or visit http://www.gnu.org/licenses/.
17287+ *
17288+ * This file may also be available under a different license from Cavium.
17289+ * Contact Cavium Networks for more information
17290+ ***********************license end**************************************/
17291+
17292+/**
17293+ *
17294+ * Interface to the hardware Packet Output unit.
17295+ *
17296+ * Starting with SDK 1.7.0, the PKO output functions now support
17297+ * two types of locking. CVMX_PKO_LOCK_ATOMIC_TAG continues to
17298+ * function similarly to previous SDKs by using POW atomic tags
17299+ * to preserve ordering and exclusivity. As a new option, you
17300+ * can now pass CVMX_PKO_LOCK_CMD_QUEUE which uses a ll/sc
17301+ * memory based locking instead. This locking has the advantage
17302+ * of not affecting the tag state but doesn't preserve packet
17303+ * ordering. CVMX_PKO_LOCK_CMD_QUEUE is appropriate in most
17304+ * generic code while CVMX_PKO_LOCK_CMD_QUEUE should be used
17305+ * with hand tuned fast path code.
17306+ *
17307+ * Some of other SDK differences visible to the command command
17308+ * queuing:
17309+ * - PKO indexes are no longer stored in the FAU. A large
17310+ * percentage of the FAU register block used to be tied up
17311+ * maintaining PKO queue pointers. These are now stored in a
17312+ * global named block.
17313+ * - The PKO <b>use_locking</b> parameter can now have a global
17314+ * effect. Since all application use the same named block,
17315+ * queue locking correctly applies across all operating
17316+ * systems when using CVMX_PKO_LOCK_CMD_QUEUE.
17317+ * - PKO 3 word commands are now supported. Use
17318+ * cvmx_pko_send_packet_finish3().
17319+ *
17320+ */
17321+
17322+#ifndef __CVMX_PKO_H__
17323+#define __CVMX_PKO_H__
17324+
17325+#include "cvmx-fpa.h"
17326+#include "cvmx-pow.h"
17327+#include "cvmx-cmd-queue.h"
17328+#include "cvmx-pko-defs.h"
17329+
17330+/* Adjust the command buffer size by 1 word so that in the case of using only
17331+ * two word PKO commands no command words stradle buffers. The useful values
17332+ * for this are 0 and 1. */
17333+#define CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST (1)
17334+
17335+#define CVMX_PKO_MAX_OUTPUT_QUEUES_STATIC 256
17336+#define CVMX_PKO_MAX_OUTPUT_QUEUES ((OCTEON_IS_MODEL(OCTEON_CN31XX) || \
17337+ OCTEON_IS_MODEL(OCTEON_CN3010) || OCTEON_IS_MODEL(OCTEON_CN3005) || \
17338+ OCTEON_IS_MODEL(OCTEON_CN50XX)) ? 32 : \
17339+ (OCTEON_IS_MODEL(OCTEON_CN58XX) || \
17340+ OCTEON_IS_MODEL(OCTEON_CN56XX)) ? 256 : 128)
17341+#define CVMX_PKO_NUM_OUTPUT_PORTS 40
17342+/* use this for queues that are not used */
17343+#define CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63
17344+#define CVMX_PKO_QUEUE_STATIC_PRIORITY 9
17345+#define CVMX_PKO_ILLEGAL_QUEUE 0xFFFF
17346+#define CVMX_PKO_MAX_QUEUE_DEPTH 0
17347+
17348+typedef enum {
17349+ CVMX_PKO_SUCCESS,
17350+ CVMX_PKO_INVALID_PORT,
17351+ CVMX_PKO_INVALID_QUEUE,
17352+ CVMX_PKO_INVALID_PRIORITY,
17353+ CVMX_PKO_NO_MEMORY,
17354+ CVMX_PKO_PORT_ALREADY_SETUP,
17355+ CVMX_PKO_CMD_QUEUE_INIT_ERROR
17356+} cvmx_pko_status_t;
17357+
17358+/**
17359+ * This enumeration represents the differnet locking modes supported by PKO.
17360+ */
17361+typedef enum {
17362+ /*
17363+ * PKO doesn't do any locking. It is the responsibility of the
17364+ * application to make sure that no other core is accessing
17365+ * the same queue at the smae time
17366+ */
17367+ CVMX_PKO_LOCK_NONE = 0,
17368+ /*
17369+ * PKO performs an atomic tagswitch to insure exclusive access
17370+ * to the output queue. This will maintain packet ordering on
17371+ * output.
17372+ */
17373+ CVMX_PKO_LOCK_ATOMIC_TAG = 1,
17374+ /*
17375+ * PKO uses the common command queue locks to insure exclusive
17376+ * access to the output queue. This is a memory based
17377+ * ll/sc. This is the most portable locking mechanism.
17378+ */
17379+ CVMX_PKO_LOCK_CMD_QUEUE = 2,
17380+} cvmx_pko_lock_t;
17381+
17382+typedef struct {
17383+ uint32_t packets;
17384+ uint64_t octets;
17385+ uint64_t doorbell;
17386+} cvmx_pko_port_status_t;
17387+
17388+/**
17389+ * This structure defines the address to use on a packet enqueue
17390+ */
17391+typedef union {
17392+ uint64_t u64;
17393+ struct {
17394+ /* Must CVMX_IO_SEG */
17395+ uint64_t mem_space:2;
17396+ /* Must be zero */
17397+ uint64_t reserved:13;
17398+ /* Must be one */
17399+ uint64_t is_io:1;
17400+ /* The ID of the device on the non-coherent bus */
17401+ uint64_t did:8;
17402+ /* Must be zero */
17403+ uint64_t reserved2:4;
17404+ /* Must be zero */
17405+ uint64_t reserved3:18;
17406+ /*
17407+ * The hardware likes to have the output port in
17408+ * addition to the output queue,
17409+ */
17410+ uint64_t port:6;
17411+ /*
17412+ * The output queue to send the packet to (0-127 are
17413+ * legal)
17414+ */
17415+ uint64_t queue:9;
17416+ /* Must be zero */
17417+ uint64_t reserved4:3;
17418+ } s;
17419+} cvmx_pko_doorbell_address_t;
17420+
17421+/**
17422+ * Structure of the first packet output command word.
17423+ */
17424+typedef union {
17425+ uint64_t u64;
17426+ struct {
17427+ /*
17428+ * The size of the reg1 operation - could be 8, 16,
17429+ * 32, or 64 bits.
17430+ */
17431+ uint64_t size1:2;
17432+ /*
17433+ * The size of the reg0 operation - could be 8, 16,
17434+ * 32, or 64 bits.
17435+ */
17436+ uint64_t size0:2;
17437+ /*
17438+ * If set, subtract 1, if clear, subtract packet
17439+ * size.
17440+ */
17441+ uint64_t subone1:1;
17442+ /*
17443+ * The register, subtract will be done if reg1 is
17444+ * non-zero.
17445+ */
17446+ uint64_t reg1:11;
17447+ /* If set, subtract 1, if clear, subtract packet size */
17448+ uint64_t subone0:1;
17449+ /* The register, subtract will be done if reg0 is non-zero */
17450+ uint64_t reg0:11;
17451+ /*
17452+ * When set, interpret segment pointer and segment
17453+ * bytes in little endian order.
17454+ */
17455+ uint64_t le:1;
17456+ /*
17457+ * When set, packet data not allocated in L2 cache by
17458+ * PKO.
17459+ */
17460+ uint64_t n2:1;
17461+ /*
17462+ * If set and rsp is set, word3 contains a pointer to
17463+ * a work queue entry.
17464+ */
17465+ uint64_t wqp:1;
17466+ /* If set, the hardware will send a response when done */
17467+ uint64_t rsp:1;
17468+ /*
17469+ * If set, the supplied pkt_ptr is really a pointer to
17470+ * a list of pkt_ptr's.
17471+ */
17472+ uint64_t gather:1;
17473+ /*
17474+ * If ipoffp1 is non zero, (ipoffp1-1) is the number
17475+ * of bytes to IP header, and the hardware will
17476+ * calculate and insert the UDP/TCP checksum.
17477+ */
17478+ uint64_t ipoffp1:7;
17479+ /*
17480+ * If set, ignore the I bit (force to zero) from all
17481+ * pointer structures.
17482+ */
17483+ uint64_t ignore_i:1;
17484+ /*
17485+ * If clear, the hardware will attempt to free the
17486+ * buffers containing the packet.
17487+ */
17488+ uint64_t dontfree:1;
17489+ /*
17490+ * The total number of segs in the packet, if gather
17491+ * set, also gather list length.
17492+ */
17493+ uint64_t segs:6;
17494+ /* Including L2, but no trailing CRC */
17495+ uint64_t total_bytes:16;
17496+ } s;
17497+} cvmx_pko_command_word0_t;
17498+
17499+/* CSR typedefs have been moved to cvmx-csr-*.h */
17500+
17501+/**
17502+ * Definition of internal state for Packet output processing
17503+ */
17504+typedef struct {
17505+ /* ptr to start of buffer, offset kept in FAU reg */
17506+ uint64_t *start_ptr;
17507+} cvmx_pko_state_elem_t;
17508+
17509+/**
17510+ * Call before any other calls to initialize the packet
17511+ * output system.
17512+ */
17513+extern void cvmx_pko_initialize_global(void);
17514+extern int cvmx_pko_initialize_local(void);
17515+
17516+/**
17517+ * Enables the packet output hardware. It must already be
17518+ * configured.
17519+ */
17520+extern void cvmx_pko_enable(void);
17521+
17522+/**
17523+ * Disables the packet output. Does not affect any configuration.
17524+ */
17525+extern void cvmx_pko_disable(void);
17526+
17527+/**
17528+ * Shutdown and free resources required by packet output.
17529+ */
17530+
17531+extern void cvmx_pko_shutdown(void);
17532+
17533+/**
17534+ * Configure a output port and the associated queues for use.
17535+ *
17536+ * @port: Port to configure.
17537+ * @base_queue: First queue number to associate with this port.
17538+ * @num_queues: Number of queues t oassociate with this port
17539+ * @priority: Array of priority levels for each queue. Values are
17540+ * allowed to be 1-8. A value of 8 get 8 times the traffic
17541+ * of a value of 1. There must be num_queues elements in the
17542+ * array.
17543+ */
17544+extern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port,
17545+ uint64_t base_queue,
17546+ uint64_t num_queues,
17547+ const uint64_t priority[]);
17548+
17549+/**
17550+ * Ring the packet output doorbell. This tells the packet
17551+ * output hardware that "len" command words have been added
17552+ * to its pending list. This command includes the required
17553+ * CVMX_SYNCWS before the doorbell ring.
17554+ *
17555+ * @port: Port the packet is for
17556+ * @queue: Queue the packet is for
17557+ * @len: Length of the command in 64 bit words
17558+ */
17559+static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
17560+ uint64_t len)
17561+{
17562+ cvmx_pko_doorbell_address_t ptr;
17563+
17564+ ptr.u64 = 0;
17565+ ptr.s.mem_space = CVMX_IO_SEG;
17566+ ptr.s.did = CVMX_OCT_DID_PKT_SEND;
17567+ ptr.s.is_io = 1;
17568+ ptr.s.port = port;
17569+ ptr.s.queue = queue;
17570+ /*
17571+ * Need to make sure output queue data is in DRAM before
17572+ * doorbell write.
17573+ */
17574+ CVMX_SYNCWS;
17575+ cvmx_write_io(ptr.u64, len);
17576+}
17577+
17578+/**
17579+ * Prepare to send a packet. This may initiate a tag switch to
17580+ * get exclusive access to the output queue structure, and
17581+ * performs other prep work for the packet send operation.
17582+ *
17583+ * cvmx_pko_send_packet_finish() MUST be called after this function is called,
17584+ * and must be called with the same port/queue/use_locking arguments.
17585+ *
17586+ * The use_locking parameter allows the caller to use three
17587+ * possible locking modes.
17588+ * - CVMX_PKO_LOCK_NONE
17589+ * - PKO doesn't do any locking. It is the responsibility
17590+ * of the application to make sure that no other core
17591+ * is accessing the same queue at the smae time.
17592+ * - CVMX_PKO_LOCK_ATOMIC_TAG
17593+ * - PKO performs an atomic tagswitch to insure exclusive
17594+ * access to the output queue. This will maintain
17595+ * packet ordering on output.
17596+ * - CVMX_PKO_LOCK_CMD_QUEUE
17597+ * - PKO uses the common command queue locks to insure
17598+ * exclusive access to the output queue. This is a
17599+ * memory based ll/sc. This is the most portable
17600+ * locking mechanism.
17601+ *
17602+ * NOTE: If atomic locking is used, the POW entry CANNOT be
17603+ * descheduled, as it does not contain a valid WQE pointer.
17604+ *
17605+ * @port: Port to send it on
17606+ * @queue: Queue to use
17607+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17608+ * CVMX_PKO_LOCK_CMD_QUEUE
17609+ */
17610+
17611+static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
17612+ cvmx_pko_lock_t use_locking)
17613+{
17614+ if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
17615+ /*
17616+ * Must do a full switch here to handle all cases. We
17617+ * use a fake WQE pointer, as the POW does not access
17618+ * this memory. The WQE pointer and group are only
17619+ * used if this work is descheduled, which is not
17620+ * supported by the
17621+ * cvmx_pko_send_packet_prepare/cvmx_pko_send_packet_finish
17622+ * combination. Note that this is a special case in
17623+ * which these fake values can be used - this is not a
17624+ * general technique.
17625+ */
17626+ uint32_t tag =
17627+ CVMX_TAG_SW_BITS_INTERNAL << CVMX_TAG_SW_SHIFT |
17628+ CVMX_TAG_SUBGROUP_PKO << CVMX_TAG_SUBGROUP_SHIFT |
17629+ (CVMX_TAG_SUBGROUP_MASK & queue);
17630+ cvmx_pow_tag_sw_full((cvmx_wqe_t *) cvmx_phys_to_ptr(0x80), tag,
17631+ CVMX_POW_TAG_TYPE_ATOMIC, 0);
17632+ }
17633+}
17634+
17635+/**
17636+ * Complete packet output. cvmx_pko_send_packet_prepare() must be
17637+ * called exactly once before this, and the same parameters must be
17638+ * passed to both cvmx_pko_send_packet_prepare() and
17639+ * cvmx_pko_send_packet_finish().
17640+ *
17641+ * @port: Port to send it on
17642+ * @queue: Queue to use
17643+ * @pko_command:
17644+ * PKO HW command word
17645+ * @packet: Packet to send
17646+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17647+ * CVMX_PKO_LOCK_CMD_QUEUE
17648+ *
17649+ * Returns returns CVMX_PKO_SUCCESS on success, or error code on
17650+ * failure of output
17651+ */
17652+static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
17653+ uint64_t port,
17654+ uint64_t queue,
17655+ cvmx_pko_command_word0_t pko_command,
17656+ union cvmx_buf_ptr packet,
17657+ cvmx_pko_lock_t use_locking)
17658+{
17659+ cvmx_cmd_queue_result_t result;
17660+ if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
17661+ cvmx_pow_tag_sw_wait();
17662+ result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
17663+ (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
17664+ pko_command.u64, packet.u64);
17665+ if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
17666+ cvmx_pko_doorbell(port, queue, 2);
17667+ return CVMX_PKO_SUCCESS;
17668+ } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
17669+ || (result == CVMX_CMD_QUEUE_FULL)) {
17670+ return CVMX_PKO_NO_MEMORY;
17671+ } else {
17672+ return CVMX_PKO_INVALID_QUEUE;
17673+ }
17674+}
17675+
17676+/**
17677+ * Complete packet output. cvmx_pko_send_packet_prepare() must be
17678+ * called exactly once before this, and the same parameters must be
17679+ * passed to both cvmx_pko_send_packet_prepare() and
17680+ * cvmx_pko_send_packet_finish().
17681+ *
17682+ * @port: Port to send it on
17683+ * @queue: Queue to use
17684+ * @pko_command:
17685+ * PKO HW command word
17686+ * @packet: Packet to send
17687+ * @addr: Plysical address of a work queue entry or physical address
17688+ * to zero on complete.
17689+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17690+ * CVMX_PKO_LOCK_CMD_QUEUE
17691+ *
17692+ * Returns returns CVMX_PKO_SUCCESS on success, or error code on
17693+ * failure of output
17694+ */
17695+static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
17696+ uint64_t port,
17697+ uint64_t queue,
17698+ cvmx_pko_command_word0_t pko_command,
17699+ union cvmx_buf_ptr packet,
17700+ uint64_t addr,
17701+ cvmx_pko_lock_t use_locking)
17702+{
17703+ cvmx_cmd_queue_result_t result;
17704+ if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
17705+ cvmx_pow_tag_sw_wait();
17706+ result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
17707+ (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
17708+ pko_command.u64, packet.u64, addr);
17709+ if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
17710+ cvmx_pko_doorbell(port, queue, 3);
17711+ return CVMX_PKO_SUCCESS;
17712+ } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
17713+ || (result == CVMX_CMD_QUEUE_FULL)) {
17714+ return CVMX_PKO_NO_MEMORY;
17715+ } else {
17716+ return CVMX_PKO_INVALID_QUEUE;
17717+ }
17718+}
17719+
17720+/**
17721+ * Return the pko output queue associated with a port and a specific core.
17722+ * In normal mode (PKO lockless operation is disabled), the value returned
17723+ * is the base queue.
17724+ *
17725+ * @port: Port number
17726+ * @core: Core to get queue for
17727+ *
17728+ * Returns Core-specific output queue
17729+ */
17730+static inline int cvmx_pko_get_base_queue_per_core(int port, int core)
17731+{
17732+#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
17733+#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16
17734+#endif
17735+#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
17736+#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16
17737+#endif
17738+
17739+ if (port < CVMX_PKO_MAX_PORTS_INTERFACE0)
17740+ return port * CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + core;
17741+ else if (port >= 16 && port < 16 + CVMX_PKO_MAX_PORTS_INTERFACE1)
17742+ return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17743+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + (port -
17744+ 16) *
17745+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + core;
17746+ else if ((port >= 32) && (port < 36))
17747+ return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17748+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
17749+ CVMX_PKO_MAX_PORTS_INTERFACE1 *
17750+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + (port -
17751+ 32) *
17752+ CVMX_PKO_QUEUES_PER_PORT_PCI;
17753+ else if ((port >= 36) && (port < 40))
17754+ return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17755+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
17756+ CVMX_PKO_MAX_PORTS_INTERFACE1 *
17757+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 +
17758+ 4 * CVMX_PKO_QUEUES_PER_PORT_PCI + (port -
17759+ 36) *
17760+ CVMX_PKO_QUEUES_PER_PORT_LOOP;
17761+ else
17762+ /* Given the limit on the number of ports we can map to
17763+ * CVMX_MAX_OUTPUT_QUEUES_STATIC queues (currently 256,
17764+ * divided among all cores), the remaining unmapped ports
17765+ * are assigned an illegal queue number */
17766+ return CVMX_PKO_ILLEGAL_QUEUE;
17767+}
17768+
17769+/**
17770+ * For a given port number, return the base pko output queue
17771+ * for the port.
17772+ *
17773+ * @port: Port number
17774+ * Returns Base output queue
17775+ */
17776+static inline int cvmx_pko_get_base_queue(int port)
17777+{
17778+ return cvmx_pko_get_base_queue_per_core(port, 0);
17779+}
17780+
17781+/**
17782+ * For a given port number, return the number of pko output queues.
17783+ *
17784+ * @port: Port number
17785+ * Returns Number of output queues
17786+ */
17787+static inline int cvmx_pko_get_num_queues(int port)
17788+{
17789+ if (port < 16)
17790+ return CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
17791+ else if (port < 32)
17792+ return CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
17793+ else if (port < 36)
17794+ return CVMX_PKO_QUEUES_PER_PORT_PCI;
17795+ else if (port < 40)
17796+ return CVMX_PKO_QUEUES_PER_PORT_LOOP;
17797+ else
17798+ return 0;
17799+}
17800+
17801+/**
17802+ * Get the status counters for a port.
17803+ *
17804+ * @port_num: Port number to get statistics for.
17805+ * @clear: Set to 1 to clear the counters after they are read
17806+ * @status: Where to put the results.
17807+ */
17808+static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
17809+ cvmx_pko_port_status_t *status)
17810+{
17811+ union cvmx_pko_reg_read_idx pko_reg_read_idx;
17812+ union cvmx_pko_mem_count0 pko_mem_count0;
17813+ union cvmx_pko_mem_count1 pko_mem_count1;
17814+
17815+ pko_reg_read_idx.u64 = 0;
17816+ pko_reg_read_idx.s.index = port_num;
17817+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17818+
17819+ pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0);
17820+ status->packets = pko_mem_count0.s.count;
17821+ if (clear) {
17822+ pko_mem_count0.s.count = port_num;
17823+ cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64);
17824+ }
17825+
17826+ pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1);
17827+ status->octets = pko_mem_count1.s.count;
17828+ if (clear) {
17829+ pko_mem_count1.s.count = port_num;
17830+ cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64);
17831+ }
17832+
17833+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
17834+ union cvmx_pko_mem_debug9 debug9;
17835+ pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
17836+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17837+ debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
17838+ status->doorbell = debug9.cn38xx.doorbell;
17839+ } else {
17840+ union cvmx_pko_mem_debug8 debug8;
17841+ pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
17842+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17843+ debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
17844+ status->doorbell = debug8.cn58xx.doorbell;
17845+ }
17846+}
17847+
17848+/**
17849+ * Rate limit a PKO port to a max packets/sec. This function is only
17850+ * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
17851+ *
17852+ * @port: Port to rate limit
17853+ * @packets_s: Maximum packet/sec
17854+ * @burst: Maximum number of packets to burst in a row before rate
17855+ * limiting cuts in.
17856+ *
17857+ * Returns Zero on success, negative on failure
17858+ */
17859+extern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst);
17860+
17861+/**
17862+ * Rate limit a PKO port to a max bits/sec. This function is only
17863+ * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
17864+ *
17865+ * @port: Port to rate limit
17866+ * @bits_s: PKO rate limit in bits/sec
17867+ * @burst: Maximum number of bits to burst before rate
17868+ * limiting cuts in.
17869+ *
17870+ * Returns Zero on success, negative on failure
17871+ */
17872+extern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst);
17873+
17874+#endif /* __CVMX_PKO_H__ */
17875--- /dev/null
17876+++ b/drivers/staging/octeon/cvmx-pow.h
17877@@ -0,0 +1,1982 @@
17878+/***********************license start***************
17879+ * Author: Cavium Networks
17880+ *
17881+ * Contact: support@caviumnetworks.com
17882+ * This file is part of the OCTEON SDK
17883+ *
17884+ * Copyright (c) 2003-2008 Cavium Networks
17885+ *
17886+ * This file is free software; you can redistribute it and/or modify
17887+ * it under the terms of the GNU General Public License, Version 2, as
17888+ * published by the Free Software Foundation.
17889+ *
17890+ * This file is distributed in the hope that it will be useful, but
17891+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
17892+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
17893+ * NONINFRINGEMENT. See the GNU General Public License for more
17894+ * details.
17895+ *
17896+ * You should have received a copy of the GNU General Public License
17897+ * along with this file; if not, write to the Free Software
17898+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17899+ * or visit http://www.gnu.org/licenses/.
17900+ *
17901+ * This file may also be available under a different license from Cavium.
17902+ * Contact Cavium Networks for more information
17903+ ***********************license end**************************************/
17904+
17905+/**
17906+ * Interface to the hardware Packet Order / Work unit.
17907+ *
17908+ * New, starting with SDK 1.7.0, cvmx-pow supports a number of
17909+ * extended consistency checks. The define
17910+ * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW
17911+ * internal state checks to find common programming errors. If
17912+ * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default
17913+ * enabled. For example, cvmx-pow will check for the following
17914+ * program errors or POW state inconsistency.
17915+ * - Requesting a POW operation with an active tag switch in
17916+ * progress.
17917+ * - Waiting for a tag switch to complete for an excessively
17918+ * long period. This is normally a sign of an error in locking
17919+ * causing deadlock.
17920+ * - Illegal tag switches from NULL_NULL.
17921+ * - Illegal tag switches from NULL.
17922+ * - Illegal deschedule request.
17923+ * - WQE pointer not matching the one attached to the core by
17924+ * the POW.
17925+ *
17926+ */
17927+
17928+#ifndef __CVMX_POW_H__
17929+#define __CVMX_POW_H__
17930+
17931+#include <asm/octeon/cvmx-pow-defs.h>
17932+
17933+#include "cvmx-scratch.h"
17934+#include "cvmx-wqe.h"
17935+
17936+/* Default to having all POW constancy checks turned on */
17937+#ifndef CVMX_ENABLE_POW_CHECKS
17938+#define CVMX_ENABLE_POW_CHECKS 1
17939+#endif
17940+
17941+enum cvmx_pow_tag_type {
17942+ /* Tag ordering is maintained */
17943+ CVMX_POW_TAG_TYPE_ORDERED = 0L,
17944+ /* Tag ordering is maintained, and at most one PP has the tag */
17945+ CVMX_POW_TAG_TYPE_ATOMIC = 1L,
17946+ /*
17947+ * The work queue entry from the order - NEVER tag switch from
17948+ * NULL to NULL
17949+ */
17950+ CVMX_POW_TAG_TYPE_NULL = 2L,
17951+ /* A tag switch to NULL, and there is no space reserved in POW
17952+ * - NEVER tag switch to NULL_NULL
17953+ * - NEVER tag switch from NULL_NULL
17954+ * - NULL_NULL is entered at the beginning of time and on a deschedule.
17955+ * - NULL_NULL can be exited by a new work request. A NULL_SWITCH
17956+ * load can also switch the state to NULL
17957+ */
17958+ CVMX_POW_TAG_TYPE_NULL_NULL = 3L
17959+};
17960+
17961+/**
17962+ * Wait flag values for pow functions.
17963+ */
17964+typedef enum {
17965+ CVMX_POW_WAIT = 1,
17966+ CVMX_POW_NO_WAIT = 0,
17967+} cvmx_pow_wait_t;
17968+
17969+/**
17970+ * POW tag operations. These are used in the data stored to the POW.
17971+ */
17972+typedef enum {
17973+ /*
17974+ * switch the tag (only) for this PP
17975+ * - the previous tag should be non-NULL in this case
17976+ * - tag switch response required
17977+ * - fields used: op, type, tag
17978+ */
17979+ CVMX_POW_TAG_OP_SWTAG = 0L,
17980+ /*
17981+ * switch the tag for this PP, with full information
17982+ * - this should be used when the previous tag is NULL
17983+ * - tag switch response required
17984+ * - fields used: address, op, grp, type, tag
17985+ */
17986+ CVMX_POW_TAG_OP_SWTAG_FULL = 1L,
17987+ /*
17988+ * switch the tag (and/or group) for this PP and de-schedule
17989+ * - OK to keep the tag the same and only change the group
17990+ * - fields used: op, no_sched, grp, type, tag
17991+ */
17992+ CVMX_POW_TAG_OP_SWTAG_DESCH = 2L,
17993+ /*
17994+ * just de-schedule
17995+ * - fields used: op, no_sched
17996+ */
17997+ CVMX_POW_TAG_OP_DESCH = 3L,
17998+ /*
17999+ * create an entirely new work queue entry
18000+ * - fields used: address, op, qos, grp, type, tag
18001+ */
18002+ CVMX_POW_TAG_OP_ADDWQ = 4L,
18003+ /*
18004+ * just update the work queue pointer and grp for this PP
18005+ * - fields used: address, op, grp
18006+ */
18007+ CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L,
18008+ /*
18009+ * set the no_sched bit on the de-schedule list
18010+ *
18011+ * - does nothing if the selected entry is not on the
18012+ * de-schedule list
18013+ *
18014+ * - does nothing if the stored work queue pointer does not
18015+ * match the address field
18016+ *
18017+ * - fields used: address, index, op
18018+ *
18019+ * Before issuing a *_NSCHED operation, SW must guarantee
18020+ * that all prior deschedules and set/clr NSCHED operations
18021+ * are complete and all prior switches are complete. The
18022+ * hardware provides the opsdone bit and swdone bit for SW
18023+ * polling. After issuing a *_NSCHED operation, SW must
18024+ * guarantee that the set/clr NSCHED is complete before any
18025+ * subsequent operations.
18026+ */
18027+ CVMX_POW_TAG_OP_SET_NSCHED = 6L,
18028+ /*
18029+ * clears the no_sched bit on the de-schedule list
18030+ *
18031+ * - does nothing if the selected entry is not on the
18032+ * de-schedule list
18033+ *
18034+ * - does nothing if the stored work queue pointer does not
18035+ * match the address field
18036+ *
18037+ * - fields used: address, index, op
18038+ *
18039+ * Before issuing a *_NSCHED operation, SW must guarantee that
18040+ * all prior deschedules and set/clr NSCHED operations are
18041+ * complete and all prior switches are complete. The hardware
18042+ * provides the opsdone bit and swdone bit for SW
18043+ * polling. After issuing a *_NSCHED operation, SW must
18044+ * guarantee that the set/clr NSCHED is complete before any
18045+ * subsequent operations.
18046+ */
18047+ CVMX_POW_TAG_OP_CLR_NSCHED = 7L,
18048+ /* do nothing */
18049+ CVMX_POW_TAG_OP_NOP = 15L
18050+} cvmx_pow_tag_op_t;
18051+
18052+/**
18053+ * This structure defines the store data on a store to POW
18054+ */
18055+typedef union {
18056+ uint64_t u64;
18057+ struct {
18058+ /*
18059+ * Don't reschedule this entry. no_sched is used for
18060+ * CVMX_POW_TAG_OP_SWTAG_DESCH and
18061+ * CVMX_POW_TAG_OP_DESCH
18062+ */
18063+ uint64_t no_sched:1;
18064+ uint64_t unused:2;
18065+ /* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */
18066+ uint64_t index:13;
18067+ /* The operation to perform */
18068+ cvmx_pow_tag_op_t op:4;
18069+ uint64_t unused2:2;
18070+ /*
18071+ * The QOS level for the packet. qos is only used for
18072+ * CVMX_POW_TAG_OP_ADDWQ
18073+ */
18074+ uint64_t qos:3;
18075+ /*
18076+ * The group that the work queue entry will be
18077+ * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ,
18078+ * CVMX_POW_TAG_OP_SWTAG_FULL,
18079+ * CVMX_POW_TAG_OP_SWTAG_DESCH, and
18080+ * CVMX_POW_TAG_OP_UPDATE_WQP_GRP
18081+ */
18082+ uint64_t grp:4;
18083+ /*
18084+ * The type of the tag. type is used for everything
18085+ * except CVMX_POW_TAG_OP_DESCH,
18086+ * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
18087+ * CVMX_POW_TAG_OP_*_NSCHED
18088+ */
18089+ uint64_t type:3;
18090+ /*
18091+ * The actual tag. tag is used for everything except
18092+ * CVMX_POW_TAG_OP_DESCH,
18093+ * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
18094+ * CVMX_POW_TAG_OP_*_NSCHED
18095+ */
18096+ uint64_t tag:32;
18097+ } s;
18098+} cvmx_pow_tag_req_t;
18099+
18100+/**
18101+ * This structure describes the address to load stuff from POW
18102+ */
18103+typedef union {
18104+ uint64_t u64;
18105+
18106+ /**
18107+ * Address for new work request loads (did<2:0> == 0)
18108+ */
18109+ struct {
18110+ /* Mips64 address region. Should be CVMX_IO_SEG */
18111+ uint64_t mem_region:2;
18112+ /* Must be zero */
18113+ uint64_t reserved_49_61:13;
18114+ /* Must be one */
18115+ uint64_t is_io:1;
18116+ /* the ID of POW -- did<2:0> == 0 in this case */
18117+ uint64_t did:8;
18118+ /* Must be zero */
18119+ uint64_t reserved_4_39:36;
18120+ /*
18121+ * If set, don't return load response until work is
18122+ * available.
18123+ */
18124+ uint64_t wait:1;
18125+ /* Must be zero */
18126+ uint64_t reserved_0_2:3;
18127+ } swork;
18128+
18129+ /**
18130+ * Address for loads to get POW internal status
18131+ */
18132+ struct {
18133+ /* Mips64 address region. Should be CVMX_IO_SEG */
18134+ uint64_t mem_region:2;
18135+ /* Must be zero */
18136+ uint64_t reserved_49_61:13;
18137+ /* Must be one */
18138+ uint64_t is_io:1;
18139+ /* the ID of POW -- did<2:0> == 1 in this case */
18140+ uint64_t did:8;
18141+ /* Must be zero */
18142+ uint64_t reserved_10_39:30;
18143+ /* The core id to get status for */
18144+ uint64_t coreid:4;
18145+ /*
18146+ * If set and get_cur is set, return reverse tag-list
18147+ * pointer rather than forward tag-list pointer.
18148+ */
18149+ uint64_t get_rev:1;
18150+ /*
18151+ * If set, return current status rather than pending
18152+ * status.
18153+ */
18154+ uint64_t get_cur:1;
18155+ /*
18156+ * If set, get the work-queue pointer rather than
18157+ * tag/type.
18158+ */
18159+ uint64_t get_wqp:1;
18160+ /* Must be zero */
18161+ uint64_t reserved_0_2:3;
18162+ } sstatus;
18163+
18164+ /**
18165+ * Address for memory loads to get POW internal state
18166+ */
18167+ struct {
18168+ /* Mips64 address region. Should be CVMX_IO_SEG */
18169+ uint64_t mem_region:2;
18170+ /* Must be zero */
18171+ uint64_t reserved_49_61:13;
18172+ /* Must be one */
18173+ uint64_t is_io:1;
18174+ /* the ID of POW -- did<2:0> == 2 in this case */
18175+ uint64_t did:8;
18176+ /* Must be zero */
18177+ uint64_t reserved_16_39:24;
18178+ /* POW memory index */
18179+ uint64_t index:11;
18180+ /*
18181+ * If set, return deschedule information rather than
18182+ * the standard response for work-queue index (invalid
18183+ * if the work-queue entry is not on the deschedule
18184+ * list).
18185+ */
18186+ uint64_t get_des:1;
18187+ /*
18188+ * If set, get the work-queue pointer rather than
18189+ * tag/type (no effect when get_des set).
18190+ */
18191+ uint64_t get_wqp:1;
18192+ /* Must be zero */
18193+ uint64_t reserved_0_2:3;
18194+ } smemload;
18195+
18196+ /**
18197+ * Address for index/pointer loads
18198+ */
18199+ struct {
18200+ /* Mips64 address region. Should be CVMX_IO_SEG */
18201+ uint64_t mem_region:2;
18202+ /* Must be zero */
18203+ uint64_t reserved_49_61:13;
18204+ /* Must be one */
18205+ uint64_t is_io:1;
18206+ /* the ID of POW -- did<2:0> == 3 in this case */
18207+ uint64_t did:8;
18208+ /* Must be zero */
18209+ uint64_t reserved_9_39:31;
18210+ /*
18211+ * when {get_rmt ==0 AND get_des_get_tail == 0}, this
18212+ * field selects one of eight POW internal-input
18213+ * queues (0-7), one per QOS level; values 8-15 are
18214+ * illegal in this case; when {get_rmt ==0 AND
18215+ * get_des_get_tail == 1}, this field selects one of
18216+ * 16 deschedule lists (per group); when get_rmt ==1,
18217+ * this field selects one of 16 memory-input queue
18218+ * lists. The two memory-input queue lists associated
18219+ * with each QOS level are:
18220+ *
18221+ * - qosgrp = 0, qosgrp = 8: QOS0
18222+ * - qosgrp = 1, qosgrp = 9: QOS1
18223+ * - qosgrp = 2, qosgrp = 10: QOS2
18224+ * - qosgrp = 3, qosgrp = 11: QOS3
18225+ * - qosgrp = 4, qosgrp = 12: QOS4
18226+ * - qosgrp = 5, qosgrp = 13: QOS5
18227+ * - qosgrp = 6, qosgrp = 14: QOS6
18228+ * - qosgrp = 7, qosgrp = 15: QOS7
18229+ */
18230+ uint64_t qosgrp:4;
18231+ /*
18232+ * If set and get_rmt is clear, return deschedule list
18233+ * indexes rather than indexes for the specified qos
18234+ * level; if set and get_rmt is set, return the tail
18235+ * pointer rather than the head pointer for the
18236+ * specified qos level.
18237+ */
18238+ uint64_t get_des_get_tail:1;
18239+ /*
18240+ * If set, return remote pointers rather than the
18241+ * local indexes for the specified qos level.
18242+ */
18243+ uint64_t get_rmt:1;
18244+ /* Must be zero */
18245+ uint64_t reserved_0_2:3;
18246+ } sindexload;
18247+
18248+ /**
18249+ * address for NULL_RD request (did<2:0> == 4) when this is read,
18250+ * HW attempts to change the state to NULL if it is NULL_NULL (the
18251+ * hardware cannot switch from NULL_NULL to NULL if a POW entry is
18252+ * not available - software may need to recover by finishing
18253+ * another piece of work before a POW entry can ever become
18254+ * available.)
18255+ */
18256+ struct {
18257+ /* Mips64 address region. Should be CVMX_IO_SEG */
18258+ uint64_t mem_region:2;
18259+ /* Must be zero */
18260+ uint64_t reserved_49_61:13;
18261+ /* Must be one */
18262+ uint64_t is_io:1;
18263+ /* the ID of POW -- did<2:0> == 4 in this case */
18264+ uint64_t did:8;
18265+ /* Must be zero */
18266+ uint64_t reserved_0_39:40;
18267+ } snull_rd;
18268+} cvmx_pow_load_addr_t;
18269+
18270+/**
18271+ * This structure defines the response to a load/SENDSINGLE to POW
18272+ * (except CSR reads)
18273+ */
18274+typedef union {
18275+ uint64_t u64;
18276+
18277+ /**
18278+ * Response to new work request loads
18279+ */
18280+ struct {
18281+ /*
18282+ * Set when no new work queue entry was returned. *
18283+ * If there was de-scheduled work, the HW will
18284+ * definitely return it. When this bit is set, it
18285+ * could mean either mean:
18286+ *
18287+ * - There was no work, or
18288+ *
18289+ * - There was no work that the HW could find. This
18290+ * case can happen, regardless of the wait bit value
18291+ * in the original request, when there is work in
18292+ * the IQ's that is too deep down the list.
18293+ */
18294+ uint64_t no_work:1;
18295+ /* Must be zero */
18296+ uint64_t reserved_40_62:23;
18297+ /* 36 in O1 -- the work queue pointer */
18298+ uint64_t addr:40;
18299+ } s_work;
18300+
18301+ /**
18302+ * Result for a POW Status Load (when get_cur==0 and get_wqp==0)
18303+ */
18304+ struct {
18305+ uint64_t reserved_62_63:2;
18306+ /* Set when there is a pending non-NULL SWTAG or
18307+ * SWTAG_FULL, and the POW entry has not left the list
18308+ * for the original tag. */
18309+ uint64_t pend_switch:1;
18310+ /* Set when SWTAG_FULL and pend_switch is set. */
18311+ uint64_t pend_switch_full:1;
18312+ /*
18313+ * Set when there is a pending NULL SWTAG, or an
18314+ * implicit switch to NULL.
18315+ */
18316+ uint64_t pend_switch_null:1;
18317+ /* Set when there is a pending DESCHED or SWTAG_DESCHED. */
18318+ uint64_t pend_desched:1;
18319+ /*
18320+ * Set when there is a pending SWTAG_DESCHED and
18321+ * pend_desched is set.
18322+ */
18323+ uint64_t pend_desched_switch:1;
18324+ /* Set when nosched is desired and pend_desched is set. */
18325+ uint64_t pend_nosched:1;
18326+ /* Set when there is a pending GET_WORK. */
18327+ uint64_t pend_new_work:1;
18328+ /*
18329+ * When pend_new_work is set, this bit indicates that
18330+ * the wait bit was set.
18331+ */
18332+ uint64_t pend_new_work_wait:1;
18333+ /* Set when there is a pending NULL_RD. */
18334+ uint64_t pend_null_rd:1;
18335+ /* Set when there is a pending CLR_NSCHED. */
18336+ uint64_t pend_nosched_clr:1;
18337+ uint64_t reserved_51:1;
18338+ /* This is the index when pend_nosched_clr is set. */
18339+ uint64_t pend_index:11;
18340+ /*
18341+ * This is the new_grp when (pend_desched AND
18342+ * pend_desched_switch) is set.
18343+ */
18344+ uint64_t pend_grp:4;
18345+ uint64_t reserved_34_35:2;
18346+ /*
18347+ * This is the tag type when pend_switch or
18348+ * (pend_desched AND pend_desched_switch) are set.
18349+ */
18350+ uint64_t pend_type:2;
18351+ /*
18352+ * - this is the tag when pend_switch or (pend_desched
18353+ * AND pend_desched_switch) are set.
18354+ */
18355+ uint64_t pend_tag:32;
18356+ } s_sstatus0;
18357+
18358+ /**
18359+ * Result for a POW Status Load (when get_cur==0 and get_wqp==1)
18360+ */
18361+ struct {
18362+ uint64_t reserved_62_63:2;
18363+ /*
18364+ * Set when there is a pending non-NULL SWTAG or
18365+ * SWTAG_FULL, and the POW entry has not left the list
18366+ * for the original tag.
18367+ */
18368+ uint64_t pend_switch:1;
18369+ /* Set when SWTAG_FULL and pend_switch is set. */
18370+ uint64_t pend_switch_full:1;
18371+ /*
18372+ * Set when there is a pending NULL SWTAG, or an
18373+ * implicit switch to NULL.
18374+ */
18375+ uint64_t pend_switch_null:1;
18376+ /*
18377+ * Set when there is a pending DESCHED or
18378+ * SWTAG_DESCHED.
18379+ */
18380+ uint64_t pend_desched:1;
18381+ /*
18382+ * Set when there is a pending SWTAG_DESCHED and
18383+ * pend_desched is set.
18384+ */
18385+ uint64_t pend_desched_switch:1;
18386+ /* Set when nosched is desired and pend_desched is set. */
18387+ uint64_t pend_nosched:1;
18388+ /* Set when there is a pending GET_WORK. */
18389+ uint64_t pend_new_work:1;
18390+ /*
18391+ * When pend_new_work is set, this bit indicates that
18392+ * the wait bit was set.
18393+ */
18394+ uint64_t pend_new_work_wait:1;
18395+ /* Set when there is a pending NULL_RD. */
18396+ uint64_t pend_null_rd:1;
18397+ /* Set when there is a pending CLR_NSCHED. */
18398+ uint64_t pend_nosched_clr:1;
18399+ uint64_t reserved_51:1;
18400+ /* This is the index when pend_nosched_clr is set. */
18401+ uint64_t pend_index:11;
18402+ /*
18403+ * This is the new_grp when (pend_desched AND
18404+ * pend_desched_switch) is set.
18405+ */
18406+ uint64_t pend_grp:4;
18407+ /* This is the wqp when pend_nosched_clr is set. */
18408+ uint64_t pend_wqp:36;
18409+ } s_sstatus1;
18410+
18411+ /**
18412+ * Result for a POW Status Load (when get_cur==1, get_wqp==0, and
18413+ * get_rev==0)
18414+ */
18415+ struct {
18416+ uint64_t reserved_62_63:2;
18417+ /*
18418+ * Points to the next POW entry in the tag list when
18419+ * tail == 0 (and tag_type is not NULL or NULL_NULL).
18420+ */
18421+ uint64_t link_index:11;
18422+ /* The POW entry attached to the core. */
18423+ uint64_t index:11;
18424+ /*
18425+ * The group attached to the core (updated when new
18426+ * tag list entered on SWTAG_FULL).
18427+ */
18428+ uint64_t grp:4;
18429+ /*
18430+ * Set when this POW entry is at the head of its tag
18431+ * list (also set when in the NULL or NULL_NULL
18432+ * state).
18433+ */
18434+ uint64_t head:1;
18435+ /*
18436+ * Set when this POW entry is at the tail of its tag
18437+ * list (also set when in the NULL or NULL_NULL
18438+ * state).
18439+ */
18440+ uint64_t tail:1;
18441+ /*
18442+ * The tag type attached to the core (updated when new
18443+ * tag list entered on SWTAG, SWTAG_FULL, or
18444+ * SWTAG_DESCHED).
18445+ */
18446+ uint64_t tag_type:2;
18447+ /*
18448+ * The tag attached to the core (updated when new tag
18449+ * list entered on SWTAG, SWTAG_FULL, or
18450+ * SWTAG_DESCHED).
18451+ */
18452+ uint64_t tag:32;
18453+ } s_sstatus2;
18454+
18455+ /**
18456+ * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1)
18457+ */
18458+ struct {
18459+ uint64_t reserved_62_63:2;
18460+ /*
18461+ * Points to the prior POW entry in the tag list when
18462+ * head == 0 (and tag_type is not NULL or
18463+ * NULL_NULL). This field is unpredictable when the
18464+ * core's state is NULL or NULL_NULL.
18465+ */
18466+ uint64_t revlink_index:11;
18467+ /* The POW entry attached to the core. */
18468+ uint64_t index:11;
18469+ /*
18470+ * The group attached to the core (updated when new
18471+ * tag list entered on SWTAG_FULL).
18472+ */
18473+ uint64_t grp:4;
18474+ /* Set when this POW entry is at the head of its tag
18475+ * list (also set when in the NULL or NULL_NULL
18476+ * state).
18477+ */
18478+ uint64_t head:1;
18479+ /*
18480+ * Set when this POW entry is at the tail of its tag
18481+ * list (also set when in the NULL or NULL_NULL
18482+ * state).
18483+ */
18484+ uint64_t tail:1;
18485+ /*
18486+ * The tag type attached to the core (updated when new
18487+ * tag list entered on SWTAG, SWTAG_FULL, or
18488+ * SWTAG_DESCHED).
18489+ */
18490+ uint64_t tag_type:2;
18491+ /*
18492+ * The tag attached to the core (updated when new tag
18493+ * list entered on SWTAG, SWTAG_FULL, or
18494+ * SWTAG_DESCHED).
18495+ */
18496+ uint64_t tag:32;
18497+ } s_sstatus3;
18498+
18499+ /**
18500+ * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
18501+ * get_rev==0)
18502+ */
18503+ struct {
18504+ uint64_t reserved_62_63:2;
18505+ /*
18506+ * Points to the next POW entry in the tag list when
18507+ * tail == 0 (and tag_type is not NULL or NULL_NULL).
18508+ */
18509+ uint64_t link_index:11;
18510+ /* The POW entry attached to the core. */
18511+ uint64_t index:11;
18512+ /*
18513+ * The group attached to the core (updated when new
18514+ * tag list entered on SWTAG_FULL).
18515+ */
18516+ uint64_t grp:4;
18517+ /*
18518+ * The wqp attached to the core (updated when new tag
18519+ * list entered on SWTAG_FULL).
18520+ */
18521+ uint64_t wqp:36;
18522+ } s_sstatus4;
18523+
18524+ /**
18525+ * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
18526+ * get_rev==1)
18527+ */
18528+ struct {
18529+ uint64_t reserved_62_63:2;
18530+ /*
18531+ * Points to the prior POW entry in the tag list when
18532+ * head == 0 (and tag_type is not NULL or
18533+ * NULL_NULL). This field is unpredictable when the
18534+ * core's state is NULL or NULL_NULL.
18535+ */
18536+ uint64_t revlink_index:11;
18537+ /* The POW entry attached to the core. */
18538+ uint64_t index:11;
18539+ /*
18540+ * The group attached to the core (updated when new
18541+ * tag list entered on SWTAG_FULL).
18542+ */
18543+ uint64_t grp:4;
18544+ /*
18545+ * The wqp attached to the core (updated when new tag
18546+ * list entered on SWTAG_FULL).
18547+ */
18548+ uint64_t wqp:36;
18549+ } s_sstatus5;
18550+
18551+ /**
18552+ * Result For POW Memory Load (get_des == 0 and get_wqp == 0)
18553+ */
18554+ struct {
18555+ uint64_t reserved_51_63:13;
18556+ /*
18557+ * The next entry in the input, free, descheduled_head
18558+ * list (unpredictable if entry is the tail of the
18559+ * list).
18560+ */
18561+ uint64_t next_index:11;
18562+ /* The group of the POW entry. */
18563+ uint64_t grp:4;
18564+ uint64_t reserved_35:1;
18565+ /*
18566+ * Set when this POW entry is at the tail of its tag
18567+ * list (also set when in the NULL or NULL_NULL
18568+ * state).
18569+ */
18570+ uint64_t tail:1;
18571+ /* The tag type of the POW entry. */
18572+ uint64_t tag_type:2;
18573+ /* The tag of the POW entry. */
18574+ uint64_t tag:32;
18575+ } s_smemload0;
18576+
18577+ /**
18578+ * Result For POW Memory Load (get_des == 0 and get_wqp == 1)
18579+ */
18580+ struct {
18581+ uint64_t reserved_51_63:13;
18582+ /*
18583+ * The next entry in the input, free, descheduled_head
18584+ * list (unpredictable if entry is the tail of the
18585+ * list).
18586+ */
18587+ uint64_t next_index:11;
18588+ /* The group of the POW entry. */
18589+ uint64_t grp:4;
18590+ /* The WQP held in the POW entry. */
18591+ uint64_t wqp:36;
18592+ } s_smemload1;
18593+
18594+ /**
18595+ * Result For POW Memory Load (get_des == 1)
18596+ */
18597+ struct {
18598+ uint64_t reserved_51_63:13;
18599+ /*
18600+ * The next entry in the tag list connected to the
18601+ * descheduled head.
18602+ */
18603+ uint64_t fwd_index:11;
18604+ /* The group of the POW entry. */
18605+ uint64_t grp:4;
18606+ /* The nosched bit for the POW entry. */
18607+ uint64_t nosched:1;
18608+ /* There is a pending tag switch */
18609+ uint64_t pend_switch:1;
18610+ /*
18611+ * The next tag type for the new tag list when
18612+ * pend_switch is set.
18613+ */
18614+ uint64_t pend_type:2;
18615+ /*
18616+ * The next tag for the new tag list when pend_switch
18617+ * is set.
18618+ */
18619+ uint64_t pend_tag:32;
18620+ } s_smemload2;
18621+
18622+ /**
18623+ * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0)
18624+ */
18625+ struct {
18626+ uint64_t reserved_52_63:12;
18627+ /*
18628+ * set when there is one or more POW entries on the
18629+ * free list.
18630+ */
18631+ uint64_t free_val:1;
18632+ /*
18633+ * set when there is exactly one POW entry on the free
18634+ * list.
18635+ */
18636+ uint64_t free_one:1;
18637+ uint64_t reserved_49:1;
18638+ /*
18639+ * when free_val is set, indicates the first entry on
18640+ * the free list.
18641+ */
18642+ uint64_t free_head:11;
18643+ uint64_t reserved_37:1;
18644+ /*
18645+ * when free_val is set, indicates the last entry on
18646+ * the free list.
18647+ */
18648+ uint64_t free_tail:11;
18649+ /*
18650+ * set when there is one or more POW entries on the
18651+ * input Q list selected by qosgrp.
18652+ */
18653+ uint64_t loc_val:1;
18654+ /*
18655+ * set when there is exactly one POW entry on the
18656+ * input Q list selected by qosgrp.
18657+ */
18658+ uint64_t loc_one:1;
18659+ uint64_t reserved_23:1;
18660+ /*
18661+ * when loc_val is set, indicates the first entry on
18662+ * the input Q list selected by qosgrp.
18663+ */
18664+ uint64_t loc_head:11;
18665+ uint64_t reserved_11:1;
18666+ /*
18667+ * when loc_val is set, indicates the last entry on
18668+ * the input Q list selected by qosgrp.
18669+ */
18670+ uint64_t loc_tail:11;
18671+ } sindexload0;
18672+
18673+ /**
18674+ * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1)
18675+ */
18676+ struct {
18677+ uint64_t reserved_52_63:12;
18678+ /*
18679+ * set when there is one or more POW entries on the
18680+ * nosched list.
18681+ */
18682+ uint64_t nosched_val:1;
18683+ /*
18684+ * set when there is exactly one POW entry on the
18685+ * nosched list.
18686+ */
18687+ uint64_t nosched_one:1;
18688+ uint64_t reserved_49:1;
18689+ /*
18690+ * when nosched_val is set, indicates the first entry
18691+ * on the nosched list.
18692+ */
18693+ uint64_t nosched_head:11;
18694+ uint64_t reserved_37:1;
18695+ /*
18696+ * when nosched_val is set, indicates the last entry
18697+ * on the nosched list.
18698+ */
18699+ uint64_t nosched_tail:11;
18700+ /*
18701+ * set when there is one or more descheduled heads on
18702+ * the descheduled list selected by qosgrp.
18703+ */
18704+ uint64_t des_val:1;
18705+ /*
18706+ * set when there is exactly one descheduled head on
18707+ * the descheduled list selected by qosgrp.
18708+ */
18709+ uint64_t des_one:1;
18710+ uint64_t reserved_23:1;
18711+ /*
18712+ * when des_val is set, indicates the first
18713+ * descheduled head on the descheduled list selected
18714+ * by qosgrp.
18715+ */
18716+ uint64_t des_head:11;
18717+ uint64_t reserved_11:1;
18718+ /*
18719+ * when des_val is set, indicates the last descheduled
18720+ * head on the descheduled list selected by qosgrp.
18721+ */
18722+ uint64_t des_tail:11;
18723+ } sindexload1;
18724+
18725+ /**
18726+ * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0)
18727+ */
18728+ struct {
18729+ uint64_t reserved_39_63:25;
18730+ /*
18731+ * Set when this DRAM list is the current head
18732+ * (i.e. is the next to be reloaded when the POW
18733+ * hardware reloads a POW entry from DRAM). The POW
18734+ * hardware alternates between the two DRAM lists
18735+ * associated with a QOS level when it reloads work
18736+ * from DRAM into the POW unit.
18737+ */
18738+ uint64_t rmt_is_head:1;
18739+ /*
18740+ * Set when the DRAM portion of the input Q list
18741+ * selected by qosgrp contains one or more pieces of
18742+ * work.
18743+ */
18744+ uint64_t rmt_val:1;
18745+ /*
18746+ * Set when the DRAM portion of the input Q list
18747+ * selected by qosgrp contains exactly one piece of
18748+ * work.
18749+ */
18750+ uint64_t rmt_one:1;
18751+ /*
18752+ * When rmt_val is set, indicates the first piece of
18753+ * work on the DRAM input Q list selected by
18754+ * qosgrp.
18755+ */
18756+ uint64_t rmt_head:36;
18757+ } sindexload2;
18758+
18759+ /**
18760+ * Result For POW Index/Pointer Load (get_rmt ==
18761+ * 1/get_des_get_tail == 1)
18762+ */
18763+ struct {
18764+ uint64_t reserved_39_63:25;
18765+ /*
18766+ * set when this DRAM list is the current head
18767+ * (i.e. is the next to be reloaded when the POW
18768+ * hardware reloads a POW entry from DRAM). The POW
18769+ * hardware alternates between the two DRAM lists
18770+ * associated with a QOS level when it reloads work
18771+ * from DRAM into the POW unit.
18772+ */
18773+ uint64_t rmt_is_head:1;
18774+ /*
18775+ * set when the DRAM portion of the input Q list
18776+ * selected by qosgrp contains one or more pieces of
18777+ * work.
18778+ */
18779+ uint64_t rmt_val:1;
18780+ /*
18781+ * set when the DRAM portion of the input Q list
18782+ * selected by qosgrp contains exactly one piece of
18783+ * work.
18784+ */
18785+ uint64_t rmt_one:1;
18786+ /*
18787+ * when rmt_val is set, indicates the last piece of
18788+ * work on the DRAM input Q list selected by
18789+ * qosgrp.
18790+ */
18791+ uint64_t rmt_tail:36;
18792+ } sindexload3;
18793+
18794+ /**
18795+ * Response to NULL_RD request loads
18796+ */
18797+ struct {
18798+ uint64_t unused:62;
18799+ /* of type cvmx_pow_tag_type_t. state is one of the
18800+ * following:
18801+ *
18802+ * - CVMX_POW_TAG_TYPE_ORDERED
18803+ * - CVMX_POW_TAG_TYPE_ATOMIC
18804+ * - CVMX_POW_TAG_TYPE_NULL
18805+ * - CVMX_POW_TAG_TYPE_NULL_NULL
18806+ */
18807+ uint64_t state:2;
18808+ } s_null_rd;
18809+
18810+} cvmx_pow_tag_load_resp_t;
18811+
18812+/**
18813+ * This structure describes the address used for stores to the POW.
18814+ * The store address is meaningful on stores to the POW. The
18815+ * hardware assumes that an aligned 64-bit store was used for all
18816+ * these stores. Note the assumption that the work queue entry is
18817+ * aligned on an 8-byte boundary (since the low-order 3 address bits
18818+ * must be zero). Note that not all fields are used by all
18819+ * operations.
18820+ *
18821+ * NOTE: The following is the behavior of the pending switch bit at the PP
18822+ * for POW stores (i.e. when did<7:3> == 0xc)
18823+ * - did<2:0> == 0 => pending switch bit is set
18824+ * - did<2:0> == 1 => no affect on the pending switch bit
18825+ * - did<2:0> == 3 => pending switch bit is cleared
18826+ * - did<2:0> == 7 => no affect on the pending switch bit
18827+ * - did<2:0> == others => must not be used
18828+ * - No other loads/stores have an affect on the pending switch bit
18829+ * - The switch bus from POW can clear the pending switch bit
18830+ *
18831+ * NOTE: did<2:0> == 2 is used by the HW for a special single-cycle
18832+ * ADDWQ command that only contains the pointer). SW must never use
18833+ * did<2:0> == 2.
18834+ */
18835+typedef union {
18836+ /**
18837+ * Unsigned 64 bit integer representation of store address
18838+ */
18839+ uint64_t u64;
18840+
18841+ struct {
18842+ /* Memory region. Should be CVMX_IO_SEG in most cases */
18843+ uint64_t mem_reg:2;
18844+ uint64_t reserved_49_61:13; /* Must be zero */
18845+ uint64_t is_io:1; /* Must be one */
18846+ /* Device ID of POW. Note that different sub-dids are used. */
18847+ uint64_t did:8;
18848+ uint64_t reserved_36_39:4; /* Must be zero */
18849+ /* Address field. addr<2:0> must be zero */
18850+ uint64_t addr:36;
18851+ } stag;
18852+} cvmx_pow_tag_store_addr_t;
18853+
18854+/**
18855+ * decode of the store data when an IOBDMA SENDSINGLE is sent to POW
18856+ */
18857+typedef union {
18858+ uint64_t u64;
18859+
18860+ struct {
18861+ /*
18862+ * the (64-bit word) location in scratchpad to write
18863+ * to (if len != 0)
18864+ */
18865+ uint64_t scraddr:8;
18866+ /* the number of words in the response (0 => no response) */
18867+ uint64_t len:8;
18868+ /* the ID of the device on the non-coherent bus */
18869+ uint64_t did:8;
18870+ uint64_t unused:36;
18871+ /* if set, don't return load response until work is available */
18872+ uint64_t wait:1;
18873+ uint64_t unused2:3;
18874+ } s;
18875+
18876+} cvmx_pow_iobdma_store_t;
18877+
18878+/* CSR typedefs have been moved to cvmx-csr-*.h */
18879+
18880+/**
18881+ * Get the POW tag for this core. This returns the current
18882+ * tag type, tag, group, and POW entry index associated with
18883+ * this core. Index is only valid if the tag type isn't NULL_NULL.
18884+ * If a tag switch is pending this routine returns the tag before
18885+ * the tag switch, not after.
18886+ *
18887+ * Returns Current tag
18888+ */
18889+static inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void)
18890+{
18891+ cvmx_pow_load_addr_t load_addr;
18892+ cvmx_pow_tag_load_resp_t load_resp;
18893+ cvmx_pow_tag_req_t result;
18894+
18895+ load_addr.u64 = 0;
18896+ load_addr.sstatus.mem_region = CVMX_IO_SEG;
18897+ load_addr.sstatus.is_io = 1;
18898+ load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
18899+ load_addr.sstatus.coreid = cvmx_get_core_num();
18900+ load_addr.sstatus.get_cur = 1;
18901+ load_resp.u64 = cvmx_read_csr(load_addr.u64);
18902+ result.u64 = 0;
18903+ result.s.grp = load_resp.s_sstatus2.grp;
18904+ result.s.index = load_resp.s_sstatus2.index;
18905+ result.s.type = load_resp.s_sstatus2.tag_type;
18906+ result.s.tag = load_resp.s_sstatus2.tag;
18907+ return result;
18908+}
18909+
18910+/**
18911+ * Get the POW WQE for this core. This returns the work queue
18912+ * entry currently associated with this core.
18913+ *
18914+ * Returns WQE pointer
18915+ */
18916+static inline cvmx_wqe_t *cvmx_pow_get_current_wqp(void)
18917+{
18918+ cvmx_pow_load_addr_t load_addr;
18919+ cvmx_pow_tag_load_resp_t load_resp;
18920+
18921+ load_addr.u64 = 0;
18922+ load_addr.sstatus.mem_region = CVMX_IO_SEG;
18923+ load_addr.sstatus.is_io = 1;
18924+ load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
18925+ load_addr.sstatus.coreid = cvmx_get_core_num();
18926+ load_addr.sstatus.get_cur = 1;
18927+ load_addr.sstatus.get_wqp = 1;
18928+ load_resp.u64 = cvmx_read_csr(load_addr.u64);
18929+ return (cvmx_wqe_t *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp);
18930+}
18931+
18932+#ifndef CVMX_MF_CHORD
18933+#define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30)
18934+#endif
18935+
18936+/**
18937+ * Print a warning if a tag switch is pending for this core
18938+ *
18939+ * @function: Function name checking for a pending tag switch
18940+ */
18941+static inline void __cvmx_pow_warn_if_pending_switch(const char *function)
18942+{
18943+ uint64_t switch_complete;
18944+ CVMX_MF_CHORD(switch_complete);
18945+ if (!switch_complete)
18946+ pr_warning("%s called with tag switch in progress\n", function);
18947+}
18948+
18949+/**
18950+ * Waits for a tag switch to complete by polling the completion bit.
18951+ * Note that switches to NULL complete immediately and do not need
18952+ * to be waited for.
18953+ */
18954+static inline void cvmx_pow_tag_sw_wait(void)
18955+{
18956+ const uint64_t MAX_CYCLES = 1ull << 31;
18957+ uint64_t switch_complete;
18958+ uint64_t start_cycle = cvmx_get_cycle();
18959+ while (1) {
18960+ CVMX_MF_CHORD(switch_complete);
18961+ if (unlikely(switch_complete))
18962+ break;
18963+ if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) {
18964+ pr_warning("Tag switch is taking a long time, "
18965+ "possible deadlock\n");
18966+ start_cycle = -MAX_CYCLES - 1;
18967+ }
18968+ }
18969+}
18970+
18971+/**
18972+ * Synchronous work request. Requests work from the POW.
18973+ * This function does NOT wait for previous tag switches to complete,
18974+ * so the caller must ensure that there is not a pending tag switch.
18975+ *
18976+ * @wait: When set, call stalls until work becomes avaiable, or times out.
18977+ * If not set, returns immediately.
18978+ *
18979+ * Returns Returns the WQE pointer from POW. Returns NULL if no work
18980+ * was available.
18981+ */
18982+static inline cvmx_wqe_t *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t
18983+ wait)
18984+{
18985+ cvmx_pow_load_addr_t ptr;
18986+ cvmx_pow_tag_load_resp_t result;
18987+
18988+ if (CVMX_ENABLE_POW_CHECKS)
18989+ __cvmx_pow_warn_if_pending_switch(__func__);
18990+
18991+ ptr.u64 = 0;
18992+ ptr.swork.mem_region = CVMX_IO_SEG;
18993+ ptr.swork.is_io = 1;
18994+ ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG;
18995+ ptr.swork.wait = wait;
18996+
18997+ result.u64 = cvmx_read_csr(ptr.u64);
18998+
18999+ if (result.s_work.no_work)
19000+ return NULL;
19001+ else
19002+ return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
19003+}
19004+
19005+/**
19006+ * Synchronous work request. Requests work from the POW.
19007+ * This function waits for any previous tag switch to complete before
19008+ * requesting the new work.
19009+ *
19010+ * @wait: When set, call stalls until work becomes avaiable, or times out.
19011+ * If not set, returns immediately.
19012+ *
19013+ * Returns Returns the WQE pointer from POW. Returns NULL if no work
19014+ * was available.
19015+ */
19016+static inline cvmx_wqe_t *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
19017+{
19018+ if (CVMX_ENABLE_POW_CHECKS)
19019+ __cvmx_pow_warn_if_pending_switch(__func__);
19020+
19021+ /* Must not have a switch pending when requesting work */
19022+ cvmx_pow_tag_sw_wait();
19023+ return cvmx_pow_work_request_sync_nocheck(wait);
19024+
19025+}
19026+
19027+/**
19028+ * Synchronous null_rd request. Requests a switch out of NULL_NULL POW state.
19029+ * This function waits for any previous tag switch to complete before
19030+ * requesting the null_rd.
19031+ *
19032+ * Returns Returns the POW state of type cvmx_pow_tag_type_t.
19033+ */
19034+static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void)
19035+{
19036+ cvmx_pow_load_addr_t ptr;
19037+ cvmx_pow_tag_load_resp_t result;
19038+
19039+ if (CVMX_ENABLE_POW_CHECKS)
19040+ __cvmx_pow_warn_if_pending_switch(__func__);
19041+
19042+ /* Must not have a switch pending when requesting work */
19043+ cvmx_pow_tag_sw_wait();
19044+
19045+ ptr.u64 = 0;
19046+ ptr.snull_rd.mem_region = CVMX_IO_SEG;
19047+ ptr.snull_rd.is_io = 1;
19048+ ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD;
19049+
19050+ result.u64 = cvmx_read_csr(ptr.u64);
19051+
19052+ return (enum cvmx_pow_tag_type) result.s_null_rd.state;
19053+}
19054+
19055+/**
19056+ * Asynchronous work request. Work is requested from the POW unit,
19057+ * and should later be checked with function
19058+ * cvmx_pow_work_response_async. This function does NOT wait for
19059+ * previous tag switches to complete, so the caller must ensure that
19060+ * there is not a pending tag switch.
19061+ *
19062+ * @scr_addr: Scratch memory address that response will be returned
19063+ * to, which is either a valid WQE, or a response with the
19064+ * invalid bit set. Byte address, must be 8 byte aligned.
19065+ *
19066+ * @wait: 1 to cause response to wait for work to become available (or
19067+ * timeout), 0 to cause response to return immediately
19068+ */
19069+static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
19070+ cvmx_pow_wait_t wait)
19071+{
19072+ cvmx_pow_iobdma_store_t data;
19073+
19074+ if (CVMX_ENABLE_POW_CHECKS)
19075+ __cvmx_pow_warn_if_pending_switch(__func__);
19076+
19077+ /* scr_addr must be 8 byte aligned */
19078+ data.s.scraddr = scr_addr >> 3;
19079+ data.s.len = 1;
19080+ data.s.did = CVMX_OCT_DID_TAG_SWTAG;
19081+ data.s.wait = wait;
19082+ cvmx_send_single(data.u64);
19083+}
19084+
19085+/**
19086+ * Asynchronous work request. Work is requested from the POW unit,
19087+ * and should later be checked with function
19088+ * cvmx_pow_work_response_async. This function waits for any previous
19089+ * tag switch to complete before requesting the new work.
19090+ *
19091+ * @scr_addr: Scratch memory address that response will be returned
19092+ * to, which is either a valid WQE, or a response with the
19093+ * invalid bit set. Byte address, must be 8 byte aligned.
19094+ *
19095+ * @wait: 1 to cause response to wait for work to become available (or
19096+ * timeout), 0 to cause response to return immediately
19097+ */
19098+static inline void cvmx_pow_work_request_async(int scr_addr,
19099+ cvmx_pow_wait_t wait)
19100+{
19101+ if (CVMX_ENABLE_POW_CHECKS)
19102+ __cvmx_pow_warn_if_pending_switch(__func__);
19103+
19104+ /* Must not have a switch pending when requesting work */
19105+ cvmx_pow_tag_sw_wait();
19106+ cvmx_pow_work_request_async_nocheck(scr_addr, wait);
19107+}
19108+
19109+/**
19110+ * Gets result of asynchronous work request. Performs a IOBDMA sync
19111+ * to wait for the response.
19112+ *
19113+ * @scr_addr: Scratch memory address to get result from Byte address,
19114+ * must be 8 byte aligned.
19115+ *
19116+ * Returns Returns the WQE from the scratch register, or NULL if no
19117+ * work was available.
19118+ */
19119+static inline cvmx_wqe_t *cvmx_pow_work_response_async(int scr_addr)
19120+{
19121+ cvmx_pow_tag_load_resp_t result;
19122+
19123+ CVMX_SYNCIOBDMA;
19124+ result.u64 = cvmx_scratch_read64(scr_addr);
19125+
19126+ if (result.s_work.no_work)
19127+ return NULL;
19128+ else
19129+ return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
19130+}
19131+
19132+/**
19133+ * Checks if a work queue entry pointer returned by a work
19134+ * request is valid. It may be invalid due to no work
19135+ * being available or due to a timeout.
19136+ *
19137+ * @wqe_ptr: pointer to a work queue entry returned by the POW
19138+ *
19139+ * Returns 0 if pointer is valid
19140+ * 1 if invalid (no work was returned)
19141+ */
19142+static inline uint64_t cvmx_pow_work_invalid(cvmx_wqe_t *wqe_ptr)
19143+{
19144+ return wqe_ptr == NULL;
19145+}
19146+
19147+/**
19148+ * Starts a tag switch to the provided tag value and tag type.
19149+ * Completion for the tag switch must be checked for separately. This
19150+ * function does NOT update the work queue entry in dram to match tag
19151+ * value and type, so the application must keep track of these if they
19152+ * are important to the application. This tag switch command must not
19153+ * be used for switches to NULL, as the tag switch pending bit will be
19154+ * set by the switch request, but never cleared by the hardware.
19155+ *
19156+ * NOTE: This should not be used when switching from a NULL tag. Use
19157+ * cvmx_pow_tag_sw_full() instead.
19158+ *
19159+ * This function does no checks, so the caller must ensure that any
19160+ * previous tag switch has completed.
19161+ *
19162+ * @tag: new tag value
19163+ * @tag_type: new tag type (ordered or atomic)
19164+ */
19165+static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag,
19166+ enum cvmx_pow_tag_type tag_type)
19167+{
19168+ cvmx_addr_t ptr;
19169+ cvmx_pow_tag_req_t tag_req;
19170+
19171+ if (CVMX_ENABLE_POW_CHECKS) {
19172+ cvmx_pow_tag_req_t current_tag;
19173+ __cvmx_pow_warn_if_pending_switch(__func__);
19174+ current_tag = cvmx_pow_get_current_tag();
19175+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19176+ pr_warning("%s called with NULL_NULL tag\n",
19177+ __func__);
19178+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19179+ pr_warning("%s called with NULL tag\n", __func__);
19180+ if ((current_tag.s.type == tag_type)
19181+ && (current_tag.s.tag == tag))
19182+ pr_warning("%s called to perform a tag switch to the "
19183+ "same tag\n",
19184+ __func__);
19185+ if (tag_type == CVMX_POW_TAG_TYPE_NULL)
19186+ pr_warning("%s called to perform a tag switch to "
19187+ "NULL. Use cvmx_pow_tag_sw_null() instead\n",
19188+ __func__);
19189+ }
19190+
19191+ /*
19192+ * Note that WQE in DRAM is not updated here, as the POW does
19193+ * not read from DRAM once the WQE is in flight. See hardware
19194+ * manual for complete details. It is the application's
19195+ * responsibility to keep track of the current tag value if
19196+ * that is important.
19197+ */
19198+
19199+ tag_req.u64 = 0;
19200+ tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
19201+ tag_req.s.tag = tag;
19202+ tag_req.s.type = tag_type;
19203+
19204+ ptr.u64 = 0;
19205+ ptr.sio.mem_region = CVMX_IO_SEG;
19206+ ptr.sio.is_io = 1;
19207+ ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
19208+
19209+ /* once this store arrives at POW, it will attempt the switch
19210+ software must wait for the switch to complete separately */
19211+ cvmx_write_io(ptr.u64, tag_req.u64);
19212+}
19213+
19214+/**
19215+ * Starts a tag switch to the provided tag value and tag type.
19216+ * Completion for the tag switch must be checked for separately. This
19217+ * function does NOT update the work queue entry in dram to match tag
19218+ * value and type, so the application must keep track of these if they
19219+ * are important to the application. This tag switch command must not
19220+ * be used for switches to NULL, as the tag switch pending bit will be
19221+ * set by the switch request, but never cleared by the hardware.
19222+ *
19223+ * NOTE: This should not be used when switching from a NULL tag. Use
19224+ * cvmx_pow_tag_sw_full() instead.
19225+ *
19226+ * This function waits for any previous tag switch to complete, and also
19227+ * displays an error on tag switches to NULL.
19228+ *
19229+ * @tag: new tag value
19230+ * @tag_type: new tag type (ordered or atomic)
19231+ */
19232+static inline void cvmx_pow_tag_sw(uint32_t tag,
19233+ enum cvmx_pow_tag_type tag_type)
19234+{
19235+ if (CVMX_ENABLE_POW_CHECKS)
19236+ __cvmx_pow_warn_if_pending_switch(__func__);
19237+
19238+ /*
19239+ * Note that WQE in DRAM is not updated here, as the POW does
19240+ * not read from DRAM once the WQE is in flight. See hardware
19241+ * manual for complete details. It is the application's
19242+ * responsibility to keep track of the current tag value if
19243+ * that is important.
19244+ */
19245+
19246+ /*
19247+ * Ensure that there is not a pending tag switch, as a tag
19248+ * switch cannot be started if a previous switch is still
19249+ * pending.
19250+ */
19251+ cvmx_pow_tag_sw_wait();
19252+ cvmx_pow_tag_sw_nocheck(tag, tag_type);
19253+}
19254+
19255+/**
19256+ * Starts a tag switch to the provided tag value and tag type.
19257+ * Completion for the tag switch must be checked for separately. This
19258+ * function does NOT update the work queue entry in dram to match tag
19259+ * value and type, so the application must keep track of these if they
19260+ * are important to the application. This tag switch command must not
19261+ * be used for switches to NULL, as the tag switch pending bit will be
19262+ * set by the switch request, but never cleared by the hardware.
19263+ *
19264+ * This function must be used for tag switches from NULL.
19265+ *
19266+ * This function does no checks, so the caller must ensure that any
19267+ * previous tag switch has completed.
19268+ *
19269+ * @wqp: pointer to work queue entry to submit. This entry is
19270+ * updated to match the other parameters
19271+ * @tag: tag value to be assigned to work queue entry
19272+ * @tag_type: type of tag
19273+ * @group: group value for the work queue entry.
19274+ */
19275+static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag,
19276+ enum cvmx_pow_tag_type tag_type,
19277+ uint64_t group)
19278+{
19279+ cvmx_addr_t ptr;
19280+ cvmx_pow_tag_req_t tag_req;
19281+
19282+ if (CVMX_ENABLE_POW_CHECKS) {
19283+ cvmx_pow_tag_req_t current_tag;
19284+ __cvmx_pow_warn_if_pending_switch(__func__);
19285+ current_tag = cvmx_pow_get_current_tag();
19286+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19287+ pr_warning("%s called with NULL_NULL tag\n",
19288+ __func__);
19289+ if ((current_tag.s.type == tag_type)
19290+ && (current_tag.s.tag == tag))
19291+ pr_warning("%s called to perform a tag switch to "
19292+ "the same tag\n",
19293+ __func__);
19294+ if (tag_type == CVMX_POW_TAG_TYPE_NULL)
19295+ pr_warning("%s called to perform a tag switch to "
19296+ "NULL. Use cvmx_pow_tag_sw_null() instead\n",
19297+ __func__);
19298+ if (wqp != cvmx_phys_to_ptr(0x80))
19299+ if (wqp != cvmx_pow_get_current_wqp())
19300+ pr_warning("%s passed WQE(%p) doesn't match "
19301+ "the address in the POW(%p)\n",
19302+ __func__, wqp,
19303+ cvmx_pow_get_current_wqp());
19304+ }
19305+
19306+ /*
19307+ * Note that WQE in DRAM is not updated here, as the POW does
19308+ * not read from DRAM once the WQE is in flight. See hardware
19309+ * manual for complete details. It is the application's
19310+ * responsibility to keep track of the current tag value if
19311+ * that is important.
19312+ */
19313+
19314+ tag_req.u64 = 0;
19315+ tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL;
19316+ tag_req.s.tag = tag;
19317+ tag_req.s.type = tag_type;
19318+ tag_req.s.grp = group;
19319+
19320+ ptr.u64 = 0;
19321+ ptr.sio.mem_region = CVMX_IO_SEG;
19322+ ptr.sio.is_io = 1;
19323+ ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
19324+ ptr.sio.offset = CAST64(wqp);
19325+
19326+ /*
19327+ * once this store arrives at POW, it will attempt the switch
19328+ * software must wait for the switch to complete separately.
19329+ */
19330+ cvmx_write_io(ptr.u64, tag_req.u64);
19331+}
19332+
19333+/**
19334+ * Starts a tag switch to the provided tag value and tag type.
19335+ * Completion for the tag switch must be checked for separately. This
19336+ * function does NOT update the work queue entry in dram to match tag
19337+ * value and type, so the application must keep track of these if they
19338+ * are important to the application. This tag switch command must not
19339+ * be used for switches to NULL, as the tag switch pending bit will be
19340+ * set by the switch request, but never cleared by the hardware.
19341+ *
19342+ * This function must be used for tag switches from NULL.
19343+ *
19344+ * This function waits for any pending tag switches to complete
19345+ * before requesting the tag switch.
19346+ *
19347+ * @wqp: pointer to work queue entry to submit. This entry is updated
19348+ * to match the other parameters
19349+ * @tag: tag value to be assigned to work queue entry
19350+ * @tag_type: type of tag
19351+ * @group: group value for the work queue entry.
19352+ */
19353+static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag,
19354+ enum cvmx_pow_tag_type tag_type,
19355+ uint64_t group)
19356+{
19357+ if (CVMX_ENABLE_POW_CHECKS)
19358+ __cvmx_pow_warn_if_pending_switch(__func__);
19359+
19360+ /*
19361+ * Ensure that there is not a pending tag switch, as a tag
19362+ * switch cannot be started if a previous switch is still
19363+ * pending.
19364+ */
19365+ cvmx_pow_tag_sw_wait();
19366+ cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group);
19367+}
19368+
19369+/**
19370+ * Switch to a NULL tag, which ends any ordering or
19371+ * synchronization provided by the POW for the current
19372+ * work queue entry. This operation completes immediatly,
19373+ * so completetion should not be waited for.
19374+ * This function does NOT wait for previous tag switches to complete,
19375+ * so the caller must ensure that any previous tag switches have completed.
19376+ */
19377+static inline void cvmx_pow_tag_sw_null_nocheck(void)
19378+{
19379+ cvmx_addr_t ptr;
19380+ cvmx_pow_tag_req_t tag_req;
19381+
19382+ if (CVMX_ENABLE_POW_CHECKS) {
19383+ cvmx_pow_tag_req_t current_tag;
19384+ __cvmx_pow_warn_if_pending_switch(__func__);
19385+ current_tag = cvmx_pow_get_current_tag();
19386+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19387+ pr_warning("%s called with NULL_NULL tag\n",
19388+ __func__);
19389+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19390+ pr_warning("%s called when we already have a "
19391+ "NULL tag\n",
19392+ __func__);
19393+ }
19394+
19395+ tag_req.u64 = 0;
19396+ tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
19397+ tag_req.s.type = CVMX_POW_TAG_TYPE_NULL;
19398+
19399+ ptr.u64 = 0;
19400+ ptr.sio.mem_region = CVMX_IO_SEG;
19401+ ptr.sio.is_io = 1;
19402+ ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
19403+
19404+ cvmx_write_io(ptr.u64, tag_req.u64);
19405+
19406+ /* switch to NULL completes immediately */
19407+}
19408+
19409+/**
19410+ * Switch to a NULL tag, which ends any ordering or
19411+ * synchronization provided by the POW for the current
19412+ * work queue entry. This operation completes immediatly,
19413+ * so completetion should not be waited for.
19414+ * This function waits for any pending tag switches to complete
19415+ * before requesting the switch to NULL.
19416+ */
19417+static inline void cvmx_pow_tag_sw_null(void)
19418+{
19419+ if (CVMX_ENABLE_POW_CHECKS)
19420+ __cvmx_pow_warn_if_pending_switch(__func__);
19421+
19422+ /*
19423+ * Ensure that there is not a pending tag switch, as a tag
19424+ * switch cannot be started if a previous switch is still
19425+ * pending.
19426+ */
19427+ cvmx_pow_tag_sw_wait();
19428+ cvmx_pow_tag_sw_null_nocheck();
19429+
19430+ /* switch to NULL completes immediately */
19431+}
19432+
19433+/**
19434+ * Submits work to an input queue. This function updates the work
19435+ * queue entry in DRAM to match the arguments given. Note that the
19436+ * tag provided is for the work queue entry submitted, and is
19437+ * unrelated to the tag that the core currently holds.
19438+ *
19439+ * @wqp: pointer to work queue entry to submit. This entry is
19440+ * updated to match the other parameters
19441+ * @tag: tag value to be assigned to work queue entry
19442+ * @tag_type: type of tag
19443+ * @qos: Input queue to add to.
19444+ * @grp: group value for the work queue entry.
19445+ */
19446+static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag,
19447+ enum cvmx_pow_tag_type tag_type,
19448+ uint64_t qos, uint64_t grp)
19449+{
19450+ cvmx_addr_t ptr;
19451+ cvmx_pow_tag_req_t tag_req;
19452+
19453+ wqp->qos = qos;
19454+ wqp->tag = tag;
19455+ wqp->tag_type = tag_type;
19456+ wqp->grp = grp;
19457+
19458+ tag_req.u64 = 0;
19459+ tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ;
19460+ tag_req.s.type = tag_type;
19461+ tag_req.s.tag = tag;
19462+ tag_req.s.qos = qos;
19463+ tag_req.s.grp = grp;
19464+
19465+ ptr.u64 = 0;
19466+ ptr.sio.mem_region = CVMX_IO_SEG;
19467+ ptr.sio.is_io = 1;
19468+ ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
19469+ ptr.sio.offset = cvmx_ptr_to_phys(wqp);
19470+
19471+ /*
19472+ * SYNC write to memory before the work submit. This is
19473+ * necessary as POW may read values from DRAM at this time.
19474+ */
19475+ CVMX_SYNCWS;
19476+ cvmx_write_io(ptr.u64, tag_req.u64);
19477+}
19478+
19479+/**
19480+ * This function sets the group mask for a core. The group mask
19481+ * indicates which groups each core will accept work from. There are
19482+ * 16 groups.
19483+ *
19484+ * @core_num: core to apply mask to
19485+ * @mask: Group mask. There are 16 groups, so only bits 0-15 are valid,
19486+ * representing groups 0-15.
19487+ * Each 1 bit in the mask enables the core to accept work from
19488+ * the corresponding group.
19489+ */
19490+static inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask)
19491+{
19492+ union cvmx_pow_pp_grp_mskx grp_msk;
19493+
19494+ grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
19495+ grp_msk.s.grp_msk = mask;
19496+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
19497+}
19498+
19499+/**
19500+ * This function sets POW static priorities for a core. Each input queue has
19501+ * an associated priority value.
19502+ *
19503+ * @core_num: core to apply priorities to
19504+ * @priority: Vector of 8 priorities, one per POW Input Queue (0-7).
19505+ * Highest priority is 0 and lowest is 7. A priority value
19506+ * of 0xF instructs POW to skip the Input Queue when
19507+ * scheduling to this specific core.
19508+ * NOTE: priorities should not have gaps in values, meaning
19509+ * {0,1,1,1,1,1,1,1} is a valid configuration while
19510+ * {0,2,2,2,2,2,2,2} is not.
19511+ */
19512+static inline void cvmx_pow_set_priority(uint64_t core_num,
19513+ const uint8_t priority[])
19514+{
19515+ /* POW priorities are supported on CN5xxx and later */
19516+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
19517+ union cvmx_pow_pp_grp_mskx grp_msk;
19518+
19519+ grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
19520+ grp_msk.s.qos0_pri = priority[0];
19521+ grp_msk.s.qos1_pri = priority[1];
19522+ grp_msk.s.qos2_pri = priority[2];
19523+ grp_msk.s.qos3_pri = priority[3];
19524+ grp_msk.s.qos4_pri = priority[4];
19525+ grp_msk.s.qos5_pri = priority[5];
19526+ grp_msk.s.qos6_pri = priority[6];
19527+ grp_msk.s.qos7_pri = priority[7];
19528+
19529+ /* Detect gaps between priorities and flag error */
19530+ {
19531+ int i;
19532+ uint32_t prio_mask = 0;
19533+
19534+ for (i = 0; i < 8; i++)
19535+ if (priority[i] != 0xF)
19536+ prio_mask |= 1 << priority[i];
19537+
19538+ if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) {
19539+ pr_err("POW static priorities should be "
19540+ "contiguous (0x%llx)\n",
19541+ (unsigned long long)prio_mask);
19542+ return;
19543+ }
19544+ }
19545+
19546+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
19547+ }
19548+}
19549+
19550+/**
19551+ * Performs a tag switch and then an immediate deschedule. This completes
19552+ * immediatly, so completion must not be waited for. This function does NOT
19553+ * update the wqe in DRAM to match arguments.
19554+ *
19555+ * This function does NOT wait for any prior tag switches to complete, so the
19556+ * calling code must do this.
19557+ *
19558+ * Note the following CAVEAT of the Octeon HW behavior when
19559+ * re-scheduling DE-SCHEDULEd items whose (next) state is
19560+ * ORDERED:
19561+ * - If there are no switches pending at the time that the
19562+ * HW executes the de-schedule, the HW will only re-schedule
19563+ * the head of the FIFO associated with the given tag. This
19564+ * means that in many respects, the HW treats this ORDERED
19565+ * tag as an ATOMIC tag. Note that in the SWTAG_DESCH
19566+ * case (to an ORDERED tag), the HW will do the switch
19567+ * before the deschedule whenever it is possible to do
19568+ * the switch immediately, so it may often look like
19569+ * this case.
19570+ * - If there is a pending switch to ORDERED at the time
19571+ * the HW executes the de-schedule, the HW will perform
19572+ * the switch at the time it re-schedules, and will be
19573+ * able to reschedule any/all of the entries with the
19574+ * same tag.
19575+ * Due to this behavior, the RECOMMENDATION to software is
19576+ * that they have a (next) state of ATOMIC when they
19577+ * DE-SCHEDULE. If an ORDERED tag is what was really desired,
19578+ * SW can choose to immediately switch to an ORDERED tag
19579+ * after the work (that has an ATOMIC tag) is re-scheduled.
19580+ * Note that since there are never any tag switches pending
19581+ * when the HW re-schedules, this switch can be IMMEDIATE upon
19582+ * the reception of the pointer during the re-schedule.
19583+ *
19584+ * @tag: New tag value
19585+ * @tag_type: New tag type
19586+ * @group: New group value
19587+ * @no_sched: Control whether this work queue entry will be rescheduled.
19588+ * - 1 : don't schedule this work
19589+ * - 0 : allow this work to be scheduled.
19590+ */
19591+static inline void cvmx_pow_tag_sw_desched_nocheck(
19592+ uint32_t tag,
19593+ enum cvmx_pow_tag_type tag_type,
19594+ uint64_t group,
19595+ uint64_t no_sched)
19596+{
19597+ cvmx_addr_t ptr;
19598+ cvmx_pow_tag_req_t tag_req;
19599+
19600+ if (CVMX_ENABLE_POW_CHECKS) {
19601+ cvmx_pow_tag_req_t current_tag;
19602+ __cvmx_pow_warn_if_pending_switch(__func__);
19603+ current_tag = cvmx_pow_get_current_tag();
19604+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19605+ pr_warning("%s called with NULL_NULL tag\n",
19606+ __func__);
19607+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19608+ pr_warning("%s called with NULL tag. Deschedule not "
19609+ "allowed from NULL state\n",
19610+ __func__);
19611+ if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC)
19612+ && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC))
19613+ pr_warning("%s called where neither the before or "
19614+ "after tag is ATOMIC\n",
19615+ __func__);
19616+ }
19617+
19618+ tag_req.u64 = 0;
19619+ tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH;
19620+ tag_req.s.tag = tag;
19621+ tag_req.s.type = tag_type;
19622+ tag_req.s.grp = group;
19623+ tag_req.s.no_sched = no_sched;
19624+
19625+ ptr.u64 = 0;
19626+ ptr.sio.mem_region = CVMX_IO_SEG;
19627+ ptr.sio.is_io = 1;
19628+ ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
19629+ /*
19630+ * since TAG3 is used, this store will clear the local pending
19631+ * switch bit.
19632+ */
19633+ cvmx_write_io(ptr.u64, tag_req.u64);
19634+}
19635+
19636+/**
19637+ * Performs a tag switch and then an immediate deschedule. This completes
19638+ * immediatly, so completion must not be waited for. This function does NOT
19639+ * update the wqe in DRAM to match arguments.
19640+ *
19641+ * This function waits for any prior tag switches to complete, so the
19642+ * calling code may call this function with a pending tag switch.
19643+ *
19644+ * Note the following CAVEAT of the Octeon HW behavior when
19645+ * re-scheduling DE-SCHEDULEd items whose (next) state is
19646+ * ORDERED:
19647+ * - If there are no switches pending at the time that the
19648+ * HW executes the de-schedule, the HW will only re-schedule
19649+ * the head of the FIFO associated with the given tag. This
19650+ * means that in many respects, the HW treats this ORDERED
19651+ * tag as an ATOMIC tag. Note that in the SWTAG_DESCH
19652+ * case (to an ORDERED tag), the HW will do the switch
19653+ * before the deschedule whenever it is possible to do
19654+ * the switch immediately, so it may often look like
19655+ * this case.
19656+ * - If there is a pending switch to ORDERED at the time
19657+ * the HW executes the de-schedule, the HW will perform
19658+ * the switch at the time it re-schedules, and will be
19659+ * able to reschedule any/all of the entries with the
19660+ * same tag.
19661+ * Due to this behavior, the RECOMMENDATION to software is
19662+ * that they have a (next) state of ATOMIC when they
19663+ * DE-SCHEDULE. If an ORDERED tag is what was really desired,
19664+ * SW can choose to immediately switch to an ORDERED tag
19665+ * after the work (that has an ATOMIC tag) is re-scheduled.
19666+ * Note that since there are never any tag switches pending
19667+ * when the HW re-schedules, this switch can be IMMEDIATE upon
19668+ * the reception of the pointer during the re-schedule.
19669+ *
19670+ * @tag: New tag value
19671+ * @tag_type: New tag type
19672+ * @group: New group value
19673+ * @no_sched: Control whether this work queue entry will be rescheduled.
19674+ * - 1 : don't schedule this work
19675+ * - 0 : allow this work to be scheduled.
19676+ */
19677+static inline void cvmx_pow_tag_sw_desched(uint32_t tag,
19678+ enum cvmx_pow_tag_type tag_type,
19679+ uint64_t group, uint64_t no_sched)
19680+{
19681+ if (CVMX_ENABLE_POW_CHECKS)
19682+ __cvmx_pow_warn_if_pending_switch(__func__);
19683+
19684+ /* Need to make sure any writes to the work queue entry are complete */
19685+ CVMX_SYNCWS;
19686+ /*
19687+ * Ensure that there is not a pending tag switch, as a tag
19688+ * switch cannot be started if a previous switch is still
19689+ * pending.
19690+ */
19691+ cvmx_pow_tag_sw_wait();
19692+ cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched);
19693+}
19694+
19695+/**
19696+ * Descchedules the current work queue entry.
19697+ *
19698+ * @no_sched: no schedule flag value to be set on the work queue
19699+ * entry. If this is set the entry will not be
19700+ * rescheduled.
19701+ */
19702+static inline void cvmx_pow_desched(uint64_t no_sched)
19703+{
19704+ cvmx_addr_t ptr;
19705+ cvmx_pow_tag_req_t tag_req;
19706+
19707+ if (CVMX_ENABLE_POW_CHECKS) {
19708+ cvmx_pow_tag_req_t current_tag;
19709+ __cvmx_pow_warn_if_pending_switch(__func__);
19710+ current_tag = cvmx_pow_get_current_tag();
19711+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19712+ pr_warning("%s called with NULL_NULL tag\n",
19713+ __func__);
19714+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19715+ pr_warning("%s called with NULL tag. Deschedule not "
19716+ "expected from NULL state\n",
19717+ __func__);
19718+ }
19719+
19720+ /* Need to make sure any writes to the work queue entry are complete */
19721+ CVMX_SYNCWS;
19722+
19723+ tag_req.u64 = 0;
19724+ tag_req.s.op = CVMX_POW_TAG_OP_DESCH;
19725+ tag_req.s.no_sched = no_sched;
19726+
19727+ ptr.u64 = 0;
19728+ ptr.sio.mem_region = CVMX_IO_SEG;
19729+ ptr.sio.is_io = 1;
19730+ ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
19731+ /*
19732+ * since TAG3 is used, this store will clear the local pending
19733+ * switch bit.
19734+ */
19735+ cvmx_write_io(ptr.u64, tag_req.u64);
19736+}
19737+
19738+/****************************************************
19739+* Define usage of bits within the 32 bit tag values.
19740+*****************************************************/
19741+
19742+/*
19743+ * Number of bits of the tag used by software. The SW bits are always
19744+ * a contiguous block of the high starting at bit 31. The hardware
19745+ * bits are always the low bits. By default, the top 8 bits of the
19746+ * tag are reserved for software, and the low 24 are set by the IPD
19747+ * unit.
19748+ */
19749+#define CVMX_TAG_SW_BITS (8)
19750+#define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS)
19751+
19752+/* Below is the list of values for the top 8 bits of the tag. */
19753+/*
19754+ * Tag values with top byte of this value are reserved for internal
19755+ * executive uses.
19756+ */
19757+#define CVMX_TAG_SW_BITS_INTERNAL 0x1
19758+/* The executive divides the remaining 24 bits as follows:
19759+ * - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup
19760+ *
19761+ * - the lower 16 bits (bits 15 - 0 of the tag) define are the value
19762+ * with the subgroup
19763+ *
19764+ * Note that this section describes the format of tags generated by
19765+ * software - refer to the hardware documentation for a description of
19766+ * the tags values generated by the packet input hardware. Subgroups
19767+ * are defined here.
19768+ */
19769+/* Mask for the value portion of the tag */
19770+#define CVMX_TAG_SUBGROUP_MASK 0xFFFF
19771+#define CVMX_TAG_SUBGROUP_SHIFT 16
19772+#define CVMX_TAG_SUBGROUP_PKO 0x1
19773+
19774+/* End of executive tag subgroup definitions */
19775+
19776+/*
19777+ * The remaining values software bit values 0x2 - 0xff are available
19778+ * for application use.
19779+ */
19780+
19781+/**
19782+ * This function creates a 32 bit tag value from the two values provided.
19783+ *
19784+ * @sw_bits: The upper bits (number depends on configuration) are set
19785+ * to this value. The remainder of bits are set by the
19786+ * hw_bits parameter.
19787+ *
19788+ * @hw_bits: The lower bits (number depends on configuration) are set
19789+ * to this value. The remainder of bits are set by the
19790+ * sw_bits parameter.
19791+ *
19792+ * Returns 32 bit value of the combined hw and sw bits.
19793+ */
19794+static inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits)
19795+{
19796+ return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) <<
19797+ CVMX_TAG_SW_SHIFT) |
19798+ (hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS));
19799+}
19800+
19801+/**
19802+ * Extracts the bits allocated for software use from the tag
19803+ *
19804+ * @tag: 32 bit tag value
19805+ *
19806+ * Returns N bit software tag value, where N is configurable with the
19807+ * CVMX_TAG_SW_BITS define
19808+ */
19809+static inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag)
19810+{
19811+ return (tag >> (32 - CVMX_TAG_SW_BITS)) &
19812+ cvmx_build_mask(CVMX_TAG_SW_BITS);
19813+}
19814+
19815+/**
19816+ *
19817+ * Extracts the bits allocated for hardware use from the tag
19818+ *
19819+ * @tag: 32 bit tag value
19820+ *
19821+ * Returns (32 - N) bit software tag value, where N is configurable
19822+ * with the CVMX_TAG_SW_BITS define
19823+ */
19824+static inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag)
19825+{
19826+ return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS);
19827+}
19828+
19829+/**
19830+ * Store the current POW internal state into the supplied
19831+ * buffer. It is recommended that you pass a buffer of at least
19832+ * 128KB. The format of the capture may change based on SDK
19833+ * version and Octeon chip.
19834+ *
19835+ * @buffer: Buffer to store capture into
19836+ * @buffer_size:
19837+ * The size of the supplied buffer
19838+ *
19839+ * Returns Zero on sucess, negative on failure
19840+ */
19841+extern int cvmx_pow_capture(void *buffer, int buffer_size);
19842+
19843+/**
19844+ * Dump a POW capture to the console in a human readable format.
19845+ *
19846+ * @buffer: POW capture from cvmx_pow_capture()
19847+ * @buffer_size:
19848+ * Size of the buffer
19849+ */
19850+extern void cvmx_pow_display(void *buffer, int buffer_size);
19851+
19852+/**
19853+ * Return the number of POW entries supported by this chip
19854+ *
19855+ * Returns Number of POW entries
19856+ */
19857+extern int cvmx_pow_get_num_entries(void);
19858+
19859+#endif /* __CVMX_POW_H__ */
19860--- /dev/null
19861+++ b/drivers/staging/octeon/cvmx-scratch.h
19862@@ -0,0 +1,139 @@
19863+/***********************license start***************
19864+ * Author: Cavium Networks
19865+ *
19866+ * Contact: support@caviumnetworks.com
19867+ * This file is part of the OCTEON SDK
19868+ *
19869+ * Copyright (c) 2003-2008 Cavium Networks
19870+ *
19871+ * This file is free software; you can redistribute it and/or modify
19872+ * it under the terms of the GNU General Public License, Version 2, as
19873+ * published by the Free Software Foundation.
19874+ *
19875+ * This file is distributed in the hope that it will be useful, but
19876+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
19877+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
19878+ * NONINFRINGEMENT. See the GNU General Public License for more
19879+ * details.
19880+ *
19881+ * You should have received a copy of the GNU General Public License
19882+ * along with this file; if not, write to the Free Software
19883+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19884+ * or visit http://www.gnu.org/licenses/.
19885+ *
19886+ * This file may also be available under a different license from Cavium.
19887+ * Contact Cavium Networks for more information
19888+ ***********************license end**************************************/
19889+
19890+/**
19891+ *
19892+ * This file provides support for the processor local scratch memory.
19893+ * Scratch memory is byte addressable - all addresses are byte addresses.
19894+ *
19895+ */
19896+
19897+#ifndef __CVMX_SCRATCH_H__
19898+#define __CVMX_SCRATCH_H__
19899+
19900+/*
19901+ * Note: This define must be a long, not a long long in order to
19902+ * compile without warnings for both 32bit and 64bit.
19903+ */
19904+#define CVMX_SCRATCH_BASE (-32768l) /* 0xffffffffffff8000 */
19905+
19906+/**
19907+ * Reads an 8 bit value from the processor local scratchpad memory.
19908+ *
19909+ * @address: byte address to read from
19910+ *
19911+ * Returns value read
19912+ */
19913+static inline uint8_t cvmx_scratch_read8(uint64_t address)
19914+{
19915+ return *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address);
19916+}
19917+
19918+/**
19919+ * Reads a 16 bit value from the processor local scratchpad memory.
19920+ *
19921+ * @address: byte address to read from
19922+ *
19923+ * Returns value read
19924+ */
19925+static inline uint16_t cvmx_scratch_read16(uint64_t address)
19926+{
19927+ return *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address);
19928+}
19929+
19930+/**
19931+ * Reads a 32 bit value from the processor local scratchpad memory.
19932+ *
19933+ * @address: byte address to read from
19934+ *
19935+ * Returns value read
19936+ */
19937+static inline uint32_t cvmx_scratch_read32(uint64_t address)
19938+{
19939+ return *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address);
19940+}
19941+
19942+/**
19943+ * Reads a 64 bit value from the processor local scratchpad memory.
19944+ *
19945+ * @address: byte address to read from
19946+ *
19947+ * Returns value read
19948+ */
19949+static inline uint64_t cvmx_scratch_read64(uint64_t address)
19950+{
19951+ return *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address);
19952+}
19953+
19954+/**
19955+ * Writes an 8 bit value to the processor local scratchpad memory.
19956+ *
19957+ * @address: byte address to write to
19958+ * @value: value to write
19959+ */
19960+static inline void cvmx_scratch_write8(uint64_t address, uint64_t value)
19961+{
19962+ *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address) =
19963+ (uint8_t) value;
19964+}
19965+
19966+/**
19967+ * Writes a 32 bit value to the processor local scratchpad memory.
19968+ *
19969+ * @address: byte address to write to
19970+ * @value: value to write
19971+ */
19972+static inline void cvmx_scratch_write16(uint64_t address, uint64_t value)
19973+{
19974+ *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address) =
19975+ (uint16_t) value;
19976+}
19977+
19978+/**
19979+ * Writes a 16 bit value to the processor local scratchpad memory.
19980+ *
19981+ * @address: byte address to write to
19982+ * @value: value to write
19983+ */
19984+static inline void cvmx_scratch_write32(uint64_t address, uint64_t value)
19985+{
19986+ *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address) =
19987+ (uint32_t) value;
19988+}
19989+
19990+/**
19991+ * Writes a 64 bit value to the processor local scratchpad memory.
19992+ *
19993+ * @address: byte address to write to
19994+ * @value: value to write
19995+ */
19996+static inline void cvmx_scratch_write64(uint64_t address, uint64_t value)
19997+{
19998+ *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address) = value;
19999+}
20000+
20001+#endif /* __CVMX_SCRATCH_H__ */
20002--- /dev/null
20003+++ b/drivers/staging/octeon/cvmx-smix-defs.h
20004@@ -0,0 +1,178 @@
20005+/***********************license start***************
20006+ * Author: Cavium Networks
20007+ *
20008+ * Contact: support@caviumnetworks.com
20009+ * This file is part of the OCTEON SDK
20010+ *
20011+ * Copyright (c) 2003-2008 Cavium Networks
20012+ *
20013+ * This file is free software; you can redistribute it and/or modify
20014+ * it under the terms of the GNU General Public License, Version 2, as
20015+ * published by the Free Software Foundation.
20016+ *
20017+ * This file is distributed in the hope that it will be useful, but
20018+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20019+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20020+ * NONINFRINGEMENT. See the GNU General Public License for more
20021+ * details.
20022+ *
20023+ * You should have received a copy of the GNU General Public License
20024+ * along with this file; if not, write to the Free Software
20025+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20026+ * or visit http://www.gnu.org/licenses/.
20027+ *
20028+ * This file may also be available under a different license from Cavium.
20029+ * Contact Cavium Networks for more information
20030+ ***********************license end**************************************/
20031+
20032+#ifndef __CVMX_SMIX_DEFS_H__
20033+#define __CVMX_SMIX_DEFS_H__
20034+
20035+#define CVMX_SMIX_CLK(offset) \
20036+ CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
20037+#define CVMX_SMIX_CMD(offset) \
20038+ CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
20039+#define CVMX_SMIX_EN(offset) \
20040+ CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
20041+#define CVMX_SMIX_RD_DAT(offset) \
20042+ CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
20043+#define CVMX_SMIX_WR_DAT(offset) \
20044+ CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
20045+
20046+union cvmx_smix_clk {
20047+ uint64_t u64;
20048+ struct cvmx_smix_clk_s {
20049+ uint64_t reserved_25_63:39;
20050+ uint64_t mode:1;
20051+ uint64_t reserved_21_23:3;
20052+ uint64_t sample_hi:5;
20053+ uint64_t sample_mode:1;
20054+ uint64_t reserved_14_14:1;
20055+ uint64_t clk_idle:1;
20056+ uint64_t preamble:1;
20057+ uint64_t sample:4;
20058+ uint64_t phase:8;
20059+ } s;
20060+ struct cvmx_smix_clk_cn30xx {
20061+ uint64_t reserved_21_63:43;
20062+ uint64_t sample_hi:5;
20063+ uint64_t reserved_14_15:2;
20064+ uint64_t clk_idle:1;
20065+ uint64_t preamble:1;
20066+ uint64_t sample:4;
20067+ uint64_t phase:8;
20068+ } cn30xx;
20069+ struct cvmx_smix_clk_cn30xx cn31xx;
20070+ struct cvmx_smix_clk_cn30xx cn38xx;
20071+ struct cvmx_smix_clk_cn30xx cn38xxp2;
20072+ struct cvmx_smix_clk_cn50xx {
20073+ uint64_t reserved_25_63:39;
20074+ uint64_t mode:1;
20075+ uint64_t reserved_21_23:3;
20076+ uint64_t sample_hi:5;
20077+ uint64_t reserved_14_15:2;
20078+ uint64_t clk_idle:1;
20079+ uint64_t preamble:1;
20080+ uint64_t sample:4;
20081+ uint64_t phase:8;
20082+ } cn50xx;
20083+ struct cvmx_smix_clk_s cn52xx;
20084+ struct cvmx_smix_clk_cn50xx cn52xxp1;
20085+ struct cvmx_smix_clk_s cn56xx;
20086+ struct cvmx_smix_clk_cn50xx cn56xxp1;
20087+ struct cvmx_smix_clk_cn30xx cn58xx;
20088+ struct cvmx_smix_clk_cn30xx cn58xxp1;
20089+};
20090+
20091+union cvmx_smix_cmd {
20092+ uint64_t u64;
20093+ struct cvmx_smix_cmd_s {
20094+ uint64_t reserved_18_63:46;
20095+ uint64_t phy_op:2;
20096+ uint64_t reserved_13_15:3;
20097+ uint64_t phy_adr:5;
20098+ uint64_t reserved_5_7:3;
20099+ uint64_t reg_adr:5;
20100+ } s;
20101+ struct cvmx_smix_cmd_cn30xx {
20102+ uint64_t reserved_17_63:47;
20103+ uint64_t phy_op:1;
20104+ uint64_t reserved_13_15:3;
20105+ uint64_t phy_adr:5;
20106+ uint64_t reserved_5_7:3;
20107+ uint64_t reg_adr:5;
20108+ } cn30xx;
20109+ struct cvmx_smix_cmd_cn30xx cn31xx;
20110+ struct cvmx_smix_cmd_cn30xx cn38xx;
20111+ struct cvmx_smix_cmd_cn30xx cn38xxp2;
20112+ struct cvmx_smix_cmd_s cn50xx;
20113+ struct cvmx_smix_cmd_s cn52xx;
20114+ struct cvmx_smix_cmd_s cn52xxp1;
20115+ struct cvmx_smix_cmd_s cn56xx;
20116+ struct cvmx_smix_cmd_s cn56xxp1;
20117+ struct cvmx_smix_cmd_cn30xx cn58xx;
20118+ struct cvmx_smix_cmd_cn30xx cn58xxp1;
20119+};
20120+
20121+union cvmx_smix_en {
20122+ uint64_t u64;
20123+ struct cvmx_smix_en_s {
20124+ uint64_t reserved_1_63:63;
20125+ uint64_t en:1;
20126+ } s;
20127+ struct cvmx_smix_en_s cn30xx;
20128+ struct cvmx_smix_en_s cn31xx;
20129+ struct cvmx_smix_en_s cn38xx;
20130+ struct cvmx_smix_en_s cn38xxp2;
20131+ struct cvmx_smix_en_s cn50xx;
20132+ struct cvmx_smix_en_s cn52xx;
20133+ struct cvmx_smix_en_s cn52xxp1;
20134+ struct cvmx_smix_en_s cn56xx;
20135+ struct cvmx_smix_en_s cn56xxp1;
20136+ struct cvmx_smix_en_s cn58xx;
20137+ struct cvmx_smix_en_s cn58xxp1;
20138+};
20139+
20140+union cvmx_smix_rd_dat {
20141+ uint64_t u64;
20142+ struct cvmx_smix_rd_dat_s {
20143+ uint64_t reserved_18_63:46;
20144+ uint64_t pending:1;
20145+ uint64_t val:1;
20146+ uint64_t dat:16;
20147+ } s;
20148+ struct cvmx_smix_rd_dat_s cn30xx;
20149+ struct cvmx_smix_rd_dat_s cn31xx;
20150+ struct cvmx_smix_rd_dat_s cn38xx;
20151+ struct cvmx_smix_rd_dat_s cn38xxp2;
20152+ struct cvmx_smix_rd_dat_s cn50xx;
20153+ struct cvmx_smix_rd_dat_s cn52xx;
20154+ struct cvmx_smix_rd_dat_s cn52xxp1;
20155+ struct cvmx_smix_rd_dat_s cn56xx;
20156+ struct cvmx_smix_rd_dat_s cn56xxp1;
20157+ struct cvmx_smix_rd_dat_s cn58xx;
20158+ struct cvmx_smix_rd_dat_s cn58xxp1;
20159+};
20160+
20161+union cvmx_smix_wr_dat {
20162+ uint64_t u64;
20163+ struct cvmx_smix_wr_dat_s {
20164+ uint64_t reserved_18_63:46;
20165+ uint64_t pending:1;
20166+ uint64_t val:1;
20167+ uint64_t dat:16;
20168+ } s;
20169+ struct cvmx_smix_wr_dat_s cn30xx;
20170+ struct cvmx_smix_wr_dat_s cn31xx;
20171+ struct cvmx_smix_wr_dat_s cn38xx;
20172+ struct cvmx_smix_wr_dat_s cn38xxp2;
20173+ struct cvmx_smix_wr_dat_s cn50xx;
20174+ struct cvmx_smix_wr_dat_s cn52xx;
20175+ struct cvmx_smix_wr_dat_s cn52xxp1;
20176+ struct cvmx_smix_wr_dat_s cn56xx;
20177+ struct cvmx_smix_wr_dat_s cn56xxp1;
20178+ struct cvmx_smix_wr_dat_s cn58xx;
20179+ struct cvmx_smix_wr_dat_s cn58xxp1;
20180+};
20181+
20182+#endif
20183--- /dev/null
20184+++ b/drivers/staging/octeon/cvmx-spi.c
20185@@ -0,0 +1,667 @@
20186+/***********************license start***************
20187+ * Author: Cavium Networks
20188+ *
20189+ * Contact: support@caviumnetworks.com
20190+ * This file is part of the OCTEON SDK
20191+ *
20192+ * Copyright (c) 2003-2008 Cavium Networks
20193+ *
20194+ * This file is free software; you can redistribute it and/or modify
20195+ * it under the terms of the GNU General Public License, Version 2, as
20196+ * published by the Free Software Foundation.
20197+ *
20198+ * This file is distributed in the hope that it will be useful, but
20199+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20200+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20201+ * NONINFRINGEMENT. See the GNU General Public License for more
20202+ * details.
20203+ *
20204+ * You should have received a copy of the GNU General Public License
20205+ * along with this file; if not, write to the Free Software
20206+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20207+ * or visit http://www.gnu.org/licenses/.
20208+ *
20209+ * This file may also be available under a different license from Cavium.
20210+ * Contact Cavium Networks for more information
20211+ ***********************license end**************************************/
20212+
20213+/*
20214+ *
20215+ * Support library for the SPI
20216+ */
20217+#include <asm/octeon/octeon.h>
20218+
20219+#include "cvmx-config.h"
20220+
20221+#include "cvmx-pko.h"
20222+#include "cvmx-spi.h"
20223+
20224+#include "cvmx-spxx-defs.h"
20225+#include "cvmx-stxx-defs.h"
20226+#include "cvmx-srxx-defs.h"
20227+
20228+#define INVOKE_CB(function_p, args...) \
20229+ do { \
20230+ if (function_p) { \
20231+ res = function_p(args); \
20232+ if (res) \
20233+ return res; \
20234+ } \
20235+ } while (0)
20236+
20237+#if CVMX_ENABLE_DEBUG_PRINTS
20238+static const char *modes[] =
20239+ { "UNKNOWN", "TX Halfplex", "Rx Halfplex", "Duplex" };
20240+#endif
20241+
20242+/* Default callbacks, can be overridden
20243+ * using cvmx_spi_get_callbacks/cvmx_spi_set_callbacks
20244+ */
20245+static cvmx_spi_callbacks_t cvmx_spi_callbacks = {
20246+ .reset_cb = cvmx_spi_reset_cb,
20247+ .calendar_setup_cb = cvmx_spi_calendar_setup_cb,
20248+ .clock_detect_cb = cvmx_spi_clock_detect_cb,
20249+ .training_cb = cvmx_spi_training_cb,
20250+ .calendar_sync_cb = cvmx_spi_calendar_sync_cb,
20251+ .interface_up_cb = cvmx_spi_interface_up_cb
20252+};
20253+
20254+/**
20255+ * Get current SPI4 initialization callbacks
20256+ *
20257+ * @callbacks: Pointer to the callbacks structure.to fill
20258+ *
20259+ * Returns Pointer to cvmx_spi_callbacks_t structure.
20260+ */
20261+void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks)
20262+{
20263+ memcpy(callbacks, &cvmx_spi_callbacks, sizeof(cvmx_spi_callbacks));
20264+}
20265+
20266+/**
20267+ * Set new SPI4 initialization callbacks
20268+ *
20269+ * @new_callbacks: Pointer to an updated callbacks structure.
20270+ */
20271+void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks)
20272+{
20273+ memcpy(&cvmx_spi_callbacks, new_callbacks, sizeof(cvmx_spi_callbacks));
20274+}
20275+
20276+/**
20277+ * Initialize and start the SPI interface.
20278+ *
20279+ * @interface: The identifier of the packet interface to configure and
20280+ * use as a SPI interface.
20281+ * @mode: The operating mode for the SPI interface. The interface
20282+ * can operate as a full duplex (both Tx and Rx data paths
20283+ * active) or as a halfplex (either the Tx data path is
20284+ * active or the Rx data path is active, but not both).
20285+ * @timeout: Timeout to wait for clock synchronization in seconds
20286+ * @num_ports: Number of SPI ports to configure
20287+ *
20288+ * Returns Zero on success, negative of failure.
20289+ */
20290+int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout,
20291+ int num_ports)
20292+{
20293+ int res = -1;
20294+
20295+ if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
20296+ return res;
20297+
20298+ /* Callback to perform SPI4 reset */
20299+ INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
20300+
20301+ /* Callback to perform calendar setup */
20302+ INVOKE_CB(cvmx_spi_callbacks.calendar_setup_cb, interface, mode,
20303+ num_ports);
20304+
20305+ /* Callback to perform clock detection */
20306+ INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
20307+
20308+ /* Callback to perform SPI4 link training */
20309+ INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
20310+
20311+ /* Callback to perform calendar sync */
20312+ INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
20313+ timeout);
20314+
20315+ /* Callback to handle interface coming up */
20316+ INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
20317+
20318+ return res;
20319+}
20320+
20321+/**
20322+ * This routine restarts the SPI interface after it has lost synchronization
20323+ * with its correspondent system.
20324+ *
20325+ * @interface: The identifier of the packet interface to configure and
20326+ * use as a SPI interface.
20327+ * @mode: The operating mode for the SPI interface. The interface
20328+ * can operate as a full duplex (both Tx and Rx data paths
20329+ * active) or as a halfplex (either the Tx data path is
20330+ * active or the Rx data path is active, but not both).
20331+ * @timeout: Timeout to wait for clock synchronization in seconds
20332+ *
20333+ * Returns Zero on success, negative of failure.
20334+ */
20335+int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout)
20336+{
20337+ int res = -1;
20338+
20339+ if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
20340+ return res;
20341+
20342+ cvmx_dprintf("SPI%d: Restart %s\n", interface, modes[mode]);
20343+
20344+ /* Callback to perform SPI4 reset */
20345+ INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
20346+
20347+ /* NOTE: Calendar setup is not performed during restart */
20348+ /* Refer to cvmx_spi_start_interface() for the full sequence */
20349+
20350+ /* Callback to perform clock detection */
20351+ INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
20352+
20353+ /* Callback to perform SPI4 link training */
20354+ INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
20355+
20356+ /* Callback to perform calendar sync */
20357+ INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
20358+ timeout);
20359+
20360+ /* Callback to handle interface coming up */
20361+ INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
20362+
20363+ return res;
20364+}
20365+
20366+/**
20367+ * Callback to perform SPI4 reset
20368+ *
20369+ * @interface: The identifier of the packet interface to configure and
20370+ * use as a SPI interface.
20371+ * @mode: The operating mode for the SPI interface. The interface
20372+ * can operate as a full duplex (both Tx and Rx data paths
20373+ * active) or as a halfplex (either the Tx data path is
20374+ * active or the Rx data path is active, but not both).
20375+ *
20376+ * Returns Zero on success, non-zero error code on failure (will cause
20377+ * SPI initialization to abort)
20378+ */
20379+int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode)
20380+{
20381+ union cvmx_spxx_dbg_deskew_ctl spxx_dbg_deskew_ctl;
20382+ union cvmx_spxx_clk_ctl spxx_clk_ctl;
20383+ union cvmx_spxx_bist_stat spxx_bist_stat;
20384+ union cvmx_spxx_int_msk spxx_int_msk;
20385+ union cvmx_stxx_int_msk stxx_int_msk;
20386+ union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
20387+ int index;
20388+ uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20389+
20390+ /* Disable SPI error events while we run BIST */
20391+ spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
20392+ cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
20393+ stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
20394+ cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
20395+
20396+ /* Run BIST in the SPI interface */
20397+ cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), 0);
20398+ cvmx_write_csr(CVMX_STXX_COM_CTL(interface), 0);
20399+ spxx_clk_ctl.u64 = 0;
20400+ spxx_clk_ctl.s.runbist = 1;
20401+ cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20402+ cvmx_wait(10 * MS);
20403+ spxx_bist_stat.u64 = cvmx_read_csr(CVMX_SPXX_BIST_STAT(interface));
20404+ if (spxx_bist_stat.s.stat0)
20405+ cvmx_dprintf
20406+ ("ERROR SPI%d: BIST failed on receive datapath FIFO\n",
20407+ interface);
20408+ if (spxx_bist_stat.s.stat1)
20409+ cvmx_dprintf("ERROR SPI%d: BIST failed on RX calendar table\n",
20410+ interface);
20411+ if (spxx_bist_stat.s.stat2)
20412+ cvmx_dprintf("ERROR SPI%d: BIST failed on TX calendar table\n",
20413+ interface);
20414+
20415+ /* Clear the calendar table after BIST to fix parity errors */
20416+ for (index = 0; index < 32; index++) {
20417+ union cvmx_srxx_spi4_calx srxx_spi4_calx;
20418+ union cvmx_stxx_spi4_calx stxx_spi4_calx;
20419+
20420+ srxx_spi4_calx.u64 = 0;
20421+ srxx_spi4_calx.s.oddpar = 1;
20422+ cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface),
20423+ srxx_spi4_calx.u64);
20424+
20425+ stxx_spi4_calx.u64 = 0;
20426+ stxx_spi4_calx.s.oddpar = 1;
20427+ cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface),
20428+ stxx_spi4_calx.u64);
20429+ }
20430+
20431+ /* Re enable reporting of error interrupts */
20432+ cvmx_write_csr(CVMX_SPXX_INT_REG(interface),
20433+ cvmx_read_csr(CVMX_SPXX_INT_REG(interface)));
20434+ cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
20435+ cvmx_write_csr(CVMX_STXX_INT_REG(interface),
20436+ cvmx_read_csr(CVMX_STXX_INT_REG(interface)));
20437+ cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
20438+
20439+ /* Setup the CLKDLY right in the middle */
20440+ spxx_clk_ctl.u64 = 0;
20441+ spxx_clk_ctl.s.seetrn = 0;
20442+ spxx_clk_ctl.s.clkdly = 0x10;
20443+ spxx_clk_ctl.s.runbist = 0;
20444+ spxx_clk_ctl.s.statdrv = 0;
20445+ /* This should always be on the opposite edge as statdrv */
20446+ spxx_clk_ctl.s.statrcv = 1;
20447+ spxx_clk_ctl.s.sndtrn = 0;
20448+ spxx_clk_ctl.s.drptrn = 0;
20449+ spxx_clk_ctl.s.rcvtrn = 0;
20450+ spxx_clk_ctl.s.srxdlck = 0;
20451+ cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20452+ cvmx_wait(100 * MS);
20453+
20454+ /* Reset SRX0 DLL */
20455+ spxx_clk_ctl.s.srxdlck = 1;
20456+ cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20457+
20458+ /* Waiting for Inf0 Spi4 RX DLL to lock */
20459+ cvmx_wait(100 * MS);
20460+
20461+ /* Enable dynamic alignment */
20462+ spxx_trn4_ctl.s.trntest = 0;
20463+ spxx_trn4_ctl.s.jitter = 1;
20464+ spxx_trn4_ctl.s.clr_boot = 1;
20465+ spxx_trn4_ctl.s.set_boot = 0;
20466+ if (OCTEON_IS_MODEL(OCTEON_CN58XX))
20467+ spxx_trn4_ctl.s.maxdist = 3;
20468+ else
20469+ spxx_trn4_ctl.s.maxdist = 8;
20470+ spxx_trn4_ctl.s.macro_en = 1;
20471+ spxx_trn4_ctl.s.mux_en = 1;
20472+ cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64);
20473+
20474+ spxx_dbg_deskew_ctl.u64 = 0;
20475+ cvmx_write_csr(CVMX_SPXX_DBG_DESKEW_CTL(interface),
20476+ spxx_dbg_deskew_ctl.u64);
20477+
20478+ return 0;
20479+}
20480+
20481+/**
20482+ * Callback to setup calendar and miscellaneous settings before clock detection
20483+ *
20484+ * @interface: The identifier of the packet interface to configure and
20485+ * use as a SPI interface.
20486+ * @mode: The operating mode for the SPI interface. The interface
20487+ * can operate as a full duplex (both Tx and Rx data paths
20488+ * active) or as a halfplex (either the Tx data path is
20489+ * active or the Rx data path is active, but not both).
20490+ * @num_ports: Number of ports to configure on SPI
20491+ *
20492+ * Returns Zero on success, non-zero error code on failure (will cause
20493+ * SPI initialization to abort)
20494+ */
20495+int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
20496+ int num_ports)
20497+{
20498+ int port;
20499+ int index;
20500+ if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20501+ union cvmx_srxx_com_ctl srxx_com_ctl;
20502+ union cvmx_srxx_spi4_stat srxx_spi4_stat;
20503+
20504+ /* SRX0 number of Ports */
20505+ srxx_com_ctl.u64 = 0;
20506+ srxx_com_ctl.s.prts = num_ports - 1;
20507+ srxx_com_ctl.s.st_en = 0;
20508+ srxx_com_ctl.s.inf_en = 0;
20509+ cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20510+
20511+ /* SRX0 Calendar Table. This round robbins through all ports */
20512+ port = 0;
20513+ index = 0;
20514+ while (port < num_ports) {
20515+ union cvmx_srxx_spi4_calx srxx_spi4_calx;
20516+ srxx_spi4_calx.u64 = 0;
20517+ srxx_spi4_calx.s.prt0 = port++;
20518+ srxx_spi4_calx.s.prt1 = port++;
20519+ srxx_spi4_calx.s.prt2 = port++;
20520+ srxx_spi4_calx.s.prt3 = port++;
20521+ srxx_spi4_calx.s.oddpar =
20522+ ~(cvmx_dpop(srxx_spi4_calx.u64) & 1);
20523+ cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface),
20524+ srxx_spi4_calx.u64);
20525+ index++;
20526+ }
20527+ srxx_spi4_stat.u64 = 0;
20528+ srxx_spi4_stat.s.len = num_ports;
20529+ srxx_spi4_stat.s.m = 1;
20530+ cvmx_write_csr(CVMX_SRXX_SPI4_STAT(interface),
20531+ srxx_spi4_stat.u64);
20532+ }
20533+
20534+ if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20535+ union cvmx_stxx_arb_ctl stxx_arb_ctl;
20536+ union cvmx_gmxx_tx_spi_max gmxx_tx_spi_max;
20537+ union cvmx_gmxx_tx_spi_thresh gmxx_tx_spi_thresh;
20538+ union cvmx_gmxx_tx_spi_ctl gmxx_tx_spi_ctl;
20539+ union cvmx_stxx_spi4_stat stxx_spi4_stat;
20540+ union cvmx_stxx_spi4_dat stxx_spi4_dat;
20541+
20542+ /* STX0 Config */
20543+ stxx_arb_ctl.u64 = 0;
20544+ stxx_arb_ctl.s.igntpa = 0;
20545+ stxx_arb_ctl.s.mintrn = 0;
20546+ cvmx_write_csr(CVMX_STXX_ARB_CTL(interface), stxx_arb_ctl.u64);
20547+
20548+ gmxx_tx_spi_max.u64 = 0;
20549+ gmxx_tx_spi_max.s.max1 = 8;
20550+ gmxx_tx_spi_max.s.max2 = 4;
20551+ gmxx_tx_spi_max.s.slice = 0;
20552+ cvmx_write_csr(CVMX_GMXX_TX_SPI_MAX(interface),
20553+ gmxx_tx_spi_max.u64);
20554+
20555+ gmxx_tx_spi_thresh.u64 = 0;
20556+ gmxx_tx_spi_thresh.s.thresh = 4;
20557+ cvmx_write_csr(CVMX_GMXX_TX_SPI_THRESH(interface),
20558+ gmxx_tx_spi_thresh.u64);
20559+
20560+ gmxx_tx_spi_ctl.u64 = 0;
20561+ gmxx_tx_spi_ctl.s.tpa_clr = 0;
20562+ gmxx_tx_spi_ctl.s.cont_pkt = 0;
20563+ cvmx_write_csr(CVMX_GMXX_TX_SPI_CTL(interface),
20564+ gmxx_tx_spi_ctl.u64);
20565+
20566+ /* STX0 Training Control */
20567+ stxx_spi4_dat.u64 = 0;
20568+ /*Minimum needed by dynamic alignment */
20569+ stxx_spi4_dat.s.alpha = 32;
20570+ stxx_spi4_dat.s.max_t = 0xFFFF; /*Minimum interval is 0x20 */
20571+ cvmx_write_csr(CVMX_STXX_SPI4_DAT(interface),
20572+ stxx_spi4_dat.u64);
20573+
20574+ /* STX0 Calendar Table. This round robbins through all ports */
20575+ port = 0;
20576+ index = 0;
20577+ while (port < num_ports) {
20578+ union cvmx_stxx_spi4_calx stxx_spi4_calx;
20579+ stxx_spi4_calx.u64 = 0;
20580+ stxx_spi4_calx.s.prt0 = port++;
20581+ stxx_spi4_calx.s.prt1 = port++;
20582+ stxx_spi4_calx.s.prt2 = port++;
20583+ stxx_spi4_calx.s.prt3 = port++;
20584+ stxx_spi4_calx.s.oddpar =
20585+ ~(cvmx_dpop(stxx_spi4_calx.u64) & 1);
20586+ cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface),
20587+ stxx_spi4_calx.u64);
20588+ index++;
20589+ }
20590+ stxx_spi4_stat.u64 = 0;
20591+ stxx_spi4_stat.s.len = num_ports;
20592+ stxx_spi4_stat.s.m = 1;
20593+ cvmx_write_csr(CVMX_STXX_SPI4_STAT(interface),
20594+ stxx_spi4_stat.u64);
20595+ }
20596+
20597+ return 0;
20598+}
20599+
20600+/**
20601+ * Callback to perform clock detection
20602+ *
20603+ * @interface: The identifier of the packet interface to configure and
20604+ * use as a SPI interface.
20605+ * @mode: The operating mode for the SPI interface. The interface
20606+ * can operate as a full duplex (both Tx and Rx data paths
20607+ * active) or as a halfplex (either the Tx data path is
20608+ * active or the Rx data path is active, but not both).
20609+ * @timeout: Timeout to wait for clock synchronization in seconds
20610+ *
20611+ * Returns Zero on success, non-zero error code on failure (will cause
20612+ * SPI initialization to abort)
20613+ */
20614+int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20615+{
20616+ int clock_transitions;
20617+ union cvmx_spxx_clk_stat stat;
20618+ uint64_t timeout_time;
20619+ uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20620+
20621+ /*
20622+ * Regardless of operating mode, both Tx and Rx clocks must be
20623+ * present for the SPI interface to operate.
20624+ */
20625+ cvmx_dprintf("SPI%d: Waiting to see TsClk...\n", interface);
20626+ timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20627+ /*
20628+ * Require 100 clock transitions in order to avoid any noise
20629+ * in the beginning.
20630+ */
20631+ clock_transitions = 100;
20632+ do {
20633+ stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20634+ if (stat.s.s4clk0 && stat.s.s4clk1 && clock_transitions) {
20635+ /*
20636+ * We've seen a clock transition, so decrement
20637+ * the number we still need.
20638+ */
20639+ clock_transitions--;
20640+ cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20641+ stat.s.s4clk0 = 0;
20642+ stat.s.s4clk1 = 0;
20643+ }
20644+ if (cvmx_get_cycle() > timeout_time) {
20645+ cvmx_dprintf("SPI%d: Timeout\n", interface);
20646+ return -1;
20647+ }
20648+ } while (stat.s.s4clk0 == 0 || stat.s.s4clk1 == 0);
20649+
20650+ cvmx_dprintf("SPI%d: Waiting to see RsClk...\n", interface);
20651+ timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20652+ /*
20653+ * Require 100 clock transitions in order to avoid any noise in the
20654+ * beginning.
20655+ */
20656+ clock_transitions = 100;
20657+ do {
20658+ stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20659+ if (stat.s.d4clk0 && stat.s.d4clk1 && clock_transitions) {
20660+ /*
20661+ * We've seen a clock transition, so decrement
20662+ * the number we still need
20663+ */
20664+ clock_transitions--;
20665+ cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20666+ stat.s.d4clk0 = 0;
20667+ stat.s.d4clk1 = 0;
20668+ }
20669+ if (cvmx_get_cycle() > timeout_time) {
20670+ cvmx_dprintf("SPI%d: Timeout\n", interface);
20671+ return -1;
20672+ }
20673+ } while (stat.s.d4clk0 == 0 || stat.s.d4clk1 == 0);
20674+
20675+ return 0;
20676+}
20677+
20678+/**
20679+ * Callback to perform link training
20680+ *
20681+ * @interface: The identifier of the packet interface to configure and
20682+ * use as a SPI interface.
20683+ * @mode: The operating mode for the SPI interface. The interface
20684+ * can operate as a full duplex (both Tx and Rx data paths
20685+ * active) or as a halfplex (either the Tx data path is
20686+ * active or the Rx data path is active, but not both).
20687+ * @timeout: Timeout to wait for link to be trained (in seconds)
20688+ *
20689+ * Returns Zero on success, non-zero error code on failure (will cause
20690+ * SPI initialization to abort)
20691+ */
20692+int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20693+{
20694+ union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
20695+ union cvmx_spxx_clk_stat stat;
20696+ uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20697+ uint64_t timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20698+ int rx_training_needed;
20699+
20700+ /* SRX0 & STX0 Inf0 Links are configured - begin training */
20701+ union cvmx_spxx_clk_ctl spxx_clk_ctl;
20702+ spxx_clk_ctl.u64 = 0;
20703+ spxx_clk_ctl.s.seetrn = 0;
20704+ spxx_clk_ctl.s.clkdly = 0x10;
20705+ spxx_clk_ctl.s.runbist = 0;
20706+ spxx_clk_ctl.s.statdrv = 0;
20707+ /* This should always be on the opposite edge as statdrv */
20708+ spxx_clk_ctl.s.statrcv = 1;
20709+ spxx_clk_ctl.s.sndtrn = 1;
20710+ spxx_clk_ctl.s.drptrn = 1;
20711+ spxx_clk_ctl.s.rcvtrn = 1;
20712+ spxx_clk_ctl.s.srxdlck = 1;
20713+ cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20714+ cvmx_wait(1000 * MS);
20715+
20716+ /* SRX0 clear the boot bit */
20717+ spxx_trn4_ctl.u64 = cvmx_read_csr(CVMX_SPXX_TRN4_CTL(interface));
20718+ spxx_trn4_ctl.s.clr_boot = 1;
20719+ cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64);
20720+
20721+ /* Wait for the training sequence to complete */
20722+ cvmx_dprintf("SPI%d: Waiting for training\n", interface);
20723+ cvmx_wait(1000 * MS);
20724+ /* Wait a really long time here */
20725+ timeout_time = cvmx_get_cycle() + 1000ull * MS * 600;
20726+ /*
20727+ * The HRM says we must wait for 34 + 16 * MAXDIST training sequences.
20728+ * We'll be pessimistic and wait for a lot more.
20729+ */
20730+ rx_training_needed = 500;
20731+ do {
20732+ stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20733+ if (stat.s.srxtrn && rx_training_needed) {
20734+ rx_training_needed--;
20735+ cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20736+ stat.s.srxtrn = 0;
20737+ }
20738+ if (cvmx_get_cycle() > timeout_time) {
20739+ cvmx_dprintf("SPI%d: Timeout\n", interface);
20740+ return -1;
20741+ }
20742+ } while (stat.s.srxtrn == 0);
20743+
20744+ return 0;
20745+}
20746+
20747+/**
20748+ * Callback to perform calendar data synchronization
20749+ *
20750+ * @interface: The identifier of the packet interface to configure and
20751+ * use as a SPI interface.
20752+ * @mode: The operating mode for the SPI interface. The interface
20753+ * can operate as a full duplex (both Tx and Rx data paths
20754+ * active) or as a halfplex (either the Tx data path is
20755+ * active or the Rx data path is active, but not both).
20756+ * @timeout: Timeout to wait for calendar data in seconds
20757+ *
20758+ * Returns Zero on success, non-zero error code on failure (will cause
20759+ * SPI initialization to abort)
20760+ */
20761+int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20762+{
20763+ uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20764+ if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20765+ /* SRX0 interface should be good, send calendar data */
20766+ union cvmx_srxx_com_ctl srxx_com_ctl;
20767+ cvmx_dprintf
20768+ ("SPI%d: Rx is synchronized, start sending calendar data\n",
20769+ interface);
20770+ srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface));
20771+ srxx_com_ctl.s.inf_en = 1;
20772+ srxx_com_ctl.s.st_en = 1;
20773+ cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20774+ }
20775+
20776+ if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20777+ /* STX0 has achieved sync */
20778+ /* The corespondant board should be sending calendar data */
20779+ /* Enable the STX0 STAT receiver. */
20780+ union cvmx_spxx_clk_stat stat;
20781+ uint64_t timeout_time;
20782+ union cvmx_stxx_com_ctl stxx_com_ctl;
20783+ stxx_com_ctl.u64 = 0;
20784+ stxx_com_ctl.s.st_en = 1;
20785+ cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64);
20786+
20787+ /* Waiting for calendar sync on STX0 STAT */
20788+ cvmx_dprintf("SPI%d: Waiting to sync on STX[%d] STAT\n",
20789+ interface, interface);
20790+ timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20791+ /* SPX0_CLK_STAT - SPX0_CLK_STAT[STXCAL] should be 1 (bit10) */
20792+ do {
20793+ stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20794+ if (cvmx_get_cycle() > timeout_time) {
20795+ cvmx_dprintf("SPI%d: Timeout\n", interface);
20796+ return -1;
20797+ }
20798+ } while (stat.s.stxcal == 0);
20799+ }
20800+
20801+ return 0;
20802+}
20803+
20804+/**
20805+ * Callback to handle interface up
20806+ *
20807+ * @interface: The identifier of the packet interface to configure and
20808+ * use as a SPI interface.
20809+ * @mode: The operating mode for the SPI interface. The interface
20810+ * can operate as a full duplex (both Tx and Rx data paths
20811+ * active) or as a halfplex (either the Tx data path is
20812+ * active or the Rx data path is active, but not both).
20813+ *
20814+ * Returns Zero on success, non-zero error code on failure (will cause
20815+ * SPI initialization to abort)
20816+ */
20817+int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode)
20818+{
20819+ union cvmx_gmxx_rxx_frm_min gmxx_rxx_frm_min;
20820+ union cvmx_gmxx_rxx_frm_max gmxx_rxx_frm_max;
20821+ union cvmx_gmxx_rxx_jabber gmxx_rxx_jabber;
20822+
20823+ if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20824+ union cvmx_srxx_com_ctl srxx_com_ctl;
20825+ srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface));
20826+ srxx_com_ctl.s.inf_en = 1;
20827+ cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20828+ cvmx_dprintf("SPI%d: Rx is now up\n", interface);
20829+ }
20830+
20831+ if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20832+ union cvmx_stxx_com_ctl stxx_com_ctl;
20833+ stxx_com_ctl.u64 = cvmx_read_csr(CVMX_STXX_COM_CTL(interface));
20834+ stxx_com_ctl.s.inf_en = 1;
20835+ cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64);
20836+ cvmx_dprintf("SPI%d: Tx is now up\n", interface);
20837+ }
20838+
20839+ gmxx_rxx_frm_min.u64 = 0;
20840+ gmxx_rxx_frm_min.s.len = 64;
20841+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MIN(0, interface),
20842+ gmxx_rxx_frm_min.u64);
20843+ gmxx_rxx_frm_max.u64 = 0;
20844+ gmxx_rxx_frm_max.s.len = 64 * 1024 - 4;
20845+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(0, interface),
20846+ gmxx_rxx_frm_max.u64);
20847+ gmxx_rxx_jabber.u64 = 0;
20848+ gmxx_rxx_jabber.s.cnt = 64 * 1024 - 4;
20849+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER(0, interface), gmxx_rxx_jabber.u64);
20850+
20851+ return 0;
20852+}
20853--- /dev/null
20854+++ b/drivers/staging/octeon/cvmx-spi.h
20855@@ -0,0 +1,269 @@
20856+/***********************license start***************
20857+ * Author: Cavium Networks
20858+ *
20859+ * Contact: support@caviumnetworks.com
20860+ * This file is part of the OCTEON SDK
20861+ *
20862+ * Copyright (c) 2003-2008 Cavium Networks
20863+ *
20864+ * This file is free software; you can redistribute it and/or modify
20865+ * it under the terms of the GNU General Public License, Version 2, as
20866+ * published by the Free Software Foundation.
20867+ *
20868+ * This file is distributed in the hope that it will be useful, but
20869+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20870+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20871+ * NONINFRINGEMENT. See the GNU General Public License for more
20872+ * details.
20873+ *
20874+ * You should have received a copy of the GNU General Public License
20875+ * along with this file; if not, write to the Free Software
20876+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20877+ * or visit http://www.gnu.org/licenses/.
20878+ *
20879+ * This file may also be available under a different license from Cavium.
20880+ * Contact Cavium Networks for more information
20881+ ***********************license end**************************************/
20882+
20883+/*
20884+ *
20885+ * This file contains defines for the SPI interface
20886+ */
20887+#ifndef __CVMX_SPI_H__
20888+#define __CVMX_SPI_H__
20889+
20890+#include "cvmx-gmxx-defs.h"
20891+
20892+/* CSR typedefs have been moved to cvmx-csr-*.h */
20893+
20894+typedef enum {
20895+ CVMX_SPI_MODE_UNKNOWN = 0,
20896+ CVMX_SPI_MODE_TX_HALFPLEX = 1,
20897+ CVMX_SPI_MODE_RX_HALFPLEX = 2,
20898+ CVMX_SPI_MODE_DUPLEX = 3
20899+} cvmx_spi_mode_t;
20900+
20901+/** Callbacks structure to customize SPI4 initialization sequence */
20902+typedef struct {
20903+ /** Called to reset SPI4 DLL */
20904+ int (*reset_cb) (int interface, cvmx_spi_mode_t mode);
20905+
20906+ /** Called to setup calendar */
20907+ int (*calendar_setup_cb) (int interface, cvmx_spi_mode_t mode,
20908+ int num_ports);
20909+
20910+ /** Called for Tx and Rx clock detection */
20911+ int (*clock_detect_cb) (int interface, cvmx_spi_mode_t mode,
20912+ int timeout);
20913+
20914+ /** Called to perform link training */
20915+ int (*training_cb) (int interface, cvmx_spi_mode_t mode, int timeout);
20916+
20917+ /** Called for calendar data synchronization */
20918+ int (*calendar_sync_cb) (int interface, cvmx_spi_mode_t mode,
20919+ int timeout);
20920+
20921+ /** Called when interface is up */
20922+ int (*interface_up_cb) (int interface, cvmx_spi_mode_t mode);
20923+
20924+} cvmx_spi_callbacks_t;
20925+
20926+/**
20927+ * Return true if the supplied interface is configured for SPI
20928+ *
20929+ * @interface: Interface to check
20930+ * Returns True if interface is SPI
20931+ */
20932+static inline int cvmx_spi_is_spi_interface(int interface)
20933+{
20934+ uint64_t gmxState = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
20935+ return (gmxState & 0x2) && (gmxState & 0x1);
20936+}
20937+
20938+/**
20939+ * Initialize and start the SPI interface.
20940+ *
20941+ * @interface: The identifier of the packet interface to configure and
20942+ * use as a SPI interface.
20943+ * @mode: The operating mode for the SPI interface. The interface
20944+ * can operate as a full duplex (both Tx and Rx data paths
20945+ * active) or as a halfplex (either the Tx data path is
20946+ * active or the Rx data path is active, but not both).
20947+ * @timeout: Timeout to wait for clock synchronization in seconds
20948+ * @num_ports: Number of SPI ports to configure
20949+ *
20950+ * Returns Zero on success, negative of failure.
20951+ */
20952+extern int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode,
20953+ int timeout, int num_ports);
20954+
20955+/**
20956+ * This routine restarts the SPI interface after it has lost synchronization
20957+ * with its corespondant system.
20958+ *
20959+ * @interface: The identifier of the packet interface to configure and
20960+ * use as a SPI interface.
20961+ * @mode: The operating mode for the SPI interface. The interface
20962+ * can operate as a full duplex (both Tx and Rx data paths
20963+ * active) or as a halfplex (either the Tx data path is
20964+ * active or the Rx data path is active, but not both).
20965+ * @timeout: Timeout to wait for clock synchronization in seconds
20966+ * Returns Zero on success, negative of failure.
20967+ */
20968+extern int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode,
20969+ int timeout);
20970+
20971+/**
20972+ * Return non-zero if the SPI interface has a SPI4000 attached
20973+ *
20974+ * @interface: SPI interface the SPI4000 is connected to
20975+ *
20976+ * Returns
20977+ */
20978+static inline int cvmx_spi4000_is_present(int interface)
20979+{
20980+ return 0;
20981+}
20982+
20983+/**
20984+ * Initialize the SPI4000 for use
20985+ *
20986+ * @interface: SPI interface the SPI4000 is connected to
20987+ */
20988+static inline int cvmx_spi4000_initialize(int interface)
20989+{
20990+ return 0;
20991+}
20992+
20993+/**
20994+ * Poll all the SPI4000 port and check its speed
20995+ *
20996+ * @interface: Interface the SPI4000 is on
20997+ * @port: Port to poll (0-9)
20998+ * Returns Status of the port. 0=down. All other values the port is up.
20999+ */
21000+static inline union cvmx_gmxx_rxx_rx_inbnd cvmx_spi4000_check_speed(
21001+ int interface,
21002+ int port)
21003+{
21004+ union cvmx_gmxx_rxx_rx_inbnd r;
21005+ r.u64 = 0;
21006+ return r;
21007+}
21008+
21009+/**
21010+ * Get current SPI4 initialization callbacks
21011+ *
21012+ * @callbacks: Pointer to the callbacks structure.to fill
21013+ *
21014+ * Returns Pointer to cvmx_spi_callbacks_t structure.
21015+ */
21016+extern void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks);
21017+
21018+/**
21019+ * Set new SPI4 initialization callbacks
21020+ *
21021+ * @new_callbacks: Pointer to an updated callbacks structure.
21022+ */
21023+extern void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks);
21024+
21025+/**
21026+ * Callback to perform SPI4 reset
21027+ *
21028+ * @interface: The identifier of the packet interface to configure and
21029+ * use as a SPI interface.
21030+ * @mode: The operating mode for the SPI interface. The interface
21031+ * can operate as a full duplex (both Tx and Rx data paths
21032+ * active) or as a halfplex (either the Tx data path is
21033+ * active or the Rx data path is active, but not both).
21034+ *
21035+ * Returns Zero on success, non-zero error code on failure (will cause
21036+ * SPI initialization to abort)
21037+ */
21038+extern int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode);
21039+
21040+/**
21041+ * Callback to setup calendar and miscellaneous settings before clock
21042+ * detection
21043+ *
21044+ * @interface: The identifier of the packet interface to configure and
21045+ * use as a SPI interface.
21046+ * @mode: The operating mode for the SPI interface. The interface
21047+ * can operate as a full duplex (both Tx and Rx data paths
21048+ * active) or as a halfplex (either the Tx data path is
21049+ * active or the Rx data path is active, but not both).
21050+ * @num_ports: Number of ports to configure on SPI
21051+ *
21052+ * Returns Zero on success, non-zero error code on failure (will cause
21053+ * SPI initialization to abort)
21054+ */
21055+extern int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
21056+ int num_ports);
21057+
21058+/**
21059+ * Callback to perform clock detection
21060+ *
21061+ * @interface: The identifier of the packet interface to configure and
21062+ * use as a SPI interface.
21063+ * @mode: The operating mode for the SPI interface. The interface
21064+ * can operate as a full duplex (both Tx and Rx data paths
21065+ * active) or as a halfplex (either the Tx data path is
21066+ * active or the Rx data path is active, but not both).
21067+ * @timeout: Timeout to wait for clock synchronization in seconds
21068+ *
21069+ * Returns Zero on success, non-zero error code on failure (will cause
21070+ * SPI initialization to abort)
21071+ */
21072+extern int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode,
21073+ int timeout);
21074+
21075+/**
21076+ * Callback to perform link training
21077+ *
21078+ * @interface: The identifier of the packet interface to configure and
21079+ * use as a SPI interface.
21080+ * @mode: The operating mode for the SPI interface. The interface
21081+ * can operate as a full duplex (both Tx and Rx data paths
21082+ * active) or as a halfplex (either the Tx data path is
21083+ * active or the Rx data path is active, but not both).
21084+ * @timeout: Timeout to wait for link to be trained (in seconds)
21085+ *
21086+ * Returns Zero on success, non-zero error code on failure (will cause
21087+ * SPI initialization to abort)
21088+ */
21089+extern int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode,
21090+ int timeout);
21091+
21092+/**
21093+ * Callback to perform calendar data synchronization
21094+ *
21095+ * @interface: The identifier of the packet interface to configure and
21096+ * use as a SPI interface.
21097+ * @mode: The operating mode for the SPI interface. The interface
21098+ * can operate as a full duplex (both Tx and Rx data paths
21099+ * active) or as a halfplex (either the Tx data path is
21100+ * active or the Rx data path is active, but not both).
21101+ * @timeout: Timeout to wait for calendar data in seconds
21102+ *
21103+ * Returns Zero on success, non-zero error code on failure (will cause
21104+ * SPI initialization to abort)
21105+ */
21106+extern int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode,
21107+ int timeout);
21108+
21109+/**
21110+ * Callback to handle interface up
21111+ *
21112+ * @interface: The identifier of the packet interface to configure and
21113+ * use as a SPI interface.
21114+ * @mode: The operating mode for the SPI interface. The interface
21115+ * can operate as a full duplex (both Tx and Rx data paths
21116+ * active) or as a halfplex (either the Tx data path is
21117+ * active or the Rx data path is active, but not both).
21118+ *
21119+ * Returns Zero on success, non-zero error code on failure (will cause
21120+ * SPI initialization to abort)
21121+ */
21122+extern int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode);
21123+
21124+#endif /* __CVMX_SPI_H__ */
21125--- /dev/null
21126+++ b/drivers/staging/octeon/cvmx-spxx-defs.h
21127@@ -0,0 +1,347 @@
21128+/***********************license start***************
21129+ * Author: Cavium Networks
21130+ *
21131+ * Contact: support@caviumnetworks.com
21132+ * This file is part of the OCTEON SDK
21133+ *
21134+ * Copyright (c) 2003-2008 Cavium Networks
21135+ *
21136+ * This file is free software; you can redistribute it and/or modify
21137+ * it under the terms of the GNU General Public License, Version 2, as
21138+ * published by the Free Software Foundation.
21139+ *
21140+ * This file is distributed in the hope that it will be useful, but
21141+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21142+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21143+ * NONINFRINGEMENT. See the GNU General Public License for more
21144+ * details.
21145+ *
21146+ * You should have received a copy of the GNU General Public License
21147+ * along with this file; if not, write to the Free Software
21148+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21149+ * or visit http://www.gnu.org/licenses/.
21150+ *
21151+ * This file may also be available under a different license from Cavium.
21152+ * Contact Cavium Networks for more information
21153+ ***********************license end**************************************/
21154+
21155+#ifndef __CVMX_SPXX_DEFS_H__
21156+#define __CVMX_SPXX_DEFS_H__
21157+
21158+#define CVMX_SPXX_BCKPRS_CNT(block_id) \
21159+ CVMX_ADD_IO_SEG(0x0001180090000340ull + (((block_id) & 1) * 0x8000000ull))
21160+#define CVMX_SPXX_BIST_STAT(block_id) \
21161+ CVMX_ADD_IO_SEG(0x00011800900007F8ull + (((block_id) & 1) * 0x8000000ull))
21162+#define CVMX_SPXX_CLK_CTL(block_id) \
21163+ CVMX_ADD_IO_SEG(0x0001180090000348ull + (((block_id) & 1) * 0x8000000ull))
21164+#define CVMX_SPXX_CLK_STAT(block_id) \
21165+ CVMX_ADD_IO_SEG(0x0001180090000350ull + (((block_id) & 1) * 0x8000000ull))
21166+#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) \
21167+ CVMX_ADD_IO_SEG(0x0001180090000368ull + (((block_id) & 1) * 0x8000000ull))
21168+#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) \
21169+ CVMX_ADD_IO_SEG(0x0001180090000370ull + (((block_id) & 1) * 0x8000000ull))
21170+#define CVMX_SPXX_DRV_CTL(block_id) \
21171+ CVMX_ADD_IO_SEG(0x0001180090000358ull + (((block_id) & 1) * 0x8000000ull))
21172+#define CVMX_SPXX_ERR_CTL(block_id) \
21173+ CVMX_ADD_IO_SEG(0x0001180090000320ull + (((block_id) & 1) * 0x8000000ull))
21174+#define CVMX_SPXX_INT_DAT(block_id) \
21175+ CVMX_ADD_IO_SEG(0x0001180090000318ull + (((block_id) & 1) * 0x8000000ull))
21176+#define CVMX_SPXX_INT_MSK(block_id) \
21177+ CVMX_ADD_IO_SEG(0x0001180090000308ull + (((block_id) & 1) * 0x8000000ull))
21178+#define CVMX_SPXX_INT_REG(block_id) \
21179+ CVMX_ADD_IO_SEG(0x0001180090000300ull + (((block_id) & 1) * 0x8000000ull))
21180+#define CVMX_SPXX_INT_SYNC(block_id) \
21181+ CVMX_ADD_IO_SEG(0x0001180090000310ull + (((block_id) & 1) * 0x8000000ull))
21182+#define CVMX_SPXX_TPA_ACC(block_id) \
21183+ CVMX_ADD_IO_SEG(0x0001180090000338ull + (((block_id) & 1) * 0x8000000ull))
21184+#define CVMX_SPXX_TPA_MAX(block_id) \
21185+ CVMX_ADD_IO_SEG(0x0001180090000330ull + (((block_id) & 1) * 0x8000000ull))
21186+#define CVMX_SPXX_TPA_SEL(block_id) \
21187+ CVMX_ADD_IO_SEG(0x0001180090000328ull + (((block_id) & 1) * 0x8000000ull))
21188+#define CVMX_SPXX_TRN4_CTL(block_id) \
21189+ CVMX_ADD_IO_SEG(0x0001180090000360ull + (((block_id) & 1) * 0x8000000ull))
21190+
21191+union cvmx_spxx_bckprs_cnt {
21192+ uint64_t u64;
21193+ struct cvmx_spxx_bckprs_cnt_s {
21194+ uint64_t reserved_32_63:32;
21195+ uint64_t cnt:32;
21196+ } s;
21197+ struct cvmx_spxx_bckprs_cnt_s cn38xx;
21198+ struct cvmx_spxx_bckprs_cnt_s cn38xxp2;
21199+ struct cvmx_spxx_bckprs_cnt_s cn58xx;
21200+ struct cvmx_spxx_bckprs_cnt_s cn58xxp1;
21201+};
21202+
21203+union cvmx_spxx_bist_stat {
21204+ uint64_t u64;
21205+ struct cvmx_spxx_bist_stat_s {
21206+ uint64_t reserved_3_63:61;
21207+ uint64_t stat2:1;
21208+ uint64_t stat1:1;
21209+ uint64_t stat0:1;
21210+ } s;
21211+ struct cvmx_spxx_bist_stat_s cn38xx;
21212+ struct cvmx_spxx_bist_stat_s cn38xxp2;
21213+ struct cvmx_spxx_bist_stat_s cn58xx;
21214+ struct cvmx_spxx_bist_stat_s cn58xxp1;
21215+};
21216+
21217+union cvmx_spxx_clk_ctl {
21218+ uint64_t u64;
21219+ struct cvmx_spxx_clk_ctl_s {
21220+ uint64_t reserved_17_63:47;
21221+ uint64_t seetrn:1;
21222+ uint64_t reserved_12_15:4;
21223+ uint64_t clkdly:5;
21224+ uint64_t runbist:1;
21225+ uint64_t statdrv:1;
21226+ uint64_t statrcv:1;
21227+ uint64_t sndtrn:1;
21228+ uint64_t drptrn:1;
21229+ uint64_t rcvtrn:1;
21230+ uint64_t srxdlck:1;
21231+ } s;
21232+ struct cvmx_spxx_clk_ctl_s cn38xx;
21233+ struct cvmx_spxx_clk_ctl_s cn38xxp2;
21234+ struct cvmx_spxx_clk_ctl_s cn58xx;
21235+ struct cvmx_spxx_clk_ctl_s cn58xxp1;
21236+};
21237+
21238+union cvmx_spxx_clk_stat {
21239+ uint64_t u64;
21240+ struct cvmx_spxx_clk_stat_s {
21241+ uint64_t reserved_11_63:53;
21242+ uint64_t stxcal:1;
21243+ uint64_t reserved_9_9:1;
21244+ uint64_t srxtrn:1;
21245+ uint64_t s4clk1:1;
21246+ uint64_t s4clk0:1;
21247+ uint64_t d4clk1:1;
21248+ uint64_t d4clk0:1;
21249+ uint64_t reserved_0_3:4;
21250+ } s;
21251+ struct cvmx_spxx_clk_stat_s cn38xx;
21252+ struct cvmx_spxx_clk_stat_s cn38xxp2;
21253+ struct cvmx_spxx_clk_stat_s cn58xx;
21254+ struct cvmx_spxx_clk_stat_s cn58xxp1;
21255+};
21256+
21257+union cvmx_spxx_dbg_deskew_ctl {
21258+ uint64_t u64;
21259+ struct cvmx_spxx_dbg_deskew_ctl_s {
21260+ uint64_t reserved_30_63:34;
21261+ uint64_t fallnop:1;
21262+ uint64_t fall8:1;
21263+ uint64_t reserved_26_27:2;
21264+ uint64_t sstep_go:1;
21265+ uint64_t sstep:1;
21266+ uint64_t reserved_22_23:2;
21267+ uint64_t clrdly:1;
21268+ uint64_t dec:1;
21269+ uint64_t inc:1;
21270+ uint64_t mux:1;
21271+ uint64_t offset:5;
21272+ uint64_t bitsel:5;
21273+ uint64_t offdly:6;
21274+ uint64_t dllfrc:1;
21275+ uint64_t dlldis:1;
21276+ } s;
21277+ struct cvmx_spxx_dbg_deskew_ctl_s cn38xx;
21278+ struct cvmx_spxx_dbg_deskew_ctl_s cn38xxp2;
21279+ struct cvmx_spxx_dbg_deskew_ctl_s cn58xx;
21280+ struct cvmx_spxx_dbg_deskew_ctl_s cn58xxp1;
21281+};
21282+
21283+union cvmx_spxx_dbg_deskew_state {
21284+ uint64_t u64;
21285+ struct cvmx_spxx_dbg_deskew_state_s {
21286+ uint64_t reserved_9_63:55;
21287+ uint64_t testres:1;
21288+ uint64_t unxterm:1;
21289+ uint64_t muxsel:2;
21290+ uint64_t offset:5;
21291+ } s;
21292+ struct cvmx_spxx_dbg_deskew_state_s cn38xx;
21293+ struct cvmx_spxx_dbg_deskew_state_s cn38xxp2;
21294+ struct cvmx_spxx_dbg_deskew_state_s cn58xx;
21295+ struct cvmx_spxx_dbg_deskew_state_s cn58xxp1;
21296+};
21297+
21298+union cvmx_spxx_drv_ctl {
21299+ uint64_t u64;
21300+ struct cvmx_spxx_drv_ctl_s {
21301+ uint64_t reserved_0_63:64;
21302+ } s;
21303+ struct cvmx_spxx_drv_ctl_cn38xx {
21304+ uint64_t reserved_16_63:48;
21305+ uint64_t stx4ncmp:4;
21306+ uint64_t stx4pcmp:4;
21307+ uint64_t srx4cmp:8;
21308+ } cn38xx;
21309+ struct cvmx_spxx_drv_ctl_cn38xx cn38xxp2;
21310+ struct cvmx_spxx_drv_ctl_cn58xx {
21311+ uint64_t reserved_24_63:40;
21312+ uint64_t stx4ncmp:4;
21313+ uint64_t stx4pcmp:4;
21314+ uint64_t reserved_10_15:6;
21315+ uint64_t srx4cmp:10;
21316+ } cn58xx;
21317+ struct cvmx_spxx_drv_ctl_cn58xx cn58xxp1;
21318+};
21319+
21320+union cvmx_spxx_err_ctl {
21321+ uint64_t u64;
21322+ struct cvmx_spxx_err_ctl_s {
21323+ uint64_t reserved_9_63:55;
21324+ uint64_t prtnxa:1;
21325+ uint64_t dipcls:1;
21326+ uint64_t dippay:1;
21327+ uint64_t reserved_4_5:2;
21328+ uint64_t errcnt:4;
21329+ } s;
21330+ struct cvmx_spxx_err_ctl_s cn38xx;
21331+ struct cvmx_spxx_err_ctl_s cn38xxp2;
21332+ struct cvmx_spxx_err_ctl_s cn58xx;
21333+ struct cvmx_spxx_err_ctl_s cn58xxp1;
21334+};
21335+
21336+union cvmx_spxx_int_dat {
21337+ uint64_t u64;
21338+ struct cvmx_spxx_int_dat_s {
21339+ uint64_t reserved_32_63:32;
21340+ uint64_t mul:1;
21341+ uint64_t reserved_14_30:17;
21342+ uint64_t calbnk:2;
21343+ uint64_t rsvop:4;
21344+ uint64_t prt:8;
21345+ } s;
21346+ struct cvmx_spxx_int_dat_s cn38xx;
21347+ struct cvmx_spxx_int_dat_s cn38xxp2;
21348+ struct cvmx_spxx_int_dat_s cn58xx;
21349+ struct cvmx_spxx_int_dat_s cn58xxp1;
21350+};
21351+
21352+union cvmx_spxx_int_msk {
21353+ uint64_t u64;
21354+ struct cvmx_spxx_int_msk_s {
21355+ uint64_t reserved_12_63:52;
21356+ uint64_t calerr:1;
21357+ uint64_t syncerr:1;
21358+ uint64_t diperr:1;
21359+ uint64_t tpaovr:1;
21360+ uint64_t rsverr:1;
21361+ uint64_t drwnng:1;
21362+ uint64_t clserr:1;
21363+ uint64_t spiovr:1;
21364+ uint64_t reserved_2_3:2;
21365+ uint64_t abnorm:1;
21366+ uint64_t prtnxa:1;
21367+ } s;
21368+ struct cvmx_spxx_int_msk_s cn38xx;
21369+ struct cvmx_spxx_int_msk_s cn38xxp2;
21370+ struct cvmx_spxx_int_msk_s cn58xx;
21371+ struct cvmx_spxx_int_msk_s cn58xxp1;
21372+};
21373+
21374+union cvmx_spxx_int_reg {
21375+ uint64_t u64;
21376+ struct cvmx_spxx_int_reg_s {
21377+ uint64_t reserved_32_63:32;
21378+ uint64_t spf:1;
21379+ uint64_t reserved_12_30:19;
21380+ uint64_t calerr:1;
21381+ uint64_t syncerr:1;
21382+ uint64_t diperr:1;
21383+ uint64_t tpaovr:1;
21384+ uint64_t rsverr:1;
21385+ uint64_t drwnng:1;
21386+ uint64_t clserr:1;
21387+ uint64_t spiovr:1;
21388+ uint64_t reserved_2_3:2;
21389+ uint64_t abnorm:1;
21390+ uint64_t prtnxa:1;
21391+ } s;
21392+ struct cvmx_spxx_int_reg_s cn38xx;
21393+ struct cvmx_spxx_int_reg_s cn38xxp2;
21394+ struct cvmx_spxx_int_reg_s cn58xx;
21395+ struct cvmx_spxx_int_reg_s cn58xxp1;
21396+};
21397+
21398+union cvmx_spxx_int_sync {
21399+ uint64_t u64;
21400+ struct cvmx_spxx_int_sync_s {
21401+ uint64_t reserved_12_63:52;
21402+ uint64_t calerr:1;
21403+ uint64_t syncerr:1;
21404+ uint64_t diperr:1;
21405+ uint64_t tpaovr:1;
21406+ uint64_t rsverr:1;
21407+ uint64_t drwnng:1;
21408+ uint64_t clserr:1;
21409+ uint64_t spiovr:1;
21410+ uint64_t reserved_2_3:2;
21411+ uint64_t abnorm:1;
21412+ uint64_t prtnxa:1;
21413+ } s;
21414+ struct cvmx_spxx_int_sync_s cn38xx;
21415+ struct cvmx_spxx_int_sync_s cn38xxp2;
21416+ struct cvmx_spxx_int_sync_s cn58xx;
21417+ struct cvmx_spxx_int_sync_s cn58xxp1;
21418+};
21419+
21420+union cvmx_spxx_tpa_acc {
21421+ uint64_t u64;
21422+ struct cvmx_spxx_tpa_acc_s {
21423+ uint64_t reserved_32_63:32;
21424+ uint64_t cnt:32;
21425+ } s;
21426+ struct cvmx_spxx_tpa_acc_s cn38xx;
21427+ struct cvmx_spxx_tpa_acc_s cn38xxp2;
21428+ struct cvmx_spxx_tpa_acc_s cn58xx;
21429+ struct cvmx_spxx_tpa_acc_s cn58xxp1;
21430+};
21431+
21432+union cvmx_spxx_tpa_max {
21433+ uint64_t u64;
21434+ struct cvmx_spxx_tpa_max_s {
21435+ uint64_t reserved_32_63:32;
21436+ uint64_t max:32;
21437+ } s;
21438+ struct cvmx_spxx_tpa_max_s cn38xx;
21439+ struct cvmx_spxx_tpa_max_s cn38xxp2;
21440+ struct cvmx_spxx_tpa_max_s cn58xx;
21441+ struct cvmx_spxx_tpa_max_s cn58xxp1;
21442+};
21443+
21444+union cvmx_spxx_tpa_sel {
21445+ uint64_t u64;
21446+ struct cvmx_spxx_tpa_sel_s {
21447+ uint64_t reserved_4_63:60;
21448+ uint64_t prtsel:4;
21449+ } s;
21450+ struct cvmx_spxx_tpa_sel_s cn38xx;
21451+ struct cvmx_spxx_tpa_sel_s cn38xxp2;
21452+ struct cvmx_spxx_tpa_sel_s cn58xx;
21453+ struct cvmx_spxx_tpa_sel_s cn58xxp1;
21454+};
21455+
21456+union cvmx_spxx_trn4_ctl {
21457+ uint64_t u64;
21458+ struct cvmx_spxx_trn4_ctl_s {
21459+ uint64_t reserved_13_63:51;
21460+ uint64_t trntest:1;
21461+ uint64_t jitter:3;
21462+ uint64_t clr_boot:1;
21463+ uint64_t set_boot:1;
21464+ uint64_t maxdist:5;
21465+ uint64_t macro_en:1;
21466+ uint64_t mux_en:1;
21467+ } s;
21468+ struct cvmx_spxx_trn4_ctl_s cn38xx;
21469+ struct cvmx_spxx_trn4_ctl_s cn38xxp2;
21470+ struct cvmx_spxx_trn4_ctl_s cn58xx;
21471+ struct cvmx_spxx_trn4_ctl_s cn58xxp1;
21472+};
21473+
21474+#endif
21475--- /dev/null
21476+++ b/drivers/staging/octeon/cvmx-srxx-defs.h
21477@@ -0,0 +1,126 @@
21478+/***********************license start***************
21479+ * Author: Cavium Networks
21480+ *
21481+ * Contact: support@caviumnetworks.com
21482+ * This file is part of the OCTEON SDK
21483+ *
21484+ * Copyright (c) 2003-2008 Cavium Networks
21485+ *
21486+ * This file is free software; you can redistribute it and/or modify
21487+ * it under the terms of the GNU General Public License, Version 2, as
21488+ * published by the Free Software Foundation.
21489+ *
21490+ * This file is distributed in the hope that it will be useful, but
21491+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21492+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21493+ * NONINFRINGEMENT. See the GNU General Public License for more
21494+ * details.
21495+ *
21496+ * You should have received a copy of the GNU General Public License
21497+ * along with this file; if not, write to the Free Software
21498+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21499+ * or visit http://www.gnu.org/licenses/.
21500+ *
21501+ * This file may also be available under a different license from Cavium.
21502+ * Contact Cavium Networks for more information
21503+ ***********************license end**************************************/
21504+
21505+#ifndef __CVMX_SRXX_DEFS_H__
21506+#define __CVMX_SRXX_DEFS_H__
21507+
21508+#define CVMX_SRXX_COM_CTL(block_id) \
21509+ CVMX_ADD_IO_SEG(0x0001180090000200ull + (((block_id) & 1) * 0x8000000ull))
21510+#define CVMX_SRXX_IGN_RX_FULL(block_id) \
21511+ CVMX_ADD_IO_SEG(0x0001180090000218ull + (((block_id) & 1) * 0x8000000ull))
21512+#define CVMX_SRXX_SPI4_CALX(offset, block_id) \
21513+ CVMX_ADD_IO_SEG(0x0001180090000000ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
21514+#define CVMX_SRXX_SPI4_STAT(block_id) \
21515+ CVMX_ADD_IO_SEG(0x0001180090000208ull + (((block_id) & 1) * 0x8000000ull))
21516+#define CVMX_SRXX_SW_TICK_CTL(block_id) \
21517+ CVMX_ADD_IO_SEG(0x0001180090000220ull + (((block_id) & 1) * 0x8000000ull))
21518+#define CVMX_SRXX_SW_TICK_DAT(block_id) \
21519+ CVMX_ADD_IO_SEG(0x0001180090000228ull + (((block_id) & 1) * 0x8000000ull))
21520+
21521+union cvmx_srxx_com_ctl {
21522+ uint64_t u64;
21523+ struct cvmx_srxx_com_ctl_s {
21524+ uint64_t reserved_8_63:56;
21525+ uint64_t prts:4;
21526+ uint64_t st_en:1;
21527+ uint64_t reserved_1_2:2;
21528+ uint64_t inf_en:1;
21529+ } s;
21530+ struct cvmx_srxx_com_ctl_s cn38xx;
21531+ struct cvmx_srxx_com_ctl_s cn38xxp2;
21532+ struct cvmx_srxx_com_ctl_s cn58xx;
21533+ struct cvmx_srxx_com_ctl_s cn58xxp1;
21534+};
21535+
21536+union cvmx_srxx_ign_rx_full {
21537+ uint64_t u64;
21538+ struct cvmx_srxx_ign_rx_full_s {
21539+ uint64_t reserved_16_63:48;
21540+ uint64_t ignore:16;
21541+ } s;
21542+ struct cvmx_srxx_ign_rx_full_s cn38xx;
21543+ struct cvmx_srxx_ign_rx_full_s cn38xxp2;
21544+ struct cvmx_srxx_ign_rx_full_s cn58xx;
21545+ struct cvmx_srxx_ign_rx_full_s cn58xxp1;
21546+};
21547+
21548+union cvmx_srxx_spi4_calx {
21549+ uint64_t u64;
21550+ struct cvmx_srxx_spi4_calx_s {
21551+ uint64_t reserved_17_63:47;
21552+ uint64_t oddpar:1;
21553+ uint64_t prt3:4;
21554+ uint64_t prt2:4;
21555+ uint64_t prt1:4;
21556+ uint64_t prt0:4;
21557+ } s;
21558+ struct cvmx_srxx_spi4_calx_s cn38xx;
21559+ struct cvmx_srxx_spi4_calx_s cn38xxp2;
21560+ struct cvmx_srxx_spi4_calx_s cn58xx;
21561+ struct cvmx_srxx_spi4_calx_s cn58xxp1;
21562+};
21563+
21564+union cvmx_srxx_spi4_stat {
21565+ uint64_t u64;
21566+ struct cvmx_srxx_spi4_stat_s {
21567+ uint64_t reserved_16_63:48;
21568+ uint64_t m:8;
21569+ uint64_t reserved_7_7:1;
21570+ uint64_t len:7;
21571+ } s;
21572+ struct cvmx_srxx_spi4_stat_s cn38xx;
21573+ struct cvmx_srxx_spi4_stat_s cn38xxp2;
21574+ struct cvmx_srxx_spi4_stat_s cn58xx;
21575+ struct cvmx_srxx_spi4_stat_s cn58xxp1;
21576+};
21577+
21578+union cvmx_srxx_sw_tick_ctl {
21579+ uint64_t u64;
21580+ struct cvmx_srxx_sw_tick_ctl_s {
21581+ uint64_t reserved_14_63:50;
21582+ uint64_t eop:1;
21583+ uint64_t sop:1;
21584+ uint64_t mod:4;
21585+ uint64_t opc:4;
21586+ uint64_t adr:4;
21587+ } s;
21588+ struct cvmx_srxx_sw_tick_ctl_s cn38xx;
21589+ struct cvmx_srxx_sw_tick_ctl_s cn58xx;
21590+ struct cvmx_srxx_sw_tick_ctl_s cn58xxp1;
21591+};
21592+
21593+union cvmx_srxx_sw_tick_dat {
21594+ uint64_t u64;
21595+ struct cvmx_srxx_sw_tick_dat_s {
21596+ uint64_t dat:64;
21597+ } s;
21598+ struct cvmx_srxx_sw_tick_dat_s cn38xx;
21599+ struct cvmx_srxx_sw_tick_dat_s cn58xx;
21600+ struct cvmx_srxx_sw_tick_dat_s cn58xxp1;
21601+};
21602+
21603+#endif
21604--- /dev/null
21605+++ b/drivers/staging/octeon/cvmx-stxx-defs.h
21606@@ -0,0 +1,292 @@
21607+/***********************license start***************
21608+ * Author: Cavium Networks
21609+ *
21610+ * Contact: support@caviumnetworks.com
21611+ * This file is part of the OCTEON SDK
21612+ *
21613+ * Copyright (c) 2003-2008 Cavium Networks
21614+ *
21615+ * This file is free software; you can redistribute it and/or modify
21616+ * it under the terms of the GNU General Public License, Version 2, as
21617+ * published by the Free Software Foundation.
21618+ *
21619+ * This file is distributed in the hope that it will be useful, but
21620+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21621+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21622+ * NONINFRINGEMENT. See the GNU General Public License for more
21623+ * details.
21624+ *
21625+ * You should have received a copy of the GNU General Public License
21626+ * along with this file; if not, write to the Free Software
21627+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21628+ * or visit http://www.gnu.org/licenses/.
21629+ *
21630+ * This file may also be available under a different license from Cavium.
21631+ * Contact Cavium Networks for more information
21632+ ***********************license end**************************************/
21633+
21634+#ifndef __CVMX_STXX_DEFS_H__
21635+#define __CVMX_STXX_DEFS_H__
21636+
21637+#define CVMX_STXX_ARB_CTL(block_id) \
21638+ CVMX_ADD_IO_SEG(0x0001180090000608ull + (((block_id) & 1) * 0x8000000ull))
21639+#define CVMX_STXX_BCKPRS_CNT(block_id) \
21640+ CVMX_ADD_IO_SEG(0x0001180090000688ull + (((block_id) & 1) * 0x8000000ull))
21641+#define CVMX_STXX_COM_CTL(block_id) \
21642+ CVMX_ADD_IO_SEG(0x0001180090000600ull + (((block_id) & 1) * 0x8000000ull))
21643+#define CVMX_STXX_DIP_CNT(block_id) \
21644+ CVMX_ADD_IO_SEG(0x0001180090000690ull + (((block_id) & 1) * 0x8000000ull))
21645+#define CVMX_STXX_IGN_CAL(block_id) \
21646+ CVMX_ADD_IO_SEG(0x0001180090000610ull + (((block_id) & 1) * 0x8000000ull))
21647+#define CVMX_STXX_INT_MSK(block_id) \
21648+ CVMX_ADD_IO_SEG(0x00011800900006A0ull + (((block_id) & 1) * 0x8000000ull))
21649+#define CVMX_STXX_INT_REG(block_id) \
21650+ CVMX_ADD_IO_SEG(0x0001180090000698ull + (((block_id) & 1) * 0x8000000ull))
21651+#define CVMX_STXX_INT_SYNC(block_id) \
21652+ CVMX_ADD_IO_SEG(0x00011800900006A8ull + (((block_id) & 1) * 0x8000000ull))
21653+#define CVMX_STXX_MIN_BST(block_id) \
21654+ CVMX_ADD_IO_SEG(0x0001180090000618ull + (((block_id) & 1) * 0x8000000ull))
21655+#define CVMX_STXX_SPI4_CALX(offset, block_id) \
21656+ CVMX_ADD_IO_SEG(0x0001180090000400ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
21657+#define CVMX_STXX_SPI4_DAT(block_id) \
21658+ CVMX_ADD_IO_SEG(0x0001180090000628ull + (((block_id) & 1) * 0x8000000ull))
21659+#define CVMX_STXX_SPI4_STAT(block_id) \
21660+ CVMX_ADD_IO_SEG(0x0001180090000630ull + (((block_id) & 1) * 0x8000000ull))
21661+#define CVMX_STXX_STAT_BYTES_HI(block_id) \
21662+ CVMX_ADD_IO_SEG(0x0001180090000648ull + (((block_id) & 1) * 0x8000000ull))
21663+#define CVMX_STXX_STAT_BYTES_LO(block_id) \
21664+ CVMX_ADD_IO_SEG(0x0001180090000680ull + (((block_id) & 1) * 0x8000000ull))
21665+#define CVMX_STXX_STAT_CTL(block_id) \
21666+ CVMX_ADD_IO_SEG(0x0001180090000638ull + (((block_id) & 1) * 0x8000000ull))
21667+#define CVMX_STXX_STAT_PKT_XMT(block_id) \
21668+ CVMX_ADD_IO_SEG(0x0001180090000640ull + (((block_id) & 1) * 0x8000000ull))
21669+
21670+union cvmx_stxx_arb_ctl {
21671+ uint64_t u64;
21672+ struct cvmx_stxx_arb_ctl_s {
21673+ uint64_t reserved_6_63:58;
21674+ uint64_t mintrn:1;
21675+ uint64_t reserved_4_4:1;
21676+ uint64_t igntpa:1;
21677+ uint64_t reserved_0_2:3;
21678+ } s;
21679+ struct cvmx_stxx_arb_ctl_s cn38xx;
21680+ struct cvmx_stxx_arb_ctl_s cn38xxp2;
21681+ struct cvmx_stxx_arb_ctl_s cn58xx;
21682+ struct cvmx_stxx_arb_ctl_s cn58xxp1;
21683+};
21684+
21685+union cvmx_stxx_bckprs_cnt {
21686+ uint64_t u64;
21687+ struct cvmx_stxx_bckprs_cnt_s {
21688+ uint64_t reserved_32_63:32;
21689+ uint64_t cnt:32;
21690+ } s;
21691+ struct cvmx_stxx_bckprs_cnt_s cn38xx;
21692+ struct cvmx_stxx_bckprs_cnt_s cn38xxp2;
21693+ struct cvmx_stxx_bckprs_cnt_s cn58xx;
21694+ struct cvmx_stxx_bckprs_cnt_s cn58xxp1;
21695+};
21696+
21697+union cvmx_stxx_com_ctl {
21698+ uint64_t u64;
21699+ struct cvmx_stxx_com_ctl_s {
21700+ uint64_t reserved_4_63:60;
21701+ uint64_t st_en:1;
21702+ uint64_t reserved_1_2:2;
21703+ uint64_t inf_en:1;
21704+ } s;
21705+ struct cvmx_stxx_com_ctl_s cn38xx;
21706+ struct cvmx_stxx_com_ctl_s cn38xxp2;
21707+ struct cvmx_stxx_com_ctl_s cn58xx;
21708+ struct cvmx_stxx_com_ctl_s cn58xxp1;
21709+};
21710+
21711+union cvmx_stxx_dip_cnt {
21712+ uint64_t u64;
21713+ struct cvmx_stxx_dip_cnt_s {
21714+ uint64_t reserved_8_63:56;
21715+ uint64_t frmmax:4;
21716+ uint64_t dipmax:4;
21717+ } s;
21718+ struct cvmx_stxx_dip_cnt_s cn38xx;
21719+ struct cvmx_stxx_dip_cnt_s cn38xxp2;
21720+ struct cvmx_stxx_dip_cnt_s cn58xx;
21721+ struct cvmx_stxx_dip_cnt_s cn58xxp1;
21722+};
21723+
21724+union cvmx_stxx_ign_cal {
21725+ uint64_t u64;
21726+ struct cvmx_stxx_ign_cal_s {
21727+ uint64_t reserved_16_63:48;
21728+ uint64_t igntpa:16;
21729+ } s;
21730+ struct cvmx_stxx_ign_cal_s cn38xx;
21731+ struct cvmx_stxx_ign_cal_s cn38xxp2;
21732+ struct cvmx_stxx_ign_cal_s cn58xx;
21733+ struct cvmx_stxx_ign_cal_s cn58xxp1;
21734+};
21735+
21736+union cvmx_stxx_int_msk {
21737+ uint64_t u64;
21738+ struct cvmx_stxx_int_msk_s {
21739+ uint64_t reserved_8_63:56;
21740+ uint64_t frmerr:1;
21741+ uint64_t unxfrm:1;
21742+ uint64_t nosync:1;
21743+ uint64_t diperr:1;
21744+ uint64_t datovr:1;
21745+ uint64_t ovrbst:1;
21746+ uint64_t calpar1:1;
21747+ uint64_t calpar0:1;
21748+ } s;
21749+ struct cvmx_stxx_int_msk_s cn38xx;
21750+ struct cvmx_stxx_int_msk_s cn38xxp2;
21751+ struct cvmx_stxx_int_msk_s cn58xx;
21752+ struct cvmx_stxx_int_msk_s cn58xxp1;
21753+};
21754+
21755+union cvmx_stxx_int_reg {
21756+ uint64_t u64;
21757+ struct cvmx_stxx_int_reg_s {
21758+ uint64_t reserved_9_63:55;
21759+ uint64_t syncerr:1;
21760+ uint64_t frmerr:1;
21761+ uint64_t unxfrm:1;
21762+ uint64_t nosync:1;
21763+ uint64_t diperr:1;
21764+ uint64_t datovr:1;
21765+ uint64_t ovrbst:1;
21766+ uint64_t calpar1:1;
21767+ uint64_t calpar0:1;
21768+ } s;
21769+ struct cvmx_stxx_int_reg_s cn38xx;
21770+ struct cvmx_stxx_int_reg_s cn38xxp2;
21771+ struct cvmx_stxx_int_reg_s cn58xx;
21772+ struct cvmx_stxx_int_reg_s cn58xxp1;
21773+};
21774+
21775+union cvmx_stxx_int_sync {
21776+ uint64_t u64;
21777+ struct cvmx_stxx_int_sync_s {
21778+ uint64_t reserved_8_63:56;
21779+ uint64_t frmerr:1;
21780+ uint64_t unxfrm:1;
21781+ uint64_t nosync:1;
21782+ uint64_t diperr:1;
21783+ uint64_t datovr:1;
21784+ uint64_t ovrbst:1;
21785+ uint64_t calpar1:1;
21786+ uint64_t calpar0:1;
21787+ } s;
21788+ struct cvmx_stxx_int_sync_s cn38xx;
21789+ struct cvmx_stxx_int_sync_s cn38xxp2;
21790+ struct cvmx_stxx_int_sync_s cn58xx;
21791+ struct cvmx_stxx_int_sync_s cn58xxp1;
21792+};
21793+
21794+union cvmx_stxx_min_bst {
21795+ uint64_t u64;
21796+ struct cvmx_stxx_min_bst_s {
21797+ uint64_t reserved_9_63:55;
21798+ uint64_t minb:9;
21799+ } s;
21800+ struct cvmx_stxx_min_bst_s cn38xx;
21801+ struct cvmx_stxx_min_bst_s cn38xxp2;
21802+ struct cvmx_stxx_min_bst_s cn58xx;
21803+ struct cvmx_stxx_min_bst_s cn58xxp1;
21804+};
21805+
21806+union cvmx_stxx_spi4_calx {
21807+ uint64_t u64;
21808+ struct cvmx_stxx_spi4_calx_s {
21809+ uint64_t reserved_17_63:47;
21810+ uint64_t oddpar:1;
21811+ uint64_t prt3:4;
21812+ uint64_t prt2:4;
21813+ uint64_t prt1:4;
21814+ uint64_t prt0:4;
21815+ } s;
21816+ struct cvmx_stxx_spi4_calx_s cn38xx;
21817+ struct cvmx_stxx_spi4_calx_s cn38xxp2;
21818+ struct cvmx_stxx_spi4_calx_s cn58xx;
21819+ struct cvmx_stxx_spi4_calx_s cn58xxp1;
21820+};
21821+
21822+union cvmx_stxx_spi4_dat {
21823+ uint64_t u64;
21824+ struct cvmx_stxx_spi4_dat_s {
21825+ uint64_t reserved_32_63:32;
21826+ uint64_t alpha:16;
21827+ uint64_t max_t:16;
21828+ } s;
21829+ struct cvmx_stxx_spi4_dat_s cn38xx;
21830+ struct cvmx_stxx_spi4_dat_s cn38xxp2;
21831+ struct cvmx_stxx_spi4_dat_s cn58xx;
21832+ struct cvmx_stxx_spi4_dat_s cn58xxp1;
21833+};
21834+
21835+union cvmx_stxx_spi4_stat {
21836+ uint64_t u64;
21837+ struct cvmx_stxx_spi4_stat_s {
21838+ uint64_t reserved_16_63:48;
21839+ uint64_t m:8;
21840+ uint64_t reserved_7_7:1;
21841+ uint64_t len:7;
21842+ } s;
21843+ struct cvmx_stxx_spi4_stat_s cn38xx;
21844+ struct cvmx_stxx_spi4_stat_s cn38xxp2;
21845+ struct cvmx_stxx_spi4_stat_s cn58xx;
21846+ struct cvmx_stxx_spi4_stat_s cn58xxp1;
21847+};
21848+
21849+union cvmx_stxx_stat_bytes_hi {
21850+ uint64_t u64;
21851+ struct cvmx_stxx_stat_bytes_hi_s {
21852+ uint64_t reserved_32_63:32;
21853+ uint64_t cnt:32;
21854+ } s;
21855+ struct cvmx_stxx_stat_bytes_hi_s cn38xx;
21856+ struct cvmx_stxx_stat_bytes_hi_s cn38xxp2;
21857+ struct cvmx_stxx_stat_bytes_hi_s cn58xx;
21858+ struct cvmx_stxx_stat_bytes_hi_s cn58xxp1;
21859+};
21860+
21861+union cvmx_stxx_stat_bytes_lo {
21862+ uint64_t u64;
21863+ struct cvmx_stxx_stat_bytes_lo_s {
21864+ uint64_t reserved_32_63:32;
21865+ uint64_t cnt:32;
21866+ } s;
21867+ struct cvmx_stxx_stat_bytes_lo_s cn38xx;
21868+ struct cvmx_stxx_stat_bytes_lo_s cn38xxp2;
21869+ struct cvmx_stxx_stat_bytes_lo_s cn58xx;
21870+ struct cvmx_stxx_stat_bytes_lo_s cn58xxp1;
21871+};
21872+
21873+union cvmx_stxx_stat_ctl {
21874+ uint64_t u64;
21875+ struct cvmx_stxx_stat_ctl_s {
21876+ uint64_t reserved_5_63:59;
21877+ uint64_t clr:1;
21878+ uint64_t bckprs:4;
21879+ } s;
21880+ struct cvmx_stxx_stat_ctl_s cn38xx;
21881+ struct cvmx_stxx_stat_ctl_s cn38xxp2;
21882+ struct cvmx_stxx_stat_ctl_s cn58xx;
21883+ struct cvmx_stxx_stat_ctl_s cn58xxp1;
21884+};
21885+
21886+union cvmx_stxx_stat_pkt_xmt {
21887+ uint64_t u64;
21888+ struct cvmx_stxx_stat_pkt_xmt_s {
21889+ uint64_t reserved_32_63:32;
21890+ uint64_t cnt:32;
21891+ } s;
21892+ struct cvmx_stxx_stat_pkt_xmt_s cn38xx;
21893+ struct cvmx_stxx_stat_pkt_xmt_s cn38xxp2;
21894+ struct cvmx_stxx_stat_pkt_xmt_s cn58xx;
21895+ struct cvmx_stxx_stat_pkt_xmt_s cn58xxp1;
21896+};
21897+
21898+#endif
21899--- /dev/null
21900+++ b/drivers/staging/octeon/cvmx-wqe.h
21901@@ -0,0 +1,397 @@
21902+/***********************license start***************
21903+ * Author: Cavium Networks
21904+ *
21905+ * Contact: support@caviumnetworks.com
21906+ * This file is part of the OCTEON SDK
21907+ *
21908+ * Copyright (c) 2003-2008 Cavium Networks
21909+ *
21910+ * This file is free software; you can redistribute it and/or modify
21911+ * it under the terms of the GNU General Public License, Version 2, as
21912+ * published by the Free Software Foundation.
21913+ *
21914+ * This file is distributed in the hope that it will be useful, but
21915+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21916+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21917+ * NONINFRINGEMENT. See the GNU General Public License for more
21918+ * details.
21919+ *
21920+ * You should have received a copy of the GNU General Public License
21921+ * along with this file; if not, write to the Free Software
21922+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21923+ * or visit http://www.gnu.org/licenses/.
21924+ *
21925+ * This file may also be available under a different license from Cavium.
21926+ * Contact Cavium Networks for more information
21927+ ***********************license end**************************************/
21928+
21929+/**
21930+ *
21931+ * This header file defines the work queue entry (wqe) data structure.
21932+ * Since this is a commonly used structure that depends on structures
21933+ * from several hardware blocks, those definitions have been placed
21934+ * in this file to create a single point of definition of the wqe
21935+ * format.
21936+ * Data structures are still named according to the block that they
21937+ * relate to.
21938+ *
21939+ */
21940+
21941+#ifndef __CVMX_WQE_H__
21942+#define __CVMX_WQE_H__
21943+
21944+#include "cvmx-packet.h"
21945+
21946+
21947+#define OCT_TAG_TYPE_STRING(x) \
21948+ (((x) == CVMX_POW_TAG_TYPE_ORDERED) ? "ORDERED" : \
21949+ (((x) == CVMX_POW_TAG_TYPE_ATOMIC) ? "ATOMIC" : \
21950+ (((x) == CVMX_POW_TAG_TYPE_NULL) ? "NULL" : \
21951+ "NULL_NULL")))
21952+
21953+/**
21954+ * HW decode / err_code in work queue entry
21955+ */
21956+typedef union {
21957+ uint64_t u64;
21958+
21959+ /* Use this struct if the hardware determines that the packet is IP */
21960+ struct {
21961+ /* HW sets this to the number of buffers used by this packet */
21962+ uint64_t bufs:8;
21963+ /* HW sets to the number of L2 bytes prior to the IP */
21964+ uint64_t ip_offset:8;
21965+ /* set to 1 if we found DSA/VLAN in the L2 */
21966+ uint64_t vlan_valid:1;
21967+ /* Set to 1 if the DSA/VLAN tag is stacked */
21968+ uint64_t vlan_stacked:1;
21969+ uint64_t unassigned:1;
21970+ /* HW sets to the DSA/VLAN CFI flag (valid when vlan_valid) */
21971+ uint64_t vlan_cfi:1;
21972+ /* HW sets to the DSA/VLAN_ID field (valid when vlan_valid) */
21973+ uint64_t vlan_id:12;
21974+ /* Ring Identifier (if PCIe). Requires PIP_GBL_CTL[RING_EN]=1 */
21975+ uint64_t pr:4;
21976+ uint64_t unassigned2:8;
21977+ /* the packet needs to be decompressed */
21978+ uint64_t dec_ipcomp:1;
21979+ /* the packet is either TCP or UDP */
21980+ uint64_t tcp_or_udp:1;
21981+ /* the packet needs to be decrypted (ESP or AH) */
21982+ uint64_t dec_ipsec:1;
21983+ /* the packet is IPv6 */
21984+ uint64_t is_v6:1;
21985+
21986+ /*
21987+ * (rcv_error, not_IP, IP_exc, is_frag, L4_error,
21988+ * software, etc.).
21989+ */
21990+
21991+ /*
21992+ * reserved for software use, hardware will clear on
21993+ * packet creation.
21994+ */
21995+ uint64_t software:1;
21996+ /* exceptional conditions below */
21997+ /* the receive interface hardware detected an L4 error
21998+ * (only applies if !is_frag) (only applies if
21999+ * !rcv_error && !not_IP && !IP_exc && !is_frag)
22000+ * failure indicated in err_code below, decode:
22001+ *
22002+ * - 1 = Malformed L4
22003+ * - 2 = L4 Checksum Error: the L4 checksum value is
22004+ * - 3 = UDP Length Error: The UDP length field would
22005+ * make the UDP data longer than what remains in
22006+ * the IP packet (as defined by the IP header
22007+ * length field).
22008+ * - 4 = Bad L4 Port: either the source or destination
22009+ * TCP/UDP port is 0.
22010+ * - 8 = TCP FIN Only: the packet is TCP and only the
22011+ * FIN flag set.
22012+ * - 9 = TCP No Flags: the packet is TCP and no flags
22013+ * are set.
22014+ * - 10 = TCP FIN RST: the packet is TCP and both FIN
22015+ * and RST are set.
22016+ * - 11 = TCP SYN URG: the packet is TCP and both SYN
22017+ * and URG are set.
22018+ * - 12 = TCP SYN RST: the packet is TCP and both SYN
22019+ * and RST are set.
22020+ * - 13 = TCP SYN FIN: the packet is TCP and both SYN
22021+ * and FIN are set.
22022+ */
22023+ uint64_t L4_error:1;
22024+ /* set if the packet is a fragment */
22025+ uint64_t is_frag:1;
22026+ /* the receive interface hardware detected an IP error
22027+ * / exception (only applies if !rcv_error && !not_IP)
22028+ * failure indicated in err_code below, decode:
22029+ *
22030+ * - 1 = Not IP: the IP version field is neither 4 nor
22031+ * 6.
22032+ * - 2 = IPv4 Header Checksum Error: the IPv4 header
22033+ * has a checksum violation.
22034+ * - 3 = IP Malformed Header: the packet is not long
22035+ * enough to contain the IP header.
22036+ * - 4 = IP Malformed: the packet is not long enough
22037+ * to contain the bytes indicated by the IP
22038+ * header. Pad is allowed.
22039+ * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6
22040+ * Hop Count field are zero.
22041+ * - 6 = IP Options
22042+ */
22043+ uint64_t IP_exc:1;
22044+ /*
22045+ * Set if the hardware determined that the packet is a
22046+ * broadcast.
22047+ */
22048+ uint64_t is_bcast:1;
22049+ /*
22050+ * St if the hardware determined that the packet is a
22051+ * multi-cast.
22052+ */
22053+ uint64_t is_mcast:1;
22054+ /*
22055+ * Set if the packet may not be IP (must be zero in
22056+ * this case).
22057+ */
22058+ uint64_t not_IP:1;
22059+ /*
22060+ * The receive interface hardware detected a receive
22061+ * error (must be zero in this case).
22062+ */
22063+ uint64_t rcv_error:1;
22064+ /* lower err_code = first-level descriptor of the
22065+ * work */
22066+ /* zero for packet submitted by hardware that isn't on
22067+ * the slow path */
22068+ /* type is cvmx_pip_err_t */
22069+ uint64_t err_code:8;
22070+ } s;
22071+
22072+ /* use this to get at the 16 vlan bits */
22073+ struct {
22074+ uint64_t unused1:16;
22075+ uint64_t vlan:16;
22076+ uint64_t unused2:32;
22077+ } svlan;
22078+
22079+ /*
22080+ * use this struct if the hardware could not determine that
22081+ * the packet is ip.
22082+ */
22083+ struct {
22084+ /*
22085+ * HW sets this to the number of buffers used by this
22086+ * packet.
22087+ */
22088+ uint64_t bufs:8;
22089+ uint64_t unused:8;
22090+ /* set to 1 if we found DSA/VLAN in the L2 */
22091+ uint64_t vlan_valid:1;
22092+ /* Set to 1 if the DSA/VLAN tag is stacked */
22093+ uint64_t vlan_stacked:1;
22094+ uint64_t unassigned:1;
22095+ /*
22096+ * HW sets to the DSA/VLAN CFI flag (valid when
22097+ * vlan_valid)
22098+ */
22099+ uint64_t vlan_cfi:1;
22100+ /*
22101+ * HW sets to the DSA/VLAN_ID field (valid when
22102+ * vlan_valid).
22103+ */
22104+ uint64_t vlan_id:12;
22105+ /*
22106+ * Ring Identifier (if PCIe). Requires
22107+ * PIP_GBL_CTL[RING_EN]=1
22108+ */
22109+ uint64_t pr:4;
22110+ uint64_t unassigned2:12;
22111+ /*
22112+ * reserved for software use, hardware will clear on
22113+ * packet creation.
22114+ */
22115+ uint64_t software:1;
22116+ uint64_t unassigned3:1;
22117+ /*
22118+ * set if the hardware determined that the packet is
22119+ * rarp.
22120+ */
22121+ uint64_t is_rarp:1;
22122+ /*
22123+ * set if the hardware determined that the packet is
22124+ * arp
22125+ */
22126+ uint64_t is_arp:1;
22127+ /*
22128+ * set if the hardware determined that the packet is a
22129+ * broadcast.
22130+ */
22131+ uint64_t is_bcast:1;
22132+ /*
22133+ * set if the hardware determined that the packet is a
22134+ * multi-cast
22135+ */
22136+ uint64_t is_mcast:1;
22137+ /*
22138+ * set if the packet may not be IP (must be one in
22139+ * this case)
22140+ */
22141+ uint64_t not_IP:1;
22142+ /* The receive interface hardware detected a receive
22143+ * error. Failure indicated in err_code below,
22144+ * decode:
22145+ *
22146+ * - 1 = partial error: a packet was partially
22147+ * received, but internal buffering / bandwidth
22148+ * was not adequate to receive the entire
22149+ * packet.
22150+ * - 2 = jabber error: the RGMII packet was too large
22151+ * and is truncated.
22152+ * - 3 = overrun error: the RGMII packet is longer
22153+ * than allowed and had an FCS error.
22154+ * - 4 = oversize error: the RGMII packet is longer
22155+ * than allowed.
22156+ * - 5 = alignment error: the RGMII packet is not an
22157+ * integer number of bytes
22158+ * and had an FCS error (100M and 10M only).
22159+ * - 6 = fragment error: the RGMII packet is shorter
22160+ * than allowed and had an FCS error.
22161+ * - 7 = GMX FCS error: the RGMII packet had an FCS
22162+ * error.
22163+ * - 8 = undersize error: the RGMII packet is shorter
22164+ * than allowed.
22165+ * - 9 = extend error: the RGMII packet had an extend
22166+ * error.
22167+ * - 10 = length mismatch error: the RGMII packet had
22168+ * a length that did not match the length field
22169+ * in the L2 HDR.
22170+ * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII
22171+ * packet had one or more data reception errors
22172+ * (RXERR) or the SPI4 packet had one or more
22173+ * DIP4 errors.
22174+ * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII
22175+ * packet was not large enough to cover the
22176+ * skipped bytes or the SPI4 packet was
22177+ * terminated with an About EOPS.
22178+ * - 13 = RGMII nibble error/SPI4 Port NXA Error: the
22179+ * RGMII packet had a studder error (data not
22180+ * repeated - 10/100M only) or the SPI4 packet
22181+ * was sent to an NXA.
22182+ * - 16 = FCS error: a SPI4.2 packet had an FCS error.
22183+ * - 17 = Skip error: a packet was not large enough to
22184+ * cover the skipped bytes.
22185+ * - 18 = L2 header malformed: the packet is not long
22186+ * enough to contain the L2.
22187+ */
22188+
22189+ uint64_t rcv_error:1;
22190+ /*
22191+ * lower err_code = first-level descriptor of the
22192+ * work
22193+ */
22194+ /*
22195+ * zero for packet submitted by hardware that isn't on
22196+ * the slow path
22197+ */
22198+ /* type is cvmx_pip_err_t (union, so can't use directly */
22199+ uint64_t err_code:8;
22200+ } snoip;
22201+
22202+} cvmx_pip_wqe_word2;
22203+
22204+/**
22205+ * Work queue entry format
22206+ *
22207+ * must be 8-byte aligned
22208+ */
22209+typedef struct {
22210+
22211+ /*****************************************************************
22212+ * WORD 0
22213+ * HW WRITE: the following 64 bits are filled by HW when a packet arrives
22214+ */
22215+
22216+ /**
22217+ * raw chksum result generated by the HW
22218+ */
22219+ uint16_t hw_chksum;
22220+ /**
22221+ * Field unused by hardware - available for software
22222+ */
22223+ uint8_t unused;
22224+ /**
22225+ * Next pointer used by hardware for list maintenance.
22226+ * May be written/read by HW before the work queue
22227+ * entry is scheduled to a PP
22228+ * (Only 36 bits used in Octeon 1)
22229+ */
22230+ uint64_t next_ptr:40;
22231+
22232+ /*****************************************************************
22233+ * WORD 1
22234+ * HW WRITE: the following 64 bits are filled by HW when a packet arrives
22235+ */
22236+
22237+ /**
22238+ * HW sets to the total number of bytes in the packet
22239+ */
22240+ uint64_t len:16;
22241+ /**
22242+ * HW sets this to input physical port
22243+ */
22244+ uint64_t ipprt:6;
22245+
22246+ /**
22247+ * HW sets this to what it thought the priority of the input packet was
22248+ */
22249+ uint64_t qos:3;
22250+
22251+ /**
22252+ * the group that the work queue entry will be scheduled to
22253+ */
22254+ uint64_t grp:4;
22255+ /**
22256+ * the type of the tag (ORDERED, ATOMIC, NULL)
22257+ */
22258+ uint64_t tag_type:3;
22259+ /**
22260+ * the synchronization/ordering tag
22261+ */
22262+ uint64_t tag:32;
22263+
22264+ /**
22265+ * WORD 2 HW WRITE: the following 64-bits are filled in by
22266+ * hardware when a packet arrives This indicates a variety of
22267+ * status and error conditions.
22268+ */
22269+ cvmx_pip_wqe_word2 word2;
22270+
22271+ /**
22272+ * Pointer to the first segment of the packet.
22273+ */
22274+ union cvmx_buf_ptr packet_ptr;
22275+
22276+ /**
22277+ * HW WRITE: octeon will fill in a programmable amount from the
22278+ * packet, up to (at most, but perhaps less) the amount
22279+ * needed to fill the work queue entry to 128 bytes
22280+ *
22281+ * If the packet is recognized to be IP, the hardware starts
22282+ * (except that the IPv4 header is padded for appropriate
22283+ * alignment) writing here where the IP header starts. If the
22284+ * packet is not recognized to be IP, the hardware starts
22285+ * writing the beginning of the packet here.
22286+ */
22287+ uint8_t packet_data[96];
22288+
22289+ /**
22290+ * If desired, SW can make the work Q entry any length. For the
22291+ * purposes of discussion here, Assume 128B always, as this is all that
22292+ * the hardware deals with.
22293+ *
22294+ */
22295+
22296+} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;
22297+
22298+#endif /* __CVMX_WQE_H__ */
22299--- /dev/null
22300+++ b/drivers/staging/octeon/ethernet-common.c
22301@@ -0,0 +1,328 @@
22302+/**********************************************************************
22303+ * Author: Cavium Networks
22304+ *
22305+ * Contact: support@caviumnetworks.com
22306+ * This file is part of the OCTEON SDK
22307+ *
22308+ * Copyright (c) 2003-2007 Cavium Networks
22309+ *
22310+ * This file is free software; you can redistribute it and/or modify
22311+ * it under the terms of the GNU General Public License, Version 2, as
22312+ * published by the Free Software Foundation.
22313+ *
22314+ * This file is distributed in the hope that it will be useful, but
22315+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22316+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22317+ * NONINFRINGEMENT. See the GNU General Public License for more
22318+ * details.
22319+ *
22320+ * You should have received a copy of the GNU General Public License
22321+ * along with this file; if not, write to the Free Software
22322+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22323+ * or visit http://www.gnu.org/licenses/.
22324+ *
22325+ * This file may also be available under a different license from Cavium.
22326+ * Contact Cavium Networks for more information
22327+**********************************************************************/
22328+#include <linux/kernel.h>
22329+#include <linux/mii.h>
22330+#include <net/dst.h>
22331+
22332+#include <asm/atomic.h>
22333+#include <asm/octeon/octeon.h>
22334+
22335+#include "ethernet-defines.h"
22336+#include "ethernet-tx.h"
22337+#include "ethernet-mdio.h"
22338+#include "ethernet-util.h"
22339+#include "octeon-ethernet.h"
22340+#include "ethernet-common.h"
22341+
22342+#include "cvmx-pip.h"
22343+#include "cvmx-pko.h"
22344+#include "cvmx-fau.h"
22345+#include "cvmx-helper.h"
22346+
22347+#include "cvmx-gmxx-defs.h"
22348+
22349+/**
22350+ * Get the low level ethernet statistics
22351+ *
22352+ * @dev: Device to get the statistics from
22353+ * Returns Pointer to the statistics
22354+ */
22355+static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
22356+{
22357+ cvmx_pip_port_status_t rx_status;
22358+ cvmx_pko_port_status_t tx_status;
22359+ struct octeon_ethernet *priv = netdev_priv(dev);
22360+
22361+ if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
22362+ if (octeon_is_simulation()) {
22363+ /* The simulator doesn't support statistics */
22364+ memset(&rx_status, 0, sizeof(rx_status));
22365+ memset(&tx_status, 0, sizeof(tx_status));
22366+ } else {
22367+ cvmx_pip_get_port_status(priv->port, 1, &rx_status);
22368+ cvmx_pko_get_port_status(priv->port, 1, &tx_status);
22369+ }
22370+
22371+ priv->stats.rx_packets += rx_status.inb_packets;
22372+ priv->stats.tx_packets += tx_status.packets;
22373+ priv->stats.rx_bytes += rx_status.inb_octets;
22374+ priv->stats.tx_bytes += tx_status.octets;
22375+ priv->stats.multicast += rx_status.multicast_packets;
22376+ priv->stats.rx_crc_errors += rx_status.inb_errors;
22377+ priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
22378+
22379+ /*
22380+ * The drop counter must be incremented atomically
22381+ * since the RX tasklet also increments it.
22382+ */
22383+#ifdef CONFIG_64BIT
22384+ atomic64_add(rx_status.dropped_packets,
22385+ (atomic64_t *)&priv->stats.rx_dropped);
22386+#else
22387+ atomic_add(rx_status.dropped_packets,
22388+ (atomic_t *)&priv->stats.rx_dropped);
22389+#endif
22390+ }
22391+
22392+ return &priv->stats;
22393+}
22394+
22395+/**
22396+ * Set the multicast list. Currently unimplemented.
22397+ *
22398+ * @dev: Device to work on
22399+ */
22400+static void cvm_oct_common_set_multicast_list(struct net_device *dev)
22401+{
22402+ union cvmx_gmxx_prtx_cfg gmx_cfg;
22403+ struct octeon_ethernet *priv = netdev_priv(dev);
22404+ int interface = INTERFACE(priv->port);
22405+ int index = INDEX(priv->port);
22406+
22407+ if ((interface < 2)
22408+ && (cvmx_helper_interface_get_mode(interface) !=
22409+ CVMX_HELPER_INTERFACE_MODE_SPI)) {
22410+ union cvmx_gmxx_rxx_adr_ctl control;
22411+ control.u64 = 0;
22412+ control.s.bcst = 1; /* Allow broadcast MAC addresses */
22413+
22414+ if (dev->mc_list || (dev->flags & IFF_ALLMULTI) ||
22415+ (dev->flags & IFF_PROMISC))
22416+ /* Force accept multicast packets */
22417+ control.s.mcst = 2;
22418+ else
22419+ /* Force reject multicat packets */
22420+ control.s.mcst = 1;
22421+
22422+ if (dev->flags & IFF_PROMISC)
22423+ /*
22424+ * Reject matches if promisc. Since CAM is
22425+ * shut off, should accept everything.
22426+ */
22427+ control.s.cam_mode = 0;
22428+ else
22429+ /* Filter packets based on the CAM */
22430+ control.s.cam_mode = 1;
22431+
22432+ gmx_cfg.u64 =
22433+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
22434+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22435+ gmx_cfg.u64 & ~1ull);
22436+
22437+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
22438+ control.u64);
22439+ if (dev->flags & IFF_PROMISC)
22440+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
22441+ (index, interface), 0);
22442+ else
22443+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
22444+ (index, interface), 1);
22445+
22446+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22447+ gmx_cfg.u64);
22448+ }
22449+}
22450+
22451+/**
22452+ * Set the hardware MAC address for a device
22453+ *
22454+ * @dev: Device to change the MAC address for
22455+ * @addr: Address structure to change it too. MAC address is addr + 2.
22456+ * Returns Zero on success
22457+ */
22458+static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
22459+{
22460+ struct octeon_ethernet *priv = netdev_priv(dev);
22461+ union cvmx_gmxx_prtx_cfg gmx_cfg;
22462+ int interface = INTERFACE(priv->port);
22463+ int index = INDEX(priv->port);
22464+
22465+ memcpy(dev->dev_addr, addr + 2, 6);
22466+
22467+ if ((interface < 2)
22468+ && (cvmx_helper_interface_get_mode(interface) !=
22469+ CVMX_HELPER_INTERFACE_MODE_SPI)) {
22470+ int i;
22471+ uint8_t *ptr = addr;
22472+ uint64_t mac = 0;
22473+ for (i = 0; i < 6; i++)
22474+ mac = (mac << 8) | (uint64_t) (ptr[i + 2]);
22475+
22476+ gmx_cfg.u64 =
22477+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
22478+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22479+ gmx_cfg.u64 & ~1ull);
22480+
22481+ cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
22482+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
22483+ ptr[2]);
22484+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
22485+ ptr[3]);
22486+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
22487+ ptr[4]);
22488+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
22489+ ptr[5]);
22490+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
22491+ ptr[6]);
22492+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
22493+ ptr[7]);
22494+ cvm_oct_common_set_multicast_list(dev);
22495+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22496+ gmx_cfg.u64);
22497+ }
22498+ return 0;
22499+}
22500+
22501+/**
22502+ * Change the link MTU. Unimplemented
22503+ *
22504+ * @dev: Device to change
22505+ * @new_mtu: The new MTU
22506+ *
22507+ * Returns Zero on success
22508+ */
22509+static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
22510+{
22511+ struct octeon_ethernet *priv = netdev_priv(dev);
22512+ int interface = INTERFACE(priv->port);
22513+ int index = INDEX(priv->port);
22514+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
22515+ int vlan_bytes = 4;
22516+#else
22517+ int vlan_bytes = 0;
22518+#endif
22519+
22520+ /*
22521+ * Limit the MTU to make sure the ethernet packets are between
22522+ * 64 bytes and 65535 bytes.
22523+ */
22524+ if ((new_mtu + 14 + 4 + vlan_bytes < 64)
22525+ || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
22526+ pr_err("MTU must be between %d and %d.\n",
22527+ 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes);
22528+ return -EINVAL;
22529+ }
22530+ dev->mtu = new_mtu;
22531+
22532+ if ((interface < 2)
22533+ && (cvmx_helper_interface_get_mode(interface) !=
22534+ CVMX_HELPER_INTERFACE_MODE_SPI)) {
22535+ /* Add ethernet header and FCS, and VLAN if configured. */
22536+ int max_packet = new_mtu + 14 + 4 + vlan_bytes;
22537+
22538+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
22539+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
22540+ /* Signal errors on packets larger than the MTU */
22541+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface),
22542+ max_packet);
22543+ } else {
22544+ /*
22545+ * Set the hardware to truncate packets larger
22546+ * than the MTU and smaller the 64 bytes.
22547+ */
22548+ union cvmx_pip_frm_len_chkx frm_len_chk;
22549+ frm_len_chk.u64 = 0;
22550+ frm_len_chk.s.minlen = 64;
22551+ frm_len_chk.s.maxlen = max_packet;
22552+ cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
22553+ frm_len_chk.u64);
22554+ }
22555+ /*
22556+ * Set the hardware to truncate packets larger than
22557+ * the MTU. The jabber register must be set to a
22558+ * multiple of 8 bytes, so round up.
22559+ */
22560+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
22561+ (max_packet + 7) & ~7u);
22562+ }
22563+ return 0;
22564+}
22565+
22566+/**
22567+ * Per network device initialization
22568+ *
22569+ * @dev: Device to initialize
22570+ * Returns Zero on success
22571+ */
22572+int cvm_oct_common_init(struct net_device *dev)
22573+{
22574+ static int count;
22575+ char mac[8] = { 0x00, 0x00,
22576+ octeon_bootinfo->mac_addr_base[0],
22577+ octeon_bootinfo->mac_addr_base[1],
22578+ octeon_bootinfo->mac_addr_base[2],
22579+ octeon_bootinfo->mac_addr_base[3],
22580+ octeon_bootinfo->mac_addr_base[4],
22581+ octeon_bootinfo->mac_addr_base[5] + count
22582+ };
22583+ struct octeon_ethernet *priv = netdev_priv(dev);
22584+
22585+ /*
22586+ * Force the interface to use the POW send if always_use_pow
22587+ * was specified or it is in the pow send list.
22588+ */
22589+ if ((pow_send_group != -1)
22590+ && (always_use_pow || strstr(pow_send_list, dev->name)))
22591+ priv->queue = -1;
22592+
22593+ if (priv->queue != -1) {
22594+ dev->hard_start_xmit = cvm_oct_xmit;
22595+ if (USE_HW_TCPUDP_CHECKSUM)
22596+ dev->features |= NETIF_F_IP_CSUM;
22597+ } else
22598+ dev->hard_start_xmit = cvm_oct_xmit_pow;
22599+ count++;
22600+
22601+ dev->get_stats = cvm_oct_common_get_stats;
22602+ dev->set_mac_address = cvm_oct_common_set_mac_address;
22603+ dev->set_multicast_list = cvm_oct_common_set_multicast_list;
22604+ dev->change_mtu = cvm_oct_common_change_mtu;
22605+ dev->do_ioctl = cvm_oct_ioctl;
22606+ /* We do our own locking, Linux doesn't need to */
22607+ dev->features |= NETIF_F_LLTX;
22608+ SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
22609+#ifdef CONFIG_NET_POLL_CONTROLLER
22610+ dev->poll_controller = cvm_oct_poll_controller;
22611+#endif
22612+
22613+ cvm_oct_mdio_setup_device(dev);
22614+ dev->set_mac_address(dev, mac);
22615+ dev->change_mtu(dev, dev->mtu);
22616+
22617+ /*
22618+ * Zero out stats for port so we won't mistakenly show
22619+ * counters from the bootloader.
22620+ */
22621+ memset(dev->get_stats(dev), 0, sizeof(struct net_device_stats));
22622+
22623+ return 0;
22624+}
22625+
22626+void cvm_oct_common_uninit(struct net_device *dev)
22627+{
22628+ /* Currently nothing to do */
22629+}
22630--- /dev/null
22631+++ b/drivers/staging/octeon/ethernet-common.h
22632@@ -0,0 +1,29 @@
22633+/*********************************************************************
22634+ * Author: Cavium Networks
22635+ *
22636+ * Contact: support@caviumnetworks.com
22637+ * This file is part of the OCTEON SDK
22638+ *
22639+ * Copyright (c) 2003-2007 Cavium Networks
22640+ *
22641+ * This file is free software; you can redistribute it and/or modify
22642+ * it under the terms of the GNU General Public License, Version 2, as
22643+ * published by the Free Software Foundation.
22644+ *
22645+ * This file is distributed in the hope that it will be useful, but
22646+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22647+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22648+ * NONINFRINGEMENT. See the GNU General Public License for more
22649+ * details.
22650+ *
22651+ * You should have received a copy of the GNU General Public License
22652+ * along with this file; if not, write to the Free Software
22653+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22654+ * or visit http://www.gnu.org/licenses/.
22655+ *
22656+ * This file may also be available under a different license from Cavium.
22657+ * Contact Cavium Networks for more information
22658+*********************************************************************/
22659+
22660+int cvm_oct_common_init(struct net_device *dev);
22661+void cvm_oct_common_uninit(struct net_device *dev);
22662--- /dev/null
22663+++ b/drivers/staging/octeon/ethernet-defines.h
22664@@ -0,0 +1,134 @@
22665+/**********************************************************************
22666+ * Author: Cavium Networks
22667+ *
22668+ * Contact: support@caviumnetworks.com
22669+ * This file is part of the OCTEON SDK
22670+ *
22671+ * Copyright (c) 2003-2007 Cavium Networks
22672+ *
22673+ * This file is free software; you can redistribute it and/or modify
22674+ * it under the terms of the GNU General Public License, Version 2, as
22675+ * published by the Free Software Foundation.
22676+ *
22677+ * This file is distributed in the hope that it will be useful, but
22678+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22679+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22680+ * NONINFRINGEMENT. See the GNU General Public License for more
22681+ * details.
22682+ *
22683+ * You should have received a copy of the GNU General Public License
22684+ * along with this file; if not, write to the Free Software
22685+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22686+ * or visit http://www.gnu.org/licenses/.
22687+ *
22688+ * This file may also be available under a different license from Cavium.
22689+ * Contact Cavium Networks for more information
22690+**********************************************************************/
22691+
22692+/*
22693+ * A few defines are used to control the operation of this driver:
22694+ * CONFIG_CAVIUM_RESERVE32
22695+ * This kernel config options controls the amount of memory configured
22696+ * in a wired TLB entry for all processes to share. If this is set, the
22697+ * driver will use this memory instead of kernel memory for pools. This
22698+ * allows 32bit userspace application to access the buffers, but also
22699+ * requires all received packets to be copied.
22700+ * CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
22701+ * This kernel config option allows the user to control the number of
22702+ * packet and work queue buffers allocated by the driver. If this is zero,
22703+ * the driver uses the default from below.
22704+ * USE_SKBUFFS_IN_HW
22705+ * Tells the driver to populate the packet buffers with kernel skbuffs.
22706+ * This allows the driver to receive packets without copying them. It also
22707+ * means that 32bit userspace can't access the packet buffers.
22708+ * USE_32BIT_SHARED
22709+ * This define tells the driver to allocate memory for buffers from the
22710+ * 32bit sahred region instead of the kernel memory space.
22711+ * USE_HW_TCPUDP_CHECKSUM
22712+ * Controls if the Octeon TCP/UDP checksum engine is used for packet
22713+ * output. If this is zero, the kernel will perform the checksum in
22714+ * software.
22715+ * USE_MULTICORE_RECEIVE
22716+ * Process receive interrupts on multiple cores. This spreads the network
22717+ * load across the first 8 processors. If ths is zero, only one core
22718+ * processes incomming packets.
22719+ * USE_ASYNC_IOBDMA
22720+ * Use asynchronous IO access to hardware. This uses Octeon's asynchronous
22721+ * IOBDMAs to issue IO accesses without stalling. Set this to zero
22722+ * to disable this. Note that IOBDMAs require CVMSEG.
22723+ * REUSE_SKBUFFS_WITHOUT_FREE
22724+ * Allows the TX path to free an skbuff into the FPA hardware pool. This
22725+ * can significantly improve performance for forwarding and bridging, but
22726+ * may be somewhat dangerous. Checks are made, but if any buffer is reused
22727+ * without the proper Linux cleanup, the networking stack may have very
22728+ * bizarre bugs.
22729+ */
22730+#ifndef __ETHERNET_DEFINES_H__
22731+#define __ETHERNET_DEFINES_H__
22732+
22733+#include "cvmx-config.h"
22734+
22735+
22736+#define OCTEON_ETHERNET_VERSION "1.9"
22737+
22738+#ifndef CONFIG_CAVIUM_RESERVE32
22739+#define CONFIG_CAVIUM_RESERVE32 0
22740+#endif
22741+
22742+#if CONFIG_CAVIUM_RESERVE32
22743+#define USE_32BIT_SHARED 1
22744+#define USE_SKBUFFS_IN_HW 0
22745+#define REUSE_SKBUFFS_WITHOUT_FREE 0
22746+#else
22747+#define USE_32BIT_SHARED 0
22748+#define USE_SKBUFFS_IN_HW 1
22749+#ifdef CONFIG_NETFILTER
22750+#define REUSE_SKBUFFS_WITHOUT_FREE 0
22751+#else
22752+#define REUSE_SKBUFFS_WITHOUT_FREE 1
22753+#endif
22754+#endif
22755+
22756+/* Max interrupts per second per core */
22757+#define INTERRUPT_LIMIT 10000
22758+
22759+/* Don't limit the number of interrupts */
22760+/*#define INTERRUPT_LIMIT 0 */
22761+#define USE_HW_TCPUDP_CHECKSUM 1
22762+
22763+#define USE_MULTICORE_RECEIVE 1
22764+
22765+/* Enable Random Early Dropping under load */
22766+#define USE_RED 1
22767+#define USE_ASYNC_IOBDMA (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0)
22768+
22769+/*
22770+ * Allow SW based preamble removal at 10Mbps to workaround PHYs giving
22771+ * us bad preambles.
22772+ */
22773+#define USE_10MBPS_PREAMBLE_WORKAROUND 1
22774+/*
22775+ * Use this to have all FPA frees also tell the L2 not to write data
22776+ * to memory.
22777+ */
22778+#define DONT_WRITEBACK(x) (x)
22779+/* Use this to not have FPA frees control L2 */
22780+/*#define DONT_WRITEBACK(x) 0 */
22781+
22782+/* Maximum number of packets to process per interrupt. */
22783+#define MAX_RX_PACKETS 120
22784+#define MAX_OUT_QUEUE_DEPTH 1000
22785+
22786+#ifndef CONFIG_SMP
22787+#undef USE_MULTICORE_RECEIVE
22788+#define USE_MULTICORE_RECEIVE 0
22789+#endif
22790+
22791+#define IP_PROTOCOL_TCP 6
22792+#define IP_PROTOCOL_UDP 0x11
22793+
22794+#define FAU_NUM_PACKET_BUFFERS_TO_FREE (CVMX_FAU_REG_END - sizeof(uint32_t))
22795+#define TOTAL_NUMBER_OF_PORTS (CVMX_PIP_NUM_INPUT_PORTS+1)
22796+
22797+
22798+#endif /* __ETHERNET_DEFINES_H__ */
22799--- /dev/null
22800+++ b/drivers/staging/octeon/ethernet-mdio.c
22801@@ -0,0 +1,231 @@
22802+/**********************************************************************
22803+ * Author: Cavium Networks
22804+ *
22805+ * Contact: support@caviumnetworks.com
22806+ * This file is part of the OCTEON SDK
22807+ *
22808+ * Copyright (c) 2003-2007 Cavium Networks
22809+ *
22810+ * This file is free software; you can redistribute it and/or modify
22811+ * it under the terms of the GNU General Public License, Version 2, as
22812+ * published by the Free Software Foundation.
22813+ *
22814+ * This file is distributed in the hope that it will be useful, but
22815+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22816+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22817+ * NONINFRINGEMENT. See the GNU General Public License for more
22818+ * details.
22819+ *
22820+ * You should have received a copy of the GNU General Public License
22821+ * along with this file; if not, write to the Free Software
22822+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22823+ * or visit http://www.gnu.org/licenses/.
22824+ *
22825+ * This file may also be available under a different license from Cavium.
22826+ * Contact Cavium Networks for more information
22827+**********************************************************************/
22828+#include <linux/kernel.h>
22829+#include <linux/ethtool.h>
22830+#include <linux/mii.h>
22831+#include <net/dst.h>
22832+
22833+#include <asm/octeon/octeon.h>
22834+
22835+#include "ethernet-defines.h"
22836+#include "octeon-ethernet.h"
22837+#include "ethernet-mdio.h"
22838+
22839+#include "cvmx-helper-board.h"
22840+
22841+#include "cvmx-smix-defs.h"
22842+
22843+DECLARE_MUTEX(mdio_sem);
22844+
22845+/**
22846+ * Perform an MII read. Called by the generic MII routines
22847+ *
22848+ * @dev: Device to perform read for
22849+ * @phy_id: The MII phy id
22850+ * @location: Register location to read
22851+ * Returns Result from the read or zero on failure
22852+ */
22853+static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location)
22854+{
22855+ union cvmx_smix_cmd smi_cmd;
22856+ union cvmx_smix_rd_dat smi_rd;
22857+
22858+ smi_cmd.u64 = 0;
22859+ smi_cmd.s.phy_op = 1;
22860+ smi_cmd.s.phy_adr = phy_id;
22861+ smi_cmd.s.reg_adr = location;
22862+ cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
22863+
22864+ do {
22865+ if (!in_interrupt())
22866+ yield();
22867+ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0));
22868+ } while (smi_rd.s.pending);
22869+
22870+ if (smi_rd.s.val)
22871+ return smi_rd.s.dat;
22872+ else
22873+ return 0;
22874+}
22875+
22876+static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id,
22877+ int location)
22878+{
22879+ return 0xffff;
22880+}
22881+
22882+/**
22883+ * Perform an MII write. Called by the generic MII routines
22884+ *
22885+ * @dev: Device to perform write for
22886+ * @phy_id: The MII phy id
22887+ * @location: Register location to write
22888+ * @val: Value to write
22889+ */
22890+static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location,
22891+ int val)
22892+{
22893+ union cvmx_smix_cmd smi_cmd;
22894+ union cvmx_smix_wr_dat smi_wr;
22895+
22896+ smi_wr.u64 = 0;
22897+ smi_wr.s.dat = val;
22898+ cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64);
22899+
22900+ smi_cmd.u64 = 0;
22901+ smi_cmd.s.phy_op = 0;
22902+ smi_cmd.s.phy_adr = phy_id;
22903+ smi_cmd.s.reg_adr = location;
22904+ cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
22905+
22906+ do {
22907+ if (!in_interrupt())
22908+ yield();
22909+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0));
22910+ } while (smi_wr.s.pending);
22911+}
22912+
22913+static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id,
22914+ int location, int val)
22915+{
22916+}
22917+
22918+static void cvm_oct_get_drvinfo(struct net_device *dev,
22919+ struct ethtool_drvinfo *info)
22920+{
22921+ strcpy(info->driver, "cavium-ethernet");
22922+ strcpy(info->version, OCTEON_ETHERNET_VERSION);
22923+ strcpy(info->bus_info, "Builtin");
22924+}
22925+
22926+static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
22927+{
22928+ struct octeon_ethernet *priv = netdev_priv(dev);
22929+ int ret;
22930+
22931+ down(&mdio_sem);
22932+ ret = mii_ethtool_gset(&priv->mii_info, cmd);
22933+ up(&mdio_sem);
22934+
22935+ return ret;
22936+}
22937+
22938+static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
22939+{
22940+ struct octeon_ethernet *priv = netdev_priv(dev);
22941+ int ret;
22942+
22943+ down(&mdio_sem);
22944+ ret = mii_ethtool_sset(&priv->mii_info, cmd);
22945+ up(&mdio_sem);
22946+
22947+ return ret;
22948+}
22949+
22950+static int cvm_oct_nway_reset(struct net_device *dev)
22951+{
22952+ struct octeon_ethernet *priv = netdev_priv(dev);
22953+ int ret;
22954+
22955+ down(&mdio_sem);
22956+ ret = mii_nway_restart(&priv->mii_info);
22957+ up(&mdio_sem);
22958+
22959+ return ret;
22960+}
22961+
22962+static u32 cvm_oct_get_link(struct net_device *dev)
22963+{
22964+ struct octeon_ethernet *priv = netdev_priv(dev);
22965+ u32 ret;
22966+
22967+ down(&mdio_sem);
22968+ ret = mii_link_ok(&priv->mii_info);
22969+ up(&mdio_sem);
22970+
22971+ return ret;
22972+}
22973+
22974+struct ethtool_ops cvm_oct_ethtool_ops = {
22975+ .get_drvinfo = cvm_oct_get_drvinfo,
22976+ .get_settings = cvm_oct_get_settings,
22977+ .set_settings = cvm_oct_set_settings,
22978+ .nway_reset = cvm_oct_nway_reset,
22979+ .get_link = cvm_oct_get_link,
22980+ .get_sg = ethtool_op_get_sg,
22981+ .get_tx_csum = ethtool_op_get_tx_csum,
22982+};
22983+
22984+/**
22985+ * IOCTL support for PHY control
22986+ *
22987+ * @dev: Device to change
22988+ * @rq: the request
22989+ * @cmd: the command
22990+ * Returns Zero on success
22991+ */
22992+int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
22993+{
22994+ struct octeon_ethernet *priv = netdev_priv(dev);
22995+ struct mii_ioctl_data *data = if_mii(rq);
22996+ unsigned int duplex_chg;
22997+ int ret;
22998+
22999+ down(&mdio_sem);
23000+ ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg);
23001+ up(&mdio_sem);
23002+
23003+ return ret;
23004+}
23005+
23006+/**
23007+ * Setup the MDIO device structures
23008+ *
23009+ * @dev: Device to setup
23010+ *
23011+ * Returns Zero on success, negative on failure
23012+ */
23013+int cvm_oct_mdio_setup_device(struct net_device *dev)
23014+{
23015+ struct octeon_ethernet *priv = netdev_priv(dev);
23016+ int phy_id = cvmx_helper_board_get_mii_address(priv->port);
23017+ if (phy_id != -1) {
23018+ priv->mii_info.dev = dev;
23019+ priv->mii_info.phy_id = phy_id;
23020+ priv->mii_info.phy_id_mask = 0xff;
23021+ priv->mii_info.supports_gmii = 1;
23022+ priv->mii_info.reg_num_mask = 0x1f;
23023+ priv->mii_info.mdio_read = cvm_oct_mdio_read;
23024+ priv->mii_info.mdio_write = cvm_oct_mdio_write;
23025+ } else {
23026+ /* Supply dummy MDIO routines so the kernel won't crash
23027+ if the user tries to read them */
23028+ priv->mii_info.mdio_read = cvm_oct_mdio_dummy_read;
23029+ priv->mii_info.mdio_write = cvm_oct_mdio_dummy_write;
23030+ }
23031+ return 0;
23032+}
23033--- /dev/null
23034+++ b/drivers/staging/octeon/ethernet-mdio.h
23035@@ -0,0 +1,46 @@
23036+/*********************************************************************
23037+ * Author: Cavium Networks
23038+ *
23039+ * Contact: support@caviumnetworks.com
23040+ * This file is part of the OCTEON SDK
23041+ *
23042+ * Copyright (c) 2003-2007 Cavium Networks
23043+ *
23044+ * This file is free software; you can redistribute it and/or modify
23045+ * it under the terms of the GNU General Public License, Version 2, as
23046+ * published by the Free Software Foundation.
23047+ *
23048+ * This file is distributed in the hope that it will be useful, but
23049+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23050+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23051+ * NONINFRINGEMENT. See the GNU General Public License for more
23052+ * details.
23053+ *
23054+ * You should have received a copy of the GNU General Public License
23055+ * along with this file; if not, write to the Free Software
23056+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23057+ * or visit http://www.gnu.org/licenses/.
23058+ *
23059+ * This file may also be available under a different license from Cavium.
23060+ * Contact Cavium Networks for more information
23061+*********************************************************************/
23062+#include <linux/module.h>
23063+#include <linux/kernel.h>
23064+#include <linux/netdevice.h>
23065+#include <linux/init.h>
23066+#include <linux/etherdevice.h>
23067+#include <linux/ip.h>
23068+#include <linux/string.h>
23069+#include <linux/ethtool.h>
23070+#include <linux/mii.h>
23071+#include <linux/seq_file.h>
23072+#include <linux/proc_fs.h>
23073+#include <net/dst.h>
23074+#ifdef CONFIG_XFRM
23075+#include <linux/xfrm.h>
23076+#include <net/xfrm.h>
23077+#endif /* CONFIG_XFRM */
23078+
23079+extern struct ethtool_ops cvm_oct_ethtool_ops;
23080+int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
23081+int cvm_oct_mdio_setup_device(struct net_device *dev);
23082--- /dev/null
23083+++ b/drivers/staging/octeon/ethernet-mem.c
23084@@ -0,0 +1,198 @@
23085+/**********************************************************************
23086+ * Author: Cavium Networks
23087+ *
23088+ * Contact: support@caviumnetworks.com
23089+ * This file is part of the OCTEON SDK
23090+ *
23091+ * Copyright (c) 2003-2007 Cavium Networks
23092+ *
23093+ * This file is free software; you can redistribute it and/or modify
23094+ * it under the terms of the GNU General Public License, Version 2, as
23095+ * published by the Free Software Foundation.
23096+ *
23097+ * This file is distributed in the hope that it will be useful, but
23098+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23099+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23100+ * NONINFRINGEMENT. See the GNU General Public License for more
23101+ * details.
23102+ *
23103+ * You should have received a copy of the GNU General Public License
23104+ * along with this file; if not, write to the Free Software
23105+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23106+ * or visit http://www.gnu.org/licenses/.
23107+ *
23108+ * This file may also be available under a different license from Cavium.
23109+ * Contact Cavium Networks for more information
23110+**********************************************************************/
23111+#include <linux/kernel.h>
23112+#include <linux/netdevice.h>
23113+#include <linux/mii.h>
23114+#include <net/dst.h>
23115+
23116+#include <asm/octeon/octeon.h>
23117+
23118+#include "ethernet-defines.h"
23119+
23120+#include "cvmx-fpa.h"
23121+
23122+/**
23123+ * Fill the supplied hardware pool with skbuffs
23124+ *
23125+ * @pool: Pool to allocate an skbuff for
23126+ * @size: Size of the buffer needed for the pool
23127+ * @elements: Number of buffers to allocate
23128+ */
23129+static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements)
23130+{
23131+ int freed = elements;
23132+ while (freed) {
23133+
23134+ struct sk_buff *skb = dev_alloc_skb(size + 128);
23135+ if (unlikely(skb == NULL)) {
23136+ pr_warning
23137+ ("Failed to allocate skb for hardware pool %d\n",
23138+ pool);
23139+ break;
23140+ }
23141+
23142+ skb_reserve(skb, 128 - (((unsigned long)skb->data) & 0x7f));
23143+ *(struct sk_buff **)(skb->data - sizeof(void *)) = skb;
23144+ cvmx_fpa_free(skb->data, pool, DONT_WRITEBACK(size / 128));
23145+ freed--;
23146+ }
23147+ return elements - freed;
23148+}
23149+
23150+/**
23151+ * Free the supplied hardware pool of skbuffs
23152+ *
23153+ * @pool: Pool to allocate an skbuff for
23154+ * @size: Size of the buffer needed for the pool
23155+ * @elements: Number of buffers to allocate
23156+ */
23157+static void cvm_oct_free_hw_skbuff(int pool, int size, int elements)
23158+{
23159+ char *memory;
23160+
23161+ do {
23162+ memory = cvmx_fpa_alloc(pool);
23163+ if (memory) {
23164+ struct sk_buff *skb =
23165+ *(struct sk_buff **)(memory - sizeof(void *));
23166+ elements--;
23167+ dev_kfree_skb(skb);
23168+ }
23169+ } while (memory);
23170+
23171+ if (elements < 0)
23172+ pr_warning("Freeing of pool %u had too many skbuffs (%d)\n",
23173+ pool, elements);
23174+ else if (elements > 0)
23175+ pr_warning("Freeing of pool %u is missing %d skbuffs\n",
23176+ pool, elements);
23177+}
23178+
23179+/**
23180+ * This function fills a hardware pool with memory. Depending
23181+ * on the config defines, this memory might come from the
23182+ * kernel or global 32bit memory allocated with
23183+ * cvmx_bootmem_alloc.
23184+ *
23185+ * @pool: Pool to populate
23186+ * @size: Size of each buffer in the pool
23187+ * @elements: Number of buffers to allocate
23188+ */
23189+static int cvm_oct_fill_hw_memory(int pool, int size, int elements)
23190+{
23191+ char *memory;
23192+ int freed = elements;
23193+
23194+ if (USE_32BIT_SHARED) {
23195+ extern uint64_t octeon_reserve32_memory;
23196+
23197+ memory =
23198+ cvmx_bootmem_alloc_range(elements * size, 128,
23199+ octeon_reserve32_memory,
23200+ octeon_reserve32_memory +
23201+ (CONFIG_CAVIUM_RESERVE32 << 20) -
23202+ 1);
23203+ if (memory == NULL)
23204+ panic("Unable to allocate %u bytes for FPA pool %d\n",
23205+ elements * size, pool);
23206+
23207+ pr_notice("Memory range %p - %p reserved for "
23208+ "hardware\n", memory,
23209+ memory + elements * size - 1);
23210+
23211+ while (freed) {
23212+ cvmx_fpa_free(memory, pool, 0);
23213+ memory += size;
23214+ freed--;
23215+ }
23216+ } else {
23217+ while (freed) {
23218+ /* We need to force alignment to 128 bytes here */
23219+ memory = kmalloc(size + 127, GFP_ATOMIC);
23220+ if (unlikely(memory == NULL)) {
23221+ pr_warning("Unable to allocate %u bytes for "
23222+ "FPA pool %d\n",
23223+ elements * size, pool);
23224+ break;
23225+ }
23226+ memory = (char *)(((unsigned long)memory + 127) & -128);
23227+ cvmx_fpa_free(memory, pool, 0);
23228+ freed--;
23229+ }
23230+ }
23231+ return elements - freed;
23232+}
23233+
23234+/**
23235+ * Free memory previously allocated with cvm_oct_fill_hw_memory
23236+ *
23237+ * @pool: FPA pool to free
23238+ * @size: Size of each buffer in the pool
23239+ * @elements: Number of buffers that should be in the pool
23240+ */
23241+static void cvm_oct_free_hw_memory(int pool, int size, int elements)
23242+{
23243+ if (USE_32BIT_SHARED) {
23244+ pr_warning("Warning: 32 shared memory is not freeable\n");
23245+ } else {
23246+ char *memory;
23247+ do {
23248+ memory = cvmx_fpa_alloc(pool);
23249+ if (memory) {
23250+ elements--;
23251+ kfree(phys_to_virt(cvmx_ptr_to_phys(memory)));
23252+ }
23253+ } while (memory);
23254+
23255+ if (elements < 0)
23256+ pr_warning("Freeing of pool %u had too many "
23257+ "buffers (%d)\n",
23258+ pool, elements);
23259+ else if (elements > 0)
23260+ pr_warning("Warning: Freeing of pool %u is "
23261+ "missing %d buffers\n",
23262+ pool, elements);
23263+ }
23264+}
23265+
23266+int cvm_oct_mem_fill_fpa(int pool, int size, int elements)
23267+{
23268+ int freed;
23269+ if (USE_SKBUFFS_IN_HW)
23270+ freed = cvm_oct_fill_hw_skbuff(pool, size, elements);
23271+ else
23272+ freed = cvm_oct_fill_hw_memory(pool, size, elements);
23273+ return freed;
23274+}
23275+
23276+void cvm_oct_mem_empty_fpa(int pool, int size, int elements)
23277+{
23278+ if (USE_SKBUFFS_IN_HW)
23279+ cvm_oct_free_hw_skbuff(pool, size, elements);
23280+ else
23281+ cvm_oct_free_hw_memory(pool, size, elements);
23282+}
23283--- /dev/null
23284+++ b/drivers/staging/octeon/ethernet-mem.h
23285@@ -0,0 +1,29 @@
23286+/*********************************************************************
23287+ * Author: Cavium Networks
23288+ *
23289+ * Contact: support@caviumnetworks.com
23290+ * This file is part of the OCTEON SDK
23291+ *
23292+ * Copyright (c) 2003-2007 Cavium Networks
23293+ *
23294+ * This file is free software; you can redistribute it and/or modify
23295+ * it under the terms of the GNU General Public License, Version 2, as
23296+ * published by the Free Software Foundation.
23297+ *
23298+ * This file is distributed in the hope that it will be useful, but
23299+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23300+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23301+ * NONINFRINGEMENT. See the GNU General Public License for more
23302+ * details.
23303+ *
23304+ * You should have received a copy of the GNU General Public License
23305+ * along with this file; if not, write to the Free Software
23306+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23307+ * or visit http://www.gnu.org/licenses/.
23308+ *
23309+ * This file may also be available under a different license from Cavium.
23310+ * Contact Cavium Networks for more information
23311+********************************************************************/
23312+
23313+int cvm_oct_mem_fill_fpa(int pool, int size, int elements);
23314+void cvm_oct_mem_empty_fpa(int pool, int size, int elements);
23315--- /dev/null
23316+++ b/drivers/staging/octeon/ethernet-proc.c
23317@@ -0,0 +1,256 @@
23318+/**********************************************************************
23319+ * Author: Cavium Networks
23320+ *
23321+ * Contact: support@caviumnetworks.com
23322+ * This file is part of the OCTEON SDK
23323+ *
23324+ * Copyright (c) 2003-2007 Cavium Networks
23325+ *
23326+ * This file is free software; you can redistribute it and/or modify
23327+ * it under the terms of the GNU General Public License, Version 2, as
23328+ * published by the Free Software Foundation.
23329+ *
23330+ * This file is distributed in the hope that it will be useful, but
23331+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23332+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23333+ * NONINFRINGEMENT. See the GNU General Public License for more
23334+ * details.
23335+ *
23336+ * You should have received a copy of the GNU General Public License
23337+ * along with this file; if not, write to the Free Software
23338+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23339+ * or visit http://www.gnu.org/licenses/.
23340+ *
23341+ * This file may also be available under a different license from Cavium.
23342+ * Contact Cavium Networks for more information
23343+**********************************************************************/
23344+#include <linux/kernel.h>
23345+#include <linux/mii.h>
23346+#include <linux/seq_file.h>
23347+#include <linux/proc_fs.h>
23348+#include <net/dst.h>
23349+
23350+#include <asm/octeon/octeon.h>
23351+
23352+#include "octeon-ethernet.h"
23353+#include "ethernet-defines.h"
23354+
23355+#include "cvmx-helper.h"
23356+#include "cvmx-pip.h"
23357+
23358+static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev,
23359+ int phy_id, int offset)
23360+{
23361+ struct octeon_ethernet *priv = netdev_priv(dev);
23362+
23363+ priv->mii_info.mdio_write(dev, phy_id, 0x1d, 0xcc00 | offset);
23364+ return ((uint64_t) priv->mii_info.
23365+ mdio_read(dev, phy_id,
23366+ 0x1e) << 16) | (uint64_t) priv->mii_info.
23367+ mdio_read(dev, phy_id, 0x1f);
23368+}
23369+
23370+static int cvm_oct_stats_switch_show(struct seq_file *m, void *v)
23371+{
23372+ static const int ports[] = { 0, 1, 2, 3, 9, -1 };
23373+ struct net_device *dev = cvm_oct_device[0];
23374+ int index = 0;
23375+
23376+ while (ports[index] != -1) {
23377+
23378+ /* Latch port */
23379+ struct octeon_ethernet *priv = netdev_priv(dev);
23380+
23381+ priv->mii_info.mdio_write(dev, 0x1b, 0x1d,
23382+ 0xdc00 | ports[index]);
23383+ seq_printf(m, "\nSwitch Port %d\n", ports[index]);
23384+ seq_printf(m, "InGoodOctets: %12llu\t"
23385+ "OutOctets: %12llu\t"
23386+ "64 Octets: %12llu\n",
23387+ cvm_oct_stats_read_switch(dev, 0x1b,
23388+ 0x00) |
23389+ (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32),
23390+ cvm_oct_stats_read_switch(dev, 0x1b,
23391+ 0x0E) |
23392+ (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32),
23393+ cvm_oct_stats_read_switch(dev, 0x1b, 0x08));
23394+
23395+ seq_printf(m, "InBadOctets: %12llu\t"
23396+ "OutUnicast: %12llu\t"
23397+ "65-127 Octets: %12llu\n",
23398+ cvm_oct_stats_read_switch(dev, 0x1b, 0x02),
23399+ cvm_oct_stats_read_switch(dev, 0x1b, 0x10),
23400+ cvm_oct_stats_read_switch(dev, 0x1b, 0x09));
23401+
23402+ seq_printf(m, "InUnicast: %12llu\t"
23403+ "OutBroadcasts: %12llu\t"
23404+ "128-255 Octets: %12llu\n",
23405+ cvm_oct_stats_read_switch(dev, 0x1b, 0x04),
23406+ cvm_oct_stats_read_switch(dev, 0x1b, 0x13),
23407+ cvm_oct_stats_read_switch(dev, 0x1b, 0x0A));
23408+
23409+ seq_printf(m, "InBroadcasts: %12llu\t"
23410+ "OutMulticasts: %12llu\t"
23411+ "256-511 Octets: %12llu\n",
23412+ cvm_oct_stats_read_switch(dev, 0x1b, 0x06),
23413+ cvm_oct_stats_read_switch(dev, 0x1b, 0x12),
23414+ cvm_oct_stats_read_switch(dev, 0x1b, 0x0B));
23415+
23416+ seq_printf(m, "InMulticasts: %12llu\t"
23417+ "OutPause: %12llu\t"
23418+ "512-1023 Octets:%12llu\n",
23419+ cvm_oct_stats_read_switch(dev, 0x1b, 0x07),
23420+ cvm_oct_stats_read_switch(dev, 0x1b, 0x15),
23421+ cvm_oct_stats_read_switch(dev, 0x1b, 0x0C));
23422+
23423+ seq_printf(m, "InPause: %12llu\t"
23424+ "Excessive: %12llu\t"
23425+ "1024-Max Octets:%12llu\n",
23426+ cvm_oct_stats_read_switch(dev, 0x1b, 0x16),
23427+ cvm_oct_stats_read_switch(dev, 0x1b, 0x11),
23428+ cvm_oct_stats_read_switch(dev, 0x1b, 0x0D));
23429+
23430+ seq_printf(m, "InUndersize: %12llu\t"
23431+ "Collisions: %12llu\n",
23432+ cvm_oct_stats_read_switch(dev, 0x1b, 0x18),
23433+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1E));
23434+
23435+ seq_printf(m, "InFragments: %12llu\t"
23436+ "Deferred: %12llu\n",
23437+ cvm_oct_stats_read_switch(dev, 0x1b, 0x19),
23438+ cvm_oct_stats_read_switch(dev, 0x1b, 0x05));
23439+
23440+ seq_printf(m, "InOversize: %12llu\t"
23441+ "Single: %12llu\n",
23442+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1A),
23443+ cvm_oct_stats_read_switch(dev, 0x1b, 0x14));
23444+
23445+ seq_printf(m, "InJabber: %12llu\t"
23446+ "Multiple: %12llu\n",
23447+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1B),
23448+ cvm_oct_stats_read_switch(dev, 0x1b, 0x17));
23449+
23450+ seq_printf(m, "In RxErr: %12llu\t"
23451+ "OutFCSErr: %12llu\n",
23452+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1C),
23453+ cvm_oct_stats_read_switch(dev, 0x1b, 0x03));
23454+
23455+ seq_printf(m, "InFCSErr: %12llu\t"
23456+ "Late: %12llu\n",
23457+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1D),
23458+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1F));
23459+ index++;
23460+ }
23461+ return 0;
23462+}
23463+
23464+/**
23465+ * User is reading /proc/octeon_ethernet_stats
23466+ *
23467+ * @m:
23468+ * @v:
23469+ * Returns
23470+ */
23471+static int cvm_oct_stats_show(struct seq_file *m, void *v)
23472+{
23473+ struct octeon_ethernet *priv;
23474+ int port;
23475+
23476+ for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
23477+
23478+ if (cvm_oct_device[port]) {
23479+ priv = netdev_priv(cvm_oct_device[port]);
23480+
23481+ seq_printf(m, "\nOcteon Port %d (%s)\n", port,
23482+ cvm_oct_device[port]->name);
23483+ seq_printf(m,
23484+ "rx_packets: %12lu\t"
23485+ "tx_packets: %12lu\n",
23486+ priv->stats.rx_packets,
23487+ priv->stats.tx_packets);
23488+ seq_printf(m,
23489+ "rx_bytes: %12lu\t"
23490+ "tx_bytes: %12lu\n",
23491+ priv->stats.rx_bytes, priv->stats.tx_bytes);
23492+ seq_printf(m,
23493+ "rx_errors: %12lu\t"
23494+ "tx_errors: %12lu\n",
23495+ priv->stats.rx_errors,
23496+ priv->stats.tx_errors);
23497+ seq_printf(m,
23498+ "rx_dropped: %12lu\t"
23499+ "tx_dropped: %12lu\n",
23500+ priv->stats.rx_dropped,
23501+ priv->stats.tx_dropped);
23502+ seq_printf(m,
23503+ "rx_length_errors: %12lu\t"
23504+ "tx_aborted_errors: %12lu\n",
23505+ priv->stats.rx_length_errors,
23506+ priv->stats.tx_aborted_errors);
23507+ seq_printf(m,
23508+ "rx_over_errors: %12lu\t"
23509+ "tx_carrier_errors: %12lu\n",
23510+ priv->stats.rx_over_errors,
23511+ priv->stats.tx_carrier_errors);
23512+ seq_printf(m,
23513+ "rx_crc_errors: %12lu\t"
23514+ "tx_fifo_errors: %12lu\n",
23515+ priv->stats.rx_crc_errors,
23516+ priv->stats.tx_fifo_errors);
23517+ seq_printf(m,
23518+ "rx_frame_errors: %12lu\t"
23519+ "tx_heartbeat_errors: %12lu\n",
23520+ priv->stats.rx_frame_errors,
23521+ priv->stats.tx_heartbeat_errors);
23522+ seq_printf(m,
23523+ "rx_fifo_errors: %12lu\t"
23524+ "tx_window_errors: %12lu\n",
23525+ priv->stats.rx_fifo_errors,
23526+ priv->stats.tx_window_errors);
23527+ seq_printf(m,
23528+ "rx_missed_errors: %12lu\t"
23529+ "multicast: %12lu\n",
23530+ priv->stats.rx_missed_errors,
23531+ priv->stats.multicast);
23532+ }
23533+ }
23534+
23535+ if (cvm_oct_device[0]) {
23536+ priv = netdev_priv(cvm_oct_device[0]);
23537+ if (priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23538+ cvm_oct_stats_switch_show(m, v);
23539+ }
23540+ return 0;
23541+}
23542+
23543+/**
23544+ * /proc/octeon_ethernet_stats was openned. Use the single_open iterator
23545+ *
23546+ * @inode:
23547+ * @file:
23548+ * Returns
23549+ */
23550+static int cvm_oct_stats_open(struct inode *inode, struct file *file)
23551+{
23552+ return single_open(file, cvm_oct_stats_show, NULL);
23553+}
23554+
23555+static const struct file_operations cvm_oct_stats_operations = {
23556+ .open = cvm_oct_stats_open,
23557+ .read = seq_read,
23558+ .llseek = seq_lseek,
23559+ .release = single_release,
23560+};
23561+
23562+void cvm_oct_proc_initialize(void)
23563+{
23564+ struct proc_dir_entry *entry =
23565+ create_proc_entry("octeon_ethernet_stats", 0, NULL);
23566+ if (entry)
23567+ entry->proc_fops = &cvm_oct_stats_operations;
23568+}
23569+
23570+void cvm_oct_proc_shutdown(void)
23571+{
23572+ remove_proc_entry("octeon_ethernet_stats", NULL);
23573+}
23574--- /dev/null
23575+++ b/drivers/staging/octeon/ethernet-proc.h
23576@@ -0,0 +1,29 @@
23577+/*********************************************************************
23578+ * Author: Cavium Networks
23579+ *
23580+ * Contact: support@caviumnetworks.com
23581+ * This file is part of the OCTEON SDK
23582+ *
23583+ * Copyright (c) 2003-2007 Cavium Networks
23584+ *
23585+ * This file is free software; you can redistribute it and/or modify
23586+ * it under the terms of the GNU General Public License, Version 2, as
23587+ * published by the Free Software Foundation.
23588+ *
23589+ * This file is distributed in the hope that it will be useful, but
23590+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23591+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23592+ * NONINFRINGEMENT. See the GNU General Public License for more
23593+ * details.
23594+ *
23595+ * You should have received a copy of the GNU General Public License
23596+ * along with this file; if not, write to the Free Software
23597+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23598+ * or visit http://www.gnu.org/licenses/.
23599+ *
23600+ * This file may also be available under a different license from Cavium.
23601+ * Contact Cavium Networks for more information
23602+*********************************************************************/
23603+
23604+void cvm_oct_proc_initialize(void);
23605+void cvm_oct_proc_shutdown(void);
23606--- /dev/null
23607+++ b/drivers/staging/octeon/ethernet-rgmii.c
23608@@ -0,0 +1,397 @@
23609+/*********************************************************************
23610+ * Author: Cavium Networks
23611+ *
23612+ * Contact: support@caviumnetworks.com
23613+ * This file is part of the OCTEON SDK
23614+ *
23615+ * Copyright (c) 2003-2007 Cavium Networks
23616+ *
23617+ * This file is free software; you can redistribute it and/or modify
23618+ * it under the terms of the GNU General Public License, Version 2, as
23619+ * published by the Free Software Foundation.
23620+ *
23621+ * This file is distributed in the hope that it will be useful, but
23622+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23623+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23624+ * NONINFRINGEMENT. See the GNU General Public License for more
23625+ * details.
23626+ *
23627+ * You should have received a copy of the GNU General Public License
23628+ * along with this file; if not, write to the Free Software
23629+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23630+ * or visit http://www.gnu.org/licenses/.
23631+ *
23632+ * This file may also be available under a different license from Cavium.
23633+ * Contact Cavium Networks for more information
23634+**********************************************************************/
23635+#include <linux/kernel.h>
23636+#include <linux/netdevice.h>
23637+#include <linux/mii.h>
23638+#include <net/dst.h>
23639+
23640+#include <asm/octeon/octeon.h>
23641+
23642+#include "ethernet-defines.h"
23643+#include "octeon-ethernet.h"
23644+#include "ethernet-common.h"
23645+#include "ethernet-util.h"
23646+
23647+#include "cvmx-helper.h"
23648+
23649+#include <asm/octeon/cvmx-ipd-defs.h>
23650+#include <asm/octeon/cvmx-npi-defs.h>
23651+#include "cvmx-gmxx-defs.h"
23652+
23653+DEFINE_SPINLOCK(global_register_lock);
23654+
23655+static int number_rgmii_ports;
23656+
23657+static void cvm_oct_rgmii_poll(struct net_device *dev)
23658+{
23659+ struct octeon_ethernet *priv = netdev_priv(dev);
23660+ unsigned long flags;
23661+ cvmx_helper_link_info_t link_info;
23662+
23663+ /*
23664+ * Take the global register lock since we are going to touch
23665+ * registers that affect more than one port.
23666+ */
23667+ spin_lock_irqsave(&global_register_lock, flags);
23668+
23669+ link_info = cvmx_helper_link_get(priv->port);
23670+ if (link_info.u64 == priv->link_info) {
23671+
23672+ /*
23673+ * If the 10Mbps preamble workaround is supported and we're
23674+ * at 10Mbps we may need to do some special checking.
23675+ */
23676+ if (USE_10MBPS_PREAMBLE_WORKAROUND && (link_info.s.speed == 10)) {
23677+
23678+ /*
23679+ * Read the GMXX_RXX_INT_REG[PCTERR] bit and
23680+ * see if we are getting preamble errors.
23681+ */
23682+ int interface = INTERFACE(priv->port);
23683+ int index = INDEX(priv->port);
23684+ union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
23685+ gmxx_rxx_int_reg.u64 =
23686+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
23687+ (index, interface));
23688+ if (gmxx_rxx_int_reg.s.pcterr) {
23689+
23690+ /*
23691+ * We are getting preamble errors at
23692+ * 10Mbps. Most likely the PHY is
23693+ * giving us packets with mis aligned
23694+ * preambles. In order to get these
23695+ * packets we need to disable preamble
23696+ * checking and do it in software.
23697+ */
23698+ union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
23699+ union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
23700+
23701+ /* Disable preamble checking */
23702+ gmxx_rxx_frm_ctl.u64 =
23703+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
23704+ (index, interface));
23705+ gmxx_rxx_frm_ctl.s.pre_chk = 0;
23706+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL
23707+ (index, interface),
23708+ gmxx_rxx_frm_ctl.u64);
23709+
23710+ /* Disable FCS stripping */
23711+ ipd_sub_port_fcs.u64 =
23712+ cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
23713+ ipd_sub_port_fcs.s.port_bit &=
23714+ 0xffffffffull ^ (1ull << priv->port);
23715+ cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS,
23716+ ipd_sub_port_fcs.u64);
23717+
23718+ /* Clear any error bits */
23719+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
23720+ (index, interface),
23721+ gmxx_rxx_int_reg.u64);
23722+ DEBUGPRINT("%s: Using 10Mbps with software "
23723+ "preamble removal\n",
23724+ dev->name);
23725+ }
23726+ }
23727+ spin_unlock_irqrestore(&global_register_lock, flags);
23728+ return;
23729+ }
23730+
23731+ /* If the 10Mbps preamble workaround is allowed we need to on
23732+ preamble checking, FCS stripping, and clear error bits on
23733+ every speed change. If errors occur during 10Mbps operation
23734+ the above code will change this stuff */
23735+ if (USE_10MBPS_PREAMBLE_WORKAROUND) {
23736+
23737+ union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
23738+ union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
23739+ union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
23740+ int interface = INTERFACE(priv->port);
23741+ int index = INDEX(priv->port);
23742+
23743+ /* Enable preamble checking */
23744+ gmxx_rxx_frm_ctl.u64 =
23745+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
23746+ gmxx_rxx_frm_ctl.s.pre_chk = 1;
23747+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface),
23748+ gmxx_rxx_frm_ctl.u64);
23749+ /* Enable FCS stripping */
23750+ ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
23751+ ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port;
23752+ cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
23753+ /* Clear any error bits */
23754+ gmxx_rxx_int_reg.u64 =
23755+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, interface));
23756+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface),
23757+ gmxx_rxx_int_reg.u64);
23758+ }
23759+
23760+ link_info = cvmx_helper_link_autoconf(priv->port);
23761+ priv->link_info = link_info.u64;
23762+ spin_unlock_irqrestore(&global_register_lock, flags);
23763+
23764+ /* Tell Linux */
23765+ if (link_info.s.link_up) {
23766+
23767+ if (!netif_carrier_ok(dev))
23768+ netif_carrier_on(dev);
23769+ if (priv->queue != -1)
23770+ DEBUGPRINT
23771+ ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
23772+ dev->name, link_info.s.speed,
23773+ (link_info.s.full_duplex) ? "Full" : "Half",
23774+ priv->port, priv->queue);
23775+ else
23776+ DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
23777+ dev->name, link_info.s.speed,
23778+ (link_info.s.full_duplex) ? "Full" : "Half",
23779+ priv->port);
23780+ } else {
23781+
23782+ if (netif_carrier_ok(dev))
23783+ netif_carrier_off(dev);
23784+ DEBUGPRINT("%s: Link down\n", dev->name);
23785+ }
23786+}
23787+
23788+static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id)
23789+{
23790+ union cvmx_npi_rsl_int_blocks rsl_int_blocks;
23791+ int index;
23792+ irqreturn_t return_status = IRQ_NONE;
23793+
23794+ rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
23795+
23796+ /* Check and see if this interrupt was caused by the GMX0 block */
23797+ if (rsl_int_blocks.s.gmx0) {
23798+
23799+ int interface = 0;
23800+ /* Loop through every port of this interface */
23801+ for (index = 0;
23802+ index < cvmx_helper_ports_on_interface(interface);
23803+ index++) {
23804+
23805+ /* Read the GMX interrupt status bits */
23806+ union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
23807+ gmx_rx_int_reg.u64 =
23808+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
23809+ (index, interface));
23810+ gmx_rx_int_reg.u64 &=
23811+ cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
23812+ (index, interface));
23813+ /* Poll the port if inband status changed */
23814+ if (gmx_rx_int_reg.s.phy_dupx
23815+ || gmx_rx_int_reg.s.phy_link
23816+ || gmx_rx_int_reg.s.phy_spd) {
23817+
23818+ struct net_device *dev =
23819+ cvm_oct_device[cvmx_helper_get_ipd_port
23820+ (interface, index)];
23821+ if (dev)
23822+ cvm_oct_rgmii_poll(dev);
23823+ gmx_rx_int_reg.u64 = 0;
23824+ gmx_rx_int_reg.s.phy_dupx = 1;
23825+ gmx_rx_int_reg.s.phy_link = 1;
23826+ gmx_rx_int_reg.s.phy_spd = 1;
23827+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
23828+ (index, interface),
23829+ gmx_rx_int_reg.u64);
23830+ return_status = IRQ_HANDLED;
23831+ }
23832+ }
23833+ }
23834+
23835+ /* Check and see if this interrupt was caused by the GMX1 block */
23836+ if (rsl_int_blocks.s.gmx1) {
23837+
23838+ int interface = 1;
23839+ /* Loop through every port of this interface */
23840+ for (index = 0;
23841+ index < cvmx_helper_ports_on_interface(interface);
23842+ index++) {
23843+
23844+ /* Read the GMX interrupt status bits */
23845+ union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
23846+ gmx_rx_int_reg.u64 =
23847+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
23848+ (index, interface));
23849+ gmx_rx_int_reg.u64 &=
23850+ cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
23851+ (index, interface));
23852+ /* Poll the port if inband status changed */
23853+ if (gmx_rx_int_reg.s.phy_dupx
23854+ || gmx_rx_int_reg.s.phy_link
23855+ || gmx_rx_int_reg.s.phy_spd) {
23856+
23857+ struct net_device *dev =
23858+ cvm_oct_device[cvmx_helper_get_ipd_port
23859+ (interface, index)];
23860+ if (dev)
23861+ cvm_oct_rgmii_poll(dev);
23862+ gmx_rx_int_reg.u64 = 0;
23863+ gmx_rx_int_reg.s.phy_dupx = 1;
23864+ gmx_rx_int_reg.s.phy_link = 1;
23865+ gmx_rx_int_reg.s.phy_spd = 1;
23866+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
23867+ (index, interface),
23868+ gmx_rx_int_reg.u64);
23869+ return_status = IRQ_HANDLED;
23870+ }
23871+ }
23872+ }
23873+ return return_status;
23874+}
23875+
23876+static int cvm_oct_rgmii_open(struct net_device *dev)
23877+{
23878+ union cvmx_gmxx_prtx_cfg gmx_cfg;
23879+ struct octeon_ethernet *priv = netdev_priv(dev);
23880+ int interface = INTERFACE(priv->port);
23881+ int index = INDEX(priv->port);
23882+ cvmx_helper_link_info_t link_info;
23883+
23884+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
23885+ gmx_cfg.s.en = 1;
23886+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
23887+
23888+ if (!octeon_is_simulation()) {
23889+ link_info = cvmx_helper_link_get(priv->port);
23890+ if (!link_info.s.link_up)
23891+ netif_carrier_off(dev);
23892+ }
23893+
23894+ return 0;
23895+}
23896+
23897+static int cvm_oct_rgmii_stop(struct net_device *dev)
23898+{
23899+ union cvmx_gmxx_prtx_cfg gmx_cfg;
23900+ struct octeon_ethernet *priv = netdev_priv(dev);
23901+ int interface = INTERFACE(priv->port);
23902+ int index = INDEX(priv->port);
23903+
23904+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
23905+ gmx_cfg.s.en = 0;
23906+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
23907+ return 0;
23908+}
23909+
23910+int cvm_oct_rgmii_init(struct net_device *dev)
23911+{
23912+ struct octeon_ethernet *priv = netdev_priv(dev);
23913+ int r;
23914+
23915+ cvm_oct_common_init(dev);
23916+ dev->open = cvm_oct_rgmii_open;
23917+ dev->stop = cvm_oct_rgmii_stop;
23918+ dev->stop(dev);
23919+
23920+ /*
23921+ * Due to GMX errata in CN3XXX series chips, it is necessary
23922+ * to take the link down immediately whne the PHY changes
23923+ * state. In order to do this we call the poll function every
23924+ * time the RGMII inband status changes. This may cause
23925+ * problems if the PHY doesn't implement inband status
23926+ * properly.
23927+ */
23928+ if (number_rgmii_ports == 0) {
23929+ r = request_irq(OCTEON_IRQ_RML, cvm_oct_rgmii_rml_interrupt,
23930+ IRQF_SHARED, "RGMII", &number_rgmii_ports);
23931+ }
23932+ number_rgmii_ports++;
23933+
23934+ /*
23935+ * Only true RGMII ports need to be polled. In GMII mode, port
23936+ * 0 is really a RGMII port.
23937+ */
23938+ if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23939+ && (priv->port == 0))
23940+ || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
23941+
23942+ if (!octeon_is_simulation()) {
23943+
23944+ union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
23945+ int interface = INTERFACE(priv->port);
23946+ int index = INDEX(priv->port);
23947+
23948+ /*
23949+ * Enable interrupts on inband status changes
23950+ * for this port.
23951+ */
23952+ gmx_rx_int_en.u64 =
23953+ cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
23954+ (index, interface));
23955+ gmx_rx_int_en.s.phy_dupx = 1;
23956+ gmx_rx_int_en.s.phy_link = 1;
23957+ gmx_rx_int_en.s.phy_spd = 1;
23958+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
23959+ gmx_rx_int_en.u64);
23960+ priv->poll = cvm_oct_rgmii_poll;
23961+ }
23962+ }
23963+
23964+ return 0;
23965+}
23966+
23967+void cvm_oct_rgmii_uninit(struct net_device *dev)
23968+{
23969+ struct octeon_ethernet *priv = netdev_priv(dev);
23970+ cvm_oct_common_uninit(dev);
23971+
23972+ /*
23973+ * Only true RGMII ports need to be polled. In GMII mode, port
23974+ * 0 is really a RGMII port.
23975+ */
23976+ if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23977+ && (priv->port == 0))
23978+ || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
23979+
23980+ if (!octeon_is_simulation()) {
23981+
23982+ union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
23983+ int interface = INTERFACE(priv->port);
23984+ int index = INDEX(priv->port);
23985+
23986+ /*
23987+ * Disable interrupts on inband status changes
23988+ * for this port.
23989+ */
23990+ gmx_rx_int_en.u64 =
23991+ cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
23992+ (index, interface));
23993+ gmx_rx_int_en.s.phy_dupx = 0;
23994+ gmx_rx_int_en.s.phy_link = 0;
23995+ gmx_rx_int_en.s.phy_spd = 0;
23996+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
23997+ gmx_rx_int_en.u64);
23998+ }
23999+ }
24000+
24001+ /* Remove the interrupt handler when the last port is removed. */
24002+ number_rgmii_ports--;
24003+ if (number_rgmii_ports == 0)
24004+ free_irq(OCTEON_IRQ_RML, &number_rgmii_ports);
24005+}
24006--- /dev/null
24007+++ b/drivers/staging/octeon/ethernet-rx.c
24008@@ -0,0 +1,505 @@
24009+/**********************************************************************
24010+ * Author: Cavium Networks
24011+ *
24012+ * Contact: support@caviumnetworks.com
24013+ * This file is part of the OCTEON SDK
24014+ *
24015+ * Copyright (c) 2003-2007 Cavium Networks
24016+ *
24017+ * This file is free software; you can redistribute it and/or modify
24018+ * it under the terms of the GNU General Public License, Version 2, as
24019+ * published by the Free Software Foundation.
24020+ *
24021+ * This file is distributed in the hope that it will be useful, but
24022+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24023+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24024+ * NONINFRINGEMENT. See the GNU General Public License for more
24025+ * details.
24026+ *
24027+ * You should have received a copy of the GNU General Public License
24028+ * along with this file; if not, write to the Free Software
24029+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24030+ * or visit http://www.gnu.org/licenses/.
24031+ *
24032+ * This file may also be available under a different license from Cavium.
24033+ * Contact Cavium Networks for more information
24034+**********************************************************************/
24035+#include <linux/module.h>
24036+#include <linux/kernel.h>
24037+#include <linux/cache.h>
24038+#include <linux/netdevice.h>
24039+#include <linux/init.h>
24040+#include <linux/etherdevice.h>
24041+#include <linux/ip.h>
24042+#include <linux/string.h>
24043+#include <linux/prefetch.h>
24044+#include <linux/ethtool.h>
24045+#include <linux/mii.h>
24046+#include <linux/seq_file.h>
24047+#include <linux/proc_fs.h>
24048+#include <net/dst.h>
24049+#ifdef CONFIG_XFRM
24050+#include <linux/xfrm.h>
24051+#include <net/xfrm.h>
24052+#endif /* CONFIG_XFRM */
24053+
24054+#include <asm/atomic.h>
24055+
24056+#include <asm/octeon/octeon.h>
24057+
24058+#include "ethernet-defines.h"
24059+#include "octeon-ethernet.h"
24060+#include "ethernet-mem.h"
24061+#include "ethernet-util.h"
24062+
24063+#include "cvmx-helper.h"
24064+#include "cvmx-wqe.h"
24065+#include "cvmx-fau.h"
24066+#include "cvmx-pow.h"
24067+#include "cvmx-pip.h"
24068+#include "cvmx-scratch.h"
24069+
24070+#include "cvmx-gmxx-defs.h"
24071+
24072+struct cvm_tasklet_wrapper {
24073+ struct tasklet_struct t;
24074+};
24075+
24076+/*
24077+ * Aligning the tasklet_struct on cachline boundries seems to decrease
24078+ * throughput even though in theory it would reduce contantion on the
24079+ * cache lines containing the locks.
24080+ */
24081+
24082+static struct cvm_tasklet_wrapper cvm_oct_tasklet[NR_CPUS];
24083+
24084+/**
24085+ * Interrupt handler. The interrupt occurs whenever the POW
24086+ * transitions from 0->1 packets in our group.
24087+ *
24088+ * @cpl:
24089+ * @dev_id:
24090+ * @regs:
24091+ * Returns
24092+ */
24093+irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
24094+{
24095+ /* Acknowledge the interrupt */
24096+ if (INTERRUPT_LIMIT)
24097+ cvmx_write_csr(CVMX_POW_WQ_INT, 1 << pow_receive_group);
24098+ else
24099+ cvmx_write_csr(CVMX_POW_WQ_INT, 0x10001 << pow_receive_group);
24100+ preempt_disable();
24101+ tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
24102+ preempt_enable();
24103+ return IRQ_HANDLED;
24104+}
24105+
24106+#ifdef CONFIG_NET_POLL_CONTROLLER
24107+/**
24108+ * This is called when the kernel needs to manually poll the
24109+ * device. For Octeon, this is simply calling the interrupt
24110+ * handler. We actually poll all the devices, not just the
24111+ * one supplied.
24112+ *
24113+ * @dev: Device to poll. Unused
24114+ */
24115+void cvm_oct_poll_controller(struct net_device *dev)
24116+{
24117+ preempt_disable();
24118+ tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
24119+ preempt_enable();
24120+}
24121+#endif
24122+
24123+/**
24124+ * This is called on receive errors, and determines if the packet
24125+ * can be dropped early-on in cvm_oct_tasklet_rx().
24126+ *
24127+ * @work: Work queue entry pointing to the packet.
24128+ * Returns Non-zero if the packet can be dropped, zero otherwise.
24129+ */
24130+static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
24131+{
24132+ if ((work->word2.snoip.err_code == 10) && (work->len <= 64)) {
24133+ /*
24134+ * Ignore length errors on min size packets. Some
24135+ * equipment incorrectly pads packets to 64+4FCS
24136+ * instead of 60+4FCS. Note these packets still get
24137+ * counted as frame errors.
24138+ */
24139+ } else
24140+ if (USE_10MBPS_PREAMBLE_WORKAROUND
24141+ && ((work->word2.snoip.err_code == 5)
24142+ || (work->word2.snoip.err_code == 7))) {
24143+
24144+ /*
24145+ * We received a packet with either an alignment error
24146+ * or a FCS error. This may be signalling that we are
24147+ * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK}
24148+ * off. If this is the case we need to parse the
24149+ * packet to determine if we can remove a non spec
24150+ * preamble and generate a correct packet.
24151+ */
24152+ int interface = cvmx_helper_get_interface_num(work->ipprt);
24153+ int index = cvmx_helper_get_interface_index_num(work->ipprt);
24154+ union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
24155+ gmxx_rxx_frm_ctl.u64 =
24156+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
24157+ if (gmxx_rxx_frm_ctl.s.pre_chk == 0) {
24158+
24159+ uint8_t *ptr =
24160+ cvmx_phys_to_ptr(work->packet_ptr.s.addr);
24161+ int i = 0;
24162+
24163+ while (i < work->len - 1) {
24164+ if (*ptr != 0x55)
24165+ break;
24166+ ptr++;
24167+ i++;
24168+ }
24169+
24170+ if (*ptr == 0xd5) {
24171+ /*
24172+ DEBUGPRINT("Port %d received 0xd5 preamble\n", work->ipprt);
24173+ */
24174+ work->packet_ptr.s.addr += i + 1;
24175+ work->len -= i + 5;
24176+ } else if ((*ptr & 0xf) == 0xd) {
24177+ /*
24178+ DEBUGPRINT("Port %d received 0x?d preamble\n", work->ipprt);
24179+ */
24180+ work->packet_ptr.s.addr += i;
24181+ work->len -= i + 4;
24182+ for (i = 0; i < work->len; i++) {
24183+ *ptr =
24184+ ((*ptr & 0xf0) >> 4) |
24185+ ((*(ptr + 1) & 0xf) << 4);
24186+ ptr++;
24187+ }
24188+ } else {
24189+ DEBUGPRINT("Port %d unknown preamble, packet "
24190+ "dropped\n",
24191+ work->ipprt);
24192+ /*
24193+ cvmx_helper_dump_packet(work);
24194+ */
24195+ cvm_oct_free_work(work);
24196+ return 1;
24197+ }
24198+ }
24199+ } else {
24200+ DEBUGPRINT("Port %d receive error code %d, packet dropped\n",
24201+ work->ipprt, work->word2.snoip.err_code);
24202+ cvm_oct_free_work(work);
24203+ return 1;
24204+ }
24205+
24206+ return 0;
24207+}
24208+
24209+/**
24210+ * Tasklet function that is scheduled on a core when an interrupt occurs.
24211+ *
24212+ * @unused:
24213+ */
24214+void cvm_oct_tasklet_rx(unsigned long unused)
24215+{
24216+ const int coreid = cvmx_get_core_num();
24217+ uint64_t old_group_mask;
24218+ uint64_t old_scratch;
24219+ int rx_count = 0;
24220+ int number_to_free;
24221+ int num_freed;
24222+ int packet_not_copied;
24223+
24224+ /* Prefetch cvm_oct_device since we know we need it soon */
24225+ prefetch(cvm_oct_device);
24226+
24227+ if (USE_ASYNC_IOBDMA) {
24228+ /* Save scratch in case userspace is using it */
24229+ CVMX_SYNCIOBDMA;
24230+ old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
24231+ }
24232+
24233+ /* Only allow work for our group (and preserve priorities) */
24234+ old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));
24235+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
24236+ (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group);
24237+
24238+ if (USE_ASYNC_IOBDMA)
24239+ cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
24240+
24241+ while (1) {
24242+ struct sk_buff *skb = NULL;
24243+ int skb_in_hw;
24244+ cvmx_wqe_t *work;
24245+
24246+ if (USE_ASYNC_IOBDMA) {
24247+ work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);
24248+ } else {
24249+ if ((INTERRUPT_LIMIT == 0)
24250+ || likely(rx_count < MAX_RX_PACKETS))
24251+ work =
24252+ cvmx_pow_work_request_sync
24253+ (CVMX_POW_NO_WAIT);
24254+ else
24255+ work = NULL;
24256+ }
24257+ prefetch(work);
24258+ if (work == NULL)
24259+ break;
24260+
24261+ /*
24262+ * Limit each core to processing MAX_RX_PACKETS
24263+ * packets without a break. This way the RX can't
24264+ * starve the TX task.
24265+ */
24266+ if (USE_ASYNC_IOBDMA) {
24267+
24268+ if ((INTERRUPT_LIMIT == 0)
24269+ || likely(rx_count < MAX_RX_PACKETS))
24270+ cvmx_pow_work_request_async_nocheck
24271+ (CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
24272+ else {
24273+ cvmx_scratch_write64(CVMX_SCR_SCRATCH,
24274+ 0x8000000000000000ull);
24275+ cvmx_pow_tag_sw_null_nocheck();
24276+ }
24277+ }
24278+
24279+ skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1;
24280+ if (likely(skb_in_hw)) {
24281+ skb =
24282+ *(struct sk_buff
24283+ **)(cvm_oct_get_buffer_ptr(work->packet_ptr) -
24284+ sizeof(void *));
24285+ prefetch(&skb->head);
24286+ prefetch(&skb->len);
24287+ }
24288+ prefetch(cvm_oct_device[work->ipprt]);
24289+
24290+ rx_count++;
24291+ /* Immediately throw away all packets with receive errors */
24292+ if (unlikely(work->word2.snoip.rcv_error)) {
24293+ if (cvm_oct_check_rcv_error(work))
24294+ continue;
24295+ }
24296+
24297+ /*
24298+ * We can only use the zero copy path if skbuffs are
24299+ * in the FPA pool and the packet fits in a single
24300+ * buffer.
24301+ */
24302+ if (likely(skb_in_hw)) {
24303+ /*
24304+ * This calculation was changed in case the
24305+ * skb header is using a different address
24306+ * aliasing type than the buffer. It doesn't
24307+ * make any differnece now, but the new one is
24308+ * more correct.
24309+ */
24310+ skb->data =
24311+ skb->head + work->packet_ptr.s.addr -
24312+ cvmx_ptr_to_phys(skb->head);
24313+ prefetch(skb->data);
24314+ skb->len = work->len;
24315+ skb_set_tail_pointer(skb, skb->len);
24316+ packet_not_copied = 1;
24317+ } else {
24318+
24319+ /*
24320+ * We have to copy the packet. First allocate
24321+ * an skbuff for it.
24322+ */
24323+ skb = dev_alloc_skb(work->len);
24324+ if (!skb) {
24325+ DEBUGPRINT("Port %d failed to allocate "
24326+ "skbuff, packet dropped\n",
24327+ work->ipprt);
24328+ cvm_oct_free_work(work);
24329+ continue;
24330+ }
24331+
24332+ /*
24333+ * Check if we've received a packet that was
24334+ * entirely stored in the work entry. This is
24335+ * untested.
24336+ */
24337+ if (unlikely(work->word2.s.bufs == 0)) {
24338+ uint8_t *ptr = work->packet_data;
24339+
24340+ if (likely(!work->word2.s.not_IP)) {
24341+ /*
24342+ * The beginning of the packet
24343+ * moves for IP packets.
24344+ */
24345+ if (work->word2.s.is_v6)
24346+ ptr += 2;
24347+ else
24348+ ptr += 6;
24349+ }
24350+ memcpy(skb_put(skb, work->len), ptr, work->len);
24351+ /* No packet buffers to free */
24352+ } else {
24353+ int segments = work->word2.s.bufs;
24354+ union cvmx_buf_ptr segment_ptr =
24355+ work->packet_ptr;
24356+ int len = work->len;
24357+
24358+ while (segments--) {
24359+ union cvmx_buf_ptr next_ptr =
24360+ *(union cvmx_buf_ptr *)
24361+ cvmx_phys_to_ptr(segment_ptr.s.
24362+ addr - 8);
24363+ /*
24364+ * Octeon Errata PKI-100: The segment size is
24365+ * wrong. Until it is fixed, calculate the
24366+ * segment size based on the packet pool
24367+ * buffer size. When it is fixed, the
24368+ * following line should be replaced with this
24369+ * one: int segment_size =
24370+ * segment_ptr.s.size;
24371+ */
24372+ int segment_size =
24373+ CVMX_FPA_PACKET_POOL_SIZE -
24374+ (segment_ptr.s.addr -
24375+ (((segment_ptr.s.addr >> 7) -
24376+ segment_ptr.s.back) << 7));
24377+ /* Don't copy more than what is left
24378+ in the packet */
24379+ if (segment_size > len)
24380+ segment_size = len;
24381+ /* Copy the data into the packet */
24382+ memcpy(skb_put(skb, segment_size),
24383+ cvmx_phys_to_ptr(segment_ptr.s.
24384+ addr),
24385+ segment_size);
24386+ /* Reduce the amount of bytes left
24387+ to copy */
24388+ len -= segment_size;
24389+ segment_ptr = next_ptr;
24390+ }
24391+ }
24392+ packet_not_copied = 0;
24393+ }
24394+
24395+ if (likely((work->ipprt < TOTAL_NUMBER_OF_PORTS) &&
24396+ cvm_oct_device[work->ipprt])) {
24397+ struct net_device *dev = cvm_oct_device[work->ipprt];
24398+ struct octeon_ethernet *priv = netdev_priv(dev);
24399+
24400+ /* Only accept packets for devices
24401+ that are currently up */
24402+ if (likely(dev->flags & IFF_UP)) {
24403+ skb->protocol = eth_type_trans(skb, dev);
24404+ skb->dev = dev;
24405+
24406+ if (unlikely
24407+ (work->word2.s.not_IP
24408+ || work->word2.s.IP_exc
24409+ || work->word2.s.L4_error))
24410+ skb->ip_summed = CHECKSUM_NONE;
24411+ else
24412+ skb->ip_summed = CHECKSUM_UNNECESSARY;
24413+
24414+ /* Increment RX stats for virtual ports */
24415+ if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) {
24416+#ifdef CONFIG_64BIT
24417+ atomic64_add(1, (atomic64_t *)&priv->stats.rx_packets);
24418+ atomic64_add(skb->len, (atomic64_t *)&priv->stats.rx_bytes);
24419+#else
24420+ atomic_add(1, (atomic_t *)&priv->stats.rx_packets);
24421+ atomic_add(skb->len, (atomic_t *)&priv->stats.rx_bytes);
24422+#endif
24423+ }
24424+ netif_receive_skb(skb);
24425+ } else {
24426+ /*
24427+ * Drop any packet received for a
24428+ * device that isn't up.
24429+ */
24430+ /*
24431+ DEBUGPRINT("%s: Device not up, packet dropped\n",
24432+ dev->name);
24433+ */
24434+#ifdef CONFIG_64BIT
24435+ atomic64_add(1, (atomic64_t *)&priv->stats.rx_dropped);
24436+#else
24437+ atomic_add(1, (atomic_t *)&priv->stats.rx_dropped);
24438+#endif
24439+ dev_kfree_skb_irq(skb);
24440+ }
24441+ } else {
24442+ /*
24443+ * Drop any packet received for a device that
24444+ * doesn't exist.
24445+ */
24446+ DEBUGPRINT("Port %d not controlled by Linux, packet "
24447+ "dropped\n",
24448+ work->ipprt);
24449+ dev_kfree_skb_irq(skb);
24450+ }
24451+ /*
24452+ * Check to see if the skbuff and work share the same
24453+ * packet buffer.
24454+ */
24455+ if (USE_SKBUFFS_IN_HW && likely(packet_not_copied)) {
24456+ /*
24457+ * This buffer needs to be replaced, increment
24458+ * the number of buffers we need to free by
24459+ * one.
24460+ */
24461+ cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
24462+ 1);
24463+
24464+ cvmx_fpa_free(work, CVMX_FPA_WQE_POOL,
24465+ DONT_WRITEBACK(1));
24466+ } else {
24467+ cvm_oct_free_work(work);
24468+ }
24469+ }
24470+
24471+ /* Restore the original POW group mask */
24472+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask);
24473+ if (USE_ASYNC_IOBDMA) {
24474+ /* Restore the scratch area */
24475+ cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
24476+ }
24477+
24478+ if (USE_SKBUFFS_IN_HW) {
24479+ /* Refill the packet buffer pool */
24480+ number_to_free =
24481+ cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
24482+
24483+ if (number_to_free > 0) {
24484+ cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
24485+ -number_to_free);
24486+ num_freed =
24487+ cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL,
24488+ CVMX_FPA_PACKET_POOL_SIZE,
24489+ number_to_free);
24490+ if (num_freed != number_to_free) {
24491+ cvmx_fau_atomic_add32
24492+ (FAU_NUM_PACKET_BUFFERS_TO_FREE,
24493+ number_to_free - num_freed);
24494+ }
24495+ }
24496+ }
24497+}
24498+
24499+void cvm_oct_rx_initialize(void)
24500+{
24501+ int i;
24502+ /* Initialize all of the tasklets */
24503+ for (i = 0; i < NR_CPUS; i++)
24504+ tasklet_init(&cvm_oct_tasklet[i].t, cvm_oct_tasklet_rx, 0);
24505+}
24506+
24507+void cvm_oct_rx_shutdown(void)
24508+{
24509+ int i;
24510+ /* Shutdown all of the tasklets */
24511+ for (i = 0; i < NR_CPUS; i++)
24512+ tasklet_kill(&cvm_oct_tasklet[i].t);
24513+}
24514--- /dev/null
24515+++ b/drivers/staging/octeon/ethernet-rx.h
24516@@ -0,0 +1,33 @@
24517+/*********************************************************************
24518+ * Author: Cavium Networks
24519+ *
24520+ * Contact: support@caviumnetworks.com
24521+ * This file is part of the OCTEON SDK
24522+ *
24523+ * Copyright (c) 2003-2007 Cavium Networks
24524+ *
24525+ * This file is free software; you can redistribute it and/or modify
24526+ * it under the terms of the GNU General Public License, Version 2, as
24527+ * published by the Free Software Foundation.
24528+ *
24529+ * This file is distributed in the hope that it will be useful, but
24530+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24531+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24532+ * NONINFRINGEMENT. See the GNU General Public License for more
24533+ * details.
24534+ *
24535+ * You should have received a copy of the GNU General Public License
24536+ * along with this file; if not, write to the Free Software
24537+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24538+ * or visit http://www.gnu.org/licenses/.
24539+ *
24540+ * This file may also be available under a different license from Cavium.
24541+ * Contact Cavium Networks for more information
24542+*********************************************************************/
24543+
24544+irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id);
24545+void cvm_oct_poll_controller(struct net_device *dev);
24546+void cvm_oct_tasklet_rx(unsigned long unused);
24547+
24548+void cvm_oct_rx_initialize(void);
24549+void cvm_oct_rx_shutdown(void);
24550--- /dev/null
24551+++ b/drivers/staging/octeon/ethernet-sgmii.c
24552@@ -0,0 +1,129 @@
24553+/**********************************************************************
24554+ * Author: Cavium Networks
24555+ *
24556+ * Contact: support@caviumnetworks.com
24557+ * This file is part of the OCTEON SDK
24558+ *
24559+ * Copyright (c) 2003-2007 Cavium Networks
24560+ *
24561+ * This file is free software; you can redistribute it and/or modify
24562+ * it under the terms of the GNU General Public License, Version 2, as
24563+ * published by the Free Software Foundation.
24564+ *
24565+ * This file is distributed in the hope that it will be useful, but
24566+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24567+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24568+ * NONINFRINGEMENT. See the GNU General Public License for more
24569+ * details.
24570+ *
24571+ * You should have received a copy of the GNU General Public License
24572+ * along with this file; if not, write to the Free Software
24573+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24574+ * or visit http://www.gnu.org/licenses/.
24575+ *
24576+ * This file may also be available under a different license from Cavium.
24577+ * Contact Cavium Networks for more information
24578+**********************************************************************/
24579+#include <linux/kernel.h>
24580+#include <linux/netdevice.h>
24581+#include <linux/mii.h>
24582+#include <net/dst.h>
24583+
24584+#include <asm/octeon/octeon.h>
24585+
24586+#include "ethernet-defines.h"
24587+#include "octeon-ethernet.h"
24588+#include "ethernet-util.h"
24589+#include "ethernet-common.h"
24590+
24591+#include "cvmx-helper.h"
24592+
24593+#include "cvmx-gmxx-defs.h"
24594+
24595+static int cvm_oct_sgmii_open(struct net_device *dev)
24596+{
24597+ union cvmx_gmxx_prtx_cfg gmx_cfg;
24598+ struct octeon_ethernet *priv = netdev_priv(dev);
24599+ int interface = INTERFACE(priv->port);
24600+ int index = INDEX(priv->port);
24601+ cvmx_helper_link_info_t link_info;
24602+
24603+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
24604+ gmx_cfg.s.en = 1;
24605+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
24606+
24607+ if (!octeon_is_simulation()) {
24608+ link_info = cvmx_helper_link_get(priv->port);
24609+ if (!link_info.s.link_up)
24610+ netif_carrier_off(dev);
24611+ }
24612+
24613+ return 0;
24614+}
24615+
24616+static int cvm_oct_sgmii_stop(struct net_device *dev)
24617+{
24618+ union cvmx_gmxx_prtx_cfg gmx_cfg;
24619+ struct octeon_ethernet *priv = netdev_priv(dev);
24620+ int interface = INTERFACE(priv->port);
24621+ int index = INDEX(priv->port);
24622+
24623+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
24624+ gmx_cfg.s.en = 0;
24625+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
24626+ return 0;
24627+}
24628+
24629+static void cvm_oct_sgmii_poll(struct net_device *dev)
24630+{
24631+ struct octeon_ethernet *priv = netdev_priv(dev);
24632+ cvmx_helper_link_info_t link_info;
24633+
24634+ link_info = cvmx_helper_link_get(priv->port);
24635+ if (link_info.u64 == priv->link_info)
24636+ return;
24637+
24638+ link_info = cvmx_helper_link_autoconf(priv->port);
24639+ priv->link_info = link_info.u64;
24640+
24641+ /* Tell Linux */
24642+ if (link_info.s.link_up) {
24643+
24644+ if (!netif_carrier_ok(dev))
24645+ netif_carrier_on(dev);
24646+ if (priv->queue != -1)
24647+ DEBUGPRINT
24648+ ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
24649+ dev->name, link_info.s.speed,
24650+ (link_info.s.full_duplex) ? "Full" : "Half",
24651+ priv->port, priv->queue);
24652+ else
24653+ DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
24654+ dev->name, link_info.s.speed,
24655+ (link_info.s.full_duplex) ? "Full" : "Half",
24656+ priv->port);
24657+ } else {
24658+ if (netif_carrier_ok(dev))
24659+ netif_carrier_off(dev);
24660+ DEBUGPRINT("%s: Link down\n", dev->name);
24661+ }
24662+}
24663+
24664+int cvm_oct_sgmii_init(struct net_device *dev)
24665+{
24666+ struct octeon_ethernet *priv = netdev_priv(dev);
24667+ cvm_oct_common_init(dev);
24668+ dev->open = cvm_oct_sgmii_open;
24669+ dev->stop = cvm_oct_sgmii_stop;
24670+ dev->stop(dev);
24671+ if (!octeon_is_simulation())
24672+ priv->poll = cvm_oct_sgmii_poll;
24673+
24674+ /* FIXME: Need autoneg logic */
24675+ return 0;
24676+}
24677+
24678+void cvm_oct_sgmii_uninit(struct net_device *dev)
24679+{
24680+ cvm_oct_common_uninit(dev);
24681+}
24682--- /dev/null
24683+++ b/drivers/staging/octeon/ethernet-spi.c
24684@@ -0,0 +1,323 @@
24685+/**********************************************************************
24686+ * Author: Cavium Networks
24687+ *
24688+ * Contact: support@caviumnetworks.com
24689+ * This file is part of the OCTEON SDK
24690+ *
24691+ * Copyright (c) 2003-2007 Cavium Networks
24692+ *
24693+ * This file is free software; you can redistribute it and/or modify
24694+ * it under the terms of the GNU General Public License, Version 2, as
24695+ * published by the Free Software Foundation.
24696+ *
24697+ * This file is distributed in the hope that it will be useful, but
24698+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24699+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24700+ * NONINFRINGEMENT. See the GNU General Public License for more
24701+ * details.
24702+ *
24703+ * You should have received a copy of the GNU General Public License
24704+ * along with this file; if not, write to the Free Software
24705+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24706+ * or visit http://www.gnu.org/licenses/.
24707+ *
24708+ * This file may also be available under a different license from Cavium.
24709+ * Contact Cavium Networks for more information
24710+**********************************************************************/
24711+#include <linux/kernel.h>
24712+#include <linux/netdevice.h>
24713+#include <linux/mii.h>
24714+#include <net/dst.h>
24715+
24716+#include <asm/octeon/octeon.h>
24717+
24718+#include "ethernet-defines.h"
24719+#include "octeon-ethernet.h"
24720+#include "ethernet-common.h"
24721+#include "ethernet-util.h"
24722+
24723+#include "cvmx-spi.h"
24724+
24725+#include <asm/octeon/cvmx-npi-defs.h>
24726+#include "cvmx-spxx-defs.h"
24727+#include "cvmx-stxx-defs.h"
24728+
24729+static int number_spi_ports;
24730+static int need_retrain[2] = { 0, 0 };
24731+
24732+static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
24733+{
24734+ irqreturn_t return_status = IRQ_NONE;
24735+ union cvmx_npi_rsl_int_blocks rsl_int_blocks;
24736+
24737+ /* Check and see if this interrupt was caused by the GMX block */
24738+ rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
24739+ if (rsl_int_blocks.s.spx1) { /* 19 - SPX1_INT_REG & STX1_INT_REG */
24740+
24741+ union cvmx_spxx_int_reg spx_int_reg;
24742+ union cvmx_stxx_int_reg stx_int_reg;
24743+
24744+ spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(1));
24745+ cvmx_write_csr(CVMX_SPXX_INT_REG(1), spx_int_reg.u64);
24746+ if (!need_retrain[1]) {
24747+
24748+ spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(1));
24749+ if (spx_int_reg.s.spf)
24750+ pr_err("SPI1: SRX Spi4 interface down\n");
24751+ if (spx_int_reg.s.calerr)
24752+ pr_err("SPI1: SRX Spi4 Calendar table "
24753+ "parity error\n");
24754+ if (spx_int_reg.s.syncerr)
24755+ pr_err("SPI1: SRX Consecutive Spi4 DIP4 "
24756+ "errors have exceeded "
24757+ "SPX_ERR_CTL[ERRCNT]\n");
24758+ if (spx_int_reg.s.diperr)
24759+ pr_err("SPI1: SRX Spi4 DIP4 error\n");
24760+ if (spx_int_reg.s.tpaovr)
24761+ pr_err("SPI1: SRX Selected port has hit "
24762+ "TPA overflow\n");
24763+ if (spx_int_reg.s.rsverr)
24764+ pr_err("SPI1: SRX Spi4 reserved control "
24765+ "word detected\n");
24766+ if (spx_int_reg.s.drwnng)
24767+ pr_err("SPI1: SRX Spi4 receive FIFO "
24768+ "drowning/overflow\n");
24769+ if (spx_int_reg.s.clserr)
24770+ pr_err("SPI1: SRX Spi4 packet closed on "
24771+ "non-16B alignment without EOP\n");
24772+ if (spx_int_reg.s.spiovr)
24773+ pr_err("SPI1: SRX Spi4 async FIFO overflow\n");
24774+ if (spx_int_reg.s.abnorm)
24775+ pr_err("SPI1: SRX Abnormal packet "
24776+ "termination (ERR bit)\n");
24777+ if (spx_int_reg.s.prtnxa)
24778+ pr_err("SPI1: SRX Port out of range\n");
24779+ }
24780+
24781+ stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(1));
24782+ cvmx_write_csr(CVMX_STXX_INT_REG(1), stx_int_reg.u64);
24783+ if (!need_retrain[1]) {
24784+
24785+ stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(1));
24786+ if (stx_int_reg.s.syncerr)
24787+ pr_err("SPI1: STX Interface encountered a "
24788+ "fatal error\n");
24789+ if (stx_int_reg.s.frmerr)
24790+ pr_err("SPI1: STX FRMCNT has exceeded "
24791+ "STX_DIP_CNT[MAXFRM]\n");
24792+ if (stx_int_reg.s.unxfrm)
24793+ pr_err("SPI1: STX Unexpected framing "
24794+ "sequence\n");
24795+ if (stx_int_reg.s.nosync)
24796+ pr_err("SPI1: STX ERRCNT has exceeded "
24797+ "STX_DIP_CNT[MAXDIP]\n");
24798+ if (stx_int_reg.s.diperr)
24799+ pr_err("SPI1: STX DIP2 error on the Spi4 "
24800+ "Status channel\n");
24801+ if (stx_int_reg.s.datovr)
24802+ pr_err("SPI1: STX Spi4 FIFO overflow error\n");
24803+ if (stx_int_reg.s.ovrbst)
24804+ pr_err("SPI1: STX Transmit packet burst "
24805+ "too big\n");
24806+ if (stx_int_reg.s.calpar1)
24807+ pr_err("SPI1: STX Calendar Table Parity "
24808+ "Error Bank1\n");
24809+ if (stx_int_reg.s.calpar0)
24810+ pr_err("SPI1: STX Calendar Table Parity "
24811+ "Error Bank0\n");
24812+ }
24813+
24814+ cvmx_write_csr(CVMX_SPXX_INT_MSK(1), 0);
24815+ cvmx_write_csr(CVMX_STXX_INT_MSK(1), 0);
24816+ need_retrain[1] = 1;
24817+ return_status = IRQ_HANDLED;
24818+ }
24819+
24820+ if (rsl_int_blocks.s.spx0) { /* 18 - SPX0_INT_REG & STX0_INT_REG */
24821+ union cvmx_spxx_int_reg spx_int_reg;
24822+ union cvmx_stxx_int_reg stx_int_reg;
24823+
24824+ spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(0));
24825+ cvmx_write_csr(CVMX_SPXX_INT_REG(0), spx_int_reg.u64);
24826+ if (!need_retrain[0]) {
24827+
24828+ spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(0));
24829+ if (spx_int_reg.s.spf)
24830+ pr_err("SPI0: SRX Spi4 interface down\n");
24831+ if (spx_int_reg.s.calerr)
24832+ pr_err("SPI0: SRX Spi4 Calendar table "
24833+ "parity error\n");
24834+ if (spx_int_reg.s.syncerr)
24835+ pr_err("SPI0: SRX Consecutive Spi4 DIP4 "
24836+ "errors have exceeded "
24837+ "SPX_ERR_CTL[ERRCNT]\n");
24838+ if (spx_int_reg.s.diperr)
24839+ pr_err("SPI0: SRX Spi4 DIP4 error\n");
24840+ if (spx_int_reg.s.tpaovr)
24841+ pr_err("SPI0: SRX Selected port has hit "
24842+ "TPA overflow\n");
24843+ if (spx_int_reg.s.rsverr)
24844+ pr_err("SPI0: SRX Spi4 reserved control "
24845+ "word detected\n");
24846+ if (spx_int_reg.s.drwnng)
24847+ pr_err("SPI0: SRX Spi4 receive FIFO "
24848+ "drowning/overflow\n");
24849+ if (spx_int_reg.s.clserr)
24850+ pr_err("SPI0: SRX Spi4 packet closed on "
24851+ "non-16B alignment without EOP\n");
24852+ if (spx_int_reg.s.spiovr)
24853+ pr_err("SPI0: SRX Spi4 async FIFO overflow\n");
24854+ if (spx_int_reg.s.abnorm)
24855+ pr_err("SPI0: SRX Abnormal packet "
24856+ "termination (ERR bit)\n");
24857+ if (spx_int_reg.s.prtnxa)
24858+ pr_err("SPI0: SRX Port out of range\n");
24859+ }
24860+
24861+ stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(0));
24862+ cvmx_write_csr(CVMX_STXX_INT_REG(0), stx_int_reg.u64);
24863+ if (!need_retrain[0]) {
24864+
24865+ stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(0));
24866+ if (stx_int_reg.s.syncerr)
24867+ pr_err("SPI0: STX Interface encountered a "
24868+ "fatal error\n");
24869+ if (stx_int_reg.s.frmerr)
24870+ pr_err("SPI0: STX FRMCNT has exceeded "
24871+ "STX_DIP_CNT[MAXFRM]\n");
24872+ if (stx_int_reg.s.unxfrm)
24873+ pr_err("SPI0: STX Unexpected framing "
24874+ "sequence\n");
24875+ if (stx_int_reg.s.nosync)
24876+ pr_err("SPI0: STX ERRCNT has exceeded "
24877+ "STX_DIP_CNT[MAXDIP]\n");
24878+ if (stx_int_reg.s.diperr)
24879+ pr_err("SPI0: STX DIP2 error on the Spi4 "
24880+ "Status channel\n");
24881+ if (stx_int_reg.s.datovr)
24882+ pr_err("SPI0: STX Spi4 FIFO overflow error\n");
24883+ if (stx_int_reg.s.ovrbst)
24884+ pr_err("SPI0: STX Transmit packet burst "
24885+ "too big\n");
24886+ if (stx_int_reg.s.calpar1)
24887+ pr_err("SPI0: STX Calendar Table Parity "
24888+ "Error Bank1\n");
24889+ if (stx_int_reg.s.calpar0)
24890+ pr_err("SPI0: STX Calendar Table Parity "
24891+ "Error Bank0\n");
24892+ }
24893+
24894+ cvmx_write_csr(CVMX_SPXX_INT_MSK(0), 0);
24895+ cvmx_write_csr(CVMX_STXX_INT_MSK(0), 0);
24896+ need_retrain[0] = 1;
24897+ return_status = IRQ_HANDLED;
24898+ }
24899+
24900+ return return_status;
24901+}
24902+
24903+static void cvm_oct_spi_enable_error_reporting(int interface)
24904+{
24905+ union cvmx_spxx_int_msk spxx_int_msk;
24906+ union cvmx_stxx_int_msk stxx_int_msk;
24907+
24908+ spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
24909+ spxx_int_msk.s.calerr = 1;
24910+ spxx_int_msk.s.syncerr = 1;
24911+ spxx_int_msk.s.diperr = 1;
24912+ spxx_int_msk.s.tpaovr = 1;
24913+ spxx_int_msk.s.rsverr = 1;
24914+ spxx_int_msk.s.drwnng = 1;
24915+ spxx_int_msk.s.clserr = 1;
24916+ spxx_int_msk.s.spiovr = 1;
24917+ spxx_int_msk.s.abnorm = 1;
24918+ spxx_int_msk.s.prtnxa = 1;
24919+ cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
24920+
24921+ stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
24922+ stxx_int_msk.s.frmerr = 1;
24923+ stxx_int_msk.s.unxfrm = 1;
24924+ stxx_int_msk.s.nosync = 1;
24925+ stxx_int_msk.s.diperr = 1;
24926+ stxx_int_msk.s.datovr = 1;
24927+ stxx_int_msk.s.ovrbst = 1;
24928+ stxx_int_msk.s.calpar1 = 1;
24929+ stxx_int_msk.s.calpar0 = 1;
24930+ cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
24931+}
24932+
24933+static void cvm_oct_spi_poll(struct net_device *dev)
24934+{
24935+ static int spi4000_port;
24936+ struct octeon_ethernet *priv = netdev_priv(dev);
24937+ int interface;
24938+
24939+ for (interface = 0; interface < 2; interface++) {
24940+
24941+ if ((priv->port == interface * 16) && need_retrain[interface]) {
24942+
24943+ if (cvmx_spi_restart_interface
24944+ (interface, CVMX_SPI_MODE_DUPLEX, 10) == 0) {
24945+ need_retrain[interface] = 0;
24946+ cvm_oct_spi_enable_error_reporting(interface);
24947+ }
24948+ }
24949+
24950+ /*
24951+ * The SPI4000 TWSI interface is very slow. In order
24952+ * not to bring the system to a crawl, we only poll a
24953+ * single port every second. This means negotiation
24954+ * speed changes take up to 10 seconds, but at least
24955+ * we don't waste absurd amounts of time waiting for
24956+ * TWSI.
24957+ */
24958+ if (priv->port == spi4000_port) {
24959+ /*
24960+ * This function does nothing if it is called on an
24961+ * interface without a SPI4000.
24962+ */
24963+ cvmx_spi4000_check_speed(interface, priv->port);
24964+ /*
24965+ * Normal ordering increments. By decrementing
24966+ * we only match once per iteration.
24967+ */
24968+ spi4000_port--;
24969+ if (spi4000_port < 0)
24970+ spi4000_port = 10;
24971+ }
24972+ }
24973+}
24974+
24975+int cvm_oct_spi_init(struct net_device *dev)
24976+{
24977+ int r;
24978+ struct octeon_ethernet *priv = netdev_priv(dev);
24979+
24980+ if (number_spi_ports == 0) {
24981+ r = request_irq(OCTEON_IRQ_RML, cvm_oct_spi_rml_interrupt,
24982+ IRQF_SHARED, "SPI", &number_spi_ports);
24983+ }
24984+ number_spi_ports++;
24985+
24986+ if ((priv->port == 0) || (priv->port == 16)) {
24987+ cvm_oct_spi_enable_error_reporting(INTERFACE(priv->port));
24988+ priv->poll = cvm_oct_spi_poll;
24989+ }
24990+ cvm_oct_common_init(dev);
24991+ return 0;
24992+}
24993+
24994+void cvm_oct_spi_uninit(struct net_device *dev)
24995+{
24996+ int interface;
24997+
24998+ cvm_oct_common_uninit(dev);
24999+ number_spi_ports--;
25000+ if (number_spi_ports == 0) {
25001+ for (interface = 0; interface < 2; interface++) {
25002+ cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
25003+ cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
25004+ }
25005+ free_irq(8 + 46, &number_spi_ports);
25006+ }
25007+}
25008--- /dev/null
25009+++ b/drivers/staging/octeon/ethernet-tx.c
25010@@ -0,0 +1,634 @@
25011+/*********************************************************************
25012+ * Author: Cavium Networks
25013+ *
25014+ * Contact: support@caviumnetworks.com
25015+ * This file is part of the OCTEON SDK
25016+ *
25017+ * Copyright (c) 2003-2007 Cavium Networks
25018+ *
25019+ * This file is free software; you can redistribute it and/or modify
25020+ * it under the terms of the GNU General Public License, Version 2, as
25021+ * published by the Free Software Foundation.
25022+ *
25023+ * This file is distributed in the hope that it will be useful, but
25024+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25025+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25026+ * NONINFRINGEMENT. See the GNU General Public License for more
25027+ * details.
25028+ *
25029+ * You should have received a copy of the GNU General Public License
25030+ * along with this file; if not, write to the Free Software
25031+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25032+ * or visit http://www.gnu.org/licenses/.
25033+ *
25034+ * This file may also be available under a different license from Cavium.
25035+ * Contact Cavium Networks for more information
25036+*********************************************************************/
25037+#include <linux/module.h>
25038+#include <linux/kernel.h>
25039+#include <linux/netdevice.h>
25040+#include <linux/init.h>
25041+#include <linux/etherdevice.h>
25042+#include <linux/ip.h>
25043+#include <linux/string.h>
25044+#include <linux/ethtool.h>
25045+#include <linux/mii.h>
25046+#include <linux/seq_file.h>
25047+#include <linux/proc_fs.h>
25048+#include <net/dst.h>
25049+#ifdef CONFIG_XFRM
25050+#include <linux/xfrm.h>
25051+#include <net/xfrm.h>
25052+#endif /* CONFIG_XFRM */
25053+
25054+#include <asm/atomic.h>
25055+
25056+#include <asm/octeon/octeon.h>
25057+
25058+#include "ethernet-defines.h"
25059+#include "octeon-ethernet.h"
25060+#include "ethernet-util.h"
25061+
25062+#include "cvmx-wqe.h"
25063+#include "cvmx-fau.h"
25064+#include "cvmx-pko.h"
25065+#include "cvmx-helper.h"
25066+
25067+#include "cvmx-gmxx-defs.h"
25068+
25069+/*
25070+ * You can define GET_SKBUFF_QOS() to override how the skbuff output
25071+ * function determines which output queue is used. The default
25072+ * implementation always uses the base queue for the port. If, for
25073+ * example, you wanted to use the skb->priority fieid, define
25074+ * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority)
25075+ */
25076+#ifndef GET_SKBUFF_QOS
25077+#define GET_SKBUFF_QOS(skb) 0
25078+#endif
25079+
25080+/**
25081+ * Packet transmit
25082+ *
25083+ * @skb: Packet to send
25084+ * @dev: Device info structure
25085+ * Returns Always returns zero
25086+ */
25087+int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
25088+{
25089+ cvmx_pko_command_word0_t pko_command;
25090+ union cvmx_buf_ptr hw_buffer;
25091+ uint64_t old_scratch;
25092+ uint64_t old_scratch2;
25093+ int dropped;
25094+ int qos;
25095+ struct octeon_ethernet *priv = netdev_priv(dev);
25096+ int32_t in_use;
25097+ int32_t buffers_to_free;
25098+#if REUSE_SKBUFFS_WITHOUT_FREE
25099+ unsigned char *fpa_head;
25100+#endif
25101+
25102+ /*
25103+ * Prefetch the private data structure. It is larger that one
25104+ * cache line.
25105+ */
25106+ prefetch(priv);
25107+
25108+ /* Start off assuming no drop */
25109+ dropped = 0;
25110+
25111+ /*
25112+ * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
25113+ * completely remove "qos" in the event neither interface
25114+ * supports multiple queues per port.
25115+ */
25116+ if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
25117+ (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
25118+ qos = GET_SKBUFF_QOS(skb);
25119+ if (qos <= 0)
25120+ qos = 0;
25121+ else if (qos >= cvmx_pko_get_num_queues(priv->port))
25122+ qos = 0;
25123+ } else
25124+ qos = 0;
25125+
25126+ if (USE_ASYNC_IOBDMA) {
25127+ /* Save scratch in case userspace is using it */
25128+ CVMX_SYNCIOBDMA;
25129+ old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
25130+ old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
25131+
25132+ /*
25133+ * Assume we're going to be able t osend this
25134+ * packet. Fetch and increment the number of pending
25135+ * packets for output.
25136+ */
25137+ cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8,
25138+ FAU_NUM_PACKET_BUFFERS_TO_FREE,
25139+ 0);
25140+ cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
25141+ priv->fau + qos * 4, 1);
25142+ }
25143+
25144+ /*
25145+ * The CN3XXX series of parts has an errata (GMX-401) which
25146+ * causes the GMX block to hang if a collision occurs towards
25147+ * the end of a <68 byte packet. As a workaround for this, we
25148+ * pad packets to be 68 bytes whenever we are in half duplex
25149+ * mode. We don't handle the case of having a small packet but
25150+ * no room to add the padding. The kernel should always give
25151+ * us at least a cache line
25152+ */
25153+ if ((skb->len < 64) && OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
25154+ union cvmx_gmxx_prtx_cfg gmx_prt_cfg;
25155+ int interface = INTERFACE(priv->port);
25156+ int index = INDEX(priv->port);
25157+
25158+ if (interface < 2) {
25159+ /* We only need to pad packet in half duplex mode */
25160+ gmx_prt_cfg.u64 =
25161+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
25162+ if (gmx_prt_cfg.s.duplex == 0) {
25163+ int add_bytes = 64 - skb->len;
25164+ if ((skb_tail_pointer(skb) + add_bytes) <=
25165+ skb_end_pointer(skb))
25166+ memset(__skb_put(skb, add_bytes), 0,
25167+ add_bytes);
25168+ }
25169+ }
25170+ }
25171+
25172+ /* Build the PKO buffer pointer */
25173+ hw_buffer.u64 = 0;
25174+ hw_buffer.s.addr = cvmx_ptr_to_phys(skb->data);
25175+ hw_buffer.s.pool = 0;
25176+ hw_buffer.s.size =
25177+ (unsigned long)skb_end_pointer(skb) - (unsigned long)skb->head;
25178+
25179+ /* Build the PKO command */
25180+ pko_command.u64 = 0;
25181+ pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */
25182+ pko_command.s.segs = 1;
25183+ pko_command.s.total_bytes = skb->len;
25184+ pko_command.s.size0 = CVMX_FAU_OP_SIZE_32;
25185+ pko_command.s.subone0 = 1;
25186+
25187+ pko_command.s.dontfree = 1;
25188+ pko_command.s.reg0 = priv->fau + qos * 4;
25189+ /*
25190+ * See if we can put this skb in the FPA pool. Any strange
25191+ * behavior from the Linux networking stack will most likely
25192+ * be caused by a bug in the following code. If some field is
25193+ * in use by the network stack and get carried over when a
25194+ * buffer is reused, bad thing may happen. If in doubt and
25195+ * you dont need the absolute best performance, disable the
25196+ * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has
25197+ * shown a 25% increase in performance under some loads.
25198+ */
25199+#if REUSE_SKBUFFS_WITHOUT_FREE
25200+ fpa_head = skb->head + 128 - ((unsigned long)skb->head & 0x7f);
25201+ if (unlikely(skb->data < fpa_head)) {
25202+ /*
25203+ * printk("TX buffer beginning can't meet FPA
25204+ * alignment constraints\n");
25205+ */
25206+ goto dont_put_skbuff_in_hw;
25207+ }
25208+ if (unlikely
25209+ ((skb_end_pointer(skb) - fpa_head) < CVMX_FPA_PACKET_POOL_SIZE)) {
25210+ /*
25211+ printk("TX buffer isn't large enough for the FPA\n");
25212+ */
25213+ goto dont_put_skbuff_in_hw;
25214+ }
25215+ if (unlikely(skb_shared(skb))) {
25216+ /*
25217+ printk("TX buffer sharing data with someone else\n");
25218+ */
25219+ goto dont_put_skbuff_in_hw;
25220+ }
25221+ if (unlikely(skb_cloned(skb))) {
25222+ /*
25223+ printk("TX buffer has been cloned\n");
25224+ */
25225+ goto dont_put_skbuff_in_hw;
25226+ }
25227+ if (unlikely(skb_header_cloned(skb))) {
25228+ /*
25229+ printk("TX buffer header has been cloned\n");
25230+ */
25231+ goto dont_put_skbuff_in_hw;
25232+ }
25233+ if (unlikely(skb->destructor)) {
25234+ /*
25235+ printk("TX buffer has a destructor\n");
25236+ */
25237+ goto dont_put_skbuff_in_hw;
25238+ }
25239+ if (unlikely(skb_shinfo(skb)->nr_frags)) {
25240+ /*
25241+ printk("TX buffer has fragments\n");
25242+ */
25243+ goto dont_put_skbuff_in_hw;
25244+ }
25245+ if (unlikely
25246+ (skb->truesize !=
25247+ sizeof(*skb) + skb_end_pointer(skb) - skb->head)) {
25248+ /*
25249+ printk("TX buffer truesize has been changed\n");
25250+ */
25251+ goto dont_put_skbuff_in_hw;
25252+ }
25253+
25254+ /*
25255+ * We can use this buffer in the FPA. We don't need the FAU
25256+ * update anymore
25257+ */
25258+ pko_command.s.reg0 = 0;
25259+ pko_command.s.dontfree = 0;
25260+
25261+ hw_buffer.s.back = (skb->data - fpa_head) >> 7;
25262+ *(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
25263+
25264+ /*
25265+ * The skbuff will be reused without ever being freed. We must
25266+ * cleanup a bunch of Linux stuff.
25267+ */
25268+ dst_release(skb->dst);
25269+ skb->dst = NULL;
25270+#ifdef CONFIG_XFRM
25271+ secpath_put(skb->sp);
25272+ skb->sp = NULL;
25273+#endif
25274+ nf_reset(skb);
25275+
25276+#ifdef CONFIG_NET_SCHED
25277+ skb->tc_index = 0;
25278+#ifdef CONFIG_NET_CLS_ACT
25279+ skb->tc_verd = 0;
25280+#endif /* CONFIG_NET_CLS_ACT */
25281+#endif /* CONFIG_NET_SCHED */
25282+
25283+dont_put_skbuff_in_hw:
25284+#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
25285+
25286+ /* Check if we can use the hardware checksumming */
25287+ if (USE_HW_TCPUDP_CHECKSUM && (skb->protocol == htons(ETH_P_IP)) &&
25288+ (ip_hdr(skb)->version == 4) && (ip_hdr(skb)->ihl == 5) &&
25289+ ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == 1 << 14))
25290+ && ((ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
25291+ || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP))) {
25292+ /* Use hardware checksum calc */
25293+ pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
25294+ }
25295+
25296+ if (USE_ASYNC_IOBDMA) {
25297+ /* Get the number of skbuffs in use by the hardware */
25298+ CVMX_SYNCIOBDMA;
25299+ in_use = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
25300+ buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
25301+ } else {
25302+ /* Get the number of skbuffs in use by the hardware */
25303+ in_use = cvmx_fau_fetch_and_add32(priv->fau + qos * 4, 1);
25304+ buffers_to_free =
25305+ cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
25306+ }
25307+
25308+ /*
25309+ * If we're sending faster than the receive can free them then
25310+ * don't do the HW free.
25311+ */
25312+ if ((buffers_to_free < -100) && !pko_command.s.dontfree) {
25313+ pko_command.s.dontfree = 1;
25314+ pko_command.s.reg0 = priv->fau + qos * 4;
25315+ }
25316+
25317+ cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
25318+ CVMX_PKO_LOCK_CMD_QUEUE);
25319+
25320+ /* Drop this packet if we have too many already queued to the HW */
25321+ if (unlikely
25322+ (skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) {
25323+ /*
25324+ DEBUGPRINT("%s: Tx dropped. Too many queued\n", dev->name);
25325+ */
25326+ dropped = 1;
25327+ }
25328+ /* Send the packet to the output queue */
25329+ else if (unlikely
25330+ (cvmx_pko_send_packet_finish
25331+ (priv->port, priv->queue + qos, pko_command, hw_buffer,
25332+ CVMX_PKO_LOCK_CMD_QUEUE))) {
25333+ DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
25334+ dropped = 1;
25335+ }
25336+
25337+ if (USE_ASYNC_IOBDMA) {
25338+ /* Restore the scratch area */
25339+ cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
25340+ cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2);
25341+ }
25342+
25343+ if (unlikely(dropped)) {
25344+ dev_kfree_skb_any(skb);
25345+ cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
25346+ priv->stats.tx_dropped++;
25347+ } else {
25348+ if (USE_SKBUFFS_IN_HW) {
25349+ /* Put this packet on the queue to be freed later */
25350+ if (pko_command.s.dontfree)
25351+ skb_queue_tail(&priv->tx_free_list[qos], skb);
25352+ else {
25353+ cvmx_fau_atomic_add32
25354+ (FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
25355+ cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
25356+ }
25357+ } else {
25358+ /* Put this packet on the queue to be freed later */
25359+ skb_queue_tail(&priv->tx_free_list[qos], skb);
25360+ }
25361+ }
25362+
25363+ /* Free skbuffs not in use by the hardware, possibly two at a time */
25364+ if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) {
25365+ spin_lock(&priv->tx_free_list[qos].lock);
25366+ /*
25367+ * Check again now that we have the lock. It might
25368+ * have changed.
25369+ */
25370+ if (skb_queue_len(&priv->tx_free_list[qos]) > in_use)
25371+ dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
25372+ if (skb_queue_len(&priv->tx_free_list[qos]) > in_use)
25373+ dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
25374+ spin_unlock(&priv->tx_free_list[qos].lock);
25375+ }
25376+
25377+ return 0;
25378+}
25379+
25380+/**
25381+ * Packet transmit to the POW
25382+ *
25383+ * @skb: Packet to send
25384+ * @dev: Device info structure
25385+ * Returns Always returns zero
25386+ */
25387+int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
25388+{
25389+ struct octeon_ethernet *priv = netdev_priv(dev);
25390+ void *packet_buffer;
25391+ void *copy_location;
25392+
25393+ /* Get a work queue entry */
25394+ cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL);
25395+ if (unlikely(work == NULL)) {
25396+ DEBUGPRINT("%s: Failed to allocate a work queue entry\n",
25397+ dev->name);
25398+ priv->stats.tx_dropped++;
25399+ dev_kfree_skb(skb);
25400+ return 0;
25401+ }
25402+
25403+ /* Get a packet buffer */
25404+ packet_buffer = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL);
25405+ if (unlikely(packet_buffer == NULL)) {
25406+ DEBUGPRINT("%s: Failed to allocate a packet buffer\n",
25407+ dev->name);
25408+ cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
25409+ priv->stats.tx_dropped++;
25410+ dev_kfree_skb(skb);
25411+ return 0;
25412+ }
25413+
25414+ /*
25415+ * Calculate where we need to copy the data to. We need to
25416+ * leave 8 bytes for a next pointer (unused). We also need to
25417+ * include any configure skip. Then we need to align the IP
25418+ * packet src and dest into the same 64bit word. The below
25419+ * calculation may add a little extra, but that doesn't
25420+ * hurt.
25421+ */
25422+ copy_location = packet_buffer + sizeof(uint64_t);
25423+ copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6;
25424+
25425+ /*
25426+ * We have to copy the packet since whoever processes this
25427+ * packet will free it to a hardware pool. We can't use the
25428+ * trick of counting outstanding packets like in
25429+ * cvm_oct_xmit.
25430+ */
25431+ memcpy(copy_location, skb->data, skb->len);
25432+
25433+ /*
25434+ * Fill in some of the work queue fields. We may need to add
25435+ * more if the software at the other end needs them.
25436+ */
25437+ work->hw_chksum = skb->csum;
25438+ work->len = skb->len;
25439+ work->ipprt = priv->port;
25440+ work->qos = priv->port & 0x7;
25441+ work->grp = pow_send_group;
25442+ work->tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
25443+ work->tag = pow_send_group; /* FIXME */
25444+ /* Default to zero. Sets of zero later are commented out */
25445+ work->word2.u64 = 0;
25446+ work->word2.s.bufs = 1;
25447+ work->packet_ptr.u64 = 0;
25448+ work->packet_ptr.s.addr = cvmx_ptr_to_phys(copy_location);
25449+ work->packet_ptr.s.pool = CVMX_FPA_PACKET_POOL;
25450+ work->packet_ptr.s.size = CVMX_FPA_PACKET_POOL_SIZE;
25451+ work->packet_ptr.s.back = (copy_location - packet_buffer) >> 7;
25452+
25453+ if (skb->protocol == htons(ETH_P_IP)) {
25454+ work->word2.s.ip_offset = 14;
25455+#if 0
25456+ work->word2.s.vlan_valid = 0; /* FIXME */
25457+ work->word2.s.vlan_cfi = 0; /* FIXME */
25458+ work->word2.s.vlan_id = 0; /* FIXME */
25459+ work->word2.s.dec_ipcomp = 0; /* FIXME */
25460+#endif
25461+ work->word2.s.tcp_or_udp =
25462+ (ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
25463+ || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP);
25464+#if 0
25465+ /* FIXME */
25466+ work->word2.s.dec_ipsec = 0;
25467+ /* We only support IPv4 right now */
25468+ work->word2.s.is_v6 = 0;
25469+ /* Hardware would set to zero */
25470+ work->word2.s.software = 0;
25471+ /* No error, packet is internal */
25472+ work->word2.s.L4_error = 0;
25473+#endif
25474+ work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0)
25475+ || (ip_hdr(skb)->frag_off ==
25476+ 1 << 14));
25477+#if 0
25478+ /* Assume Linux is sending a good packet */
25479+ work->word2.s.IP_exc = 0;
25480+#endif
25481+ work->word2.s.is_bcast = (skb->pkt_type == PACKET_BROADCAST);
25482+ work->word2.s.is_mcast = (skb->pkt_type == PACKET_MULTICAST);
25483+#if 0
25484+ /* This is an IP packet */
25485+ work->word2.s.not_IP = 0;
25486+ /* No error, packet is internal */
25487+ work->word2.s.rcv_error = 0;
25488+ /* No error, packet is internal */
25489+ work->word2.s.err_code = 0;
25490+#endif
25491+
25492+ /*
25493+ * When copying the data, include 4 bytes of the
25494+ * ethernet header to align the same way hardware
25495+ * does.
25496+ */
25497+ memcpy(work->packet_data, skb->data + 10,
25498+ sizeof(work->packet_data));
25499+ } else {
25500+#if 0
25501+ work->word2.snoip.vlan_valid = 0; /* FIXME */
25502+ work->word2.snoip.vlan_cfi = 0; /* FIXME */
25503+ work->word2.snoip.vlan_id = 0; /* FIXME */
25504+ work->word2.snoip.software = 0; /* Hardware would set to zero */
25505+#endif
25506+ work->word2.snoip.is_rarp = skb->protocol == htons(ETH_P_RARP);
25507+ work->word2.snoip.is_arp = skb->protocol == htons(ETH_P_ARP);
25508+ work->word2.snoip.is_bcast =
25509+ (skb->pkt_type == PACKET_BROADCAST);
25510+ work->word2.snoip.is_mcast =
25511+ (skb->pkt_type == PACKET_MULTICAST);
25512+ work->word2.snoip.not_IP = 1; /* IP was done up above */
25513+#if 0
25514+ /* No error, packet is internal */
25515+ work->word2.snoip.rcv_error = 0;
25516+ /* No error, packet is internal */
25517+ work->word2.snoip.err_code = 0;
25518+#endif
25519+ memcpy(work->packet_data, skb->data, sizeof(work->packet_data));
25520+ }
25521+
25522+ /* Submit the packet to the POW */
25523+ cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos,
25524+ work->grp);
25525+ priv->stats.tx_packets++;
25526+ priv->stats.tx_bytes += skb->len;
25527+ dev_kfree_skb(skb);
25528+ return 0;
25529+}
25530+
25531+/**
25532+ * Transmit a work queue entry out of the ethernet port. Both
25533+ * the work queue entry and the packet data can optionally be
25534+ * freed. The work will be freed on error as well.
25535+ *
25536+ * @dev: Device to transmit out.
25537+ * @work_queue_entry:
25538+ * Work queue entry to send
25539+ * @do_free: True if the work queue entry and packet data should be
25540+ * freed. If false, neither will be freed.
25541+ * @qos: Index into the queues for this port to transmit on. This
25542+ * is used to implement QoS if their are multiple queues per
25543+ * port. This parameter must be between 0 and the number of
25544+ * queues per port minus 1. Values outside of this range will
25545+ * be change to zero.
25546+ *
25547+ * Returns Zero on success, negative on failure.
25548+ */
25549+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
25550+ int do_free, int qos)
25551+{
25552+ unsigned long flags;
25553+ union cvmx_buf_ptr hw_buffer;
25554+ cvmx_pko_command_word0_t pko_command;
25555+ int dropped;
25556+ struct octeon_ethernet *priv = netdev_priv(dev);
25557+ cvmx_wqe_t *work = work_queue_entry;
25558+
25559+ if (!(dev->flags & IFF_UP)) {
25560+ DEBUGPRINT("%s: Device not up\n", dev->name);
25561+ if (do_free)
25562+ cvm_oct_free_work(work);
25563+ return -1;
25564+ }
25565+
25566+ /* The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to completely
25567+ remove "qos" in the event neither interface supports
25568+ multiple queues per port */
25569+ if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
25570+ (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
25571+ if (qos <= 0)
25572+ qos = 0;
25573+ else if (qos >= cvmx_pko_get_num_queues(priv->port))
25574+ qos = 0;
25575+ } else
25576+ qos = 0;
25577+
25578+ /* Start off assuming no drop */
25579+ dropped = 0;
25580+
25581+ local_irq_save(flags);
25582+ cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
25583+ CVMX_PKO_LOCK_CMD_QUEUE);
25584+
25585+ /* Build the PKO buffer pointer */
25586+ hw_buffer.u64 = 0;
25587+ hw_buffer.s.addr = work->packet_ptr.s.addr;
25588+ hw_buffer.s.pool = CVMX_FPA_PACKET_POOL;
25589+ hw_buffer.s.size = CVMX_FPA_PACKET_POOL_SIZE;
25590+ hw_buffer.s.back = work->packet_ptr.s.back;
25591+
25592+ /* Build the PKO command */
25593+ pko_command.u64 = 0;
25594+ pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */
25595+ pko_command.s.dontfree = !do_free;
25596+ pko_command.s.segs = work->word2.s.bufs;
25597+ pko_command.s.total_bytes = work->len;
25598+
25599+ /* Check if we can use the hardware checksumming */
25600+ if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc))
25601+ pko_command.s.ipoffp1 = 0;
25602+ else
25603+ pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
25604+
25605+ /* Send the packet to the output queue */
25606+ if (unlikely
25607+ (cvmx_pko_send_packet_finish
25608+ (priv->port, priv->queue + qos, pko_command, hw_buffer,
25609+ CVMX_PKO_LOCK_CMD_QUEUE))) {
25610+ DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
25611+ dropped = -1;
25612+ }
25613+ local_irq_restore(flags);
25614+
25615+ if (unlikely(dropped)) {
25616+ if (do_free)
25617+ cvm_oct_free_work(work);
25618+ priv->stats.tx_dropped++;
25619+ } else if (do_free)
25620+ cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
25621+
25622+ return dropped;
25623+}
25624+EXPORT_SYMBOL(cvm_oct_transmit_qos);
25625+
25626+/**
25627+ * This function frees all skb that are currenty queued for TX.
25628+ *
25629+ * @dev: Device being shutdown
25630+ */
25631+void cvm_oct_tx_shutdown(struct net_device *dev)
25632+{
25633+ struct octeon_ethernet *priv = netdev_priv(dev);
25634+ unsigned long flags;
25635+ int qos;
25636+
25637+ for (qos = 0; qos < 16; qos++) {
25638+ spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
25639+ while (skb_queue_len(&priv->tx_free_list[qos]))
25640+ dev_kfree_skb_any(__skb_dequeue
25641+ (&priv->tx_free_list[qos]));
25642+ spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
25643+ }
25644+}
25645--- /dev/null
25646+++ b/drivers/staging/octeon/ethernet-tx.h
25647@@ -0,0 +1,32 @@
25648+/*********************************************************************
25649+ * Author: Cavium Networks
25650+ *
25651+ * Contact: support@caviumnetworks.com
25652+ * This file is part of the OCTEON SDK
25653+ *
25654+ * Copyright (c) 2003-2007 Cavium Networks
25655+ *
25656+ * This file is free software; you can redistribute it and/or modify
25657+ * it under the terms of the GNU General Public License, Version 2, as
25658+ * published by the Free Software Foundation.
25659+ *
25660+ * This file is distributed in the hope that it will be useful, but
25661+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25662+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25663+ * NONINFRINGEMENT. See the GNU General Public License for more
25664+ * details.
25665+ *
25666+ * You should have received a copy of the GNU General Public License
25667+ * along with this file; if not, write to the Free Software
25668+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25669+ * or visit http://www.gnu.org/licenses/.
25670+ *
25671+ * This file may also be available under a different license from Cavium.
25672+ * Contact Cavium Networks for more information
25673+*********************************************************************/
25674+
25675+int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev);
25676+int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev);
25677+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
25678+ int do_free, int qos);
25679+void cvm_oct_tx_shutdown(struct net_device *dev);
25680--- /dev/null
25681+++ b/drivers/staging/octeon/ethernet-util.h
25682@@ -0,0 +1,81 @@
25683+/**********************************************************************
25684+ * Author: Cavium Networks
25685+ *
25686+ * Contact: support@caviumnetworks.com
25687+ * This file is part of the OCTEON SDK
25688+ *
25689+ * Copyright (c) 2003-2007 Cavium Networks
25690+ *
25691+ * This file is free software; you can redistribute it and/or modify
25692+ * it under the terms of the GNU General Public License, Version 2, as
25693+ * published by the Free Software Foundation.
25694+ *
25695+ * This file is distributed in the hope that it will be useful, but
25696+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25697+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25698+ * NONINFRINGEMENT. See the GNU General Public License for more
25699+ * details.
25700+ *
25701+ * You should have received a copy of the GNU General Public License
25702+ * along with this file; if not, write to the Free Software
25703+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25704+ * or visit http://www.gnu.org/licenses/.
25705+ *
25706+ * This file may also be available under a different license from Cavium.
25707+ * Contact Cavium Networks for more information
25708+*********************************************************************/
25709+
25710+#define DEBUGPRINT(format, ...) do { if (printk_ratelimit()) \
25711+ printk(format, ##__VA_ARGS__); \
25712+ } while (0)
25713+
25714+/**
25715+ * Given a packet data address, return a pointer to the
25716+ * beginning of the packet buffer.
25717+ *
25718+ * @packet_ptr: Packet data hardware address
25719+ * Returns Packet buffer pointer
25720+ */
25721+static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr)
25722+{
25723+ return cvmx_phys_to_ptr(((packet_ptr.s.addr >> 7) - packet_ptr.s.back)
25724+ << 7);
25725+}
25726+
25727+/**
25728+ * Given an IPD/PKO port number, return the logical interface it is
25729+ * on.
25730+ *
25731+ * @ipd_port: Port to check
25732+ *
25733+ * Returns Logical interface
25734+ */
25735+static inline int INTERFACE(int ipd_port)
25736+{
25737+ if (ipd_port < 32) /* Interface 0 or 1 for RGMII,GMII,SPI, etc */
25738+ return ipd_port >> 4;
25739+ else if (ipd_port < 36) /* Interface 2 for NPI */
25740+ return 2;
25741+ else if (ipd_port < 40) /* Interface 3 for loopback */
25742+ return 3;
25743+ else if (ipd_port == 40) /* Non existant interface for POW0 */
25744+ return 4;
25745+ else
25746+ panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);
25747+}
25748+
25749+/**
25750+ * Given an IPD/PKO port number, return the port's index on a
25751+ * logical interface.
25752+ *
25753+ * @ipd_port: Port to check
25754+ *
25755+ * Returns Index into interface port list
25756+ */
25757+static inline int INDEX(int ipd_port)
25758+{
25759+ if (ipd_port < 32)
25760+ return ipd_port & 15;
25761+ else
25762+ return ipd_port & 3;
25763+}
25764--- /dev/null
25765+++ b/drivers/staging/octeon/ethernet-xaui.c
25766@@ -0,0 +1,127 @@
25767+/**********************************************************************
25768+ * Author: Cavium Networks
25769+ *
25770+ * Contact: support@caviumnetworks.com
25771+ * This file is part of the OCTEON SDK
25772+ *
25773+ * Copyright (c) 2003-2007 Cavium Networks
25774+ *
25775+ * This file is free software; you can redistribute it and/or modify
25776+ * it under the terms of the GNU General Public License, Version 2, as
25777+ * published by the Free Software Foundation.
25778+ *
25779+ * This file is distributed in the hope that it will be useful, but
25780+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25781+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25782+ * NONINFRINGEMENT. See the GNU General Public License for more
25783+ * details.
25784+ *
25785+ * You should have received a copy of the GNU General Public License
25786+ * along with this file; if not, write to the Free Software
25787+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25788+ * or visit http://www.gnu.org/licenses/.
25789+ *
25790+ * This file may also be available under a different license from Cavium.
25791+ * Contact Cavium Networks for more information
25792+**********************************************************************/
25793+#include <linux/kernel.h>
25794+#include <linux/netdevice.h>
25795+#include <linux/mii.h>
25796+#include <net/dst.h>
25797+
25798+#include <asm/octeon/octeon.h>
25799+
25800+#include "ethernet-defines.h"
25801+#include "octeon-ethernet.h"
25802+#include "ethernet-common.h"
25803+#include "ethernet-util.h"
25804+
25805+#include "cvmx-helper.h"
25806+
25807+#include "cvmx-gmxx-defs.h"
25808+
25809+static int cvm_oct_xaui_open(struct net_device *dev)
25810+{
25811+ union cvmx_gmxx_prtx_cfg gmx_cfg;
25812+ struct octeon_ethernet *priv = netdev_priv(dev);
25813+ int interface = INTERFACE(priv->port);
25814+ int index = INDEX(priv->port);
25815+ cvmx_helper_link_info_t link_info;
25816+
25817+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
25818+ gmx_cfg.s.en = 1;
25819+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
25820+
25821+ if (!octeon_is_simulation()) {
25822+ link_info = cvmx_helper_link_get(priv->port);
25823+ if (!link_info.s.link_up)
25824+ netif_carrier_off(dev);
25825+ }
25826+ return 0;
25827+}
25828+
25829+static int cvm_oct_xaui_stop(struct net_device *dev)
25830+{
25831+ union cvmx_gmxx_prtx_cfg gmx_cfg;
25832+ struct octeon_ethernet *priv = netdev_priv(dev);
25833+ int interface = INTERFACE(priv->port);
25834+ int index = INDEX(priv->port);
25835+
25836+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
25837+ gmx_cfg.s.en = 0;
25838+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
25839+ return 0;
25840+}
25841+
25842+static void cvm_oct_xaui_poll(struct net_device *dev)
25843+{
25844+ struct octeon_ethernet *priv = netdev_priv(dev);
25845+ cvmx_helper_link_info_t link_info;
25846+
25847+ link_info = cvmx_helper_link_get(priv->port);
25848+ if (link_info.u64 == priv->link_info)
25849+ return;
25850+
25851+ link_info = cvmx_helper_link_autoconf(priv->port);
25852+ priv->link_info = link_info.u64;
25853+
25854+ /* Tell Linux */
25855+ if (link_info.s.link_up) {
25856+
25857+ if (!netif_carrier_ok(dev))
25858+ netif_carrier_on(dev);
25859+ if (priv->queue != -1)
25860+ DEBUGPRINT
25861+ ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
25862+ dev->name, link_info.s.speed,
25863+ (link_info.s.full_duplex) ? "Full" : "Half",
25864+ priv->port, priv->queue);
25865+ else
25866+ DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
25867+ dev->name, link_info.s.speed,
25868+ (link_info.s.full_duplex) ? "Full" : "Half",
25869+ priv->port);
25870+ } else {
25871+ if (netif_carrier_ok(dev))
25872+ netif_carrier_off(dev);
25873+ DEBUGPRINT("%s: Link down\n", dev->name);
25874+ }
25875+}
25876+
25877+int cvm_oct_xaui_init(struct net_device *dev)
25878+{
25879+ struct octeon_ethernet *priv = netdev_priv(dev);
25880+ cvm_oct_common_init(dev);
25881+ dev->open = cvm_oct_xaui_open;
25882+ dev->stop = cvm_oct_xaui_stop;
25883+ dev->stop(dev);
25884+ if (!octeon_is_simulation())
25885+ priv->poll = cvm_oct_xaui_poll;
25886+
25887+ return 0;
25888+}
25889+
25890+void cvm_oct_xaui_uninit(struct net_device *dev)
25891+{
25892+ cvm_oct_common_uninit(dev);
25893+}
25894--- /dev/null
25895+++ b/drivers/staging/octeon/ethernet.c
25896@@ -0,0 +1,507 @@
25897+/**********************************************************************
25898+ * Author: Cavium Networks
25899+ *
25900+ * Contact: support@caviumnetworks.com
25901+ * This file is part of the OCTEON SDK
25902+ *
25903+ * Copyright (c) 2003-2007 Cavium Networks
25904+ *
25905+ * This file is free software; you can redistribute it and/or modify
25906+ * it under the terms of the GNU General Public License, Version 2, as
25907+ * published by the Free Software Foundation.
25908+ *
25909+ * This file is distributed in the hope that it will be useful, but
25910+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25911+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25912+ * NONINFRINGEMENT. See the GNU General Public License for more
25913+ * details.
25914+ *
25915+ * You should have received a copy of the GNU General Public License
25916+ * along with this file; if not, write to the Free Software
25917+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25918+ * or visit http://www.gnu.org/licenses/.
25919+ *
25920+ * This file may also be available under a different license from Cavium.
25921+ * Contact Cavium Networks for more information
25922+**********************************************************************/
25923+#include <linux/kernel.h>
25924+#include <linux/init.h>
25925+#include <linux/module.h>
25926+#include <linux/netdevice.h>
25927+#include <linux/etherdevice.h>
25928+#include <linux/delay.h>
25929+#include <linux/mii.h>
25930+
25931+#include <net/dst.h>
25932+
25933+#include <asm/octeon/octeon.h>
25934+
25935+#include "ethernet-defines.h"
25936+#include "ethernet-mem.h"
25937+#include "ethernet-rx.h"
25938+#include "ethernet-tx.h"
25939+#include "ethernet-util.h"
25940+#include "ethernet-proc.h"
25941+#include "ethernet-common.h"
25942+#include "octeon-ethernet.h"
25943+
25944+#include "cvmx-pip.h"
25945+#include "cvmx-pko.h"
25946+#include "cvmx-fau.h"
25947+#include "cvmx-ipd.h"
25948+#include "cvmx-helper.h"
25949+
25950+#include "cvmx-smix-defs.h"
25951+
25952+#if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \
25953+ && CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
25954+int num_packet_buffers = CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS;
25955+#else
25956+int num_packet_buffers = 1024;
25957+#endif
25958+module_param(num_packet_buffers, int, 0444);
25959+MODULE_PARM_DESC(num_packet_buffers, "\n"
25960+ "\tNumber of packet buffers to allocate and store in the\n"
25961+ "\tFPA. By default, 1024 packet buffers are used unless\n"
25962+ "\tCONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS is defined.");
25963+
25964+int pow_receive_group = 15;
25965+module_param(pow_receive_group, int, 0444);
25966+MODULE_PARM_DESC(pow_receive_group, "\n"
25967+ "\tPOW group to receive packets from. All ethernet hardware\n"
25968+ "\twill be configured to send incomming packets to this POW\n"
25969+ "\tgroup. Also any other software can submit packets to this\n"
25970+ "\tgroup for the kernel to process.");
25971+
25972+int pow_send_group = -1;
25973+module_param(pow_send_group, int, 0644);
25974+MODULE_PARM_DESC(pow_send_group, "\n"
25975+ "\tPOW group to send packets to other software on. This\n"
25976+ "\tcontrols the creation of the virtual device pow0.\n"
25977+ "\talways_use_pow also depends on this value.");
25978+
25979+int always_use_pow;
25980+module_param(always_use_pow, int, 0444);
25981+MODULE_PARM_DESC(always_use_pow, "\n"
25982+ "\tWhen set, always send to the pow group. This will cause\n"
25983+ "\tpackets sent to real ethernet devices to be sent to the\n"
25984+ "\tPOW group instead of the hardware. Unless some other\n"
25985+ "\tapplication changes the config, packets will still be\n"
25986+ "\treceived from the low level hardware. Use this option\n"
25987+ "\tto allow a CVMX app to intercept all packets from the\n"
25988+ "\tlinux kernel. You must specify pow_send_group along with\n"
25989+ "\tthis option.");
25990+
25991+char pow_send_list[128] = "";
25992+module_param_string(pow_send_list, pow_send_list, sizeof(pow_send_list), 0444);
25993+MODULE_PARM_DESC(pow_send_list, "\n"
25994+ "\tComma separated list of ethernet devices that should use the\n"
25995+ "\tPOW for transmit instead of the actual ethernet hardware. This\n"
25996+ "\tis a per port version of always_use_pow. always_use_pow takes\n"
25997+ "\tprecedence over this list. For example, setting this to\n"
25998+ "\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n"
25999+ "\tusing the pow_send_group.");
26000+
26001+static int disable_core_queueing = 1;
26002+module_param(disable_core_queueing, int, 0444);
26003+MODULE_PARM_DESC(disable_core_queueing, "\n"
26004+ "\tWhen set the networking core's tx_queue_len is set to zero. This\n"
26005+ "\tallows packets to be sent without lock contention in the packet\n"
26006+ "\tscheduler resulting in some cases in improved throughput.\n");
26007+
26008+/**
26009+ * Periodic timer to check auto negotiation
26010+ */
26011+static struct timer_list cvm_oct_poll_timer;
26012+
26013+/**
26014+ * Array of every ethernet device owned by this driver indexed by
26015+ * the ipd input port number.
26016+ */
26017+struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
26018+
26019+extern struct semaphore mdio_sem;
26020+
26021+/**
26022+ * Periodic timer tick for slow management operations
26023+ *
26024+ * @arg: Device to check
26025+ */
26026+static void cvm_do_timer(unsigned long arg)
26027+{
26028+ static int port;
26029+ if (port < CVMX_PIP_NUM_INPUT_PORTS) {
26030+ if (cvm_oct_device[port]) {
26031+ int queues_per_port;
26032+ int qos;
26033+ struct octeon_ethernet *priv =
26034+ netdev_priv(cvm_oct_device[port]);
26035+ if (priv->poll) {
26036+ /* skip polling if we don't get the lock */
26037+ if (!down_trylock(&mdio_sem)) {
26038+ priv->poll(cvm_oct_device[port]);
26039+ up(&mdio_sem);
26040+ }
26041+ }
26042+
26043+ queues_per_port = cvmx_pko_get_num_queues(port);
26044+ /* Drain any pending packets in the free list */
26045+ for (qos = 0; qos < queues_per_port; qos++) {
26046+ if (skb_queue_len(&priv->tx_free_list[qos])) {
26047+ spin_lock(&priv->tx_free_list[qos].
26048+ lock);
26049+ while (skb_queue_len
26050+ (&priv->tx_free_list[qos]) >
26051+ cvmx_fau_fetch_and_add32(priv->
26052+ fau +
26053+ qos * 4,
26054+ 0))
26055+ dev_kfree_skb(__skb_dequeue
26056+ (&priv->
26057+ tx_free_list
26058+ [qos]));
26059+ spin_unlock(&priv->tx_free_list[qos].
26060+ lock);
26061+ }
26062+ }
26063+ cvm_oct_device[port]->get_stats(cvm_oct_device[port]);
26064+ }
26065+ port++;
26066+ /* Poll the next port in a 50th of a second.
26067+ This spreads the polling of ports out a little bit */
26068+ mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50);
26069+ } else {
26070+ port = 0;
26071+ /* All ports have been polled. Start the next iteration through
26072+ the ports in one second */
26073+ mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
26074+ }
26075+}
26076+
26077+/**
26078+ * Configure common hardware for all interfaces
26079+ */
26080+static __init void cvm_oct_configure_common_hw(void)
26081+{
26082+ int r;
26083+ /* Setup the FPA */
26084+ cvmx_fpa_enable();
26085+ cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
26086+ num_packet_buffers);
26087+ cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
26088+ num_packet_buffers);
26089+ if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
26090+ cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
26091+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
26092+
26093+ if (USE_RED)
26094+ cvmx_helper_setup_red(num_packet_buffers / 4,
26095+ num_packet_buffers / 8);
26096+
26097+ /* Enable the MII interface */
26098+ if (!octeon_is_simulation())
26099+ cvmx_write_csr(CVMX_SMIX_EN(0), 1);
26100+
26101+ /* Register an IRQ hander for to receive POW interrupts */
26102+ r = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
26103+ cvm_oct_do_interrupt, IRQF_SHARED, "Ethernet",
26104+ cvm_oct_device);
26105+
26106+#if defined(CONFIG_SMP) && 0
26107+ if (USE_MULTICORE_RECEIVE) {
26108+ irq_set_affinity(OCTEON_IRQ_WORKQ0 + pow_receive_group,
26109+ cpu_online_mask);
26110+ }
26111+#endif
26112+}
26113+
26114+/**
26115+ * Free a work queue entry received in a intercept callback.
26116+ *
26117+ * @work_queue_entry:
26118+ * Work queue entry to free
26119+ * Returns Zero on success, Negative on failure.
26120+ */
26121+int cvm_oct_free_work(void *work_queue_entry)
26122+{
26123+ cvmx_wqe_t *work = work_queue_entry;
26124+
26125+ int segments = work->word2.s.bufs;
26126+ union cvmx_buf_ptr segment_ptr = work->packet_ptr;
26127+
26128+ while (segments--) {
26129+ union cvmx_buf_ptr next_ptr = *(union cvmx_buf_ptr *)
26130+ cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
26131+ if (unlikely(!segment_ptr.s.i))
26132+ cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr),
26133+ segment_ptr.s.pool,
26134+ DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE /
26135+ 128));
26136+ segment_ptr = next_ptr;
26137+ }
26138+ cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
26139+
26140+ return 0;
26141+}
26142+EXPORT_SYMBOL(cvm_oct_free_work);
26143+
26144+/**
26145+ * Module/ driver initialization. Creates the linux network
26146+ * devices.
26147+ *
26148+ * Returns Zero on success
26149+ */
26150+static int __init cvm_oct_init_module(void)
26151+{
26152+ int num_interfaces;
26153+ int interface;
26154+ int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
26155+ int qos;
26156+
26157+ pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
26158+
26159+ cvm_oct_proc_initialize();
26160+ cvm_oct_rx_initialize();
26161+ cvm_oct_configure_common_hw();
26162+
26163+ cvmx_helper_initialize_packet_io_global();
26164+
26165+ /* Change the input group for all ports before input is enabled */
26166+ num_interfaces = cvmx_helper_get_number_of_interfaces();
26167+ for (interface = 0; interface < num_interfaces; interface++) {
26168+ int num_ports = cvmx_helper_ports_on_interface(interface);
26169+ int port;
26170+
26171+ for (port = cvmx_helper_get_ipd_port(interface, 0);
26172+ port < cvmx_helper_get_ipd_port(interface, num_ports);
26173+ port++) {
26174+ union cvmx_pip_prt_tagx pip_prt_tagx;
26175+ pip_prt_tagx.u64 =
26176+ cvmx_read_csr(CVMX_PIP_PRT_TAGX(port));
26177+ pip_prt_tagx.s.grp = pow_receive_group;
26178+ cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
26179+ pip_prt_tagx.u64);
26180+ }
26181+ }
26182+
26183+ cvmx_helper_ipd_and_packet_input_enable();
26184+
26185+ memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
26186+
26187+ /*
26188+ * Initialize the FAU used for counting packet buffers that
26189+ * need to be freed.
26190+ */
26191+ cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
26192+
26193+ if ((pow_send_group != -1)) {
26194+ struct net_device *dev;
26195+ pr_info("\tConfiguring device for POW only access\n");
26196+ dev = alloc_etherdev(sizeof(struct octeon_ethernet));
26197+ if (dev) {
26198+ /* Initialize the device private structure. */
26199+ struct octeon_ethernet *priv = netdev_priv(dev);
26200+ memset(priv, 0, sizeof(struct octeon_ethernet));
26201+
26202+ dev->init = cvm_oct_common_init;
26203+ priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
26204+ priv->port = CVMX_PIP_NUM_INPUT_PORTS;
26205+ priv->queue = -1;
26206+ strcpy(dev->name, "pow%d");
26207+ for (qos = 0; qos < 16; qos++)
26208+ skb_queue_head_init(&priv->tx_free_list[qos]);
26209+
26210+ if (register_netdev(dev) < 0) {
26211+ pr_err("Failed to register ethernet "
26212+ "device for POW\n");
26213+ kfree(dev);
26214+ } else {
26215+ cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
26216+ pr_info("%s: POW send group %d, receive "
26217+ "group %d\n",
26218+ dev->name, pow_send_group,
26219+ pow_receive_group);
26220+ }
26221+ } else {
26222+ pr_err("Failed to allocate ethernet device "
26223+ "for POW\n");
26224+ }
26225+ }
26226+
26227+ num_interfaces = cvmx_helper_get_number_of_interfaces();
26228+ for (interface = 0; interface < num_interfaces; interface++) {
26229+ cvmx_helper_interface_mode_t imode =
26230+ cvmx_helper_interface_get_mode(interface);
26231+ int num_ports = cvmx_helper_ports_on_interface(interface);
26232+ int port;
26233+
26234+ for (port = cvmx_helper_get_ipd_port(interface, 0);
26235+ port < cvmx_helper_get_ipd_port(interface, num_ports);
26236+ port++) {
26237+ struct octeon_ethernet *priv;
26238+ struct net_device *dev =
26239+ alloc_etherdev(sizeof(struct octeon_ethernet));
26240+ if (!dev) {
26241+ pr_err("Failed to allocate ethernet device "
26242+ "for port %d\n", port);
26243+ continue;
26244+ }
26245+ if (disable_core_queueing)
26246+ dev->tx_queue_len = 0;
26247+
26248+ /* Initialize the device private structure. */
26249+ priv = netdev_priv(dev);
26250+ memset(priv, 0, sizeof(struct octeon_ethernet));
26251+
26252+ priv->imode = imode;
26253+ priv->port = port;
26254+ priv->queue = cvmx_pko_get_base_queue(priv->port);
26255+ priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
26256+ for (qos = 0; qos < 16; qos++)
26257+ skb_queue_head_init(&priv->tx_free_list[qos]);
26258+ for (qos = 0; qos < cvmx_pko_get_num_queues(port);
26259+ qos++)
26260+ cvmx_fau_atomic_write32(priv->fau + qos * 4, 0);
26261+
26262+ switch (priv->imode) {
26263+
26264+ /* These types don't support ports to IPD/PKO */
26265+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
26266+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
26267+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
26268+ break;
26269+
26270+ case CVMX_HELPER_INTERFACE_MODE_NPI:
26271+ dev->init = cvm_oct_common_init;
26272+ dev->uninit = cvm_oct_common_uninit;
26273+ strcpy(dev->name, "npi%d");
26274+ break;
26275+
26276+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
26277+ dev->init = cvm_oct_xaui_init;
26278+ dev->uninit = cvm_oct_xaui_uninit;
26279+ strcpy(dev->name, "xaui%d");
26280+ break;
26281+
26282+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
26283+ dev->init = cvm_oct_common_init;
26284+ dev->uninit = cvm_oct_common_uninit;
26285+ strcpy(dev->name, "loop%d");
26286+ break;
26287+
26288+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
26289+ dev->init = cvm_oct_sgmii_init;
26290+ dev->uninit = cvm_oct_sgmii_uninit;
26291+ strcpy(dev->name, "eth%d");
26292+ break;
26293+
26294+ case CVMX_HELPER_INTERFACE_MODE_SPI:
26295+ dev->init = cvm_oct_spi_init;
26296+ dev->uninit = cvm_oct_spi_uninit;
26297+ strcpy(dev->name, "spi%d");
26298+ break;
26299+
26300+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
26301+ case CVMX_HELPER_INTERFACE_MODE_GMII:
26302+ dev->init = cvm_oct_rgmii_init;
26303+ dev->uninit = cvm_oct_rgmii_uninit;
26304+ strcpy(dev->name, "eth%d");
26305+ break;
26306+ }
26307+
26308+ if (!dev->init) {
26309+ kfree(dev);
26310+ } else if (register_netdev(dev) < 0) {
26311+ pr_err("Failed to register ethernet device "
26312+ "for interface %d, port %d\n",
26313+ interface, priv->port);
26314+ kfree(dev);
26315+ } else {
26316+ cvm_oct_device[priv->port] = dev;
26317+ fau -=
26318+ cvmx_pko_get_num_queues(priv->port) *
26319+ sizeof(uint32_t);
26320+ }
26321+ }
26322+ }
26323+
26324+ if (INTERRUPT_LIMIT) {
26325+ /*
26326+ * Set the POW timer rate to give an interrupt at most
26327+ * INTERRUPT_LIMIT times per second.
26328+ */
26329+ cvmx_write_csr(CVMX_POW_WQ_INT_PC,
26330+ octeon_bootinfo->eclock_hz / (INTERRUPT_LIMIT *
26331+ 16 * 256) << 8);
26332+
26333+ /*
26334+ * Enable POW timer interrupt. It will count when
26335+ * there are packets available.
26336+ */
26337+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
26338+ 0x1ful << 24);
26339+ } else {
26340+ /* Enable POW interrupt when our port has at least one packet */
26341+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1001);
26342+ }
26343+
26344+ /* Enable the poll timer for checking RGMII status */
26345+ init_timer(&cvm_oct_poll_timer);
26346+ cvm_oct_poll_timer.data = 0;
26347+ cvm_oct_poll_timer.function = cvm_do_timer;
26348+ mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
26349+
26350+ return 0;
26351+}
26352+
26353+/**
26354+ * Module / driver shutdown
26355+ *
26356+ * Returns Zero on success
26357+ */
26358+static void __exit cvm_oct_cleanup_module(void)
26359+{
26360+ int port;
26361+
26362+ /* Disable POW interrupt */
26363+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
26364+
26365+ cvmx_ipd_disable();
26366+
26367+ /* Free the interrupt handler */
26368+ free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
26369+
26370+ del_timer(&cvm_oct_poll_timer);
26371+ cvm_oct_rx_shutdown();
26372+ cvmx_pko_disable();
26373+
26374+ /* Free the ethernet devices */
26375+ for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
26376+ if (cvm_oct_device[port]) {
26377+ cvm_oct_tx_shutdown(cvm_oct_device[port]);
26378+ unregister_netdev(cvm_oct_device[port]);
26379+ kfree(cvm_oct_device[port]);
26380+ cvm_oct_device[port] = NULL;
26381+ }
26382+ }
26383+
26384+ cvmx_pko_shutdown();
26385+ cvm_oct_proc_shutdown();
26386+
26387+ cvmx_ipd_free_ptr();
26388+
26389+ /* Free the HW pools */
26390+ cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
26391+ num_packet_buffers);
26392+ cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
26393+ num_packet_buffers);
26394+ if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
26395+ cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
26396+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
26397+}
26398+
26399+MODULE_LICENSE("GPL");
26400+MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
26401+MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver.");
26402+module_init(cvm_oct_init_module);
26403+module_exit(cvm_oct_cleanup_module);
26404--- /dev/null
26405+++ b/drivers/staging/octeon/octeon-ethernet.h
26406@@ -0,0 +1,127 @@
26407+/**********************************************************************
26408+ * Author: Cavium Networks
26409+ *
26410+ * Contact: support@caviumnetworks.com
26411+ * This file is part of the OCTEON SDK
26412+ *
26413+ * Copyright (c) 2003-2007 Cavium Networks
26414+ *
26415+ * This file is free software; you can redistribute it and/or modify
26416+ * it under the terms of the GNU General Public License, Version 2, as
26417+ * published by the Free Software Foundation.
26418+ *
26419+ * This file is distributed in the hope that it will be useful, but
26420+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
26421+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
26422+ * NONINFRINGEMENT. See the GNU General Public License for more
26423+ * details.
26424+ *
26425+ * You should have received a copy of the GNU General Public License
26426+ * along with this file; if not, write to the Free Software
26427+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26428+ * or visit http://www.gnu.org/licenses/.
26429+ *
26430+ * This file may also be available under a different license from Cavium.
26431+ * Contact Cavium Networks for more information
26432+**********************************************************************/
26433+
26434+/*
26435+ * External interface for the Cavium Octeon ethernet driver.
26436+ */
26437+#ifndef OCTEON_ETHERNET_H
26438+#define OCTEON_ETHERNET_H
26439+
26440+/**
26441+ * This is the definition of the Ethernet driver's private
26442+ * driver state stored in netdev_priv(dev).
26443+ */
26444+struct octeon_ethernet {
26445+ /* PKO hardware output port */
26446+ int port;
26447+ /* PKO hardware queue for the port */
26448+ int queue;
26449+ /* Hardware fetch and add to count outstanding tx buffers */
26450+ int fau;
26451+ /*
26452+ * Type of port. This is one of the enums in
26453+ * cvmx_helper_interface_mode_t
26454+ */
26455+ int imode;
26456+ /* List of outstanding tx buffers per queue */
26457+ struct sk_buff_head tx_free_list[16];
26458+ /* Device statistics */
26459+ struct net_device_stats stats
26460+; /* Generic MII info structure */
26461+ struct mii_if_info mii_info;
26462+ /* Last negotiated link state */
26463+ uint64_t link_info;
26464+ /* Called periodically to check link status */
26465+ void (*poll) (struct net_device *dev);
26466+};
26467+
26468+/**
26469+ * Free a work queue entry received in a intercept callback.
26470+ *
26471+ * @work_queue_entry:
26472+ * Work queue entry to free
26473+ * Returns Zero on success, Negative on failure.
26474+ */
26475+int cvm_oct_free_work(void *work_queue_entry);
26476+
26477+/**
26478+ * Transmit a work queue entry out of the ethernet port. Both
26479+ * the work queue entry and the packet data can optionally be
26480+ * freed. The work will be freed on error as well.
26481+ *
26482+ * @dev: Device to transmit out.
26483+ * @work_queue_entry:
26484+ * Work queue entry to send
26485+ * @do_free: True if the work queue entry and packet data should be
26486+ * freed. If false, neither will be freed.
26487+ * @qos: Index into the queues for this port to transmit on. This
26488+ * is used to implement QoS if their are multiple queues per
26489+ * port. This parameter must be between 0 and the number of
26490+ * queues per port minus 1. Values outside of this range will
26491+ * be change to zero.
26492+ *
26493+ * Returns Zero on success, negative on failure.
26494+ */
26495+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
26496+ int do_free, int qos);
26497+
26498+/**
26499+ * Transmit a work queue entry out of the ethernet port. Both
26500+ * the work queue entry and the packet data can optionally be
26501+ * freed. The work will be freed on error as well. This simply
26502+ * wraps cvmx_oct_transmit_qos() for backwards compatability.
26503+ *
26504+ * @dev: Device to transmit out.
26505+ * @work_queue_entry:
26506+ * Work queue entry to send
26507+ * @do_free: True if the work queue entry and packet data should be
26508+ * freed. If false, neither will be freed.
26509+ *
26510+ * Returns Zero on success, negative on failure.
26511+ */
26512+static inline int cvm_oct_transmit(struct net_device *dev,
26513+ void *work_queue_entry, int do_free)
26514+{
26515+ return cvm_oct_transmit_qos(dev, work_queue_entry, do_free, 0);
26516+}
26517+
26518+extern int cvm_oct_rgmii_init(struct net_device *dev);
26519+extern void cvm_oct_rgmii_uninit(struct net_device *dev);
26520+extern int cvm_oct_sgmii_init(struct net_device *dev);
26521+extern void cvm_oct_sgmii_uninit(struct net_device *dev);
26522+extern int cvm_oct_spi_init(struct net_device *dev);
26523+extern void cvm_oct_spi_uninit(struct net_device *dev);
26524+extern int cvm_oct_xaui_init(struct net_device *dev);
26525+extern void cvm_oct_xaui_uninit(struct net_device *dev);
26526+
26527+extern int always_use_pow;
26528+extern int pow_send_group;
26529+extern int pow_receive_group;
26530+extern char pow_send_list[];
26531+extern struct net_device *cvm_oct_device[];
26532+
26533+#endif
26534

Archive Download this file



interactive