[brcm63xx] add missing SSB_BLOCKIO to prevent build failres, will resolve that global...
[openwrt/svn-archive/archive.git] / target / linux / cavium-octeon / patches / 011-octeon_ethernet_driver.patch
1 The octeon-ethernet driver supports the sgmii, rgmii, spi, and xaui
2 ports present on the Cavium OCTEON family of SOCs. These SOCs are
3 multi-core mips64 processors with existing support over in arch/mips.
4
5 The driver files can be categorized into three basic groups:
6
7 1) Register definitions, these are named cvmx-*-defs.h
8
9 2) Main driver code, these have names that don't start cvmx-.
10
11 3) Interface specific functions and other utility code, names starting
12 with cvmx-
13
14 Signed-off-by: David Daney <ddaney@caviumnetworks.com>
15 ---
16 drivers/staging/octeon/Kconfig | 12 +
17 drivers/staging/octeon/Makefile | 30 +
18 drivers/staging/octeon/cvmx-address.h | 274 +++
19 drivers/staging/octeon/cvmx-asxx-defs.h | 475 +++++
20 drivers/staging/octeon/cvmx-cmd-queue.c | 306 +++
21 drivers/staging/octeon/cvmx-cmd-queue.h | 617 ++++++
22 drivers/staging/octeon/cvmx-config.h | 169 ++
23 drivers/staging/octeon/cvmx-dbg-defs.h | 72 +
24 drivers/staging/octeon/cvmx-fau.h | 597 ++++++
25 drivers/staging/octeon/cvmx-fpa-defs.h | 403 ++++
26 drivers/staging/octeon/cvmx-fpa.c | 183 ++
27 drivers/staging/octeon/cvmx-fpa.h | 299 +++
28 drivers/staging/octeon/cvmx-gmxx-defs.h | 2529 +++++++++++++++++++++++
29 drivers/staging/octeon/cvmx-helper-board.c | 706 +++++++
30 drivers/staging/octeon/cvmx-helper-board.h | 180 ++
31 drivers/staging/octeon/cvmx-helper-fpa.c | 243 +++
32 drivers/staging/octeon/cvmx-helper-fpa.h | 64 +
33 drivers/staging/octeon/cvmx-helper-loop.c | 85 +
34 drivers/staging/octeon/cvmx-helper-loop.h | 59 +
35 drivers/staging/octeon/cvmx-helper-npi.c | 113 +
36 drivers/staging/octeon/cvmx-helper-npi.h | 60 +
37 drivers/staging/octeon/cvmx-helper-rgmii.c | 525 +++++
38 drivers/staging/octeon/cvmx-helper-rgmii.h | 110 +
39 drivers/staging/octeon/cvmx-helper-sgmii.c | 550 +++++
40 drivers/staging/octeon/cvmx-helper-sgmii.h | 104 +
41 drivers/staging/octeon/cvmx-helper-spi.c | 195 ++
42 drivers/staging/octeon/cvmx-helper-spi.h | 84 +
43 drivers/staging/octeon/cvmx-helper-util.c | 433 ++++
44 drivers/staging/octeon/cvmx-helper-util.h | 215 ++
45 drivers/staging/octeon/cvmx-helper-xaui.c | 348 ++++
46 drivers/staging/octeon/cvmx-helper-xaui.h | 103 +
47 drivers/staging/octeon/cvmx-helper.c | 1058 ++++++++++
48 drivers/staging/octeon/cvmx-helper.h | 227 ++
49 drivers/staging/octeon/cvmx-interrupt-decodes.c | 371 ++++
50 drivers/staging/octeon/cvmx-interrupt-rsl.c | 140 ++
51 drivers/staging/octeon/cvmx-ipd.h | 338 +++
52 drivers/staging/octeon/cvmx-mdio.h | 506 +++++
53 drivers/staging/octeon/cvmx-packet.h | 65 +
54 drivers/staging/octeon/cvmx-pcsx-defs.h | 370 ++++
55 drivers/staging/octeon/cvmx-pcsxx-defs.h | 316 +++
56 drivers/staging/octeon/cvmx-pip-defs.h | 1267 ++++++++++++
57 drivers/staging/octeon/cvmx-pip.h | 524 +++++
58 drivers/staging/octeon/cvmx-pko-defs.h | 1133 ++++++++++
59 drivers/staging/octeon/cvmx-pko.c | 506 +++++
60 drivers/staging/octeon/cvmx-pko.h | 610 ++++++
61 drivers/staging/octeon/cvmx-pow.h | 1982 ++++++++++++++++++
62 drivers/staging/octeon/cvmx-scratch.h | 139 ++
63 drivers/staging/octeon/cvmx-smix-defs.h | 178 ++
64 drivers/staging/octeon/cvmx-spi.c | 667 ++++++
65 drivers/staging/octeon/cvmx-spi.h | 269 +++
66 drivers/staging/octeon/cvmx-spxx-defs.h | 347 ++++
67 drivers/staging/octeon/cvmx-srxx-defs.h | 126 ++
68 drivers/staging/octeon/cvmx-stxx-defs.h | 292 +++
69 drivers/staging/octeon/cvmx-wqe.h | 397 ++++
70 drivers/staging/octeon/ethernet-common.c | 328 +++
71 drivers/staging/octeon/ethernet-common.h | 29 +
72 drivers/staging/octeon/ethernet-defines.h | 134 ++
73 drivers/staging/octeon/ethernet-mdio.c | 231 +++
74 drivers/staging/octeon/ethernet-mdio.h | 46 +
75 drivers/staging/octeon/ethernet-mem.c | 198 ++
76 drivers/staging/octeon/ethernet-mem.h | 29 +
77 drivers/staging/octeon/ethernet-proc.c | 256 +++
78 drivers/staging/octeon/ethernet-proc.h | 29 +
79 drivers/staging/octeon/ethernet-rgmii.c | 397 ++++
80 drivers/staging/octeon/ethernet-rx.c | 505 +++++
81 drivers/staging/octeon/ethernet-rx.h | 33 +
82 drivers/staging/octeon/ethernet-sgmii.c | 129 ++
83 drivers/staging/octeon/ethernet-spi.c | 323 +++
84 drivers/staging/octeon/ethernet-tx.c | 634 ++++++
85 drivers/staging/octeon/ethernet-tx.h | 32 +
86 drivers/staging/octeon/ethernet-util.h | 81 +
87 drivers/staging/octeon/ethernet-xaui.c | 127 ++
88 drivers/staging/octeon/ethernet.c | 507 +++++
89 drivers/staging/octeon/octeon-ethernet.h | 127 ++
90 74 files changed, 26146 insertions(+), 0 deletions(-)
91 create mode 100644 drivers/staging/octeon/Kconfig
92 create mode 100644 drivers/staging/octeon/Makefile
93 create mode 100644 drivers/staging/octeon/cvmx-address.h
94 create mode 100644 drivers/staging/octeon/cvmx-asxx-defs.h
95 create mode 100644 drivers/staging/octeon/cvmx-cmd-queue.c
96 create mode 100644 drivers/staging/octeon/cvmx-cmd-queue.h
97 create mode 100644 drivers/staging/octeon/cvmx-config.h
98 create mode 100644 drivers/staging/octeon/cvmx-dbg-defs.h
99 create mode 100644 drivers/staging/octeon/cvmx-fau.h
100 create mode 100644 drivers/staging/octeon/cvmx-fpa-defs.h
101 create mode 100644 drivers/staging/octeon/cvmx-fpa.c
102 create mode 100644 drivers/staging/octeon/cvmx-fpa.h
103 create mode 100644 drivers/staging/octeon/cvmx-gmxx-defs.h
104 create mode 100644 drivers/staging/octeon/cvmx-helper-board.c
105 create mode 100644 drivers/staging/octeon/cvmx-helper-board.h
106 create mode 100644 drivers/staging/octeon/cvmx-helper-fpa.c
107 create mode 100644 drivers/staging/octeon/cvmx-helper-fpa.h
108 create mode 100644 drivers/staging/octeon/cvmx-helper-loop.c
109 create mode 100644 drivers/staging/octeon/cvmx-helper-loop.h
110 create mode 100644 drivers/staging/octeon/cvmx-helper-npi.c
111 create mode 100644 drivers/staging/octeon/cvmx-helper-npi.h
112 create mode 100644 drivers/staging/octeon/cvmx-helper-rgmii.c
113 create mode 100644 drivers/staging/octeon/cvmx-helper-rgmii.h
114 create mode 100644 drivers/staging/octeon/cvmx-helper-sgmii.c
115 create mode 100644 drivers/staging/octeon/cvmx-helper-sgmii.h
116 create mode 100644 drivers/staging/octeon/cvmx-helper-spi.c
117 create mode 100644 drivers/staging/octeon/cvmx-helper-spi.h
118 create mode 100644 drivers/staging/octeon/cvmx-helper-util.c
119 create mode 100644 drivers/staging/octeon/cvmx-helper-util.h
120 create mode 100644 drivers/staging/octeon/cvmx-helper-xaui.c
121 create mode 100644 drivers/staging/octeon/cvmx-helper-xaui.h
122 create mode 100644 drivers/staging/octeon/cvmx-helper.c
123 create mode 100644 drivers/staging/octeon/cvmx-helper.h
124 create mode 100644 drivers/staging/octeon/cvmx-interrupt-decodes.c
125 create mode 100644 drivers/staging/octeon/cvmx-interrupt-rsl.c
126 create mode 100644 drivers/staging/octeon/cvmx-ipd.h
127 create mode 100644 drivers/staging/octeon/cvmx-mdio.h
128 create mode 100644 drivers/staging/octeon/cvmx-packet.h
129 create mode 100644 drivers/staging/octeon/cvmx-pcsx-defs.h
130 create mode 100644 drivers/staging/octeon/cvmx-pcsxx-defs.h
131 create mode 100644 drivers/staging/octeon/cvmx-pip-defs.h
132 create mode 100644 drivers/staging/octeon/cvmx-pip.h
133 create mode 100644 drivers/staging/octeon/cvmx-pko-defs.h
134 create mode 100644 drivers/staging/octeon/cvmx-pko.c
135 create mode 100644 drivers/staging/octeon/cvmx-pko.h
136 create mode 100644 drivers/staging/octeon/cvmx-pow.h
137 create mode 100644 drivers/staging/octeon/cvmx-scratch.h
138 create mode 100644 drivers/staging/octeon/cvmx-smix-defs.h
139 create mode 100644 drivers/staging/octeon/cvmx-spi.c
140 create mode 100644 drivers/staging/octeon/cvmx-spi.h
141 create mode 100644 drivers/staging/octeon/cvmx-spxx-defs.h
142 create mode 100644 drivers/staging/octeon/cvmx-srxx-defs.h
143 create mode 100644 drivers/staging/octeon/cvmx-stxx-defs.h
144 create mode 100644 drivers/staging/octeon/cvmx-wqe.h
145 create mode 100644 drivers/staging/octeon/ethernet-common.c
146 create mode 100644 drivers/staging/octeon/ethernet-common.h
147 create mode 100644 drivers/staging/octeon/ethernet-defines.h
148 create mode 100644 drivers/staging/octeon/ethernet-mdio.c
149 create mode 100644 drivers/staging/octeon/ethernet-mdio.h
150 create mode 100644 drivers/staging/octeon/ethernet-mem.c
151 create mode 100644 drivers/staging/octeon/ethernet-mem.h
152 create mode 100644 drivers/staging/octeon/ethernet-proc.c
153 create mode 100644 drivers/staging/octeon/ethernet-proc.h
154 create mode 100644 drivers/staging/octeon/ethernet-rgmii.c
155 create mode 100644 drivers/staging/octeon/ethernet-rx.c
156 create mode 100644 drivers/staging/octeon/ethernet-rx.h
157 create mode 100644 drivers/staging/octeon/ethernet-sgmii.c
158 create mode 100644 drivers/staging/octeon/ethernet-spi.c
159 create mode 100644 drivers/staging/octeon/ethernet-tx.c
160 create mode 100644 drivers/staging/octeon/ethernet-tx.h
161 create mode 100644 drivers/staging/octeon/ethernet-util.h
162 create mode 100644 drivers/staging/octeon/ethernet-xaui.c
163 create mode 100644 drivers/staging/octeon/ethernet.c
164 create mode 100644 drivers/staging/octeon/octeon-ethernet.h
165
166 diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig
167 new file mode 100644
168 index 0000000..536e238
169 --- /dev/null
170 +++ b/drivers/staging/octeon/Kconfig
171 @@ -0,0 +1,12 @@
172 +config OCTEON_ETHERNET
173 + tristate "Cavium Networks Octeon Ethernet support"
174 + depends on CPU_CAVIUM_OCTEON
175 + select MII
176 + help
177 + This driver supports the builtin ethernet ports on Cavium
178 + Networks' products in the Octeon family. This driver supports the
179 + CN3XXX and CN5XXX Octeon processors.
180 +
181 + To compile this driver as a module, choose M here. The module
182 + will be called octeon-ethernet.
183 +
184 diff --git a/drivers/staging/octeon/Makefile b/drivers/staging/octeon/Makefile
185 new file mode 100644
186 index 0000000..3c839e3
187 --- /dev/null
188 +++ b/drivers/staging/octeon/Makefile
189 @@ -0,0 +1,30 @@
190 +# This file is subject to the terms and conditions of the GNU General Public
191 +# License. See the file "COPYING" in the main directory of this archive
192 +# for more details.
193 +#
194 +# Copyright (C) 2005-2009 Cavium Networks
195 +#
196 +
197 +#
198 +# Makefile for Cavium OCTEON on-board ethernet driver
199 +#
200 +
201 +obj-${CONFIG_OCTEON_ETHERNET} := octeon-ethernet.o
202 +
203 +octeon-ethernet-objs := ethernet.o
204 +octeon-ethernet-objs += ethernet-common.o
205 +octeon-ethernet-objs += ethernet-mdio.o
206 +octeon-ethernet-objs += ethernet-mem.o
207 +octeon-ethernet-objs += ethernet-proc.o
208 +octeon-ethernet-objs += ethernet-rgmii.o
209 +octeon-ethernet-objs += ethernet-rx.o
210 +octeon-ethernet-objs += ethernet-sgmii.o
211 +octeon-ethernet-objs += ethernet-spi.o
212 +octeon-ethernet-objs += ethernet-tx.o
213 +octeon-ethernet-objs += ethernet-xaui.o
214 +octeon-ethernet-objs += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \
215 + cvmx-helper-board.o cvmx-helper.o cvmx-helper-xaui.o \
216 + cvmx-helper-rgmii.o cvmx-helper-sgmii.o cvmx-helper-npi.o \
217 + cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \
218 + cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o
219 +
220 diff --git a/drivers/staging/octeon/cvmx-address.h b/drivers/staging/octeon/cvmx-address.h
221 new file mode 100644
222 index 0000000..3c74d82
223 --- /dev/null
224 +++ b/drivers/staging/octeon/cvmx-address.h
225 @@ -0,0 +1,274 @@
226 +/***********************license start***************
227 + * Author: Cavium Networks
228 + *
229 + * Contact: support@caviumnetworks.com
230 + * This file is part of the OCTEON SDK
231 + *
232 + * Copyright (c) 2003-2009 Cavium Networks
233 + *
234 + * This file is free software; you can redistribute it and/or modify
235 + * it under the terms of the GNU General Public License, Version 2, as
236 + * published by the Free Software Foundation.
237 + *
238 + * This file is distributed in the hope that it will be useful, but
239 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
240 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
241 + * NONINFRINGEMENT. See the GNU General Public License for more
242 + * details.
243 + *
244 + * You should have received a copy of the GNU General Public License
245 + * along with this file; if not, write to the Free Software
246 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
247 + * or visit http://www.gnu.org/licenses/.
248 + *
249 + * This file may also be available under a different license from Cavium.
250 + * Contact Cavium Networks for more information
251 + ***********************license end**************************************/
252 +
253 +/**
254 + * Typedefs and defines for working with Octeon physical addresses.
255 + *
256 + */
257 +#ifndef __CVMX_ADDRESS_H__
258 +#define __CVMX_ADDRESS_H__
259 +
260 +#if 0
261 +typedef enum {
262 + CVMX_MIPS_SPACE_XKSEG = 3LL,
263 + CVMX_MIPS_SPACE_XKPHYS = 2LL,
264 + CVMX_MIPS_SPACE_XSSEG = 1LL,
265 + CVMX_MIPS_SPACE_XUSEG = 0LL
266 +} cvmx_mips_space_t;
267 +#endif
268 +
269 +typedef enum {
270 + CVMX_MIPS_XKSEG_SPACE_KSEG0 = 0LL,
271 + CVMX_MIPS_XKSEG_SPACE_KSEG1 = 1LL,
272 + CVMX_MIPS_XKSEG_SPACE_SSEG = 2LL,
273 + CVMX_MIPS_XKSEG_SPACE_KSEG3 = 3LL
274 +} cvmx_mips_xkseg_space_t;
275 +
276 +/* decodes <14:13> of a kseg3 window address */
277 +typedef enum {
278 + CVMX_ADD_WIN_SCR = 0L,
279 + /* see cvmx_add_win_dma_dec_t for further decode */
280 + CVMX_ADD_WIN_DMA = 1L,
281 + CVMX_ADD_WIN_UNUSED = 2L,
282 + CVMX_ADD_WIN_UNUSED2 = 3L
283 +} cvmx_add_win_dec_t;
284 +
285 +/* decode within DMA space */
286 +typedef enum {
287 + /*
288 + * Add store data to the write buffer entry, allocating it if
289 + * necessary.
290 + */
291 + CVMX_ADD_WIN_DMA_ADD = 0L,
292 + /* send out the write buffer entry to DRAM */
293 + CVMX_ADD_WIN_DMA_SENDMEM = 1L,
294 + /* store data must be normal DRAM memory space address in this case */
295 + /* send out the write buffer entry as an IOBDMA command */
296 + CVMX_ADD_WIN_DMA_SENDDMA = 2L,
297 + /* see CVMX_ADD_WIN_DMA_SEND_DEC for data contents */
298 + /* send out the write buffer entry as an IO write */
299 + CVMX_ADD_WIN_DMA_SENDIO = 3L,
300 + /* store data must be normal IO space address in this case */
301 + /* send out a single-tick command on the NCB bus */
302 + CVMX_ADD_WIN_DMA_SENDSINGLE = 4L,
303 + /* no write buffer data needed/used */
304 +} cvmx_add_win_dma_dec_t;
305 +
306 +/*
307 + * Physical Address Decode
308 + *
309 + * Octeon-I HW never interprets this X (<39:36> reserved
310 + * for future expansion), software should set to 0.
311 + *
312 + * - 0x0 XXX0 0000 0000 to DRAM Cached
313 + * - 0x0 XXX0 0FFF FFFF
314 + *
315 + * - 0x0 XXX0 1000 0000 to Boot Bus Uncached (Converted to 0x1 00X0 1000 0000
316 + * - 0x0 XXX0 1FFF FFFF + EJTAG to 0x1 00X0 1FFF FFFF)
317 + *
318 + * - 0x0 XXX0 2000 0000 to DRAM Cached
319 + * - 0x0 XXXF FFFF FFFF
320 + *
321 + * - 0x1 00X0 0000 0000 to Boot Bus Uncached
322 + * - 0x1 00XF FFFF FFFF
323 + *
324 + * - 0x1 01X0 0000 0000 to Other NCB Uncached
325 + * - 0x1 FFXF FFFF FFFF devices
326 + *
327 + * Decode of all Octeon addresses
328 + */
329 +typedef union {
330 +
331 + uint64_t u64;
332 + /* mapped or unmapped virtual address */
333 + struct {
334 + uint64_t R:2;
335 + uint64_t offset:62;
336 + } sva;
337 +
338 + /* mapped USEG virtual addresses (typically) */
339 + struct {
340 + uint64_t zeroes:33;
341 + uint64_t offset:31;
342 + } suseg;
343 +
344 + /* mapped or unmapped virtual address */
345 + struct {
346 + uint64_t ones:33;
347 + uint64_t sp:2;
348 + uint64_t offset:29;
349 + } sxkseg;
350 +
351 + /*
352 + * physical address accessed through xkphys unmapped virtual
353 + * address.
354 + */
355 + struct {
356 + uint64_t R:2; /* CVMX_MIPS_SPACE_XKPHYS in this case */
357 + uint64_t cca:3; /* ignored by octeon */
358 + uint64_t mbz:10;
359 + uint64_t pa:49; /* physical address */
360 + } sxkphys;
361 +
362 + /* physical address */
363 + struct {
364 + uint64_t mbz:15;
365 + /* if set, the address is uncached and resides on MCB bus */
366 + uint64_t is_io:1;
367 + /*
368 + * the hardware ignores this field when is_io==0, else
369 + * device ID.
370 + */
371 + uint64_t did:8;
372 + /* the hardware ignores <39:36> in Octeon I */
373 + uint64_t unaddr:4;
374 + uint64_t offset:36;
375 + } sphys;
376 +
377 + /* physical mem address */
378 + struct {
379 + /* techically, <47:40> are dont-cares */
380 + uint64_t zeroes:24;
381 + /* the hardware ignores <39:36> in Octeon I */
382 + uint64_t unaddr:4;
383 + uint64_t offset:36;
384 + } smem;
385 +
386 + /* physical IO address */
387 + struct {
388 + uint64_t mem_region:2;
389 + uint64_t mbz:13;
390 + /* 1 in this case */
391 + uint64_t is_io:1;
392 + /*
393 + * The hardware ignores this field when is_io==0, else
394 + * device ID.
395 + */
396 + uint64_t did:8;
397 + /* the hardware ignores <39:36> in Octeon I */
398 + uint64_t unaddr:4;
399 + uint64_t offset:36;
400 + } sio;
401 +
402 + /*
403 + * Scratchpad virtual address - accessed through a window at
404 + * the end of kseg3
405 + */
406 + struct {
407 + uint64_t ones:49;
408 + /* CVMX_ADD_WIN_SCR (0) in this case */
409 + cvmx_add_win_dec_t csrdec:2;
410 + uint64_t addr:13;
411 + } sscr;
412 +
413 + /* there should only be stores to IOBDMA space, no loads */
414 + /*
415 + * IOBDMA virtual address - accessed through a window at the
416 + * end of kseg3
417 + */
418 + struct {
419 + uint64_t ones:49;
420 + uint64_t csrdec:2; /* CVMX_ADD_WIN_DMA (1) in this case */
421 + uint64_t unused2:3;
422 + uint64_t type:3;
423 + uint64_t addr:7;
424 + } sdma;
425 +
426 + struct {
427 + uint64_t didspace:24;
428 + uint64_t unused:40;
429 + } sfilldidspace;
430 +
431 +} cvmx_addr_t;
432 +
433 +/* These macros for used by 32 bit applications */
434 +
435 +#define CVMX_MIPS32_SPACE_KSEG0 1l
436 +#define CVMX_ADD_SEG32(segment, add) \
437 + (((int32_t)segment << 31) | (int32_t)(add))
438 +
439 +/*
440 + * Currently all IOs are performed using XKPHYS addressing. Linux uses
441 + * the CvmMemCtl register to enable XKPHYS addressing to IO space from
442 + * user mode. Future OSes may need to change the upper bits of IO
443 + * addresses. The following define controls the upper two bits for all
444 + * IO addresses generated by the simple executive library.
445 + */
446 +#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
447 +
448 +/* These macros simplify the process of creating common IO addresses */
449 +#define CVMX_ADD_SEG(segment, add) ((((uint64_t)segment) << 62) | (add))
450 +#ifndef CVMX_ADD_IO_SEG
451 +#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
452 +#endif
453 +#define CVMX_ADDR_DIDSPACE(did) (((CVMX_IO_SEG) << 22) | ((1ULL) << 8) | (did))
454 +#define CVMX_ADDR_DID(did) (CVMX_ADDR_DIDSPACE(did) << 40)
455 +#define CVMX_FULL_DID(did, subdid) (((did) << 3) | (subdid))
456 +
457 + /* from include/ncb_rsl_id.v */
458 +#define CVMX_OCT_DID_MIS 0ULL /* misc stuff */
459 +#define CVMX_OCT_DID_GMX0 1ULL
460 +#define CVMX_OCT_DID_GMX1 2ULL
461 +#define CVMX_OCT_DID_PCI 3ULL
462 +#define CVMX_OCT_DID_KEY 4ULL
463 +#define CVMX_OCT_DID_FPA 5ULL
464 +#define CVMX_OCT_DID_DFA 6ULL
465 +#define CVMX_OCT_DID_ZIP 7ULL
466 +#define CVMX_OCT_DID_RNG 8ULL
467 +#define CVMX_OCT_DID_IPD 9ULL
468 +#define CVMX_OCT_DID_PKT 10ULL
469 +#define CVMX_OCT_DID_TIM 11ULL
470 +#define CVMX_OCT_DID_TAG 12ULL
471 + /* the rest are not on the IO bus */
472 +#define CVMX_OCT_DID_L2C 16ULL
473 +#define CVMX_OCT_DID_LMC 17ULL
474 +#define CVMX_OCT_DID_SPX0 18ULL
475 +#define CVMX_OCT_DID_SPX1 19ULL
476 +#define CVMX_OCT_DID_PIP 20ULL
477 +#define CVMX_OCT_DID_ASX0 22ULL
478 +#define CVMX_OCT_DID_ASX1 23ULL
479 +#define CVMX_OCT_DID_IOB 30ULL
480 +
481 +#define CVMX_OCT_DID_PKT_SEND CVMX_FULL_DID(CVMX_OCT_DID_PKT, 2ULL)
482 +#define CVMX_OCT_DID_TAG_SWTAG CVMX_FULL_DID(CVMX_OCT_DID_TAG, 0ULL)
483 +#define CVMX_OCT_DID_TAG_TAG1 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 1ULL)
484 +#define CVMX_OCT_DID_TAG_TAG2 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 2ULL)
485 +#define CVMX_OCT_DID_TAG_TAG3 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 3ULL)
486 +#define CVMX_OCT_DID_TAG_NULL_RD CVMX_FULL_DID(CVMX_OCT_DID_TAG, 4ULL)
487 +#define CVMX_OCT_DID_TAG_CSR CVMX_FULL_DID(CVMX_OCT_DID_TAG, 7ULL)
488 +#define CVMX_OCT_DID_FAU_FAI CVMX_FULL_DID(CVMX_OCT_DID_IOB, 0ULL)
489 +#define CVMX_OCT_DID_TIM_CSR CVMX_FULL_DID(CVMX_OCT_DID_TIM, 0ULL)
490 +#define CVMX_OCT_DID_KEY_RW CVMX_FULL_DID(CVMX_OCT_DID_KEY, 0ULL)
491 +#define CVMX_OCT_DID_PCI_6 CVMX_FULL_DID(CVMX_OCT_DID_PCI, 6ULL)
492 +#define CVMX_OCT_DID_MIS_BOO CVMX_FULL_DID(CVMX_OCT_DID_MIS, 0ULL)
493 +#define CVMX_OCT_DID_PCI_RML CVMX_FULL_DID(CVMX_OCT_DID_PCI, 0ULL)
494 +#define CVMX_OCT_DID_IPD_CSR CVMX_FULL_DID(CVMX_OCT_DID_IPD, 7ULL)
495 +#define CVMX_OCT_DID_DFA_CSR CVMX_FULL_DID(CVMX_OCT_DID_DFA, 7ULL)
496 +#define CVMX_OCT_DID_MIS_CSR CVMX_FULL_DID(CVMX_OCT_DID_MIS, 7ULL)
497 +#define CVMX_OCT_DID_ZIP_CSR CVMX_FULL_DID(CVMX_OCT_DID_ZIP, 0ULL)
498 +
499 +#endif /* __CVMX_ADDRESS_H__ */
500 diff --git a/drivers/staging/octeon/cvmx-asxx-defs.h b/drivers/staging/octeon/cvmx-asxx-defs.h
501 new file mode 100644
502 index 0000000..91415a8
503 --- /dev/null
504 +++ b/drivers/staging/octeon/cvmx-asxx-defs.h
505 @@ -0,0 +1,475 @@
506 +/***********************license start***************
507 + * Author: Cavium Networks
508 + *
509 + * Contact: support@caviumnetworks.com
510 + * This file is part of the OCTEON SDK
511 + *
512 + * Copyright (c) 2003-2008 Cavium Networks
513 + *
514 + * This file is free software; you can redistribute it and/or modify
515 + * it under the terms of the GNU General Public License, Version 2, as
516 + * published by the Free Software Foundation.
517 + *
518 + * This file is distributed in the hope that it will be useful, but
519 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
520 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
521 + * NONINFRINGEMENT. See the GNU General Public License for more
522 + * details.
523 + *
524 + * You should have received a copy of the GNU General Public License
525 + * along with this file; if not, write to the Free Software
526 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
527 + * or visit http://www.gnu.org/licenses/.
528 + *
529 + * This file may also be available under a different license from Cavium.
530 + * Contact Cavium Networks for more information
531 + ***********************license end**************************************/
532 +
533 +#ifndef __CVMX_ASXX_DEFS_H__
534 +#define __CVMX_ASXX_DEFS_H__
535 +
536 +#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) \
537 + CVMX_ADD_IO_SEG(0x00011800B0000180ull + (((block_id) & 0) * 0x8000000ull))
538 +#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) \
539 + CVMX_ADD_IO_SEG(0x00011800B0000188ull + (((block_id) & 0) * 0x8000000ull))
540 +#define CVMX_ASXX_INT_EN(block_id) \
541 + CVMX_ADD_IO_SEG(0x00011800B0000018ull + (((block_id) & 1) * 0x8000000ull))
542 +#define CVMX_ASXX_INT_REG(block_id) \
543 + CVMX_ADD_IO_SEG(0x00011800B0000010ull + (((block_id) & 1) * 0x8000000ull))
544 +#define CVMX_ASXX_MII_RX_DAT_SET(block_id) \
545 + CVMX_ADD_IO_SEG(0x00011800B0000190ull + (((block_id) & 0) * 0x8000000ull))
546 +#define CVMX_ASXX_PRT_LOOP(block_id) \
547 + CVMX_ADD_IO_SEG(0x00011800B0000040ull + (((block_id) & 1) * 0x8000000ull))
548 +#define CVMX_ASXX_RLD_BYPASS(block_id) \
549 + CVMX_ADD_IO_SEG(0x00011800B0000248ull + (((block_id) & 1) * 0x8000000ull))
550 +#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) \
551 + CVMX_ADD_IO_SEG(0x00011800B0000250ull + (((block_id) & 1) * 0x8000000ull))
552 +#define CVMX_ASXX_RLD_COMP(block_id) \
553 + CVMX_ADD_IO_SEG(0x00011800B0000220ull + (((block_id) & 1) * 0x8000000ull))
554 +#define CVMX_ASXX_RLD_DATA_DRV(block_id) \
555 + CVMX_ADD_IO_SEG(0x00011800B0000218ull + (((block_id) & 1) * 0x8000000ull))
556 +#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) \
557 + CVMX_ADD_IO_SEG(0x00011800B0000210ull + (((block_id) & 1) * 0x8000000ull))
558 +#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) \
559 + CVMX_ADD_IO_SEG(0x00011800B0000230ull + (((block_id) & 1) * 0x8000000ull))
560 +#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) \
561 + CVMX_ADD_IO_SEG(0x00011800B0000240ull + (((block_id) & 1) * 0x8000000ull))
562 +#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) \
563 + CVMX_ADD_IO_SEG(0x00011800B0000228ull + (((block_id) & 1) * 0x8000000ull))
564 +#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) \
565 + CVMX_ADD_IO_SEG(0x00011800B0000238ull + (((block_id) & 1) * 0x8000000ull))
566 +#define CVMX_ASXX_RLD_SETTING(block_id) \
567 + CVMX_ADD_IO_SEG(0x00011800B0000258ull + (((block_id) & 1) * 0x8000000ull))
568 +#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) \
569 + CVMX_ADD_IO_SEG(0x00011800B0000020ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
570 +#define CVMX_ASXX_RX_PRT_EN(block_id) \
571 + CVMX_ADD_IO_SEG(0x00011800B0000000ull + (((block_id) & 1) * 0x8000000ull))
572 +#define CVMX_ASXX_RX_WOL(block_id) \
573 + CVMX_ADD_IO_SEG(0x00011800B0000100ull + (((block_id) & 1) * 0x8000000ull))
574 +#define CVMX_ASXX_RX_WOL_MSK(block_id) \
575 + CVMX_ADD_IO_SEG(0x00011800B0000108ull + (((block_id) & 1) * 0x8000000ull))
576 +#define CVMX_ASXX_RX_WOL_POWOK(block_id) \
577 + CVMX_ADD_IO_SEG(0x00011800B0000118ull + (((block_id) & 1) * 0x8000000ull))
578 +#define CVMX_ASXX_RX_WOL_SIG(block_id) \
579 + CVMX_ADD_IO_SEG(0x00011800B0000110ull + (((block_id) & 1) * 0x8000000ull))
580 +#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) \
581 + CVMX_ADD_IO_SEG(0x00011800B0000048ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
582 +#define CVMX_ASXX_TX_COMP_BYP(block_id) \
583 + CVMX_ADD_IO_SEG(0x00011800B0000068ull + (((block_id) & 1) * 0x8000000ull))
584 +#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) \
585 + CVMX_ADD_IO_SEG(0x00011800B0000080ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
586 +#define CVMX_ASXX_TX_PRT_EN(block_id) \
587 + CVMX_ADD_IO_SEG(0x00011800B0000008ull + (((block_id) & 1) * 0x8000000ull))
588 +
589 +union cvmx_asxx_gmii_rx_clk_set {
590 + uint64_t u64;
591 + struct cvmx_asxx_gmii_rx_clk_set_s {
592 + uint64_t reserved_5_63:59;
593 + uint64_t setting:5;
594 + } s;
595 + struct cvmx_asxx_gmii_rx_clk_set_s cn30xx;
596 + struct cvmx_asxx_gmii_rx_clk_set_s cn31xx;
597 + struct cvmx_asxx_gmii_rx_clk_set_s cn50xx;
598 +};
599 +
600 +union cvmx_asxx_gmii_rx_dat_set {
601 + uint64_t u64;
602 + struct cvmx_asxx_gmii_rx_dat_set_s {
603 + uint64_t reserved_5_63:59;
604 + uint64_t setting:5;
605 + } s;
606 + struct cvmx_asxx_gmii_rx_dat_set_s cn30xx;
607 + struct cvmx_asxx_gmii_rx_dat_set_s cn31xx;
608 + struct cvmx_asxx_gmii_rx_dat_set_s cn50xx;
609 +};
610 +
611 +union cvmx_asxx_int_en {
612 + uint64_t u64;
613 + struct cvmx_asxx_int_en_s {
614 + uint64_t reserved_12_63:52;
615 + uint64_t txpsh:4;
616 + uint64_t txpop:4;
617 + uint64_t ovrflw:4;
618 + } s;
619 + struct cvmx_asxx_int_en_cn30xx {
620 + uint64_t reserved_11_63:53;
621 + uint64_t txpsh:3;
622 + uint64_t reserved_7_7:1;
623 + uint64_t txpop:3;
624 + uint64_t reserved_3_3:1;
625 + uint64_t ovrflw:3;
626 + } cn30xx;
627 + struct cvmx_asxx_int_en_cn30xx cn31xx;
628 + struct cvmx_asxx_int_en_s cn38xx;
629 + struct cvmx_asxx_int_en_s cn38xxp2;
630 + struct cvmx_asxx_int_en_cn30xx cn50xx;
631 + struct cvmx_asxx_int_en_s cn58xx;
632 + struct cvmx_asxx_int_en_s cn58xxp1;
633 +};
634 +
635 +union cvmx_asxx_int_reg {
636 + uint64_t u64;
637 + struct cvmx_asxx_int_reg_s {
638 + uint64_t reserved_12_63:52;
639 + uint64_t txpsh:4;
640 + uint64_t txpop:4;
641 + uint64_t ovrflw:4;
642 + } s;
643 + struct cvmx_asxx_int_reg_cn30xx {
644 + uint64_t reserved_11_63:53;
645 + uint64_t txpsh:3;
646 + uint64_t reserved_7_7:1;
647 + uint64_t txpop:3;
648 + uint64_t reserved_3_3:1;
649 + uint64_t ovrflw:3;
650 + } cn30xx;
651 + struct cvmx_asxx_int_reg_cn30xx cn31xx;
652 + struct cvmx_asxx_int_reg_s cn38xx;
653 + struct cvmx_asxx_int_reg_s cn38xxp2;
654 + struct cvmx_asxx_int_reg_cn30xx cn50xx;
655 + struct cvmx_asxx_int_reg_s cn58xx;
656 + struct cvmx_asxx_int_reg_s cn58xxp1;
657 +};
658 +
659 +union cvmx_asxx_mii_rx_dat_set {
660 + uint64_t u64;
661 + struct cvmx_asxx_mii_rx_dat_set_s {
662 + uint64_t reserved_5_63:59;
663 + uint64_t setting:5;
664 + } s;
665 + struct cvmx_asxx_mii_rx_dat_set_s cn30xx;
666 + struct cvmx_asxx_mii_rx_dat_set_s cn50xx;
667 +};
668 +
669 +union cvmx_asxx_prt_loop {
670 + uint64_t u64;
671 + struct cvmx_asxx_prt_loop_s {
672 + uint64_t reserved_8_63:56;
673 + uint64_t ext_loop:4;
674 + uint64_t int_loop:4;
675 + } s;
676 + struct cvmx_asxx_prt_loop_cn30xx {
677 + uint64_t reserved_7_63:57;
678 + uint64_t ext_loop:3;
679 + uint64_t reserved_3_3:1;
680 + uint64_t int_loop:3;
681 + } cn30xx;
682 + struct cvmx_asxx_prt_loop_cn30xx cn31xx;
683 + struct cvmx_asxx_prt_loop_s cn38xx;
684 + struct cvmx_asxx_prt_loop_s cn38xxp2;
685 + struct cvmx_asxx_prt_loop_cn30xx cn50xx;
686 + struct cvmx_asxx_prt_loop_s cn58xx;
687 + struct cvmx_asxx_prt_loop_s cn58xxp1;
688 +};
689 +
690 +union cvmx_asxx_rld_bypass {
691 + uint64_t u64;
692 + struct cvmx_asxx_rld_bypass_s {
693 + uint64_t reserved_1_63:63;
694 + uint64_t bypass:1;
695 + } s;
696 + struct cvmx_asxx_rld_bypass_s cn38xx;
697 + struct cvmx_asxx_rld_bypass_s cn38xxp2;
698 + struct cvmx_asxx_rld_bypass_s cn58xx;
699 + struct cvmx_asxx_rld_bypass_s cn58xxp1;
700 +};
701 +
702 +union cvmx_asxx_rld_bypass_setting {
703 + uint64_t u64;
704 + struct cvmx_asxx_rld_bypass_setting_s {
705 + uint64_t reserved_5_63:59;
706 + uint64_t setting:5;
707 + } s;
708 + struct cvmx_asxx_rld_bypass_setting_s cn38xx;
709 + struct cvmx_asxx_rld_bypass_setting_s cn38xxp2;
710 + struct cvmx_asxx_rld_bypass_setting_s cn58xx;
711 + struct cvmx_asxx_rld_bypass_setting_s cn58xxp1;
712 +};
713 +
714 +union cvmx_asxx_rld_comp {
715 + uint64_t u64;
716 + struct cvmx_asxx_rld_comp_s {
717 + uint64_t reserved_9_63:55;
718 + uint64_t pctl:5;
719 + uint64_t nctl:4;
720 + } s;
721 + struct cvmx_asxx_rld_comp_cn38xx {
722 + uint64_t reserved_8_63:56;
723 + uint64_t pctl:4;
724 + uint64_t nctl:4;
725 + } cn38xx;
726 + struct cvmx_asxx_rld_comp_cn38xx cn38xxp2;
727 + struct cvmx_asxx_rld_comp_s cn58xx;
728 + struct cvmx_asxx_rld_comp_s cn58xxp1;
729 +};
730 +
731 +union cvmx_asxx_rld_data_drv {
732 + uint64_t u64;
733 + struct cvmx_asxx_rld_data_drv_s {
734 + uint64_t reserved_8_63:56;
735 + uint64_t pctl:4;
736 + uint64_t nctl:4;
737 + } s;
738 + struct cvmx_asxx_rld_data_drv_s cn38xx;
739 + struct cvmx_asxx_rld_data_drv_s cn38xxp2;
740 + struct cvmx_asxx_rld_data_drv_s cn58xx;
741 + struct cvmx_asxx_rld_data_drv_s cn58xxp1;
742 +};
743 +
744 +union cvmx_asxx_rld_fcram_mode {
745 + uint64_t u64;
746 + struct cvmx_asxx_rld_fcram_mode_s {
747 + uint64_t reserved_1_63:63;
748 + uint64_t mode:1;
749 + } s;
750 + struct cvmx_asxx_rld_fcram_mode_s cn38xx;
751 + struct cvmx_asxx_rld_fcram_mode_s cn38xxp2;
752 +};
753 +
754 +union cvmx_asxx_rld_nctl_strong {
755 + uint64_t u64;
756 + struct cvmx_asxx_rld_nctl_strong_s {
757 + uint64_t reserved_5_63:59;
758 + uint64_t nctl:5;
759 + } s;
760 + struct cvmx_asxx_rld_nctl_strong_s cn38xx;
761 + struct cvmx_asxx_rld_nctl_strong_s cn38xxp2;
762 + struct cvmx_asxx_rld_nctl_strong_s cn58xx;
763 + struct cvmx_asxx_rld_nctl_strong_s cn58xxp1;
764 +};
765 +
766 +union cvmx_asxx_rld_nctl_weak {
767 + uint64_t u64;
768 + struct cvmx_asxx_rld_nctl_weak_s {
769 + uint64_t reserved_5_63:59;
770 + uint64_t nctl:5;
771 + } s;
772 + struct cvmx_asxx_rld_nctl_weak_s cn38xx;
773 + struct cvmx_asxx_rld_nctl_weak_s cn38xxp2;
774 + struct cvmx_asxx_rld_nctl_weak_s cn58xx;
775 + struct cvmx_asxx_rld_nctl_weak_s cn58xxp1;
776 +};
777 +
778 +union cvmx_asxx_rld_pctl_strong {
779 + uint64_t u64;
780 + struct cvmx_asxx_rld_pctl_strong_s {
781 + uint64_t reserved_5_63:59;
782 + uint64_t pctl:5;
783 + } s;
784 + struct cvmx_asxx_rld_pctl_strong_s cn38xx;
785 + struct cvmx_asxx_rld_pctl_strong_s cn38xxp2;
786 + struct cvmx_asxx_rld_pctl_strong_s cn58xx;
787 + struct cvmx_asxx_rld_pctl_strong_s cn58xxp1;
788 +};
789 +
790 +union cvmx_asxx_rld_pctl_weak {
791 + uint64_t u64;
792 + struct cvmx_asxx_rld_pctl_weak_s {
793 + uint64_t reserved_5_63:59;
794 + uint64_t pctl:5;
795 + } s;
796 + struct cvmx_asxx_rld_pctl_weak_s cn38xx;
797 + struct cvmx_asxx_rld_pctl_weak_s cn38xxp2;
798 + struct cvmx_asxx_rld_pctl_weak_s cn58xx;
799 + struct cvmx_asxx_rld_pctl_weak_s cn58xxp1;
800 +};
801 +
802 +union cvmx_asxx_rld_setting {
803 + uint64_t u64;
804 + struct cvmx_asxx_rld_setting_s {
805 + uint64_t reserved_13_63:51;
806 + uint64_t dfaset:5;
807 + uint64_t dfalag:1;
808 + uint64_t dfalead:1;
809 + uint64_t dfalock:1;
810 + uint64_t setting:5;
811 + } s;
812 + struct cvmx_asxx_rld_setting_cn38xx {
813 + uint64_t reserved_5_63:59;
814 + uint64_t setting:5;
815 + } cn38xx;
816 + struct cvmx_asxx_rld_setting_cn38xx cn38xxp2;
817 + struct cvmx_asxx_rld_setting_s cn58xx;
818 + struct cvmx_asxx_rld_setting_s cn58xxp1;
819 +};
820 +
821 +union cvmx_asxx_rx_clk_setx {
822 + uint64_t u64;
823 + struct cvmx_asxx_rx_clk_setx_s {
824 + uint64_t reserved_5_63:59;
825 + uint64_t setting:5;
826 + } s;
827 + struct cvmx_asxx_rx_clk_setx_s cn30xx;
828 + struct cvmx_asxx_rx_clk_setx_s cn31xx;
829 + struct cvmx_asxx_rx_clk_setx_s cn38xx;
830 + struct cvmx_asxx_rx_clk_setx_s cn38xxp2;
831 + struct cvmx_asxx_rx_clk_setx_s cn50xx;
832 + struct cvmx_asxx_rx_clk_setx_s cn58xx;
833 + struct cvmx_asxx_rx_clk_setx_s cn58xxp1;
834 +};
835 +
836 +union cvmx_asxx_rx_prt_en {
837 + uint64_t u64;
838 + struct cvmx_asxx_rx_prt_en_s {
839 + uint64_t reserved_4_63:60;
840 + uint64_t prt_en:4;
841 + } s;
842 + struct cvmx_asxx_rx_prt_en_cn30xx {
843 + uint64_t reserved_3_63:61;
844 + uint64_t prt_en:3;
845 + } cn30xx;
846 + struct cvmx_asxx_rx_prt_en_cn30xx cn31xx;
847 + struct cvmx_asxx_rx_prt_en_s cn38xx;
848 + struct cvmx_asxx_rx_prt_en_s cn38xxp2;
849 + struct cvmx_asxx_rx_prt_en_cn30xx cn50xx;
850 + struct cvmx_asxx_rx_prt_en_s cn58xx;
851 + struct cvmx_asxx_rx_prt_en_s cn58xxp1;
852 +};
853 +
854 +union cvmx_asxx_rx_wol {
855 + uint64_t u64;
856 + struct cvmx_asxx_rx_wol_s {
857 + uint64_t reserved_2_63:62;
858 + uint64_t status:1;
859 + uint64_t enable:1;
860 + } s;
861 + struct cvmx_asxx_rx_wol_s cn38xx;
862 + struct cvmx_asxx_rx_wol_s cn38xxp2;
863 +};
864 +
865 +union cvmx_asxx_rx_wol_msk {
866 + uint64_t u64;
867 + struct cvmx_asxx_rx_wol_msk_s {
868 + uint64_t msk:64;
869 + } s;
870 + struct cvmx_asxx_rx_wol_msk_s cn38xx;
871 + struct cvmx_asxx_rx_wol_msk_s cn38xxp2;
872 +};
873 +
874 +union cvmx_asxx_rx_wol_powok {
875 + uint64_t u64;
876 + struct cvmx_asxx_rx_wol_powok_s {
877 + uint64_t reserved_1_63:63;
878 + uint64_t powerok:1;
879 + } s;
880 + struct cvmx_asxx_rx_wol_powok_s cn38xx;
881 + struct cvmx_asxx_rx_wol_powok_s cn38xxp2;
882 +};
883 +
884 +union cvmx_asxx_rx_wol_sig {
885 + uint64_t u64;
886 + struct cvmx_asxx_rx_wol_sig_s {
887 + uint64_t reserved_32_63:32;
888 + uint64_t sig:32;
889 + } s;
890 + struct cvmx_asxx_rx_wol_sig_s cn38xx;
891 + struct cvmx_asxx_rx_wol_sig_s cn38xxp2;
892 +};
893 +
894 +union cvmx_asxx_tx_clk_setx {
895 + uint64_t u64;
896 + struct cvmx_asxx_tx_clk_setx_s {
897 + uint64_t reserved_5_63:59;
898 + uint64_t setting:5;
899 + } s;
900 + struct cvmx_asxx_tx_clk_setx_s cn30xx;
901 + struct cvmx_asxx_tx_clk_setx_s cn31xx;
902 + struct cvmx_asxx_tx_clk_setx_s cn38xx;
903 + struct cvmx_asxx_tx_clk_setx_s cn38xxp2;
904 + struct cvmx_asxx_tx_clk_setx_s cn50xx;
905 + struct cvmx_asxx_tx_clk_setx_s cn58xx;
906 + struct cvmx_asxx_tx_clk_setx_s cn58xxp1;
907 +};
908 +
909 +union cvmx_asxx_tx_comp_byp {
910 + uint64_t u64;
911 + struct cvmx_asxx_tx_comp_byp_s {
912 + uint64_t reserved_0_63:64;
913 + } s;
914 + struct cvmx_asxx_tx_comp_byp_cn30xx {
915 + uint64_t reserved_9_63:55;
916 + uint64_t bypass:1;
917 + uint64_t pctl:4;
918 + uint64_t nctl:4;
919 + } cn30xx;
920 + struct cvmx_asxx_tx_comp_byp_cn30xx cn31xx;
921 + struct cvmx_asxx_tx_comp_byp_cn38xx {
922 + uint64_t reserved_8_63:56;
923 + uint64_t pctl:4;
924 + uint64_t nctl:4;
925 + } cn38xx;
926 + struct cvmx_asxx_tx_comp_byp_cn38xx cn38xxp2;
927 + struct cvmx_asxx_tx_comp_byp_cn50xx {
928 + uint64_t reserved_17_63:47;
929 + uint64_t bypass:1;
930 + uint64_t reserved_13_15:3;
931 + uint64_t pctl:5;
932 + uint64_t reserved_5_7:3;
933 + uint64_t nctl:5;
934 + } cn50xx;
935 + struct cvmx_asxx_tx_comp_byp_cn58xx {
936 + uint64_t reserved_13_63:51;
937 + uint64_t pctl:5;
938 + uint64_t reserved_5_7:3;
939 + uint64_t nctl:5;
940 + } cn58xx;
941 + struct cvmx_asxx_tx_comp_byp_cn58xx cn58xxp1;
942 +};
943 +
944 +union cvmx_asxx_tx_hi_waterx {
945 + uint64_t u64;
946 + struct cvmx_asxx_tx_hi_waterx_s {
947 + uint64_t reserved_4_63:60;
948 + uint64_t mark:4;
949 + } s;
950 + struct cvmx_asxx_tx_hi_waterx_cn30xx {
951 + uint64_t reserved_3_63:61;
952 + uint64_t mark:3;
953 + } cn30xx;
954 + struct cvmx_asxx_tx_hi_waterx_cn30xx cn31xx;
955 + struct cvmx_asxx_tx_hi_waterx_s cn38xx;
956 + struct cvmx_asxx_tx_hi_waterx_s cn38xxp2;
957 + struct cvmx_asxx_tx_hi_waterx_cn30xx cn50xx;
958 + struct cvmx_asxx_tx_hi_waterx_s cn58xx;
959 + struct cvmx_asxx_tx_hi_waterx_s cn58xxp1;
960 +};
961 +
962 +union cvmx_asxx_tx_prt_en {
963 + uint64_t u64;
964 + struct cvmx_asxx_tx_prt_en_s {
965 + uint64_t reserved_4_63:60;
966 + uint64_t prt_en:4;
967 + } s;
968 + struct cvmx_asxx_tx_prt_en_cn30xx {
969 + uint64_t reserved_3_63:61;
970 + uint64_t prt_en:3;
971 + } cn30xx;
972 + struct cvmx_asxx_tx_prt_en_cn30xx cn31xx;
973 + struct cvmx_asxx_tx_prt_en_s cn38xx;
974 + struct cvmx_asxx_tx_prt_en_s cn38xxp2;
975 + struct cvmx_asxx_tx_prt_en_cn30xx cn50xx;
976 + struct cvmx_asxx_tx_prt_en_s cn58xx;
977 + struct cvmx_asxx_tx_prt_en_s cn58xxp1;
978 +};
979 +
980 +#endif
981 diff --git a/drivers/staging/octeon/cvmx-cmd-queue.c b/drivers/staging/octeon/cvmx-cmd-queue.c
982 new file mode 100644
983 index 0000000..976227b
984 --- /dev/null
985 +++ b/drivers/staging/octeon/cvmx-cmd-queue.c
986 @@ -0,0 +1,306 @@
987 +/***********************license start***************
988 + * Author: Cavium Networks
989 + *
990 + * Contact: support@caviumnetworks.com
991 + * This file is part of the OCTEON SDK
992 + *
993 + * Copyright (c) 2003-2008 Cavium Networks
994 + *
995 + * This file is free software; you can redistribute it and/or modify
996 + * it under the terms of the GNU General Public License, Version 2, as
997 + * published by the Free Software Foundation.
998 + *
999 + * This file is distributed in the hope that it will be useful, but
1000 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
1001 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
1002 + * NONINFRINGEMENT. See the GNU General Public License for more
1003 + * details.
1004 + *
1005 + * You should have received a copy of the GNU General Public License
1006 + * along with this file; if not, write to the Free Software
1007 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1008 + * or visit http://www.gnu.org/licenses/.
1009 + *
1010 + * This file may also be available under a different license from Cavium.
1011 + * Contact Cavium Networks for more information
1012 + ***********************license end**************************************/
1013 +
1014 +/*
1015 + * Support functions for managing command queues used for
1016 + * various hardware blocks.
1017 + */
1018 +
1019 +#include <linux/kernel.h>
1020 +
1021 +#include <asm/octeon/octeon.h>
1022 +
1023 +#include "cvmx-config.h"
1024 +#include "cvmx-fpa.h"
1025 +#include "cvmx-cmd-queue.h"
1026 +
1027 +#include <asm/octeon/cvmx-npei-defs.h>
1028 +#include <asm/octeon/cvmx-pexp-defs.h>
1029 +#include "cvmx-pko-defs.h"
1030 +
1031 +/**
1032 + * This application uses this pointer to access the global queue
1033 + * state. It points to a bootmem named block.
1034 + */
1035 +__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr;
1036 +
1037 +/**
1038 + * Initialize the Global queue state pointer.
1039 + *
1040 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1041 + */
1042 +static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void)
1043 +{
1044 + char *alloc_name = "cvmx_cmd_queues";
1045 +#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
1046 + extern uint64_t octeon_reserve32_memory;
1047 +#endif
1048 +
1049 + if (likely(__cvmx_cmd_queue_state_ptr))
1050 + return CVMX_CMD_QUEUE_SUCCESS;
1051 +
1052 +#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
1053 + if (octeon_reserve32_memory)
1054 + __cvmx_cmd_queue_state_ptr =
1055 + cvmx_bootmem_alloc_named_range(sizeof(*__cvmx_cmd_queue_state_ptr),
1056 + octeon_reserve32_memory,
1057 + octeon_reserve32_memory +
1058 + (CONFIG_CAVIUM_RESERVE32 <<
1059 + 20) - 1, 128, alloc_name);
1060 + else
1061 +#endif
1062 + __cvmx_cmd_queue_state_ptr =
1063 + cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr),
1064 + 128,
1065 + alloc_name);
1066 + if (__cvmx_cmd_queue_state_ptr)
1067 + memset(__cvmx_cmd_queue_state_ptr, 0,
1068 + sizeof(*__cvmx_cmd_queue_state_ptr));
1069 + else {
1070 + struct cvmx_bootmem_named_block_desc *block_desc =
1071 + cvmx_bootmem_find_named_block(alloc_name);
1072 + if (block_desc)
1073 + __cvmx_cmd_queue_state_ptr =
1074 + cvmx_phys_to_ptr(block_desc->base_addr);
1075 + else {
1076 + cvmx_dprintf
1077 + ("ERROR: cvmx_cmd_queue_initialize: Unable to get named block %s.\n",
1078 + alloc_name);
1079 + return CVMX_CMD_QUEUE_NO_MEMORY;
1080 + }
1081 + }
1082 + return CVMX_CMD_QUEUE_SUCCESS;
1083 +}
1084 +
1085 +/**
1086 + * Initialize a command queue for use. The initial FPA buffer is
1087 + * allocated and the hardware unit is configured to point to the
1088 + * new command queue.
1089 + *
1090 + * @queue_id: Hardware command queue to initialize.
1091 + * @max_depth: Maximum outstanding commands that can be queued.
1092 + * @fpa_pool: FPA pool the command queues should come from.
1093 + * @pool_size: Size of each buffer in the FPA pool (bytes)
1094 + *
1095 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1096 + */
1097 +cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
1098 + int max_depth, int fpa_pool,
1099 + int pool_size)
1100 +{
1101 + __cvmx_cmd_queue_state_t *qstate;
1102 + cvmx_cmd_queue_result_t result = __cvmx_cmd_queue_init_state_ptr();
1103 + if (result != CVMX_CMD_QUEUE_SUCCESS)
1104 + return result;
1105 +
1106 + qstate = __cvmx_cmd_queue_get_state(queue_id);
1107 + if (qstate == NULL)
1108 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1109 +
1110 + /*
1111 + * We artificially limit max_depth to 1<<20 words. It is an
1112 + * arbitrary limit.
1113 + */
1114 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH) {
1115 + if ((max_depth < 0) || (max_depth > 1 << 20))
1116 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1117 + } else if (max_depth != 0)
1118 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1119 +
1120 + if ((fpa_pool < 0) || (fpa_pool > 7))
1121 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1122 + if ((pool_size < 128) || (pool_size > 65536))
1123 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1124 +
1125 + /* See if someone else has already initialized the queue */
1126 + if (qstate->base_ptr_div128) {
1127 + if (max_depth != (int)qstate->max_depth) {
1128 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1129 + "Queue already initalized with different "
1130 + "max_depth (%d).\n",
1131 + (int)qstate->max_depth);
1132 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1133 + }
1134 + if (fpa_pool != qstate->fpa_pool) {
1135 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1136 + "Queue already initalized with different "
1137 + "FPA pool (%u).\n",
1138 + qstate->fpa_pool);
1139 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1140 + }
1141 + if ((pool_size >> 3) - 1 != qstate->pool_size_m1) {
1142 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1143 + "Queue already initalized with different "
1144 + "FPA pool size (%u).\n",
1145 + (qstate->pool_size_m1 + 1) << 3);
1146 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1147 + }
1148 + CVMX_SYNCWS;
1149 + return CVMX_CMD_QUEUE_ALREADY_SETUP;
1150 + } else {
1151 + union cvmx_fpa_ctl_status status;
1152 + void *buffer;
1153 +
1154 + status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
1155 + if (!status.s.enb) {
1156 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1157 + "FPA is not enabled.\n");
1158 + return CVMX_CMD_QUEUE_NO_MEMORY;
1159 + }
1160 + buffer = cvmx_fpa_alloc(fpa_pool);
1161 + if (buffer == NULL) {
1162 + cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
1163 + "Unable to allocate initial buffer.\n");
1164 + return CVMX_CMD_QUEUE_NO_MEMORY;
1165 + }
1166 +
1167 + memset(qstate, 0, sizeof(*qstate));
1168 + qstate->max_depth = max_depth;
1169 + qstate->fpa_pool = fpa_pool;
1170 + qstate->pool_size_m1 = (pool_size >> 3) - 1;
1171 + qstate->base_ptr_div128 = cvmx_ptr_to_phys(buffer) / 128;
1172 + /*
1173 + * We zeroed the now serving field so we need to also
1174 + * zero the ticket.
1175 + */
1176 + __cvmx_cmd_queue_state_ptr->
1177 + ticket[__cvmx_cmd_queue_get_index(queue_id)] = 0;
1178 + CVMX_SYNCWS;
1179 + return CVMX_CMD_QUEUE_SUCCESS;
1180 + }
1181 +}
1182 +
1183 +/**
1184 + * Shutdown a queue a free it's command buffers to the FPA. The
1185 + * hardware connected to the queue must be stopped before this
1186 + * function is called.
1187 + *
1188 + * @queue_id: Queue to shutdown
1189 + *
1190 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1191 + */
1192 +cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id)
1193 +{
1194 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1195 + if (qptr == NULL) {
1196 + cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Unable to "
1197 + "get queue information.\n");
1198 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1199 + }
1200 +
1201 + if (cvmx_cmd_queue_length(queue_id) > 0) {
1202 + cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Queue still "
1203 + "has data in it.\n");
1204 + return CVMX_CMD_QUEUE_FULL;
1205 + }
1206 +
1207 + __cvmx_cmd_queue_lock(queue_id, qptr);
1208 + if (qptr->base_ptr_div128) {
1209 + cvmx_fpa_free(cvmx_phys_to_ptr
1210 + ((uint64_t) qptr->base_ptr_div128 << 7),
1211 + qptr->fpa_pool, 0);
1212 + qptr->base_ptr_div128 = 0;
1213 + }
1214 + __cvmx_cmd_queue_unlock(qptr);
1215 +
1216 + return CVMX_CMD_QUEUE_SUCCESS;
1217 +}
1218 +
1219 +/**
1220 + * Return the number of command words pending in the queue. This
1221 + * function may be relatively slow for some hardware units.
1222 + *
1223 + * @queue_id: Hardware command queue to query
1224 + *
1225 + * Returns Number of outstanding commands
1226 + */
1227 +int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id)
1228 +{
1229 + if (CVMX_ENABLE_PARAMETER_CHECKING) {
1230 + if (__cvmx_cmd_queue_get_state(queue_id) == NULL)
1231 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1232 + }
1233 +
1234 + /*
1235 + * The cast is here so gcc with check that all values in the
1236 + * cvmx_cmd_queue_id_t enumeration are here.
1237 + */
1238 + switch ((cvmx_cmd_queue_id_t) (queue_id & 0xff0000)) {
1239 + case CVMX_CMD_QUEUE_PKO_BASE:
1240 + /*
1241 + * FIXME: Need atomic lock on
1242 + * CVMX_PKO_REG_READ_IDX. Right now we are normally
1243 + * called with the queue lock, so that is a SLIGHT
1244 + * amount of protection.
1245 + */
1246 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue_id & 0xffff);
1247 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
1248 + union cvmx_pko_mem_debug9 debug9;
1249 + debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
1250 + return debug9.cn38xx.doorbell;
1251 + } else {
1252 + union cvmx_pko_mem_debug8 debug8;
1253 + debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
1254 + return debug8.cn58xx.doorbell;
1255 + }
1256 + case CVMX_CMD_QUEUE_ZIP:
1257 + case CVMX_CMD_QUEUE_DFA:
1258 + case CVMX_CMD_QUEUE_RAID:
1259 + /* FIXME: Implement other lengths */
1260 + return 0;
1261 + case CVMX_CMD_QUEUE_DMA_BASE:
1262 + {
1263 + union cvmx_npei_dmax_counts dmax_counts;
1264 + dmax_counts.u64 =
1265 + cvmx_read_csr(CVMX_PEXP_NPEI_DMAX_COUNTS
1266 + (queue_id & 0x7));
1267 + return dmax_counts.s.dbell;
1268 + }
1269 + case CVMX_CMD_QUEUE_END:
1270 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1271 + }
1272 + return CVMX_CMD_QUEUE_INVALID_PARAM;
1273 +}
1274 +
1275 +/**
1276 + * Return the command buffer to be written to. The purpose of this
1277 + * function is to allow CVMX routine access t othe low level buffer
1278 + * for initial hardware setup. User applications should not call this
1279 + * function directly.
1280 + *
1281 + * @queue_id: Command queue to query
1282 + *
1283 + * Returns Command buffer or NULL on failure
1284 + */
1285 +void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id)
1286 +{
1287 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1288 + if (qptr && qptr->base_ptr_div128)
1289 + return cvmx_phys_to_ptr((uint64_t) qptr->base_ptr_div128 << 7);
1290 + else
1291 + return NULL;
1292 +}
1293 diff --git a/drivers/staging/octeon/cvmx-cmd-queue.h b/drivers/staging/octeon/cvmx-cmd-queue.h
1294 new file mode 100644
1295 index 0000000..f0cb20f
1296 --- /dev/null
1297 +++ b/drivers/staging/octeon/cvmx-cmd-queue.h
1298 @@ -0,0 +1,617 @@
1299 +/***********************license start***************
1300 + * Author: Cavium Networks
1301 + *
1302 + * Contact: support@caviumnetworks.com
1303 + * This file is part of the OCTEON SDK
1304 + *
1305 + * Copyright (c) 2003-2008 Cavium Networks
1306 + *
1307 + * This file is free software; you can redistribute it and/or modify
1308 + * it under the terms of the GNU General Public License, Version 2, as
1309 + * published by the Free Software Foundation.
1310 + *
1311 + * This file is distributed in the hope that it will be useful, but
1312 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
1313 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
1314 + * NONINFRINGEMENT. See the GNU General Public License for more
1315 + * details.
1316 + *
1317 + * You should have received a copy of the GNU General Public License
1318 + * along with this file; if not, write to the Free Software
1319 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1320 + * or visit http://www.gnu.org/licenses/.
1321 + *
1322 + * This file may also be available under a different license from Cavium.
1323 + * Contact Cavium Networks for more information
1324 + ***********************license end**************************************/
1325 +
1326 +/*
1327 + *
1328 + * Support functions for managing command queues used for
1329 + * various hardware blocks.
1330 + *
1331 + * The common command queue infrastructure abstracts out the
1332 + * software necessary for adding to Octeon's chained queue
1333 + * structures. These structures are used for commands to the
1334 + * PKO, ZIP, DFA, RAID, and DMA engine blocks. Although each
1335 + * hardware unit takes commands and CSRs of different types,
1336 + * they all use basic linked command buffers to store the
1337 + * pending request. In general, users of the CVMX API don't
1338 + * call cvmx-cmd-queue functions directly. Instead the hardware
1339 + * unit specific wrapper should be used. The wrappers perform
1340 + * unit specific validation and CSR writes to submit the
1341 + * commands.
1342 + *
1343 + * Even though most software will never directly interact with
1344 + * cvmx-cmd-queue, knowledge of its internal working can help
1345 + * in diagnosing performance problems and help with debugging.
1346 + *
1347 + * Command queue pointers are stored in a global named block
1348 + * called "cvmx_cmd_queues". Except for the PKO queues, each
1349 + * hardware queue is stored in its own cache line to reduce SMP
1350 + * contention on spin locks. The PKO queues are stored such that
1351 + * every 16th queue is next to each other in memory. This scheme
1352 + * allows for queues being in separate cache lines when there
1353 + * are low number of queues per port. With 16 queues per port,
1354 + * the first queue for each port is in the same cache area. The
1355 + * second queues for each port are in another area, etc. This
1356 + * allows software to implement very efficient lockless PKO with
1357 + * 16 queues per port using a minimum of cache lines per core.
1358 + * All queues for a given core will be isolated in the same
1359 + * cache area.
1360 + *
1361 + * In addition to the memory pointer layout, cvmx-cmd-queue
1362 + * provides an optimized fair ll/sc locking mechanism for the
1363 + * queues. The lock uses a "ticket / now serving" model to
1364 + * maintain fair order on contended locks. In addition, it uses
1365 + * predicted locking time to limit cache contention. When a core
1366 + * know it must wait in line for a lock, it spins on the
1367 + * internal cycle counter to completely eliminate any causes of
1368 + * bus traffic.
1369 + *
1370 + */
1371 +
1372 +#ifndef __CVMX_CMD_QUEUE_H__
1373 +#define __CVMX_CMD_QUEUE_H__
1374 +
1375 +#include <linux/prefetch.h>
1376 +
1377 +#include "cvmx-fpa.h"
1378 +/**
1379 + * By default we disable the max depth support. Most programs
1380 + * don't use it and it slows down the command queue processing
1381 + * significantly.
1382 + */
1383 +#ifndef CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH
1384 +#define CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH 0
1385 +#endif
1386 +
1387 +/**
1388 + * Enumeration representing all hardware blocks that use command
1389 + * queues. Each hardware block has up to 65536 sub identifiers for
1390 + * multiple command queues. Not all chips support all hardware
1391 + * units.
1392 + */
1393 +typedef enum {
1394 + CVMX_CMD_QUEUE_PKO_BASE = 0x00000,
1395 +
1396 +#define CVMX_CMD_QUEUE_PKO(queue) \
1397 + ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_PKO_BASE + (0xffff&(queue))))
1398 +
1399 + CVMX_CMD_QUEUE_ZIP = 0x10000,
1400 + CVMX_CMD_QUEUE_DFA = 0x20000,
1401 + CVMX_CMD_QUEUE_RAID = 0x30000,
1402 + CVMX_CMD_QUEUE_DMA_BASE = 0x40000,
1403 +
1404 +#define CVMX_CMD_QUEUE_DMA(queue) \
1405 + ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_DMA_BASE + (0xffff&(queue))))
1406 +
1407 + CVMX_CMD_QUEUE_END = 0x50000,
1408 +} cvmx_cmd_queue_id_t;
1409 +
1410 +/**
1411 + * Command write operations can fail if the comamnd queue needs
1412 + * a new buffer and the associated FPA pool is empty. It can also
1413 + * fail if the number of queued command words reaches the maximum
1414 + * set at initialization.
1415 + */
1416 +typedef enum {
1417 + CVMX_CMD_QUEUE_SUCCESS = 0,
1418 + CVMX_CMD_QUEUE_NO_MEMORY = -1,
1419 + CVMX_CMD_QUEUE_FULL = -2,
1420 + CVMX_CMD_QUEUE_INVALID_PARAM = -3,
1421 + CVMX_CMD_QUEUE_ALREADY_SETUP = -4,
1422 +} cvmx_cmd_queue_result_t;
1423 +
1424 +typedef struct {
1425 + /* You have lock when this is your ticket */
1426 + uint8_t now_serving;
1427 + uint64_t unused1:24;
1428 + /* Maximum outstanding command words */
1429 + uint32_t max_depth;
1430 + /* FPA pool buffers come from */
1431 + uint64_t fpa_pool:3;
1432 + /* Top of command buffer pointer shifted 7 */
1433 + uint64_t base_ptr_div128:29;
1434 + uint64_t unused2:6;
1435 + /* FPA buffer size in 64bit words minus 1 */
1436 + uint64_t pool_size_m1:13;
1437 + /* Number of comamnds already used in buffer */
1438 + uint64_t index:13;
1439 +} __cvmx_cmd_queue_state_t;
1440 +
1441 +/**
1442 + * This structure contains the global state of all comamnd queues.
1443 + * It is stored in a bootmem named block and shared by all
1444 + * applications running on Octeon. Tickets are stored in a differnet
1445 + * cahce line that queue information to reduce the contention on the
1446 + * ll/sc used to get a ticket. If this is not the case, the update
1447 + * of queue state causes the ll/sc to fail quite often.
1448 + */
1449 +typedef struct {
1450 + uint64_t ticket[(CVMX_CMD_QUEUE_END >> 16) * 256];
1451 + __cvmx_cmd_queue_state_t state[(CVMX_CMD_QUEUE_END >> 16) * 256];
1452 +} __cvmx_cmd_queue_all_state_t;
1453 +
1454 +/**
1455 + * Initialize a command queue for use. The initial FPA buffer is
1456 + * allocated and the hardware unit is configured to point to the
1457 + * new command queue.
1458 + *
1459 + * @queue_id: Hardware command queue to initialize.
1460 + * @max_depth: Maximum outstanding commands that can be queued.
1461 + * @fpa_pool: FPA pool the command queues should come from.
1462 + * @pool_size: Size of each buffer in the FPA pool (bytes)
1463 + *
1464 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1465 + */
1466 +cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
1467 + int max_depth, int fpa_pool,
1468 + int pool_size);
1469 +
1470 +/**
1471 + * Shutdown a queue a free it's command buffers to the FPA. The
1472 + * hardware connected to the queue must be stopped before this
1473 + * function is called.
1474 + *
1475 + * @queue_id: Queue to shutdown
1476 + *
1477 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1478 + */
1479 +cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id);
1480 +
1481 +/**
1482 + * Return the number of command words pending in the queue. This
1483 + * function may be relatively slow for some hardware units.
1484 + *
1485 + * @queue_id: Hardware command queue to query
1486 + *
1487 + * Returns Number of outstanding commands
1488 + */
1489 +int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id);
1490 +
1491 +/**
1492 + * Return the command buffer to be written to. The purpose of this
1493 + * function is to allow CVMX routine access t othe low level buffer
1494 + * for initial hardware setup. User applications should not call this
1495 + * function directly.
1496 + *
1497 + * @queue_id: Command queue to query
1498 + *
1499 + * Returns Command buffer or NULL on failure
1500 + */
1501 +void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id);
1502 +
1503 +/**
1504 + * Get the index into the state arrays for the supplied queue id.
1505 + *
1506 + * @queue_id: Queue ID to get an index for
1507 + *
1508 + * Returns Index into the state arrays
1509 + */
1510 +static inline int __cvmx_cmd_queue_get_index(cvmx_cmd_queue_id_t queue_id)
1511 +{
1512 + /*
1513 + * Warning: This code currently only works with devices that
1514 + * have 256 queues or less. Devices with more than 16 queues
1515 + * are layed out in memory to allow cores quick access to
1516 + * every 16th queue. This reduces cache thrashing when you are
1517 + * running 16 queues per port to support lockless operation.
1518 + */
1519 + int unit = queue_id >> 16;
1520 + int q = (queue_id >> 4) & 0xf;
1521 + int core = queue_id & 0xf;
1522 + return unit * 256 + core * 16 + q;
1523 +}
1524 +
1525 +/**
1526 + * Lock the supplied queue so nobody else is updating it at the same
1527 + * time as us.
1528 + *
1529 + * @queue_id: Queue ID to lock
1530 + * @qptr: Pointer to the queue's global state
1531 + */
1532 +static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id,
1533 + __cvmx_cmd_queue_state_t *qptr)
1534 +{
1535 + extern __cvmx_cmd_queue_all_state_t
1536 + *__cvmx_cmd_queue_state_ptr;
1537 + int tmp;
1538 + int my_ticket;
1539 + prefetch(qptr);
1540 + asm volatile (
1541 + ".set push\n"
1542 + ".set noreorder\n"
1543 + "1:\n"
1544 + /* Atomic add one to ticket_ptr */
1545 + "ll %[my_ticket], %[ticket_ptr]\n"
1546 + /* and store the original value */
1547 + "li %[ticket], 1\n"
1548 + /* in my_ticket */
1549 + "baddu %[ticket], %[my_ticket]\n"
1550 + "sc %[ticket], %[ticket_ptr]\n"
1551 + "beqz %[ticket], 1b\n"
1552 + " nop\n"
1553 + /* Load the current now_serving ticket */
1554 + "lbu %[ticket], %[now_serving]\n"
1555 + "2:\n"
1556 + /* Jump out if now_serving == my_ticket */
1557 + "beq %[ticket], %[my_ticket], 4f\n"
1558 + /* Find out how many tickets are in front of me */
1559 + " subu %[ticket], %[my_ticket], %[ticket]\n"
1560 + /* Use tickets in front of me minus one to delay */
1561 + "subu %[ticket], 1\n"
1562 + /* Delay will be ((tickets in front)-1)*32 loops */
1563 + "cins %[ticket], %[ticket], 5, 7\n"
1564 + "3:\n"
1565 + /* Loop here until our ticket might be up */
1566 + "bnez %[ticket], 3b\n"
1567 + " subu %[ticket], 1\n"
1568 + /* Jump back up to check out ticket again */
1569 + "b 2b\n"
1570 + /* Load the current now_serving ticket */
1571 + " lbu %[ticket], %[now_serving]\n"
1572 + "4:\n"
1573 + ".set pop\n" :
1574 + [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]),
1575 + [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp),
1576 + [my_ticket] "=r"(my_ticket)
1577 + );
1578 +}
1579 +
1580 +/**
1581 + * Unlock the queue, flushing all writes.
1582 + *
1583 + * @qptr: Queue to unlock
1584 + */
1585 +static inline void __cvmx_cmd_queue_unlock(__cvmx_cmd_queue_state_t *qptr)
1586 +{
1587 + qptr->now_serving++;
1588 + CVMX_SYNCWS;
1589 +}
1590 +
1591 +/**
1592 + * Get the queue state structure for the given queue id
1593 + *
1594 + * @queue_id: Queue id to get
1595 + *
1596 + * Returns Queue structure or NULL on failure
1597 + */
1598 +static inline __cvmx_cmd_queue_state_t
1599 + *__cvmx_cmd_queue_get_state(cvmx_cmd_queue_id_t queue_id)
1600 +{
1601 + extern __cvmx_cmd_queue_all_state_t
1602 + *__cvmx_cmd_queue_state_ptr;
1603 + return &__cvmx_cmd_queue_state_ptr->
1604 + state[__cvmx_cmd_queue_get_index(queue_id)];
1605 +}
1606 +
1607 +/**
1608 + * Write an arbitrary number of command words to a command queue.
1609 + * This is a generic function; the fixed number of comamnd word
1610 + * functions yield higher performance.
1611 + *
1612 + * @queue_id: Hardware command queue to write to
1613 + * @use_locking:
1614 + * Use internal locking to ensure exclusive access for queue
1615 + * updates. If you don't use this locking you must ensure
1616 + * exclusivity some other way. Locking is strongly recommended.
1617 + * @cmd_count: Number of command words to write
1618 + * @cmds: Array of comamnds to write
1619 + *
1620 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1621 + */
1622 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write(cvmx_cmd_queue_id_t
1623 + queue_id,
1624 + int use_locking,
1625 + int cmd_count,
1626 + uint64_t *cmds)
1627 +{
1628 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1629 +
1630 + /* Make sure nobody else is updating the same queue */
1631 + if (likely(use_locking))
1632 + __cvmx_cmd_queue_lock(queue_id, qptr);
1633 +
1634 + /*
1635 + * If a max queue length was specified then make sure we don't
1636 + * exceed it. If any part of the command would be below the
1637 + * limit we allow it.
1638 + */
1639 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1640 + if (unlikely
1641 + (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1642 + if (likely(use_locking))
1643 + __cvmx_cmd_queue_unlock(qptr);
1644 + return CVMX_CMD_QUEUE_FULL;
1645 + }
1646 + }
1647 +
1648 + /*
1649 + * Normally there is plenty of room in the current buffer for
1650 + * the command.
1651 + */
1652 + if (likely(qptr->index + cmd_count < qptr->pool_size_m1)) {
1653 + uint64_t *ptr =
1654 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1655 + base_ptr_div128 << 7);
1656 + ptr += qptr->index;
1657 + qptr->index += cmd_count;
1658 + while (cmd_count--)
1659 + *ptr++ = *cmds++;
1660 + } else {
1661 + uint64_t *ptr;
1662 + int count;
1663 + /*
1664 + * We need a new comamnd buffer. Fail if there isn't
1665 + * one available.
1666 + */
1667 + uint64_t *new_buffer =
1668 + (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1669 + if (unlikely(new_buffer == NULL)) {
1670 + if (likely(use_locking))
1671 + __cvmx_cmd_queue_unlock(qptr);
1672 + return CVMX_CMD_QUEUE_NO_MEMORY;
1673 + }
1674 + ptr =
1675 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1676 + base_ptr_div128 << 7);
1677 + /*
1678 + * Figure out how many command words will fit in this
1679 + * buffer. One location will be needed for the next
1680 + * buffer pointer.
1681 + */
1682 + count = qptr->pool_size_m1 - qptr->index;
1683 + ptr += qptr->index;
1684 + cmd_count -= count;
1685 + while (count--)
1686 + *ptr++ = *cmds++;
1687 + *ptr = cvmx_ptr_to_phys(new_buffer);
1688 + /*
1689 + * The current buffer is full and has a link to the
1690 + * next buffer. Time to write the rest of the commands
1691 + * into the new buffer.
1692 + */
1693 + qptr->base_ptr_div128 = *ptr >> 7;
1694 + qptr->index = cmd_count;
1695 + ptr = new_buffer;
1696 + while (cmd_count--)
1697 + *ptr++ = *cmds++;
1698 + }
1699 +
1700 + /* All updates are complete. Release the lock and return */
1701 + if (likely(use_locking))
1702 + __cvmx_cmd_queue_unlock(qptr);
1703 + return CVMX_CMD_QUEUE_SUCCESS;
1704 +}
1705 +
1706 +/**
1707 + * Simple function to write two command words to a command
1708 + * queue.
1709 + *
1710 + * @queue_id: Hardware command queue to write to
1711 + * @use_locking:
1712 + * Use internal locking to ensure exclusive access for queue
1713 + * updates. If you don't use this locking you must ensure
1714 + * exclusivity some other way. Locking is strongly recommended.
1715 + * @cmd1: Command
1716 + * @cmd2: Command
1717 + *
1718 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1719 + */
1720 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write2(cvmx_cmd_queue_id_t
1721 + queue_id,
1722 + int use_locking,
1723 + uint64_t cmd1,
1724 + uint64_t cmd2)
1725 +{
1726 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1727 +
1728 + /* Make sure nobody else is updating the same queue */
1729 + if (likely(use_locking))
1730 + __cvmx_cmd_queue_lock(queue_id, qptr);
1731 +
1732 + /*
1733 + * If a max queue length was specified then make sure we don't
1734 + * exceed it. If any part of the command would be below the
1735 + * limit we allow it.
1736 + */
1737 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1738 + if (unlikely
1739 + (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1740 + if (likely(use_locking))
1741 + __cvmx_cmd_queue_unlock(qptr);
1742 + return CVMX_CMD_QUEUE_FULL;
1743 + }
1744 + }
1745 +
1746 + /*
1747 + * Normally there is plenty of room in the current buffer for
1748 + * the command.
1749 + */
1750 + if (likely(qptr->index + 2 < qptr->pool_size_m1)) {
1751 + uint64_t *ptr =
1752 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1753 + base_ptr_div128 << 7);
1754 + ptr += qptr->index;
1755 + qptr->index += 2;
1756 + ptr[0] = cmd1;
1757 + ptr[1] = cmd2;
1758 + } else {
1759 + uint64_t *ptr;
1760 + /*
1761 + * Figure out how many command words will fit in this
1762 + * buffer. One location will be needed for the next
1763 + * buffer pointer.
1764 + */
1765 + int count = qptr->pool_size_m1 - qptr->index;
1766 + /*
1767 + * We need a new comamnd buffer. Fail if there isn't
1768 + * one available.
1769 + */
1770 + uint64_t *new_buffer =
1771 + (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1772 + if (unlikely(new_buffer == NULL)) {
1773 + if (likely(use_locking))
1774 + __cvmx_cmd_queue_unlock(qptr);
1775 + return CVMX_CMD_QUEUE_NO_MEMORY;
1776 + }
1777 + count--;
1778 + ptr =
1779 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1780 + base_ptr_div128 << 7);
1781 + ptr += qptr->index;
1782 + *ptr++ = cmd1;
1783 + if (likely(count))
1784 + *ptr++ = cmd2;
1785 + *ptr = cvmx_ptr_to_phys(new_buffer);
1786 + /*
1787 + * The current buffer is full and has a link to the
1788 + * next buffer. Time to write the rest of the commands
1789 + * into the new buffer.
1790 + */
1791 + qptr->base_ptr_div128 = *ptr >> 7;
1792 + qptr->index = 0;
1793 + if (unlikely(count == 0)) {
1794 + qptr->index = 1;
1795 + new_buffer[0] = cmd2;
1796 + }
1797 + }
1798 +
1799 + /* All updates are complete. Release the lock and return */
1800 + if (likely(use_locking))
1801 + __cvmx_cmd_queue_unlock(qptr);
1802 + return CVMX_CMD_QUEUE_SUCCESS;
1803 +}
1804 +
1805 +/**
1806 + * Simple function to write three command words to a command
1807 + * queue.
1808 + *
1809 + * @queue_id: Hardware command queue to write to
1810 + * @use_locking:
1811 + * Use internal locking to ensure exclusive access for queue
1812 + * updates. If you don't use this locking you must ensure
1813 + * exclusivity some other way. Locking is strongly recommended.
1814 + * @cmd1: Command
1815 + * @cmd2: Command
1816 + * @cmd3: Command
1817 + *
1818 + * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
1819 + */
1820 +static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write3(cvmx_cmd_queue_id_t
1821 + queue_id,
1822 + int use_locking,
1823 + uint64_t cmd1,
1824 + uint64_t cmd2,
1825 + uint64_t cmd3)
1826 +{
1827 + __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
1828 +
1829 + /* Make sure nobody else is updating the same queue */
1830 + if (likely(use_locking))
1831 + __cvmx_cmd_queue_lock(queue_id, qptr);
1832 +
1833 + /*
1834 + * If a max queue length was specified then make sure we don't
1835 + * exceed it. If any part of the command would be below the
1836 + * limit we allow it.
1837 + */
1838 + if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
1839 + if (unlikely
1840 + (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
1841 + if (likely(use_locking))
1842 + __cvmx_cmd_queue_unlock(qptr);
1843 + return CVMX_CMD_QUEUE_FULL;
1844 + }
1845 + }
1846 +
1847 + /*
1848 + * Normally there is plenty of room in the current buffer for
1849 + * the command.
1850 + */
1851 + if (likely(qptr->index + 3 < qptr->pool_size_m1)) {
1852 + uint64_t *ptr =
1853 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1854 + base_ptr_div128 << 7);
1855 + ptr += qptr->index;
1856 + qptr->index += 3;
1857 + ptr[0] = cmd1;
1858 + ptr[1] = cmd2;
1859 + ptr[2] = cmd3;
1860 + } else {
1861 + uint64_t *ptr;
1862 + /*
1863 + * Figure out how many command words will fit in this
1864 + * buffer. One location will be needed for the next
1865 + * buffer pointer
1866 + */
1867 + int count = qptr->pool_size_m1 - qptr->index;
1868 + /*
1869 + * We need a new comamnd buffer. Fail if there isn't
1870 + * one available
1871 + */
1872 + uint64_t *new_buffer =
1873 + (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
1874 + if (unlikely(new_buffer == NULL)) {
1875 + if (likely(use_locking))
1876 + __cvmx_cmd_queue_unlock(qptr);
1877 + return CVMX_CMD_QUEUE_NO_MEMORY;
1878 + }
1879 + count--;
1880 + ptr =
1881 + (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
1882 + base_ptr_div128 << 7);
1883 + ptr += qptr->index;
1884 + *ptr++ = cmd1;
1885 + if (count) {
1886 + *ptr++ = cmd2;
1887 + if (count > 1)
1888 + *ptr++ = cmd3;
1889 + }
1890 + *ptr = cvmx_ptr_to_phys(new_buffer);
1891 + /*
1892 + * The current buffer is full and has a link to the
1893 + * next buffer. Time to write the rest of the commands
1894 + * into the new buffer.
1895 + */
1896 + qptr->base_ptr_div128 = *ptr >> 7;
1897 + qptr->index = 0;
1898 + ptr = new_buffer;
1899 + if (count == 0) {
1900 + *ptr++ = cmd2;
1901 + qptr->index++;
1902 + }
1903 + if (count < 2) {
1904 + *ptr++ = cmd3;
1905 + qptr->index++;
1906 + }
1907 + }
1908 +
1909 + /* All updates are complete. Release the lock and return */
1910 + if (likely(use_locking))
1911 + __cvmx_cmd_queue_unlock(qptr);
1912 + return CVMX_CMD_QUEUE_SUCCESS;
1913 +}
1914 +
1915 +#endif /* __CVMX_CMD_QUEUE_H__ */
1916 diff --git a/drivers/staging/octeon/cvmx-config.h b/drivers/staging/octeon/cvmx-config.h
1917 new file mode 100644
1918 index 0000000..078a520
1919 --- /dev/null
1920 +++ b/drivers/staging/octeon/cvmx-config.h
1921 @@ -0,0 +1,169 @@
1922 +#ifndef __CVMX_CONFIG_H__
1923 +#define __CVMX_CONFIG_H__
1924 +
1925 +/************************* Config Specific Defines ************************/
1926 +#define CVMX_LLM_NUM_PORTS 1
1927 +#define CVMX_NULL_POINTER_PROTECT 1
1928 +#define CVMX_ENABLE_DEBUG_PRINTS 1
1929 +/* PKO queues per port for interface 0 (ports 0-15) */
1930 +#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 1
1931 +/* PKO queues per port for interface 1 (ports 16-31) */
1932 +#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 1
1933 +/* Limit on the number of PKO ports enabled for interface 0 */
1934 +#define CVMX_PKO_MAX_PORTS_INTERFACE0 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
1935 +/* Limit on the number of PKO ports enabled for interface 1 */
1936 +#define CVMX_PKO_MAX_PORTS_INTERFACE1 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
1937 +/* PKO queues per port for PCI (ports 32-35) */
1938 +#define CVMX_PKO_QUEUES_PER_PORT_PCI 1
1939 +/* PKO queues per port for Loop devices (ports 36-39) */
1940 +#define CVMX_PKO_QUEUES_PER_PORT_LOOP 1
1941 +
1942 +/************************* FPA allocation *********************************/
1943 +/* Pool sizes in bytes, must be multiple of a cache line */
1944 +#define CVMX_FPA_POOL_0_SIZE (16 * CVMX_CACHE_LINE_SIZE)
1945 +#define CVMX_FPA_POOL_1_SIZE (1 * CVMX_CACHE_LINE_SIZE)
1946 +#define CVMX_FPA_POOL_2_SIZE (8 * CVMX_CACHE_LINE_SIZE)
1947 +#define CVMX_FPA_POOL_3_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1948 +#define CVMX_FPA_POOL_4_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1949 +#define CVMX_FPA_POOL_5_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1950 +#define CVMX_FPA_POOL_6_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1951 +#define CVMX_FPA_POOL_7_SIZE (0 * CVMX_CACHE_LINE_SIZE)
1952 +
1953 +/* Pools in use */
1954 +/* Packet buffers */
1955 +#define CVMX_FPA_PACKET_POOL (0)
1956 +#define CVMX_FPA_PACKET_POOL_SIZE CVMX_FPA_POOL_0_SIZE
1957 +/* Work queue entrys */
1958 +#define CVMX_FPA_WQE_POOL (1)
1959 +#define CVMX_FPA_WQE_POOL_SIZE CVMX_FPA_POOL_1_SIZE
1960 +/* PKO queue command buffers */
1961 +#define CVMX_FPA_OUTPUT_BUFFER_POOL (2)
1962 +#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE CVMX_FPA_POOL_2_SIZE
1963 +
1964 +/************************* FAU allocation ********************************/
1965 +/* The fetch and add registers are allocated here. They are arranged
1966 + * in order of descending size so that all alignment constraints are
1967 + * automatically met. The enums are linked so that the following enum
1968 + * continues allocating where the previous one left off, so the
1969 + * numbering within each enum always starts with zero. The macros
1970 + * take care of the address increment size, so the values entered
1971 + * always increase by 1. FAU registers are accessed with byte
1972 + * addresses.
1973 + */
1974 +
1975 +#define CVMX_FAU_REG_64_ADDR(x) ((x << 3) + CVMX_FAU_REG_64_START)
1976 +typedef enum {
1977 + CVMX_FAU_REG_64_START = 0,
1978 + CVMX_FAU_REG_64_END = CVMX_FAU_REG_64_ADDR(0),
1979 +} cvmx_fau_reg_64_t;
1980 +
1981 +#define CVMX_FAU_REG_32_ADDR(x) ((x << 2) + CVMX_FAU_REG_32_START)
1982 +typedef enum {
1983 + CVMX_FAU_REG_32_START = CVMX_FAU_REG_64_END,
1984 + CVMX_FAU_REG_32_END = CVMX_FAU_REG_32_ADDR(0),
1985 +} cvmx_fau_reg_32_t;
1986 +
1987 +#define CVMX_FAU_REG_16_ADDR(x) ((x << 1) + CVMX_FAU_REG_16_START)
1988 +typedef enum {
1989 + CVMX_FAU_REG_16_START = CVMX_FAU_REG_32_END,
1990 + CVMX_FAU_REG_16_END = CVMX_FAU_REG_16_ADDR(0),
1991 +} cvmx_fau_reg_16_t;
1992 +
1993 +#define CVMX_FAU_REG_8_ADDR(x) ((x) + CVMX_FAU_REG_8_START)
1994 +typedef enum {
1995 + CVMX_FAU_REG_8_START = CVMX_FAU_REG_16_END,
1996 + CVMX_FAU_REG_8_END = CVMX_FAU_REG_8_ADDR(0),
1997 +} cvmx_fau_reg_8_t;
1998 +
1999 +/*
2000 + * The name CVMX_FAU_REG_AVAIL_BASE is provided to indicate the first
2001 + * available FAU address that is not allocated in cvmx-config.h. This
2002 + * is 64 bit aligned.
2003 + */
2004 +#define CVMX_FAU_REG_AVAIL_BASE ((CVMX_FAU_REG_8_END + 0x7) & (~0x7ULL))
2005 +#define CVMX_FAU_REG_END (2048)
2006 +
2007 +/********************** scratch memory allocation *************************/
2008 +/* Scratchpad memory allocation. Note that these are byte memory
2009 + * addresses. Some uses of scratchpad (IOBDMA for example) require
2010 + * the use of 8-byte aligned addresses, so proper alignment needs to
2011 + * be taken into account.
2012 + */
2013 +/* Generic scratch iobdma area */
2014 +#define CVMX_SCR_SCRATCH (0)
2015 +/* First location available after cvmx-config.h allocated region. */
2016 +#define CVMX_SCR_REG_AVAIL_BASE (8)
2017 +
2018 +/*
2019 + * CVMX_HELPER_FIRST_MBUFF_SKIP is the number of bytes to reserve
2020 + * before the beginning of the packet. If necessary, override the
2021 + * default here. See the IPD section of the hardware manual for MBUFF
2022 + * SKIP details.
2023 + */
2024 +#define CVMX_HELPER_FIRST_MBUFF_SKIP 184
2025 +
2026 +/*
2027 + * CVMX_HELPER_NOT_FIRST_MBUFF_SKIP is the number of bytes to reserve
2028 + * in each chained packet element. If necessary, override the default
2029 + * here.
2030 + */
2031 +#define CVMX_HELPER_NOT_FIRST_MBUFF_SKIP 0
2032 +
2033 +/*
2034 + * CVMX_HELPER_ENABLE_BACK_PRESSURE controls whether back pressure is
2035 + * enabled for all input ports. This controls if IPD sends
2036 + * backpressure to all ports if Octeon's FPA pools don't have enough
2037 + * packet or work queue entries. Even when this is off, it is still
2038 + * possible to get backpressure from individual hardware ports. When
2039 + * configuring backpressure, also check
2040 + * CVMX_HELPER_DISABLE_*_BACKPRESSURE below. If necessary, override
2041 + * the default here.
2042 + */
2043 +#define CVMX_HELPER_ENABLE_BACK_PRESSURE 1
2044 +
2045 +/*
2046 + * CVMX_HELPER_ENABLE_IPD controls if the IPD is enabled in the helper
2047 + * function. Once it is enabled the hardware starts accepting
2048 + * packets. You might want to skip the IPD enable if configuration
2049 + * changes are need from the default helper setup. If necessary,
2050 + * override the default here.
2051 + */
2052 +#define CVMX_HELPER_ENABLE_IPD 0
2053 +
2054 +/*
2055 + * CVMX_HELPER_INPUT_TAG_TYPE selects the type of tag that the IPD assigns
2056 + * to incoming packets.
2057 + */
2058 +#define CVMX_HELPER_INPUT_TAG_TYPE CVMX_POW_TAG_TYPE_ORDERED
2059 +
2060 +#define CVMX_ENABLE_PARAMETER_CHECKING 0
2061 +
2062 +/*
2063 + * The following select which fields are used by the PIP to generate
2064 + * the tag on INPUT
2065 + * 0: don't include
2066 + * 1: include
2067 + */
2068 +#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP 0
2069 +#define CVMX_HELPER_INPUT_TAG_IPV6_DST_IP 0
2070 +#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT 0
2071 +#define CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT 0
2072 +#define CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER 0
2073 +#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP 0
2074 +#define CVMX_HELPER_INPUT_TAG_IPV4_DST_IP 0
2075 +#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT 0
2076 +#define CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT 0
2077 +#define CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL 0
2078 +#define CVMX_HELPER_INPUT_TAG_INPUT_PORT 1
2079 +
2080 +/* Select skip mode for input ports */
2081 +#define CVMX_HELPER_INPUT_PORT_SKIP_MODE CVMX_PIP_PORT_CFG_MODE_SKIPL2
2082 +
2083 +/*
2084 + * Force backpressure to be disabled. This overrides all other
2085 + * backpressure configuration.
2086 + */
2087 +#define CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 0
2088 +
2089 +#endif /* __CVMX_CONFIG_H__ */
2090 +
2091 diff --git a/drivers/staging/octeon/cvmx-dbg-defs.h b/drivers/staging/octeon/cvmx-dbg-defs.h
2092 new file mode 100644
2093 index 0000000..abbf42d
2094 --- /dev/null
2095 +++ b/drivers/staging/octeon/cvmx-dbg-defs.h
2096 @@ -0,0 +1,72 @@
2097 +/***********************license start***************
2098 + * Author: Cavium Networks
2099 + *
2100 + * Contact: support@caviumnetworks.com
2101 + * This file is part of the OCTEON SDK
2102 + *
2103 + * Copyright (c) 2003-2008 Cavium Networks
2104 + *
2105 + * This file is free software; you can redistribute it and/or modify
2106 + * it under the terms of the GNU General Public License, Version 2, as
2107 + * published by the Free Software Foundation.
2108 + *
2109 + * This file is distributed in the hope that it will be useful, but
2110 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2111 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2112 + * NONINFRINGEMENT. See the GNU General Public License for more
2113 + * details.
2114 + *
2115 + * You should have received a copy of the GNU General Public License
2116 + * along with this file; if not, write to the Free Software
2117 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2118 + * or visit http://www.gnu.org/licenses/.
2119 + *
2120 + * This file may also be available under a different license from Cavium.
2121 + * Contact Cavium Networks for more information
2122 + ***********************license end**************************************/
2123 +
2124 +#ifndef __CVMX_DBG_DEFS_H__
2125 +#define __CVMX_DBG_DEFS_H__
2126 +
2127 +#define CVMX_DBG_DATA \
2128 + CVMX_ADD_IO_SEG(0x00011F00000001E8ull)
2129 +
2130 +union cvmx_dbg_data {
2131 + uint64_t u64;
2132 + struct cvmx_dbg_data_s {
2133 + uint64_t reserved_23_63:41;
2134 + uint64_t c_mul:5;
2135 + uint64_t dsel_ext:1;
2136 + uint64_t data:17;
2137 + } s;
2138 + struct cvmx_dbg_data_cn30xx {
2139 + uint64_t reserved_31_63:33;
2140 + uint64_t pll_mul:3;
2141 + uint64_t reserved_23_27:5;
2142 + uint64_t c_mul:5;
2143 + uint64_t dsel_ext:1;
2144 + uint64_t data:17;
2145 + } cn30xx;
2146 + struct cvmx_dbg_data_cn30xx cn31xx;
2147 + struct cvmx_dbg_data_cn38xx {
2148 + uint64_t reserved_29_63:35;
2149 + uint64_t d_mul:4;
2150 + uint64_t dclk_mul2:1;
2151 + uint64_t cclk_div2:1;
2152 + uint64_t c_mul:5;
2153 + uint64_t dsel_ext:1;
2154 + uint64_t data:17;
2155 + } cn38xx;
2156 + struct cvmx_dbg_data_cn38xx cn38xxp2;
2157 + struct cvmx_dbg_data_cn30xx cn50xx;
2158 + struct cvmx_dbg_data_cn58xx {
2159 + uint64_t reserved_29_63:35;
2160 + uint64_t rem:6;
2161 + uint64_t c_mul:5;
2162 + uint64_t dsel_ext:1;
2163 + uint64_t data:17;
2164 + } cn58xx;
2165 + struct cvmx_dbg_data_cn58xx cn58xxp1;
2166 +};
2167 +
2168 +#endif
2169 diff --git a/drivers/staging/octeon/cvmx-fau.h b/drivers/staging/octeon/cvmx-fau.h
2170 new file mode 100644
2171 index 0000000..29bdce6
2172 --- /dev/null
2173 +++ b/drivers/staging/octeon/cvmx-fau.h
2174 @@ -0,0 +1,597 @@
2175 +/***********************license start***************
2176 + * Author: Cavium Networks
2177 + *
2178 + * Contact: support@caviumnetworks.com
2179 + * This file is part of the OCTEON SDK
2180 + *
2181 + * Copyright (c) 2003-2008 Cavium Networks
2182 + *
2183 + * This file is free software; you can redistribute it and/or modify
2184 + * it under the terms of the GNU General Public License, Version 2, as
2185 + * published by the Free Software Foundation.
2186 + *
2187 + * This file is distributed in the hope that it will be useful, but
2188 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2189 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2190 + * NONINFRINGEMENT. See the GNU General Public License for more
2191 + * details.
2192 + *
2193 + * You should have received a copy of the GNU General Public License
2194 + * along with this file; if not, write to the Free Software
2195 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2196 + * or visit http://www.gnu.org/licenses/.
2197 + *
2198 + * This file may also be available under a different license from Cavium.
2199 + * Contact Cavium Networks for more information
2200 + ***********************license end**************************************/
2201 +
2202 +/*
2203 + * Interface to the hardware Fetch and Add Unit.
2204 + */
2205 +
2206 +#ifndef __CVMX_FAU_H__
2207 +#define __CVMX_FAU_H__
2208 +
2209 +/*
2210 + * Octeon Fetch and Add Unit (FAU)
2211 + */
2212 +
2213 +#define CVMX_FAU_LOAD_IO_ADDRESS cvmx_build_io_address(0x1e, 0)
2214 +#define CVMX_FAU_BITS_SCRADDR 63, 56
2215 +#define CVMX_FAU_BITS_LEN 55, 48
2216 +#define CVMX_FAU_BITS_INEVAL 35, 14
2217 +#define CVMX_FAU_BITS_TAGWAIT 13, 13
2218 +#define CVMX_FAU_BITS_NOADD 13, 13
2219 +#define CVMX_FAU_BITS_SIZE 12, 11
2220 +#define CVMX_FAU_BITS_REGISTER 10, 0
2221 +
2222 +typedef enum {
2223 + CVMX_FAU_OP_SIZE_8 = 0,
2224 + CVMX_FAU_OP_SIZE_16 = 1,
2225 + CVMX_FAU_OP_SIZE_32 = 2,
2226 + CVMX_FAU_OP_SIZE_64 = 3
2227 +} cvmx_fau_op_size_t;
2228 +
2229 +/**
2230 + * Tagwait return definition. If a timeout occurs, the error
2231 + * bit will be set. Otherwise the value of the register before
2232 + * the update will be returned.
2233 + */
2234 +typedef struct {
2235 + uint64_t error:1;
2236 + int64_t value:63;
2237 +} cvmx_fau_tagwait64_t;
2238 +
2239 +/**
2240 + * Tagwait return definition. If a timeout occurs, the error
2241 + * bit will be set. Otherwise the value of the register before
2242 + * the update will be returned.
2243 + */
2244 +typedef struct {
2245 + uint64_t error:1;
2246 + int32_t value:31;
2247 +} cvmx_fau_tagwait32_t;
2248 +
2249 +/**
2250 + * Tagwait return definition. If a timeout occurs, the error
2251 + * bit will be set. Otherwise the value of the register before
2252 + * the update will be returned.
2253 + */
2254 +typedef struct {
2255 + uint64_t error:1;
2256 + int16_t value:15;
2257 +} cvmx_fau_tagwait16_t;
2258 +
2259 +/**
2260 + * Tagwait return definition. If a timeout occurs, the error
2261 + * bit will be set. Otherwise the value of the register before
2262 + * the update will be returned.
2263 + */
2264 +typedef struct {
2265 + uint64_t error:1;
2266 + int8_t value:7;
2267 +} cvmx_fau_tagwait8_t;
2268 +
2269 +/**
2270 + * Asynchronous tagwait return definition. If a timeout occurs,
2271 + * the error bit will be set. Otherwise the value of the
2272 + * register before the update will be returned.
2273 + */
2274 +typedef union {
2275 + uint64_t u64;
2276 + struct {
2277 + uint64_t invalid:1;
2278 + uint64_t data:63; /* unpredictable if invalid is set */
2279 + } s;
2280 +} cvmx_fau_async_tagwait_result_t;
2281 +
2282 +/**
2283 + * Builds a store I/O address for writing to the FAU
2284 + *
2285 + * @noadd: 0 = Store value is atomically added to the current value
2286 + * 1 = Store value is atomically written over the current value
2287 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2288 + * - Step by 2 for 16 bit access.
2289 + * - Step by 4 for 32 bit access.
2290 + * - Step by 8 for 64 bit access.
2291 + * Returns Address to store for atomic update
2292 + */
2293 +static inline uint64_t __cvmx_fau_store_address(uint64_t noadd, uint64_t reg)
2294 +{
2295 + return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
2296 + cvmx_build_bits(CVMX_FAU_BITS_NOADD, noadd) |
2297 + cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2298 +}
2299 +
2300 +/**
2301 + * Builds a I/O address for accessing the FAU
2302 + *
2303 + * @tagwait: Should the atomic add wait for the current tag switch
2304 + * operation to complete.
2305 + * - 0 = Don't wait
2306 + * - 1 = Wait for tag switch to complete
2307 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2308 + * - Step by 2 for 16 bit access.
2309 + * - Step by 4 for 32 bit access.
2310 + * - Step by 8 for 64 bit access.
2311 + * @value: Signed value to add.
2312 + * Note: When performing 32 and 64 bit access, only the low
2313 + * 22 bits are available.
2314 + * Returns Address to read from for atomic update
2315 + */
2316 +static inline uint64_t __cvmx_fau_atomic_address(uint64_t tagwait, uint64_t reg,
2317 + int64_t value)
2318 +{
2319 + return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
2320 + cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
2321 + cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
2322 + cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2323 +}
2324 +
2325 +/**
2326 + * Perform an atomic 64 bit add
2327 + *
2328 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2329 + * - Step by 8 for 64 bit access.
2330 + * @value: Signed value to add.
2331 + * Note: Only the low 22 bits are available.
2332 + * Returns Value of the register before the update
2333 + */
2334 +static inline int64_t cvmx_fau_fetch_and_add64(cvmx_fau_reg_64_t reg,
2335 + int64_t value)
2336 +{
2337 + return cvmx_read64_int64(__cvmx_fau_atomic_address(0, reg, value));
2338 +}
2339 +
2340 +/**
2341 + * Perform an atomic 32 bit add
2342 + *
2343 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2344 + * - Step by 4 for 32 bit access.
2345 + * @value: Signed value to add.
2346 + * Note: Only the low 22 bits are available.
2347 + * Returns Value of the register before the update
2348 + */
2349 +static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg_32_t reg,
2350 + int32_t value)
2351 +{
2352 + return cvmx_read64_int32(__cvmx_fau_atomic_address(0, reg, value));
2353 +}
2354 +
2355 +/**
2356 + * Perform an atomic 16 bit add
2357 + *
2358 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2359 + * - Step by 2 for 16 bit access.
2360 + * @value: Signed value to add.
2361 + * Returns Value of the register before the update
2362 + */
2363 +static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg_16_t reg,
2364 + int16_t value)
2365 +{
2366 + return cvmx_read64_int16(__cvmx_fau_atomic_address(0, reg, value));
2367 +}
2368 +
2369 +/**
2370 + * Perform an atomic 8 bit add
2371 + *
2372 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2373 + * @value: Signed value to add.
2374 + * Returns Value of the register before the update
2375 + */
2376 +static inline int8_t cvmx_fau_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
2377 +{
2378 + return cvmx_read64_int8(__cvmx_fau_atomic_address(0, reg, value));
2379 +}
2380 +
2381 +/**
2382 + * Perform an atomic 64 bit add after the current tag switch
2383 + * completes
2384 + *
2385 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2386 + * - Step by 8 for 64 bit access.
2387 + * @value: Signed value to add.
2388 + * Note: Only the low 22 bits are available.
2389 + * Returns If a timeout occurs, the error bit will be set. Otherwise
2390 + * the value of the register before the update will be
2391 + * returned
2392 + */
2393 +static inline cvmx_fau_tagwait64_t
2394 +cvmx_fau_tagwait_fetch_and_add64(cvmx_fau_reg_64_t reg, int64_t value)
2395 +{
2396 + union {
2397 + uint64_t i64;
2398 + cvmx_fau_tagwait64_t t;
2399 + } result;
2400 + result.i64 =
2401 + cvmx_read64_int64(__cvmx_fau_atomic_address(1, reg, value));
2402 + return result.t;
2403 +}
2404 +
2405 +/**
2406 + * Perform an atomic 32 bit add after the current tag switch
2407 + * completes
2408 + *
2409 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2410 + * - Step by 4 for 32 bit access.
2411 + * @value: Signed value to add.
2412 + * Note: Only the low 22 bits are available.
2413 + * Returns If a timeout occurs, the error bit will be set. Otherwise
2414 + * the value of the register before the update will be
2415 + * returned
2416 + */
2417 +static inline cvmx_fau_tagwait32_t
2418 +cvmx_fau_tagwait_fetch_and_add32(cvmx_fau_reg_32_t reg, int32_t value)
2419 +{
2420 + union {
2421 + uint64_t i32;
2422 + cvmx_fau_tagwait32_t t;
2423 + } result;
2424 + result.i32 =
2425 + cvmx_read64_int32(__cvmx_fau_atomic_address(1, reg, value));
2426 + return result.t;
2427 +}
2428 +
2429 +/**
2430 + * Perform an atomic 16 bit add after the current tag switch
2431 + * completes
2432 + *
2433 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2434 + * - Step by 2 for 16 bit access.
2435 + * @value: Signed value to add.
2436 + * Returns If a timeout occurs, the error bit will be set. Otherwise
2437 + * the value of the register before the update will be
2438 + * returned
2439 + */
2440 +static inline cvmx_fau_tagwait16_t
2441 +cvmx_fau_tagwait_fetch_and_add16(cvmx_fau_reg_16_t reg, int16_t value)
2442 +{
2443 + union {
2444 + uint64_t i16;
2445 + cvmx_fau_tagwait16_t t;
2446 + } result;
2447 + result.i16 =
2448 + cvmx_read64_int16(__cvmx_fau_atomic_address(1, reg, value));
2449 + return result.t;
2450 +}
2451 +
2452 +/**
2453 + * Perform an atomic 8 bit add after the current tag switch
2454 + * completes
2455 + *
2456 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2457 + * @value: Signed value to add.
2458 + * Returns If a timeout occurs, the error bit will be set. Otherwise
2459 + * the value of the register before the update will be
2460 + * returned
2461 + */
2462 +static inline cvmx_fau_tagwait8_t
2463 +cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
2464 +{
2465 + union {
2466 + uint64_t i8;
2467 + cvmx_fau_tagwait8_t t;
2468 + } result;
2469 + result.i8 = cvmx_read64_int8(__cvmx_fau_atomic_address(1, reg, value));
2470 + return result.t;
2471 +}
2472 +
2473 +/**
2474 + * Builds I/O data for async operations
2475 + *
2476 + * @scraddr: Scratch pad byte addres to write to. Must be 8 byte aligned
2477 + * @value: Signed value to add.
2478 + * Note: When performing 32 and 64 bit access, only the low
2479 + * 22 bits are available.
2480 + * @tagwait: Should the atomic add wait for the current tag switch
2481 + * operation to complete.
2482 + * - 0 = Don't wait
2483 + * - 1 = Wait for tag switch to complete
2484 + * @size: The size of the operation:
2485 + * - CVMX_FAU_OP_SIZE_8 (0) = 8 bits
2486 + * - CVMX_FAU_OP_SIZE_16 (1) = 16 bits
2487 + * - CVMX_FAU_OP_SIZE_32 (2) = 32 bits
2488 + * - CVMX_FAU_OP_SIZE_64 (3) = 64 bits
2489 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2490 + * - Step by 2 for 16 bit access.
2491 + * - Step by 4 for 32 bit access.
2492 + * - Step by 8 for 64 bit access.
2493 + * Returns Data to write using cvmx_send_single
2494 + */
2495 +static inline uint64_t __cvmx_fau_iobdma_data(uint64_t scraddr, int64_t value,
2496 + uint64_t tagwait,
2497 + cvmx_fau_op_size_t size,
2498 + uint64_t reg)
2499 +{
2500 + return CVMX_FAU_LOAD_IO_ADDRESS |
2501 + cvmx_build_bits(CVMX_FAU_BITS_SCRADDR, scraddr >> 3) |
2502 + cvmx_build_bits(CVMX_FAU_BITS_LEN, 1) |
2503 + cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
2504 + cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
2505 + cvmx_build_bits(CVMX_FAU_BITS_SIZE, size) |
2506 + cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
2507 +}
2508 +
2509 +/**
2510 + * Perform an async atomic 64 bit add. The old value is
2511 + * placed in the scratch memory at byte address scraddr.
2512 + *
2513 + * @scraddr: Scratch memory byte address to put response in.
2514 + * Must be 8 byte aligned.
2515 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2516 + * - Step by 8 for 64 bit access.
2517 + * @value: Signed value to add.
2518 + * Note: Only the low 22 bits are available.
2519 + * Returns Placed in the scratch pad register
2520 + */
2521 +static inline void cvmx_fau_async_fetch_and_add64(uint64_t scraddr,
2522 + cvmx_fau_reg_64_t reg,
2523 + int64_t value)
2524 +{
2525 + cvmx_send_single(__cvmx_fau_iobdma_data
2526 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_64, reg));
2527 +}
2528 +
2529 +/**
2530 + * Perform an async atomic 32 bit add. The old value is
2531 + * placed in the scratch memory at byte address scraddr.
2532 + *
2533 + * @scraddr: Scratch memory byte address to put response in.
2534 + * Must be 8 byte aligned.
2535 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2536 + * - Step by 4 for 32 bit access.
2537 + * @value: Signed value to add.
2538 + * Note: Only the low 22 bits are available.
2539 + * Returns Placed in the scratch pad register
2540 + */
2541 +static inline void cvmx_fau_async_fetch_and_add32(uint64_t scraddr,
2542 + cvmx_fau_reg_32_t reg,
2543 + int32_t value)
2544 +{
2545 + cvmx_send_single(__cvmx_fau_iobdma_data
2546 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_32, reg));
2547 +}
2548 +
2549 +/**
2550 + * Perform an async atomic 16 bit add. The old value is
2551 + * placed in the scratch memory at byte address scraddr.
2552 + *
2553 + * @scraddr: Scratch memory byte address to put response in.
2554 + * Must be 8 byte aligned.
2555 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2556 + * - Step by 2 for 16 bit access.
2557 + * @value: Signed value to add.
2558 + * Returns Placed in the scratch pad register
2559 + */
2560 +static inline void cvmx_fau_async_fetch_and_add16(uint64_t scraddr,
2561 + cvmx_fau_reg_16_t reg,
2562 + int16_t value)
2563 +{
2564 + cvmx_send_single(__cvmx_fau_iobdma_data
2565 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_16, reg));
2566 +}
2567 +
2568 +/**
2569 + * Perform an async atomic 8 bit add. The old value is
2570 + * placed in the scratch memory at byte address scraddr.
2571 + *
2572 + * @scraddr: Scratch memory byte address to put response in.
2573 + * Must be 8 byte aligned.
2574 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2575 + * @value: Signed value to add.
2576 + * Returns Placed in the scratch pad register
2577 + */
2578 +static inline void cvmx_fau_async_fetch_and_add8(uint64_t scraddr,
2579 + cvmx_fau_reg_8_t reg,
2580 + int8_t value)
2581 +{
2582 + cvmx_send_single(__cvmx_fau_iobdma_data
2583 + (scraddr, value, 0, CVMX_FAU_OP_SIZE_8, reg));
2584 +}
2585 +
2586 +/**
2587 + * Perform an async atomic 64 bit add after the current tag
2588 + * switch completes.
2589 + *
2590 + * @scraddr: Scratch memory byte address to put response in. Must be
2591 + * 8 byte aligned. If a timeout occurs, the error bit (63)
2592 + * will be set. Otherwise the value of the register before
2593 + * the update will be returned
2594 + *
2595 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2596 + * - Step by 8 for 64 bit access.
2597 + * @value: Signed value to add.
2598 + * Note: Only the low 22 bits are available.
2599 + * Returns Placed in the scratch pad register
2600 + */
2601 +static inline void cvmx_fau_async_tagwait_fetch_and_add64(uint64_t scraddr,
2602 + cvmx_fau_reg_64_t reg,
2603 + int64_t value)
2604 +{
2605 + cvmx_send_single(__cvmx_fau_iobdma_data
2606 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_64, reg));
2607 +}
2608 +
2609 +/**
2610 + * Perform an async atomic 32 bit add after the current tag
2611 + * switch completes.
2612 + *
2613 + * @scraddr: Scratch memory byte address to put response in. Must be
2614 + * 8 byte aligned. If a timeout occurs, the error bit (63)
2615 + * will be set. Otherwise the value of the register before
2616 + * the update will be returned
2617 + *
2618 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2619 + * - Step by 4 for 32 bit access.
2620 + * @value: Signed value to add.
2621 + * Note: Only the low 22 bits are available.
2622 + * Returns Placed in the scratch pad register
2623 + */
2624 +static inline void cvmx_fau_async_tagwait_fetch_and_add32(uint64_t scraddr,
2625 + cvmx_fau_reg_32_t reg,
2626 + int32_t value)
2627 +{
2628 + cvmx_send_single(__cvmx_fau_iobdma_data
2629 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_32, reg));
2630 +}
2631 +
2632 +/**
2633 + * Perform an async atomic 16 bit add after the current tag
2634 + * switch completes.
2635 + *
2636 + * @scraddr: Scratch memory byte address to put response in. Must be
2637 + * 8 byte aligned. If a timeout occurs, the error bit (63)
2638 + * will be set. Otherwise the value of the register before
2639 + * the update will be returned
2640 + *
2641 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2642 + * - Step by 2 for 16 bit access.
2643 + * @value: Signed value to add.
2644 + *
2645 + * Returns Placed in the scratch pad register
2646 + */
2647 +static inline void cvmx_fau_async_tagwait_fetch_and_add16(uint64_t scraddr,
2648 + cvmx_fau_reg_16_t reg,
2649 + int16_t value)
2650 +{
2651 + cvmx_send_single(__cvmx_fau_iobdma_data
2652 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_16, reg));
2653 +}
2654 +
2655 +/**
2656 + * Perform an async atomic 8 bit add after the current tag
2657 + * switch completes.
2658 + *
2659 + * @scraddr: Scratch memory byte address to put response in. Must be
2660 + * 8 byte aligned. If a timeout occurs, the error bit (63)
2661 + * will be set. Otherwise the value of the register before
2662 + * the update will be returned
2663 + *
2664 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2665 + * @value: Signed value to add.
2666 + *
2667 + * Returns Placed in the scratch pad register
2668 + */
2669 +static inline void cvmx_fau_async_tagwait_fetch_and_add8(uint64_t scraddr,
2670 + cvmx_fau_reg_8_t reg,
2671 + int8_t value)
2672 +{
2673 + cvmx_send_single(__cvmx_fau_iobdma_data
2674 + (scraddr, value, 1, CVMX_FAU_OP_SIZE_8, reg));
2675 +}
2676 +
2677 +/**
2678 + * Perform an atomic 64 bit add
2679 + *
2680 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2681 + * - Step by 8 for 64 bit access.
2682 + * @value: Signed value to add.
2683 + */
2684 +static inline void cvmx_fau_atomic_add64(cvmx_fau_reg_64_t reg, int64_t value)
2685 +{
2686 + cvmx_write64_int64(__cvmx_fau_store_address(0, reg), value);
2687 +}
2688 +
2689 +/**
2690 + * Perform an atomic 32 bit add
2691 + *
2692 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2693 + * - Step by 4 for 32 bit access.
2694 + * @value: Signed value to add.
2695 + */
2696 +static inline void cvmx_fau_atomic_add32(cvmx_fau_reg_32_t reg, int32_t value)
2697 +{
2698 + cvmx_write64_int32(__cvmx_fau_store_address(0, reg), value);
2699 +}
2700 +
2701 +/**
2702 + * Perform an atomic 16 bit add
2703 + *
2704 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2705 + * - Step by 2 for 16 bit access.
2706 + * @value: Signed value to add.
2707 + */
2708 +static inline void cvmx_fau_atomic_add16(cvmx_fau_reg_16_t reg, int16_t value)
2709 +{
2710 + cvmx_write64_int16(__cvmx_fau_store_address(0, reg), value);
2711 +}
2712 +
2713 +/**
2714 + * Perform an atomic 8 bit add
2715 + *
2716 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2717 + * @value: Signed value to add.
2718 + */
2719 +static inline void cvmx_fau_atomic_add8(cvmx_fau_reg_8_t reg, int8_t value)
2720 +{
2721 + cvmx_write64_int8(__cvmx_fau_store_address(0, reg), value);
2722 +}
2723 +
2724 +/**
2725 + * Perform an atomic 64 bit write
2726 + *
2727 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2728 + * - Step by 8 for 64 bit access.
2729 + * @value: Signed value to write.
2730 + */
2731 +static inline void cvmx_fau_atomic_write64(cvmx_fau_reg_64_t reg, int64_t value)
2732 +{
2733 + cvmx_write64_int64(__cvmx_fau_store_address(1, reg), value);
2734 +}
2735 +
2736 +/**
2737 + * Perform an atomic 32 bit write
2738 + *
2739 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2740 + * - Step by 4 for 32 bit access.
2741 + * @value: Signed value to write.
2742 + */
2743 +static inline void cvmx_fau_atomic_write32(cvmx_fau_reg_32_t reg, int32_t value)
2744 +{
2745 + cvmx_write64_int32(__cvmx_fau_store_address(1, reg), value);
2746 +}
2747 +
2748 +/**
2749 + * Perform an atomic 16 bit write
2750 + *
2751 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2752 + * - Step by 2 for 16 bit access.
2753 + * @value: Signed value to write.
2754 + */
2755 +static inline void cvmx_fau_atomic_write16(cvmx_fau_reg_16_t reg, int16_t value)
2756 +{
2757 + cvmx_write64_int16(__cvmx_fau_store_address(1, reg), value);
2758 +}
2759 +
2760 +/**
2761 + * Perform an atomic 8 bit write
2762 + *
2763 + * @reg: FAU atomic register to access. 0 <= reg < 2048.
2764 + * @value: Signed value to write.
2765 + */
2766 +static inline void cvmx_fau_atomic_write8(cvmx_fau_reg_8_t reg, int8_t value)
2767 +{
2768 + cvmx_write64_int8(__cvmx_fau_store_address(1, reg), value);
2769 +}
2770 +
2771 +#endif /* __CVMX_FAU_H__ */
2772 diff --git a/drivers/staging/octeon/cvmx-fpa-defs.h b/drivers/staging/octeon/cvmx-fpa-defs.h
2773 new file mode 100644
2774 index 0000000..bf5546b
2775 --- /dev/null
2776 +++ b/drivers/staging/octeon/cvmx-fpa-defs.h
2777 @@ -0,0 +1,403 @@
2778 +/***********************license start***************
2779 + * Author: Cavium Networks
2780 + *
2781 + * Contact: support@caviumnetworks.com
2782 + * This file is part of the OCTEON SDK
2783 + *
2784 + * Copyright (c) 2003-2008 Cavium Networks
2785 + *
2786 + * This file is free software; you can redistribute it and/or modify
2787 + * it under the terms of the GNU General Public License, Version 2, as
2788 + * published by the Free Software Foundation.
2789 + *
2790 + * This file is distributed in the hope that it will be useful, but
2791 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
2792 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
2793 + * NONINFRINGEMENT. See the GNU General Public License for more
2794 + * details.
2795 + *
2796 + * You should have received a copy of the GNU General Public License
2797 + * along with this file; if not, write to the Free Software
2798 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2799 + * or visit http://www.gnu.org/licenses/.
2800 + *
2801 + * This file may also be available under a different license from Cavium.
2802 + * Contact Cavium Networks for more information
2803 + ***********************license end**************************************/
2804 +
2805 +#ifndef __CVMX_FPA_DEFS_H__
2806 +#define __CVMX_FPA_DEFS_H__
2807 +
2808 +#define CVMX_FPA_BIST_STATUS \
2809 + CVMX_ADD_IO_SEG(0x00011800280000E8ull)
2810 +#define CVMX_FPA_CTL_STATUS \
2811 + CVMX_ADD_IO_SEG(0x0001180028000050ull)
2812 +#define CVMX_FPA_FPF0_MARKS \
2813 + CVMX_ADD_IO_SEG(0x0001180028000000ull)
2814 +#define CVMX_FPA_FPF0_SIZE \
2815 + CVMX_ADD_IO_SEG(0x0001180028000058ull)
2816 +#define CVMX_FPA_FPF1_MARKS \
2817 + CVMX_ADD_IO_SEG(0x0001180028000008ull)
2818 +#define CVMX_FPA_FPF2_MARKS \
2819 + CVMX_ADD_IO_SEG(0x0001180028000010ull)
2820 +#define CVMX_FPA_FPF3_MARKS \
2821 + CVMX_ADD_IO_SEG(0x0001180028000018ull)
2822 +#define CVMX_FPA_FPF4_MARKS \
2823 + CVMX_ADD_IO_SEG(0x0001180028000020ull)
2824 +#define CVMX_FPA_FPF5_MARKS \
2825 + CVMX_ADD_IO_SEG(0x0001180028000028ull)
2826 +#define CVMX_FPA_FPF6_MARKS \
2827 + CVMX_ADD_IO_SEG(0x0001180028000030ull)
2828 +#define CVMX_FPA_FPF7_MARKS \
2829 + CVMX_ADD_IO_SEG(0x0001180028000038ull)
2830 +#define CVMX_FPA_FPFX_MARKS(offset) \
2831 + CVMX_ADD_IO_SEG(0x0001180028000008ull + (((offset) & 7) * 8) - 8 * 1)
2832 +#define CVMX_FPA_FPFX_SIZE(offset) \
2833 + CVMX_ADD_IO_SEG(0x0001180028000060ull + (((offset) & 7) * 8) - 8 * 1)
2834 +#define CVMX_FPA_INT_ENB \
2835 + CVMX_ADD_IO_SEG(0x0001180028000048ull)
2836 +#define CVMX_FPA_INT_SUM \
2837 + CVMX_ADD_IO_SEG(0x0001180028000040ull)
2838 +#define CVMX_FPA_QUE0_PAGE_INDEX \
2839 + CVMX_ADD_IO_SEG(0x00011800280000F0ull)
2840 +#define CVMX_FPA_QUE1_PAGE_INDEX \
2841 + CVMX_ADD_IO_SEG(0x00011800280000F8ull)
2842 +#define CVMX_FPA_QUE2_PAGE_INDEX \
2843 + CVMX_ADD_IO_SEG(0x0001180028000100ull)
2844 +#define CVMX_FPA_QUE3_PAGE_INDEX \
2845 + CVMX_ADD_IO_SEG(0x0001180028000108ull)
2846 +#define CVMX_FPA_QUE4_PAGE_INDEX \
2847 + CVMX_ADD_IO_SEG(0x0001180028000110ull)
2848 +#define CVMX_FPA_QUE5_PAGE_INDEX \
2849 + CVMX_ADD_IO_SEG(0x0001180028000118ull)
2850 +#define CVMX_FPA_QUE6_PAGE_INDEX \
2851 + CVMX_ADD_IO_SEG(0x0001180028000120ull)
2852 +#define CVMX_FPA_QUE7_PAGE_INDEX \
2853 + CVMX_ADD_IO_SEG(0x0001180028000128ull)
2854 +#define CVMX_FPA_QUEX_AVAILABLE(offset) \
2855 + CVMX_ADD_IO_SEG(0x0001180028000098ull + (((offset) & 7) * 8))
2856 +#define CVMX_FPA_QUEX_PAGE_INDEX(offset) \
2857 + CVMX_ADD_IO_SEG(0x00011800280000F0ull + (((offset) & 7) * 8))
2858 +#define CVMX_FPA_QUE_ACT \
2859 + CVMX_ADD_IO_SEG(0x0001180028000138ull)
2860 +#define CVMX_FPA_QUE_EXP \
2861 + CVMX_ADD_IO_SEG(0x0001180028000130ull)
2862 +#define CVMX_FPA_WART_CTL \
2863 + CVMX_ADD_IO_SEG(0x00011800280000D8ull)
2864 +#define CVMX_FPA_WART_STATUS \
2865 + CVMX_ADD_IO_SEG(0x00011800280000E0ull)
2866 +
2867 +union cvmx_fpa_bist_status {
2868 + uint64_t u64;
2869 + struct cvmx_fpa_bist_status_s {
2870 + uint64_t reserved_5_63:59;
2871 + uint64_t frd:1;
2872 + uint64_t fpf0:1;
2873 + uint64_t fpf1:1;
2874 + uint64_t ffr:1;
2875 + uint64_t fdr:1;
2876 + } s;
2877 + struct cvmx_fpa_bist_status_s cn30xx;
2878 + struct cvmx_fpa_bist_status_s cn31xx;
2879 + struct cvmx_fpa_bist_status_s cn38xx;
2880 + struct cvmx_fpa_bist_status_s cn38xxp2;
2881 + struct cvmx_fpa_bist_status_s cn50xx;
2882 + struct cvmx_fpa_bist_status_s cn52xx;
2883 + struct cvmx_fpa_bist_status_s cn52xxp1;
2884 + struct cvmx_fpa_bist_status_s cn56xx;
2885 + struct cvmx_fpa_bist_status_s cn56xxp1;
2886 + struct cvmx_fpa_bist_status_s cn58xx;
2887 + struct cvmx_fpa_bist_status_s cn58xxp1;
2888 +};
2889 +
2890 +union cvmx_fpa_ctl_status {
2891 + uint64_t u64;
2892 + struct cvmx_fpa_ctl_status_s {
2893 + uint64_t reserved_18_63:46;
2894 + uint64_t reset:1;
2895 + uint64_t use_ldt:1;
2896 + uint64_t use_stt:1;
2897 + uint64_t enb:1;
2898 + uint64_t mem1_err:7;
2899 + uint64_t mem0_err:7;
2900 + } s;
2901 + struct cvmx_fpa_ctl_status_s cn30xx;
2902 + struct cvmx_fpa_ctl_status_s cn31xx;
2903 + struct cvmx_fpa_ctl_status_s cn38xx;
2904 + struct cvmx_fpa_ctl_status_s cn38xxp2;
2905 + struct cvmx_fpa_ctl_status_s cn50xx;
2906 + struct cvmx_fpa_ctl_status_s cn52xx;
2907 + struct cvmx_fpa_ctl_status_s cn52xxp1;
2908 + struct cvmx_fpa_ctl_status_s cn56xx;
2909 + struct cvmx_fpa_ctl_status_s cn56xxp1;
2910 + struct cvmx_fpa_ctl_status_s cn58xx;
2911 + struct cvmx_fpa_ctl_status_s cn58xxp1;
2912 +};
2913 +
2914 +union cvmx_fpa_fpfx_marks {
2915 + uint64_t u64;
2916 + struct cvmx_fpa_fpfx_marks_s {
2917 + uint64_t reserved_22_63:42;
2918 + uint64_t fpf_wr:11;
2919 + uint64_t fpf_rd:11;
2920 + } s;
2921 + struct cvmx_fpa_fpfx_marks_s cn38xx;
2922 + struct cvmx_fpa_fpfx_marks_s cn38xxp2;
2923 + struct cvmx_fpa_fpfx_marks_s cn56xx;
2924 + struct cvmx_fpa_fpfx_marks_s cn56xxp1;
2925 + struct cvmx_fpa_fpfx_marks_s cn58xx;
2926 + struct cvmx_fpa_fpfx_marks_s cn58xxp1;
2927 +};
2928 +
2929 +union cvmx_fpa_fpfx_size {
2930 + uint64_t u64;
2931 + struct cvmx_fpa_fpfx_size_s {
2932 + uint64_t reserved_11_63:53;
2933 + uint64_t fpf_siz:11;
2934 + } s;
2935 + struct cvmx_fpa_fpfx_size_s cn38xx;
2936 + struct cvmx_fpa_fpfx_size_s cn38xxp2;
2937 + struct cvmx_fpa_fpfx_size_s cn56xx;
2938 + struct cvmx_fpa_fpfx_size_s cn56xxp1;
2939 + struct cvmx_fpa_fpfx_size_s cn58xx;
2940 + struct cvmx_fpa_fpfx_size_s cn58xxp1;
2941 +};
2942 +
2943 +union cvmx_fpa_fpf0_marks {
2944 + uint64_t u64;
2945 + struct cvmx_fpa_fpf0_marks_s {
2946 + uint64_t reserved_24_63:40;
2947 + uint64_t fpf_wr:12;
2948 + uint64_t fpf_rd:12;
2949 + } s;
2950 + struct cvmx_fpa_fpf0_marks_s cn38xx;
2951 + struct cvmx_fpa_fpf0_marks_s cn38xxp2;
2952 + struct cvmx_fpa_fpf0_marks_s cn56xx;
2953 + struct cvmx_fpa_fpf0_marks_s cn56xxp1;
2954 + struct cvmx_fpa_fpf0_marks_s cn58xx;
2955 + struct cvmx_fpa_fpf0_marks_s cn58xxp1;
2956 +};
2957 +
2958 +union cvmx_fpa_fpf0_size {
2959 + uint64_t u64;
2960 + struct cvmx_fpa_fpf0_size_s {
2961 + uint64_t reserved_12_63:52;
2962 + uint64_t fpf_siz:12;
2963 + } s;
2964 + struct cvmx_fpa_fpf0_size_s cn38xx;
2965 + struct cvmx_fpa_fpf0_size_s cn38xxp2;
2966 + struct cvmx_fpa_fpf0_size_s cn56xx;
2967 + struct cvmx_fpa_fpf0_size_s cn56xxp1;
2968 + struct cvmx_fpa_fpf0_size_s cn58xx;
2969 + struct cvmx_fpa_fpf0_size_s cn58xxp1;
2970 +};
2971 +
2972 +union cvmx_fpa_int_enb {
2973 + uint64_t u64;
2974 + struct cvmx_fpa_int_enb_s {
2975 + uint64_t reserved_28_63:36;
2976 + uint64_t q7_perr:1;
2977 + uint64_t q7_coff:1;
2978 + uint64_t q7_und:1;
2979 + uint64_t q6_perr:1;
2980 + uint64_t q6_coff:1;
2981 + uint64_t q6_und:1;
2982 + uint64_t q5_perr:1;
2983 + uint64_t q5_coff:1;
2984 + uint64_t q5_und:1;
2985 + uint64_t q4_perr:1;
2986 + uint64_t q4_coff:1;
2987 + uint64_t q4_und:1;
2988 + uint64_t q3_perr:1;
2989 + uint64_t q3_coff:1;
2990 + uint64_t q3_und:1;
2991 + uint64_t q2_perr:1;
2992 + uint64_t q2_coff:1;
2993 + uint64_t q2_und:1;
2994 + uint64_t q1_perr:1;
2995 + uint64_t q1_coff:1;
2996 + uint64_t q1_und:1;
2997 + uint64_t q0_perr:1;
2998 + uint64_t q0_coff:1;
2999 + uint64_t q0_und:1;
3000 + uint64_t fed1_dbe:1;
3001 + uint64_t fed1_sbe:1;
3002 + uint64_t fed0_dbe:1;
3003 + uint64_t fed0_sbe:1;
3004 + } s;
3005 + struct cvmx_fpa_int_enb_s cn30xx;
3006 + struct cvmx_fpa_int_enb_s cn31xx;
3007 + struct cvmx_fpa_int_enb_s cn38xx;
3008 + struct cvmx_fpa_int_enb_s cn38xxp2;
3009 + struct cvmx_fpa_int_enb_s cn50xx;
3010 + struct cvmx_fpa_int_enb_s cn52xx;
3011 + struct cvmx_fpa_int_enb_s cn52xxp1;
3012 + struct cvmx_fpa_int_enb_s cn56xx;
3013 + struct cvmx_fpa_int_enb_s cn56xxp1;
3014 + struct cvmx_fpa_int_enb_s cn58xx;
3015 + struct cvmx_fpa_int_enb_s cn58xxp1;
3016 +};
3017 +
3018 +union cvmx_fpa_int_sum {
3019 + uint64_t u64;
3020 + struct cvmx_fpa_int_sum_s {
3021 + uint64_t reserved_28_63:36;
3022 + uint64_t q7_perr:1;
3023 + uint64_t q7_coff:1;
3024 + uint64_t q7_und:1;
3025 + uint64_t q6_perr:1;
3026 + uint64_t q6_coff:1;
3027 + uint64_t q6_und:1;
3028 + uint64_t q5_perr:1;
3029 + uint64_t q5_coff:1;
3030 + uint64_t q5_und:1;
3031 + uint64_t q4_perr:1;
3032 + uint64_t q4_coff:1;
3033 + uint64_t q4_und:1;
3034 + uint64_t q3_perr:1;
3035 + uint64_t q3_coff:1;
3036 + uint64_t q3_und:1;
3037 + uint64_t q2_perr:1;
3038 + uint64_t q2_coff:1;
3039 + uint64_t q2_und:1;
3040 + uint64_t q1_perr:1;
3041 + uint64_t q1_coff:1;
3042 + uint64_t q1_und:1;
3043 + uint64_t q0_perr:1;
3044 + uint64_t q0_coff:1;
3045 + uint64_t q0_und:1;
3046 + uint64_t fed1_dbe:1;
3047 + uint64_t fed1_sbe:1;
3048 + uint64_t fed0_dbe:1;
3049 + uint64_t fed0_sbe:1;
3050 + } s;
3051 + struct cvmx_fpa_int_sum_s cn30xx;
3052 + struct cvmx_fpa_int_sum_s cn31xx;
3053 + struct cvmx_fpa_int_sum_s cn38xx;
3054 + struct cvmx_fpa_int_sum_s cn38xxp2;
3055 + struct cvmx_fpa_int_sum_s cn50xx;
3056 + struct cvmx_fpa_int_sum_s cn52xx;
3057 + struct cvmx_fpa_int_sum_s cn52xxp1;
3058 + struct cvmx_fpa_int_sum_s cn56xx;
3059 + struct cvmx_fpa_int_sum_s cn56xxp1;
3060 + struct cvmx_fpa_int_sum_s cn58xx;
3061 + struct cvmx_fpa_int_sum_s cn58xxp1;
3062 +};
3063 +
3064 +union cvmx_fpa_quex_available {
3065 + uint64_t u64;
3066 + struct cvmx_fpa_quex_available_s {
3067 + uint64_t reserved_29_63:35;
3068 + uint64_t que_siz:29;
3069 + } s;
3070 + struct cvmx_fpa_quex_available_s cn30xx;
3071 + struct cvmx_fpa_quex_available_s cn31xx;
3072 + struct cvmx_fpa_quex_available_s cn38xx;
3073 + struct cvmx_fpa_quex_available_s cn38xxp2;
3074 + struct cvmx_fpa_quex_available_s cn50xx;
3075 + struct cvmx_fpa_quex_available_s cn52xx;
3076 + struct cvmx_fpa_quex_available_s cn52xxp1;
3077 + struct cvmx_fpa_quex_available_s cn56xx;
3078 + struct cvmx_fpa_quex_available_s cn56xxp1;
3079 + struct cvmx_fpa_quex_available_s cn58xx;
3080 + struct cvmx_fpa_quex_available_s cn58xxp1;
3081 +};
3082 +
3083 +union cvmx_fpa_quex_page_index {
3084 + uint64_t u64;
3085 + struct cvmx_fpa_quex_page_index_s {
3086 + uint64_t reserved_25_63:39;
3087 + uint64_t pg_num:25;
3088 + } s;
3089 + struct cvmx_fpa_quex_page_index_s cn30xx;
3090 + struct cvmx_fpa_quex_page_index_s cn31xx;
3091 + struct cvmx_fpa_quex_page_index_s cn38xx;
3092 + struct cvmx_fpa_quex_page_index_s cn38xxp2;
3093 + struct cvmx_fpa_quex_page_index_s cn50xx;
3094 + struct cvmx_fpa_quex_page_index_s cn52xx;
3095 + struct cvmx_fpa_quex_page_index_s cn52xxp1;
3096 + struct cvmx_fpa_quex_page_index_s cn56xx;
3097 + struct cvmx_fpa_quex_page_index_s cn56xxp1;
3098 + struct cvmx_fpa_quex_page_index_s cn58xx;
3099 + struct cvmx_fpa_quex_page_index_s cn58xxp1;
3100 +};
3101 +
3102 +union cvmx_fpa_que_act {
3103 + uint64_t u64;
3104 + struct cvmx_fpa_que_act_s {
3105 + uint64_t reserved_29_63:35;
3106 + uint64_t act_que:3;
3107 + uint64_t act_indx:26;
3108 + } s;
3109 + struct cvmx_fpa_que_act_s cn30xx;
3110 + struct cvmx_fpa_que_act_s cn31xx;
3111 + struct cvmx_fpa_que_act_s cn38xx;
3112 + struct cvmx_fpa_que_act_s cn38xxp2;
3113 + struct cvmx_fpa_que_act_s cn50xx;
3114 + struct cvmx_fpa_que_act_s cn52xx;
3115 + struct cvmx_fpa_que_act_s cn52xxp1;
3116 + struct cvmx_fpa_que_act_s cn56xx;
3117 + struct cvmx_fpa_que_act_s cn56xxp1;
3118 + struct cvmx_fpa_que_act_s cn58xx;
3119 + struct cvmx_fpa_que_act_s cn58xxp1;
3120 +};
3121 +
3122 +union cvmx_fpa_que_exp {
3123 + uint64_t u64;
3124 + struct cvmx_fpa_que_exp_s {
3125 + uint64_t reserved_29_63:35;
3126 + uint64_t exp_que:3;
3127 + uint64_t exp_indx:26;
3128 + } s;
3129 + struct cvmx_fpa_que_exp_s cn30xx;
3130 + struct cvmx_fpa_que_exp_s cn31xx;
3131 + struct cvmx_fpa_que_exp_s cn38xx;
3132 + struct cvmx_fpa_que_exp_s cn38xxp2;
3133 + struct cvmx_fpa_que_exp_s cn50xx;
3134 + struct cvmx_fpa_que_exp_s cn52xx;
3135 + struct cvmx_fpa_que_exp_s cn52xxp1;
3136 + struct cvmx_fpa_que_exp_s cn56xx;
3137 + struct cvmx_fpa_que_exp_s cn56xxp1;
3138 + struct cvmx_fpa_que_exp_s cn58xx;
3139 + struct cvmx_fpa_que_exp_s cn58xxp1;
3140 +};
3141 +
3142 +union cvmx_fpa_wart_ctl {
3143 + uint64_t u64;
3144 + struct cvmx_fpa_wart_ctl_s {
3145 + uint64_t reserved_16_63:48;
3146 + uint64_t ctl:16;
3147 + } s;
3148 + struct cvmx_fpa_wart_ctl_s cn30xx;
3149 + struct cvmx_fpa_wart_ctl_s cn31xx;
3150 + struct cvmx_fpa_wart_ctl_s cn38xx;
3151 + struct cvmx_fpa_wart_ctl_s cn38xxp2;
3152 + struct cvmx_fpa_wart_ctl_s cn50xx;
3153 + struct cvmx_fpa_wart_ctl_s cn52xx;
3154 + struct cvmx_fpa_wart_ctl_s cn52xxp1;
3155 + struct cvmx_fpa_wart_ctl_s cn56xx;
3156 + struct cvmx_fpa_wart_ctl_s cn56xxp1;
3157 + struct cvmx_fpa_wart_ctl_s cn58xx;
3158 + struct cvmx_fpa_wart_ctl_s cn58xxp1;
3159 +};
3160 +
3161 +union cvmx_fpa_wart_status {
3162 + uint64_t u64;
3163 + struct cvmx_fpa_wart_status_s {
3164 + uint64_t reserved_32_63:32;
3165 + uint64_t status:32;
3166 + } s;
3167 + struct cvmx_fpa_wart_status_s cn30xx;
3168 + struct cvmx_fpa_wart_status_s cn31xx;
3169 + struct cvmx_fpa_wart_status_s cn38xx;
3170 + struct cvmx_fpa_wart_status_s cn38xxp2;
3171 + struct cvmx_fpa_wart_status_s cn50xx;
3172 + struct cvmx_fpa_wart_status_s cn52xx;
3173 + struct cvmx_fpa_wart_status_s cn52xxp1;
3174 + struct cvmx_fpa_wart_status_s cn56xx;
3175 + struct cvmx_fpa_wart_status_s cn56xxp1;
3176 + struct cvmx_fpa_wart_status_s cn58xx;
3177 + struct cvmx_fpa_wart_status_s cn58xxp1;
3178 +};
3179 +
3180 +#endif
3181 diff --git a/drivers/staging/octeon/cvmx-fpa.c b/drivers/staging/octeon/cvmx-fpa.c
3182 new file mode 100644
3183 index 0000000..55d9147
3184 --- /dev/null
3185 +++ b/drivers/staging/octeon/cvmx-fpa.c
3186 @@ -0,0 +1,183 @@
3187 +/***********************license start***************
3188 + * Author: Cavium Networks
3189 + *
3190 + * Contact: support@caviumnetworks.com
3191 + * This file is part of the OCTEON SDK
3192 + *
3193 + * Copyright (c) 2003-2008 Cavium Networks
3194 + *
3195 + * This file is free software; you can redistribute it and/or modify
3196 + * it under the terms of the GNU General Public License, Version 2, as
3197 + * published by the Free Software Foundation.
3198 + *
3199 + * This file is distributed in the hope that it will be useful, but
3200 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3201 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3202 + * NONINFRINGEMENT. See the GNU General Public License for more
3203 + * details.
3204 + *
3205 + * You should have received a copy of the GNU General Public License
3206 + * along with this file; if not, write to the Free Software
3207 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3208 + * or visit http://www.gnu.org/licenses/.
3209 + *
3210 + * This file may also be available under a different license from Cavium.
3211 + * Contact Cavium Networks for more information
3212 + ***********************license end**************************************/
3213 +
3214 +/**
3215 + * @file
3216 + *
3217 + * Support library for the hardware Free Pool Allocator.
3218 + *
3219 + *
3220 + */
3221 +
3222 +#include "cvmx-config.h"
3223 +#include "cvmx.h"
3224 +#include "cvmx-fpa.h"
3225 +#include "cvmx-ipd.h"
3226 +
3227 +/**
3228 + * Current state of all the pools. Use access functions
3229 + * instead of using it directly.
3230 + */
3231 +CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
3232 +
3233 +/**
3234 + * Setup a FPA pool to control a new block of memory. The
3235 + * buffer pointer must be a physical address.
3236 + *
3237 + * @pool: Pool to initialize
3238 + * 0 <= pool < 8
3239 + * @name: Constant character string to name this pool.
3240 + * String is not copied.
3241 + * @buffer: Pointer to the block of memory to use. This must be
3242 + * accessable by all processors and external hardware.
3243 + * @block_size: Size for each block controlled by the FPA
3244 + * @num_blocks: Number of blocks
3245 + *
3246 + * Returns 0 on Success,
3247 + * -1 on failure
3248 + */
3249 +int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
3250 + uint64_t block_size, uint64_t num_blocks)
3251 +{
3252 + char *ptr;
3253 + if (!buffer) {
3254 + cvmx_dprintf
3255 + ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
3256 + return -1;
3257 + }
3258 + if (pool >= CVMX_FPA_NUM_POOLS) {
3259 + cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
3260 + return -1;
3261 + }
3262 +
3263 + if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
3264 + cvmx_dprintf
3265 + ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
3266 + return -1;
3267 + }
3268 +
3269 + if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
3270 + cvmx_dprintf
3271 + ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
3272 + return -1;
3273 + }
3274 +
3275 + cvmx_fpa_pool_info[pool].name = name;
3276 + cvmx_fpa_pool_info[pool].size = block_size;
3277 + cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
3278 + cvmx_fpa_pool_info[pool].base = buffer;
3279 +
3280 + ptr = (char *)buffer;
3281 + while (num_blocks--) {
3282 + cvmx_fpa_free(ptr, pool, 0);
3283 + ptr += block_size;
3284 + }
3285 + return 0;
3286 +}
3287 +
3288 +/**
3289 + * Shutdown a Memory pool and validate that it had all of
3290 + * the buffers originally placed in it.
3291 + *
3292 + * @pool: Pool to shutdown
3293 + * Returns Zero on success
3294 + * - Positive is count of missing buffers
3295 + * - Negative is too many buffers or corrupted pointers
3296 + */
3297 +uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
3298 +{
3299 + uint64_t errors = 0;
3300 + uint64_t count = 0;
3301 + uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
3302 + uint64_t finish =
3303 + base +
3304 + cvmx_fpa_pool_info[pool].size *
3305 + cvmx_fpa_pool_info[pool].starting_element_count;
3306 + void *ptr;
3307 + uint64_t address;
3308 +
3309 + count = 0;
3310 + do {
3311 + ptr = cvmx_fpa_alloc(pool);
3312 + if (ptr)
3313 + address = cvmx_ptr_to_phys(ptr);
3314 + else
3315 + address = 0;
3316 + if (address) {
3317 + if ((address >= base) && (address < finish) &&
3318 + (((address -
3319 + base) % cvmx_fpa_pool_info[pool].size) == 0)) {
3320 + count++;
3321 + } else {
3322 + cvmx_dprintf
3323 + ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
3324 + (unsigned long long)address,
3325 + cvmx_fpa_pool_info[pool].name, (int)pool);
3326 + errors++;
3327 + }
3328 + }
3329 + } while (address);
3330 +
3331 +#ifdef CVMX_ENABLE_PKO_FUNCTIONS
3332 + if (pool == 0)
3333 + cvmx_ipd_free_ptr();
3334 +#endif
3335 +
3336 + if (errors) {
3337 + cvmx_dprintf
3338 + ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n",
3339 + cvmx_fpa_pool_info[pool].name, (int)pool,
3340 + (unsigned long long)base, (unsigned long long)finish,
3341 + (unsigned long long)cvmx_fpa_pool_info[pool].size);
3342 + return -errors;
3343 + } else
3344 + return 0;
3345 +}
3346 +
3347 +uint64_t cvmx_fpa_get_block_size(uint64_t pool)
3348 +{
3349 + switch (pool) {
3350 + case 0:
3351 + return CVMX_FPA_POOL_0_SIZE;
3352 + case 1:
3353 + return CVMX_FPA_POOL_1_SIZE;
3354 + case 2:
3355 + return CVMX_FPA_POOL_2_SIZE;
3356 + case 3:
3357 + return CVMX_FPA_POOL_3_SIZE;
3358 + case 4:
3359 + return CVMX_FPA_POOL_4_SIZE;
3360 + case 5:
3361 + return CVMX_FPA_POOL_5_SIZE;
3362 + case 6:
3363 + return CVMX_FPA_POOL_6_SIZE;
3364 + case 7:
3365 + return CVMX_FPA_POOL_7_SIZE;
3366 + default:
3367 + return 0;
3368 + }
3369 +}
3370 diff --git a/drivers/staging/octeon/cvmx-fpa.h b/drivers/staging/octeon/cvmx-fpa.h
3371 new file mode 100644
3372 index 0000000..1d7788f
3373 --- /dev/null
3374 +++ b/drivers/staging/octeon/cvmx-fpa.h
3375 @@ -0,0 +1,299 @@
3376 +/***********************license start***************
3377 + * Author: Cavium Networks
3378 + *
3379 + * Contact: support@caviumnetworks.com
3380 + * This file is part of the OCTEON SDK
3381 + *
3382 + * Copyright (c) 2003-2008 Cavium Networks
3383 + *
3384 + * This file is free software; you can redistribute it and/or modify
3385 + * it under the terms of the GNU General Public License, Version 2, as
3386 + * published by the Free Software Foundation.
3387 + *
3388 + * This file is distributed in the hope that it will be useful, but
3389 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3390 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3391 + * NONINFRINGEMENT. See the GNU General Public License for more
3392 + * details.
3393 + *
3394 + * You should have received a copy of the GNU General Public License
3395 + * along with this file; if not, write to the Free Software
3396 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3397 + * or visit http://www.gnu.org/licenses/.
3398 + *
3399 + * This file may also be available under a different license from Cavium.
3400 + * Contact Cavium Networks for more information
3401 + ***********************license end**************************************/
3402 +
3403 +/**
3404 + * @file
3405 + *
3406 + * Interface to the hardware Free Pool Allocator.
3407 + *
3408 + *
3409 + */
3410 +
3411 +#ifndef __CVMX_FPA_H__
3412 +#define __CVMX_FPA_H__
3413 +
3414 +#include "cvmx-address.h"
3415 +#include "cvmx-fpa-defs.h"
3416 +
3417 +#define CVMX_FPA_NUM_POOLS 8
3418 +#define CVMX_FPA_MIN_BLOCK_SIZE 128
3419 +#define CVMX_FPA_ALIGNMENT 128
3420 +
3421 +/**
3422 + * Structure describing the data format used for stores to the FPA.
3423 + */
3424 +typedef union {
3425 + uint64_t u64;
3426 + struct {
3427 + /*
3428 + * the (64-bit word) location in scratchpad to write
3429 + * to (if len != 0)
3430 + */
3431 + uint64_t scraddr:8;
3432 + /* the number of words in the response (0 => no response) */
3433 + uint64_t len:8;
3434 + /* the ID of the device on the non-coherent bus */
3435 + uint64_t did:8;
3436 + /*
3437 + * the address that will appear in the first tick on
3438 + * the NCB bus.
3439 + */
3440 + uint64_t addr:40;
3441 + } s;
3442 +} cvmx_fpa_iobdma_data_t;
3443 +
3444 +/**
3445 + * Structure describing the current state of a FPA pool.
3446 + */
3447 +typedef struct {
3448 + /* Name it was created under */
3449 + const char *name;
3450 + /* Size of each block */
3451 + uint64_t size;
3452 + /* The base memory address of whole block */
3453 + void *base;
3454 + /* The number of elements in the pool at creation */
3455 + uint64_t starting_element_count;
3456 +} cvmx_fpa_pool_info_t;
3457 +
3458 +/**
3459 + * Current state of all the pools. Use access functions
3460 + * instead of using it directly.
3461 + */
3462 +extern cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
3463 +
3464 +/* CSR typedefs have been moved to cvmx-csr-*.h */
3465 +
3466 +/**
3467 + * Return the name of the pool
3468 + *
3469 + * @pool: Pool to get the name of
3470 + * Returns The name
3471 + */
3472 +static inline const char *cvmx_fpa_get_name(uint64_t pool)
3473 +{
3474 + return cvmx_fpa_pool_info[pool].name;
3475 +}
3476 +
3477 +/**
3478 + * Return the base of the pool
3479 + *
3480 + * @pool: Pool to get the base of
3481 + * Returns The base
3482 + */
3483 +static inline void *cvmx_fpa_get_base(uint64_t pool)
3484 +{
3485 + return cvmx_fpa_pool_info[pool].base;
3486 +}
3487 +
3488 +/**
3489 + * Check if a pointer belongs to an FPA pool. Return non-zero
3490 + * if the supplied pointer is inside the memory controlled by
3491 + * an FPA pool.
3492 + *
3493 + * @pool: Pool to check
3494 + * @ptr: Pointer to check
3495 + * Returns Non-zero if pointer is in the pool. Zero if not
3496 + */
3497 +static inline int cvmx_fpa_is_member(uint64_t pool, void *ptr)
3498 +{
3499 + return ((ptr >= cvmx_fpa_pool_info[pool].base) &&
3500 + ((char *)ptr <
3501 + ((char *)(cvmx_fpa_pool_info[pool].base)) +
3502 + cvmx_fpa_pool_info[pool].size *
3503 + cvmx_fpa_pool_info[pool].starting_element_count));
3504 +}
3505 +
3506 +/**
3507 + * Enable the FPA for use. Must be performed after any CSR
3508 + * configuration but before any other FPA functions.
3509 + */
3510 +static inline void cvmx_fpa_enable(void)
3511 +{
3512 + union cvmx_fpa_ctl_status status;
3513 +
3514 + status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
3515 + if (status.s.enb) {
3516 + cvmx_dprintf
3517 + ("Warning: Enabling FPA when FPA already enabled.\n");
3518 + }
3519 +
3520 + /*
3521 + * Do runtime check as we allow pass1 compiled code to run on
3522 + * pass2 chips.
3523 + */
3524 + if (cvmx_octeon_is_pass1()) {
3525 + union cvmx_fpa_fpfx_marks marks;
3526 + int i;
3527 + for (i = 1; i < 8; i++) {
3528 + marks.u64 =
3529 + cvmx_read_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull);
3530 + marks.s.fpf_wr = 0xe0;
3531 + cvmx_write_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull,
3532 + marks.u64);
3533 + }
3534 +
3535 + /* Enforce a 10 cycle delay between config and enable */
3536 + cvmx_wait(10);
3537 + }
3538 +
3539 + /* FIXME: CVMX_FPA_CTL_STATUS read is unmodelled */
3540 + status.u64 = 0;
3541 + status.s.enb = 1;
3542 + cvmx_write_csr(CVMX_FPA_CTL_STATUS, status.u64);
3543 +}
3544 +
3545 +/**
3546 + * Get a new block from the FPA
3547 + *
3548 + * @pool: Pool to get the block from
3549 + * Returns Pointer to the block or NULL on failure
3550 + */
3551 +static inline void *cvmx_fpa_alloc(uint64_t pool)
3552 +{
3553 + uint64_t address =
3554 + cvmx_read_csr(CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool)));
3555 + if (address)
3556 + return cvmx_phys_to_ptr(address);
3557 + else
3558 + return NULL;
3559 +}
3560 +
3561 +/**
3562 + * Asynchronously get a new block from the FPA
3563 + *
3564 + * @scr_addr: Local scratch address to put response in. This is a byte address,
3565 + * but must be 8 byte aligned.
3566 + * @pool: Pool to get the block from
3567 + */
3568 +static inline void cvmx_fpa_async_alloc(uint64_t scr_addr, uint64_t pool)
3569 +{
3570 + cvmx_fpa_iobdma_data_t data;
3571 +
3572 + /*
3573 + * Hardware only uses 64 bit alligned locations, so convert
3574 + * from byte address to 64-bit index
3575 + */
3576 + data.s.scraddr = scr_addr >> 3;
3577 + data.s.len = 1;
3578 + data.s.did = CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool);
3579 + data.s.addr = 0;
3580 + cvmx_send_single(data.u64);
3581 +}
3582 +
3583 +/**
3584 + * Free a block allocated with a FPA pool. Does NOT provide memory
3585 + * ordering in cases where the memory block was modified by the core.
3586 + *
3587 + * @ptr: Block to free
3588 + * @pool: Pool to put it in
3589 + * @num_cache_lines:
3590 + * Cache lines to invalidate
3591 + */
3592 +static inline void cvmx_fpa_free_nosync(void *ptr, uint64_t pool,
3593 + uint64_t num_cache_lines)
3594 +{
3595 + cvmx_addr_t newptr;
3596 + newptr.u64 = cvmx_ptr_to_phys(ptr);
3597 + newptr.sfilldidspace.didspace =
3598 + CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool));
3599 + /* Prevent GCC from reordering around free */
3600 + barrier();
3601 + /* value written is number of cache lines not written back */
3602 + cvmx_write_io(newptr.u64, num_cache_lines);
3603 +}
3604 +
3605 +/**
3606 + * Free a block allocated with a FPA pool. Provides required memory
3607 + * ordering in cases where memory block was modified by core.
3608 + *
3609 + * @ptr: Block to free
3610 + * @pool: Pool to put it in
3611 + * @num_cache_lines:
3612 + * Cache lines to invalidate
3613 + */
3614 +static inline void cvmx_fpa_free(void *ptr, uint64_t pool,
3615 + uint64_t num_cache_lines)
3616 +{
3617 + cvmx_addr_t newptr;
3618 + newptr.u64 = cvmx_ptr_to_phys(ptr);
3619 + newptr.sfilldidspace.didspace =
3620 + CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool));
3621 + /*
3622 + * Make sure that any previous writes to memory go out before
3623 + * we free this buffer. This also serves as a barrier to
3624 + * prevent GCC from reordering operations to after the
3625 + * free.
3626 + */
3627 + CVMX_SYNCWS;
3628 + /* value written is number of cache lines not written back */
3629 + cvmx_write_io(newptr.u64, num_cache_lines);
3630 +}
3631 +
3632 +/**
3633 + * Setup a FPA pool to control a new block of memory.
3634 + * This can only be called once per pool. Make sure proper
3635 + * locking enforces this.
3636 + *
3637 + * @pool: Pool to initialize
3638 + * 0 <= pool < 8
3639 + * @name: Constant character string to name this pool.
3640 + * String is not copied.
3641 + * @buffer: Pointer to the block of memory to use. This must be
3642 + * accessable by all processors and external hardware.
3643 + * @block_size: Size for each block controlled by the FPA
3644 + * @num_blocks: Number of blocks
3645 + *
3646 + * Returns 0 on Success,
3647 + * -1 on failure
3648 + */
3649 +extern int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
3650 + uint64_t block_size, uint64_t num_blocks);
3651 +
3652 +/**
3653 + * Shutdown a Memory pool and validate that it had all of
3654 + * the buffers originally placed in it. This should only be
3655 + * called by one processor after all hardware has finished
3656 + * using the pool.
3657 + *
3658 + * @pool: Pool to shutdown
3659 + * Returns Zero on success
3660 + * - Positive is count of missing buffers
3661 + * - Negative is too many buffers or corrupted pointers
3662 + */
3663 +extern uint64_t cvmx_fpa_shutdown_pool(uint64_t pool);
3664 +
3665 +/**
3666 + * Get the size of blocks controlled by the pool
3667 + * This is resolved to a constant at compile time.
3668 + *
3669 + * @pool: Pool to access
3670 + * Returns Size of the block in bytes
3671 + */
3672 +uint64_t cvmx_fpa_get_block_size(uint64_t pool);
3673 +
3674 +#endif /* __CVM_FPA_H__ */
3675 diff --git a/drivers/staging/octeon/cvmx-gmxx-defs.h b/drivers/staging/octeon/cvmx-gmxx-defs.h
3676 new file mode 100644
3677 index 0000000..946a43a
3678 --- /dev/null
3679 +++ b/drivers/staging/octeon/cvmx-gmxx-defs.h
3680 @@ -0,0 +1,2529 @@
3681 +/***********************license start***************
3682 + * Author: Cavium Networks
3683 + *
3684 + * Contact: support@caviumnetworks.com
3685 + * This file is part of the OCTEON SDK
3686 + *
3687 + * Copyright (c) 2003-2008 Cavium Networks
3688 + *
3689 + * This file is free software; you can redistribute it and/or modify
3690 + * it under the terms of the GNU General Public License, Version 2, as
3691 + * published by the Free Software Foundation.
3692 + *
3693 + * This file is distributed in the hope that it will be useful, but
3694 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
3695 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
3696 + * NONINFRINGEMENT. See the GNU General Public License for more
3697 + * details.
3698 + *
3699 + * You should have received a copy of the GNU General Public License
3700 + * along with this file; if not, write to the Free Software
3701 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3702 + * or visit http://www.gnu.org/licenses/.
3703 + *
3704 + * This file may also be available under a different license from Cavium.
3705 + * Contact Cavium Networks for more information
3706 + ***********************license end**************************************/
3707 +
3708 +#ifndef __CVMX_GMXX_DEFS_H__
3709 +#define __CVMX_GMXX_DEFS_H__
3710 +
3711 +#define CVMX_GMXX_BAD_REG(block_id) \
3712 + CVMX_ADD_IO_SEG(0x0001180008000518ull + (((block_id) & 1) * 0x8000000ull))
3713 +#define CVMX_GMXX_BIST(block_id) \
3714 + CVMX_ADD_IO_SEG(0x0001180008000400ull + (((block_id) & 1) * 0x8000000ull))
3715 +#define CVMX_GMXX_CLK_EN(block_id) \
3716 + CVMX_ADD_IO_SEG(0x00011800080007F0ull + (((block_id) & 1) * 0x8000000ull))
3717 +#define CVMX_GMXX_HG2_CONTROL(block_id) \
3718 + CVMX_ADD_IO_SEG(0x0001180008000550ull + (((block_id) & 1) * 0x8000000ull))
3719 +#define CVMX_GMXX_INF_MODE(block_id) \
3720 + CVMX_ADD_IO_SEG(0x00011800080007F8ull + (((block_id) & 1) * 0x8000000ull))
3721 +#define CVMX_GMXX_NXA_ADR(block_id) \
3722 + CVMX_ADD_IO_SEG(0x0001180008000510ull + (((block_id) & 1) * 0x8000000ull))
3723 +#define CVMX_GMXX_PRTX_CBFC_CTL(offset, block_id) \
3724 + CVMX_ADD_IO_SEG(0x0001180008000580ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3725 +#define CVMX_GMXX_PRTX_CFG(offset, block_id) \
3726 + CVMX_ADD_IO_SEG(0x0001180008000010ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3727 +#define CVMX_GMXX_RXX_ADR_CAM0(offset, block_id) \
3728 + CVMX_ADD_IO_SEG(0x0001180008000180ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3729 +#define CVMX_GMXX_RXX_ADR_CAM1(offset, block_id) \
3730 + CVMX_ADD_IO_SEG(0x0001180008000188ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3731 +#define CVMX_GMXX_RXX_ADR_CAM2(offset, block_id) \
3732 + CVMX_ADD_IO_SEG(0x0001180008000190ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3733 +#define CVMX_GMXX_RXX_ADR_CAM3(offset, block_id) \
3734 + CVMX_ADD_IO_SEG(0x0001180008000198ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3735 +#define CVMX_GMXX_RXX_ADR_CAM4(offset, block_id) \
3736 + CVMX_ADD_IO_SEG(0x00011800080001A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3737 +#define CVMX_GMXX_RXX_ADR_CAM5(offset, block_id) \
3738 + CVMX_ADD_IO_SEG(0x00011800080001A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3739 +#define CVMX_GMXX_RXX_ADR_CAM_EN(offset, block_id) \
3740 + CVMX_ADD_IO_SEG(0x0001180008000108ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3741 +#define CVMX_GMXX_RXX_ADR_CTL(offset, block_id) \
3742 + CVMX_ADD_IO_SEG(0x0001180008000100ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3743 +#define CVMX_GMXX_RXX_DECISION(offset, block_id) \
3744 + CVMX_ADD_IO_SEG(0x0001180008000040ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3745 +#define CVMX_GMXX_RXX_FRM_CHK(offset, block_id) \
3746 + CVMX_ADD_IO_SEG(0x0001180008000020ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3747 +#define CVMX_GMXX_RXX_FRM_CTL(offset, block_id) \
3748 + CVMX_ADD_IO_SEG(0x0001180008000018ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3749 +#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) \
3750 + CVMX_ADD_IO_SEG(0x0001180008000030ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3751 +#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) \
3752 + CVMX_ADD_IO_SEG(0x0001180008000028ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3753 +#define CVMX_GMXX_RXX_IFG(offset, block_id) \
3754 + CVMX_ADD_IO_SEG(0x0001180008000058ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3755 +#define CVMX_GMXX_RXX_INT_EN(offset, block_id) \
3756 + CVMX_ADD_IO_SEG(0x0001180008000008ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3757 +#define CVMX_GMXX_RXX_INT_REG(offset, block_id) \
3758 + CVMX_ADD_IO_SEG(0x0001180008000000ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3759 +#define CVMX_GMXX_RXX_JABBER(offset, block_id) \
3760 + CVMX_ADD_IO_SEG(0x0001180008000038ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3761 +#define CVMX_GMXX_RXX_PAUSE_DROP_TIME(offset, block_id) \
3762 + CVMX_ADD_IO_SEG(0x0001180008000068ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3763 +#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) \
3764 + CVMX_ADD_IO_SEG(0x0001180008000060ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3765 +#define CVMX_GMXX_RXX_STATS_CTL(offset, block_id) \
3766 + CVMX_ADD_IO_SEG(0x0001180008000050ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3767 +#define CVMX_GMXX_RXX_STATS_OCTS(offset, block_id) \
3768 + CVMX_ADD_IO_SEG(0x0001180008000088ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3769 +#define CVMX_GMXX_RXX_STATS_OCTS_CTL(offset, block_id) \
3770 + CVMX_ADD_IO_SEG(0x0001180008000098ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3771 +#define CVMX_GMXX_RXX_STATS_OCTS_DMAC(offset, block_id) \
3772 + CVMX_ADD_IO_SEG(0x00011800080000A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3773 +#define CVMX_GMXX_RXX_STATS_OCTS_DRP(offset, block_id) \
3774 + CVMX_ADD_IO_SEG(0x00011800080000B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3775 +#define CVMX_GMXX_RXX_STATS_PKTS(offset, block_id) \
3776 + CVMX_ADD_IO_SEG(0x0001180008000080ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3777 +#define CVMX_GMXX_RXX_STATS_PKTS_BAD(offset, block_id) \
3778 + CVMX_ADD_IO_SEG(0x00011800080000C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3779 +#define CVMX_GMXX_RXX_STATS_PKTS_CTL(offset, block_id) \
3780 + CVMX_ADD_IO_SEG(0x0001180008000090ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3781 +#define CVMX_GMXX_RXX_STATS_PKTS_DMAC(offset, block_id) \
3782 + CVMX_ADD_IO_SEG(0x00011800080000A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3783 +#define CVMX_GMXX_RXX_STATS_PKTS_DRP(offset, block_id) \
3784 + CVMX_ADD_IO_SEG(0x00011800080000B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3785 +#define CVMX_GMXX_RXX_UDD_SKP(offset, block_id) \
3786 + CVMX_ADD_IO_SEG(0x0001180008000048ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3787 +#define CVMX_GMXX_RX_BP_DROPX(offset, block_id) \
3788 + CVMX_ADD_IO_SEG(0x0001180008000420ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3789 +#define CVMX_GMXX_RX_BP_OFFX(offset, block_id) \
3790 + CVMX_ADD_IO_SEG(0x0001180008000460ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3791 +#define CVMX_GMXX_RX_BP_ONX(offset, block_id) \
3792 + CVMX_ADD_IO_SEG(0x0001180008000440ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
3793 +#define CVMX_GMXX_RX_HG2_STATUS(block_id) \
3794 + CVMX_ADD_IO_SEG(0x0001180008000548ull + (((block_id) & 1) * 0x8000000ull))
3795 +#define CVMX_GMXX_RX_PASS_EN(block_id) \
3796 + CVMX_ADD_IO_SEG(0x00011800080005F8ull + (((block_id) & 1) * 0x8000000ull))
3797 +#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) \
3798 + CVMX_ADD_IO_SEG(0x0001180008000600ull + (((offset) & 15) * 8) + (((block_id) & 1) * 0x8000000ull))
3799 +#define CVMX_GMXX_RX_PRTS(block_id) \
3800 + CVMX_ADD_IO_SEG(0x0001180008000410ull + (((block_id) & 1) * 0x8000000ull))
3801 +#define CVMX_GMXX_RX_PRT_INFO(block_id) \
3802 + CVMX_ADD_IO_SEG(0x00011800080004E8ull + (((block_id) & 1) * 0x8000000ull))
3803 +#define CVMX_GMXX_RX_TX_STATUS(block_id) \
3804 + CVMX_ADD_IO_SEG(0x00011800080007E8ull + (((block_id) & 0) * 0x8000000ull))
3805 +#define CVMX_GMXX_RX_XAUI_BAD_COL(block_id) \
3806 + CVMX_ADD_IO_SEG(0x0001180008000538ull + (((block_id) & 1) * 0x8000000ull))
3807 +#define CVMX_GMXX_RX_XAUI_CTL(block_id) \
3808 + CVMX_ADD_IO_SEG(0x0001180008000530ull + (((block_id) & 1) * 0x8000000ull))
3809 +#define CVMX_GMXX_SMACX(offset, block_id) \
3810 + CVMX_ADD_IO_SEG(0x0001180008000230ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3811 +#define CVMX_GMXX_STAT_BP(block_id) \
3812 + CVMX_ADD_IO_SEG(0x0001180008000520ull + (((block_id) & 1) * 0x8000000ull))
3813 +#define CVMX_GMXX_TXX_APPEND(offset, block_id) \
3814 + CVMX_ADD_IO_SEG(0x0001180008000218ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3815 +#define CVMX_GMXX_TXX_BURST(offset, block_id) \
3816 + CVMX_ADD_IO_SEG(0x0001180008000228ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3817 +#define CVMX_GMXX_TXX_CBFC_XOFF(offset, block_id) \
3818 + CVMX_ADD_IO_SEG(0x00011800080005A0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3819 +#define CVMX_GMXX_TXX_CBFC_XON(offset, block_id) \
3820 + CVMX_ADD_IO_SEG(0x00011800080005C0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
3821 +#define CVMX_GMXX_TXX_CLK(offset, block_id) \
3822 + CVMX_ADD_IO_SEG(0x0001180008000208ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3823 +#define CVMX_GMXX_TXX_CTL(offset, block_id) \
3824 + CVMX_ADD_IO_SEG(0x0001180008000270ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3825 +#define CVMX_GMXX_TXX_MIN_PKT(offset, block_id) \
3826 + CVMX_ADD_IO_SEG(0x0001180008000240ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3827 +#define CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(offset, block_id) \
3828 + CVMX_ADD_IO_SEG(0x0001180008000248ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3829 +#define CVMX_GMXX_TXX_PAUSE_PKT_TIME(offset, block_id) \
3830 + CVMX_ADD_IO_SEG(0x0001180008000238ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3831 +#define CVMX_GMXX_TXX_PAUSE_TOGO(offset, block_id) \
3832 + CVMX_ADD_IO_SEG(0x0001180008000258ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3833 +#define CVMX_GMXX_TXX_PAUSE_ZERO(offset, block_id) \
3834 + CVMX_ADD_IO_SEG(0x0001180008000260ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3835 +#define CVMX_GMXX_TXX_SGMII_CTL(offset, block_id) \
3836 + CVMX_ADD_IO_SEG(0x0001180008000300ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3837 +#define CVMX_GMXX_TXX_SLOT(offset, block_id) \
3838 + CVMX_ADD_IO_SEG(0x0001180008000220ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3839 +#define CVMX_GMXX_TXX_SOFT_PAUSE(offset, block_id) \
3840 + CVMX_ADD_IO_SEG(0x0001180008000250ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3841 +#define CVMX_GMXX_TXX_STAT0(offset, block_id) \
3842 + CVMX_ADD_IO_SEG(0x0001180008000280ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3843 +#define CVMX_GMXX_TXX_STAT1(offset, block_id) \
3844 + CVMX_ADD_IO_SEG(0x0001180008000288ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3845 +#define CVMX_GMXX_TXX_STAT2(offset, block_id) \
3846 + CVMX_ADD_IO_SEG(0x0001180008000290ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3847 +#define CVMX_GMXX_TXX_STAT3(offset, block_id) \
3848 + CVMX_ADD_IO_SEG(0x0001180008000298ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3849 +#define CVMX_GMXX_TXX_STAT4(offset, block_id) \
3850 + CVMX_ADD_IO_SEG(0x00011800080002A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3851 +#define CVMX_GMXX_TXX_STAT5(offset, block_id) \
3852 + CVMX_ADD_IO_SEG(0x00011800080002A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3853 +#define CVMX_GMXX_TXX_STAT6(offset, block_id) \
3854 + CVMX_ADD_IO_SEG(0x00011800080002B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3855 +#define CVMX_GMXX_TXX_STAT7(offset, block_id) \
3856 + CVMX_ADD_IO_SEG(0x00011800080002B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3857 +#define CVMX_GMXX_TXX_STAT8(offset, block_id) \
3858 + CVMX_ADD_IO_SEG(0x00011800080002C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3859 +#define CVMX_GMXX_TXX_STAT9(offset, block_id) \
3860 + CVMX_ADD_IO_SEG(0x00011800080002C8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3861 +#define CVMX_GMXX_TXX_STATS_CTL(offset, block_id) \
3862 + CVMX_ADD_IO_SEG(0x0001180008000268ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3863 +#define CVMX_GMXX_TXX_THRESH(offset, block_id) \
3864 + CVMX_ADD_IO_SEG(0x0001180008000210ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
3865 +#define CVMX_GMXX_TX_BP(block_id) \
3866 + CVMX_ADD_IO_SEG(0x00011800080004D0ull + (((block_id) & 1) * 0x8000000ull))
3867 +#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) \
3868 + CVMX_ADD_IO_SEG(0x0001180008000780ull + (((offset) & 1) * 8) + (((block_id) & 0) * 0x0ull))
3869 +#define CVMX_GMXX_TX_COL_ATTEMPT(block_id) \
3870 + CVMX_ADD_IO_SEG(0x0001180008000498ull + (((block_id) & 1) * 0x8000000ull))
3871 +#define CVMX_GMXX_TX_CORRUPT(block_id) \
3872 + CVMX_ADD_IO_SEG(0x00011800080004D8ull + (((block_id) & 1) * 0x8000000ull))
3873 +#define CVMX_GMXX_TX_HG2_REG1(block_id) \
3874 + CVMX_ADD_IO_SEG(0x0001180008000558ull + (((block_id) & 1) * 0x8000000ull))
3875 +#define CVMX_GMXX_TX_HG2_REG2(block_id) \
3876 + CVMX_ADD_IO_SEG(0x0001180008000560ull + (((block_id) & 1) * 0x8000000ull))
3877 +#define CVMX_GMXX_TX_IFG(block_id) \
3878 + CVMX_ADD_IO_SEG(0x0001180008000488ull + (((block_id) & 1) * 0x8000000ull))
3879 +#define CVMX_GMXX_TX_INT_EN(block_id) \
3880 + CVMX_ADD_IO_SEG(0x0001180008000508ull + (((block_id) & 1) * 0x8000000ull))
3881 +#define CVMX_GMXX_TX_INT_REG(block_id) \
3882 + CVMX_ADD_IO_SEG(0x0001180008000500ull + (((block_id) & 1) * 0x8000000ull))
3883 +#define CVMX_GMXX_TX_JAM(block_id) \
3884 + CVMX_ADD_IO_SEG(0x0001180008000490ull + (((block_id) & 1) * 0x8000000ull))
3885 +#define CVMX_GMXX_TX_LFSR(block_id) \
3886 + CVMX_ADD_IO_SEG(0x00011800080004F8ull + (((block_id) & 1) * 0x8000000ull))
3887 +#define CVMX_GMXX_TX_OVR_BP(block_id) \
3888 + CVMX_ADD_IO_SEG(0x00011800080004C8ull + (((block_id) & 1) * 0x8000000ull))
3889 +#define CVMX_GMXX_TX_PAUSE_PKT_DMAC(block_id) \
3890 + CVMX_ADD_IO_SEG(0x00011800080004A0ull + (((block_id) & 1) * 0x8000000ull))
3891 +#define CVMX_GMXX_TX_PAUSE_PKT_TYPE(block_id) \
3892 + CVMX_ADD_IO_SEG(0x00011800080004A8ull + (((block_id) & 1) * 0x8000000ull))
3893 +#define CVMX_GMXX_TX_PRTS(block_id) \
3894 + CVMX_ADD_IO_SEG(0x0001180008000480ull + (((block_id) & 1) * 0x8000000ull))
3895 +#define CVMX_GMXX_TX_SPI_CTL(block_id) \
3896 + CVMX_ADD_IO_SEG(0x00011800080004C0ull + (((block_id) & 1) * 0x8000000ull))
3897 +#define CVMX_GMXX_TX_SPI_DRAIN(block_id) \
3898 + CVMX_ADD_IO_SEG(0x00011800080004E0ull + (((block_id) & 1) * 0x8000000ull))
3899 +#define CVMX_GMXX_TX_SPI_MAX(block_id) \
3900 + CVMX_ADD_IO_SEG(0x00011800080004B0ull + (((block_id) & 1) * 0x8000000ull))
3901 +#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) \
3902 + CVMX_ADD_IO_SEG(0x0001180008000680ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
3903 +#define CVMX_GMXX_TX_SPI_THRESH(block_id) \
3904 + CVMX_ADD_IO_SEG(0x00011800080004B8ull + (((block_id) & 1) * 0x8000000ull))
3905 +#define CVMX_GMXX_TX_XAUI_CTL(block_id) \
3906 + CVMX_ADD_IO_SEG(0x0001180008000528ull + (((block_id) & 1) * 0x8000000ull))
3907 +#define CVMX_GMXX_XAUI_EXT_LOOPBACK(block_id) \
3908 + CVMX_ADD_IO_SEG(0x0001180008000540ull + (((block_id) & 1) * 0x8000000ull))
3909 +
3910 +union cvmx_gmxx_bad_reg {
3911 + uint64_t u64;
3912 + struct cvmx_gmxx_bad_reg_s {
3913 + uint64_t reserved_31_63:33;
3914 + uint64_t inb_nxa:4;
3915 + uint64_t statovr:1;
3916 + uint64_t loststat:4;
3917 + uint64_t reserved_18_21:4;
3918 + uint64_t out_ovr:16;
3919 + uint64_t ncb_ovr:1;
3920 + uint64_t out_col:1;
3921 + } s;
3922 + struct cvmx_gmxx_bad_reg_cn30xx {
3923 + uint64_t reserved_31_63:33;
3924 + uint64_t inb_nxa:4;
3925 + uint64_t statovr:1;
3926 + uint64_t reserved_25_25:1;
3927 + uint64_t loststat:3;
3928 + uint64_t reserved_5_21:17;
3929 + uint64_t out_ovr:3;
3930 + uint64_t reserved_0_1:2;
3931 + } cn30xx;
3932 + struct cvmx_gmxx_bad_reg_cn30xx cn31xx;
3933 + struct cvmx_gmxx_bad_reg_s cn38xx;
3934 + struct cvmx_gmxx_bad_reg_s cn38xxp2;
3935 + struct cvmx_gmxx_bad_reg_cn30xx cn50xx;
3936 + struct cvmx_gmxx_bad_reg_cn52xx {
3937 + uint64_t reserved_31_63:33;
3938 + uint64_t inb_nxa:4;
3939 + uint64_t statovr:1;
3940 + uint64_t loststat:4;
3941 + uint64_t reserved_6_21:16;
3942 + uint64_t out_ovr:4;
3943 + uint64_t reserved_0_1:2;
3944 + } cn52xx;
3945 + struct cvmx_gmxx_bad_reg_cn52xx cn52xxp1;
3946 + struct cvmx_gmxx_bad_reg_cn52xx cn56xx;
3947 + struct cvmx_gmxx_bad_reg_cn52xx cn56xxp1;
3948 + struct cvmx_gmxx_bad_reg_s cn58xx;
3949 + struct cvmx_gmxx_bad_reg_s cn58xxp1;
3950 +};
3951 +
3952 +union cvmx_gmxx_bist {
3953 + uint64_t u64;
3954 + struct cvmx_gmxx_bist_s {
3955 + uint64_t reserved_17_63:47;
3956 + uint64_t status:17;
3957 + } s;
3958 + struct cvmx_gmxx_bist_cn30xx {
3959 + uint64_t reserved_10_63:54;
3960 + uint64_t status:10;
3961 + } cn30xx;
3962 + struct cvmx_gmxx_bist_cn30xx cn31xx;
3963 + struct cvmx_gmxx_bist_cn30xx cn38xx;
3964 + struct cvmx_gmxx_bist_cn30xx cn38xxp2;
3965 + struct cvmx_gmxx_bist_cn50xx {
3966 + uint64_t reserved_12_63:52;
3967 + uint64_t status:12;
3968 + } cn50xx;
3969 + struct cvmx_gmxx_bist_cn52xx {
3970 + uint64_t reserved_16_63:48;
3971 + uint64_t status:16;
3972 + } cn52xx;
3973 + struct cvmx_gmxx_bist_cn52xx cn52xxp1;
3974 + struct cvmx_gmxx_bist_cn52xx cn56xx;
3975 + struct cvmx_gmxx_bist_cn52xx cn56xxp1;
3976 + struct cvmx_gmxx_bist_s cn58xx;
3977 + struct cvmx_gmxx_bist_s cn58xxp1;
3978 +};
3979 +
3980 +union cvmx_gmxx_clk_en {
3981 + uint64_t u64;
3982 + struct cvmx_gmxx_clk_en_s {
3983 + uint64_t reserved_1_63:63;
3984 + uint64_t clk_en:1;
3985 + } s;
3986 + struct cvmx_gmxx_clk_en_s cn52xx;
3987 + struct cvmx_gmxx_clk_en_s cn52xxp1;
3988 + struct cvmx_gmxx_clk_en_s cn56xx;
3989 + struct cvmx_gmxx_clk_en_s cn56xxp1;
3990 +};
3991 +
3992 +union cvmx_gmxx_hg2_control {
3993 + uint64_t u64;
3994 + struct cvmx_gmxx_hg2_control_s {
3995 + uint64_t reserved_19_63:45;
3996 + uint64_t hg2tx_en:1;
3997 + uint64_t hg2rx_en:1;
3998 + uint64_t phys_en:1;
3999 + uint64_t logl_en:16;
4000 + } s;
4001 + struct cvmx_gmxx_hg2_control_s cn52xx;
4002 + struct cvmx_gmxx_hg2_control_s cn52xxp1;
4003 + struct cvmx_gmxx_hg2_control_s cn56xx;
4004 +};
4005 +
4006 +union cvmx_gmxx_inf_mode {
4007 + uint64_t u64;
4008 + struct cvmx_gmxx_inf_mode_s {
4009 + uint64_t reserved_10_63:54;
4010 + uint64_t speed:2;
4011 + uint64_t reserved_6_7:2;
4012 + uint64_t mode:2;
4013 + uint64_t reserved_3_3:1;
4014 + uint64_t p0mii:1;
4015 + uint64_t en:1;
4016 + uint64_t type:1;
4017 + } s;
4018 + struct cvmx_gmxx_inf_mode_cn30xx {
4019 + uint64_t reserved_3_63:61;
4020 + uint64_t p0mii:1;
4021 + uint64_t en:1;
4022 + uint64_t type:1;
4023 + } cn30xx;
4024 + struct cvmx_gmxx_inf_mode_cn31xx {
4025 + uint64_t reserved_2_63:62;
4026 + uint64_t en:1;
4027 + uint64_t type:1;
4028 + } cn31xx;
4029 + struct cvmx_gmxx_inf_mode_cn31xx cn38xx;
4030 + struct cvmx_gmxx_inf_mode_cn31xx cn38xxp2;
4031 + struct cvmx_gmxx_inf_mode_cn30xx cn50xx;
4032 + struct cvmx_gmxx_inf_mode_cn52xx {
4033 + uint64_t reserved_10_63:54;
4034 + uint64_t speed:2;
4035 + uint64_t reserved_6_7:2;
4036 + uint64_t mode:2;
4037 + uint64_t reserved_2_3:2;
4038 + uint64_t en:1;
4039 + uint64_t type:1;
4040 + } cn52xx;
4041 + struct cvmx_gmxx_inf_mode_cn52xx cn52xxp1;
4042 + struct cvmx_gmxx_inf_mode_cn52xx cn56xx;
4043 + struct cvmx_gmxx_inf_mode_cn52xx cn56xxp1;
4044 + struct cvmx_gmxx_inf_mode_cn31xx cn58xx;
4045 + struct cvmx_gmxx_inf_mode_cn31xx cn58xxp1;
4046 +};
4047 +
4048 +union cvmx_gmxx_nxa_adr {
4049 + uint64_t u64;
4050 + struct cvmx_gmxx_nxa_adr_s {
4051 + uint64_t reserved_6_63:58;
4052 + uint64_t prt:6;
4053 + } s;
4054 + struct cvmx_gmxx_nxa_adr_s cn30xx;
4055 + struct cvmx_gmxx_nxa_adr_s cn31xx;
4056 + struct cvmx_gmxx_nxa_adr_s cn38xx;
4057 + struct cvmx_gmxx_nxa_adr_s cn38xxp2;
4058 + struct cvmx_gmxx_nxa_adr_s cn50xx;
4059 + struct cvmx_gmxx_nxa_adr_s cn52xx;
4060 + struct cvmx_gmxx_nxa_adr_s cn52xxp1;
4061 + struct cvmx_gmxx_nxa_adr_s cn56xx;
4062 + struct cvmx_gmxx_nxa_adr_s cn56xxp1;
4063 + struct cvmx_gmxx_nxa_adr_s cn58xx;
4064 + struct cvmx_gmxx_nxa_adr_s cn58xxp1;
4065 +};
4066 +
4067 +union cvmx_gmxx_prtx_cbfc_ctl {
4068 + uint64_t u64;
4069 + struct cvmx_gmxx_prtx_cbfc_ctl_s {
4070 + uint64_t phys_en:16;
4071 + uint64_t logl_en:16;
4072 + uint64_t phys_bp:16;
4073 + uint64_t reserved_4_15:12;
4074 + uint64_t bck_en:1;
4075 + uint64_t drp_en:1;
4076 + uint64_t tx_en:1;
4077 + uint64_t rx_en:1;
4078 + } s;
4079 + struct cvmx_gmxx_prtx_cbfc_ctl_s cn52xx;
4080 + struct cvmx_gmxx_prtx_cbfc_ctl_s cn56xx;
4081 +};
4082 +
4083 +union cvmx_gmxx_prtx_cfg {
4084 + uint64_t u64;
4085 + struct cvmx_gmxx_prtx_cfg_s {
4086 + uint64_t reserved_14_63:50;
4087 + uint64_t tx_idle:1;
4088 + uint64_t rx_idle:1;
4089 + uint64_t reserved_9_11:3;
4090 + uint64_t speed_msb:1;
4091 + uint64_t reserved_4_7:4;
4092 + uint64_t slottime:1;
4093 + uint64_t duplex:1;
4094 + uint64_t speed:1;
4095 + uint64_t en:1;
4096 + } s;
4097 + struct cvmx_gmxx_prtx_cfg_cn30xx {
4098 + uint64_t reserved_4_63:60;
4099 + uint64_t slottime:1;
4100 + uint64_t duplex:1;
4101 + uint64_t speed:1;
4102 + uint64_t en:1;
4103 + } cn30xx;
4104 + struct cvmx_gmxx_prtx_cfg_cn30xx cn31xx;
4105 + struct cvmx_gmxx_prtx_cfg_cn30xx cn38xx;
4106 + struct cvmx_gmxx_prtx_cfg_cn30xx cn38xxp2;
4107 + struct cvmx_gmxx_prtx_cfg_cn30xx cn50xx;
4108 + struct cvmx_gmxx_prtx_cfg_s cn52xx;
4109 + struct cvmx_gmxx_prtx_cfg_s cn52xxp1;
4110 + struct cvmx_gmxx_prtx_cfg_s cn56xx;
4111 + struct cvmx_gmxx_prtx_cfg_s cn56xxp1;
4112 + struct cvmx_gmxx_prtx_cfg_cn30xx cn58xx;
4113 + struct cvmx_gmxx_prtx_cfg_cn30xx cn58xxp1;
4114 +};
4115 +
4116 +union cvmx_gmxx_rxx_adr_cam0 {
4117 + uint64_t u64;
4118 + struct cvmx_gmxx_rxx_adr_cam0_s {
4119 + uint64_t adr:64;
4120 + } s;
4121 + struct cvmx_gmxx_rxx_adr_cam0_s cn30xx;
4122 + struct cvmx_gmxx_rxx_adr_cam0_s cn31xx;
4123 + struct cvmx_gmxx_rxx_adr_cam0_s cn38xx;
4124 + struct cvmx_gmxx_rxx_adr_cam0_s cn38xxp2;
4125 + struct cvmx_gmxx_rxx_adr_cam0_s cn50xx;
4126 + struct cvmx_gmxx_rxx_adr_cam0_s cn52xx;
4127 + struct cvmx_gmxx_rxx_adr_cam0_s cn52xxp1;
4128 + struct cvmx_gmxx_rxx_adr_cam0_s cn56xx;
4129 + struct cvmx_gmxx_rxx_adr_cam0_s cn56xxp1;
4130 + struct cvmx_gmxx_rxx_adr_cam0_s cn58xx;
4131 + struct cvmx_gmxx_rxx_adr_cam0_s cn58xxp1;
4132 +};
4133 +
4134 +union cvmx_gmxx_rxx_adr_cam1 {
4135 + uint64_t u64;
4136 + struct cvmx_gmxx_rxx_adr_cam1_s {
4137 + uint64_t adr:64;
4138 + } s;
4139 + struct cvmx_gmxx_rxx_adr_cam1_s cn30xx;
4140 + struct cvmx_gmxx_rxx_adr_cam1_s cn31xx;
4141 + struct cvmx_gmxx_rxx_adr_cam1_s cn38xx;
4142 + struct cvmx_gmxx_rxx_adr_cam1_s cn38xxp2;
4143 + struct cvmx_gmxx_rxx_adr_cam1_s cn50xx;
4144 + struct cvmx_gmxx_rxx_adr_cam1_s cn52xx;
4145 + struct cvmx_gmxx_rxx_adr_cam1_s cn52xxp1;
4146 + struct cvmx_gmxx_rxx_adr_cam1_s cn56xx;
4147 + struct cvmx_gmxx_rxx_adr_cam1_s cn56xxp1;
4148 + struct cvmx_gmxx_rxx_adr_cam1_s cn58xx;
4149 + struct cvmx_gmxx_rxx_adr_cam1_s cn58xxp1;
4150 +};
4151 +
4152 +union cvmx_gmxx_rxx_adr_cam2 {
4153 + uint64_t u64;
4154 + struct cvmx_gmxx_rxx_adr_cam2_s {
4155 + uint64_t adr:64;
4156 + } s;
4157 + struct cvmx_gmxx_rxx_adr_cam2_s cn30xx;
4158 + struct cvmx_gmxx_rxx_adr_cam2_s cn31xx;
4159 + struct cvmx_gmxx_rxx_adr_cam2_s cn38xx;
4160 + struct cvmx_gmxx_rxx_adr_cam2_s cn38xxp2;
4161 + struct cvmx_gmxx_rxx_adr_cam2_s cn50xx;
4162 + struct cvmx_gmxx_rxx_adr_cam2_s cn52xx;
4163 + struct cvmx_gmxx_rxx_adr_cam2_s cn52xxp1;
4164 + struct cvmx_gmxx_rxx_adr_cam2_s cn56xx;
4165 + struct cvmx_gmxx_rxx_adr_cam2_s cn56xxp1;
4166 + struct cvmx_gmxx_rxx_adr_cam2_s cn58xx;
4167 + struct cvmx_gmxx_rxx_adr_cam2_s cn58xxp1;
4168 +};
4169 +
4170 +union cvmx_gmxx_rxx_adr_cam3 {
4171 + uint64_t u64;
4172 + struct cvmx_gmxx_rxx_adr_cam3_s {
4173 + uint64_t adr:64;
4174 + } s;
4175 + struct cvmx_gmxx_rxx_adr_cam3_s cn30xx;
4176 + struct cvmx_gmxx_rxx_adr_cam3_s cn31xx;
4177 + struct cvmx_gmxx_rxx_adr_cam3_s cn38xx;
4178 + struct cvmx_gmxx_rxx_adr_cam3_s cn38xxp2;
4179 + struct cvmx_gmxx_rxx_adr_cam3_s cn50xx;
4180 + struct cvmx_gmxx_rxx_adr_cam3_s cn52xx;
4181 + struct cvmx_gmxx_rxx_adr_cam3_s cn52xxp1;
4182 + struct cvmx_gmxx_rxx_adr_cam3_s cn56xx;
4183 + struct cvmx_gmxx_rxx_adr_cam3_s cn56xxp1;
4184 + struct cvmx_gmxx_rxx_adr_cam3_s cn58xx;
4185 + struct cvmx_gmxx_rxx_adr_cam3_s cn58xxp1;
4186 +};
4187 +
4188 +union cvmx_gmxx_rxx_adr_cam4 {
4189 + uint64_t u64;
4190 + struct cvmx_gmxx_rxx_adr_cam4_s {
4191 + uint64_t adr:64;
4192 + } s;
4193 + struct cvmx_gmxx_rxx_adr_cam4_s cn30xx;
4194 + struct cvmx_gmxx_rxx_adr_cam4_s cn31xx;
4195 + struct cvmx_gmxx_rxx_adr_cam4_s cn38xx;
4196 + struct cvmx_gmxx_rxx_adr_cam4_s cn38xxp2;
4197 + struct cvmx_gmxx_rxx_adr_cam4_s cn50xx;
4198 + struct cvmx_gmxx_rxx_adr_cam4_s cn52xx;
4199 + struct cvmx_gmxx_rxx_adr_cam4_s cn52xxp1;
4200 + struct cvmx_gmxx_rxx_adr_cam4_s cn56xx;
4201 + struct cvmx_gmxx_rxx_adr_cam4_s cn56xxp1;
4202 + struct cvmx_gmxx_rxx_adr_cam4_s cn58xx;
4203 + struct cvmx_gmxx_rxx_adr_cam4_s cn58xxp1;
4204 +};
4205 +
4206 +union cvmx_gmxx_rxx_adr_cam5 {
4207 + uint64_t u64;
4208 + struct cvmx_gmxx_rxx_adr_cam5_s {
4209 + uint64_t adr:64;
4210 + } s;
4211 + struct cvmx_gmxx_rxx_adr_cam5_s cn30xx;
4212 + struct cvmx_gmxx_rxx_adr_cam5_s cn31xx;
4213 + struct cvmx_gmxx_rxx_adr_cam5_s cn38xx;
4214 + struct cvmx_gmxx_rxx_adr_cam5_s cn38xxp2;
4215 + struct cvmx_gmxx_rxx_adr_cam5_s cn50xx;
4216 + struct cvmx_gmxx_rxx_adr_cam5_s cn52xx;
4217 + struct cvmx_gmxx_rxx_adr_cam5_s cn52xxp1;
4218 + struct cvmx_gmxx_rxx_adr_cam5_s cn56xx;
4219 + struct cvmx_gmxx_rxx_adr_cam5_s cn56xxp1;
4220 + struct cvmx_gmxx_rxx_adr_cam5_s cn58xx;
4221 + struct cvmx_gmxx_rxx_adr_cam5_s cn58xxp1;
4222 +};
4223 +
4224 +union cvmx_gmxx_rxx_adr_cam_en {
4225 + uint64_t u64;
4226 + struct cvmx_gmxx_rxx_adr_cam_en_s {
4227 + uint64_t reserved_8_63:56;
4228 + uint64_t en:8;
4229 + } s;
4230 + struct cvmx_gmxx_rxx_adr_cam_en_s cn30xx;
4231 + struct cvmx_gmxx_rxx_adr_cam_en_s cn31xx;
4232 + struct cvmx_gmxx_rxx_adr_cam_en_s cn38xx;
4233 + struct cvmx_gmxx_rxx_adr_cam_en_s cn38xxp2;
4234 + struct cvmx_gmxx_rxx_adr_cam_en_s cn50xx;
4235 + struct cvmx_gmxx_rxx_adr_cam_en_s cn52xx;
4236 + struct cvmx_gmxx_rxx_adr_cam_en_s cn52xxp1;
4237 + struct cvmx_gmxx_rxx_adr_cam_en_s cn56xx;
4238 + struct cvmx_gmxx_rxx_adr_cam_en_s cn56xxp1;
4239 + struct cvmx_gmxx_rxx_adr_cam_en_s cn58xx;
4240 + struct cvmx_gmxx_rxx_adr_cam_en_s cn58xxp1;
4241 +};
4242 +
4243 +union cvmx_gmxx_rxx_adr_ctl {
4244 + uint64_t u64;
4245 + struct cvmx_gmxx_rxx_adr_ctl_s {
4246 + uint64_t reserved_4_63:60;
4247 + uint64_t cam_mode:1;
4248 + uint64_t mcst:2;
4249 + uint64_t bcst:1;
4250 + } s;
4251 + struct cvmx_gmxx_rxx_adr_ctl_s cn30xx;
4252 + struct cvmx_gmxx_rxx_adr_ctl_s cn31xx;
4253 + struct cvmx_gmxx_rxx_adr_ctl_s cn38xx;
4254 + struct cvmx_gmxx_rxx_adr_ctl_s cn38xxp2;
4255 + struct cvmx_gmxx_rxx_adr_ctl_s cn50xx;
4256 + struct cvmx_gmxx_rxx_adr_ctl_s cn52xx;
4257 + struct cvmx_gmxx_rxx_adr_ctl_s cn52xxp1;
4258 + struct cvmx_gmxx_rxx_adr_ctl_s cn56xx;
4259 + struct cvmx_gmxx_rxx_adr_ctl_s cn56xxp1;
4260 + struct cvmx_gmxx_rxx_adr_ctl_s cn58xx;
4261 + struct cvmx_gmxx_rxx_adr_ctl_s cn58xxp1;
4262 +};
4263 +
4264 +union cvmx_gmxx_rxx_decision {
4265 + uint64_t u64;
4266 + struct cvmx_gmxx_rxx_decision_s {
4267 + uint64_t reserved_5_63:59;
4268 + uint64_t cnt:5;
4269 + } s;
4270 + struct cvmx_gmxx_rxx_decision_s cn30xx;
4271 + struct cvmx_gmxx_rxx_decision_s cn31xx;
4272 + struct cvmx_gmxx_rxx_decision_s cn38xx;
4273 + struct cvmx_gmxx_rxx_decision_s cn38xxp2;
4274 + struct cvmx_gmxx_rxx_decision_s cn50xx;
4275 + struct cvmx_gmxx_rxx_decision_s cn52xx;
4276 + struct cvmx_gmxx_rxx_decision_s cn52xxp1;
4277 + struct cvmx_gmxx_rxx_decision_s cn56xx;
4278 + struct cvmx_gmxx_rxx_decision_s cn56xxp1;
4279 + struct cvmx_gmxx_rxx_decision_s cn58xx;
4280 + struct cvmx_gmxx_rxx_decision_s cn58xxp1;
4281 +};
4282 +
4283 +union cvmx_gmxx_rxx_frm_chk {
4284 + uint64_t u64;
4285 + struct cvmx_gmxx_rxx_frm_chk_s {
4286 + uint64_t reserved_10_63:54;
4287 + uint64_t niberr:1;
4288 + uint64_t skperr:1;
4289 + uint64_t rcverr:1;
4290 + uint64_t lenerr:1;
4291 + uint64_t alnerr:1;
4292 + uint64_t fcserr:1;
4293 + uint64_t jabber:1;
4294 + uint64_t maxerr:1;
4295 + uint64_t carext:1;
4296 + uint64_t minerr:1;
4297 + } s;
4298 + struct cvmx_gmxx_rxx_frm_chk_s cn30xx;
4299 + struct cvmx_gmxx_rxx_frm_chk_s cn31xx;
4300 + struct cvmx_gmxx_rxx_frm_chk_s cn38xx;
4301 + struct cvmx_gmxx_rxx_frm_chk_s cn38xxp2;
4302 + struct cvmx_gmxx_rxx_frm_chk_cn50xx {
4303 + uint64_t reserved_10_63:54;
4304 + uint64_t niberr:1;
4305 + uint64_t skperr:1;
4306 + uint64_t rcverr:1;
4307 + uint64_t reserved_6_6:1;
4308 + uint64_t alnerr:1;
4309 + uint64_t fcserr:1;
4310 + uint64_t jabber:1;
4311 + uint64_t reserved_2_2:1;
4312 + uint64_t carext:1;
4313 + uint64_t reserved_0_0:1;
4314 + } cn50xx;
4315 + struct cvmx_gmxx_rxx_frm_chk_cn52xx {
4316 + uint64_t reserved_9_63:55;
4317 + uint64_t skperr:1;
4318 + uint64_t rcverr:1;
4319 + uint64_t reserved_5_6:2;
4320 + uint64_t fcserr:1;
4321 + uint64_t jabber:1;
4322 + uint64_t reserved_2_2:1;
4323 + uint64_t carext:1;
4324 + uint64_t reserved_0_0:1;
4325 + } cn52xx;
4326 + struct cvmx_gmxx_rxx_frm_chk_cn52xx cn52xxp1;
4327 + struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xx;
4328 + struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xxp1;
4329 + struct cvmx_gmxx_rxx_frm_chk_s cn58xx;
4330 + struct cvmx_gmxx_rxx_frm_chk_s cn58xxp1;
4331 +};
4332 +
4333 +union cvmx_gmxx_rxx_frm_ctl {
4334 + uint64_t u64;
4335 + struct cvmx_gmxx_rxx_frm_ctl_s {
4336 + uint64_t reserved_11_63:53;
4337 + uint64_t null_dis:1;
4338 + uint64_t pre_align:1;
4339 + uint64_t pad_len:1;
4340 + uint64_t vlan_len:1;
4341 + uint64_t pre_free:1;
4342 + uint64_t ctl_smac:1;
4343 + uint64_t ctl_mcst:1;
4344 + uint64_t ctl_bck:1;
4345 + uint64_t ctl_drp:1;
4346 + uint64_t pre_strp:1;
4347 + uint64_t pre_chk:1;
4348 + } s;
4349 + struct cvmx_gmxx_rxx_frm_ctl_cn30xx {
4350 + uint64_t reserved_9_63:55;
4351 + uint64_t pad_len:1;
4352 + uint64_t vlan_len:1;
4353 + uint64_t pre_free:1;
4354 + uint64_t ctl_smac:1;
4355 + uint64_t ctl_mcst:1;
4356 + uint64_t ctl_bck:1;
4357 + uint64_t ctl_drp:1;
4358 + uint64_t pre_strp:1;
4359 + uint64_t pre_chk:1;
4360 + } cn30xx;
4361 + struct cvmx_gmxx_rxx_frm_ctl_cn31xx {
4362 + uint64_t reserved_8_63:56;
4363 + uint64_t vlan_len:1;
4364 + uint64_t pre_free:1;
4365 + uint64_t ctl_smac:1;
4366 + uint64_t ctl_mcst:1;
4367 + uint64_t ctl_bck:1;
4368 + uint64_t ctl_drp:1;
4369 + uint64_t pre_strp:1;
4370 + uint64_t pre_chk:1;
4371 + } cn31xx;
4372 + struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn38xx;
4373 + struct cvmx_gmxx_rxx_frm_ctl_cn31xx cn38xxp2;
4374 + struct cvmx_gmxx_rxx_frm_ctl_cn50xx {
4375 + uint64_t reserved_11_63:53;
4376 + uint64_t null_dis:1;
4377 + uint64_t pre_align:1;
4378 + uint64_t reserved_7_8:2;
4379 + uint64_t pre_free:1;
4380 + uint64_t ctl_smac:1;
4381 + uint64_t ctl_mcst:1;
4382 + uint64_t ctl_bck:1;
4383 + uint64_t ctl_drp:1;
4384 + uint64_t pre_strp:1;
4385 + uint64_t pre_chk:1;
4386 + } cn50xx;
4387 + struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xx;
4388 + struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xxp1;
4389 + struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn56xx;
4390 + struct cvmx_gmxx_rxx_frm_ctl_cn56xxp1 {
4391 + uint64_t reserved_10_63:54;
4392 + uint64_t pre_align:1;
4393 + uint64_t reserved_7_8:2;
4394 + uint64_t pre_free:1;
4395 + uint64_t ctl_smac:1;
4396 + uint64_t ctl_mcst:1;
4397 + uint64_t ctl_bck:1;
4398 + uint64_t ctl_drp:1;
4399 + uint64_t pre_strp:1;
4400 + uint64_t pre_chk:1;
4401 + } cn56xxp1;
4402 + struct cvmx_gmxx_rxx_frm_ctl_s cn58xx;
4403 + struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn58xxp1;
4404 +};
4405 +
4406 +union cvmx_gmxx_rxx_frm_max {
4407 + uint64_t u64;
4408 + struct cvmx_gmxx_rxx_frm_max_s {
4409 + uint64_t reserved_16_63:48;
4410 + uint64_t len:16;
4411 + } s;
4412 + struct cvmx_gmxx_rxx_frm_max_s cn30xx;
4413 + struct cvmx_gmxx_rxx_frm_max_s cn31xx;
4414 + struct cvmx_gmxx_rxx_frm_max_s cn38xx;
4415 + struct cvmx_gmxx_rxx_frm_max_s cn38xxp2;
4416 + struct cvmx_gmxx_rxx_frm_max_s cn58xx;
4417 + struct cvmx_gmxx_rxx_frm_max_s cn58xxp1;
4418 +};
4419 +
4420 +union cvmx_gmxx_rxx_frm_min {
4421 + uint64_t u64;
4422 + struct cvmx_gmxx_rxx_frm_min_s {
4423 + uint64_t reserved_16_63:48;
4424 + uint64_t len:16;
4425 + } s;
4426 + struct cvmx_gmxx_rxx_frm_min_s cn30xx;
4427 + struct cvmx_gmxx_rxx_frm_min_s cn31xx;
4428 + struct cvmx_gmxx_rxx_frm_min_s cn38xx;
4429 + struct cvmx_gmxx_rxx_frm_min_s cn38xxp2;
4430 + struct cvmx_gmxx_rxx_frm_min_s cn58xx;
4431 + struct cvmx_gmxx_rxx_frm_min_s cn58xxp1;
4432 +};
4433 +
4434 +union cvmx_gmxx_rxx_ifg {
4435 + uint64_t u64;
4436 + struct cvmx_gmxx_rxx_ifg_s {
4437 + uint64_t reserved_4_63:60;
4438 + uint64_t ifg:4;
4439 + } s;
4440 + struct cvmx_gmxx_rxx_ifg_s cn30xx;
4441 + struct cvmx_gmxx_rxx_ifg_s cn31xx;
4442 + struct cvmx_gmxx_rxx_ifg_s cn38xx;
4443 + struct cvmx_gmxx_rxx_ifg_s cn38xxp2;
4444 + struct cvmx_gmxx_rxx_ifg_s cn50xx;
4445 + struct cvmx_gmxx_rxx_ifg_s cn52xx;
4446 + struct cvmx_gmxx_rxx_ifg_s cn52xxp1;
4447 + struct cvmx_gmxx_rxx_ifg_s cn56xx;
4448 + struct cvmx_gmxx_rxx_ifg_s cn56xxp1;
4449 + struct cvmx_gmxx_rxx_ifg_s cn58xx;
4450 + struct cvmx_gmxx_rxx_ifg_s cn58xxp1;
4451 +};
4452 +
4453 +union cvmx_gmxx_rxx_int_en {
4454 + uint64_t u64;
4455 + struct cvmx_gmxx_rxx_int_en_s {
4456 + uint64_t reserved_29_63:35;
4457 + uint64_t hg2cc:1;
4458 + uint64_t hg2fld:1;
4459 + uint64_t undat:1;
4460 + uint64_t uneop:1;
4461 + uint64_t unsop:1;
4462 + uint64_t bad_term:1;
4463 + uint64_t bad_seq:1;
4464 + uint64_t rem_fault:1;
4465 + uint64_t loc_fault:1;
4466 + uint64_t pause_drp:1;
4467 + uint64_t phy_dupx:1;
4468 + uint64_t phy_spd:1;
4469 + uint64_t phy_link:1;
4470 + uint64_t ifgerr:1;
4471 + uint64_t coldet:1;
4472 + uint64_t falerr:1;
4473 + uint64_t rsverr:1;
4474 + uint64_t pcterr:1;
4475 + uint64_t ovrerr:1;
4476 + uint64_t niberr:1;
4477 + uint64_t skperr:1;
4478 + uint64_t rcverr:1;
4479 + uint64_t lenerr:1;
4480 + uint64_t alnerr:1;
4481 + uint64_t fcserr:1;
4482 + uint64_t jabber:1;
4483 + uint64_t maxerr:1;
4484 + uint64_t carext:1;
4485 + uint64_t minerr:1;
4486 + } s;
4487 + struct cvmx_gmxx_rxx_int_en_cn30xx {
4488 + uint64_t reserved_19_63:45;
4489 + uint64_t phy_dupx:1;
4490 + uint64_t phy_spd:1;
4491 + uint64_t phy_link:1;
4492 + uint64_t ifgerr:1;
4493 + uint64_t coldet:1;
4494 + uint64_t falerr:1;
4495 + uint64_t rsverr:1;
4496 + uint64_t pcterr:1;
4497 + uint64_t ovrerr:1;
4498 + uint64_t niberr:1;
4499 + uint64_t skperr:1;
4500 + uint64_t rcverr:1;
4501 + uint64_t lenerr:1;
4502 + uint64_t alnerr:1;
4503 + uint64_t fcserr:1;
4504 + uint64_t jabber:1;
4505 + uint64_t maxerr:1;
4506 + uint64_t carext:1;
4507 + uint64_t minerr:1;
4508 + } cn30xx;
4509 + struct cvmx_gmxx_rxx_int_en_cn30xx cn31xx;
4510 + struct cvmx_gmxx_rxx_int_en_cn30xx cn38xx;
4511 + struct cvmx_gmxx_rxx_int_en_cn30xx cn38xxp2;
4512 + struct cvmx_gmxx_rxx_int_en_cn50xx {
4513 + uint64_t reserved_20_63:44;
4514 + uint64_t pause_drp:1;
4515 + uint64_t phy_dupx:1;
4516 + uint64_t phy_spd:1;
4517 + uint64_t phy_link:1;
4518 + uint64_t ifgerr:1;
4519 + uint64_t coldet:1;
4520 + uint64_t falerr:1;
4521 + uint64_t rsverr:1;
4522 + uint64_t pcterr:1;
4523 + uint64_t ovrerr:1;
4524 + uint64_t niberr:1;
4525 + uint64_t skperr:1;
4526 + uint64_t rcverr:1;
4527 + uint64_t reserved_6_6:1;
4528 + uint64_t alnerr:1;
4529 + uint64_t fcserr:1;
4530 + uint64_t jabber:1;
4531 + uint64_t reserved_2_2:1;
4532 + uint64_t carext:1;
4533 + uint64_t reserved_0_0:1;
4534 + } cn50xx;
4535 + struct cvmx_gmxx_rxx_int_en_cn52xx {
4536 + uint64_t reserved_29_63:35;
4537 + uint64_t hg2cc:1;
4538 + uint64_t hg2fld:1;
4539 + uint64_t undat:1;
4540 + uint64_t uneop:1;
4541 + uint64_t unsop:1;
4542 + uint64_t bad_term:1;
4543 + uint64_t bad_seq:1;
4544 + uint64_t rem_fault:1;
4545 + uint64_t loc_fault:1;
4546 + uint64_t pause_drp:1;
4547 + uint64_t reserved_16_18:3;
4548 + uint64_t ifgerr:1;
4549 + uint64_t coldet:1;
4550 + uint64_t falerr:1;
4551 + uint64_t rsverr:1;
4552 + uint64_t pcterr:1;
4553 + uint64_t ovrerr:1;
4554 + uint64_t reserved_9_9:1;
4555 + uint64_t skperr:1;
4556 + uint64_t rcverr:1;
4557 + uint64_t reserved_5_6:2;
4558 + uint64_t fcserr:1;
4559 + uint64_t jabber:1;
4560 + uint64_t reserved_2_2:1;
4561 + uint64_t carext:1;
4562 + uint64_t reserved_0_0:1;
4563 + } cn52xx;
4564 + struct cvmx_gmxx_rxx_int_en_cn52xx cn52xxp1;
4565 + struct cvmx_gmxx_rxx_int_en_cn52xx cn56xx;
4566 + struct cvmx_gmxx_rxx_int_en_cn56xxp1 {
4567 + uint64_t reserved_27_63:37;
4568 + uint64_t undat:1;
4569 + uint64_t uneop:1;
4570 + uint64_t unsop:1;
4571 + uint64_t bad_term:1;
4572 + uint64_t bad_seq:1;
4573 + uint64_t rem_fault:1;
4574 + uint64_t loc_fault:1;
4575 + uint64_t pause_drp:1;
4576 + uint64_t reserved_16_18:3;
4577 + uint64_t ifgerr:1;
4578 + uint64_t coldet:1;
4579 + uint64_t falerr:1;
4580 + uint64_t rsverr:1;
4581 + uint64_t pcterr:1;
4582 + uint64_t ovrerr:1;
4583 + uint64_t reserved_9_9:1;
4584 + uint64_t skperr:1;
4585 + uint64_t rcverr:1;
4586 + uint64_t reserved_5_6:2;
4587 + uint64_t fcserr:1;
4588 + uint64_t jabber:1;
4589 + uint64_t reserved_2_2:1;
4590 + uint64_t carext:1;
4591 + uint64_t reserved_0_0:1;
4592 + } cn56xxp1;
4593 + struct cvmx_gmxx_rxx_int_en_cn58xx {
4594 + uint64_t reserved_20_63:44;
4595 + uint64_t pause_drp:1;
4596 + uint64_t phy_dupx:1;
4597 + uint64_t phy_spd:1;
4598 + uint64_t phy_link:1;
4599 + uint64_t ifgerr:1;
4600 + uint64_t coldet:1;
4601 + uint64_t falerr:1;
4602 + uint64_t rsverr:1;
4603 + uint64_t pcterr:1;
4604 + uint64_t ovrerr:1;
4605 + uint64_t niberr:1;
4606 + uint64_t skperr:1;
4607 + uint64_t rcverr:1;
4608 + uint64_t lenerr:1;
4609 + uint64_t alnerr:1;
4610 + uint64_t fcserr:1;
4611 + uint64_t jabber:1;
4612 + uint64_t maxerr:1;
4613 + uint64_t carext:1;
4614 + uint64_t minerr:1;
4615 + } cn58xx;
4616 + struct cvmx_gmxx_rxx_int_en_cn58xx cn58xxp1;
4617 +};
4618 +
4619 +union cvmx_gmxx_rxx_int_reg {
4620 + uint64_t u64;
4621 + struct cvmx_gmxx_rxx_int_reg_s {
4622 + uint64_t reserved_29_63:35;
4623 + uint64_t hg2cc:1;
4624 + uint64_t hg2fld:1;
4625 + uint64_t undat:1;
4626 + uint64_t uneop:1;
4627 + uint64_t unsop:1;
4628 + uint64_t bad_term:1;
4629 + uint64_t bad_seq:1;
4630 + uint64_t rem_fault:1;
4631 + uint64_t loc_fault:1;
4632 + uint64_t pause_drp:1;
4633 + uint64_t phy_dupx:1;
4634 + uint64_t phy_spd:1;
4635 + uint64_t phy_link:1;
4636 + uint64_t ifgerr:1;
4637 + uint64_t coldet:1;
4638 + uint64_t falerr:1;
4639 + uint64_t rsverr:1;
4640 + uint64_t pcterr:1;
4641 + uint64_t ovrerr:1;
4642 + uint64_t niberr:1;
4643 + uint64_t skperr:1;
4644 + uint64_t rcverr:1;
4645 + uint64_t lenerr:1;
4646 + uint64_t alnerr:1;
4647 + uint64_t fcserr:1;
4648 + uint64_t jabber:1;
4649 + uint64_t maxerr:1;
4650 + uint64_t carext:1;
4651 + uint64_t minerr:1;
4652 + } s;
4653 + struct cvmx_gmxx_rxx_int_reg_cn30xx {
4654 + uint64_t reserved_19_63:45;
4655 + uint64_t phy_dupx:1;
4656 + uint64_t phy_spd:1;
4657 + uint64_t phy_link:1;
4658 + uint64_t ifgerr:1;
4659 + uint64_t coldet:1;
4660 + uint64_t falerr:1;
4661 + uint64_t rsverr:1;
4662 + uint64_t pcterr:1;
4663 + uint64_t ovrerr:1;
4664 + uint64_t niberr:1;
4665 + uint64_t skperr:1;
4666 + uint64_t rcverr:1;
4667 + uint64_t lenerr:1;
4668 + uint64_t alnerr:1;
4669 + uint64_t fcserr:1;
4670 + uint64_t jabber:1;
4671 + uint64_t maxerr:1;
4672 + uint64_t carext:1;
4673 + uint64_t minerr:1;
4674 + } cn30xx;
4675 + struct cvmx_gmxx_rxx_int_reg_cn30xx cn31xx;
4676 + struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xx;
4677 + struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xxp2;
4678 + struct cvmx_gmxx_rxx_int_reg_cn50xx {
4679 + uint64_t reserved_20_63:44;
4680 + uint64_t pause_drp:1;
4681 + uint64_t phy_dupx:1;
4682 + uint64_t phy_spd:1;
4683 + uint64_t phy_link:1;
4684 + uint64_t ifgerr:1;
4685 + uint64_t coldet:1;
4686 + uint64_t falerr:1;
4687 + uint64_t rsverr:1;
4688 + uint64_t pcterr:1;
4689 + uint64_t ovrerr:1;
4690 + uint64_t niberr:1;
4691 + uint64_t skperr:1;
4692 + uint64_t rcverr:1;
4693 + uint64_t reserved_6_6:1;
4694 + uint64_t alnerr:1;
4695 + uint64_t fcserr:1;
4696 + uint64_t jabber:1;
4697 + uint64_t reserved_2_2:1;
4698 + uint64_t carext:1;
4699 + uint64_t reserved_0_0:1;
4700 + } cn50xx;
4701 + struct cvmx_gmxx_rxx_int_reg_cn52xx {
4702 + uint64_t reserved_29_63:35;
4703 + uint64_t hg2cc:1;
4704 + uint64_t hg2fld:1;
4705 + uint64_t undat:1;
4706 + uint64_t uneop:1;
4707 + uint64_t unsop:1;
4708 + uint64_t bad_term:1;
4709 + uint64_t bad_seq:1;
4710 + uint64_t rem_fault:1;
4711 + uint64_t loc_fault:1;
4712 + uint64_t pause_drp:1;
4713 + uint64_t reserved_16_18:3;
4714 + uint64_t ifgerr:1;
4715 + uint64_t coldet:1;
4716 + uint64_t falerr:1;
4717 + uint64_t rsverr:1;
4718 + uint64_t pcterr:1;
4719 + uint64_t ovrerr:1;
4720 + uint64_t reserved_9_9:1;
4721 + uint64_t skperr:1;
4722 + uint64_t rcverr:1;
4723 + uint64_t reserved_5_6:2;
4724 + uint64_t fcserr:1;
4725 + uint64_t jabber:1;
4726 + uint64_t reserved_2_2:1;
4727 + uint64_t carext:1;
4728 + uint64_t reserved_0_0:1;
4729 + } cn52xx;
4730 + struct cvmx_gmxx_rxx_int_reg_cn52xx cn52xxp1;
4731 + struct cvmx_gmxx_rxx_int_reg_cn52xx cn56xx;
4732 + struct cvmx_gmxx_rxx_int_reg_cn56xxp1 {
4733 + uint64_t reserved_27_63:37;
4734 + uint64_t undat:1;
4735 + uint64_t uneop:1;
4736 + uint64_t unsop:1;
4737 + uint64_t bad_term:1;
4738 + uint64_t bad_seq:1;
4739 + uint64_t rem_fault:1;
4740 + uint64_t loc_fault:1;
4741 + uint64_t pause_drp:1;
4742 + uint64_t reserved_16_18:3;
4743 + uint64_t ifgerr:1;
4744 + uint64_t coldet:1;
4745 + uint64_t falerr:1;
4746 + uint64_t rsverr:1;
4747 + uint64_t pcterr:1;
4748 + uint64_t ovrerr:1;
4749 + uint64_t reserved_9_9:1;
4750 + uint64_t skperr:1;
4751 + uint64_t rcverr:1;
4752 + uint64_t reserved_5_6:2;
4753 + uint64_t fcserr:1;
4754 + uint64_t jabber:1;
4755 + uint64_t reserved_2_2:1;
4756 + uint64_t carext:1;
4757 + uint64_t reserved_0_0:1;
4758 + } cn56xxp1;
4759 + struct cvmx_gmxx_rxx_int_reg_cn58xx {
4760 + uint64_t reserved_20_63:44;
4761 + uint64_t pause_drp:1;
4762 + uint64_t phy_dupx:1;
4763 + uint64_t phy_spd:1;
4764 + uint64_t phy_link:1;
4765 + uint64_t ifgerr:1;
4766 + uint64_t coldet:1;
4767 + uint64_t falerr:1;
4768 + uint64_t rsverr:1;
4769 + uint64_t pcterr:1;
4770 + uint64_t ovrerr:1;
4771 + uint64_t niberr:1;
4772 + uint64_t skperr:1;
4773 + uint64_t rcverr:1;
4774 + uint64_t lenerr:1;
4775 + uint64_t alnerr:1;
4776 + uint64_t fcserr:1;
4777 + uint64_t jabber:1;
4778 + uint64_t maxerr:1;
4779 + uint64_t carext:1;
4780 + uint64_t minerr:1;
4781 + } cn58xx;
4782 + struct cvmx_gmxx_rxx_int_reg_cn58xx cn58xxp1;
4783 +};
4784 +
4785 +union cvmx_gmxx_rxx_jabber {
4786 + uint64_t u64;
4787 + struct cvmx_gmxx_rxx_jabber_s {
4788 + uint64_t reserved_16_63:48;
4789 + uint64_t cnt:16;
4790 + } s;
4791 + struct cvmx_gmxx_rxx_jabber_s cn30xx;
4792 + struct cvmx_gmxx_rxx_jabber_s cn31xx;
4793 + struct cvmx_gmxx_rxx_jabber_s cn38xx;
4794 + struct cvmx_gmxx_rxx_jabber_s cn38xxp2;
4795 + struct cvmx_gmxx_rxx_jabber_s cn50xx;
4796 + struct cvmx_gmxx_rxx_jabber_s cn52xx;
4797 + struct cvmx_gmxx_rxx_jabber_s cn52xxp1;
4798 + struct cvmx_gmxx_rxx_jabber_s cn56xx;
4799 + struct cvmx_gmxx_rxx_jabber_s cn56xxp1;
4800 + struct cvmx_gmxx_rxx_jabber_s cn58xx;
4801 + struct cvmx_gmxx_rxx_jabber_s cn58xxp1;
4802 +};
4803 +
4804 +union cvmx_gmxx_rxx_pause_drop_time {
4805 + uint64_t u64;
4806 + struct cvmx_gmxx_rxx_pause_drop_time_s {
4807 + uint64_t reserved_16_63:48;
4808 + uint64_t status:16;
4809 + } s;
4810 + struct cvmx_gmxx_rxx_pause_drop_time_s cn50xx;
4811 + struct cvmx_gmxx_rxx_pause_drop_time_s cn52xx;
4812 + struct cvmx_gmxx_rxx_pause_drop_time_s cn52xxp1;
4813 + struct cvmx_gmxx_rxx_pause_drop_time_s cn56xx;
4814 + struct cvmx_gmxx_rxx_pause_drop_time_s cn56xxp1;
4815 + struct cvmx_gmxx_rxx_pause_drop_time_s cn58xx;
4816 + struct cvmx_gmxx_rxx_pause_drop_time_s cn58xxp1;
4817 +};
4818 +
4819 +union cvmx_gmxx_rxx_rx_inbnd {
4820 + uint64_t u64;
4821 + struct cvmx_gmxx_rxx_rx_inbnd_s {
4822 + uint64_t reserved_4_63:60;
4823 + uint64_t duplex:1;
4824 + uint64_t speed:2;
4825 + uint64_t status:1;
4826 + } s;
4827 + struct cvmx_gmxx_rxx_rx_inbnd_s cn30xx;
4828 + struct cvmx_gmxx_rxx_rx_inbnd_s cn31xx;
4829 + struct cvmx_gmxx_rxx_rx_inbnd_s cn38xx;
4830 + struct cvmx_gmxx_rxx_rx_inbnd_s cn38xxp2;
4831 + struct cvmx_gmxx_rxx_rx_inbnd_s cn50xx;
4832 + struct cvmx_gmxx_rxx_rx_inbnd_s cn58xx;
4833 + struct cvmx_gmxx_rxx_rx_inbnd_s cn58xxp1;
4834 +};
4835 +
4836 +union cvmx_gmxx_rxx_stats_ctl {
4837 + uint64_t u64;
4838 + struct cvmx_gmxx_rxx_stats_ctl_s {
4839 + uint64_t reserved_1_63:63;
4840 + uint64_t rd_clr:1;
4841 + } s;
4842 + struct cvmx_gmxx_rxx_stats_ctl_s cn30xx;
4843 + struct cvmx_gmxx_rxx_stats_ctl_s cn31xx;
4844 + struct cvmx_gmxx_rxx_stats_ctl_s cn38xx;
4845 + struct cvmx_gmxx_rxx_stats_ctl_s cn38xxp2;
4846 + struct cvmx_gmxx_rxx_stats_ctl_s cn50xx;
4847 + struct cvmx_gmxx_rxx_stats_ctl_s cn52xx;
4848 + struct cvmx_gmxx_rxx_stats_ctl_s cn52xxp1;
4849 + struct cvmx_gmxx_rxx_stats_ctl_s cn56xx;
4850 + struct cvmx_gmxx_rxx_stats_ctl_s cn56xxp1;
4851 + struct cvmx_gmxx_rxx_stats_ctl_s cn58xx;
4852 + struct cvmx_gmxx_rxx_stats_ctl_s cn58xxp1;
4853 +};
4854 +
4855 +union cvmx_gmxx_rxx_stats_octs {
4856 + uint64_t u64;
4857 + struct cvmx_gmxx_rxx_stats_octs_s {
4858 + uint64_t reserved_48_63:16;
4859 + uint64_t cnt:48;
4860 + } s;
4861 + struct cvmx_gmxx_rxx_stats_octs_s cn30xx;
4862 + struct cvmx_gmxx_rxx_stats_octs_s cn31xx;
4863 + struct cvmx_gmxx_rxx_stats_octs_s cn38xx;
4864 + struct cvmx_gmxx_rxx_stats_octs_s cn38xxp2;
4865 + struct cvmx_gmxx_rxx_stats_octs_s cn50xx;
4866 + struct cvmx_gmxx_rxx_stats_octs_s cn52xx;
4867 + struct cvmx_gmxx_rxx_stats_octs_s cn52xxp1;
4868 + struct cvmx_gmxx_rxx_stats_octs_s cn56xx;
4869 + struct cvmx_gmxx_rxx_stats_octs_s cn56xxp1;
4870 + struct cvmx_gmxx_rxx_stats_octs_s cn58xx;
4871 + struct cvmx_gmxx_rxx_stats_octs_s cn58xxp1;
4872 +};
4873 +
4874 +union cvmx_gmxx_rxx_stats_octs_ctl {
4875 + uint64_t u64;
4876 + struct cvmx_gmxx_rxx_stats_octs_ctl_s {
4877 + uint64_t reserved_48_63:16;
4878 + uint64_t cnt:48;
4879 + } s;
4880 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn30xx;
4881 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn31xx;
4882 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xx;
4883 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xxp2;
4884 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn50xx;
4885 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xx;
4886 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xxp1;
4887 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xx;
4888 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xxp1;
4889 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xx;
4890 + struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xxp1;
4891 +};
4892 +
4893 +union cvmx_gmxx_rxx_stats_octs_dmac {
4894 + uint64_t u64;
4895 + struct cvmx_gmxx_rxx_stats_octs_dmac_s {
4896 + uint64_t reserved_48_63:16;
4897 + uint64_t cnt:48;
4898 + } s;
4899 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn30xx;
4900 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn31xx;
4901 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xx;
4902 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xxp2;
4903 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn50xx;
4904 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xx;
4905 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xxp1;
4906 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xx;
4907 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xxp1;
4908 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xx;
4909 + struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xxp1;
4910 +};
4911 +
4912 +union cvmx_gmxx_rxx_stats_octs_drp {
4913 + uint64_t u64;
4914 + struct cvmx_gmxx_rxx_stats_octs_drp_s {
4915 + uint64_t reserved_48_63:16;
4916 + uint64_t cnt:48;
4917 + } s;
4918 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn30xx;
4919 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn31xx;
4920 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xx;
4921 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xxp2;
4922 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn50xx;
4923 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xx;
4924 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xxp1;
4925 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xx;
4926 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xxp1;
4927 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xx;
4928 + struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xxp1;
4929 +};
4930 +
4931 +union cvmx_gmxx_rxx_stats_pkts {
4932 + uint64_t u64;
4933 + struct cvmx_gmxx_rxx_stats_pkts_s {
4934 + uint64_t reserved_32_63:32;
4935 + uint64_t cnt:32;
4936 + } s;
4937 + struct cvmx_gmxx_rxx_stats_pkts_s cn30xx;
4938 + struct cvmx_gmxx_rxx_stats_pkts_s cn31xx;
4939 + struct cvmx_gmxx_rxx_stats_pkts_s cn38xx;
4940 + struct cvmx_gmxx_rxx_stats_pkts_s cn38xxp2;
4941 + struct cvmx_gmxx_rxx_stats_pkts_s cn50xx;
4942 + struct cvmx_gmxx_rxx_stats_pkts_s cn52xx;
4943 + struct cvmx_gmxx_rxx_stats_pkts_s cn52xxp1;
4944 + struct cvmx_gmxx_rxx_stats_pkts_s cn56xx;
4945 + struct cvmx_gmxx_rxx_stats_pkts_s cn56xxp1;
4946 + struct cvmx_gmxx_rxx_stats_pkts_s cn58xx;
4947 + struct cvmx_gmxx_rxx_stats_pkts_s cn58xxp1;
4948 +};
4949 +
4950 +union cvmx_gmxx_rxx_stats_pkts_bad {
4951 + uint64_t u64;
4952 + struct cvmx_gmxx_rxx_stats_pkts_bad_s {
4953 + uint64_t reserved_32_63:32;
4954 + uint64_t cnt:32;
4955 + } s;
4956 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn30xx;
4957 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn31xx;
4958 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xx;
4959 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xxp2;
4960 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn50xx;
4961 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xx;
4962 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xxp1;
4963 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xx;
4964 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xxp1;
4965 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xx;
4966 + struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xxp1;
4967 +};
4968 +
4969 +union cvmx_gmxx_rxx_stats_pkts_ctl {
4970 + uint64_t u64;
4971 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s {
4972 + uint64_t reserved_32_63:32;
4973 + uint64_t cnt:32;
4974 + } s;
4975 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn30xx;
4976 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn31xx;
4977 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xx;
4978 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xxp2;
4979 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn50xx;
4980 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xx;
4981 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xxp1;
4982 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xx;
4983 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xxp1;
4984 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xx;
4985 + struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xxp1;
4986 +};
4987 +
4988 +union cvmx_gmxx_rxx_stats_pkts_dmac {
4989 + uint64_t u64;
4990 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s {
4991 + uint64_t reserved_32_63:32;
4992 + uint64_t cnt:32;
4993 + } s;
4994 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn30xx;
4995 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn31xx;
4996 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xx;
4997 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xxp2;
4998 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn50xx;
4999 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xx;
5000 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xxp1;
5001 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xx;
5002 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xxp1;
5003 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xx;
5004 + struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xxp1;
5005 +};
5006 +
5007 +union cvmx_gmxx_rxx_stats_pkts_drp {
5008 + uint64_t u64;
5009 + struct cvmx_gmxx_rxx_stats_pkts_drp_s {
5010 + uint64_t reserved_32_63:32;
5011 + uint64_t cnt:32;
5012 + } s;
5013 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn30xx;
5014 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn31xx;
5015 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xx;
5016 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xxp2;
5017 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn50xx;
5018 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xx;
5019 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xxp1;
5020 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xx;
5021 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xxp1;
5022 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xx;
5023 + struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xxp1;
5024 +};
5025 +
5026 +union cvmx_gmxx_rxx_udd_skp {
5027 + uint64_t u64;
5028 + struct cvmx_gmxx_rxx_udd_skp_s {
5029 + uint64_t reserved_9_63:55;
5030 + uint64_t fcssel:1;
5031 + uint64_t reserved_7_7:1;
5032 + uint64_t len:7;
5033 + } s;
5034 + struct cvmx_gmxx_rxx_udd_skp_s cn30xx;
5035 + struct cvmx_gmxx_rxx_udd_skp_s cn31xx;
5036 + struct cvmx_gmxx_rxx_udd_skp_s cn38xx;
5037 + struct cvmx_gmxx_rxx_udd_skp_s cn38xxp2;
5038 + struct cvmx_gmxx_rxx_udd_skp_s cn50xx;
5039 + struct cvmx_gmxx_rxx_udd_skp_s cn52xx;
5040 + struct cvmx_gmxx_rxx_udd_skp_s cn52xxp1;
5041 + struct cvmx_gmxx_rxx_udd_skp_s cn56xx;
5042 + struct cvmx_gmxx_rxx_udd_skp_s cn56xxp1;
5043 + struct cvmx_gmxx_rxx_udd_skp_s cn58xx;
5044 + struct cvmx_gmxx_rxx_udd_skp_s cn58xxp1;
5045 +};
5046 +
5047 +union cvmx_gmxx_rx_bp_dropx {
5048 + uint64_t u64;
5049 + struct cvmx_gmxx_rx_bp_dropx_s {
5050 + uint64_t reserved_6_63:58;
5051 + uint64_t mark:6;
5052 + } s;
5053 + struct cvmx_gmxx_rx_bp_dropx_s cn30xx;
5054 + struct cvmx_gmxx_rx_bp_dropx_s cn31xx;
5055 + struct cvmx_gmxx_rx_bp_dropx_s cn38xx;
5056 + struct cvmx_gmxx_rx_bp_dropx_s cn38xxp2;
5057 + struct cvmx_gmxx_rx_bp_dropx_s cn50xx;
5058 + struct cvmx_gmxx_rx_bp_dropx_s cn52xx;
5059 + struct cvmx_gmxx_rx_bp_dropx_s cn52xxp1;
5060 + struct cvmx_gmxx_rx_bp_dropx_s cn56xx;
5061 + struct cvmx_gmxx_rx_bp_dropx_s cn56xxp1;
5062 + struct cvmx_gmxx_rx_bp_dropx_s cn58xx;
5063 + struct cvmx_gmxx_rx_bp_dropx_s cn58xxp1;
5064 +};
5065 +
5066 +union cvmx_gmxx_rx_bp_offx {
5067 + uint64_t u64;
5068 + struct cvmx_gmxx_rx_bp_offx_s {
5069 + uint64_t reserved_6_63:58;
5070 + uint64_t mark:6;
5071 + } s;
5072 + struct cvmx_gmxx_rx_bp_offx_s cn30xx;
5073 + struct cvmx_gmxx_rx_bp_offx_s cn31xx;
5074 + struct cvmx_gmxx_rx_bp_offx_s cn38xx;
5075 + struct cvmx_gmxx_rx_bp_offx_s cn38xxp2;
5076 + struct cvmx_gmxx_rx_bp_offx_s cn50xx;
5077 + struct cvmx_gmxx_rx_bp_offx_s cn52xx;
5078 + struct cvmx_gmxx_rx_bp_offx_s cn52xxp1;
5079 + struct cvmx_gmxx_rx_bp_offx_s cn56xx;
5080 + struct cvmx_gmxx_rx_bp_offx_s cn56xxp1;
5081 + struct cvmx_gmxx_rx_bp_offx_s cn58xx;
5082 + struct cvmx_gmxx_rx_bp_offx_s cn58xxp1;
5083 +};
5084 +
5085 +union cvmx_gmxx_rx_bp_onx {
5086 + uint64_t u64;
5087 + struct cvmx_gmxx_rx_bp_onx_s {
5088 + uint64_t reserved_9_63:55;
5089 + uint64_t mark:9;
5090 + } s;
5091 + struct cvmx_gmxx_rx_bp_onx_s cn30xx;
5092 + struct cvmx_gmxx_rx_bp_onx_s cn31xx;
5093 + struct cvmx_gmxx_rx_bp_onx_s cn38xx;
5094 + struct cvmx_gmxx_rx_bp_onx_s cn38xxp2;
5095 + struct cvmx_gmxx_rx_bp_onx_s cn50xx;
5096 + struct cvmx_gmxx_rx_bp_onx_s cn52xx;
5097 + struct cvmx_gmxx_rx_bp_onx_s cn52xxp1;
5098 + struct cvmx_gmxx_rx_bp_onx_s cn56xx;
5099 + struct cvmx_gmxx_rx_bp_onx_s cn56xxp1;
5100 + struct cvmx_gmxx_rx_bp_onx_s cn58xx;
5101 + struct cvmx_gmxx_rx_bp_onx_s cn58xxp1;
5102 +};
5103 +
5104 +union cvmx_gmxx_rx_hg2_status {
5105 + uint64_t u64;
5106 + struct cvmx_gmxx_rx_hg2_status_s {
5107 + uint64_t reserved_48_63:16;
5108 + uint64_t phtim2go:16;
5109 + uint64_t xof:16;
5110 + uint64_t lgtim2go:16;
5111 + } s;
5112 + struct cvmx_gmxx_rx_hg2_status_s cn52xx;
5113 + struct cvmx_gmxx_rx_hg2_status_s cn52xxp1;
5114 + struct cvmx_gmxx_rx_hg2_status_s cn56xx;
5115 +};
5116 +
5117 +union cvmx_gmxx_rx_pass_en {
5118 + uint64_t u64;
5119 + struct cvmx_gmxx_rx_pass_en_s {
5120 + uint64_t reserved_16_63:48;
5121 + uint64_t en:16;
5122 + } s;
5123 + struct cvmx_gmxx_rx_pass_en_s cn38xx;
5124 + struct cvmx_gmxx_rx_pass_en_s cn38xxp2;
5125 + struct cvmx_gmxx_rx_pass_en_s cn58xx;
5126 + struct cvmx_gmxx_rx_pass_en_s cn58xxp1;
5127 +};
5128 +
5129 +union cvmx_gmxx_rx_pass_mapx {
5130 + uint64_t u64;
5131 + struct cvmx_gmxx_rx_pass_mapx_s {
5132 + uint64_t reserved_4_63:60;
5133 + uint64_t dprt:4;
5134 + } s;
5135 + struct cvmx_gmxx_rx_pass_mapx_s cn38xx;
5136 + struct cvmx_gmxx_rx_pass_mapx_s cn38xxp2;
5137 + struct cvmx_gmxx_rx_pass_mapx_s cn58xx;
5138 + struct cvmx_gmxx_rx_pass_mapx_s cn58xxp1;
5139 +};
5140 +
5141 +union cvmx_gmxx_rx_prt_info {
5142 + uint64_t u64;
5143 + struct cvmx_gmxx_rx_prt_info_s {
5144 + uint64_t reserved_32_63:32;
5145 + uint64_t drop:16;
5146 + uint64_t commit:16;
5147 + } s;
5148 + struct cvmx_gmxx_rx_prt_info_cn30xx {
5149 + uint64_t reserved_19_63:45;
5150 + uint64_t drop:3;
5151 + uint64_t reserved_3_15:13;
5152 + uint64_t commit:3;
5153 + } cn30xx;
5154 + struct cvmx_gmxx_rx_prt_info_cn30xx cn31xx;
5155 + struct cvmx_gmxx_rx_prt_info_s cn38xx;
5156 + struct cvmx_gmxx_rx_prt_info_cn30xx cn50xx;
5157 + struct cvmx_gmxx_rx_prt_info_cn52xx {
5158 + uint64_t reserved_20_63:44;
5159 + uint64_t drop:4;
5160 + uint64_t reserved_4_15:12;
5161 + uint64_t commit:4;
5162 + } cn52xx;
5163 + struct cvmx_gmxx_rx_prt_info_cn52xx cn52xxp1;
5164 + struct cvmx_gmxx_rx_prt_info_cn52xx cn56xx;
5165 + struct cvmx_gmxx_rx_prt_info_cn52xx cn56xxp1;
5166 + struct cvmx_gmxx_rx_prt_info_s cn58xx;
5167 + struct cvmx_gmxx_rx_prt_info_s cn58xxp1;
5168 +};
5169 +
5170 +union cvmx_gmxx_rx_prts {
5171 + uint64_t u64;
5172 + struct cvmx_gmxx_rx_prts_s {
5173 + uint64_t reserved_3_63:61;
5174 + uint64_t prts:3;
5175 + } s;
5176 + struct cvmx_gmxx_rx_prts_s cn30xx;
5177 + struct cvmx_gmxx_rx_prts_s cn31xx;
5178 + struct cvmx_gmxx_rx_prts_s cn38xx;
5179 + struct cvmx_gmxx_rx_prts_s cn38xxp2;
5180 + struct cvmx_gmxx_rx_prts_s cn50xx;
5181 + struct cvmx_gmxx_rx_prts_s cn52xx;
5182 + struct cvmx_gmxx_rx_prts_s cn52xxp1;
5183 + struct cvmx_gmxx_rx_prts_s cn56xx;
5184 + struct cvmx_gmxx_rx_prts_s cn56xxp1;
5185 + struct cvmx_gmxx_rx_prts_s cn58xx;
5186 + struct cvmx_gmxx_rx_prts_s cn58xxp1;
5187 +};
5188 +
5189 +union cvmx_gmxx_rx_tx_status {
5190 + uint64_t u64;
5191 + struct cvmx_gmxx_rx_tx_status_s {
5192 + uint64_t reserved_7_63:57;
5193 + uint64_t tx:3;
5194 + uint64_t reserved_3_3:1;
5195 + uint64_t rx:3;
5196 + } s;
5197 + struct cvmx_gmxx_rx_tx_status_s cn30xx;
5198 + struct cvmx_gmxx_rx_tx_status_s cn31xx;
5199 + struct cvmx_gmxx_rx_tx_status_s cn50xx;
5200 +};
5201 +
5202 +union cvmx_gmxx_rx_xaui_bad_col {
5203 + uint64_t u64;
5204 + struct cvmx_gmxx_rx_xaui_bad_col_s {
5205 + uint64_t reserved_40_63:24;
5206 + uint64_t val:1;
5207 + uint64_t state:3;
5208 + uint64_t lane_rxc:4;
5209 + uint64_t lane_rxd:32;
5210 + } s;
5211 + struct cvmx_gmxx_rx_xaui_bad_col_s cn52xx;
5212 + struct cvmx_gmxx_rx_xaui_bad_col_s cn52xxp1;
5213 + struct cvmx_gmxx_rx_xaui_bad_col_s cn56xx;
5214 + struct cvmx_gmxx_rx_xaui_bad_col_s cn56xxp1;
5215 +};
5216 +
5217 +union cvmx_gmxx_rx_xaui_ctl {
5218 + uint64_t u64;
5219 + struct cvmx_gmxx_rx_xaui_ctl_s {
5220 + uint64_t reserved_2_63:62;
5221 + uint64_t status:2;
5222 + } s;
5223 + struct cvmx_gmxx_rx_xaui_ctl_s cn52xx;
5224 + struct cvmx_gmxx_rx_xaui_ctl_s cn52xxp1;
5225 + struct cvmx_gmxx_rx_xaui_ctl_s cn56xx;
5226 + struct cvmx_gmxx_rx_xaui_ctl_s cn56xxp1;
5227 +};
5228 +
5229 +union cvmx_gmxx_smacx {
5230 + uint64_t u64;
5231 + struct cvmx_gmxx_smacx_s {
5232 + uint64_t reserved_48_63:16;
5233 + uint64_t smac:48;
5234 + } s;
5235 + struct cvmx_gmxx_smacx_s cn30xx;
5236 + struct cvmx_gmxx_smacx_s cn31xx;
5237 + struct cvmx_gmxx_smacx_s cn38xx;
5238 + struct cvmx_gmxx_smacx_s cn38xxp2;
5239 + struct cvmx_gmxx_smacx_s cn50xx;
5240 + struct cvmx_gmxx_smacx_s cn52xx;
5241 + struct cvmx_gmxx_smacx_s cn52xxp1;
5242 + struct cvmx_gmxx_smacx_s cn56xx;
5243 + struct cvmx_gmxx_smacx_s cn56xxp1;
5244 + struct cvmx_gmxx_smacx_s cn58xx;
5245 + struct cvmx_gmxx_smacx_s cn58xxp1;
5246 +};
5247 +
5248 +union cvmx_gmxx_stat_bp {
5249 + uint64_t u64;
5250 + struct cvmx_gmxx_stat_bp_s {
5251 + uint64_t reserved_17_63:47;
5252 + uint64_t bp:1;
5253 + uint64_t cnt:16;
5254 + } s;
5255 + struct cvmx_gmxx_stat_bp_s cn30xx;
5256 + struct cvmx_gmxx_stat_bp_s cn31xx;
5257 + struct cvmx_gmxx_stat_bp_s cn38xx;
5258 + struct cvmx_gmxx_stat_bp_s cn38xxp2;
5259 + struct cvmx_gmxx_stat_bp_s cn50xx;
5260 + struct cvmx_gmxx_stat_bp_s cn52xx;
5261 + struct cvmx_gmxx_stat_bp_s cn52xxp1;
5262 + struct cvmx_gmxx_stat_bp_s cn56xx;
5263 + struct cvmx_gmxx_stat_bp_s cn56xxp1;
5264 + struct cvmx_gmxx_stat_bp_s cn58xx;
5265 + struct cvmx_gmxx_stat_bp_s cn58xxp1;
5266 +};
5267 +
5268 +union cvmx_gmxx_txx_append {
5269 + uint64_t u64;
5270 + struct cvmx_gmxx_txx_append_s {
5271 + uint64_t reserved_4_63:60;
5272 + uint64_t force_fcs:1;
5273 + uint64_t fcs:1;
5274 + uint64_t pad:1;
5275 + uint64_t preamble:1;
5276 + } s;
5277 + struct cvmx_gmxx_txx_append_s cn30xx;
5278 + struct cvmx_gmxx_txx_append_s cn31xx;
5279 + struct cvmx_gmxx_txx_append_s cn38xx;
5280 + struct cvmx_gmxx_txx_append_s cn38xxp2;
5281 + struct cvmx_gmxx_txx_append_s cn50xx;
5282 + struct cvmx_gmxx_txx_append_s cn52xx;
5283 + struct cvmx_gmxx_txx_append_s cn52xxp1;
5284 + struct cvmx_gmxx_txx_append_s cn56xx;
5285 + struct cvmx_gmxx_txx_append_s cn56xxp1;
5286 + struct cvmx_gmxx_txx_append_s cn58xx;
5287 + struct cvmx_gmxx_txx_append_s cn58xxp1;
5288 +};
5289 +
5290 +union cvmx_gmxx_txx_burst {
5291 + uint64_t u64;
5292 + struct cvmx_gmxx_txx_burst_s {
5293 + uint64_t reserved_16_63:48;
5294 + uint64_t burst:16;
5295 + } s;
5296 + struct cvmx_gmxx_txx_burst_s cn30xx;
5297 + struct cvmx_gmxx_txx_burst_s cn31xx;
5298 + struct cvmx_gmxx_txx_burst_s cn38xx;
5299 + struct cvmx_gmxx_txx_burst_s cn38xxp2;
5300 + struct cvmx_gmxx_txx_burst_s cn50xx;
5301 + struct cvmx_gmxx_txx_burst_s cn52xx;
5302 + struct cvmx_gmxx_txx_burst_s cn52xxp1;
5303 + struct cvmx_gmxx_txx_burst_s cn56xx;
5304 + struct cvmx_gmxx_txx_burst_s cn56xxp1;
5305 + struct cvmx_gmxx_txx_burst_s cn58xx;
5306 + struct cvmx_gmxx_txx_burst_s cn58xxp1;
5307 +};
5308 +
5309 +union cvmx_gmxx_txx_cbfc_xoff {
5310 + uint64_t u64;
5311 + struct cvmx_gmxx_txx_cbfc_xoff_s {
5312 + uint64_t reserved_16_63:48;
5313 + uint64_t xoff:16;
5314 + } s;
5315 + struct cvmx_gmxx_txx_cbfc_xoff_s cn52xx;
5316 + struct cvmx_gmxx_txx_cbfc_xoff_s cn56xx;
5317 +};
5318 +
5319 +union cvmx_gmxx_txx_cbfc_xon {
5320 + uint64_t u64;
5321 + struct cvmx_gmxx_txx_cbfc_xon_s {
5322 + uint64_t reserved_16_63:48;
5323 + uint64_t xon:16;
5324 + } s;
5325 + struct cvmx_gmxx_txx_cbfc_xon_s cn52xx;
5326 + struct cvmx_gmxx_txx_cbfc_xon_s cn56xx;
5327 +};
5328 +
5329 +union cvmx_gmxx_txx_clk {
5330 + uint64_t u64;
5331 + struct cvmx_gmxx_txx_clk_s {
5332 + uint64_t reserved_6_63:58;
5333 + uint64_t clk_cnt:6;
5334 + } s;
5335 + struct cvmx_gmxx_txx_clk_s cn30xx;
5336 + struct cvmx_gmxx_txx_clk_s cn31xx;
5337 + struct cvmx_gmxx_txx_clk_s cn38xx;
5338 + struct cvmx_gmxx_txx_clk_s cn38xxp2;
5339 + struct cvmx_gmxx_txx_clk_s cn50xx;
5340 + struct cvmx_gmxx_txx_clk_s cn58xx;
5341 + struct cvmx_gmxx_txx_clk_s cn58xxp1;
5342 +};
5343 +
5344 +union cvmx_gmxx_txx_ctl {
5345 + uint64_t u64;
5346 + struct cvmx_gmxx_txx_ctl_s {
5347 + uint64_t reserved_2_63:62;
5348 + uint64_t xsdef_en:1;
5349 + uint64_t xscol_en:1;
5350 + } s;
5351 + struct cvmx_gmxx_txx_ctl_s cn30xx;
5352 + struct cvmx_gmxx_txx_ctl_s cn31xx;
5353 + struct cvmx_gmxx_txx_ctl_s cn38xx;
5354 + struct cvmx_gmxx_txx_ctl_s cn38xxp2;
5355 + struct cvmx_gmxx_txx_ctl_s cn50xx;
5356 + struct cvmx_gmxx_txx_ctl_s cn52xx;
5357 + struct cvmx_gmxx_txx_ctl_s cn52xxp1;
5358 + struct cvmx_gmxx_txx_ctl_s cn56xx;
5359 + struct cvmx_gmxx_txx_ctl_s cn56xxp1;
5360 + struct cvmx_gmxx_txx_ctl_s cn58xx;
5361 + struct cvmx_gmxx_txx_ctl_s cn58xxp1;
5362 +};
5363 +
5364 +union cvmx_gmxx_txx_min_pkt {
5365 + uint64_t u64;
5366 + struct cvmx_gmxx_txx_min_pkt_s {
5367 + uint64_t reserved_8_63:56;
5368 + uint64_t min_size:8;
5369 + } s;
5370 + struct cvmx_gmxx_txx_min_pkt_s cn30xx;
5371 + struct cvmx_gmxx_txx_min_pkt_s cn31xx;
5372 + struct cvmx_gmxx_txx_min_pkt_s cn38xx;
5373 + struct cvmx_gmxx_txx_min_pkt_s cn38xxp2;
5374 + struct cvmx_gmxx_txx_min_pkt_s cn50xx;
5375 + struct cvmx_gmxx_txx_min_pkt_s cn52xx;
5376 + struct cvmx_gmxx_txx_min_pkt_s cn52xxp1;
5377 + struct cvmx_gmxx_txx_min_pkt_s cn56xx;
5378 + struct cvmx_gmxx_txx_min_pkt_s cn56xxp1;
5379 + struct cvmx_gmxx_txx_min_pkt_s cn58xx;
5380 + struct cvmx_gmxx_txx_min_pkt_s cn58xxp1;
5381 +};
5382 +
5383 +union cvmx_gmxx_txx_pause_pkt_interval {
5384 + uint64_t u64;
5385 + struct cvmx_gmxx_txx_pause_pkt_interval_s {
5386 + uint64_t reserved_16_63:48;
5387 + uint64_t interval:16;
5388 + } s;
5389 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn30xx;
5390 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn31xx;
5391 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xx;
5392 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xxp2;
5393 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn50xx;
5394 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xx;
5395 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xxp1;
5396 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xx;
5397 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xxp1;
5398 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xx;
5399 + struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xxp1;
5400 +};
5401 +
5402 +union cvmx_gmxx_txx_pause_pkt_time {
5403 + uint64_t u64;
5404 + struct cvmx_gmxx_txx_pause_pkt_time_s {
5405 + uint64_t reserved_16_63:48;
5406 + uint64_t time:16;
5407 + } s;
5408 + struct cvmx_gmxx_txx_pause_pkt_time_s cn30xx;
5409 + struct cvmx_gmxx_txx_pause_pkt_time_s cn31xx;
5410 + struct cvmx_gmxx_txx_pause_pkt_time_s cn38xx;
5411 + struct cvmx_gmxx_txx_pause_pkt_time_s cn38xxp2;
5412 + struct cvmx_gmxx_txx_pause_pkt_time_s cn50xx;
5413 + struct cvmx_gmxx_txx_pause_pkt_time_s cn52xx;
5414 + struct cvmx_gmxx_txx_pause_pkt_time_s cn52xxp1;
5415 + struct cvmx_gmxx_txx_pause_pkt_time_s cn56xx;
5416 + struct cvmx_gmxx_txx_pause_pkt_time_s cn56xxp1;
5417 + struct cvmx_gmxx_txx_pause_pkt_time_s cn58xx;
5418 + struct cvmx_gmxx_txx_pause_pkt_time_s cn58xxp1;
5419 +};
5420 +
5421 +union cvmx_gmxx_txx_pause_togo {
5422 + uint64_t u64;
5423 + struct cvmx_gmxx_txx_pause_togo_s {
5424 + uint64_t reserved_32_63:32;
5425 + uint64_t msg_time:16;
5426 + uint64_t time:16;
5427 + } s;
5428 + struct cvmx_gmxx_txx_pause_togo_cn30xx {
5429 + uint64_t reserved_16_63:48;
5430 + uint64_t time:16;
5431 + } cn30xx;
5432 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn31xx;
5433 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xx;
5434 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xxp2;
5435 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn50xx;
5436 + struct cvmx_gmxx_txx_pause_togo_s cn52xx;
5437 + struct cvmx_gmxx_txx_pause_togo_s cn52xxp1;
5438 + struct cvmx_gmxx_txx_pause_togo_s cn56xx;
5439 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn56xxp1;
5440 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xx;
5441 + struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xxp1;
5442 +};
5443 +
5444 +union cvmx_gmxx_txx_pause_zero {
5445 + uint64_t u64;
5446 + struct cvmx_gmxx_txx_pause_zero_s {
5447 + uint64_t reserved_1_63:63;
5448 + uint64_t send:1;
5449 + } s;
5450 + struct cvmx_gmxx_txx_pause_zero_s cn30xx;
5451 + struct cvmx_gmxx_txx_pause_zero_s cn31xx;
5452 + struct cvmx_gmxx_txx_pause_zero_s cn38xx;
5453 + struct cvmx_gmxx_txx_pause_zero_s cn38xxp2;
5454 + struct cvmx_gmxx_txx_pause_zero_s cn50xx;
5455 + struct cvmx_gmxx_txx_pause_zero_s cn52xx;
5456 + struct cvmx_gmxx_txx_pause_zero_s cn52xxp1;
5457 + struct cvmx_gmxx_txx_pause_zero_s cn56xx;
5458 + struct cvmx_gmxx_txx_pause_zero_s cn56xxp1;
5459 + struct cvmx_gmxx_txx_pause_zero_s cn58xx;
5460 + struct cvmx_gmxx_txx_pause_zero_s cn58xxp1;
5461 +};
5462 +
5463 +union cvmx_gmxx_txx_sgmii_ctl {
5464 + uint64_t u64;
5465 + struct cvmx_gmxx_txx_sgmii_ctl_s {
5466 + uint64_t reserved_1_63:63;
5467 + uint64_t align:1;
5468 + } s;
5469 + struct cvmx_gmxx_txx_sgmii_ctl_s cn52xx;
5470 + struct cvmx_gmxx_txx_sgmii_ctl_s cn52xxp1;
5471 + struct cvmx_gmxx_txx_sgmii_ctl_s cn56xx;
5472 + struct cvmx_gmxx_txx_sgmii_ctl_s cn56xxp1;
5473 +};
5474 +
5475 +union cvmx_gmxx_txx_slot {
5476 + uint64_t u64;
5477 + struct cvmx_gmxx_txx_slot_s {
5478 + uint64_t reserved_10_63:54;
5479 + uint64_t slot:10;
5480 + } s;
5481 + struct cvmx_gmxx_txx_slot_s cn30xx;
5482 + struct cvmx_gmxx_txx_slot_s cn31xx;
5483 + struct cvmx_gmxx_txx_slot_s cn38xx;
5484 + struct cvmx_gmxx_txx_slot_s cn38xxp2;
5485 + struct cvmx_gmxx_txx_slot_s cn50xx;
5486 + struct cvmx_gmxx_txx_slot_s cn52xx;
5487 + struct cvmx_gmxx_txx_slot_s cn52xxp1;
5488 + struct cvmx_gmxx_txx_slot_s cn56xx;
5489 + struct cvmx_gmxx_txx_slot_s cn56xxp1;
5490 + struct cvmx_gmxx_txx_slot_s cn58xx;
5491 + struct cvmx_gmxx_txx_slot_s cn58xxp1;
5492 +};
5493 +
5494 +union cvmx_gmxx_txx_soft_pause {
5495 + uint64_t u64;
5496 + struct cvmx_gmxx_txx_soft_pause_s {
5497 + uint64_t reserved_16_63:48;
5498 + uint64_t time:16;
5499 + } s;
5500 + struct cvmx_gmxx_txx_soft_pause_s cn30xx;
5501 + struct cvmx_gmxx_txx_soft_pause_s cn31xx;
5502 + struct cvmx_gmxx_txx_soft_pause_s cn38xx;
5503 + struct cvmx_gmxx_txx_soft_pause_s cn38xxp2;
5504 + struct cvmx_gmxx_txx_soft_pause_s cn50xx;
5505 + struct cvmx_gmxx_txx_soft_pause_s cn52xx;
5506 + struct cvmx_gmxx_txx_soft_pause_s cn52xxp1;
5507 + struct cvmx_gmxx_txx_soft_pause_s cn56xx;
5508 + struct cvmx_gmxx_txx_soft_pause_s cn56xxp1;
5509 + struct cvmx_gmxx_txx_soft_pause_s cn58xx;
5510 + struct cvmx_gmxx_txx_soft_pause_s cn58xxp1;
5511 +};
5512 +
5513 +union cvmx_gmxx_txx_stat0 {
5514 + uint64_t u64;
5515 + struct cvmx_gmxx_txx_stat0_s {
5516 + uint64_t xsdef:32;
5517 + uint64_t xscol:32;
5518 + } s;
5519 + struct cvmx_gmxx_txx_stat0_s cn30xx;
5520 + struct cvmx_gmxx_txx_stat0_s cn31xx;
5521 + struct cvmx_gmxx_txx_stat0_s cn38xx;
5522 + struct cvmx_gmxx_txx_stat0_s cn38xxp2;
5523 + struct cvmx_gmxx_txx_stat0_s cn50xx;
5524 + struct cvmx_gmxx_txx_stat0_s cn52xx;
5525 + struct cvmx_gmxx_txx_stat0_s cn52xxp1;
5526 + struct cvmx_gmxx_txx_stat0_s cn56xx;
5527 + struct cvmx_gmxx_txx_stat0_s cn56xxp1;
5528 + struct cvmx_gmxx_txx_stat0_s cn58xx;
5529 + struct cvmx_gmxx_txx_stat0_s cn58xxp1;
5530 +};
5531 +
5532 +union cvmx_gmxx_txx_stat1 {
5533 + uint64_t u64;
5534 + struct cvmx_gmxx_txx_stat1_s {
5535 + uint64_t scol:32;
5536 + uint64_t mcol:32;
5537 + } s;
5538 + struct cvmx_gmxx_txx_stat1_s cn30xx;
5539 + struct cvmx_gmxx_txx_stat1_s cn31xx;
5540 + struct cvmx_gmxx_txx_stat1_s cn38xx;
5541 + struct cvmx_gmxx_txx_stat1_s cn38xxp2;
5542 + struct cvmx_gmxx_txx_stat1_s cn50xx;
5543 + struct cvmx_gmxx_txx_stat1_s cn52xx;
5544 + struct cvmx_gmxx_txx_stat1_s cn52xxp1;
5545 + struct cvmx_gmxx_txx_stat1_s cn56xx;
5546 + struct cvmx_gmxx_txx_stat1_s cn56xxp1;
5547 + struct cvmx_gmxx_txx_stat1_s cn58xx;
5548 + struct cvmx_gmxx_txx_stat1_s cn58xxp1;
5549 +};
5550 +
5551 +union cvmx_gmxx_txx_stat2 {
5552 + uint64_t u64;
5553 + struct cvmx_gmxx_txx_stat2_s {
5554 + uint64_t reserved_48_63:16;
5555 + uint64_t octs:48;
5556 + } s;
5557 + struct cvmx_gmxx_txx_stat2_s cn30xx;
5558 + struct cvmx_gmxx_txx_stat2_s cn31xx;
5559 + struct cvmx_gmxx_txx_stat2_s cn38xx;
5560 + struct cvmx_gmxx_txx_stat2_s cn38xxp2;
5561 + struct cvmx_gmxx_txx_stat2_s cn50xx;
5562 + struct cvmx_gmxx_txx_stat2_s cn52xx;
5563 + struct cvmx_gmxx_txx_stat2_s cn52xxp1;
5564 + struct cvmx_gmxx_txx_stat2_s cn56xx;
5565 + struct cvmx_gmxx_txx_stat2_s cn56xxp1;
5566 + struct cvmx_gmxx_txx_stat2_s cn58xx;
5567 + struct cvmx_gmxx_txx_stat2_s cn58xxp1;
5568 +};
5569 +
5570 +union cvmx_gmxx_txx_stat3 {
5571 + uint64_t u64;
5572 + struct cvmx_gmxx_txx_stat3_s {
5573 + uint64_t reserved_32_63:32;
5574 + uint64_t pkts:32;
5575 + } s;
5576 + struct cvmx_gmxx_txx_stat3_s cn30xx;
5577 + struct cvmx_gmxx_txx_stat3_s cn31xx;
5578 + struct cvmx_gmxx_txx_stat3_s cn38xx;
5579 + struct cvmx_gmxx_txx_stat3_s cn38xxp2;
5580 + struct cvmx_gmxx_txx_stat3_s cn50xx;
5581 + struct cvmx_gmxx_txx_stat3_s cn52xx;
5582 + struct cvmx_gmxx_txx_stat3_s cn52xxp1;
5583 + struct cvmx_gmxx_txx_stat3_s cn56xx;
5584 + struct cvmx_gmxx_txx_stat3_s cn56xxp1;
5585 + struct cvmx_gmxx_txx_stat3_s cn58xx;
5586 + struct cvmx_gmxx_txx_stat3_s cn58xxp1;
5587 +};
5588 +
5589 +union cvmx_gmxx_txx_stat4 {
5590 + uint64_t u64;
5591 + struct cvmx_gmxx_txx_stat4_s {
5592 + uint64_t hist1:32;
5593 + uint64_t hist0:32;
5594 + } s;
5595 + struct cvmx_gmxx_txx_stat4_s cn30xx;
5596 + struct cvmx_gmxx_txx_stat4_s cn31xx;
5597 + struct cvmx_gmxx_txx_stat4_s cn38xx;
5598 + struct cvmx_gmxx_txx_stat4_s cn38xxp2;
5599 + struct cvmx_gmxx_txx_stat4_s cn50xx;
5600 + struct cvmx_gmxx_txx_stat4_s cn52xx;
5601 + struct cvmx_gmxx_txx_stat4_s cn52xxp1;
5602 + struct cvmx_gmxx_txx_stat4_s cn56xx;
5603 + struct cvmx_gmxx_txx_stat4_s cn56xxp1;
5604 + struct cvmx_gmxx_txx_stat4_s cn58xx;
5605 + struct cvmx_gmxx_txx_stat4_s cn58xxp1;
5606 +};
5607 +
5608 +union cvmx_gmxx_txx_stat5 {
5609 + uint64_t u64;
5610 + struct cvmx_gmxx_txx_stat5_s {
5611 + uint64_t hist3:32;
5612 + uint64_t hist2:32;
5613 + } s;
5614 + struct cvmx_gmxx_txx_stat5_s cn30xx;
5615 + struct cvmx_gmxx_txx_stat5_s cn31xx;
5616 + struct cvmx_gmxx_txx_stat5_s cn38xx;
5617 + struct cvmx_gmxx_txx_stat5_s cn38xxp2;
5618 + struct cvmx_gmxx_txx_stat5_s cn50xx;
5619 + struct cvmx_gmxx_txx_stat5_s cn52xx;
5620 + struct cvmx_gmxx_txx_stat5_s cn52xxp1;
5621 + struct cvmx_gmxx_txx_stat5_s cn56xx;
5622 + struct cvmx_gmxx_txx_stat5_s cn56xxp1;
5623 + struct cvmx_gmxx_txx_stat5_s cn58xx;
5624 + struct cvmx_gmxx_txx_stat5_s cn58xxp1;
5625 +};
5626 +
5627 +union cvmx_gmxx_txx_stat6 {
5628 + uint64_t u64;
5629 + struct cvmx_gmxx_txx_stat6_s {
5630 + uint64_t hist5:32;
5631 + uint64_t hist4:32;
5632 + } s;
5633 + struct cvmx_gmxx_txx_stat6_s cn30xx;
5634 + struct cvmx_gmxx_txx_stat6_s cn31xx;
5635 + struct cvmx_gmxx_txx_stat6_s cn38xx;
5636 + struct cvmx_gmxx_txx_stat6_s cn38xxp2;
5637 + struct cvmx_gmxx_txx_stat6_s cn50xx;
5638 + struct cvmx_gmxx_txx_stat6_s cn52xx;
5639 + struct cvmx_gmxx_txx_stat6_s cn52xxp1;
5640 + struct cvmx_gmxx_txx_stat6_s cn56xx;
5641 + struct cvmx_gmxx_txx_stat6_s cn56xxp1;
5642 + struct cvmx_gmxx_txx_stat6_s cn58xx;
5643 + struct cvmx_gmxx_txx_stat6_s cn58xxp1;
5644 +};
5645 +
5646 +union cvmx_gmxx_txx_stat7 {
5647 + uint64_t u64;
5648 + struct cvmx_gmxx_txx_stat7_s {
5649 + uint64_t hist7:32;
5650 + uint64_t hist6:32;
5651 + } s;
5652 + struct cvmx_gmxx_txx_stat7_s cn30xx;
5653 + struct cvmx_gmxx_txx_stat7_s cn31xx;
5654 + struct cvmx_gmxx_txx_stat7_s cn38xx;
5655 + struct cvmx_gmxx_txx_stat7_s cn38xxp2;
5656 + struct cvmx_gmxx_txx_stat7_s cn50xx;
5657 + struct cvmx_gmxx_txx_stat7_s cn52xx;
5658 + struct cvmx_gmxx_txx_stat7_s cn52xxp1;
5659 + struct cvmx_gmxx_txx_stat7_s cn56xx;
5660 + struct cvmx_gmxx_txx_stat7_s cn56xxp1;
5661 + struct cvmx_gmxx_txx_stat7_s cn58xx;
5662 + struct cvmx_gmxx_txx_stat7_s cn58xxp1;
5663 +};
5664 +
5665 +union cvmx_gmxx_txx_stat8 {
5666 + uint64_t u64;
5667 + struct cvmx_gmxx_txx_stat8_s {
5668 + uint64_t mcst:32;
5669 + uint64_t bcst:32;
5670 + } s;
5671 + struct cvmx_gmxx_txx_stat8_s cn30xx;
5672 + struct cvmx_gmxx_txx_stat8_s cn31xx;
5673 + struct cvmx_gmxx_txx_stat8_s cn38xx;
5674 + struct cvmx_gmxx_txx_stat8_s cn38xxp2;
5675 + struct cvmx_gmxx_txx_stat8_s cn50xx;
5676 + struct cvmx_gmxx_txx_stat8_s cn52xx;
5677 + struct cvmx_gmxx_txx_stat8_s cn52xxp1;
5678 + struct cvmx_gmxx_txx_stat8_s cn56xx;
5679 + struct cvmx_gmxx_txx_stat8_s cn56xxp1;
5680 + struct cvmx_gmxx_txx_stat8_s cn58xx;
5681 + struct cvmx_gmxx_txx_stat8_s cn58xxp1;
5682 +};
5683 +
5684 +union cvmx_gmxx_txx_stat9 {
5685 + uint64_t u64;
5686 + struct cvmx_gmxx_txx_stat9_s {
5687 + uint64_t undflw:32;
5688 + uint64_t ctl:32;
5689 + } s;
5690 + struct cvmx_gmxx_txx_stat9_s cn30xx;
5691 + struct cvmx_gmxx_txx_stat9_s cn31xx;
5692 + struct cvmx_gmxx_txx_stat9_s cn38xx;
5693 + struct cvmx_gmxx_txx_stat9_s cn38xxp2;
5694 + struct cvmx_gmxx_txx_stat9_s cn50xx;
5695 + struct cvmx_gmxx_txx_stat9_s cn52xx;
5696 + struct cvmx_gmxx_txx_stat9_s cn52xxp1;
5697 + struct cvmx_gmxx_txx_stat9_s cn56xx;
5698 + struct cvmx_gmxx_txx_stat9_s cn56xxp1;
5699 + struct cvmx_gmxx_txx_stat9_s cn58xx;
5700 + struct cvmx_gmxx_txx_stat9_s cn58xxp1;
5701 +};
5702 +
5703 +union cvmx_gmxx_txx_stats_ctl {
5704 + uint64_t u64;
5705 + struct cvmx_gmxx_txx_stats_ctl_s {
5706 + uint64_t reserved_1_63:63;
5707 + uint64_t rd_clr:1;
5708 + } s;
5709 + struct cvmx_gmxx_txx_stats_ctl_s cn30xx;
5710 + struct cvmx_gmxx_txx_stats_ctl_s cn31xx;
5711 + struct cvmx_gmxx_txx_stats_ctl_s cn38xx;
5712 + struct cvmx_gmxx_txx_stats_ctl_s cn38xxp2;
5713 + struct cvmx_gmxx_txx_stats_ctl_s cn50xx;
5714 + struct cvmx_gmxx_txx_stats_ctl_s cn52xx;
5715 + struct cvmx_gmxx_txx_stats_ctl_s cn52xxp1;
5716 + struct cvmx_gmxx_txx_stats_ctl_s cn56xx;
5717 + struct cvmx_gmxx_txx_stats_ctl_s cn56xxp1;
5718 + struct cvmx_gmxx_txx_stats_ctl_s cn58xx;
5719 + struct cvmx_gmxx_txx_stats_ctl_s cn58xxp1;
5720 +};
5721 +
5722 +union cvmx_gmxx_txx_thresh {
5723 + uint64_t u64;
5724 + struct cvmx_gmxx_txx_thresh_s {
5725 + uint64_t reserved_9_63:55;
5726 + uint64_t cnt:9;
5727 + } s;
5728 + struct cvmx_gmxx_txx_thresh_cn30xx {
5729 + uint64_t reserved_7_63:57;
5730 + uint64_t cnt:7;
5731 + } cn30xx;
5732 + struct cvmx_gmxx_txx_thresh_cn30xx cn31xx;
5733 + struct cvmx_gmxx_txx_thresh_s cn38xx;
5734 + struct cvmx_gmxx_txx_thresh_s cn38xxp2;
5735 + struct cvmx_gmxx_txx_thresh_cn30xx cn50xx;
5736 + struct cvmx_gmxx_txx_thresh_s cn52xx;
5737 + struct cvmx_gmxx_txx_thresh_s cn52xxp1;
5738 + struct cvmx_gmxx_txx_thresh_s cn56xx;
5739 + struct cvmx_gmxx_txx_thresh_s cn56xxp1;
5740 + struct cvmx_gmxx_txx_thresh_s cn58xx;
5741 + struct cvmx_gmxx_txx_thresh_s cn58xxp1;
5742 +};
5743 +
5744 +union cvmx_gmxx_tx_bp {
5745 + uint64_t u64;
5746 + struct cvmx_gmxx_tx_bp_s {
5747 + uint64_t reserved_4_63:60;
5748 + uint64_t bp:4;
5749 + } s;
5750 + struct cvmx_gmxx_tx_bp_cn30xx {
5751 + uint64_t reserved_3_63:61;
5752 + uint64_t bp:3;
5753 + } cn30xx;
5754 + struct cvmx_gmxx_tx_bp_cn30xx cn31xx;
5755 + struct cvmx_gmxx_tx_bp_s cn38xx;
5756 + struct cvmx_gmxx_tx_bp_s cn38xxp2;
5757 + struct cvmx_gmxx_tx_bp_cn30xx cn50xx;
5758 + struct cvmx_gmxx_tx_bp_s cn52xx;
5759 + struct cvmx_gmxx_tx_bp_s cn52xxp1;
5760 + struct cvmx_gmxx_tx_bp_s cn56xx;
5761 + struct cvmx_gmxx_tx_bp_s cn56xxp1;
5762 + struct cvmx_gmxx_tx_bp_s cn58xx;
5763 + struct cvmx_gmxx_tx_bp_s cn58xxp1;
5764 +};
5765 +
5766 +union cvmx_gmxx_tx_clk_mskx {
5767 + uint64_t u64;
5768 + struct cvmx_gmxx_tx_clk_mskx_s {
5769 + uint64_t reserved_1_63:63;
5770 + uint64_t msk:1;
5771 + } s;
5772 + struct cvmx_gmxx_tx_clk_mskx_s cn30xx;
5773 + struct cvmx_gmxx_tx_clk_mskx_s cn50xx;
5774 +};
5775 +
5776 +union cvmx_gmxx_tx_col_attempt {
5777 + uint64_t u64;
5778 + struct cvmx_gmxx_tx_col_attempt_s {
5779 + uint64_t reserved_5_63:59;
5780 + uint64_t limit:5;
5781 + } s;
5782 + struct cvmx_gmxx_tx_col_attempt_s cn30xx;
5783 + struct cvmx_gmxx_tx_col_attempt_s cn31xx;
5784 + struct cvmx_gmxx_tx_col_attempt_s cn38xx;
5785 + struct cvmx_gmxx_tx_col_attempt_s cn38xxp2;
5786 + struct cvmx_gmxx_tx_col_attempt_s cn50xx;
5787 + struct cvmx_gmxx_tx_col_attempt_s cn52xx;
5788 + struct cvmx_gmxx_tx_col_attempt_s cn52xxp1;
5789 + struct cvmx_gmxx_tx_col_attempt_s cn56xx;
5790 + struct cvmx_gmxx_tx_col_attempt_s cn56xxp1;
5791 + struct cvmx_gmxx_tx_col_attempt_s cn58xx;
5792 + struct cvmx_gmxx_tx_col_attempt_s cn58xxp1;
5793 +};
5794 +
5795 +union cvmx_gmxx_tx_corrupt {
5796 + uint64_t u64;
5797 + struct cvmx_gmxx_tx_corrupt_s {
5798 + uint64_t reserved_4_63:60;
5799 + uint64_t corrupt:4;
5800 + } s;
5801 + struct cvmx_gmxx_tx_corrupt_cn30xx {
5802 + uint64_t reserved_3_63:61;
5803 + uint64_t corrupt:3;
5804 + } cn30xx;
5805 + struct cvmx_gmxx_tx_corrupt_cn30xx cn31xx;
5806 + struct cvmx_gmxx_tx_corrupt_s cn38xx;
5807 + struct cvmx_gmxx_tx_corrupt_s cn38xxp2;
5808 + struct cvmx_gmxx_tx_corrupt_cn30xx cn50xx;
5809 + struct cvmx_gmxx_tx_corrupt_s cn52xx;
5810 + struct cvmx_gmxx_tx_corrupt_s cn52xxp1;
5811 + struct cvmx_gmxx_tx_corrupt_s cn56xx;
5812 + struct cvmx_gmxx_tx_corrupt_s cn56xxp1;
5813 + struct cvmx_gmxx_tx_corrupt_s cn58xx;
5814 + struct cvmx_gmxx_tx_corrupt_s cn58xxp1;
5815 +};
5816 +
5817 +union cvmx_gmxx_tx_hg2_reg1 {
5818 + uint64_t u64;
5819 + struct cvmx_gmxx_tx_hg2_reg1_s {
5820 + uint64_t reserved_16_63:48;
5821 + uint64_t tx_xof:16;
5822 + } s;
5823 + struct cvmx_gmxx_tx_hg2_reg1_s cn52xx;
5824 + struct cvmx_gmxx_tx_hg2_reg1_s cn52xxp1;
5825 + struct cvmx_gmxx_tx_hg2_reg1_s cn56xx;
5826 +};
5827 +
5828 +union cvmx_gmxx_tx_hg2_reg2 {
5829 + uint64_t u64;
5830 + struct cvmx_gmxx_tx_hg2_reg2_s {
5831 + uint64_t reserved_16_63:48;
5832 + uint64_t tx_xon:16;
5833 + } s;
5834 + struct cvmx_gmxx_tx_hg2_reg2_s cn52xx;
5835 + struct cvmx_gmxx_tx_hg2_reg2_s cn52xxp1;
5836 + struct cvmx_gmxx_tx_hg2_reg2_s cn56xx;
5837 +};
5838 +
5839 +union cvmx_gmxx_tx_ifg {
5840 + uint64_t u64;
5841 + struct cvmx_gmxx_tx_ifg_s {
5842 + uint64_t reserved_8_63:56;
5843 + uint64_t ifg2:4;
5844 + uint64_t ifg1:4;
5845 + } s;
5846 + struct cvmx_gmxx_tx_ifg_s cn30xx;
5847 + struct cvmx_gmxx_tx_ifg_s cn31xx;
5848 + struct cvmx_gmxx_tx_ifg_s cn38xx;
5849 + struct cvmx_gmxx_tx_ifg_s cn38xxp2;
5850 + struct cvmx_gmxx_tx_ifg_s cn50xx;
5851 + struct cvmx_gmxx_tx_ifg_s cn52xx;
5852 + struct cvmx_gmxx_tx_ifg_s cn52xxp1;
5853 + struct cvmx_gmxx_tx_ifg_s cn56xx;
5854 + struct cvmx_gmxx_tx_ifg_s cn56xxp1;
5855 + struct cvmx_gmxx_tx_ifg_s cn58xx;
5856 + struct cvmx_gmxx_tx_ifg_s cn58xxp1;
5857 +};
5858 +
5859 +union cvmx_gmxx_tx_int_en {
5860 + uint64_t u64;
5861 + struct cvmx_gmxx_tx_int_en_s {
5862 + uint64_t reserved_20_63:44;
5863 + uint64_t late_col:4;
5864 + uint64_t xsdef:4;
5865 + uint64_t xscol:4;
5866 + uint64_t reserved_6_7:2;
5867 + uint64_t undflw:4;
5868 + uint64_t ncb_nxa:1;
5869 + uint64_t pko_nxa:1;
5870 + } s;
5871 + struct cvmx_gmxx_tx_int_en_cn30xx {
5872 + uint64_t reserved_19_63:45;
5873 + uint64_t late_col:3;
5874 + uint64_t reserved_15_15:1;
5875 + uint64_t xsdef:3;
5876 + uint64_t reserved_11_11:1;
5877 + uint64_t xscol:3;
5878 + uint64_t reserved_5_7:3;
5879 + uint64_t undflw:3;
5880 + uint64_t reserved_1_1:1;
5881 + uint64_t pko_nxa:1;
5882 + } cn30xx;
5883 + struct cvmx_gmxx_tx_int_en_cn31xx {
5884 + uint64_t reserved_15_63:49;
5885 + uint64_t xsdef:3;
5886 + uint64_t reserved_11_11:1;
5887 + uint64_t xscol:3;
5888 + uint64_t reserved_5_7:3;
5889 + uint64_t undflw:3;
5890 + uint64_t reserved_1_1:1;
5891 + uint64_t pko_nxa:1;
5892 + } cn31xx;
5893 + struct cvmx_gmxx_tx_int_en_s cn38xx;
5894 + struct cvmx_gmxx_tx_int_en_cn38xxp2 {
5895 + uint64_t reserved_16_63:48;
5896 + uint64_t xsdef:4;
5897 + uint64_t xscol:4;
5898 + uint64_t reserved_6_7:2;
5899 + uint64_t undflw:4;
5900 + uint64_t ncb_nxa:1;
5901 + uint64_t pko_nxa:1;
5902 + } cn38xxp2;
5903 + struct cvmx_gmxx_tx_int_en_cn30xx cn50xx;
5904 + struct cvmx_gmxx_tx_int_en_cn52xx {
5905 + uint64_t reserved_20_63:44;
5906 + uint64_t late_col:4;
5907 + uint64_t xsdef:4;
5908 + uint64_t xscol:4;
5909 + uint64_t reserved_6_7:2;
5910 + uint64_t undflw:4;
5911 + uint64_t reserved_1_1:1;
5912 + uint64_t pko_nxa:1;
5913 + } cn52xx;
5914 + struct cvmx_gmxx_tx_int_en_cn52xx cn52xxp1;
5915 + struct cvmx_gmxx_tx_int_en_cn52xx cn56xx;
5916 + struct cvmx_gmxx_tx_int_en_cn52xx cn56xxp1;
5917 + struct cvmx_gmxx_tx_int_en_s cn58xx;
5918 + struct cvmx_gmxx_tx_int_en_s cn58xxp1;
5919 +};
5920 +
5921 +union cvmx_gmxx_tx_int_reg {
5922 + uint64_t u64;
5923 + struct cvmx_gmxx_tx_int_reg_s {
5924 + uint64_t reserved_20_63:44;
5925 + uint64_t late_col:4;
5926 + uint64_t xsdef:4;
5927 + uint64_t xscol:4;
5928 + uint64_t reserved_6_7:2;
5929 + uint64_t undflw:4;
5930 + uint64_t ncb_nxa:1;
5931 + uint64_t pko_nxa:1;
5932 + } s;
5933 + struct cvmx_gmxx_tx_int_reg_cn30xx {
5934 + uint64_t reserved_19_63:45;
5935 + uint64_t late_col:3;
5936 + uint64_t reserved_15_15:1;
5937 + uint64_t xsdef:3;
5938 + uint64_t reserved_11_11:1;
5939 + uint64_t xscol:3;
5940 + uint64_t reserved_5_7:3;
5941 + uint64_t undflw:3;
5942 + uint64_t reserved_1_1:1;
5943 + uint64_t pko_nxa:1;
5944 + } cn30xx;
5945 + struct cvmx_gmxx_tx_int_reg_cn31xx {
5946 + uint64_t reserved_15_63:49;
5947 + uint64_t xsdef:3;
5948 + uint64_t reserved_11_11:1;
5949 + uint64_t xscol:3;
5950 + uint64_t reserved_5_7:3;
5951 + uint64_t undflw:3;
5952 + uint64_t reserved_1_1:1;
5953 + uint64_t pko_nxa:1;
5954 + } cn31xx;
5955 + struct cvmx_gmxx_tx_int_reg_s cn38xx;
5956 + struct cvmx_gmxx_tx_int_reg_cn38xxp2 {
5957 + uint64_t reserved_16_63:48;
5958 + uint64_t xsdef:4;
5959 + uint64_t xscol:4;
5960 + uint64_t reserved_6_7:2;
5961 + uint64_t undflw:4;
5962 + uint64_t ncb_nxa:1;
5963 + uint64_t pko_nxa:1;
5964 + } cn38xxp2;
5965 + struct cvmx_gmxx_tx_int_reg_cn30xx cn50xx;
5966 + struct cvmx_gmxx_tx_int_reg_cn52xx {
5967 + uint64_t reserved_20_63:44;
5968 + uint64_t late_col:4;
5969 + uint64_t xsdef:4;
5970 + uint64_t xscol:4;
5971 + uint64_t reserved_6_7:2;
5972 + uint64_t undflw:4;
5973 + uint64_t reserved_1_1:1;
5974 + uint64_t pko_nxa:1;
5975 + } cn52xx;
5976 + struct cvmx_gmxx_tx_int_reg_cn52xx cn52xxp1;
5977 + struct cvmx_gmxx_tx_int_reg_cn52xx cn56xx;
5978 + struct cvmx_gmxx_tx_int_reg_cn52xx cn56xxp1;
5979 + struct cvmx_gmxx_tx_int_reg_s cn58xx;
5980 + struct cvmx_gmxx_tx_int_reg_s cn58xxp1;
5981 +};
5982 +
5983 +union cvmx_gmxx_tx_jam {
5984 + uint64_t u64;
5985 + struct cvmx_gmxx_tx_jam_s {
5986 + uint64_t reserved_8_63:56;
5987 + uint64_t jam:8;
5988 + } s;
5989 + struct cvmx_gmxx_tx_jam_s cn30xx;
5990 + struct cvmx_gmxx_tx_jam_s cn31xx;
5991 + struct cvmx_gmxx_tx_jam_s cn38xx;
5992 + struct cvmx_gmxx_tx_jam_s cn38xxp2;
5993 + struct cvmx_gmxx_tx_jam_s cn50xx;
5994 + struct cvmx_gmxx_tx_jam_s cn52xx;
5995 + struct cvmx_gmxx_tx_jam_s cn52xxp1;
5996 + struct cvmx_gmxx_tx_jam_s cn56xx;
5997 + struct cvmx_gmxx_tx_jam_s cn56xxp1;
5998 + struct cvmx_gmxx_tx_jam_s cn58xx;
5999 + struct cvmx_gmxx_tx_jam_s cn58xxp1;
6000 +};
6001 +
6002 +union cvmx_gmxx_tx_lfsr {
6003 + uint64_t u64;
6004 + struct cvmx_gmxx_tx_lfsr_s {
6005 + uint64_t reserved_16_63:48;
6006 + uint64_t lfsr:16;
6007 + } s;
6008 + struct cvmx_gmxx_tx_lfsr_s cn30xx;
6009 + struct cvmx_gmxx_tx_lfsr_s cn31xx;
6010 + struct cvmx_gmxx_tx_lfsr_s cn38xx;
6011 + struct cvmx_gmxx_tx_lfsr_s cn38xxp2;
6012 + struct cvmx_gmxx_tx_lfsr_s cn50xx;
6013 + struct cvmx_gmxx_tx_lfsr_s cn52xx;
6014 + struct cvmx_gmxx_tx_lfsr_s cn52xxp1;
6015 + struct cvmx_gmxx_tx_lfsr_s cn56xx;
6016 + struct cvmx_gmxx_tx_lfsr_s cn56xxp1;
6017 + struct cvmx_gmxx_tx_lfsr_s cn58xx;
6018 + struct cvmx_gmxx_tx_lfsr_s cn58xxp1;
6019 +};
6020 +
6021 +union cvmx_gmxx_tx_ovr_bp {
6022 + uint64_t u64;
6023 + struct cvmx_gmxx_tx_ovr_bp_s {
6024 + uint64_t reserved_48_63:16;
6025 + uint64_t tx_prt_bp:16;
6026 + uint64_t reserved_12_31:20;
6027 + uint64_t en:4;
6028 + uint64_t bp:4;
6029 + uint64_t ign_full:4;
6030 + } s;
6031 + struct cvmx_gmxx_tx_ovr_bp_cn30xx {
6032 + uint64_t reserved_11_63:53;
6033 + uint64_t en:3;
6034 + uint64_t reserved_7_7:1;
6035 + uint64_t bp:3;
6036 + uint64_t reserved_3_3:1;
6037 + uint64_t ign_full:3;
6038 + } cn30xx;
6039 + struct cvmx_gmxx_tx_ovr_bp_cn30xx cn31xx;
6040 + struct cvmx_gmxx_tx_ovr_bp_cn38xx {
6041 + uint64_t reserved_12_63:52;
6042 + uint64_t en:4;
6043 + uint64_t bp:4;
6044 + uint64_t ign_full:4;
6045 + } cn38xx;
6046 + struct cvmx_gmxx_tx_ovr_bp_cn38xx cn38xxp2;
6047 + struct cvmx_gmxx_tx_ovr_bp_cn30xx cn50xx;
6048 + struct cvmx_gmxx_tx_ovr_bp_s cn52xx;
6049 + struct cvmx_gmxx_tx_ovr_bp_s cn52xxp1;
6050 + struct cvmx_gmxx_tx_ovr_bp_s cn56xx;
6051 + struct cvmx_gmxx_tx_ovr_bp_s cn56xxp1;
6052 + struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xx;
6053 + struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xxp1;
6054 +};
6055 +
6056 +union cvmx_gmxx_tx_pause_pkt_dmac {
6057 + uint64_t u64;
6058 + struct cvmx_gmxx_tx_pause_pkt_dmac_s {
6059 + uint64_t reserved_48_63:16;
6060 + uint64_t dmac:48;
6061 + } s;
6062 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn30xx;
6063 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn31xx;
6064 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xx;
6065 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xxp2;
6066 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn50xx;
6067 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xx;
6068 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xxp1;
6069 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xx;
6070 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xxp1;
6071 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xx;
6072 + struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xxp1;
6073 +};
6074 +
6075 +union cvmx_gmxx_tx_pause_pkt_type {
6076 + uint64_t u64;
6077 + struct cvmx_gmxx_tx_pause_pkt_type_s {
6078 + uint64_t reserved_16_63:48;
6079 + uint64_t type:16;
6080 + } s;
6081 + struct cvmx_gmxx_tx_pause_pkt_type_s cn30xx;
6082 + struct cvmx_gmxx_tx_pause_pkt_type_s cn31xx;
6083 + struct cvmx_gmxx_tx_pause_pkt_type_s cn38xx;
6084 + struct cvmx_gmxx_tx_pause_pkt_type_s cn38xxp2;
6085 + struct cvmx_gmxx_tx_pause_pkt_type_s cn50xx;
6086 + struct cvmx_gmxx_tx_pause_pkt_type_s cn52xx;
6087 + struct cvmx_gmxx_tx_pause_pkt_type_s cn52xxp1;
6088 + struct cvmx_gmxx_tx_pause_pkt_type_s cn56xx;
6089 + struct cvmx_gmxx_tx_pause_pkt_type_s cn56xxp1;
6090 + struct cvmx_gmxx_tx_pause_pkt_type_s cn58xx;
6091 + struct cvmx_gmxx_tx_pause_pkt_type_s cn58xxp1;
6092 +};
6093 +
6094 +union cvmx_gmxx_tx_prts {
6095 + uint64_t u64;
6096 + struct cvmx_gmxx_tx_prts_s {
6097 + uint64_t reserved_5_63:59;
6098 + uint64_t prts:5;
6099 + } s;
6100 + struct cvmx_gmxx_tx_prts_s cn30xx;
6101 + struct cvmx_gmxx_tx_prts_s cn31xx;
6102 + struct cvmx_gmxx_tx_prts_s cn38xx;
6103 + struct cvmx_gmxx_tx_prts_s cn38xxp2;
6104 + struct cvmx_gmxx_tx_prts_s cn50xx;
6105 + struct cvmx_gmxx_tx_prts_s cn52xx;
6106 + struct cvmx_gmxx_tx_prts_s cn52xxp1;
6107 + struct cvmx_gmxx_tx_prts_s cn56xx;
6108 + struct cvmx_gmxx_tx_prts_s cn56xxp1;
6109 + struct cvmx_gmxx_tx_prts_s cn58xx;
6110 + struct cvmx_gmxx_tx_prts_s cn58xxp1;
6111 +};
6112 +
6113 +union cvmx_gmxx_tx_spi_ctl {
6114 + uint64_t u64;
6115 + struct cvmx_gmxx_tx_spi_ctl_s {
6116 + uint64_t reserved_2_63:62;
6117 + uint64_t tpa_clr:1;
6118 + uint64_t cont_pkt:1;
6119 + } s;
6120 + struct cvmx_gmxx_tx_spi_ctl_s cn38xx;
6121 + struct cvmx_gmxx_tx_spi_ctl_s cn38xxp2;
6122 + struct cvmx_gmxx_tx_spi_ctl_s cn58xx;
6123 + struct cvmx_gmxx_tx_spi_ctl_s cn58xxp1;
6124 +};
6125 +
6126 +union cvmx_gmxx_tx_spi_drain {
6127 + uint64_t u64;
6128 + struct cvmx_gmxx_tx_spi_drain_s {
6129 + uint64_t reserved_16_63:48;
6130 + uint64_t drain:16;
6131 + } s;
6132 + struct cvmx_gmxx_tx_spi_drain_s cn38xx;
6133 + struct cvmx_gmxx_tx_spi_drain_s cn58xx;
6134 + struct cvmx_gmxx_tx_spi_drain_s cn58xxp1;
6135 +};
6136 +
6137 +union cvmx_gmxx_tx_spi_max {
6138 + uint64_t u64;
6139 + struct cvmx_gmxx_tx_spi_max_s {
6140 + uint64_t reserved_23_63:41;
6141 + uint64_t slice:7;
6142 + uint64_t max2:8;
6143 + uint64_t max1:8;
6144 + } s;
6145 + struct cvmx_gmxx_tx_spi_max_cn38xx {
6146 + uint64_t reserved_16_63:48;
6147 + uint64_t max2:8;
6148 + uint64_t max1:8;
6149 + } cn38xx;
6150 + struct cvmx_gmxx_tx_spi_max_cn38xx cn38xxp2;
6151 + struct cvmx_gmxx_tx_spi_max_s cn58xx;
6152 + struct cvmx_gmxx_tx_spi_max_s cn58xxp1;
6153 +};
6154 +
6155 +union cvmx_gmxx_tx_spi_roundx {
6156 + uint64_t u64;
6157 + struct cvmx_gmxx_tx_spi_roundx_s {
6158 + uint64_t reserved_16_63:48;
6159 + uint64_t round:16;
6160 + } s;
6161 + struct cvmx_gmxx_tx_spi_roundx_s cn58xx;
6162 + struct cvmx_gmxx_tx_spi_roundx_s cn58xxp1;
6163 +};
6164 +
6165 +union cvmx_gmxx_tx_spi_thresh {
6166 + uint64_t u64;
6167 + struct cvmx_gmxx_tx_spi_thresh_s {
6168 + uint64_t reserved_6_63:58;
6169 + uint64_t thresh:6;
6170 + } s;
6171 + struct cvmx_gmxx_tx_spi_thresh_s cn38xx;
6172 + struct cvmx_gmxx_tx_spi_thresh_s cn38xxp2;
6173 + struct cvmx_gmxx_tx_spi_thresh_s cn58xx;
6174 + struct cvmx_gmxx_tx_spi_thresh_s cn58xxp1;
6175 +};
6176 +
6177 +union cvmx_gmxx_tx_xaui_ctl {
6178 + uint64_t u64;
6179 + struct cvmx_gmxx_tx_xaui_ctl_s {
6180 + uint64_t reserved_11_63:53;
6181 + uint64_t hg_pause_hgi:2;
6182 + uint64_t hg_en:1;
6183 + uint64_t reserved_7_7:1;
6184 + uint64_t ls_byp:1;
6185 + uint64_t ls:2;
6186 + uint64_t reserved_2_3:2;
6187 + uint64_t uni_en:1;
6188 + uint64_t dic_en:1;
6189 + } s;
6190 + struct cvmx_gmxx_tx_xaui_ctl_s cn52xx;
6191 + struct cvmx_gmxx_tx_xaui_ctl_s cn52xxp1;
6192 + struct cvmx_gmxx_tx_xaui_ctl_s cn56xx;
6193 + struct cvmx_gmxx_tx_xaui_ctl_s cn56xxp1;
6194 +};
6195 +
6196 +union cvmx_gmxx_xaui_ext_loopback {
6197 + uint64_t u64;
6198 + struct cvmx_gmxx_xaui_ext_loopback_s {
6199 + uint64_t reserved_5_63:59;
6200 + uint64_t en:1;
6201 + uint64_t thresh:4;
6202 + } s;
6203 + struct cvmx_gmxx_xaui_ext_loopback_s cn52xx;
6204 + struct cvmx_gmxx_xaui_ext_loopback_s cn52xxp1;
6205 + struct cvmx_gmxx_xaui_ext_loopback_s cn56xx;
6206 + struct cvmx_gmxx_xaui_ext_loopback_s cn56xxp1;
6207 +};
6208 +
6209 +#endif
6210 diff --git a/drivers/staging/octeon/cvmx-helper-board.c b/drivers/staging/octeon/cvmx-helper-board.c
6211 new file mode 100644
6212 index 0000000..3085e38
6213 --- /dev/null
6214 +++ b/drivers/staging/octeon/cvmx-helper-board.c
6215 @@ -0,0 +1,706 @@
6216 +/***********************license start***************
6217 + * Author: Cavium Networks
6218 + *
6219 + * Contact: support@caviumnetworks.com
6220 + * This file is part of the OCTEON SDK
6221 + *
6222 + * Copyright (c) 2003-2008 Cavium Networks
6223 + *
6224 + * This file is free software; you can redistribute it and/or modify
6225 + * it under the terms of the GNU General Public License, Version 2, as
6226 + * published by the Free Software Foundation.
6227 + *
6228 + * This file is distributed in the hope that it will be useful, but
6229 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
6230 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
6231 + * NONINFRINGEMENT. See the GNU General Public License for more
6232 + * details.
6233 + *
6234 + * You should have received a copy of the GNU General Public License
6235 + * along with this file; if not, write to the Free Software
6236 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6237 + * or visit http://www.gnu.org/licenses/.
6238 + *
6239 + * This file may also be available under a different license from Cavium.
6240 + * Contact Cavium Networks for more information
6241 + ***********************license end**************************************/
6242 +
6243 +/*
6244 + *
6245 + * Helper functions to abstract board specific data about
6246 + * network ports from the rest of the cvmx-helper files.
6247 + */
6248 +
6249 +#include <asm/octeon/octeon.h>
6250 +#include <asm/octeon/cvmx-bootinfo.h>
6251 +
6252 +#include "cvmx-config.h"
6253 +
6254 +#include "cvmx-mdio.h"
6255 +
6256 +#include "cvmx-helper.h"
6257 +#include "cvmx-helper-util.h"
6258 +#include "cvmx-helper-board.h"
6259 +
6260 +#include "cvmx-gmxx-defs.h"
6261 +#include "cvmx-asxx-defs.h"
6262 +
6263 +/**
6264 + * cvmx_override_board_link_get(int ipd_port) is a function
6265 + * pointer. It is meant to allow customization of the process of
6266 + * talking to a PHY to determine link speed. It is called every
6267 + * time a PHY must be polled for link status. Users should set
6268 + * this pointer to a function before calling any cvmx-helper
6269 + * operations.
6270 + */
6271 +cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port) =
6272 + NULL;
6273 +
6274 +/**
6275 + * Return the MII PHY address associated with the given IPD
6276 + * port. A result of -1 means there isn't a MII capable PHY
6277 + * connected to this port. On chips supporting multiple MII
6278 + * busses the bus number is encoded in bits <15:8>.
6279 + *
6280 + * This function must be modified for every new Octeon board.
6281 + * Internally it uses switch statements based on the cvmx_sysinfo
6282 + * data to determine board types and revisions. It replies on the
6283 + * fact that every Octeon board receives a unique board type
6284 + * enumeration from the bootloader.
6285 + *
6286 + * @ipd_port: Octeon IPD port to get the MII address for.
6287 + *
6288 + * Returns MII PHY address and bus number or -1.
6289 + */
6290 +int cvmx_helper_board_get_mii_address(int ipd_port)
6291 +{
6292 + switch (cvmx_sysinfo_get()->board_type) {
6293 + case CVMX_BOARD_TYPE_SIM:
6294 + /* Simulator doesn't have MII */
6295 + return -1;
6296 + case CVMX_BOARD_TYPE_EBT3000:
6297 + case CVMX_BOARD_TYPE_EBT5800:
6298 + case CVMX_BOARD_TYPE_THUNDER:
6299 + case CVMX_BOARD_TYPE_NICPRO2:
6300 + /* Interface 0 is SPI4, interface 1 is RGMII */
6301 + if ((ipd_port >= 16) && (ipd_port < 20))
6302 + return ipd_port - 16;
6303 + else
6304 + return -1;
6305 + case CVMX_BOARD_TYPE_KODAMA:
6306 + case CVMX_BOARD_TYPE_EBH3100:
6307 + case CVMX_BOARD_TYPE_HIKARI:
6308 + case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
6309 + case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6310 + case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
6311 + /*
6312 + * Port 0 is WAN connected to a PHY, Port 1 is GMII
6313 + * connected to a switch
6314 + */
6315 + if (ipd_port == 0)
6316 + return 4;
6317 + else if (ipd_port == 1)
6318 + return 9;
6319 + else
6320 + return -1;
6321 + case CVMX_BOARD_TYPE_NAC38:
6322 + /* Board has 8 RGMII ports PHYs are 0-7 */
6323 + if ((ipd_port >= 0) && (ipd_port < 4))
6324 + return ipd_port;
6325 + else if ((ipd_port >= 16) && (ipd_port < 20))
6326 + return ipd_port - 16 + 4;
6327 + else
6328 + return -1;
6329 + case CVMX_BOARD_TYPE_EBH3000:
6330 + /* Board has dual SPI4 and no PHYs */
6331 + return -1;
6332 + case CVMX_BOARD_TYPE_EBH5200:
6333 + case CVMX_BOARD_TYPE_EBH5201:
6334 + case CVMX_BOARD_TYPE_EBT5200:
6335 + /*
6336 + * Board has 4 SGMII ports. The PHYs start right after the MII
6337 + * ports MII0 = 0, MII1 = 1, SGMII = 2-5.
6338 + */
6339 + if ((ipd_port >= 0) && (ipd_port < 4))
6340 + return ipd_port + 2;
6341 + else
6342 + return -1;
6343 + case CVMX_BOARD_TYPE_EBH5600:
6344 + case CVMX_BOARD_TYPE_EBH5601:
6345 + case CVMX_BOARD_TYPE_EBH5610:
6346 + /*
6347 + * Board has 8 SGMII ports. 4 connect out, two connect
6348 + * to a switch, and 2 loop to each other
6349 + */
6350 + if ((ipd_port >= 0) && (ipd_port < 4))
6351 + return ipd_port + 1;
6352 + else
6353 + return -1;
6354 + case CVMX_BOARD_TYPE_CUST_NB5:
6355 + if (ipd_port == 2)
6356 + return 4;
6357 + else
6358 + return -1;
6359 + case CVMX_BOARD_TYPE_NIC_XLE_4G:
6360 + /* Board has 4 SGMII ports. connected QLM3(interface 1) */
6361 + if ((ipd_port >= 16) && (ipd_port < 20))
6362 + return ipd_port - 16 + 1;
6363 + else
6364 + return -1;
6365 + case CVMX_BOARD_TYPE_BBGW_REF:
6366 + /*
6367 + * No PHYs are connected to Octeon, everything is
6368 + * through switch.
6369 + */
6370 + return -1;
6371 + }
6372 +
6373 + /* Some unknown board. Somebody forgot to update this function... */
6374 + cvmx_dprintf
6375 + ("cvmx_helper_board_get_mii_address: Unknown board type %d\n",
6376 + cvmx_sysinfo_get()->board_type);
6377 + return -1;
6378 +}
6379 +
6380 +/**
6381 + * This function is the board specific method of determining an
6382 + * ethernet ports link speed. Most Octeon boards have Marvell PHYs
6383 + * and are handled by the fall through case. This function must be
6384 + * updated for boards that don't have the normal Marvell PHYs.
6385 + *
6386 + * This function must be modified for every new Octeon board.
6387 + * Internally it uses switch statements based on the cvmx_sysinfo
6388 + * data to determine board types and revisions. It relies on the
6389 + * fact that every Octeon board receives a unique board type
6390 + * enumeration from the bootloader.
6391 + *
6392 + * @ipd_port: IPD input port associated with the port we want to get link
6393 + * status for.
6394 + *
6395 + * Returns The ports link status. If the link isn't fully resolved, this must
6396 + * return zero.
6397 + */
6398 +cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
6399 +{
6400 + cvmx_helper_link_info_t result;
6401 + int phy_addr;
6402 + int is_broadcom_phy = 0;
6403 +
6404 + /* Give the user a chance to override the processing of this function */
6405 + if (cvmx_override_board_link_get)
6406 + return cvmx_override_board_link_get(ipd_port);
6407 +
6408 + /* Unless we fix it later, all links are defaulted to down */
6409 + result.u64 = 0;
6410 +
6411 + /*
6412 + * This switch statement should handle all ports that either don't use
6413 + * Marvell PHYS, or don't support in-band status.
6414 + */
6415 + switch (cvmx_sysinfo_get()->board_type) {
6416 + case CVMX_BOARD_TYPE_SIM:
6417 + /* The simulator gives you a simulated 1Gbps full duplex link */
6418 + result.s.link_up = 1;
6419 + result.s.full_duplex = 1;
6420 + result.s.speed = 1000;
6421 + return result;
6422 + case CVMX_BOARD_TYPE_EBH3100:
6423 + case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
6424 + case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6425 + case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
6426 + /* Port 1 on these boards is always Gigabit */
6427 + if (ipd_port == 1) {
6428 + result.s.link_up = 1;
6429 + result.s.full_duplex = 1;
6430 + result.s.speed = 1000;
6431 + return result;
6432 + }
6433 + /* Fall through to the generic code below */
6434 + break;
6435 + case CVMX_BOARD_TYPE_CUST_NB5:
6436 + /* Port 1 on these boards is always Gigabit */
6437 + if (ipd_port == 1) {
6438 + result.s.link_up = 1;
6439 + result.s.full_duplex = 1;
6440 + result.s.speed = 1000;
6441 + return result;
6442 + } else /* The other port uses a broadcom PHY */
6443 + is_broadcom_phy = 1;
6444 + break;
6445 + case CVMX_BOARD_TYPE_BBGW_REF:
6446 + /* Port 1 on these boards is always Gigabit */
6447 + if (ipd_port == 2) {
6448 + /* Port 2 is not hooked up */
6449 + result.u64 = 0;
6450 + return result;
6451 + } else {
6452 + /* Ports 0 and 1 connect to the switch */
6453 + result.s.link_up = 1;
6454 + result.s.full_duplex = 1;
6455 + result.s.speed = 1000;
6456 + return result;
6457 + }
6458 + break;
6459 + }
6460 +
6461 + phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
6462 + if (phy_addr != -1) {
6463 + if (is_broadcom_phy) {
6464 + /*
6465 + * Below we are going to read SMI/MDIO
6466 + * register 0x19 which works on Broadcom
6467 + * parts
6468 + */
6469 + int phy_status =
6470 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6471 + 0x19);
6472 + switch ((phy_status >> 8) & 0x7) {
6473 + case 0:
6474 + result.u64 = 0;
6475 + break;
6476 + case 1:
6477 + result.s.link_up = 1;
6478 + result.s.full_duplex = 0;
6479 + result.s.speed = 10;
6480 + break;
6481 + case 2:
6482 + result.s.link_up = 1;
6483 + result.s.full_duplex = 1;
6484 + result.s.speed = 10;
6485 + break;
6486 + case 3:
6487 + result.s.link_up = 1;
6488 + result.s.full_duplex = 0;
6489 + result.s.speed = 100;
6490 + break;
6491 + case 4:
6492 + result.s.link_up = 1;
6493 + result.s.full_duplex = 1;
6494 + result.s.speed = 100;
6495 + break;
6496 + case 5:
6497 + result.s.link_up = 1;
6498 + result.s.full_duplex = 1;
6499 + result.s.speed = 100;
6500 + break;
6501 + case 6:
6502 + result.s.link_up = 1;
6503 + result.s.full_duplex = 0;
6504 + result.s.speed = 1000;
6505 + break;
6506 + case 7:
6507 + result.s.link_up = 1;
6508 + result.s.full_duplex = 1;
6509 + result.s.speed = 1000;
6510 + break;
6511 + }
6512 + } else {
6513 + /*
6514 + * This code assumes we are using a Marvell
6515 + * Gigabit PHY. All the speed information can
6516 + * be read from register 17 in one
6517 + * go. Somebody using a different PHY will
6518 + * need to handle it above in the board
6519 + * specific area.
6520 + */
6521 + int phy_status =
6522 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17);
6523 +
6524 + /*
6525 + * If the resolve bit 11 isn't set, see if
6526 + * autoneg is turned off (bit 12, reg 0). The
6527 + * resolve bit doesn't get set properly when
6528 + * autoneg is off, so force it.
6529 + */
6530 + if ((phy_status & (1 << 11)) == 0) {
6531 + int auto_status =
6532 + cvmx_mdio_read(phy_addr >> 8,
6533 + phy_addr & 0xff, 0);
6534 + if ((auto_status & (1 << 12)) == 0)
6535 + phy_status |= 1 << 11;
6536 + }
6537 +
6538 + /*
6539 + * Only return a link if the PHY has finished
6540 + * auto negotiation and set the resolved bit
6541 + * (bit 11)
6542 + */
6543 + if (phy_status & (1 << 11)) {
6544 + result.s.link_up = 1;
6545 + result.s.full_duplex = ((phy_status >> 13) & 1);
6546 + switch ((phy_status >> 14) & 3) {
6547 + case 0: /* 10 Mbps */
6548 + result.s.speed = 10;
6549 + break;
6550 + case 1: /* 100 Mbps */
6551 + result.s.speed = 100;
6552 + break;
6553 + case 2: /* 1 Gbps */
6554 + result.s.speed = 1000;
6555 + break;
6556 + case 3: /* Illegal */
6557 + result.u64 = 0;
6558 + break;
6559 + }
6560 + }
6561 + }
6562 + } else if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
6563 + || OCTEON_IS_MODEL(OCTEON_CN58XX)
6564 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
6565 + /*
6566 + * We don't have a PHY address, so attempt to use
6567 + * in-band status. It is really important that boards
6568 + * not supporting in-band status never get
6569 + * here. Reading broken in-band status tends to do bad
6570 + * things
6571 + */
6572 + union cvmx_gmxx_rxx_rx_inbnd inband_status;
6573 + int interface = cvmx_helper_get_interface_num(ipd_port);
6574 + int index = cvmx_helper_get_interface_index_num(ipd_port);
6575 + inband_status.u64 =
6576 + cvmx_read_csr(CVMX_GMXX_RXX_RX_INBND(index, interface));
6577 +
6578 + result.s.link_up = inband_status.s.status;
6579 + result.s.full_duplex = inband_status.s.duplex;
6580 + switch (inband_status.s.speed) {
6581 + case 0: /* 10 Mbps */
6582 + result.s.speed = 10;
6583 + break;
6584 + case 1: /* 100 Mbps */
6585 + result.s.speed = 100;
6586 + break;
6587 + case 2: /* 1 Gbps */
6588 + result.s.speed = 1000;
6589 + break;
6590 + case 3: /* Illegal */
6591 + result.u64 = 0;
6592 + break;
6593 + }
6594 + } else {
6595 + /*
6596 + * We don't have a PHY address and we don't have
6597 + * in-band status. There is no way to determine the
6598 + * link speed. Return down assuming this port isn't
6599 + * wired
6600 + */
6601 + result.u64 = 0;
6602 + }
6603 +
6604 + /* If link is down, return all fields as zero. */
6605 + if (!result.s.link_up)
6606 + result.u64 = 0;
6607 +
6608 + return result;
6609 +}
6610 +
6611 +/**
6612 + * This function as a board specific method of changing the PHY
6613 + * speed, duplex, and auto-negotiation. This programs the PHY and
6614 + * not Octeon. This can be used to force Octeon's links to
6615 + * specific settings.
6616 + *
6617 + * @phy_addr: The address of the PHY to program
6618 + * @enable_autoneg:
6619 + * Non zero if you want to enable auto-negotiation.
6620 + * @link_info: Link speed to program. If the speed is zero and auto-negotiation
6621 + * is enabled, all possible negotiation speeds are advertised.
6622 + *
6623 + * Returns Zero on success, negative on failure
6624 + */
6625 +int cvmx_helper_board_link_set_phy(int phy_addr,
6626 + cvmx_helper_board_set_phy_link_flags_types_t
6627 + link_flags,
6628 + cvmx_helper_link_info_t link_info)
6629 +{
6630 +
6631 + /* Set the flow control settings based on link_flags */
6632 + if ((link_flags & set_phy_link_flags_flow_control_mask) !=
6633 + set_phy_link_flags_flow_control_dont_touch) {
6634 + cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6635 + reg_autoneg_adver.u16 =
6636 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6637 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6638 + reg_autoneg_adver.s.asymmetric_pause =
6639 + (link_flags & set_phy_link_flags_flow_control_mask) ==
6640 + set_phy_link_flags_flow_control_enable;
6641 + reg_autoneg_adver.s.pause =
6642 + (link_flags & set_phy_link_flags_flow_control_mask) ==
6643 + set_phy_link_flags_flow_control_enable;
6644 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6645 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6646 + reg_autoneg_adver.u16);
6647 + }
6648 +
6649 + /* If speed isn't set and autoneg is on advertise all supported modes */
6650 + if ((link_flags & set_phy_link_flags_autoneg)
6651 + && (link_info.s.speed == 0)) {
6652 + cvmx_mdio_phy_reg_control_t reg_control;
6653 + cvmx_mdio_phy_reg_status_t reg_status;
6654 + cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6655 + cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
6656 + cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
6657 +
6658 + reg_status.u16 =
6659 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6660 + CVMX_MDIO_PHY_REG_STATUS);
6661 + reg_autoneg_adver.u16 =
6662 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6663 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6664 + reg_autoneg_adver.s.advert_100base_t4 =
6665 + reg_status.s.capable_100base_t4;
6666 + reg_autoneg_adver.s.advert_10base_tx_full =
6667 + reg_status.s.capable_10_full;
6668 + reg_autoneg_adver.s.advert_10base_tx_half =
6669 + reg_status.s.capable_10_half;
6670 + reg_autoneg_adver.s.advert_100base_tx_full =
6671 + reg_status.s.capable_100base_x_full;
6672 + reg_autoneg_adver.s.advert_100base_tx_half =
6673 + reg_status.s.capable_100base_x_half;
6674 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6675 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6676 + reg_autoneg_adver.u16);
6677 + if (reg_status.s.capable_extended_status) {
6678 + reg_extended_status.u16 =
6679 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6680 + CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
6681 + reg_control_1000.u16 =
6682 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6683 + CVMX_MDIO_PHY_REG_CONTROL_1000);
6684 + reg_control_1000.s.advert_1000base_t_full =
6685 + reg_extended_status.s.capable_1000base_t_full;
6686 + reg_control_1000.s.advert_1000base_t_half =
6687 + reg_extended_status.s.capable_1000base_t_half;
6688 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6689 + CVMX_MDIO_PHY_REG_CONTROL_1000,
6690 + reg_control_1000.u16);
6691 + }
6692 + reg_control.u16 =
6693 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6694 + CVMX_MDIO_PHY_REG_CONTROL);
6695 + reg_control.s.autoneg_enable = 1;
6696 + reg_control.s.restart_autoneg = 1;
6697 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6698 + CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6699 + } else if ((link_flags & set_phy_link_flags_autoneg)) {
6700 + cvmx_mdio_phy_reg_control_t reg_control;
6701 + cvmx_mdio_phy_reg_status_t reg_status;
6702 + cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
6703 + cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
6704 + cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
6705 +
6706 + reg_status.u16 =
6707 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6708 + CVMX_MDIO_PHY_REG_STATUS);
6709 + reg_autoneg_adver.u16 =
6710 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6711 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
6712 + reg_autoneg_adver.s.advert_100base_t4 = 0;
6713 + reg_autoneg_adver.s.advert_10base_tx_full = 0;
6714 + reg_autoneg_adver.s.advert_10base_tx_half = 0;
6715 + reg_autoneg_adver.s.advert_100base_tx_full = 0;
6716 + reg_autoneg_adver.s.advert_100base_tx_half = 0;
6717 + if (reg_status.s.capable_extended_status) {
6718 + reg_extended_status.u16 =
6719 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6720 + CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
6721 + reg_control_1000.u16 =
6722 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6723 + CVMX_MDIO_PHY_REG_CONTROL_1000);
6724 + reg_control_1000.s.advert_1000base_t_full = 0;
6725 + reg_control_1000.s.advert_1000base_t_half = 0;
6726 + }
6727 + switch (link_info.s.speed) {
6728 + case 10:
6729 + reg_autoneg_adver.s.advert_10base_tx_full =
6730 + link_info.s.full_duplex;
6731 + reg_autoneg_adver.s.advert_10base_tx_half =
6732 + !link_info.s.full_duplex;
6733 + break;
6734 + case 100:
6735 + reg_autoneg_adver.s.advert_100base_tx_full =
6736 + link_info.s.full_duplex;
6737 + reg_autoneg_adver.s.advert_100base_tx_half =
6738 + !link_info.s.full_duplex;
6739 + break;
6740 + case 1000:
6741 + reg_control_1000.s.advert_1000base_t_full =
6742 + link_info.s.full_duplex;
6743 + reg_control_1000.s.advert_1000base_t_half =
6744 + !link_info.s.full_duplex;
6745 + break;
6746 + }
6747 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6748 + CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
6749 + reg_autoneg_adver.u16);
6750 + if (reg_status.s.capable_extended_status)
6751 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6752 + CVMX_MDIO_PHY_REG_CONTROL_1000,
6753 + reg_control_1000.u16);
6754 + reg_control.u16 =
6755 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6756 + CVMX_MDIO_PHY_REG_CONTROL);
6757 + reg_control.s.autoneg_enable = 1;
6758 + reg_control.s.restart_autoneg = 1;
6759 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6760 + CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6761 + } else {
6762 + cvmx_mdio_phy_reg_control_t reg_control;
6763 + reg_control.u16 =
6764 + cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
6765 + CVMX_MDIO_PHY_REG_CONTROL);
6766 + reg_control.s.autoneg_enable = 0;
6767 + reg_control.s.restart_autoneg = 1;
6768 + reg_control.s.duplex = link_info.s.full_duplex;
6769 + if (link_info.s.speed == 1000) {
6770 + reg_control.s.speed_msb = 1;
6771 + reg_control.s.speed_lsb = 0;
6772 + } else if (link_info.s.speed == 100) {
6773 + reg_control.s.speed_msb = 0;
6774 + reg_control.s.speed_lsb = 1;
6775 + } else if (link_info.s.speed == 10) {
6776 + reg_control.s.speed_msb = 0;
6777 + reg_control.s.speed_lsb = 0;
6778 + }
6779 + cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
6780 + CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
6781 + }
6782 + return 0;
6783 +}
6784 +
6785 +/**
6786 + * This function is called by cvmx_helper_interface_probe() after it
6787 + * determines the number of ports Octeon can support on a specific
6788 + * interface. This function is the per board location to override
6789 + * this value. It is called with the number of ports Octeon might
6790 + * support and should return the number of actual ports on the
6791 + * board.
6792 + *
6793 + * This function must be modifed for every new Octeon board.
6794 + * Internally it uses switch statements based on the cvmx_sysinfo
6795 + * data to determine board types and revisions. It relys on the
6796 + * fact that every Octeon board receives a unique board type
6797 + * enumeration from the bootloader.
6798 + *
6799 + * @interface: Interface to probe
6800 + * @supported_ports:
6801 + * Number of ports Octeon supports.
6802 + *
6803 + * Returns Number of ports the actual board supports. Many times this will
6804 + * simple be "support_ports".
6805 + */
6806 +int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
6807 +{
6808 + switch (cvmx_sysinfo_get()->board_type) {
6809 + case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
6810 + if (interface == 0)
6811 + return 2;
6812 + break;
6813 + case CVMX_BOARD_TYPE_BBGW_REF:
6814 + if (interface == 0)
6815 + return 2;
6816 + break;
6817 + case CVMX_BOARD_TYPE_NIC_XLE_4G:
6818 + if (interface == 0)
6819 + return 0;
6820 + break;
6821 + /* The 2nd interface on the EBH5600 is connected to the Marvel switch,
6822 + which we don't support. Disable ports connected to it */
6823 + case CVMX_BOARD_TYPE_EBH5600:
6824 + if (interface == 1)
6825 + return 0;
6826 + break;
6827 + }
6828 + return supported_ports;
6829 +}
6830 +
6831 +/**
6832 + * Enable packet input/output from the hardware. This function is
6833 + * called after by cvmx_helper_packet_hardware_enable() to
6834 + * perform board specific initialization. For most boards
6835 + * nothing is needed.
6836 + *
6837 + * @interface: Interface to enable
6838 + *
6839 + * Returns Zero on success, negative on failure
6840 + */
6841 +int __cvmx_helper_board_hardware_enable(int interface)
6842 +{
6843 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5) {
6844 + if (interface == 0) {
6845 + /* Different config for switch port */
6846 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0);
6847 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
6848 + /*
6849 + * Boards with gigabit WAN ports need a
6850 + * different setting that is compatible with
6851 + * 100 Mbit settings
6852 + */
6853 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface),
6854 + 0xc);
6855 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface),
6856 + 0xc);
6857 + }
6858 + } else if (cvmx_sysinfo_get()->board_type ==
6859 + CVMX_BOARD_TYPE_CN3010_EVB_HS5) {
6860 + /*
6861 + * Broadcom PHYs require differnet ASX
6862 + * clocks. Unfortunately many boards don't define a
6863 + * new board Id and simply mangle the
6864 + * CN3010_EVB_HS5
6865 + */
6866 + if (interface == 0) {
6867 + /*
6868 + * Some boards use a hacked up bootloader that
6869 + * identifies them as CN3010_EVB_HS5
6870 + * evaluation boards. This leads to all kinds
6871 + * of configuration problems. Detect one
6872 + * case, and print warning, while trying to do
6873 + * the right thing.
6874 + */
6875 + int phy_addr = cvmx_helper_board_get_mii_address(0);
6876 + if (phy_addr != -1) {
6877 + int phy_identifier =
6878 + cvmx_mdio_read(phy_addr >> 8,
6879 + phy_addr & 0xff, 0x2);
6880 + /* Is it a Broadcom PHY? */
6881 + if (phy_identifier == 0x0143) {
6882 + cvmx_dprintf("\n");
6883 + cvmx_dprintf("ERROR:\n");
6884 + cvmx_dprintf
6885 + ("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n");
6886 + cvmx_dprintf
6887 + ("ERROR: The board type is mis-configured, and software malfunctions are likely.\n");
6888 + cvmx_dprintf
6889 + ("ERROR: All boards require a unique board type to identify them.\n");
6890 + cvmx_dprintf("ERROR:\n");
6891 + cvmx_dprintf("\n");
6892 + cvmx_wait(1000000000);
6893 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX
6894 + (0, interface), 5);
6895 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX
6896 + (0, interface), 5);
6897 + }
6898 + }
6899 + }
6900 + }
6901 + return 0;
6902 +}
6903 +
6904 +cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void)
6905 +{
6906 + switch (cvmx_sysinfo_get()->board_type) {
6907 + case CVMX_BOARD_TYPE_BBGW_REF:
6908 + return USB_CLOCK_TYPE_CRYSTAL_12;
6909 + }
6910 + return USB_CLOCK_TYPE_REF_48;
6911 +}
6912 +
6913 +int __cvmx_helper_board_usb_get_num_ports(int supported_ports)
6914 +{
6915 + switch (cvmx_sysinfo_get()->board_type) {
6916 + case CVMX_BOARD_TYPE_NIC_XLE_4G:
6917 + return 0;
6918 + }
6919 +
6920 + return supported_ports;
6921 +}
6922 diff --git a/drivers/staging/octeon/cvmx-helper-board.h b/drivers/staging/octeon/cvmx-helper-board.h
6923 new file mode 100644
6924 index 0000000..dc20b01
6925 --- /dev/null
6926 +++ b/drivers/staging/octeon/cvmx-helper-board.h
6927 @@ -0,0 +1,180 @@
6928 +/***********************license start***************
6929 + * Author: Cavium Networks
6930 + *
6931 + * Contact: support@caviumnetworks.com
6932 + * This file is part of the OCTEON SDK
6933 + *
6934 + * Copyright (c) 2003-2008 Cavium Networks
6935 + *
6936 + * This file is free software; you can redistribute it and/or modify
6937 + * it under the terms of the GNU General Public License, Version 2, as
6938 + * published by the Free Software Foundation.
6939 + *
6940 + * This file is distributed in the hope that it will be useful, but
6941 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
6942 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
6943 + * NONINFRINGEMENT. See the GNU General Public License for more
6944 + * details.
6945 + *
6946 + * You should have received a copy of the GNU General Public License
6947 + * along with this file; if not, write to the Free Software
6948 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6949 + * or visit http://www.gnu.org/licenses/.
6950 + *
6951 + * This file may also be available under a different license from Cavium.
6952 + * Contact Cavium Networks for more information
6953 + ***********************license end**************************************/
6954 +
6955 +/**
6956 + *
6957 + * Helper functions to abstract board specific data about
6958 + * network ports from the rest of the cvmx-helper files.
6959 + *
6960 + */
6961 +#ifndef __CVMX_HELPER_BOARD_H__
6962 +#define __CVMX_HELPER_BOARD_H__
6963 +
6964 +#include "cvmx-helper.h"
6965 +
6966 +typedef enum {
6967 + USB_CLOCK_TYPE_REF_12,
6968 + USB_CLOCK_TYPE_REF_24,
6969 + USB_CLOCK_TYPE_REF_48,
6970 + USB_CLOCK_TYPE_CRYSTAL_12,
6971 +} cvmx_helper_board_usb_clock_types_t;
6972 +
6973 +typedef enum {
6974 + set_phy_link_flags_autoneg = 0x1,
6975 + set_phy_link_flags_flow_control_dont_touch = 0x0 << 1,
6976 + set_phy_link_flags_flow_control_enable = 0x1 << 1,
6977 + set_phy_link_flags_flow_control_disable = 0x2 << 1,
6978 + set_phy_link_flags_flow_control_mask = 0x3 << 1, /* Mask for 2 bit wide flow control field */
6979 +} cvmx_helper_board_set_phy_link_flags_types_t;
6980 +
6981 +/**
6982 + * cvmx_override_board_link_get(int ipd_port) is a function
6983 + * pointer. It is meant to allow customization of the process of
6984 + * talking to a PHY to determine link speed. It is called every
6985 + * time a PHY must be polled for link status. Users should set
6986 + * this pointer to a function before calling any cvmx-helper
6987 + * operations.
6988 + */
6989 +extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port);
6990 +
6991 +/**
6992 + * Return the MII PHY address associated with the given IPD
6993 + * port. A result of -1 means there isn't a MII capable PHY
6994 + * connected to this port. On chips supporting multiple MII
6995 + * busses the bus number is encoded in bits <15:8>.
6996 + *
6997 + * This function must be modifed for every new Octeon board.
6998 + * Internally it uses switch statements based on the cvmx_sysinfo
6999 + * data to determine board types and revisions. It relys on the
7000 + * fact that every Octeon board receives a unique board type
7001 + * enumeration from the bootloader.
7002 + *
7003 + * @ipd_port: Octeon IPD port to get the MII address for.
7004 + *
7005 + * Returns MII PHY address and bus number or -1.
7006 + */
7007 +extern int cvmx_helper_board_get_mii_address(int ipd_port);
7008 +
7009 +/**
7010 + * This function as a board specific method of changing the PHY
7011 + * speed, duplex, and autonegotiation. This programs the PHY and
7012 + * not Octeon. This can be used to force Octeon's links to
7013 + * specific settings.
7014 + *
7015 + * @phy_addr: The address of the PHY to program
7016 + * @link_flags:
7017 + * Flags to control autonegotiation. Bit 0 is autonegotiation
7018 + * enable/disable to maintain backware compatability.
7019 + * @link_info: Link speed to program. If the speed is zero and autonegotiation
7020 + * is enabled, all possible negotiation speeds are advertised.
7021 + *
7022 + * Returns Zero on success, negative on failure
7023 + */
7024 +int cvmx_helper_board_link_set_phy(int phy_addr,
7025 + cvmx_helper_board_set_phy_link_flags_types_t
7026 + link_flags,
7027 + cvmx_helper_link_info_t link_info);
7028 +
7029 +/**
7030 + * This function is the board specific method of determining an
7031 + * ethernet ports link speed. Most Octeon boards have Marvell PHYs
7032 + * and are handled by the fall through case. This function must be
7033 + * updated for boards that don't have the normal Marvell PHYs.
7034 + *
7035 + * This function must be modifed for every new Octeon board.
7036 + * Internally it uses switch statements based on the cvmx_sysinfo
7037 + * data to determine board types and revisions. It relys on the
7038 + * fact that every Octeon board receives a unique board type
7039 + * enumeration from the bootloader.
7040 + *
7041 + * @ipd_port: IPD input port associated with the port we want to get link
7042 + * status for.
7043 + *
7044 + * Returns The ports link status. If the link isn't fully resolved, this must
7045 + * return zero.
7046 + */
7047 +extern cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port);
7048 +
7049 +/**
7050 + * This function is called by cvmx_helper_interface_probe() after it
7051 + * determines the number of ports Octeon can support on a specific
7052 + * interface. This function is the per board location to override
7053 + * this value. It is called with the number of ports Octeon might
7054 + * support and should return the number of actual ports on the
7055 + * board.
7056 + *
7057 + * This function must be modifed for every new Octeon board.
7058 + * Internally it uses switch statements based on the cvmx_sysinfo
7059 + * data to determine board types and revisions. It relys on the
7060 + * fact that every Octeon board receives a unique board type
7061 + * enumeration from the bootloader.
7062 + *
7063 + * @interface: Interface to probe
7064 + * @supported_ports:
7065 + * Number of ports Octeon supports.
7066 + *
7067 + * Returns Number of ports the actual board supports. Many times this will
7068 + * simple be "support_ports".
7069 + */
7070 +extern int __cvmx_helper_board_interface_probe(int interface,
7071 + int supported_ports);
7072 +
7073 +/**
7074 + * Enable packet input/output from the hardware. This function is
7075 + * called after by cvmx_helper_packet_hardware_enable() to
7076 + * perform board specific initialization. For most boards
7077 + * nothing is needed.
7078 + *
7079 + * @interface: Interface to enable
7080 + *
7081 + * Returns Zero on success, negative on failure
7082 + */
7083 +extern int __cvmx_helper_board_hardware_enable(int interface);
7084 +
7085 +/**
7086 + * Gets the clock type used for the USB block based on board type.
7087 + * Used by the USB code for auto configuration of clock type.
7088 + *
7089 + * Returns USB clock type enumeration
7090 + */
7091 +cvmx_helper_board_usb_clock_types_t
7092 +__cvmx_helper_board_usb_get_clock_type(void);
7093 +
7094 +/**
7095 + * Adjusts the number of available USB ports on Octeon based on board
7096 + * specifics.
7097 + *
7098 + * @supported_ports: expected number of ports based on chip type;
7099 + *
7100 + *
7101 + * Returns number of available usb ports, based on board specifics.
7102 + * Return value is supported_ports if function does not
7103 + * override.
7104 + */
7105 +int __cvmx_helper_board_usb_get_num_ports(int supported_ports);
7106 +
7107 +#endif /* __CVMX_HELPER_BOARD_H__ */
7108 diff --git a/drivers/staging/octeon/cvmx-helper-fpa.c b/drivers/staging/octeon/cvmx-helper-fpa.c
7109 new file mode 100644
7110 index 0000000..c239e5f
7111 --- /dev/null
7112 +++ b/drivers/staging/octeon/cvmx-helper-fpa.c
7113 @@ -0,0 +1,243 @@
7114 +/***********************license start***************
7115 + * Author: Cavium Networks
7116 + *
7117 + * Contact: support@caviumnetworks.com
7118 + * This file is part of the OCTEON SDK
7119 + *
7120 + * Copyright (c) 2003-2008 Cavium Networks
7121 + *
7122 + * This file is free software; you can redistribute it and/or modify
7123 + * it under the terms of the GNU General Public License, Version 2, as
7124 + * published by the Free Software Foundation.
7125 + *
7126 + * This file is distributed in the hope that it will be useful, but
7127 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7128 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7129 + * NONINFRINGEMENT. See the GNU General Public License for more
7130 + * details.
7131 + *
7132 + * You should have received a copy of the GNU General Public License
7133 + * along with this file; if not, write to the Free Software
7134 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7135 + * or visit http://www.gnu.org/licenses/.
7136 + *
7137 + * This file may also be available under a different license from Cavium.
7138 + * Contact Cavium Networks for more information
7139 + ***********************license end**************************************/
7140 +
7141 +/**
7142 + * @file
7143 + *
7144 + * Helper functions for FPA setup.
7145 + *
7146 + */
7147 +#include "executive-config.h"
7148 +#include "cvmx-config.h"
7149 +#include "cvmx.h"
7150 +#include "cvmx-bootmem.h"
7151 +#include "cvmx-fpa.h"
7152 +#include "cvmx-helper-fpa.h"
7153 +
7154 +/**
7155 + * Allocate memory for and initialize a single FPA pool.
7156 + *
7157 + * @pool: Pool to initialize
7158 + * @buffer_size: Size of buffers to allocate in bytes
7159 + * @buffers: Number of buffers to put in the pool. Zero is allowed
7160 + * @name: String name of the pool for debugging purposes
7161 + * Returns Zero on success, non-zero on failure
7162 + */
7163 +static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size,
7164 + uint64_t buffers, const char *name)
7165 +{
7166 + uint64_t current_num;
7167 + void *memory;
7168 + uint64_t align = CVMX_CACHE_LINE_SIZE;
7169 +
7170 + /*
7171 + * Align the allocation so that power of 2 size buffers are
7172 + * naturally aligned.
7173 + */
7174 + while (align < buffer_size)
7175 + align = align << 1;
7176 +
7177 + if (buffers == 0)
7178 + return 0;
7179 +
7180 + current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool));
7181 + if (current_num) {
7182 + cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. "
7183 + "Skipping setup.\n",
7184 + pool, name, (unsigned long long)current_num);
7185 + return 0;
7186 + }
7187 +
7188 + memory = cvmx_bootmem_alloc(buffer_size * buffers, align);
7189 + if (memory == NULL) {
7190 + cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n",
7191 + pool, name);
7192 + return -1;
7193 + }
7194 + cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers);
7195 + return 0;
7196 +}
7197 +
7198 +/**
7199 + * Allocate memory and initialize the FPA pools using memory
7200 + * from cvmx-bootmem. Specifying zero for the number of
7201 + * buffers will cause that FPA pool to not be setup. This is
7202 + * useful if you aren't using some of the hardware and want
7203 + * to save memory. Use cvmx_helper_initialize_fpa instead of
7204 + * this function directly.
7205 + *
7206 + * @pip_pool: Should always be CVMX_FPA_PACKET_POOL
7207 + * @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE
7208 + * @pip_buffers:
7209 + * Number of packet buffers.
7210 + * @wqe_pool: Should always be CVMX_FPA_WQE_POOL
7211 + * @wqe_size: Should always be CVMX_FPA_WQE_POOL_SIZE
7212 + * @wqe_entries:
7213 + * Number of work queue entries
7214 + * @pko_pool: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL
7215 + * @pko_size: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
7216 + * @pko_buffers:
7217 + * PKO Command buffers. You should at minimum have two per
7218 + * each PKO queue.
7219 + * @tim_pool: Should always be CVMX_FPA_TIMER_POOL
7220 + * @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE
7221 + * @tim_buffers:
7222 + * TIM ring buffer command queues. At least two per timer bucket
7223 + * is recommened.
7224 + * @dfa_pool: Should always be CVMX_FPA_DFA_POOL
7225 + * @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE
7226 + * @dfa_buffers:
7227 + * DFA command buffer. A relatively small (32 for example)
7228 + * number should work.
7229 + * Returns Zero on success, non-zero if out of memory
7230 + */
7231 +static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size,
7232 + int pip_buffers, int wqe_pool,
7233 + int wqe_size, int wqe_entries,
7234 + int pko_pool, int pko_size,
7235 + int pko_buffers, int tim_pool,
7236 + int tim_size, int tim_buffers,
7237 + int dfa_pool, int dfa_size,
7238 + int dfa_buffers)
7239 +{
7240 + int status;
7241 +
7242 + cvmx_fpa_enable();
7243 +
7244 + if ((pip_buffers > 0) && (pip_buffers <= 64))
7245 + cvmx_dprintf
7246 + ("Warning: %d packet buffers may not be enough for hardware"
7247 + " prefetch. 65 or more is recommended.\n", pip_buffers);
7248 +
7249 + if (pip_pool >= 0) {
7250 + status =
7251 + __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size,
7252 + pip_buffers,
7253 + "Packet Buffers");
7254 + if (status)
7255 + return status;
7256 + }
7257 +
7258 + if (wqe_pool >= 0) {
7259 + status =
7260 + __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size,
7261 + wqe_entries,
7262 + "Work Queue Entries");
7263 + if (status)
7264 + return status;
7265 + }
7266 +
7267 + if (pko_pool >= 0) {
7268 + status =
7269 + __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size,
7270 + pko_buffers,
7271 + "PKO Command Buffers");
7272 + if (status)
7273 + return status;
7274 + }
7275 +
7276 + if (tim_pool >= 0) {
7277 + status =
7278 + __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size,
7279 + tim_buffers,
7280 + "TIM Command Buffers");
7281 + if (status)
7282 + return status;
7283 + }
7284 +
7285 + if (dfa_pool >= 0) {
7286 + status =
7287 + __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size,
7288 + dfa_buffers,
7289 + "DFA Command Buffers");
7290 + if (status)
7291 + return status;
7292 + }
7293 +
7294 + return 0;
7295 +}
7296 +
7297 +/**
7298 + * Allocate memory and initialize the FPA pools using memory
7299 + * from cvmx-bootmem. Sizes of each element in the pools is
7300 + * controlled by the cvmx-config.h header file. Specifying
7301 + * zero for any parameter will cause that FPA pool to not be
7302 + * setup. This is useful if you aren't using some of the
7303 + * hardware and want to save memory.
7304 + *
7305 + * @packet_buffers:
7306 + * Number of packet buffers to allocate
7307 + * @work_queue_entries:
7308 + * Number of work queue entries
7309 + * @pko_buffers:
7310 + * PKO Command buffers. You should at minimum have two per
7311 + * each PKO queue.
7312 + * @tim_buffers:
7313 + * TIM ring buffer command queues. At least two per timer bucket
7314 + * is recommened.
7315 + * @dfa_buffers:
7316 + * DFA command buffer. A relatively small (32 for example)
7317 + * number should work.
7318 + * Returns Zero on success, non-zero if out of memory
7319 + */
7320 +int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries,
7321 + int pko_buffers, int tim_buffers,
7322 + int dfa_buffers)
7323 +{
7324 +#ifndef CVMX_FPA_PACKET_POOL
7325 +#define CVMX_FPA_PACKET_POOL -1
7326 +#define CVMX_FPA_PACKET_POOL_SIZE 0
7327 +#endif
7328 +#ifndef CVMX_FPA_WQE_POOL
7329 +#define CVMX_FPA_WQE_POOL -1
7330 +#define CVMX_FPA_WQE_POOL_SIZE 0
7331 +#endif
7332 +#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL
7333 +#define CVMX_FPA_OUTPUT_BUFFER_POOL -1
7334 +#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0
7335 +#endif
7336 +#ifndef CVMX_FPA_TIMER_POOL
7337 +#define CVMX_FPA_TIMER_POOL -1
7338 +#define CVMX_FPA_TIMER_POOL_SIZE 0
7339 +#endif
7340 +#ifndef CVMX_FPA_DFA_POOL
7341 +#define CVMX_FPA_DFA_POOL -1
7342 +#define CVMX_FPA_DFA_POOL_SIZE 0
7343 +#endif
7344 + return __cvmx_helper_initialize_fpa(CVMX_FPA_PACKET_POOL,
7345 + CVMX_FPA_PACKET_POOL_SIZE,
7346 + packet_buffers, CVMX_FPA_WQE_POOL,
7347 + CVMX_FPA_WQE_POOL_SIZE,
7348 + work_queue_entries,
7349 + CVMX_FPA_OUTPUT_BUFFER_POOL,
7350 + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
7351 + pko_buffers, CVMX_FPA_TIMER_POOL,
7352 + CVMX_FPA_TIMER_POOL_SIZE,
7353 + tim_buffers, CVMX_FPA_DFA_POOL,
7354 + CVMX_FPA_DFA_POOL_SIZE,
7355 + dfa_buffers);
7356 +}
7357 diff --git a/drivers/staging/octeon/cvmx-helper-fpa.h b/drivers/staging/octeon/cvmx-helper-fpa.h
7358 new file mode 100644
7359 index 0000000..5ff8c93
7360 --- /dev/null
7361 +++ b/drivers/staging/octeon/cvmx-helper-fpa.h
7362 @@ -0,0 +1,64 @@
7363 +/***********************license start***************
7364 + * Author: Cavium Networks
7365 + *
7366 + * Contact: support@caviumnetworks.com
7367 + * This file is part of the OCTEON SDK
7368 + *
7369 + * Copyright (c) 2003-2008 Cavium Networks
7370 + *
7371 + * This file is free software; you can redistribute it and/or modify
7372 + * it under the terms of the GNU General Public License, Version 2, as
7373 + * published by the Free Software Foundation.
7374 + *
7375 + * This file is distributed in the hope that it will be useful, but
7376 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7377 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7378 + * NONINFRINGEMENT. See the GNU General Public License for more
7379 + * details.
7380 + *
7381 + * You should have received a copy of the GNU General Public License
7382 + * along with this file; if not, write to the Free Software
7383 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7384 + * or visit http://www.gnu.org/licenses/.
7385 + *
7386 + * This file may also be available under a different license from Cavium.
7387 + * Contact Cavium Networks for more information
7388 + ***********************license end**************************************/
7389 +
7390 +/**
7391 + * @file
7392 + *
7393 + * Helper functions for FPA setup.
7394 + *
7395 + */
7396 +#ifndef __CVMX_HELPER_H_FPA__
7397 +#define __CVMX_HELPER_H_FPA__
7398 +
7399 +/**
7400 + * Allocate memory and initialize the FPA pools using memory
7401 + * from cvmx-bootmem. Sizes of each element in the pools is
7402 + * controlled by the cvmx-config.h header file. Specifying
7403 + * zero for any parameter will cause that FPA pool to not be
7404 + * setup. This is useful if you aren't using some of the
7405 + * hardware and want to save memory.
7406 + *
7407 + * @packet_buffers:
7408 + * Number of packet buffers to allocate
7409 + * @work_queue_entries:
7410 + * Number of work queue entries
7411 + * @pko_buffers:
7412 + * PKO Command buffers. You should at minimum have two per
7413 + * each PKO queue.
7414 + * @tim_buffers:
7415 + * TIM ring buffer command queues. At least two per timer bucket
7416 + * is recommened.
7417 + * @dfa_buffers:
7418 + * DFA command buffer. A relatively small (32 for example)
7419 + * number should work.
7420 + * Returns Zero on success, non-zero if out of memory
7421 + */
7422 +extern int cvmx_helper_initialize_fpa(int packet_buffers,
7423 + int work_queue_entries, int pko_buffers,
7424 + int tim_buffers, int dfa_buffers);
7425 +
7426 +#endif /* __CVMX_HELPER_H__ */
7427 diff --git a/drivers/staging/octeon/cvmx-helper-loop.c b/drivers/staging/octeon/cvmx-helper-loop.c
7428 new file mode 100644
7429 index 0000000..55a571a
7430 --- /dev/null
7431 +++ b/drivers/staging/octeon/cvmx-helper-loop.c
7432 @@ -0,0 +1,85 @@
7433 +/***********************license start***************
7434 + * Author: Cavium Networks
7435 + *
7436 + * Contact: support@caviumnetworks.com
7437 + * This file is part of the OCTEON SDK
7438 + *
7439 + * Copyright (c) 2003-2008 Cavium Networks
7440 + *
7441 + * This file is free software; you can redistribute it and/or modify
7442 + * it under the terms of the GNU General Public License, Version 2, as
7443 + * published by the Free Software Foundation.
7444 + *
7445 + * This file is distributed in the hope that it will be useful, but
7446 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7447 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7448 + * NONINFRINGEMENT. See the GNU General Public License for more
7449 + * details.
7450 + *
7451 + * You should have received a copy of the GNU General Public License
7452 + * along with this file; if not, write to the Free Software
7453 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7454 + * or visit http://www.gnu.org/licenses/.
7455 + *
7456 + * This file may also be available under a different license from Cavium.
7457 + * Contact Cavium Networks for more information
7458 + ***********************license end**************************************/
7459 +
7460 +/*
7461 + * Functions for LOOP initialization, configuration,
7462 + * and monitoring.
7463 + */
7464 +#include <asm/octeon/octeon.h>
7465 +
7466 +#include "cvmx-config.h"
7467 +
7468 +#include "cvmx-helper.h"
7469 +#include "cvmx-pip-defs.h"
7470 +
7471 +/**
7472 + * Probe a LOOP interface and determine the number of ports
7473 + * connected to it. The LOOP interface should still be down
7474 + * after this call.
7475 + *
7476 + * @interface: Interface to probe
7477 + *
7478 + * Returns Number of ports on the interface. Zero to disable.
7479 + */
7480 +int __cvmx_helper_loop_probe(int interface)
7481 +{
7482 + union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
7483 + int num_ports = 4;
7484 + int port;
7485 +
7486 + /* We need to disable length checking so packet < 64 bytes and jumbo
7487 + frames don't get errors */
7488 + for (port = 0; port < num_ports; port++) {
7489 + union cvmx_pip_prt_cfgx port_cfg;
7490 + int ipd_port = cvmx_helper_get_ipd_port(interface, port);
7491 + port_cfg.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
7492 + port_cfg.s.maxerr_en = 0;
7493 + port_cfg.s.minerr_en = 0;
7494 + cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_cfg.u64);
7495 + }
7496 +
7497 + /* Disable FCS stripping for loopback ports */
7498 + ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
7499 + ipd_sub_port_fcs.s.port_bit2 = 0;
7500 + cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
7501 + return num_ports;
7502 +}
7503 +
7504 +/**
7505 + * Bringup and enable a LOOP interface. After this call packet
7506 + * I/O should be fully functional. This is called with IPD
7507 + * enabled but PKO disabled.
7508 + *
7509 + * @interface: Interface to bring up
7510 + *
7511 + * Returns Zero on success, negative on failure
7512 + */
7513 +int __cvmx_helper_loop_enable(int interface)
7514 +{
7515 + /* Do nothing. */
7516 + return 0;
7517 +}
7518 diff --git a/drivers/staging/octeon/cvmx-helper-loop.h b/drivers/staging/octeon/cvmx-helper-loop.h
7519 new file mode 100644
7520 index 0000000..e646a6c
7521 --- /dev/null
7522 +++ b/drivers/staging/octeon/cvmx-helper-loop.h
7523 @@ -0,0 +1,59 @@
7524 +/***********************license start***************
7525 + * Author: Cavium Networks
7526 + *
7527 + * Contact: support@caviumnetworks.com
7528 + * This file is part of the OCTEON SDK
7529 + *
7530 + * Copyright (c) 2003-2008 Cavium Networks
7531 + *
7532 + * This file is free software; you can redistribute it and/or modify
7533 + * it under the terms of the GNU General Public License, Version 2, as published by
7534 + * the Free Software Foundation.
7535 + *
7536 + * This file is distributed in the hope that it will be useful,
7537 + * but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
7538 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
7539 + * See the GNU General Public License for more details.
7540 + *
7541 + * You should have received a copy of the GNU General Public License
7542 + * along with this file; if not, write to the Free Software
7543 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7544 + * or visit http://www.gnu.org/licenses/.
7545 + *
7546 + * This file may also be available under a different license from Cavium.
7547 + * Contact Cavium Networks for more information
7548 + ***********************license end**************************************/
7549 +
7550 +/**
7551 + * @file
7552 + *
7553 + * Functions for LOOP initialization, configuration,
7554 + * and monitoring.
7555 + *
7556 + */
7557 +#ifndef __CVMX_HELPER_LOOP_H__
7558 +#define __CVMX_HELPER_LOOP_H__
7559 +
7560 +/**
7561 + * Probe a LOOP interface and determine the number of ports
7562 + * connected to it. The LOOP interface should still be down after
7563 + * this call.
7564 + *
7565 + * @interface: Interface to probe
7566 + *
7567 + * Returns Number of ports on the interface. Zero to disable.
7568 + */
7569 +extern int __cvmx_helper_loop_probe(int interface);
7570 +
7571 +/**
7572 + * Bringup and enable a LOOP interface. After this call packet
7573 + * I/O should be fully functional. This is called with IPD
7574 + * enabled but PKO disabled.
7575 + *
7576 + * @interface: Interface to bring up
7577 + *
7578 + * Returns Zero on success, negative on failure
7579 + */
7580 +extern int __cvmx_helper_loop_enable(int interface);
7581 +
7582 +#endif
7583 diff --git a/drivers/staging/octeon/cvmx-helper-npi.c b/drivers/staging/octeon/cvmx-helper-npi.c
7584 new file mode 100644
7585 index 0000000..7388a1e
7586 --- /dev/null
7587 +++ b/drivers/staging/octeon/cvmx-helper-npi.c
7588 @@ -0,0 +1,113 @@
7589 +/***********************license start***************
7590 + * Author: Cavium Networks
7591 + *
7592 + * Contact: support@caviumnetworks.com
7593 + * This file is part of the OCTEON SDK
7594 + *
7595 + * Copyright (c) 2003-2008 Cavium Networks
7596 + *
7597 + * This file is free software; you can redistribute it and/or modify
7598 + * it under the terms of the GNU General Public License, Version 2, as
7599 + * published by the Free Software Foundation.
7600 + *
7601 + * This file is distributed in the hope that it will be useful, but
7602 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7603 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7604 + * NONINFRINGEMENT. See the GNU General Public License for more
7605 + * details.
7606 + *
7607 + * You should have received a copy of the GNU General Public License
7608 + * along with this file; if not, write to the Free Software
7609 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7610 + * or visit http://www.gnu.org/licenses/.
7611 + *
7612 + * This file may also be available under a different license from Cavium.
7613 + * Contact Cavium Networks for more information
7614 + ***********************license end**************************************/
7615 +
7616 +/*
7617 + * Functions for NPI initialization, configuration,
7618 + * and monitoring.
7619 + */
7620 +#include <asm/octeon/octeon.h>
7621 +
7622 +#include "cvmx-config.h"
7623 +
7624 +#include "cvmx-helper.h"
7625 +
7626 +#include "cvmx-pip-defs.h"
7627 +
7628 +/**
7629 + * Probe a NPI interface and determine the number of ports
7630 + * connected to it. The NPI interface should still be down
7631 + * after this call.
7632 + *
7633 + * @interface: Interface to probe
7634 + *
7635 + * Returns Number of ports on the interface. Zero to disable.
7636 + */
7637 +int __cvmx_helper_npi_probe(int interface)
7638 +{
7639 +#if CVMX_PKO_QUEUES_PER_PORT_PCI > 0
7640 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
7641 + return 4;
7642 + else if (OCTEON_IS_MODEL(OCTEON_CN56XX)
7643 + && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
7644 + /* The packet engines didn't exist before pass 2 */
7645 + return 4;
7646 + else if (OCTEON_IS_MODEL(OCTEON_CN52XX)
7647 + && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X))
7648 + /* The packet engines didn't exist before pass 2 */
7649 + return 4;
7650 +#if 0
7651 + /*
7652 + * Technically CN30XX, CN31XX, and CN50XX contain packet
7653 + * engines, but nobody ever uses them. Since this is the case,
7654 + * we disable them here.
7655 + */
7656 + else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7657 + || OCTEON_IS_MODEL(OCTEON_CN50XX))
7658 + return 2;
7659 + else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
7660 + return 1;
7661 +#endif
7662 +#endif
7663 + return 0;
7664 +}
7665 +
7666 +/**
7667 + * Bringup and enable a NPI interface. After this call packet
7668 + * I/O should be fully functional. This is called with IPD
7669 + * enabled but PKO disabled.
7670 + *
7671 + * @interface: Interface to bring up
7672 + *
7673 + * Returns Zero on success, negative on failure
7674 + */
7675 +int __cvmx_helper_npi_enable(int interface)
7676 +{
7677 + /*
7678 + * On CN50XX, CN52XX, and CN56XX we need to disable length
7679 + * checking so packet < 64 bytes and jumbo frames don't get
7680 + * errors.
7681 + */
7682 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
7683 + !OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7684 + int num_ports = cvmx_helper_ports_on_interface(interface);
7685 + int port;
7686 + for (port = 0; port < num_ports; port++) {
7687 + union cvmx_pip_prt_cfgx port_cfg;
7688 + int ipd_port =
7689 + cvmx_helper_get_ipd_port(interface, port);
7690 + port_cfg.u64 =
7691 + cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
7692 + port_cfg.s.maxerr_en = 0;
7693 + port_cfg.s.minerr_en = 0;
7694 + cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port),
7695 + port_cfg.u64);
7696 + }
7697 + }
7698 +
7699 + /* Enables are controlled by the remote host, so nothing to do here */
7700 + return 0;
7701 +}
7702 diff --git a/drivers/staging/octeon/cvmx-helper-npi.h b/drivers/staging/octeon/cvmx-helper-npi.h
7703 new file mode 100644
7704 index 0000000..908e7b0
7705 --- /dev/null
7706 +++ b/drivers/staging/octeon/cvmx-helper-npi.h
7707 @@ -0,0 +1,60 @@
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 + * @file
7737 + *
7738 + * Functions for NPI initialization, configuration,
7739 + * and monitoring.
7740 + *
7741 + */
7742 +#ifndef __CVMX_HELPER_NPI_H__
7743 +#define __CVMX_HELPER_NPI_H__
7744 +
7745 +/**
7746 + * Probe a NPI interface and determine the number of ports
7747 + * connected to it. The NPI interface should still be down after
7748 + * this call.
7749 + *
7750 + * @interface: Interface to probe
7751 + *
7752 + * Returns Number of ports on the interface. Zero to disable.
7753 + */
7754 +extern int __cvmx_helper_npi_probe(int interface);
7755 +
7756 +/**
7757 + * Bringup and enable a NPI interface. After this call packet
7758 + * I/O should be fully functional. This is called with IPD
7759 + * enabled but PKO disabled.
7760 + *
7761 + * @interface: Interface to bring up
7762 + *
7763 + * Returns Zero on success, negative on failure
7764 + */
7765 +extern int __cvmx_helper_npi_enable(int interface);
7766 +
7767 +#endif
7768 diff --git a/drivers/staging/octeon/cvmx-helper-rgmii.c b/drivers/staging/octeon/cvmx-helper-rgmii.c
7769 new file mode 100644
7770 index 0000000..aa2d5d7
7771 --- /dev/null
7772 +++ b/drivers/staging/octeon/cvmx-helper-rgmii.c
7773 @@ -0,0 +1,525 @@
7774 +/***********************license start***************
7775 + * Author: Cavium Networks
7776 + *
7777 + * Contact: support@caviumnetworks.com
7778 + * This file is part of the OCTEON SDK
7779 + *
7780 + * Copyright (c) 2003-2008 Cavium Networks
7781 + *
7782 + * This file is free software; you can redistribute it and/or modify
7783 + * it under the terms of the GNU General Public License, Version 2, as
7784 + * published by the Free Software Foundation.
7785 + *
7786 + * This file is distributed in the hope that it will be useful, but
7787 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
7788 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7789 + * NONINFRINGEMENT. See the GNU General Public License for more
7790 + * details.
7791 + *
7792 + * You should have received a copy of the GNU General Public License
7793 + * along with this file; if not, write to the Free Software
7794 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7795 + * or visit http://www.gnu.org/licenses/.
7796 + *
7797 + * This file may also be available under a different license from Cavium.
7798 + * Contact Cavium Networks for more information
7799 + ***********************license end**************************************/
7800 +
7801 +/*
7802 + * Functions for RGMII/GMII/MII initialization, configuration,
7803 + * and monitoring.
7804 + */
7805 +#include <asm/octeon/octeon.h>
7806 +
7807 +#include "cvmx-config.h"
7808 +
7809 +
7810 +#include "cvmx-mdio.h"
7811 +#include "cvmx-pko.h"
7812 +#include "cvmx-helper.h"
7813 +#include "cvmx-helper-board.h"
7814 +
7815 +#include <asm/octeon/cvmx-npi-defs.h>
7816 +#include "cvmx-gmxx-defs.h"
7817 +#include "cvmx-asxx-defs.h"
7818 +#include "cvmx-dbg-defs.h"
7819 +
7820 +void __cvmx_interrupt_gmxx_enable(int interface);
7821 +void __cvmx_interrupt_asxx_enable(int block);
7822 +
7823 +/**
7824 + * Probe RGMII ports and determine the number present
7825 + *
7826 + * @interface: Interface to probe
7827 + *
7828 + * Returns Number of RGMII/GMII/MII ports (0-4).
7829 + */
7830 +int __cvmx_helper_rgmii_probe(int interface)
7831 +{
7832 + int num_ports = 0;
7833 + union cvmx_gmxx_inf_mode mode;
7834 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
7835 +
7836 + if (mode.s.type) {
7837 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
7838 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7839 + cvmx_dprintf("ERROR: RGMII initialize called in "
7840 + "SPI interface\n");
7841 + } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7842 + || OCTEON_IS_MODEL(OCTEON_CN30XX)
7843 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7844 + /*
7845 + * On these chips "type" says we're in
7846 + * GMII/MII mode. This limits us to 2 ports
7847 + */
7848 + num_ports = 2;
7849 + } else {
7850 + cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
7851 + __func__);
7852 + }
7853 + } else {
7854 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
7855 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
7856 + num_ports = 4;
7857 + } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
7858 + || OCTEON_IS_MODEL(OCTEON_CN30XX)
7859 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
7860 + num_ports = 3;
7861 + } else {
7862 + cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
7863 + __func__);
7864 + }
7865 + }
7866 + return num_ports;
7867 +}
7868 +
7869 +/**
7870 + * Put an RGMII interface in loopback mode. Internal packets sent
7871 + * out will be received back again on the same port. Externally
7872 + * received packets will echo back out.
7873 + *
7874 + * @port: IPD port number to loop.
7875 + */
7876 +void cvmx_helper_rgmii_internal_loopback(int port)
7877 +{
7878 + int interface = (port >> 4) & 1;
7879 + int index = port & 0xf;
7880 + uint64_t tmp;
7881 +
7882 + union cvmx_gmxx_prtx_cfg gmx_cfg;
7883 + gmx_cfg.u64 = 0;
7884 + gmx_cfg.s.duplex = 1;
7885 + gmx_cfg.s.slottime = 1;
7886 + gmx_cfg.s.speed = 1;
7887 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
7888 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
7889 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
7890 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
7891 + tmp = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
7892 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), (1 << index) | tmp);
7893 + tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface));
7894 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), (1 << index) | tmp);
7895 + tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface));
7896 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), (1 << index) | tmp);
7897 + gmx_cfg.s.en = 1;
7898 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
7899 +}
7900 +
7901 +/**
7902 + * Workaround ASX setup errata with CN38XX pass1
7903 + *
7904 + * @interface: Interface to setup
7905 + * @port: Port to setup (0..3)
7906 + * @cpu_clock_hz:
7907 + * Chip frequency in Hertz
7908 + *
7909 + * Returns Zero on success, negative on failure
7910 + */
7911 +static int __cvmx_helper_errata_asx_pass1(int interface, int port,
7912 + int cpu_clock_hz)
7913 +{
7914 + /* Set hi water mark as per errata GMX-4 */
7915 + if (cpu_clock_hz >= 325000000 && cpu_clock_hz < 375000000)
7916 + cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 12);
7917 + else if (cpu_clock_hz >= 375000000 && cpu_clock_hz < 437000000)
7918 + cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 11);
7919 + else if (cpu_clock_hz >= 437000000 && cpu_clock_hz < 550000000)
7920 + cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 10);
7921 + else if (cpu_clock_hz >= 550000000 && cpu_clock_hz < 687000000)
7922 + cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 9);
7923 + else
7924 + cvmx_dprintf("Illegal clock frequency (%d). "
7925 + "CVMX_ASXX_TX_HI_WATERX not set\n", cpu_clock_hz);
7926 + return 0;
7927 +}
7928 +
7929 +/**
7930 + * Configure all of the ASX, GMX, and PKO regsiters required
7931 + * to get RGMII to function on the supplied interface.
7932 + *
7933 + * @interface: PKO Interface to configure (0 or 1)
7934 + *
7935 + * Returns Zero on success
7936 + */
7937 +int __cvmx_helper_rgmii_enable(int interface)
7938 +{
7939 + int num_ports = cvmx_helper_ports_on_interface(interface);
7940 + int port;
7941 + struct cvmx_sysinfo *sys_info_ptr = cvmx_sysinfo_get();
7942 + union cvmx_gmxx_inf_mode mode;
7943 + union cvmx_asxx_tx_prt_en asx_tx;
7944 + union cvmx_asxx_rx_prt_en asx_rx;
7945 +
7946 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
7947 +
7948 + if (mode.s.en == 0)
7949 + return -1;
7950 + if ((OCTEON_IS_MODEL(OCTEON_CN38XX) ||
7951 + OCTEON_IS_MODEL(OCTEON_CN58XX)) && mode.s.type == 1)
7952 + /* Ignore SPI interfaces */
7953 + return -1;
7954 +
7955 + /* Configure the ASX registers needed to use the RGMII ports */
7956 + asx_tx.u64 = 0;
7957 + asx_tx.s.prt_en = cvmx_build_mask(num_ports);
7958 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), asx_tx.u64);
7959 +
7960 + asx_rx.u64 = 0;
7961 + asx_rx.s.prt_en = cvmx_build_mask(num_ports);
7962 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), asx_rx.u64);
7963 +
7964 + /* Configure the GMX registers needed to use the RGMII ports */
7965 + for (port = 0; port < num_ports; port++) {
7966 + /* Setting of CVMX_GMXX_TXX_THRESH has been moved to
7967 + __cvmx_helper_setup_gmx() */
7968 +
7969 + if (cvmx_octeon_is_pass1())
7970 + __cvmx_helper_errata_asx_pass1(interface, port,
7971 + sys_info_ptr->
7972 + cpu_clock_hz);
7973 + else {
7974 + /*
7975 + * Configure more flexible RGMII preamble
7976 + * checking. Pass 1 doesn't support this
7977 + * feature.
7978 + */
7979 + union cvmx_gmxx_rxx_frm_ctl frm_ctl;
7980 + frm_ctl.u64 =
7981 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
7982 + (port, interface));
7983 + /* New field, so must be compile time */
7984 + frm_ctl.s.pre_free = 1;
7985 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(port, interface),
7986 + frm_ctl.u64);
7987 + }
7988 +
7989 + /*
7990 + * Each pause frame transmitted will ask for about 10M
7991 + * bit times before resume. If buffer space comes
7992 + * available before that time has expired, an XON
7993 + * pause frame (0 time) will be transmitted to restart
7994 + * the flow.
7995 + */
7996 + cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_TIME(port, interface),
7997 + 20000);
7998 + cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL
7999 + (port, interface), 19000);
8000 +
8001 + if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
8002 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
8003 + 16);
8004 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
8005 + 16);
8006 + } else {
8007 + cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
8008 + 24);
8009 + cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
8010 + 24);
8011 + }
8012 + }
8013 +
8014 + __cvmx_helper_setup_gmx(interface, num_ports);
8015 +
8016 + /* enable the ports now */
8017 + for (port = 0; port < num_ports; port++) {
8018 + union cvmx_gmxx_prtx_cfg gmx_cfg;
8019 + cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port
8020 + (interface, port));
8021 + gmx_cfg.u64 =
8022 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(port, interface));
8023 + gmx_cfg.s.en = 1;
8024 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(port, interface),
8025 + gmx_cfg.u64);
8026 + }
8027 + __cvmx_interrupt_asxx_enable(interface);
8028 + __cvmx_interrupt_gmxx_enable(interface);
8029 +
8030 + return 0;
8031 +}
8032 +
8033 +/**
8034 + * Return the link state of an IPD/PKO port as returned by
8035 + * auto negotiation. The result of this function may not match
8036 + * Octeon's link config if auto negotiation has changed since
8037 + * the last call to cvmx_helper_link_set().
8038 + *
8039 + * @ipd_port: IPD/PKO port to query
8040 + *
8041 + * Returns Link state
8042 + */
8043 +cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port)
8044 +{
8045 + int interface = cvmx_helper_get_interface_num(ipd_port);
8046 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8047 + union cvmx_asxx_prt_loop asxx_prt_loop;
8048 +
8049 + asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
8050 + if (asxx_prt_loop.s.int_loop & (1 << index)) {
8051 + /* Force 1Gbps full duplex on internal loopback */
8052 + cvmx_helper_link_info_t result;
8053 + result.u64 = 0;
8054 + result.s.full_duplex = 1;
8055 + result.s.link_up = 1;
8056 + result.s.speed = 1000;
8057 + return result;
8058 + } else
8059 + return __cvmx_helper_board_link_get(ipd_port);
8060 +}
8061 +
8062 +/**
8063 + * Configure an IPD/PKO port for the specified link state. This
8064 + * function does not influence auto negotiation at the PHY level.
8065 + * The passed link state must always match the link state returned
8066 + * by cvmx_helper_link_get(). It is normally best to use
8067 + * cvmx_helper_link_autoconf() instead.
8068 + *
8069 + * @ipd_port: IPD/PKO port to configure
8070 + * @link_info: The new link state
8071 + *
8072 + * Returns Zero on success, negative on failure
8073 + */
8074 +int __cvmx_helper_rgmii_link_set(int ipd_port,
8075 + cvmx_helper_link_info_t link_info)
8076 +{
8077 + int result = 0;
8078 + int interface = cvmx_helper_get_interface_num(ipd_port);
8079 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8080 + union cvmx_gmxx_prtx_cfg original_gmx_cfg;
8081 + union cvmx_gmxx_prtx_cfg new_gmx_cfg;
8082 + union cvmx_pko_mem_queue_qos pko_mem_queue_qos;
8083 + union cvmx_pko_mem_queue_qos pko_mem_queue_qos_save[16];
8084 + union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp;
8085 + union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp_save;
8086 + int i;
8087 +
8088 + /* Ignore speed sets in the simulator */
8089 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
8090 + return 0;
8091 +
8092 + /* Read the current settings so we know the current enable state */
8093 + original_gmx_cfg.u64 =
8094 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8095 + new_gmx_cfg = original_gmx_cfg;
8096 +
8097 + /* Disable the lowest level RX */
8098 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8099 + cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) &
8100 + ~(1 << index));
8101 +
8102 + /* Disable all queues so that TX should become idle */
8103 + for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
8104 + int queue = cvmx_pko_get_base_queue(ipd_port) + i;
8105 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue);
8106 + pko_mem_queue_qos.u64 = cvmx_read_csr(CVMX_PKO_MEM_QUEUE_QOS);
8107 + pko_mem_queue_qos.s.pid = ipd_port;
8108 + pko_mem_queue_qos.s.qid = queue;
8109 + pko_mem_queue_qos_save[i] = pko_mem_queue_qos;
8110 + pko_mem_queue_qos.s.qos_mask = 0;
8111 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS, pko_mem_queue_qos.u64);
8112 + }
8113 +
8114 + /* Disable backpressure */
8115 + gmx_tx_ovr_bp.u64 = cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface));
8116 + gmx_tx_ovr_bp_save = gmx_tx_ovr_bp;
8117 + gmx_tx_ovr_bp.s.bp &= ~(1 << index);
8118 + gmx_tx_ovr_bp.s.en |= 1 << index;
8119 + cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp.u64);
8120 + cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface));
8121 +
8122 + /*
8123 + * Poll the GMX state machine waiting for it to become
8124 + * idle. Preferably we should only change speed when it is
8125 + * idle. If it doesn't become idle we will still do the speed
8126 + * change, but there is a slight chance that GMX will
8127 + * lockup.
8128 + */
8129 + cvmx_write_csr(CVMX_NPI_DBG_SELECT,
8130 + interface * 0x800 + index * 0x100 + 0x880);
8131 + CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 7,
8132 + ==, 0, 10000);
8133 + CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 0xf,
8134 + ==, 0, 10000);
8135 +
8136 + /* Disable the port before we make any changes */
8137 + new_gmx_cfg.s.en = 0;
8138 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8139 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8140 +
8141 + /* Set full/half duplex */
8142 + if (cvmx_octeon_is_pass1())
8143 + /* Half duplex is broken for 38XX Pass 1 */
8144 + new_gmx_cfg.s.duplex = 1;
8145 + else if (!link_info.s.link_up)
8146 + /* Force full duplex on down links */
8147 + new_gmx_cfg.s.duplex = 1;
8148 + else
8149 + new_gmx_cfg.s.duplex = link_info.s.full_duplex;
8150 +
8151 + /* Set the link speed. Anything unknown is set to 1Gbps */
8152 + if (link_info.s.speed == 10) {
8153 + new_gmx_cfg.s.slottime = 0;
8154 + new_gmx_cfg.s.speed = 0;
8155 + } else if (link_info.s.speed == 100) {
8156 + new_gmx_cfg.s.slottime = 0;
8157 + new_gmx_cfg.s.speed = 0;
8158 + } else {
8159 + new_gmx_cfg.s.slottime = 1;
8160 + new_gmx_cfg.s.speed = 1;
8161 + }
8162 +
8163 + /* Adjust the clocks */
8164 + if (link_info.s.speed == 10) {
8165 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 50);
8166 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40);
8167 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8168 + } else if (link_info.s.speed == 100) {
8169 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 5);
8170 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40);
8171 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8172 + } else {
8173 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
8174 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
8175 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
8176 + }
8177 +
8178 + if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
8179 + if ((link_info.s.speed == 10) || (link_info.s.speed == 100)) {
8180 + union cvmx_gmxx_inf_mode mode;
8181 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
8182 +
8183 + /*
8184 + * Port .en .type .p0mii Configuration
8185 + * ---- --- ----- ------ -----------------------------------------
8186 + * X 0 X X All links are disabled.
8187 + * 0 1 X 0 Port 0 is RGMII
8188 + * 0 1 X 1 Port 0 is MII
8189 + * 1 1 0 X Ports 1 and 2 are configured as RGMII ports.
8190 + * 1 1 1 X Port 1: GMII/MII; Port 2: disabled. GMII or
8191 + * MII port is selected by GMX_PRT1_CFG[SPEED].
8192 + */
8193 +
8194 + /* In MII mode, CLK_CNT = 1. */
8195 + if (((index == 0) && (mode.s.p0mii == 1))
8196 + || ((index != 0) && (mode.s.type == 1))) {
8197 + cvmx_write_csr(CVMX_GMXX_TXX_CLK
8198 + (index, interface), 1);
8199 + }
8200 + }
8201 + }
8202 +
8203 + /* Do a read to make sure all setup stuff is complete */
8204 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8205 +
8206 + /* Save the new GMX setting without enabling the port */
8207 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8208 +
8209 + /* Enable the lowest level RX */
8210 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8211 + cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) | (1 <<
8212 + index));
8213 +
8214 + /* Re-enable the TX path */
8215 + for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
8216 + int queue = cvmx_pko_get_base_queue(ipd_port) + i;
8217 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue);
8218 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS,
8219 + pko_mem_queue_qos_save[i].u64);
8220 + }
8221 +
8222 + /* Restore backpressure */
8223 + cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp_save.u64);
8224 +
8225 + /* Restore the GMX enable state. Port config is complete */
8226 + new_gmx_cfg.s.en = original_gmx_cfg.s.en;
8227 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
8228 +
8229 + return result;
8230 +}
8231 +
8232 +/**
8233 + * Configure a port for internal and/or external loopback. Internal loopback
8234 + * causes packets sent by the port to be received by Octeon. External loopback
8235 + * causes packets received from the wire to sent out again.
8236 + *
8237 + * @ipd_port: IPD/PKO port to loopback.
8238 + * @enable_internal:
8239 + * Non zero if you want internal loopback
8240 + * @enable_external:
8241 + * Non zero if you want external loopback
8242 + *
8243 + * Returns Zero on success, negative on failure.
8244 + */
8245 +int __cvmx_helper_rgmii_configure_loopback(int ipd_port, int enable_internal,
8246 + int enable_external)
8247 +{
8248 + int interface = cvmx_helper_get_interface_num(ipd_port);
8249 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8250 + int original_enable;
8251 + union cvmx_gmxx_prtx_cfg gmx_cfg;
8252 + union cvmx_asxx_prt_loop asxx_prt_loop;
8253 +
8254 + /* Read the current enable state and save it */
8255 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8256 + original_enable = gmx_cfg.s.en;
8257 + /* Force port to be disabled */
8258 + gmx_cfg.s.en = 0;
8259 + if (enable_internal) {
8260 + /* Force speed if we're doing internal loopback */
8261 + gmx_cfg.s.duplex = 1;
8262 + gmx_cfg.s.slottime = 1;
8263 + gmx_cfg.s.speed = 1;
8264 + cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
8265 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
8266 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
8267 + }
8268 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
8269 +
8270 + /* Set the loopback bits */
8271 + asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
8272 + if (enable_internal)
8273 + asxx_prt_loop.s.int_loop |= 1 << index;
8274 + else
8275 + asxx_prt_loop.s.int_loop &= ~(1 << index);
8276 + if (enable_external)
8277 + asxx_prt_loop.s.ext_loop |= 1 << index;
8278 + else
8279 + asxx_prt_loop.s.ext_loop &= ~(1 << index);
8280 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), asxx_prt_loop.u64);
8281 +
8282 + /* Force enables in internal loopback */
8283 + if (enable_internal) {
8284 + uint64_t tmp;
8285 + tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface));
8286 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface),
8287 + (1 << index) | tmp);
8288 + tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface));
8289 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
8290 + (1 << index) | tmp);
8291 + original_enable = 1;
8292 + }
8293 +
8294 + /* Restore the enable state */
8295 + gmx_cfg.s.en = original_enable;
8296 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
8297 + return 0;
8298 +}
8299 diff --git a/drivers/staging/octeon/cvmx-helper-rgmii.h b/drivers/staging/octeon/cvmx-helper-rgmii.h
8300 new file mode 100644
8301 index 0000000..ea26526
8302 --- /dev/null
8303 +++ b/drivers/staging/octeon/cvmx-helper-rgmii.h
8304 @@ -0,0 +1,110 @@
8305 +/***********************license start***************
8306 + * Author: Cavium Networks
8307 + *
8308 + * Contact: support@caviumnetworks.com
8309 + * This file is part of the OCTEON SDK
8310 + *
8311 + * Copyright (c) 2003-2008 Cavium Networks
8312 + *
8313 + * This file is free software; you can redistribute it and/or modify
8314 + * it under the terms of the GNU General Public License, Version 2, as
8315 + * published by the Free Software Foundation.
8316 + *
8317 + * This file is distributed in the hope that it will be useful, but
8318 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8319 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8320 + * NONINFRINGEMENT. See the GNU General Public License for more
8321 + * details.
8322 + *
8323 + * You should have received a copy of the GNU General Public License
8324 + * along with this file; if not, write to the Free Software
8325 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8326 + * or visit http://www.gnu.org/licenses/.
8327 + *
8328 + * This file may also be available under a different license from Cavium.
8329 + * Contact Cavium Networks for more information
8330 + ***********************license end**************************************/
8331 +
8332 +/**
8333 + * @file
8334 + *
8335 + * Functions for RGMII/GMII/MII initialization, configuration,
8336 + * and monitoring.
8337 + *
8338 + */
8339 +#ifndef __CVMX_HELPER_RGMII_H__
8340 +#define __CVMX_HELPER_RGMII_H__
8341 +
8342 +/**
8343 + * Probe RGMII ports and determine the number present
8344 + *
8345 + * @interface: Interface to probe
8346 + *
8347 + * Returns Number of RGMII/GMII/MII ports (0-4).
8348 + */
8349 +extern int __cvmx_helper_rgmii_probe(int interface);
8350 +
8351 +/**
8352 + * Put an RGMII interface in loopback mode. Internal packets sent
8353 + * out will be received back again on the same port. Externally
8354 + * received packets will echo back out.
8355 + *
8356 + * @port: IPD port number to loop.
8357 + */
8358 +extern void cvmx_helper_rgmii_internal_loopback(int port);
8359 +
8360 +/**
8361 + * Configure all of the ASX, GMX, and PKO regsiters required
8362 + * to get RGMII to function on the supplied interface.
8363 + *
8364 + * @interface: PKO Interface to configure (0 or 1)
8365 + *
8366 + * Returns Zero on success
8367 + */
8368 +extern int __cvmx_helper_rgmii_enable(int interface);
8369 +
8370 +/**
8371 + * Return the link state of an IPD/PKO port as returned by
8372 + * auto negotiation. The result of this function may not match
8373 + * Octeon's link config if auto negotiation has changed since
8374 + * the last call to cvmx_helper_link_set().
8375 + *
8376 + * @ipd_port: IPD/PKO port to query
8377 + *
8378 + * Returns Link state
8379 + */
8380 +extern cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port);
8381 +
8382 +/**
8383 + * Configure an IPD/PKO port for the specified link state. This
8384 + * function does not influence auto negotiation at the PHY level.
8385 + * The passed link state must always match the link state returned
8386 + * by cvmx_helper_link_get(). It is normally best to use
8387 + * cvmx_helper_link_autoconf() instead.
8388 + *
8389 + * @ipd_port: IPD/PKO port to configure
8390 + * @link_info: The new link state
8391 + *
8392 + * Returns Zero on success, negative on failure
8393 + */
8394 +extern int __cvmx_helper_rgmii_link_set(int ipd_port,
8395 + cvmx_helper_link_info_t link_info);
8396 +
8397 +/**
8398 + * Configure a port for internal and/or external loopback. Internal loopback
8399 + * causes packets sent by the port to be received by Octeon. External loopback
8400 + * causes packets received from the wire to sent out again.
8401 + *
8402 + * @ipd_port: IPD/PKO port to loopback.
8403 + * @enable_internal:
8404 + * Non zero if you want internal loopback
8405 + * @enable_external:
8406 + * Non zero if you want external loopback
8407 + *
8408 + * Returns Zero on success, negative on failure.
8409 + */
8410 +extern int __cvmx_helper_rgmii_configure_loopback(int ipd_port,
8411 + int enable_internal,
8412 + int enable_external);
8413 +
8414 +#endif
8415 diff --git a/drivers/staging/octeon/cvmx-helper-sgmii.c b/drivers/staging/octeon/cvmx-helper-sgmii.c
8416 new file mode 100644
8417 index 0000000..6214e3b
8418 --- /dev/null
8419 +++ b/drivers/staging/octeon/cvmx-helper-sgmii.c
8420 @@ -0,0 +1,550 @@
8421 +/***********************license start***************
8422 + * Author: Cavium Networks
8423 + *
8424 + * Contact: support@caviumnetworks.com
8425 + * This file is part of the OCTEON SDK
8426 + *
8427 + * Copyright (c) 2003-2008 Cavium Networks
8428 + *
8429 + * This file is free software; you can redistribute it and/or modify
8430 + * it under the terms of the GNU General Public License, Version 2, as
8431 + * published by the Free Software Foundation.
8432 + *
8433 + * This file is distributed in the hope that it will be useful, but
8434 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8435 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8436 + * NONINFRINGEMENT. See the GNU General Public License for more
8437 + * details.
8438 + *
8439 + * You should have received a copy of the GNU General Public License
8440 + * along with this file; if not, write to the Free Software
8441 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8442 + * or visit http://www.gnu.org/licenses/.
8443 + *
8444 + * This file may also be available under a different license from Cavium.
8445 + * Contact Cavium Networks for more information
8446 + ***********************license end**************************************/
8447 +
8448 +/*
8449 + * Functions for SGMII initialization, configuration,
8450 + * and monitoring.
8451 + */
8452 +
8453 +#include <asm/octeon/octeon.h>
8454 +
8455 +#include "cvmx-config.h"
8456 +
8457 +#include "cvmx-mdio.h"
8458 +#include "cvmx-helper.h"
8459 +#include "cvmx-helper-board.h"
8460 +
8461 +#include "cvmx-gmxx-defs.h"
8462 +#include "cvmx-pcsx-defs.h"
8463 +
8464 +void __cvmx_interrupt_gmxx_enable(int interface);
8465 +void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
8466 +void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
8467 +
8468 +/**
8469 + * Perform initialization required only once for an SGMII port.
8470 + *
8471 + * @interface: Interface to init
8472 + * @index: Index of prot on the interface
8473 + *
8474 + * Returns Zero on success, negative on failure
8475 + */
8476 +static int __cvmx_helper_sgmii_hardware_init_one_time(int interface, int index)
8477 +{
8478 + const uint64_t clock_mhz = cvmx_sysinfo_get()->cpu_clock_hz / 1000000;
8479 + union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
8480 + union cvmx_pcsx_linkx_timer_count_reg pcsx_linkx_timer_count_reg;
8481 + union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8482 +
8483 + /* Disable GMX */
8484 + gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8485 + gmxx_prtx_cfg.s.en = 0;
8486 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8487 +
8488 + /*
8489 + * Write PCS*_LINK*_TIMER_COUNT_REG[COUNT] with the
8490 + * appropriate value. 1000BASE-X specifies a 10ms
8491 + * interval. SGMII specifies a 1.6ms interval.
8492 + */
8493 + pcs_misc_ctl_reg.u64 =
8494 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8495 + pcsx_linkx_timer_count_reg.u64 =
8496 + cvmx_read_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface));
8497 + if (pcs_misc_ctl_reg.s.mode) {
8498 + /* 1000BASE-X */
8499 + pcsx_linkx_timer_count_reg.s.count =
8500 + (10000ull * clock_mhz) >> 10;
8501 + } else {
8502 + /* SGMII */
8503 + pcsx_linkx_timer_count_reg.s.count =
8504 + (1600ull * clock_mhz) >> 10;
8505 + }
8506 + cvmx_write_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface),
8507 + pcsx_linkx_timer_count_reg.u64);
8508 +
8509 + /*
8510 + * Write the advertisement register to be used as the
8511 + * tx_Config_Reg<D15:D0> of the autonegotiation. In
8512 + * 1000BASE-X mode, tx_Config_Reg<D15:D0> is PCS*_AN*_ADV_REG.
8513 + * In SGMII PHY mode, tx_Config_Reg<D15:D0> is
8514 + * PCS*_SGM*_AN_ADV_REG. In SGMII MAC mode,
8515 + * tx_Config_Reg<D15:D0> is the fixed value 0x4001, so this
8516 + * step can be skipped.
8517 + */
8518 + if (pcs_misc_ctl_reg.s.mode) {
8519 + /* 1000BASE-X */
8520 + union cvmx_pcsx_anx_adv_reg pcsx_anx_adv_reg;
8521 + pcsx_anx_adv_reg.u64 =
8522 + cvmx_read_csr(CVMX_PCSX_ANX_ADV_REG(index, interface));
8523 + pcsx_anx_adv_reg.s.rem_flt = 0;
8524 + pcsx_anx_adv_reg.s.pause = 3;
8525 + pcsx_anx_adv_reg.s.hfd = 1;
8526 + pcsx_anx_adv_reg.s.fd = 1;
8527 + cvmx_write_csr(CVMX_PCSX_ANX_ADV_REG(index, interface),
8528 + pcsx_anx_adv_reg.u64);
8529 + } else {
8530 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8531 + pcsx_miscx_ctl_reg.u64 =
8532 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8533 + if (pcsx_miscx_ctl_reg.s.mac_phy) {
8534 + /* PHY Mode */
8535 + union cvmx_pcsx_sgmx_an_adv_reg pcsx_sgmx_an_adv_reg;
8536 + pcsx_sgmx_an_adv_reg.u64 =
8537 + cvmx_read_csr(CVMX_PCSX_SGMX_AN_ADV_REG
8538 + (index, interface));
8539 + pcsx_sgmx_an_adv_reg.s.link = 1;
8540 + pcsx_sgmx_an_adv_reg.s.dup = 1;
8541 + pcsx_sgmx_an_adv_reg.s.speed = 2;
8542 + cvmx_write_csr(CVMX_PCSX_SGMX_AN_ADV_REG
8543 + (index, interface),
8544 + pcsx_sgmx_an_adv_reg.u64);
8545 + } else {
8546 + /* MAC Mode - Nothing to do */
8547 + }
8548 + }
8549 + return 0;
8550 +}
8551 +
8552 +/**
8553 + * Initialize the SERTES link for the first time or after a loss
8554 + * of link.
8555 + *
8556 + * @interface: Interface to init
8557 + * @index: Index of prot on the interface
8558 + *
8559 + * Returns Zero on success, negative on failure
8560 + */
8561 +static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index)
8562 +{
8563 + union cvmx_pcsx_mrx_control_reg control_reg;
8564 +
8565 + /*
8566 + * Take PCS through a reset sequence.
8567 + * PCS*_MR*_CONTROL_REG[PWR_DN] should be cleared to zero.
8568 + * Write PCS*_MR*_CONTROL_REG[RESET]=1 (while not changing the
8569 + * value of the other PCS*_MR*_CONTROL_REG bits). Read
8570 + * PCS*_MR*_CONTROL_REG[RESET] until it changes value to
8571 + * zero.
8572 + */
8573 + control_reg.u64 =
8574 + cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8575 + if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
8576 + control_reg.s.reset = 1;
8577 + cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8578 + control_reg.u64);
8579 + if (CVMX_WAIT_FOR_FIELD64
8580 + (CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8581 + union cvmx_pcsx_mrx_control_reg, reset, ==, 0, 10000)) {
8582 + cvmx_dprintf("SGMII%d: Timeout waiting for port %d "
8583 + "to finish reset\n",
8584 + interface, index);
8585 + return -1;
8586 + }
8587 + }
8588 +
8589 + /*
8590 + * Write PCS*_MR*_CONTROL_REG[RST_AN]=1 to ensure a fresh
8591 + * sgmii negotiation starts.
8592 + */
8593 + control_reg.s.rst_an = 1;
8594 + control_reg.s.an_en = 1;
8595 + control_reg.s.pwr_dn = 0;
8596 + cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8597 + control_reg.u64);
8598 +
8599 + /*
8600 + * Wait for PCS*_MR*_STATUS_REG[AN_CPT] to be set, indicating
8601 + * that sgmii autonegotiation is complete. In MAC mode this
8602 + * isn't an ethernet link, but a link between Octeon and the
8603 + * PHY.
8604 + */
8605 + if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
8606 + CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_STATUS_REG(index, interface),
8607 + union cvmx_pcsx_mrx_status_reg, an_cpt, ==, 1,
8608 + 10000)) {
8609 + /* cvmx_dprintf("SGMII%d: Port %d link timeout\n", interface, index); */
8610 + return -1;
8611 + }
8612 + return 0;
8613 +}
8614 +
8615 +/**
8616 + * Configure an SGMII link to the specified speed after the SERTES
8617 + * link is up.
8618 + *
8619 + * @interface: Interface to init
8620 + * @index: Index of prot on the interface
8621 + * @link_info: Link state to configure
8622 + *
8623 + * Returns Zero on success, negative on failure
8624 + */
8625 +static int __cvmx_helper_sgmii_hardware_init_link_speed(int interface,
8626 + int index,
8627 + cvmx_helper_link_info_t
8628 + link_info)
8629 +{
8630 + int is_enabled;
8631 + union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8632 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8633 +
8634 + /* Disable GMX before we make any changes. Remember the enable state */
8635 + gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8636 + is_enabled = gmxx_prtx_cfg.s.en;
8637 + gmxx_prtx_cfg.s.en = 0;
8638 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8639 +
8640 + /* Wait for GMX to be idle */
8641 + if (CVMX_WAIT_FOR_FIELD64
8642 + (CVMX_GMXX_PRTX_CFG(index, interface), union cvmx_gmxx_prtx_cfg,
8643 + rx_idle, ==, 1, 10000)
8644 + || CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface),
8645 + union cvmx_gmxx_prtx_cfg, tx_idle, ==, 1,
8646 + 10000)) {
8647 + cvmx_dprintf
8648 + ("SGMII%d: Timeout waiting for port %d to be idle\n",
8649 + interface, index);
8650 + return -1;
8651 + }
8652 +
8653 + /* Read GMX CFG again to make sure the disable completed */
8654 + gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8655 +
8656 + /*
8657 + * Get the misc control for PCS. We will need to set the
8658 + * duplication amount.
8659 + */
8660 + pcsx_miscx_ctl_reg.u64 =
8661 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8662 +
8663 + /*
8664 + * Use GMXENO to force the link down if the status we get says
8665 + * it should be down.
8666 + */
8667 + pcsx_miscx_ctl_reg.s.gmxeno = !link_info.s.link_up;
8668 +
8669 + /* Only change the duplex setting if the link is up */
8670 + if (link_info.s.link_up)
8671 + gmxx_prtx_cfg.s.duplex = link_info.s.full_duplex;
8672 +
8673 + /* Do speed based setting for GMX */
8674 + switch (link_info.s.speed) {
8675 + case 10:
8676 + gmxx_prtx_cfg.s.speed = 0;
8677 + gmxx_prtx_cfg.s.speed_msb = 1;
8678 + gmxx_prtx_cfg.s.slottime = 0;
8679 + /* Setting from GMX-603 */
8680 + pcsx_miscx_ctl_reg.s.samp_pt = 25;
8681 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
8682 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8683 + break;
8684 + case 100:
8685 + gmxx_prtx_cfg.s.speed = 0;
8686 + gmxx_prtx_cfg.s.speed_msb = 0;
8687 + gmxx_prtx_cfg.s.slottime = 0;
8688 + pcsx_miscx_ctl_reg.s.samp_pt = 0x5;
8689 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
8690 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
8691 + break;
8692 + case 1000:
8693 + gmxx_prtx_cfg.s.speed = 1;
8694 + gmxx_prtx_cfg.s.speed_msb = 0;
8695 + gmxx_prtx_cfg.s.slottime = 1;
8696 + pcsx_miscx_ctl_reg.s.samp_pt = 1;
8697 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 512);
8698 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 8192);
8699 + break;
8700 + default:
8701 + break;
8702 + }
8703 +
8704 + /* Write the new misc control for PCS */
8705 + cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
8706 + pcsx_miscx_ctl_reg.u64);
8707 +
8708 + /* Write the new GMX settings with the port still disabled */
8709 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8710 +
8711 + /* Read GMX CFG again to make sure the config completed */
8712 + gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8713 +
8714 + /* Restore the enabled / disabled state */
8715 + gmxx_prtx_cfg.s.en = is_enabled;
8716 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
8717 +
8718 + return 0;
8719 +}
8720 +
8721 +/**
8722 + * Bring up the SGMII interface to be ready for packet I/O but
8723 + * leave I/O disabled using the GMX override. This function
8724 + * follows the bringup documented in 10.6.3 of the manual.
8725 + *
8726 + * @interface: Interface to bringup
8727 + * @num_ports: Number of ports on the interface
8728 + *
8729 + * Returns Zero on success, negative on failure
8730 + */
8731 +static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
8732 +{
8733 + int index;
8734 +
8735 + __cvmx_helper_setup_gmx(interface, num_ports);
8736 +
8737 + for (index = 0; index < num_ports; index++) {
8738 + int ipd_port = cvmx_helper_get_ipd_port(interface, index);
8739 + __cvmx_helper_sgmii_hardware_init_one_time(interface, index);
8740 + __cvmx_helper_sgmii_link_set(ipd_port,
8741 + __cvmx_helper_sgmii_link_get
8742 + (ipd_port));
8743 +
8744 + }
8745 +
8746 + return 0;
8747 +}
8748 +
8749 +/**
8750 + * Probe a SGMII interface and determine the number of ports
8751 + * connected to it. The SGMII interface should still be down after
8752 + * this call.
8753 + *
8754 + * @interface: Interface to probe
8755 + *
8756 + * Returns Number of ports on the interface. Zero to disable.
8757 + */
8758 +int __cvmx_helper_sgmii_probe(int interface)
8759 +{
8760 + union cvmx_gmxx_inf_mode mode;
8761 +
8762 + /*
8763 + * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
8764 + * interface needs to be enabled before IPD otherwise per port
8765 + * backpressure may not work properly
8766 + */
8767 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
8768 + mode.s.en = 1;
8769 + cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
8770 + return 4;
8771 +}
8772 +
8773 +/**
8774 + * Bringup and enable a SGMII interface. After this call packet
8775 + * I/O should be fully functional. This is called with IPD
8776 + * enabled but PKO disabled.
8777 + *
8778 + * @interface: Interface to bring up
8779 + *
8780 + * Returns Zero on success, negative on failure
8781 + */
8782 +int __cvmx_helper_sgmii_enable(int interface)
8783 +{
8784 + int num_ports = cvmx_helper_ports_on_interface(interface);
8785 + int index;
8786 +
8787 + __cvmx_helper_sgmii_hardware_init(interface, num_ports);
8788 +
8789 + for (index = 0; index < num_ports; index++) {
8790 + union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
8791 + gmxx_prtx_cfg.u64 =
8792 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
8793 + gmxx_prtx_cfg.s.en = 1;
8794 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
8795 + gmxx_prtx_cfg.u64);
8796 + __cvmx_interrupt_pcsx_intx_en_reg_enable(index, interface);
8797 + }
8798 + __cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
8799 + __cvmx_interrupt_gmxx_enable(interface);
8800 + return 0;
8801 +}
8802 +
8803 +/**
8804 + * Return the link state of an IPD/PKO port as returned by
8805 + * auto negotiation. The result of this function may not match
8806 + * Octeon's link config if auto negotiation has changed since
8807 + * the last call to cvmx_helper_link_set().
8808 + *
8809 + * @ipd_port: IPD/PKO port to query
8810 + *
8811 + * Returns Link state
8812 + */
8813 +cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port)
8814 +{
8815 + cvmx_helper_link_info_t result;
8816 + union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
8817 + int interface = cvmx_helper_get_interface_num(ipd_port);
8818 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8819 + union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
8820 +
8821 + result.u64 = 0;
8822 +
8823 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
8824 + /* The simulator gives you a simulated 1Gbps full duplex link */
8825 + result.s.link_up = 1;
8826 + result.s.full_duplex = 1;
8827 + result.s.speed = 1000;
8828 + return result;
8829 + }
8830 +
8831 + pcsx_mrx_control_reg.u64 =
8832 + cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8833 + if (pcsx_mrx_control_reg.s.loopbck1) {
8834 + /* Force 1Gbps full duplex link for internal loopback */
8835 + result.s.link_up = 1;
8836 + result.s.full_duplex = 1;
8837 + result.s.speed = 1000;
8838 + return result;
8839 + }
8840 +
8841 + pcs_misc_ctl_reg.u64 =
8842 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8843 + if (pcs_misc_ctl_reg.s.mode) {
8844 + /* 1000BASE-X */
8845 + /* FIXME */
8846 + } else {
8847 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8848 + pcsx_miscx_ctl_reg.u64 =
8849 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8850 + if (pcsx_miscx_ctl_reg.s.mac_phy) {
8851 + /* PHY Mode */
8852 + union cvmx_pcsx_mrx_status_reg pcsx_mrx_status_reg;
8853 + union cvmx_pcsx_anx_results_reg pcsx_anx_results_reg;
8854 +
8855 + /*
8856 + * Don't bother continuing if the SERTES low
8857 + * level link is down
8858 + */
8859 + pcsx_mrx_status_reg.u64 =
8860 + cvmx_read_csr(CVMX_PCSX_MRX_STATUS_REG
8861 + (index, interface));
8862 + if (pcsx_mrx_status_reg.s.lnk_st == 0) {
8863 + if (__cvmx_helper_sgmii_hardware_init_link
8864 + (interface, index) != 0)
8865 + return result;
8866 + }
8867 +
8868 + /* Read the autoneg results */
8869 + pcsx_anx_results_reg.u64 =
8870 + cvmx_read_csr(CVMX_PCSX_ANX_RESULTS_REG
8871 + (index, interface));
8872 + if (pcsx_anx_results_reg.s.an_cpt) {
8873 + /*
8874 + * Auto negotiation is complete. Set
8875 + * status accordingly.
8876 + */
8877 + result.s.full_duplex =
8878 + pcsx_anx_results_reg.s.dup;
8879 + result.s.link_up =
8880 + pcsx_anx_results_reg.s.link_ok;
8881 + switch (pcsx_anx_results_reg.s.spd) {
8882 + case 0:
8883 + result.s.speed = 10;
8884 + break;
8885 + case 1:
8886 + result.s.speed = 100;
8887 + break;
8888 + case 2:
8889 + result.s.speed = 1000;
8890 + break;
8891 + default:
8892 + result.s.speed = 0;
8893 + result.s.link_up = 0;
8894 + break;
8895 + }
8896 + } else {
8897 + /*
8898 + * Auto negotiation isn't
8899 + * complete. Return link down.
8900 + */
8901 + result.s.speed = 0;
8902 + result.s.link_up = 0;
8903 + }
8904 + } else { /* MAC Mode */
8905 +
8906 + result = __cvmx_helper_board_link_get(ipd_port);
8907 + }
8908 + }
8909 + return result;
8910 +}
8911 +
8912 +/**
8913 + * Configure an IPD/PKO port for the specified link state. This
8914 + * function does not influence auto negotiation at the PHY level.
8915 + * The passed link state must always match the link state returned
8916 + * by cvmx_helper_link_get(). It is normally best to use
8917 + * cvmx_helper_link_autoconf() instead.
8918 + *
8919 + * @ipd_port: IPD/PKO port to configure
8920 + * @link_info: The new link state
8921 + *
8922 + * Returns Zero on success, negative on failure
8923 + */
8924 +int __cvmx_helper_sgmii_link_set(int ipd_port,
8925 + cvmx_helper_link_info_t link_info)
8926 +{
8927 + int interface = cvmx_helper_get_interface_num(ipd_port);
8928 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8929 + __cvmx_helper_sgmii_hardware_init_link(interface, index);
8930 + return __cvmx_helper_sgmii_hardware_init_link_speed(interface, index,
8931 + link_info);
8932 +}
8933 +
8934 +/**
8935 + * Configure a port for internal and/or external loopback. Internal
8936 + * loopback causes packets sent by the port to be received by
8937 + * Octeon. External loopback causes packets received from the wire to
8938 + * sent out again.
8939 + *
8940 + * @ipd_port: IPD/PKO port to loopback.
8941 + * @enable_internal:
8942 + * Non zero if you want internal loopback
8943 + * @enable_external:
8944 + * Non zero if you want external loopback
8945 + *
8946 + * Returns Zero on success, negative on failure.
8947 + */
8948 +int __cvmx_helper_sgmii_configure_loopback(int ipd_port, int enable_internal,
8949 + int enable_external)
8950 +{
8951 + int interface = cvmx_helper_get_interface_num(ipd_port);
8952 + int index = cvmx_helper_get_interface_index_num(ipd_port);
8953 + union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
8954 + union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
8955 +
8956 + pcsx_mrx_control_reg.u64 =
8957 + cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
8958 + pcsx_mrx_control_reg.s.loopbck1 = enable_internal;
8959 + cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
8960 + pcsx_mrx_control_reg.u64);
8961 +
8962 + pcsx_miscx_ctl_reg.u64 =
8963 + cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
8964 + pcsx_miscx_ctl_reg.s.loopbck2 = enable_external;
8965 + cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
8966 + pcsx_miscx_ctl_reg.u64);
8967 +
8968 + __cvmx_helper_sgmii_hardware_init_link(interface, index);
8969 + return 0;
8970 +}
8971 diff --git a/drivers/staging/octeon/cvmx-helper-sgmii.h b/drivers/staging/octeon/cvmx-helper-sgmii.h
8972 new file mode 100644
8973 index 0000000..19b48d6
8974 --- /dev/null
8975 +++ b/drivers/staging/octeon/cvmx-helper-sgmii.h
8976 @@ -0,0 +1,104 @@
8977 +/***********************license start***************
8978 + * Author: Cavium Networks
8979 + *
8980 + * Contact: support@caviumnetworks.com
8981 + * This file is part of the OCTEON SDK
8982 + *
8983 + * Copyright (c) 2003-2008 Cavium Networks
8984 + *
8985 + * This file is free software; you can redistribute it and/or modify
8986 + * it under the terms of the GNU General Public License, Version 2, as
8987 + * published by the Free Software Foundation.
8988 + *
8989 + * This file is distributed in the hope that it will be useful, but
8990 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
8991 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
8992 + * NONINFRINGEMENT. See the GNU General Public License for more
8993 + * details.
8994 + *
8995 + * You should have received a copy of the GNU General Public License
8996 + * along with this file; if not, write to the Free Software
8997 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8998 + * or visit http://www.gnu.org/licenses/.
8999 + *
9000 + * This file may also be available under a different license from Cavium.
9001 + * Contact Cavium Networks for more information
9002 + ***********************license end**************************************/
9003 +
9004 +/**
9005 + * @file
9006 + *
9007 + * Functions for SGMII initialization, configuration,
9008 + * and monitoring.
9009 + *
9010 + */
9011 +#ifndef __CVMX_HELPER_SGMII_H__
9012 +#define __CVMX_HELPER_SGMII_H__
9013 +
9014 +/**
9015 + * Probe a SGMII interface and determine the number of ports
9016 + * connected to it. The SGMII interface should still be down after
9017 + * this call.
9018 + *
9019 + * @interface: Interface to probe
9020 + *
9021 + * Returns Number of ports on the interface. Zero to disable.
9022 + */
9023 +extern int __cvmx_helper_sgmii_probe(int interface);
9024 +
9025 +/**
9026 + * Bringup and enable a SGMII interface. After this call packet
9027 + * I/O should be fully functional. This is called with IPD
9028 + * enabled but PKO disabled.
9029 + *
9030 + * @interface: Interface to bring up
9031 + *
9032 + * Returns Zero on success, negative on failure
9033 + */
9034 +extern int __cvmx_helper_sgmii_enable(int interface);
9035 +
9036 +/**
9037 + * Return the link state of an IPD/PKO port as returned by
9038 + * auto negotiation. The result of this function may not match
9039 + * Octeon's link config if auto negotiation has changed since
9040 + * the last call to cvmx_helper_link_set().
9041 + *
9042 + * @ipd_port: IPD/PKO port to query
9043 + *
9044 + * Returns Link state
9045 + */
9046 +extern cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port);
9047 +
9048 +/**
9049 + * Configure an IPD/PKO port for the specified link state. This
9050 + * function does not influence auto negotiation at the PHY level.
9051 + * The passed link state must always match the link state returned
9052 + * by cvmx_helper_link_get(). It is normally best to use
9053 + * cvmx_helper_link_autoconf() instead.
9054 + *
9055 + * @ipd_port: IPD/PKO port to configure
9056 + * @link_info: The new link state
9057 + *
9058 + * Returns Zero on success, negative on failure
9059 + */
9060 +extern int __cvmx_helper_sgmii_link_set(int ipd_port,
9061 + cvmx_helper_link_info_t link_info);
9062 +
9063 +/**
9064 + * Configure a port for internal and/or external loopback. Internal loopback
9065 + * causes packets sent by the port to be received by Octeon. External loopback
9066 + * causes packets received from the wire to sent out again.
9067 + *
9068 + * @ipd_port: IPD/PKO port to loopback.
9069 + * @enable_internal:
9070 + * Non zero if you want internal loopback
9071 + * @enable_external:
9072 + * Non zero if you want external loopback
9073 + *
9074 + * Returns Zero on success, negative on failure.
9075 + */
9076 +extern int __cvmx_helper_sgmii_configure_loopback(int ipd_port,
9077 + int enable_internal,
9078 + int enable_external);
9079 +
9080 +#endif
9081 diff --git a/drivers/staging/octeon/cvmx-helper-spi.c b/drivers/staging/octeon/cvmx-helper-spi.c
9082 new file mode 100644
9083 index 0000000..8ba6c83
9084 --- /dev/null
9085 +++ b/drivers/staging/octeon/cvmx-helper-spi.c
9086 @@ -0,0 +1,195 @@
9087 +/***********************license start***************
9088 + * Author: Cavium Networks
9089 + *
9090 + * Contact: support@caviumnetworks.com
9091 + * This file is part of the OCTEON SDK
9092 + *
9093 + * Copyright (c) 2003-2008 Cavium Networks
9094 + *
9095 + * This file is free software; you can redistribute it and/or modify
9096 + * it under the terms of the GNU General Public License, Version 2, as
9097 + * published by the Free Software Foundation.
9098 + *
9099 + * This file is distributed in the hope that it will be useful, but
9100 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9101 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9102 + * NONINFRINGEMENT. See the GNU General Public License for more
9103 + * details.
9104 + *
9105 + * You should have received a copy of the GNU General Public License
9106 + * along with this file; if not, write to the Free Software
9107 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9108 + * or visit http://www.gnu.org/licenses/.
9109 + *
9110 + * This file may also be available under a different license from Cavium.
9111 + * Contact Cavium Networks for more information
9112 + ***********************license end**************************************/
9113 +
9114 +void __cvmx_interrupt_gmxx_enable(int interface);
9115 +void __cvmx_interrupt_spxx_int_msk_enable(int index);
9116 +void __cvmx_interrupt_stxx_int_msk_enable(int index);
9117 +
9118 +/*
9119 + * Functions for SPI initialization, configuration,
9120 + * and monitoring.
9121 + */
9122 +#include <asm/octeon/octeon.h>
9123 +
9124 +#include "cvmx-config.h"
9125 +#include "cvmx-spi.h"
9126 +#include "cvmx-helper.h"
9127 +
9128 +#include "cvmx-pip-defs.h"
9129 +#include "cvmx-pko-defs.h"
9130 +
9131 +/*
9132 + * CVMX_HELPER_SPI_TIMEOUT is used to determine how long the SPI
9133 + * initialization routines wait for SPI training. You can override the
9134 + * value using executive-config.h if necessary.
9135 + */
9136 +#ifndef CVMX_HELPER_SPI_TIMEOUT
9137 +#define CVMX_HELPER_SPI_TIMEOUT 10
9138 +#endif
9139 +
9140 +/**
9141 + * Probe a SPI interface and determine the number of ports
9142 + * connected to it. The SPI interface should still be down after
9143 + * this call.
9144 + *
9145 + * @interface: Interface to probe
9146 + *
9147 + * Returns Number of ports on the interface. Zero to disable.
9148 + */
9149 +int __cvmx_helper_spi_probe(int interface)
9150 +{
9151 + int num_ports = 0;
9152 +
9153 + if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
9154 + cvmx_spi4000_is_present(interface)) {
9155 + num_ports = 10;
9156 + } else {
9157 + union cvmx_pko_reg_crc_enable enable;
9158 + num_ports = 16;
9159 + /*
9160 + * Unlike the SPI4000, most SPI devices don't
9161 + * automatically put on the L2 CRC. For everything
9162 + * except for the SPI4000 have PKO append the L2 CRC
9163 + * to the packet.
9164 + */
9165 + enable.u64 = cvmx_read_csr(CVMX_PKO_REG_CRC_ENABLE);
9166 + enable.s.enable |= 0xffff << (interface * 16);
9167 + cvmx_write_csr(CVMX_PKO_REG_CRC_ENABLE, enable.u64);
9168 + }
9169 + __cvmx_helper_setup_gmx(interface, num_ports);
9170 + return num_ports;
9171 +}
9172 +
9173 +/**
9174 + * Bringup and enable a SPI interface. After this call packet I/O
9175 + * should be fully functional. This is called with IPD enabled but
9176 + * PKO disabled.
9177 + *
9178 + * @interface: Interface to bring up
9179 + *
9180 + * Returns Zero on success, negative on failure
9181 + */
9182 +int __cvmx_helper_spi_enable(int interface)
9183 +{
9184 + /*
9185 + * Normally the ethernet L2 CRC is checked and stripped in the
9186 + * GMX block. When you are using SPI, this isn' the case and
9187 + * IPD needs to check the L2 CRC.
9188 + */
9189 + int num_ports = cvmx_helper_ports_on_interface(interface);
9190 + int ipd_port;
9191 + for (ipd_port = interface * 16; ipd_port < interface * 16 + num_ports;
9192 + ipd_port++) {
9193 + union cvmx_pip_prt_cfgx port_config;
9194 + port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
9195 + port_config.s.crc_en = 1;
9196 + cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_config.u64);
9197 + }
9198 +
9199 + if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
9200 + cvmx_spi_start_interface(interface, CVMX_SPI_MODE_DUPLEX,
9201 + CVMX_HELPER_SPI_TIMEOUT, num_ports);
9202 + if (cvmx_spi4000_is_present(interface))
9203 + cvmx_spi4000_initialize(interface);
9204 + }
9205 + __cvmx_interrupt_spxx_int_msk_enable(interface);
9206 + __cvmx_interrupt_stxx_int_msk_enable(interface);
9207 + __cvmx_interrupt_gmxx_enable(interface);
9208 + return 0;
9209 +}
9210 +
9211 +/**
9212 + * Return the link state of an IPD/PKO port as returned by
9213 + * auto negotiation. The result of this function may not match
9214 + * Octeon's link config if auto negotiation has changed since
9215 + * the last call to cvmx_helper_link_set().
9216 + *
9217 + * @ipd_port: IPD/PKO port to query
9218 + *
9219 + * Returns Link state
9220 + */
9221 +cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port)
9222 +{
9223 + cvmx_helper_link_info_t result;
9224 + int interface = cvmx_helper_get_interface_num(ipd_port);
9225 + int index = cvmx_helper_get_interface_index_num(ipd_port);
9226 + result.u64 = 0;
9227 +
9228 + if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
9229 + /* The simulator gives you a simulated full duplex link */
9230 + result.s.link_up = 1;
9231 + result.s.full_duplex = 1;
9232 + result.s.speed = 10000;
9233 + } else if (cvmx_spi4000_is_present(interface)) {
9234 + union cvmx_gmxx_rxx_rx_inbnd inband =
9235 + cvmx_spi4000_check_speed(interface, index);
9236 + result.s.link_up = inband.s.status;
9237 + result.s.full_duplex = inband.s.duplex;
9238 + switch (inband.s.speed) {
9239 + case 0: /* 10 Mbps */
9240 + result.s.speed = 10;
9241 + break;
9242 + case 1: /* 100 Mbps */
9243 + result.s.speed = 100;
9244 + break;
9245 + case 2: /* 1 Gbps */
9246 + result.s.speed = 1000;
9247 + break;
9248 + case 3: /* Illegal */
9249 + result.s.speed = 0;
9250 + result.s.link_up = 0;
9251 + break;
9252 + }
9253 + } else {
9254 + /* For generic SPI we can't determine the link, just return some
9255 + sane results */
9256 + result.s.link_up = 1;
9257 + result.s.full_duplex = 1;
9258 + result.s.speed = 10000;
9259 + }
9260 + return result;
9261 +}
9262 +
9263 +/**
9264 + * Configure an IPD/PKO port for the specified link state. This
9265 + * function does not influence auto negotiation at the PHY level.
9266 + * The passed link state must always match the link state returned
9267 + * by cvmx_helper_link_get(). It is normally best to use
9268 + * cvmx_helper_link_autoconf() instead.
9269 + *
9270 + * @ipd_port: IPD/PKO port to configure
9271 + * @link_info: The new link state
9272 + *
9273 + * Returns Zero on success, negative on failure
9274 + */
9275 +int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
9276 +{
9277 + /* Nothing to do. If we have a SPI4000 then the setup was already performed
9278 + by cvmx_spi4000_check_speed(). If not then there isn't any link
9279 + info */
9280 + return 0;
9281 +}
9282 diff --git a/drivers/staging/octeon/cvmx-helper-spi.h b/drivers/staging/octeon/cvmx-helper-spi.h
9283 new file mode 100644
9284 index 0000000..69bac03
9285 --- /dev/null
9286 +++ b/drivers/staging/octeon/cvmx-helper-spi.h
9287 @@ -0,0 +1,84 @@
9288 +/***********************license start***************
9289 + * Author: Cavium Networks
9290 + *
9291 + * Contact: support@caviumnetworks.com
9292 + * This file is part of the OCTEON SDK
9293 + *
9294 + * Copyright (c) 2003-2008 Cavium Networks
9295 + *
9296 + * This file is free software; you can redistribute it and/or modify
9297 + * it under the terms of the GNU General Public License, Version 2, as
9298 + * published by the Free Software Foundation.
9299 + *
9300 + * This file is distributed in the hope that it will be useful, but
9301 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9302 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9303 + * NONINFRINGEMENT. See the GNU General Public License for more
9304 + * details.
9305 + *
9306 + * You should have received a copy of the GNU General Public License
9307 + * along with this file; if not, write to the Free Software
9308 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9309 + * or visit http://www.gnu.org/licenses/.
9310 + *
9311 + * This file may also be available under a different license from Cavium.
9312 + * Contact Cavium Networks for more information
9313 + ***********************license end**************************************/
9314 +
9315 +/*
9316 + * Functions for SPI initialization, configuration,
9317 + * and monitoring.
9318 + */
9319 +#ifndef __CVMX_HELPER_SPI_H__
9320 +#define __CVMX_HELPER_SPI_H__
9321 +
9322 +/**
9323 + * Probe a SPI interface and determine the number of ports
9324 + * connected to it. The SPI interface should still be down after
9325 + * this call.
9326 + *
9327 + * @interface: Interface to probe
9328 + *
9329 + * Returns Number of ports on the interface. Zero to disable.
9330 + */
9331 +extern int __cvmx_helper_spi_probe(int interface);
9332 +
9333 +/**
9334 + * Bringup and enable a SPI interface. After this call packet I/O
9335 + * should be fully functional. This is called with IPD enabled but
9336 + * PKO disabled.
9337 + *
9338 + * @interface: Interface to bring up
9339 + *
9340 + * Returns Zero on success, negative on failure
9341 + */
9342 +extern int __cvmx_helper_spi_enable(int interface);
9343 +
9344 +/**
9345 + * Return the link state of an IPD/PKO port as returned by
9346 + * auto negotiation. The result of this function may not match
9347 + * Octeon's link config if auto negotiation has changed since
9348 + * the last call to cvmx_helper_link_set().
9349 + *
9350 + * @ipd_port: IPD/PKO port to query
9351 + *
9352 + * Returns Link state
9353 + */
9354 +extern cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port);
9355 +
9356 +/**
9357 + * Configure an IPD/PKO port for the specified link state. This
9358 + * function does not influence auto negotiation at the PHY level.
9359 + * The passed link state must always match the link state returned
9360 + * by cvmx_helper_link_get(). It is normally best to use
9361 + * cvmx_helper_link_autoconf() instead.
9362 + *
9363 + * @ipd_port: IPD/PKO port to configure
9364 + * @link_info: The new link state
9365 + *
9366 + * Returns Zero on success, negative on failure
9367 + */
9368 +extern int __cvmx_helper_spi_link_set(int ipd_port,
9369 + cvmx_helper_link_info_t link_info);
9370 +
9371 +#endif
9372 diff --git a/drivers/staging/octeon/cvmx-helper-util.c b/drivers/staging/octeon/cvmx-helper-util.c
9373 new file mode 100644
9374 index 0000000..41ef8a4
9375 --- /dev/null
9376 +++ b/drivers/staging/octeon/cvmx-helper-util.c
9377 @@ -0,0 +1,433 @@
9378 +/***********************license start***************
9379 + * Author: Cavium Networks
9380 + *
9381 + * Contact: support@caviumnetworks.com
9382 + * This file is part of the OCTEON SDK
9383 + *
9384 + * Copyright (c) 2003-2008 Cavium Networks
9385 + *
9386 + * This file is free software; you can redistribute it and/or modify
9387 + * it under the terms of the GNU General Public License, Version 2, as
9388 + * published by the Free Software Foundation.
9389 + *
9390 + * This file is distributed in the hope that it will be useful, but
9391 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9392 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9393 + * NONINFRINGEMENT. See the GNU General Public License for more
9394 + * details.
9395 + *
9396 + * You should have received a copy of the GNU General Public License
9397 + * along with this file; if not, write to the Free Software
9398 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9399 + * or visit http://www.gnu.org/licenses/.
9400 + *
9401 + * This file may also be available under a different license from Cavium.
9402 + * Contact Cavium Networks for more information
9403 + ***********************license end**************************************/
9404 +
9405 +/*
9406 + * Small helper utilities.
9407 + */
9408 +#include <linux/kernel.h>
9409 +
9410 +#include <asm/octeon/octeon.h>
9411 +
9412 +#include "cvmx-config.h"
9413 +
9414 +#include "cvmx-fpa.h"
9415 +#include "cvmx-pip.h"
9416 +#include "cvmx-pko.h"
9417 +#include "cvmx-ipd.h"
9418 +#include "cvmx-spi.h"
9419 +
9420 +#include "cvmx-helper.h"
9421 +#include "cvmx-helper-util.h"
9422 +
9423 +#include <asm/octeon/cvmx-ipd-defs.h>
9424 +
9425 +/**
9426 + * Convert a interface mode into a human readable string
9427 + *
9428 + * @mode: Mode to convert
9429 + *
9430 + * Returns String
9431 + */
9432 +const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t
9433 + mode)
9434 +{
9435 + switch (mode) {
9436 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
9437 + return "DISABLED";
9438 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
9439 + return "RGMII";
9440 + case CVMX_HELPER_INTERFACE_MODE_GMII:
9441 + return "GMII";
9442 + case CVMX_HELPER_INTERFACE_MODE_SPI:
9443 + return "SPI";
9444 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
9445 + return "PCIE";
9446 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
9447 + return "XAUI";
9448 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
9449 + return "SGMII";
9450 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
9451 + return "PICMG";
9452 + case CVMX_HELPER_INTERFACE_MODE_NPI:
9453 + return "NPI";
9454 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
9455 + return "LOOP";
9456 + }
9457 + return "UNKNOWN";
9458 +}
9459 +
9460 +/**
9461 + * Debug routine to dump the packet structure to the console
9462 + *
9463 + * @work: Work queue entry containing the packet to dump
9464 + * Returns
9465 + */
9466 +int cvmx_helper_dump_packet(cvmx_wqe_t *work)
9467 +{
9468 + uint64_t count;
9469 + uint64_t remaining_bytes;
9470 + union cvmx_buf_ptr buffer_ptr;
9471 + uint64_t start_of_buffer;
9472 + uint8_t *data_address;
9473 + uint8_t *end_of_data;
9474 +
9475 + cvmx_dprintf("Packet Length: %u\n", work->len);
9476 + cvmx_dprintf(" Input Port: %u\n", work->ipprt);
9477 + cvmx_dprintf(" QoS: %u\n", work->qos);
9478 + cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs);
9479 +
9480 + if (work->word2.s.bufs == 0) {
9481 + union cvmx_ipd_wqe_fpa_queue wqe_pool;
9482 + wqe_pool.u64 = cvmx_read_csr(CVMX_IPD_WQE_FPA_QUEUE);
9483 + buffer_ptr.u64 = 0;
9484 + buffer_ptr.s.pool = wqe_pool.s.wqe_pool;
9485 + buffer_ptr.s.size = 128;
9486 + buffer_ptr.s.addr = cvmx_ptr_to_phys(work->packet_data);
9487 + if (likely(!work->word2.s.not_IP)) {
9488 + union cvmx_pip_ip_offset pip_ip_offset;
9489 + pip_ip_offset.u64 = cvmx_read_csr(CVMX_PIP_IP_OFFSET);
9490 + buffer_ptr.s.addr +=
9491 + (pip_ip_offset.s.offset << 3) -
9492 + work->word2.s.ip_offset;
9493 + buffer_ptr.s.addr += (work->word2.s.is_v6 ^ 1) << 2;
9494 + } else {
9495 + /*
9496 + * WARNING: This code assumes that the packet
9497 + * is not RAW. If it was, we would use
9498 + * PIP_GBL_CFG[RAW_SHF] instead of
9499 + * PIP_GBL_CFG[NIP_SHF].
9500 + */
9501 + union cvmx_pip_gbl_cfg pip_gbl_cfg;
9502 + pip_gbl_cfg.u64 = cvmx_read_csr(CVMX_PIP_GBL_CFG);
9503 + buffer_ptr.s.addr += pip_gbl_cfg.s.nip_shf;
9504 + }
9505 + } else
9506 + buffer_ptr = work->packet_ptr;
9507 + remaining_bytes = work->len;
9508 +
9509 + while (remaining_bytes) {
9510 + start_of_buffer =
9511 + ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9512 + cvmx_dprintf(" Buffer Start:%llx\n",
9513 + (unsigned long long)start_of_buffer);
9514 + cvmx_dprintf(" Buffer I : %u\n", buffer_ptr.s.i);
9515 + cvmx_dprintf(" Buffer Back: %u\n", buffer_ptr.s.back);
9516 + cvmx_dprintf(" Buffer Pool: %u\n", buffer_ptr.s.pool);
9517 + cvmx_dprintf(" Buffer Data: %llx\n",
9518 + (unsigned long long)buffer_ptr.s.addr);
9519 + cvmx_dprintf(" Buffer Size: %u\n", buffer_ptr.s.size);
9520 +
9521 + cvmx_dprintf("\t\t");
9522 + data_address = (uint8_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr);
9523 + end_of_data = data_address + buffer_ptr.s.size;
9524 + count = 0;
9525 + while (data_address < end_of_data) {
9526 + if (remaining_bytes == 0)
9527 + break;
9528 + else
9529 + remaining_bytes--;
9530 + cvmx_dprintf("%02x", (unsigned int)*data_address);
9531 + data_address++;
9532 + if (remaining_bytes && (count == 7)) {
9533 + cvmx_dprintf("\n\t\t");
9534 + count = 0;
9535 + } else
9536 + count++;
9537 + }
9538 + cvmx_dprintf("\n");
9539 +
9540 + if (remaining_bytes)
9541 + buffer_ptr = *(union cvmx_buf_ptr *)
9542 + cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9543 + }
9544 + return 0;
9545 +}
9546 +
9547 +/**
9548 + * Setup Random Early Drop on a specific input queue
9549 + *
9550 + * @queue: Input queue to setup RED on (0-7)
9551 + * @pass_thresh:
9552 + * Packets will begin slowly dropping when there are less than
9553 + * this many packet buffers free in FPA 0.
9554 + * @drop_thresh:
9555 + * All incomming packets will be dropped when there are less
9556 + * than this many free packet buffers in FPA 0.
9557 + * Returns Zero on success. Negative on failure
9558 + */
9559 +int cvmx_helper_setup_red_queue(int queue, int pass_thresh, int drop_thresh)
9560 +{
9561 + union cvmx_ipd_qosx_red_marks red_marks;
9562 + union cvmx_ipd_red_quex_param red_param;
9563 +
9564 + /* Set RED to begin dropping packets when there are pass_thresh buffers
9565 + left. It will linearly drop more packets until reaching drop_thresh
9566 + buffers */
9567 + red_marks.u64 = 0;
9568 + red_marks.s.drop = drop_thresh;
9569 + red_marks.s.pass = pass_thresh;
9570 + cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64);
9571 +
9572 + /* Use the actual queue 0 counter, not the average */
9573 + red_param.u64 = 0;
9574 + red_param.s.prb_con =
9575 + (255ul << 24) / (red_marks.s.pass - red_marks.s.drop);
9576 + red_param.s.avg_con = 1;
9577 + red_param.s.new_con = 255;
9578 + red_param.s.use_pcnt = 1;
9579 + cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64);
9580 + return 0;
9581 +}
9582 +
9583 +/**
9584 + * Setup Random Early Drop to automatically begin dropping packets.
9585 + *
9586 + * @pass_thresh:
9587 + * Packets will begin slowly dropping when there are less than
9588 + * this many packet buffers free in FPA 0.
9589 + * @drop_thresh:
9590 + * All incomming packets will be dropped when there are less
9591 + * than this many free packet buffers in FPA 0.
9592 + * Returns Zero on success. Negative on failure
9593 + */
9594 +int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
9595 +{
9596 + union cvmx_ipd_portx_bp_page_cnt page_cnt;
9597 + union cvmx_ipd_bp_prt_red_end ipd_bp_prt_red_end;
9598 + union cvmx_ipd_red_port_enable red_port_enable;
9599 + int queue;
9600 + int interface;
9601 + int port;
9602 +
9603 + /* Disable backpressure based on queued buffers. It needs SW support */
9604 + page_cnt.u64 = 0;
9605 + page_cnt.s.bp_enb = 0;
9606 + page_cnt.s.page_cnt = 100;
9607 + for (interface = 0; interface < 2; interface++) {
9608 + for (port = cvmx_helper_get_first_ipd_port(interface);
9609 + port < cvmx_helper_get_last_ipd_port(interface); port++)
9610 + cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port),
9611 + page_cnt.u64);
9612 + }
9613 +
9614 + for (queue = 0; queue < 8; queue++)
9615 + cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh);
9616 +
9617 + /* Shutoff the dropping based on the per port page count. SW isn't
9618 + decrementing it right now */
9619 + ipd_bp_prt_red_end.u64 = 0;
9620 + ipd_bp_prt_red_end.s.prt_enb = 0;
9621 + cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64);
9622 +
9623 + red_port_enable.u64 = 0;
9624 + red_port_enable.s.prt_enb = 0xfffffffffull;
9625 + red_port_enable.s.avg_dly = 10000;
9626 + red_port_enable.s.prb_dly = 10000;
9627 + cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64);
9628 +
9629 + return 0;
9630 +}
9631 +
9632 +/**
9633 + * Setup the common GMX settings that determine the number of
9634 + * ports. These setting apply to almost all configurations of all
9635 + * chips.
9636 + *
9637 + * @interface: Interface to configure
9638 + * @num_ports: Number of ports on the interface
9639 + *
9640 + * Returns Zero on success, negative on failure
9641 + */
9642 +int __cvmx_helper_setup_gmx(int interface, int num_ports)
9643 +{
9644 + union cvmx_gmxx_tx_prts gmx_tx_prts;
9645 + union cvmx_gmxx_rx_prts gmx_rx_prts;
9646 + union cvmx_pko_reg_gmx_port_mode pko_mode;
9647 + union cvmx_gmxx_txx_thresh gmx_tx_thresh;
9648 + int index;
9649 +
9650 + /* Tell GMX the number of TX ports on this interface */
9651 + gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface));
9652 + gmx_tx_prts.s.prts = num_ports;
9653 + cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64);
9654 +
9655 + /* Tell GMX the number of RX ports on this interface. This only
9656 + ** applies to *GMII and XAUI ports */
9657 + if (cvmx_helper_interface_get_mode(interface) ==
9658 + CVMX_HELPER_INTERFACE_MODE_RGMII
9659 + || cvmx_helper_interface_get_mode(interface) ==
9660 + CVMX_HELPER_INTERFACE_MODE_SGMII
9661 + || cvmx_helper_interface_get_mode(interface) ==
9662 + CVMX_HELPER_INTERFACE_MODE_GMII
9663 + || cvmx_helper_interface_get_mode(interface) ==
9664 + CVMX_HELPER_INTERFACE_MODE_XAUI) {
9665 + if (num_ports > 4) {
9666 + cvmx_dprintf("__cvmx_helper_setup_gmx: Illegal "
9667 + "num_ports\n");
9668 + return -1;
9669 + }
9670 +
9671 + gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface));
9672 + gmx_rx_prts.s.prts = num_ports;
9673 + cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64);
9674 + }
9675 +
9676 + /* Skip setting CVMX_PKO_REG_GMX_PORT_MODE on 30XX, 31XX, and 50XX */
9677 + if (!OCTEON_IS_MODEL(OCTEON_CN30XX) && !OCTEON_IS_MODEL(OCTEON_CN31XX)
9678 + && !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
9679 + /* Tell PKO the number of ports on this interface */
9680 + pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE);
9681 + if (interface == 0) {
9682 + if (num_ports == 1)
9683 + pko_mode.s.mode0 = 4;
9684 + else if (num_ports == 2)
9685 + pko_mode.s.mode0 = 3;
9686 + else if (num_ports <= 4)
9687 + pko_mode.s.mode0 = 2;
9688 + else if (num_ports <= 8)
9689 + pko_mode.s.mode0 = 1;
9690 + else
9691 + pko_mode.s.mode0 = 0;
9692 + } else {
9693 + if (num_ports == 1)
9694 + pko_mode.s.mode1 = 4;
9695 + else if (num_ports == 2)
9696 + pko_mode.s.mode1 = 3;
9697 + else if (num_ports <= 4)
9698 + pko_mode.s.mode1 = 2;
9699 + else if (num_ports <= 8)
9700 + pko_mode.s.mode1 = 1;
9701 + else
9702 + pko_mode.s.mode1 = 0;
9703 + }
9704 + cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64);
9705 + }
9706 +
9707 + /*
9708 + * Set GMX to buffer as much data as possible before starting
9709 + * transmit. This reduces the chances that we have a TX under
9710 + * run due to memory contention. Any packet that fits entirely
9711 + * in the GMX FIFO can never have an under run regardless of
9712 + * memory load.
9713 + */
9714 + gmx_tx_thresh.u64 = cvmx_read_csr(CVMX_GMXX_TXX_THRESH(0, interface));
9715 + if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX)
9716 + || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
9717 + /* These chips have a fixed max threshold of 0x40 */
9718 + gmx_tx_thresh.s.cnt = 0x40;
9719 + } else {
9720 + /* Choose the max value for the number of ports */
9721 + if (num_ports <= 1)
9722 + gmx_tx_thresh.s.cnt = 0x100 / 1;
9723 + else if (num_ports == 2)
9724 + gmx_tx_thresh.s.cnt = 0x100 / 2;
9725 + else
9726 + gmx_tx_thresh.s.cnt = 0x100 / 4;
9727 + }
9728 + /*
9729 + * SPI and XAUI can have lots of ports but the GMX hardware
9730 + * only ever has a max of 4.
9731 + */
9732 + if (num_ports > 4)
9733 + num_ports = 4;
9734 + for (index = 0; index < num_ports; index++)
9735 + cvmx_write_csr(CVMX_GMXX_TXX_THRESH(index, interface),
9736 + gmx_tx_thresh.u64);
9737 +
9738 + return 0;
9739 +}
9740 +
9741 +/**
9742 + * Returns the IPD/PKO port number for a port on teh given
9743 + * interface.
9744 + *
9745 + * @interface: Interface to use
9746 + * @port: Port on the interface
9747 + *
9748 + * Returns IPD/PKO port number
9749 + */
9750 +int cvmx_helper_get_ipd_port(int interface, int port)
9751 +{
9752 + switch (interface) {
9753 + case 0:
9754 + return port;
9755 + case 1:
9756 + return port + 16;
9757 + case 2:
9758 + return port + 32;
9759 + case 3:
9760 + return port + 36;
9761 + }
9762 + return -1;
9763 +}
9764 +
9765 +/**
9766 + * Returns the interface number for an IPD/PKO port number.
9767 + *
9768 + * @ipd_port: IPD/PKO port number
9769 + *
9770 + * Returns Interface number
9771 + */
9772 +int cvmx_helper_get_interface_num(int ipd_port)
9773 +{
9774 + if (ipd_port < 16)
9775 + return 0;
9776 + else if (ipd_port < 32)
9777 + return 1;
9778 + else if (ipd_port < 36)
9779 + return 2;
9780 + else if (ipd_port < 40)
9781 + return 3;
9782 + else
9783 + cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "
9784 + "port number\n");
9785 +
9786 + return -1;
9787 +}
9788 +
9789 +/**
9790 + * Returns the interface index number for an IPD/PKO port
9791 + * number.
9792 + *
9793 + * @ipd_port: IPD/PKO port number
9794 + *
9795 + * Returns Interface index number
9796 + */
9797 +int cvmx_helper_get_interface_index_num(int ipd_port)
9798 +{
9799 + if (ipd_port < 32)
9800 + return ipd_port & 15;
9801 + else if (ipd_port < 36)
9802 + return ipd_port & 3;
9803 + else if (ipd_port < 40)
9804 + return ipd_port & 3;
9805 + else
9806 + cvmx_dprintf("cvmx_helper_get_interface_index_num: "
9807 + "Illegal IPD port number\n");
9808 +
9809 + return -1;
9810 +}
9811 diff --git a/drivers/staging/octeon/cvmx-helper-util.h b/drivers/staging/octeon/cvmx-helper-util.h
9812 new file mode 100644
9813 index 0000000..6a6e52f
9814 --- /dev/null
9815 +++ b/drivers/staging/octeon/cvmx-helper-util.h
9816 @@ -0,0 +1,215 @@
9817 +/***********************license start***************
9818 + * Author: Cavium Networks
9819 + *
9820 + * Contact: support@caviumnetworks.com
9821 + * This file is part of the OCTEON SDK
9822 + *
9823 + * Copyright (c) 2003-2008 Cavium Networks
9824 + *
9825 + * This file is free software; you can redistribute it and/or modify
9826 + * it under the terms of the GNU General Public License, Version 2, as
9827 + * published by the Free Software Foundation.
9828 + *
9829 + * This file is distributed in the hope that it will be useful, but
9830 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
9831 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
9832 + * NONINFRINGEMENT. See the GNU General Public License for more
9833 + * details.
9834 + *
9835 + * You should have received a copy of the GNU General Public License
9836 + * along with this file; if not, write to the Free Software
9837 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9838 + * or visit http://www.gnu.org/licenses/.
9839 + *
9840 + * This file may also be available under a different license from Cavium.
9841 + * Contact Cavium Networks for more information
9842 + ***********************license end**************************************/
9843 +
9844 +/*
9845 + *
9846 + * Small helper utilities.
9847 + *
9848 + */
9849 +
9850 +#ifndef __CVMX_HELPER_UTIL_H__
9851 +#define __CVMX_HELPER_UTIL_H__
9852 +
9853 +/**
9854 + * Convert a interface mode into a human readable string
9855 + *
9856 + * @mode: Mode to convert
9857 + *
9858 + * Returns String
9859 + */
9860 +extern const char
9861 + *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode);
9862 +
9863 +/**
9864 + * Debug routine to dump the packet structure to the console
9865 + *
9866 + * @work: Work queue entry containing the packet to dump
9867 + * Returns
9868 + */
9869 +extern int cvmx_helper_dump_packet(cvmx_wqe_t *work);
9870 +
9871 +/**
9872 + * Setup Random Early Drop on a specific input queue
9873 + *
9874 + * @queue: Input queue to setup RED on (0-7)
9875 + * @pass_thresh:
9876 + * Packets will begin slowly dropping when there are less than
9877 + * this many packet buffers free in FPA 0.
9878 + * @drop_thresh:
9879 + * All incomming packets will be dropped when there are less
9880 + * than this many free packet buffers in FPA 0.
9881 + * Returns Zero on success. Negative on failure
9882 + */
9883 +extern int cvmx_helper_setup_red_queue(int queue, int pass_thresh,
9884 + int drop_thresh);
9885 +
9886 +/**
9887 + * Setup Random Early Drop to automatically begin dropping packets.
9888 + *
9889 + * @pass_thresh:
9890 + * Packets will begin slowly dropping when there are less than
9891 + * this many packet buffers free in FPA 0.
9892 + * @drop_thresh:
9893 + * All incomming packets will be dropped when there are less
9894 + * than this many free packet buffers in FPA 0.
9895 + * Returns Zero on success. Negative on failure
9896 + */
9897 +extern int cvmx_helper_setup_red(int pass_thresh, int drop_thresh);
9898 +
9899 +/**
9900 + * Get the version of the CVMX libraries.
9901 + *
9902 + * Returns Version string. Note this buffer is allocated statically
9903 + * and will be shared by all callers.
9904 + */
9905 +extern const char *cvmx_helper_get_version(void);
9906 +
9907 +/**
9908 + * Setup the common GMX settings that determine the number of
9909 + * ports. These setting apply to almost all configurations of all
9910 + * chips.
9911 + *
9912 + * @interface: Interface to configure
9913 + * @num_ports: Number of ports on the interface
9914 + *
9915 + * Returns Zero on success, negative on failure
9916 + */
9917 +extern int __cvmx_helper_setup_gmx(int interface, int num_ports);
9918 +
9919 +/**
9920 + * Returns the IPD/PKO port number for a port on the given
9921 + * interface.
9922 + *
9923 + * @interface: Interface to use
9924 + * @port: Port on the interface
9925 + *
9926 + * Returns IPD/PKO port number
9927 + */
9928 +extern int cvmx_helper_get_ipd_port(int interface, int port);
9929 +
9930 +/**
9931 + * Returns the IPD/PKO port number for the first port on the given
9932 + * interface.
9933 + *
9934 + * @interface: Interface to use
9935 + *
9936 + * Returns IPD/PKO port number
9937 + */
9938 +static inline int cvmx_helper_get_first_ipd_port(int interface)
9939 +{
9940 + return cvmx_helper_get_ipd_port(interface, 0);
9941 +}
9942 +
9943 +/**
9944 + * Returns the IPD/PKO port number for the last port on the given
9945 + * interface.
9946 + *
9947 + * @interface: Interface to use
9948 + *
9949 + * Returns IPD/PKO port number
9950 + */
9951 +static inline int cvmx_helper_get_last_ipd_port(int interface)
9952 +{
9953 + extern int cvmx_helper_ports_on_interface(int interface);
9954 +
9955 + return cvmx_helper_get_first_ipd_port(interface) +
9956 + cvmx_helper_ports_on_interface(interface) - 1;
9957 +}
9958 +
9959 +/**
9960 + * Free the packet buffers contained in a work queue entry.
9961 + * The work queue entry is not freed.
9962 + *
9963 + * @work: Work queue entry with packet to free
9964 + */
9965 +static inline void cvmx_helper_free_packet_data(cvmx_wqe_t *work)
9966 +{
9967 + uint64_t number_buffers;
9968 + union cvmx_buf_ptr buffer_ptr;
9969 + union cvmx_buf_ptr next_buffer_ptr;
9970 + uint64_t start_of_buffer;
9971 +
9972 + number_buffers = work->word2.s.bufs;
9973 + if (number_buffers == 0)
9974 + return;
9975 + buffer_ptr = work->packet_ptr;
9976 +
9977 + /*
9978 + * Since the number of buffers is not zero, we know this is
9979 + * not a dynamic short packet. We need to check if it is a
9980 + * packet received with IPD_CTL_STATUS[NO_WPTR]. If this is
9981 + * true, we need to free all buffers except for the first
9982 + * one. The caller doesn't expect their WQE pointer to be
9983 + * freed
9984 + */
9985 + start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
9986 + if (cvmx_ptr_to_phys(work) == start_of_buffer) {
9987 + next_buffer_ptr =
9988 + *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
9989 + buffer_ptr = next_buffer_ptr;
9990 + number_buffers--;
9991 + }
9992 +
9993 + while (number_buffers--) {
9994 + /*
9995 + * Remember the back pointer is in cache lines, not
9996 + * 64bit words
9997 + */
9998 + start_of_buffer =
9999 + ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
10000 + /*
10001 + * Read pointer to next buffer before we free the
10002 + * current buffer.
10003 + */
10004 + next_buffer_ptr =
10005 + *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
10006 + cvmx_fpa_free(cvmx_phys_to_ptr(start_of_buffer),
10007 + buffer_ptr.s.pool, 0);
10008 + buffer_ptr = next_buffer_ptr;
10009 + }
10010 +}
10011 +
10012 +/**
10013 + * Returns the interface number for an IPD/PKO port number.
10014 + *
10015 + * @ipd_port: IPD/PKO port number
10016 + *
10017 + * Returns Interface number
10018 + */
10019 +extern int cvmx_helper_get_interface_num(int ipd_port);
10020 +
10021 +/**
10022 + * Returns the interface index number for an IPD/PKO port
10023 + * number.
10024 + *
10025 + * @ipd_port: IPD/PKO port number
10026 + *
10027 + * Returns Interface index number
10028 + */
10029 +extern int cvmx_helper_get_interface_index_num(int ipd_port);
10030 +
10031 +#endif /* __CVMX_HELPER_H__ */
10032 diff --git a/drivers/staging/octeon/cvmx-helper-xaui.c b/drivers/staging/octeon/cvmx-helper-xaui.c
10033 new file mode 100644
10034 index 0000000..a11e676
10035 --- /dev/null
10036 +++ b/drivers/staging/octeon/cvmx-helper-xaui.c
10037 @@ -0,0 +1,348 @@
10038 +/***********************license start***************
10039 + * Author: Cavium Networks
10040 + *
10041 + * Contact: support@caviumnetworks.com
10042 + * This file is part of the OCTEON SDK
10043 + *
10044 + * Copyright (c) 2003-2008 Cavium Networks
10045 + *
10046 + * This file is free software; you can redistribute it and/or modify
10047 + * it under the terms of the GNU General Public License, Version 2, as
10048 + * published by the Free Software Foundation.
10049 + *
10050 + * This file is distributed in the hope that it will be useful, but
10051 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
10052 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
10053 + * NONINFRINGEMENT. See the GNU General Public License for more
10054 + * details.
10055 + *
10056 + * You should have received a copy of the GNU General Public License
10057 + * along with this file; if not, write to the Free Software
10058 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10059 + * or visit http://www.gnu.org/licenses/.
10060 + *
10061 + * This file may also be available under a different license from Cavium.
10062 + * Contact Cavium Networks for more information
10063 + ***********************license end**************************************/
10064 +
10065 +/*
10066 + * Functions for XAUI initialization, configuration,
10067 + * and monitoring.
10068 + *
10069 + */
10070 +
10071 +#include <asm/octeon/octeon.h>
10072 +
10073 +#include "cvmx-config.h"
10074 +
10075 +#include "cvmx-helper.h"
10076 +
10077 +#include "cvmx-pko-defs.h"
10078 +#include "cvmx-gmxx-defs.h"
10079 +#include "cvmx-pcsxx-defs.h"
10080 +
10081 +void __cvmx_interrupt_gmxx_enable(int interface);
10082 +void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
10083 +void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
10084 +/**
10085 + * Probe a XAUI interface and determine the number of ports
10086 + * connected to it. The XAUI interface should still be down
10087 + * after this call.
10088 + *
10089 + * @interface: Interface to probe
10090 + *
10091 + * Returns Number of ports on the interface. Zero to disable.
10092 + */
10093 +int __cvmx_helper_xaui_probe(int interface)
10094 +{
10095 + int i;
10096 + union cvmx_gmxx_hg2_control gmx_hg2_control;
10097 + union cvmx_gmxx_inf_mode mode;
10098 +
10099 + /*
10100 + * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
10101 + * interface needs to be enabled before IPD otherwise per port
10102 + * backpressure may not work properly.
10103 + */
10104 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
10105 + mode.s.en = 1;
10106 + cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
10107 +
10108 + __cvmx_helper_setup_gmx(interface, 1);
10109 +
10110 + /*
10111 + * Setup PKO to support 16 ports for HiGig2 virtual
10112 + * ports. We're pointing all of the PKO packet ports for this
10113 + * interface to the XAUI. This allows us to use HiGig2
10114 + * backpressure per port.
10115 + */
10116 + for (i = 0; i < 16; i++) {
10117 + union cvmx_pko_mem_port_ptrs pko_mem_port_ptrs;
10118 + pko_mem_port_ptrs.u64 = 0;
10119 + /*
10120 + * We set each PKO port to have equal priority in a
10121 + * round robin fashion.
10122 + */
10123 + pko_mem_port_ptrs.s.static_p = 0;
10124 + pko_mem_port_ptrs.s.qos_mask = 0xff;
10125 + /* All PKO ports map to the same XAUI hardware port */
10126 + pko_mem_port_ptrs.s.eid = interface * 4;
10127 + pko_mem_port_ptrs.s.pid = interface * 16 + i;
10128 + cvmx_write_csr(CVMX_PKO_MEM_PORT_PTRS, pko_mem_port_ptrs.u64);
10129 + }
10130 +
10131 + /* If HiGig2 is enabled return 16 ports, otherwise return 1 port */
10132 + gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface));
10133 + if (gmx_hg2_control.s.hg2tx_en)
10134 + return 16;
10135 + else
10136 + return 1;
10137 +}
10138 +
10139 +/**
10140 + * Bringup and enable a XAUI interface. After this call packet
10141 + * I/O should be fully functional. This is called with IPD
10142 + * enabled but PKO disabled.
10143 + *
10144 + * @interface: Interface to bring up
10145 + *
10146 + * Returns Zero on success, negative on failure
10147 + */
10148 +int __cvmx_helper_xaui_enable(int interface)
10149 +{
10150 + union cvmx_gmxx_prtx_cfg gmx_cfg;
10151 + union cvmx_pcsxx_control1_reg xauiCtl;
10152 + union cvmx_pcsxx_misc_ctl_reg xauiMiscCtl;
10153 + union cvmx_gmxx_tx_xaui_ctl gmxXauiTxCtl;
10154 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
10155 + union cvmx_gmxx_tx_int_en gmx_tx_int_en;
10156 + union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
10157 +
10158 + /* (1) Interface has already been enabled. */
10159 +
10160 + /* (2) Disable GMX. */
10161 + xauiMiscCtl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface));
10162 + xauiMiscCtl.s.gmxeno = 1;
10163 + cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
10164 +
10165 + /* (3) Disable GMX and PCSX interrupts. */
10166 + gmx_rx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_EN(0, interface));
10167 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
10168 + gmx_tx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_TX_INT_EN(interface));
10169 + cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
10170 + pcsx_int_en_reg.u64 = cvmx_read_csr(CVMX_PCSXX_INT_EN_REG(interface));
10171 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
10172 +
10173 + /* (4) Bring up the PCSX and GMX reconciliation layer. */
10174 + /* (4)a Set polarity and lane swapping. */
10175 + /* (4)b */
10176 + gmxXauiTxCtl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10177 + /* Enable better IFG packing and improves performance */
10178 + gmxXauiTxCtl.s.dic_en = 1;
10179 + gmxXauiTxCtl.s.uni_en = 0;
10180 + cvmx_write_csr(CVMX_GMXX_TX_XAUI_CTL(interface), gmxXauiTxCtl.u64);
10181 +
10182 + /* (4)c Aply reset sequence */
10183 + xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
10184 + xauiCtl.s.lo_pwr = 0;
10185 + xauiCtl.s.reset = 1;
10186 + cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
10187 +
10188 + /* Wait for PCS to come out of reset */
10189 + if (CVMX_WAIT_FOR_FIELD64
10190 + (CVMX_PCSXX_CONTROL1_REG(interface), union cvmx_pcsxx_control1_reg,
10191 + reset, ==, 0, 10000))
10192 + return -1;
10193 + /* Wait for PCS to be aligned */
10194 + if (CVMX_WAIT_FOR_FIELD64
10195 + (CVMX_PCSXX_10GBX_STATUS_REG(interface),
10196 + union cvmx_pcsxx_10gbx_status_reg, alignd, ==, 1, 10000))
10197 + return -1;
10198 + /* Wait for RX to be ready */
10199 + if (CVMX_WAIT_FOR_FIELD64
10200 + (CVMX_GMXX_RX_XAUI_CTL(interface), union cvmx_gmxx_rx_xaui_ctl,
10201 + status, ==, 0, 10000))
10202 + return -1;
10203 +
10204 + /* (6) Configure GMX */
10205 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10206 + gmx_cfg.s.en = 0;
10207 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10208 +
10209 + /* Wait for GMX RX to be idle */
10210 + if (CVMX_WAIT_FOR_FIELD64
10211 + (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
10212 + rx_idle, ==, 1, 10000))
10213 + return -1;
10214 + /* Wait for GMX TX to be idle */
10215 + if (CVMX_WAIT_FOR_FIELD64
10216 + (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
10217 + tx_idle, ==, 1, 10000))
10218 + return -1;
10219 +
10220 + /* GMX configure */
10221 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10222 + gmx_cfg.s.speed = 1;
10223 + gmx_cfg.s.speed_msb = 0;
10224 + gmx_cfg.s.slottime = 1;
10225 + cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), 1);
10226 + cvmx_write_csr(CVMX_GMXX_TXX_SLOT(0, interface), 512);
10227 + cvmx_write_csr(CVMX_GMXX_TXX_BURST(0, interface), 8192);
10228 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10229 +
10230 + /* (7) Clear out any error state */
10231 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(0, interface),
10232 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(0, interface)));
10233 + cvmx_write_csr(CVMX_GMXX_TX_INT_REG(interface),
10234 + cvmx_read_csr(CVMX_GMXX_TX_INT_REG(interface)));
10235 + cvmx_write_csr(CVMX_PCSXX_INT_REG(interface),
10236 + cvmx_read_csr(CVMX_PCSXX_INT_REG(interface)));
10237 +
10238 + /* Wait for receive link */
10239 + if (CVMX_WAIT_FOR_FIELD64
10240 + (CVMX_PCSXX_STATUS1_REG(interface), union cvmx_pcsxx_status1_reg,
10241 + rcv_lnk, ==, 1, 10000))
10242 + return -1;
10243 + if (CVMX_WAIT_FOR_FIELD64
10244 + (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
10245 + xmtflt, ==, 0, 10000))
10246 + return -1;
10247 + if (CVMX_WAIT_FOR_FIELD64
10248 + (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
10249 + rcvflt, ==, 0, 10000))
10250 + return -1;
10251 +
10252 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), gmx_rx_int_en.u64);
10253 + cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
10254 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64);
10255 +
10256 + cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port(interface, 0));
10257 +
10258 + /* (8) Enable packet reception */
10259 + xauiMiscCtl.s.gmxeno = 0;
10260 + cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
10261 +
10262 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
10263 + gmx_cfg.s.en = 1;
10264 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
10265 +
10266 + __cvmx_interrupt_pcsx_intx_en_reg_enable(0, interface);
10267 + __cvmx_interrupt_pcsx_intx_en_reg_enable(1, interface);
10268 + __cvmx_interrupt_pcsx_intx_en_reg_enable(2, interface);
10269 + __cvmx_interrupt_pcsx_intx_en_reg_enable(3, interface);
10270 + __cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
10271 + __cvmx_interrupt_gmxx_enable(interface);
10272 +
10273 + return 0;
10274 +}
10275 +
10276 +/**
10277 + * Return the link state of an IPD/PKO port as returned by
10278 + * auto negotiation. The result of this function may not match
10279 + * Octeon's link config if auto negotiation has changed since
10280 + * the last call to cvmx_helper_link_set().
10281 + *
10282 + * @ipd_port: IPD/PKO port to query
10283 + *
10284 + * Returns Link state
10285 + */
10286 +cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port)
10287 +{
10288 + int interface = cvmx_helper_get_interface_num(ipd_port);
10289 + union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
10290 + union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
10291 + union cvmx_pcsxx_status1_reg pcsxx_status1_reg;
10292 + cvmx_helper_link_info_t result;
10293 +
10294 + gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10295 + gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
10296 + pcsxx_status1_reg.u64 =
10297 + cvmx_read_csr(CVMX_PCSXX_STATUS1_REG(interface));
10298 + result.u64 = 0;
10299 +
10300 + /* Only return a link if both RX and TX are happy */
10301 + if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0) &&
10302 + (pcsxx_status1_reg.s.rcv_lnk == 1)) {
10303 + result.s.link_up = 1;
10304 + result.s.full_duplex = 1;
10305 + result.s.speed = 10000;
10306 + } else {
10307 + /* Disable GMX and PCSX interrupts. */
10308 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
10309 + cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
10310 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
10311 + }
10312 + return result;
10313 +}
10314 +
10315 +/**
10316 + * Configure an IPD/PKO port for the specified link state. This
10317 + * function does not influence auto negotiation at the PHY level.
10318 + * The passed link state must always match the link state returned
10319 + * by cvmx_helper_link_get(). It is normally best to use
10320 + * cvmx_helper_link_autoconf() instead.
10321 + *
10322 + * @ipd_port: IPD/PKO port to configure
10323 + * @link_info: The new link state
10324 + *
10325 + * Returns Zero on success, negative on failure
10326 + */
10327 +int __cvmx_helper_xaui_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
10328 +{
10329 + int interface = cvmx_helper_get_interface_num(ipd_port);
10330 + union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
10331 + union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
10332 +
10333 + gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
10334 + gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
10335 +
10336 + /* If the link shouldn't be up, then just return */
10337 + if (!link_info.s.link_up)
10338 + return 0;
10339 +
10340 + /* Do nothing if both RX and TX are happy */
10341 + if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0))
10342 + return 0;
10343 +
10344 + /* Bring the link up */
10345 + return __cvmx_helper_xaui_enable(interface);
10346 +}
10347 +
10348 +/**
10349 + * Configure a port for internal and/or external loopback. Internal loopback
10350 + * causes packets sent by the port to be received by Octeon. External loopback
10351 + * causes packets received from the wire to sent out again.
10352 + *
10353 + * @ipd_port: IPD/PKO port to loopback.
10354 + * @enable_internal:
10355 + * Non zero if you want internal loopback
10356 + * @enable_external:
10357 + * Non zero if you want external loopback
10358 + *
10359 + * Returns Zero on success, negative on failure.
10360 + */
10361 +extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
10362 + int enable_internal,
10363 + int enable_external)
10364 +{
10365 + int interface = cvmx_helper_get_interface_num(ipd_port);
10366 + union cvmx_pcsxx_control1_reg pcsxx_control1_reg;
10367 + union cvmx_gmxx_xaui_ext_loopback gmxx_xaui_ext_loopback;
10368 +
10369 + /* Set the internal loop */
10370 + pcsxx_control1_reg.u64 =
10371 + cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
10372 + pcsxx_control1_reg.s.loopbck1 = enable_internal;
10373 + cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface),
10374 + pcsxx_control1_reg.u64);
10375 +
10376 + /* Set the external loop */
10377 + gmxx_xaui_ext_loopback.u64 =
10378 + cvmx_read_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface));
10379 + gmxx_xaui_ext_loopback.s.en = enable_external;
10380 + cvmx_write_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface),
10381 + gmxx_xaui_ext_loopback.u64);
10382 +
10383 + /* Take the link through a reset */
10384 + return __cvmx_helper_xaui_enable(interface);
10385 +}
10386 diff --git a/drivers/staging/octeon/cvmx-helper-xaui.h b/drivers/staging/octeon/cvmx-helper-xaui.h
10387 new file mode 100644
10388 index 0000000..4b4db2f
10389 --- /dev/null
10390 +++ b/drivers/staging/octeon/cvmx-helper-xaui.h
10391 @@ -0,0 +1,103 @@
10392 +/***********************license start***************
10393 + * Author: Cavium Networks
10394 + *
10395 + * Contact: support@caviumnetworks.com
10396 + * This file is part of the OCTEON SDK
10397 + *
10398 + * Copyright (c) 2003-2008 Cavium Networks
10399 + *
10400 + * This file is free software; you can redistribute it and/or modify
10401 + * it under the terms of the GNU General Public License, Version 2, as
10402 + * published by the Free Software Foundation.
10403 + *
10404 + * This file is distributed in the hope that it will be useful, but
10405 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
10406 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
10407 + * NONINFRINGEMENT. See the GNU General Public License for more
10408 + * details.
10409 + *
10410 + * You should have received a copy of the GNU General Public License
10411 + * along with this file; if not, write to the Free Software
10412 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10413 + * or visit http://www.gnu.org/licenses/.
10414 + *
10415 + * This file may also be available under a different license from Cavium.
10416 + * Contact Cavium Networks for more information
10417 + ***********************license end**************************************/
10418 +
10419 +/**
10420 + * @file
10421 + *
10422 + * Functions for XAUI initialization, configuration,
10423 + * and monitoring.
10424 + *
10425 + */
10426 +#ifndef __CVMX_HELPER_XAUI_H__
10427 +#define __CVMX_HELPER_XAUI_H__
10428 +
10429 +/**
10430 + * Probe a XAUI interface and determine the number of ports
10431 + * connected to it. The XAUI interface should still be down
10432 + * after this call.
10433 + *
10434 + * @interface: Interface to probe
10435 + *
10436 + * Returns Number of ports on the interface. Zero to disable.
10437 + */
10438 +extern int __cvmx_helper_xaui_probe(int interface);
10439 +
10440 +/**
10441 + * Bringup and enable a XAUI interface. After this call packet
10442 + * I/O should be fully functional. This is called with IPD
10443 + * enabled but PKO disabled.
10444 + *
10445 + * @interface: Interface to bring up
10446 + *
10447 + * Returns Zero on success, negative on failure
10448 + */
10449 +extern int __cvmx_helper_xaui_enable(int interface);
10450 +
10451 +/**
10452 + * Return the link state of an IPD/PKO port as returned by
10453 + * auto negotiation. The result of this function may not match
10454 + * Octeon's link config if auto negotiation has changed since
10455 + * the last call to cvmx_helper_link_set().
10456 + *
10457 + * @ipd_port: IPD/PKO port to query
10458 + *
10459 + * Returns Link state
10460 + */
10461 +extern cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port);
10462 +
10463 +/**
10464 + * Configure an IPD/PKO port for the specified link state. This
10465 + * function does not influence auto negotiation at the PHY level.
10466 + * The passed link state must always match the link state returned
10467 + * by cvmx_helper_link_get(). It is normally best to use
10468 + * cvmx_helper_link_autoconf() instead.
10469 + *
10470 + * @ipd_port: IPD/PKO port to configure
10471 + * @link_info: The new link state
10472 + *
10473 + * Returns Zero on success, negative on failure
10474 + */
10475 +extern int __cvmx_helper_xaui_link_set(int ipd_port,
10476 + cvmx_helper_link_info_t link_info);
10477 +
10478 +/**
10479 + * Configure a port for internal and/or external loopback. Internal loopback
10480 + * causes packets sent by the port to be received by Octeon. External loopback
10481 + * causes packets received from the wire to sent out again.
10482 + *
10483 + * @ipd_port: IPD/PKO port to loopback.
10484 + * @enable_internal:
10485 + * Non zero if you want internal loopback
10486 + * @enable_external:
10487 + * Non zero if you want external loopback
10488 + *
10489 + * Returns Zero on success, negative on failure.
10490 + */
10491 +extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
10492 + int enable_internal,
10493 + int enable_external);
10494 +#endif
10495 diff --git a/drivers/staging/octeon/cvmx-helper.c b/drivers/staging/octeon/cvmx-helper.c
10496 new file mode 100644
10497 index 0000000..5915066
10498 --- /dev/null
10499 +++ b/drivers/staging/octeon/cvmx-helper.c
10500 @@ -0,0 +1,1058 @@
10501 +/***********************license start***************
10502 + * Author: Cavium Networks
10503 + *
10504 + * Contact: support@caviumnetworks.com
10505 + * This file is part of the OCTEON SDK
10506 + *
10507 + * Copyright (c) 2003-2008 Cavium Networks
10508 + *
10509 + * This file is free software; you can redistribute it and/or modify
10510 + * it under the terms of the GNU General Public License, Version 2, as
10511 + * published by the Free Software Foundation.
10512 + *
10513 + * This file is distributed in the hope that it will be useful, but
10514 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
10515 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
10516 + * NONINFRINGEMENT. See the GNU General Public License for more
10517 + * details.
10518 + *
10519 + * You should have received a copy of the GNU General Public License
10520 + * along with this file; if not, write to the Free Software
10521 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10522 + * or visit http://www.gnu.org/licenses/.
10523 + *
10524 + * This file may also be available under a different license from Cavium.
10525 + * Contact Cavium Networks for more information
10526 + ***********************license end**************************************/
10527 +
10528 +/*
10529 + *
10530 + * Helper functions for common, but complicated tasks.
10531 + *
10532 + */
10533 +#include <asm/octeon/octeon.h>
10534 +
10535 +#include "cvmx-config.h"
10536 +
10537 +#include "cvmx-fpa.h"
10538 +#include "cvmx-pip.h"
10539 +#include "cvmx-pko.h"
10540 +#include "cvmx-ipd.h"
10541 +#include "cvmx-spi.h"
10542 +#include "cvmx-helper.h"
10543 +#include "cvmx-helper-board.h"
10544 +
10545 +#include "cvmx-pip-defs.h"
10546 +#include "cvmx-smix-defs.h"
10547 +#include "cvmx-asxx-defs.h"
10548 +
10549 +/**
10550 + * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
10551 + * priorities[16]) is a function pointer. It is meant to allow
10552 + * customization of the PKO queue priorities based on the port
10553 + * number. Users should set this pointer to a function before
10554 + * calling any cvmx-helper operations.
10555 + */
10556 +void (*cvmx_override_pko_queue_priority) (int pko_port,
10557 + uint64_t priorities[16]);
10558 +
10559 +/**
10560 + * cvmx_override_ipd_port_setup(int ipd_port) is a function
10561 + * pointer. It is meant to allow customization of the IPD port
10562 + * setup before packet input/output comes online. It is called
10563 + * after cvmx-helper does the default IPD configuration, but
10564 + * before IPD is enabled. Users should set this pointer to a
10565 + * function before calling any cvmx-helper operations.
10566 + */
10567 +void (*cvmx_override_ipd_port_setup) (int ipd_port);
10568 +
10569 +/* Port count per interface */
10570 +static int interface_port_count[4] = { 0, 0, 0, 0 };
10571 +
10572 +/* Port last configured link info index by IPD/PKO port */
10573 +static cvmx_helper_link_info_t
10574 + port_link_info[CVMX_PIP_NUM_INPUT_PORTS];
10575 +
10576 +/**
10577 + * Return the number of interfaces the chip has. Each interface
10578 + * may have multiple ports. Most chips support two interfaces,
10579 + * but the CNX0XX and CNX1XX are exceptions. These only support
10580 + * one interface.
10581 + *
10582 + * Returns Number of interfaces on chip
10583 + */
10584 +int cvmx_helper_get_number_of_interfaces(void)
10585 +{
10586 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
10587 + return 4;
10588 + else
10589 + return 3;
10590 +}
10591 +
10592 +/**
10593 + * Return the number of ports on an interface. Depending on the
10594 + * chip and configuration, this can be 1-16. A value of 0
10595 + * specifies that the interface doesn't exist or isn't usable.
10596 + *
10597 + * @interface: Interface to get the port count for
10598 + *
10599 + * Returns Number of ports on interface. Can be Zero.
10600 + */
10601 +int cvmx_helper_ports_on_interface(int interface)
10602 +{
10603 + return interface_port_count[interface];
10604 +}
10605 +
10606 +/**
10607 + * Get the operating mode of an interface. Depending on the Octeon
10608 + * chip and configuration, this function returns an enumeration
10609 + * of the type of packet I/O supported by an interface.
10610 + *
10611 + * @interface: Interface to probe
10612 + *
10613 + * Returns Mode of the interface. Unknown or unsupported interfaces return
10614 + * DISABLED.
10615 + */
10616 +cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
10617 +{
10618 + union cvmx_gmxx_inf_mode mode;
10619 + if (interface == 2)
10620 + return CVMX_HELPER_INTERFACE_MODE_NPI;
10621 +
10622 + if (interface == 3) {
10623 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)
10624 + || OCTEON_IS_MODEL(OCTEON_CN52XX))
10625 + return CVMX_HELPER_INTERFACE_MODE_LOOP;
10626 + else
10627 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10628 + }
10629 +
10630 + if (interface == 0
10631 + && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
10632 + && cvmx_sysinfo_get()->board_rev_major == 1) {
10633 + /*
10634 + * Lie about interface type of CN3005 board. This
10635 + * board has a switch on port 1 like the other
10636 + * evaluation boards, but it is connected over RGMII
10637 + * instead of GMII. Report GMII mode so that the
10638 + * speed is forced to 1 Gbit full duplex. Other than
10639 + * some initial configuration (which does not use the
10640 + * output of this function) there is no difference in
10641 + * setup between GMII and RGMII modes.
10642 + */
10643 + return CVMX_HELPER_INTERFACE_MODE_GMII;
10644 + }
10645 +
10646 + /* Interface 1 is always disabled on CN31XX and CN30XX */
10647 + if ((interface == 1)
10648 + && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
10649 + || OCTEON_IS_MODEL(OCTEON_CN50XX)
10650 + || OCTEON_IS_MODEL(OCTEON_CN52XX)))
10651 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10652 +
10653 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
10654 +
10655 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
10656 + switch (mode.cn56xx.mode) {
10657 + case 0:
10658 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10659 + case 1:
10660 + return CVMX_HELPER_INTERFACE_MODE_XAUI;
10661 + case 2:
10662 + return CVMX_HELPER_INTERFACE_MODE_SGMII;
10663 + case 3:
10664 + return CVMX_HELPER_INTERFACE_MODE_PICMG;
10665 + default:
10666 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10667 + }
10668 + } else {
10669 + if (!mode.s.en)
10670 + return CVMX_HELPER_INTERFACE_MODE_DISABLED;
10671 +
10672 + if (mode.s.type) {
10673 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
10674 + || OCTEON_IS_MODEL(OCTEON_CN58XX))
10675 + return CVMX_HELPER_INTERFACE_MODE_SPI;
10676 + else
10677 + return CVMX_HELPER_INTERFACE_MODE_GMII;
10678 + } else
10679 + return CVMX_HELPER_INTERFACE_MODE_RGMII;
10680 + }
10681 +}
10682 +
10683 +/**
10684 + * Configure the IPD/PIP tagging and QoS options for a specific
10685 + * port. This function determines the POW work queue entry
10686 + * contents for a port. The setup performed here is controlled by
10687 + * the defines in executive-config.h.
10688 + *
10689 + * @ipd_port: Port to configure. This follows the IPD numbering, not the
10690 + * per interface numbering
10691 + *
10692 + * Returns Zero on success, negative on failure
10693 + */
10694 +static int __cvmx_helper_port_setup_ipd(int ipd_port)
10695 +{
10696 + union cvmx_pip_prt_cfgx port_config;
10697 + union cvmx_pip_prt_tagx tag_config;
10698 +
10699 + port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
10700 + tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
10701 +
10702 + /* Have each port go to a different POW queue */
10703 + port_config.s.qos = ipd_port & 0x7;
10704 +
10705 + /* Process the headers and place the IP header in the work queue */
10706 + port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
10707 +
10708 + tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
10709 + tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
10710 + tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
10711 + tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
10712 + tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
10713 + tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
10714 + tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
10715 + tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
10716 + tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
10717 + tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
10718 + tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
10719 + tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10720 + tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10721 + tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10722 + tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10723 + tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
10724 + /* Put all packets in group 0. Other groups can be used by the app */
10725 + tag_config.s.grp = 0;
10726 +
10727 + cvmx_pip_config_port(ipd_port, port_config, tag_config);
10728 +
10729 + /* Give the user a chance to override our setting for each port */
10730 + if (cvmx_override_ipd_port_setup)
10731 + cvmx_override_ipd_port_setup(ipd_port);
10732 +
10733 + return 0;
10734 +}
10735 +
10736 +/**
10737 + * This function probes an interface to determine the actual
10738 + * number of hardware ports connected to it. It doesn't setup the
10739 + * ports or enable them. The main goal here is to set the global
10740 + * interface_port_count[interface] correctly. Hardware setup of the
10741 + * ports will be performed later.
10742 + *
10743 + * @interface: Interface to probe
10744 + *
10745 + * Returns Zero on success, negative on failure
10746 + */
10747 +int cvmx_helper_interface_probe(int interface)
10748 +{
10749 + /* At this stage in the game we don't want packets to be moving yet.
10750 + The following probe calls should perform hardware setup
10751 + needed to determine port counts. Receive must still be disabled */
10752 + switch (cvmx_helper_interface_get_mode(interface)) {
10753 + /* These types don't support ports to IPD/PKO */
10754 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10755 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
10756 + interface_port_count[interface] = 0;
10757 + break;
10758 + /* XAUI is a single high speed port */
10759 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
10760 + interface_port_count[interface] =
10761 + __cvmx_helper_xaui_probe(interface);
10762 + break;
10763 + /*
10764 + * RGMII/GMII/MII are all treated about the same. Most
10765 + * functions refer to these ports as RGMII.
10766 + */
10767 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
10768 + case CVMX_HELPER_INTERFACE_MODE_GMII:
10769 + interface_port_count[interface] =
10770 + __cvmx_helper_rgmii_probe(interface);
10771 + break;
10772 + /*
10773 + * SPI4 can have 1-16 ports depending on the device at
10774 + * the other end.
10775 + */
10776 + case CVMX_HELPER_INTERFACE_MODE_SPI:
10777 + interface_port_count[interface] =
10778 + __cvmx_helper_spi_probe(interface);
10779 + break;
10780 + /*
10781 + * SGMII can have 1-4 ports depending on how many are
10782 + * hooked up.
10783 + */
10784 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
10785 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
10786 + interface_port_count[interface] =
10787 + __cvmx_helper_sgmii_probe(interface);
10788 + break;
10789 + /* PCI target Network Packet Interface */
10790 + case CVMX_HELPER_INTERFACE_MODE_NPI:
10791 + interface_port_count[interface] =
10792 + __cvmx_helper_npi_probe(interface);
10793 + break;
10794 + /*
10795 + * Special loopback only ports. These are not the same
10796 + * as other ports in loopback mode.
10797 + */
10798 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
10799 + interface_port_count[interface] =
10800 + __cvmx_helper_loop_probe(interface);
10801 + break;
10802 + }
10803 +
10804 + interface_port_count[interface] =
10805 + __cvmx_helper_board_interface_probe(interface,
10806 + interface_port_count
10807 + [interface]);
10808 +
10809 + /* Make sure all global variables propagate to other cores */
10810 + CVMX_SYNCWS;
10811 +
10812 + return 0;
10813 +}
10814 +
10815 +/**
10816 + * Setup the IPD/PIP for the ports on an interface. Packet
10817 + * classification and tagging are set for every port on the
10818 + * interface. The number of ports on the interface must already
10819 + * have been probed.
10820 + *
10821 + * @interface: Interface to setup IPD/PIP for
10822 + *
10823 + * Returns Zero on success, negative on failure
10824 + */
10825 +static int __cvmx_helper_interface_setup_ipd(int interface)
10826 +{
10827 + int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
10828 + int num_ports = interface_port_count[interface];
10829 +
10830 + while (num_ports--) {
10831 + __cvmx_helper_port_setup_ipd(ipd_port);
10832 + ipd_port++;
10833 + }
10834 + return 0;
10835 +}
10836 +
10837 +/**
10838 + * Setup global setting for IPD/PIP not related to a specific
10839 + * interface or port. This must be called before IPD is enabled.
10840 + *
10841 + * Returns Zero on success, negative on failure.
10842 + */
10843 +static int __cvmx_helper_global_setup_ipd(void)
10844 +{
10845 + /* Setup the global packet input options */
10846 + cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8,
10847 + CVMX_HELPER_FIRST_MBUFF_SKIP / 8,
10848 + CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8,
10849 + /* The +8 is to account for the next ptr */
10850 + (CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128,
10851 + /* The +8 is to account for the next ptr */
10852 + (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128,
10853 + CVMX_FPA_WQE_POOL,
10854 + CVMX_IPD_OPC_MODE_STT,
10855 + CVMX_HELPER_ENABLE_BACK_PRESSURE);
10856 + return 0;
10857 +}
10858 +
10859 +/**
10860 + * Setup the PKO for the ports on an interface. The number of
10861 + * queues per port and the priority of each PKO output queue
10862 + * is set here. PKO must be disabled when this function is called.
10863 + *
10864 + * @interface: Interface to setup PKO for
10865 + *
10866 + * Returns Zero on success, negative on failure
10867 + */
10868 +static int __cvmx_helper_interface_setup_pko(int interface)
10869 +{
10870 + /*
10871 + * Each packet output queue has an associated priority. The
10872 + * higher the priority, the more often it can send a packet. A
10873 + * priority of 8 means it can send in all 8 rounds of
10874 + * contention. We're going to make each queue one less than
10875 + * the last. The vector of priorities has been extended to
10876 + * support CN5xxx CPUs, where up to 16 queues can be
10877 + * associated to a port. To keep backward compatibility we
10878 + * don't change the initial 8 priorities and replicate them in
10879 + * the second half. With per-core PKO queues (PKO lockless
10880 + * operation) all queues have the same priority.
10881 + */
10882 + uint64_t priorities[16] =
10883 + { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
10884 +
10885 + /*
10886 + * Setup the IPD/PIP and PKO for the ports discovered
10887 + * above. Here packet classification, tagging and output
10888 + * priorities are set.
10889 + */
10890 + int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
10891 + int num_ports = interface_port_count[interface];
10892 + while (num_ports--) {
10893 + /*
10894 + * Give the user a chance to override the per queue
10895 + * priorities.
10896 + */
10897 + if (cvmx_override_pko_queue_priority)
10898 + cvmx_override_pko_queue_priority(ipd_port, priorities);
10899 +
10900 + cvmx_pko_config_port(ipd_port,
10901 + cvmx_pko_get_base_queue_per_core(ipd_port,
10902 + 0),
10903 + cvmx_pko_get_num_queues(ipd_port),
10904 + priorities);
10905 + ipd_port++;
10906 + }
10907 + return 0;
10908 +}
10909 +
10910 +/**
10911 + * Setup global setting for PKO not related to a specific
10912 + * interface or port. This must be called before PKO is enabled.
10913 + *
10914 + * Returns Zero on success, negative on failure.
10915 + */
10916 +static int __cvmx_helper_global_setup_pko(void)
10917 +{
10918 + /*
10919 + * Disable tagwait FAU timeout. This needs to be done before
10920 + * anyone might start packet output using tags.
10921 + */
10922 + union cvmx_iob_fau_timeout fau_to;
10923 + fau_to.u64 = 0;
10924 + fau_to.s.tout_val = 0xfff;
10925 + fau_to.s.tout_enb = 0;
10926 + cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
10927 + return 0;
10928 +}
10929 +
10930 +/**
10931 + * Setup global backpressure setting.
10932 + *
10933 + * Returns Zero on success, negative on failure
10934 + */
10935 +static int __cvmx_helper_global_setup_backpressure(void)
10936 +{
10937 +#if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
10938 + /* Disable backpressure if configured to do so */
10939 + /* Disable backpressure (pause frame) generation */
10940 + int num_interfaces = cvmx_helper_get_number_of_interfaces();
10941 + int interface;
10942 + for (interface = 0; interface < num_interfaces; interface++) {
10943 + switch (cvmx_helper_interface_get_mode(interface)) {
10944 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10945 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
10946 + case CVMX_HELPER_INTERFACE_MODE_NPI:
10947 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
10948 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
10949 + break;
10950 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
10951 + case CVMX_HELPER_INTERFACE_MODE_GMII:
10952 + case CVMX_HELPER_INTERFACE_MODE_SPI:
10953 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
10954 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
10955 + cvmx_gmx_set_backpressure_override(interface, 0xf);
10956 + break;
10957 + }
10958 + }
10959 +#endif
10960 +
10961 + return 0;
10962 +}
10963 +
10964 +/**
10965 + * Enable packet input/output from the hardware. This function is
10966 + * called after all internal setup is complete and IPD is enabled.
10967 + * After this function completes, packets will be accepted from the
10968 + * hardware ports. PKO should still be disabled to make sure packets
10969 + * aren't sent out partially setup hardware.
10970 + *
10971 + * @interface: Interface to enable
10972 + *
10973 + * Returns Zero on success, negative on failure
10974 + */
10975 +static int __cvmx_helper_packet_hardware_enable(int interface)
10976 +{
10977 + int result = 0;
10978 + switch (cvmx_helper_interface_get_mode(interface)) {
10979 + /* These types don't support ports to IPD/PKO */
10980 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
10981 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
10982 + /* Nothing to do */
10983 + break;
10984 + /* XAUI is a single high speed port */
10985 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
10986 + result = __cvmx_helper_xaui_enable(interface);
10987 + break;
10988 + /*
10989 + * RGMII/GMII/MII are all treated about the same. Most
10990 + * functions refer to these ports as RGMII
10991 + */
10992 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
10993 + case CVMX_HELPER_INTERFACE_MODE_GMII:
10994 + result = __cvmx_helper_rgmii_enable(interface);
10995 + break;
10996 + /*
10997 + * SPI4 can have 1-16 ports depending on the device at
10998 + * the other end
10999 + */
11000 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11001 + result = __cvmx_helper_spi_enable(interface);
11002 + break;
11003 + /*
11004 + * SGMII can have 1-4 ports depending on how many are
11005 + * hooked up
11006 + */
11007 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11008 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11009 + result = __cvmx_helper_sgmii_enable(interface);
11010 + break;
11011 + /* PCI target Network Packet Interface */
11012 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11013 + result = __cvmx_helper_npi_enable(interface);
11014 + break;
11015 + /*
11016 + * Special loopback only ports. These are not the same
11017 + * as other ports in loopback mode
11018 + */
11019 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
11020 + result = __cvmx_helper_loop_enable(interface);
11021 + break;
11022 + }
11023 + result |= __cvmx_helper_board_hardware_enable(interface);
11024 + return result;
11025 +}
11026 +
11027 +/**
11028 + * Function to adjust internal IPD pointer alignments
11029 + *
11030 + * Returns 0 on success
11031 + * !0 on failure
11032 + */
11033 +int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
11034 +{
11035 +#define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
11036 + (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
11037 +#define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
11038 + (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
11039 +#define FIX_IPD_OUTPORT 0
11040 + /* Ports 0-15 are interface 0, 16-31 are interface 1 */
11041 +#define INTERFACE(port) (port >> 4)
11042 +#define INDEX(port) (port & 0xf)
11043 + uint64_t *p64;
11044 + cvmx_pko_command_word0_t pko_command;
11045 + union cvmx_buf_ptr g_buffer, pkt_buffer;
11046 + cvmx_wqe_t *work;
11047 + int size, num_segs = 0, wqe_pcnt, pkt_pcnt;
11048 + union cvmx_gmxx_prtx_cfg gmx_cfg;
11049 + int retry_cnt;
11050 + int retry_loop_cnt;
11051 + int mtu;
11052 + int i;
11053 + cvmx_helper_link_info_t link_info;
11054 +
11055 + /* Save values for restore at end */
11056 + uint64_t prtx_cfg =
11057 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG
11058 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
11059 + uint64_t tx_ptr_en =
11060 + cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
11061 + uint64_t rx_ptr_en =
11062 + cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
11063 + uint64_t rxx_jabber =
11064 + cvmx_read_csr(CVMX_GMXX_RXX_JABBER
11065 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
11066 + uint64_t frame_max =
11067 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
11068 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
11069 +
11070 + /* Configure port to gig FDX as required for loopback mode */
11071 + cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
11072 +
11073 + /*
11074 + * Disable reception on all ports so if traffic is present it
11075 + * will not interfere.
11076 + */
11077 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
11078 +
11079 + cvmx_wait(100000000ull);
11080 +
11081 + for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) {
11082 + retry_cnt = 100000;
11083 + wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
11084 + pkt_pcnt = (wqe_pcnt >> 7) & 0x7f;
11085 + wqe_pcnt &= 0x7f;
11086 +
11087 + num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
11088 +
11089 + if (num_segs == 0)
11090 + goto fix_ipd_exit;
11091 +
11092 + num_segs += 1;
11093 +
11094 + size =
11095 + FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES +
11096 + ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) -
11097 + (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2);
11098 +
11099 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
11100 + 1 << INDEX(FIX_IPD_OUTPORT));
11101 + CVMX_SYNC;
11102 +
11103 + g_buffer.u64 = 0;
11104 + g_buffer.s.addr =
11105 + cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL));
11106 + if (g_buffer.s.addr == 0) {
11107 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11108 + "buffer allocation failure.\n");
11109 + goto fix_ipd_exit;
11110 + }
11111 +
11112 + g_buffer.s.pool = CVMX_FPA_WQE_POOL;
11113 + g_buffer.s.size = num_segs;
11114 +
11115 + pkt_buffer.u64 = 0;
11116 + pkt_buffer.s.addr =
11117 + cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL));
11118 + if (pkt_buffer.s.addr == 0) {
11119 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11120 + "buffer allocation failure.\n");
11121 + goto fix_ipd_exit;
11122 + }
11123 + pkt_buffer.s.i = 1;
11124 + pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL;
11125 + pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES;
11126 +
11127 + p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr);
11128 + p64[0] = 0xffffffffffff0000ull;
11129 + p64[1] = 0x08004510ull;
11130 + p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull;
11131 + p64[3] = 0x3a5fc0a81073c0a8ull;
11132 +
11133 + for (i = 0; i < num_segs; i++) {
11134 + if (i > 0)
11135 + pkt_buffer.s.size =
11136 + FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
11137 +
11138 + if (i == (num_segs - 1))
11139 + pkt_buffer.s.i = 0;
11140 +
11141 + *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
11142 + 8 * i) = pkt_buffer.u64;
11143 + }
11144 +
11145 + /* Build the PKO command */
11146 + pko_command.u64 = 0;
11147 + pko_command.s.segs = num_segs;
11148 + pko_command.s.total_bytes = size;
11149 + pko_command.s.dontfree = 0;
11150 + pko_command.s.gather = 1;
11151 +
11152 + gmx_cfg.u64 =
11153 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG
11154 + (INDEX(FIX_IPD_OUTPORT),
11155 + INTERFACE(FIX_IPD_OUTPORT)));
11156 + gmx_cfg.s.en = 1;
11157 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG
11158 + (INDEX(FIX_IPD_OUTPORT),
11159 + INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64);
11160 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11161 + 1 << INDEX(FIX_IPD_OUTPORT));
11162 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11163 + 1 << INDEX(FIX_IPD_OUTPORT));
11164 +
11165 + mtu =
11166 + cvmx_read_csr(CVMX_GMXX_RXX_JABBER
11167 + (INDEX(FIX_IPD_OUTPORT),
11168 + INTERFACE(FIX_IPD_OUTPORT)));
11169 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER
11170 + (INDEX(FIX_IPD_OUTPORT),
11171 + INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
11172 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
11173 + (INDEX(FIX_IPD_OUTPORT),
11174 + INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
11175 +
11176 + cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT,
11177 + cvmx_pko_get_base_queue
11178 + (FIX_IPD_OUTPORT),
11179 + CVMX_PKO_LOCK_CMD_QUEUE);
11180 + cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT,
11181 + cvmx_pko_get_base_queue
11182 + (FIX_IPD_OUTPORT), pko_command,
11183 + g_buffer, CVMX_PKO_LOCK_CMD_QUEUE);
11184 +
11185 + CVMX_SYNC;
11186 +
11187 + do {
11188 + work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
11189 + retry_cnt--;
11190 + } while ((work == NULL) && (retry_cnt > 0));
11191 +
11192 + if (!retry_cnt)
11193 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
11194 + "get_work() timeout occured.\n");
11195 +
11196 + /* Free packet */
11197 + if (work)
11198 + cvmx_helper_free_packet_data(work);
11199 + }
11200 +
11201 +fix_ipd_exit:
11202 +
11203 + /* Return CSR configs to saved values */
11204 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG
11205 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11206 + prtx_cfg);
11207 + cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11208 + tx_ptr_en);
11209 + cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
11210 + rx_ptr_en);
11211 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER
11212 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11213 + rxx_jabber);
11214 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
11215 + (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
11216 + frame_max);
11217 + cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0);
11218 + /* Set link to down so autonegotiation will set it up again */
11219 + link_info.u64 = 0;
11220 + cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info);
11221 +
11222 + /*
11223 + * Bring the link back up as autonegotiation is not done in
11224 + * user applications.
11225 + */
11226 + cvmx_helper_link_autoconf(FIX_IPD_OUTPORT);
11227 +
11228 + CVMX_SYNC;
11229 + if (num_segs)
11230 + cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
11231 +
11232 + return !!num_segs;
11233 +
11234 +}
11235 +
11236 +/**
11237 + * Called after all internal packet IO paths are setup. This
11238 + * function enables IPD/PIP and begins packet input and output.
11239 + *
11240 + * Returns Zero on success, negative on failure
11241 + */
11242 +int cvmx_helper_ipd_and_packet_input_enable(void)
11243 +{
11244 + int num_interfaces;
11245 + int interface;
11246 +
11247 + /* Enable IPD */
11248 + cvmx_ipd_enable();
11249 +
11250 + /*
11251 + * Time to enable hardware ports packet input and output. Note
11252 + * that at this point IPD/PIP must be fully functional and PKO
11253 + * must be disabled
11254 + */
11255 + num_interfaces = cvmx_helper_get_number_of_interfaces();
11256 + for (interface = 0; interface < num_interfaces; interface++) {
11257 + if (cvmx_helper_ports_on_interface(interface) > 0)
11258 + __cvmx_helper_packet_hardware_enable(interface);
11259 + }
11260 +
11261 + /* Finally enable PKO now that the entire path is up and running */
11262 + cvmx_pko_enable();
11263 +
11264 + if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
11265 + || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1))
11266 + && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
11267 + __cvmx_helper_errata_fix_ipd_ptr_alignment();
11268 + return 0;
11269 +}
11270 +
11271 +/**
11272 + * Initialize the PIP, IPD, and PKO hardware to support
11273 + * simple priority based queues for the ethernet ports. Each
11274 + * port is configured with a number of priority queues based
11275 + * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
11276 + * priority than the previous.
11277 + *
11278 + * Returns Zero on success, non-zero on failure
11279 + */
11280 +int cvmx_helper_initialize_packet_io_global(void)
11281 +{
11282 + int result = 0;
11283 + int interface;
11284 + union cvmx_l2c_cfg l2c_cfg;
11285 + union cvmx_smix_en smix_en;
11286 + const int num_interfaces = cvmx_helper_get_number_of_interfaces();
11287 +
11288 + /*
11289 + * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to
11290 + * be disabled.
11291 + */
11292 + if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
11293 + __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
11294 +
11295 + /*
11296 + * Tell L2 to give the IOB statically higher priority compared
11297 + * to the cores. This avoids conditions where IO blocks might
11298 + * be starved under very high L2 loads.
11299 + */
11300 + l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
11301 + l2c_cfg.s.lrf_arb_mode = 0;
11302 + l2c_cfg.s.rfb_arb_mode = 0;
11303 + cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
11304 +
11305 + /* Make sure SMI/MDIO is enabled so we can query PHYs */
11306 + smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
11307 + if (!smix_en.s.en) {
11308 + smix_en.s.en = 1;
11309 + cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
11310 + }
11311 +
11312 + /* Newer chips actually have two SMI/MDIO interfaces */
11313 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
11314 + !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
11315 + !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
11316 + smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
11317 + if (!smix_en.s.en) {
11318 + smix_en.s.en = 1;
11319 + cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
11320 + }
11321 + }
11322 +
11323 + cvmx_pko_initialize_global();
11324 + for (interface = 0; interface < num_interfaces; interface++) {
11325 + result |= cvmx_helper_interface_probe(interface);
11326 + if (cvmx_helper_ports_on_interface(interface) > 0)
11327 + cvmx_dprintf("Interface %d has %d ports (%s)\n",
11328 + interface,
11329 + cvmx_helper_ports_on_interface(interface),
11330 + cvmx_helper_interface_mode_to_string
11331 + (cvmx_helper_interface_get_mode
11332 + (interface)));
11333 + result |= __cvmx_helper_interface_setup_ipd(interface);
11334 + result |= __cvmx_helper_interface_setup_pko(interface);
11335 + }
11336 +
11337 + result |= __cvmx_helper_global_setup_ipd();
11338 + result |= __cvmx_helper_global_setup_pko();
11339 +
11340 + /* Enable any flow control and backpressure */
11341 + result |= __cvmx_helper_global_setup_backpressure();
11342 +
11343 +#if CVMX_HELPER_ENABLE_IPD
11344 + result |= cvmx_helper_ipd_and_packet_input_enable();
11345 +#endif
11346 + return result;
11347 +}
11348 +
11349 +/**
11350 + * Does core local initialization for packet io
11351 + *
11352 + * Returns Zero on success, non-zero on failure
11353 + */
11354 +int cvmx_helper_initialize_packet_io_local(void)
11355 +{
11356 + return cvmx_pko_initialize_local();
11357 +}
11358 +
11359 +/**
11360 + * Auto configure an IPD/PKO port link state and speed. This
11361 + * function basically does the equivalent of:
11362 + * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
11363 + *
11364 + * @ipd_port: IPD/PKO port to auto configure
11365 + *
11366 + * Returns Link state after configure
11367 + */
11368 +cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
11369 +{
11370 + cvmx_helper_link_info_t link_info;
11371 + int interface = cvmx_helper_get_interface_num(ipd_port);
11372 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11373 +
11374 + if (index >= cvmx_helper_ports_on_interface(interface)) {
11375 + link_info.u64 = 0;
11376 + return link_info;
11377 + }
11378 +
11379 + link_info = cvmx_helper_link_get(ipd_port);
11380 + if (link_info.u64 == port_link_info[ipd_port].u64)
11381 + return link_info;
11382 +
11383 + /* If we fail to set the link speed, port_link_info will not change */
11384 + cvmx_helper_link_set(ipd_port, link_info);
11385 +
11386 + /*
11387 + * port_link_info should be the current value, which will be
11388 + * different than expect if cvmx_helper_link_set() failed.
11389 + */
11390 + return port_link_info[ipd_port];
11391 +}
11392 +
11393 +/**
11394 + * Return the link state of an IPD/PKO port as returned by
11395 + * auto negotiation. The result of this function may not match
11396 + * Octeon's link config if auto negotiation has changed since
11397 + * the last call to cvmx_helper_link_set().
11398 + *
11399 + * @ipd_port: IPD/PKO port to query
11400 + *
11401 + * Returns Link state
11402 + */
11403 +cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
11404 +{
11405 + cvmx_helper_link_info_t result;
11406 + int interface = cvmx_helper_get_interface_num(ipd_port);
11407 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11408 +
11409 + /* The default result will be a down link unless the code below
11410 + changes it */
11411 + result.u64 = 0;
11412 +
11413 + if (index >= cvmx_helper_ports_on_interface(interface))
11414 + return result;
11415 +
11416 + switch (cvmx_helper_interface_get_mode(interface)) {
11417 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11418 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
11419 + /* Network links are not supported */
11420 + break;
11421 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11422 + result = __cvmx_helper_xaui_link_get(ipd_port);
11423 + break;
11424 + case CVMX_HELPER_INTERFACE_MODE_GMII:
11425 + if (index == 0)
11426 + result = __cvmx_helper_rgmii_link_get(ipd_port);
11427 + else {
11428 + result.s.full_duplex = 1;
11429 + result.s.link_up = 1;
11430 + result.s.speed = 1000;
11431 + }
11432 + break;
11433 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
11434 + result = __cvmx_helper_rgmii_link_get(ipd_port);
11435 + break;
11436 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11437 + result = __cvmx_helper_spi_link_get(ipd_port);
11438 + break;
11439 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11440 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11441 + result = __cvmx_helper_sgmii_link_get(ipd_port);
11442 + break;
11443 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11444 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
11445 + /* Network links are not supported */
11446 + break;
11447 + }
11448 + return result;
11449 +}
11450 +
11451 +/**
11452 + * Configure an IPD/PKO port for the specified link state. This
11453 + * function does not influence auto negotiation at the PHY level.
11454 + * The passed link state must always match the link state returned
11455 + * by cvmx_helper_link_get(). It is normally best to use
11456 + * cvmx_helper_link_autoconf() instead.
11457 + *
11458 + * @ipd_port: IPD/PKO port to configure
11459 + * @link_info: The new link state
11460 + *
11461 + * Returns Zero on success, negative on failure
11462 + */
11463 +int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
11464 +{
11465 + int result = -1;
11466 + int interface = cvmx_helper_get_interface_num(ipd_port);
11467 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11468 +
11469 + if (index >= cvmx_helper_ports_on_interface(interface))
11470 + return -1;
11471 +
11472 + switch (cvmx_helper_interface_get_mode(interface)) {
11473 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11474 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
11475 + break;
11476 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11477 + result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
11478 + break;
11479 + /*
11480 + * RGMII/GMII/MII are all treated about the same. Most
11481 + * functions refer to these ports as RGMII.
11482 + */
11483 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
11484 + case CVMX_HELPER_INTERFACE_MODE_GMII:
11485 + result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
11486 + break;
11487 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11488 + result = __cvmx_helper_spi_link_set(ipd_port, link_info);
11489 + break;
11490 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11491 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11492 + result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
11493 + break;
11494 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11495 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
11496 + break;
11497 + }
11498 + /* Set the port_link_info here so that the link status is updated
11499 + no matter how cvmx_helper_link_set is called. We don't change
11500 + the value if link_set failed */
11501 + if (result == 0)
11502 + port_link_info[ipd_port].u64 = link_info.u64;
11503 + return result;
11504 +}
11505 +
11506 +/**
11507 + * Configure a port for internal and/or external loopback. Internal loopback
11508 + * causes packets sent by the port to be received by Octeon. External loopback
11509 + * causes packets received from the wire to sent out again.
11510 + *
11511 + * @ipd_port: IPD/PKO port to loopback.
11512 + * @enable_internal:
11513 + * Non zero if you want internal loopback
11514 + * @enable_external:
11515 + * Non zero if you want external loopback
11516 + *
11517 + * Returns Zero on success, negative on failure.
11518 + */
11519 +int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
11520 + int enable_external)
11521 +{
11522 + int result = -1;
11523 + int interface = cvmx_helper_get_interface_num(ipd_port);
11524 + int index = cvmx_helper_get_interface_index_num(ipd_port);
11525 +
11526 + if (index >= cvmx_helper_ports_on_interface(interface))
11527 + return -1;
11528 +
11529 + switch (cvmx_helper_interface_get_mode(interface)) {
11530 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
11531 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
11532 + case CVMX_HELPER_INTERFACE_MODE_SPI:
11533 + case CVMX_HELPER_INTERFACE_MODE_NPI:
11534 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
11535 + break;
11536 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
11537 + result =
11538 + __cvmx_helper_xaui_configure_loopback(ipd_port,
11539 + enable_internal,
11540 + enable_external);
11541 + break;
11542 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
11543 + case CVMX_HELPER_INTERFACE_MODE_GMII:
11544 + result =
11545 + __cvmx_helper_rgmii_configure_loopback(ipd_port,
11546 + enable_internal,
11547 + enable_external);
11548 + break;
11549 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
11550 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
11551 + result =
11552 + __cvmx_helper_sgmii_configure_loopback(ipd_port,
11553 + enable_internal,
11554 + enable_external);
11555 + break;
11556 + }
11557 + return result;
11558 +}
11559 diff --git a/drivers/staging/octeon/cvmx-helper.h b/drivers/staging/octeon/cvmx-helper.h
11560 new file mode 100644
11561 index 0000000..51916f3
11562 --- /dev/null
11563 +++ b/drivers/staging/octeon/cvmx-helper.h
11564 @@ -0,0 +1,227 @@
11565 +/***********************license start***************
11566 + * Author: Cavium Networks
11567 + *
11568 + * Contact: support@caviumnetworks.com
11569 + * This file is part of the OCTEON SDK
11570 + *
11571 + * Copyright (c) 2003-2008 Cavium Networks
11572 + *
11573 + * This file is free software; you can redistribute it and/or modify
11574 + * it under the terms of the GNU General Public License, Version 2, as
11575 + * published by the Free Software Foundation.
11576 + *
11577 + * This file is distributed in the hope that it will be useful, but
11578 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
11579 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
11580 + * NONINFRINGEMENT. See the GNU General Public License for more
11581 + * details.
11582 + *
11583 + * You should have received a copy of the GNU General Public License
11584 + * along with this file; if not, write to the Free Software
11585 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11586 + * or visit http://www.gnu.org/licenses/.
11587 + *
11588 + * This file may also be available under a different license from Cavium.
11589 + * Contact Cavium Networks for more information
11590 + ***********************license end**************************************/
11591 +
11592 +/*
11593 + *
11594 + * Helper functions for common, but complicated tasks.
11595 + *
11596 + */
11597 +
11598 +#ifndef __CVMX_HELPER_H__
11599 +#define __CVMX_HELPER_H__
11600 +
11601 +#include "cvmx-config.h"
11602 +#include "cvmx-fpa.h"
11603 +#include "cvmx-wqe.h"
11604 +
11605 +typedef enum {
11606 + CVMX_HELPER_INTERFACE_MODE_DISABLED,
11607 + CVMX_HELPER_INTERFACE_MODE_RGMII,
11608 + CVMX_HELPER_INTERFACE_MODE_GMII,
11609 + CVMX_HELPER_INTERFACE_MODE_SPI,
11610 + CVMX_HELPER_INTERFACE_MODE_PCIE,
11611 + CVMX_HELPER_INTERFACE_MODE_XAUI,
11612 + CVMX_HELPER_INTERFACE_MODE_SGMII,
11613 + CVMX_HELPER_INTERFACE_MODE_PICMG,
11614 + CVMX_HELPER_INTERFACE_MODE_NPI,
11615 + CVMX_HELPER_INTERFACE_MODE_LOOP,
11616 +} cvmx_helper_interface_mode_t;
11617 +
11618 +typedef union {
11619 + uint64_t u64;
11620 + struct {
11621 + uint64_t reserved_20_63:44;
11622 + uint64_t link_up:1; /**< Is the physical link up? */
11623 + uint64_t full_duplex:1; /**< 1 if the link is full duplex */
11624 + uint64_t speed:18; /**< Speed of the link in Mbps */
11625 + } s;
11626 +} cvmx_helper_link_info_t;
11627 +
11628 +#include "cvmx-helper-fpa.h"
11629 +
11630 +#include <asm/octeon/cvmx-helper-errata.h>
11631 +#include "cvmx-helper-loop.h"
11632 +#include "cvmx-helper-npi.h"
11633 +#include "cvmx-helper-rgmii.h"
11634 +#include "cvmx-helper-sgmii.h"
11635 +#include "cvmx-helper-spi.h"
11636 +#include "cvmx-helper-util.h"
11637 +#include "cvmx-helper-xaui.h"
11638 +
11639 +/**
11640 + * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
11641 + * priorities[16]) is a function pointer. It is meant to allow
11642 + * customization of the PKO queue priorities based on the port
11643 + * number. Users should set this pointer to a function before
11644 + * calling any cvmx-helper operations.
11645 + */
11646 +extern void (*cvmx_override_pko_queue_priority) (int pko_port,
11647 + uint64_t priorities[16]);
11648 +
11649 +/**
11650 + * cvmx_override_ipd_port_setup(int ipd_port) is a function
11651 + * pointer. It is meant to allow customization of the IPD port
11652 + * setup before packet input/output comes online. It is called
11653 + * after cvmx-helper does the default IPD configuration, but
11654 + * before IPD is enabled. Users should set this pointer to a
11655 + * function before calling any cvmx-helper operations.
11656 + */
11657 +extern void (*cvmx_override_ipd_port_setup) (int ipd_port);
11658 +
11659 +/**
11660 + * This function enables the IPD and also enables the packet interfaces.
11661 + * The packet interfaces (RGMII and SPI) must be enabled after the
11662 + * IPD. This should be called by the user program after any additional
11663 + * IPD configuration changes are made if CVMX_HELPER_ENABLE_IPD
11664 + * is not set in the executive-config.h file.
11665 + *
11666 + * Returns 0 on success
11667 + * -1 on failure
11668 + */
11669 +extern int cvmx_helper_ipd_and_packet_input_enable(void);
11670 +
11671 +/**
11672 + * Initialize the PIP, IPD, and PKO hardware to support
11673 + * simple priority based queues for the ethernet ports. Each
11674 + * port is configured with a number of priority queues based
11675 + * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
11676 + * priority than the previous.
11677 + *
11678 + * Returns Zero on success, non-zero on failure
11679 + */
11680 +extern int cvmx_helper_initialize_packet_io_global(void);
11681 +
11682 +/**
11683 + * Does core local initialization for packet io
11684 + *
11685 + * Returns Zero on success, non-zero on failure
11686 + */
11687 +extern int cvmx_helper_initialize_packet_io_local(void);
11688 +
11689 +/**
11690 + * Returns the number of ports on the given interface.
11691 + * The interface must be initialized before the port count
11692 + * can be returned.
11693 + *
11694 + * @interface: Which interface to return port count for.
11695 + *
11696 + * Returns Port count for interface
11697 + * -1 for uninitialized interface
11698 + */
11699 +extern int cvmx_helper_ports_on_interface(int interface);
11700 +
11701 +/**
11702 + * Return the number of interfaces the chip has. Each interface
11703 + * may have multiple ports. Most chips support two interfaces,
11704 + * but the CNX0XX and CNX1XX are exceptions. These only support
11705 + * one interface.
11706 + *
11707 + * Returns Number of interfaces on chip
11708 + */
11709 +extern int cvmx_helper_get_number_of_interfaces(void);
11710 +
11711 +/**
11712 + * Get the operating mode of an interface. Depending on the Octeon
11713 + * chip and configuration, this function returns an enumeration
11714 + * of the type of packet I/O supported by an interface.
11715 + *
11716 + * @interface: Interface to probe
11717 + *
11718 + * Returns Mode of the interface. Unknown or unsupported interfaces return
11719 + * DISABLED.
11720 + */
11721 +extern cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int
11722 + interface);
11723 +
11724 +/**
11725 + * Auto configure an IPD/PKO port link state and speed. This
11726 + * function basically does the equivalent of:
11727 + * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
11728 + *
11729 + * @ipd_port: IPD/PKO port to auto configure
11730 + *
11731 + * Returns Link state after configure
11732 + */
11733 +extern cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port);
11734 +
11735 +/**
11736 + * Return the link state of an IPD/PKO port as returned by
11737 + * auto negotiation. The result of this function may not match
11738 + * Octeon's link config if auto negotiation has changed since
11739 + * the last call to cvmx_helper_link_set().
11740 + *
11741 + * @ipd_port: IPD/PKO port to query
11742 + *
11743 + * Returns Link state
11744 + */
11745 +extern cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port);
11746 +
11747 +/**
11748 + * Configure an IPD/PKO port for the specified link state. This
11749 + * function does not influence auto negotiation at the PHY level.
11750 + * The passed link state must always match the link state returned
11751 + * by cvmx_helper_link_get(). It is normally best to use
11752 + * cvmx_helper_link_autoconf() instead.
11753 + *
11754 + * @ipd_port: IPD/PKO port to configure
11755 + * @link_info: The new link state
11756 + *
11757 + * Returns Zero on success, negative on failure
11758 + */
11759 +extern int cvmx_helper_link_set(int ipd_port,
11760 + cvmx_helper_link_info_t link_info);
11761 +
11762 +/**
11763 + * This function probes an interface to determine the actual
11764 + * number of hardware ports connected to it. It doesn't setup the
11765 + * ports or enable them. The main goal here is to set the global
11766 + * interface_port_count[interface] correctly. Hardware setup of the
11767 + * ports will be performed later.
11768 + *
11769 + * @interface: Interface to probe
11770 + *
11771 + * Returns Zero on success, negative on failure
11772 + */
11773 +extern int cvmx_helper_interface_probe(int interface);
11774 +
11775 +/**
11776 + * Configure a port for internal and/or external loopback. Internal loopback
11777 + * causes packets sent by the port to be received by Octeon. External loopback
11778 + * causes packets received from the wire to sent out again.
11779 + *
11780 + * @ipd_port: IPD/PKO port to loopback.
11781 + * @enable_internal:
11782 + * Non zero if you want internal loopback
11783 + * @enable_external:
11784 + * Non zero if you want external loopback
11785 + *
11786 + * Returns Zero on success, negative on failure.
11787 + */
11788 +extern int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
11789 + int enable_external);
11790 +
11791 +#endif /* __CVMX_HELPER_H__ */
11792 diff --git a/drivers/staging/octeon/cvmx-interrupt-decodes.c b/drivers/staging/octeon/cvmx-interrupt-decodes.c
11793 new file mode 100644
11794 index 0000000..a3337e3
11795 --- /dev/null
11796 +++ b/drivers/staging/octeon/cvmx-interrupt-decodes.c
11797 @@ -0,0 +1,371 @@
11798 +/***********************license start***************
11799 + * Author: Cavium Networks
11800 + *
11801 + * Contact: support@caviumnetworks.com
11802 + * This file is part of the OCTEON SDK
11803 + *
11804 + * Copyright (c) 2003-2009 Cavium Networks
11805 + *
11806 + * This file is free software; you can redistribute it and/or modify
11807 + * it under the terms of the GNU General Public License, Version 2, as
11808 + * published by the Free Software Foundation.
11809 + *
11810 + * This file is distributed in the hope that it will be useful, but
11811 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
11812 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
11813 + * NONINFRINGEMENT. See the GNU General Public License for more
11814 + * details.
11815 + *
11816 + * You should have received a copy of the GNU General Public License
11817 + * along with this file; if not, write to the Free Software
11818 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11819 + * or visit http://www.gnu.org/licenses/.
11820 + *
11821 + * This file may also be available under a different license from Cavium.
11822 + * Contact Cavium Networks for more information
11823 + ***********************license end**************************************/
11824 +
11825 +/*
11826 + *
11827 + * Automatically generated functions useful for enabling
11828 + * and decoding RSL_INT_BLOCKS interrupts.
11829 + *
11830 + */
11831 +
11832 +#include <asm/octeon/octeon.h>
11833 +
11834 +#include "cvmx-gmxx-defs.h"
11835 +#include "cvmx-pcsx-defs.h"
11836 +#include "cvmx-pcsxx-defs.h"
11837 +#include "cvmx-spxx-defs.h"
11838 +#include "cvmx-stxx-defs.h"
11839 +
11840 +#ifndef PRINT_ERROR
11841 +#define PRINT_ERROR(format, ...)
11842 +#endif
11843 +
11844 +
11845 +/**
11846 + * __cvmx_interrupt_gmxx_rxx_int_en_enable enables all interrupt bits in cvmx_gmxx_rxx_int_en_t
11847 + */
11848 +void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block)
11849 +{
11850 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
11851 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, block),
11852 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, block)));
11853 + gmx_rx_int_en.u64 = 0;
11854 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
11855 + /* Skipping gmx_rx_int_en.s.reserved_29_63 */
11856 + gmx_rx_int_en.s.hg2cc = 1;
11857 + gmx_rx_int_en.s.hg2fld = 1;
11858 + gmx_rx_int_en.s.undat = 1;
11859 + gmx_rx_int_en.s.uneop = 1;
11860 + gmx_rx_int_en.s.unsop = 1;
11861 + gmx_rx_int_en.s.bad_term = 1;
11862 + gmx_rx_int_en.s.bad_seq = 1;
11863 + gmx_rx_int_en.s.rem_fault = 1;
11864 + gmx_rx_int_en.s.loc_fault = 1;
11865 + gmx_rx_int_en.s.pause_drp = 1;
11866 + /* Skipping gmx_rx_int_en.s.reserved_16_18 */
11867 + /*gmx_rx_int_en.s.ifgerr = 1; */
11868 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11869 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11870 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11871 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11872 + gmx_rx_int_en.s.ovrerr = 1;
11873 + /* Skipping gmx_rx_int_en.s.reserved_9_9 */
11874 + gmx_rx_int_en.s.skperr = 1;
11875 + gmx_rx_int_en.s.rcverr = 1;
11876 + /* Skipping gmx_rx_int_en.s.reserved_5_6 */
11877 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11878 + gmx_rx_int_en.s.jabber = 1;
11879 + /* Skipping gmx_rx_int_en.s.reserved_2_2 */
11880 + gmx_rx_int_en.s.carext = 1;
11881 + /* Skipping gmx_rx_int_en.s.reserved_0_0 */
11882 + }
11883 + if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
11884 + /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11885 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11886 + /*gmx_rx_int_en.s.phy_spd = 1; */
11887 + /*gmx_rx_int_en.s.phy_link = 1; */
11888 + /*gmx_rx_int_en.s.ifgerr = 1; */
11889 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11890 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11891 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11892 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11893 + gmx_rx_int_en.s.ovrerr = 1;
11894 + gmx_rx_int_en.s.niberr = 1;
11895 + gmx_rx_int_en.s.skperr = 1;
11896 + gmx_rx_int_en.s.rcverr = 1;
11897 + /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11898 + gmx_rx_int_en.s.alnerr = 1;
11899 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11900 + gmx_rx_int_en.s.jabber = 1;
11901 + gmx_rx_int_en.s.maxerr = 1;
11902 + gmx_rx_int_en.s.carext = 1;
11903 + gmx_rx_int_en.s.minerr = 1;
11904 + }
11905 + if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
11906 + /* Skipping gmx_rx_int_en.s.reserved_20_63 */
11907 + gmx_rx_int_en.s.pause_drp = 1;
11908 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11909 + /*gmx_rx_int_en.s.phy_spd = 1; */
11910 + /*gmx_rx_int_en.s.phy_link = 1; */
11911 + /*gmx_rx_int_en.s.ifgerr = 1; */
11912 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11913 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11914 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11915 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11916 + gmx_rx_int_en.s.ovrerr = 1;
11917 + gmx_rx_int_en.s.niberr = 1;
11918 + gmx_rx_int_en.s.skperr = 1;
11919 + gmx_rx_int_en.s.rcverr = 1;
11920 + /* Skipping gmx_rx_int_en.s.reserved_6_6 */
11921 + gmx_rx_int_en.s.alnerr = 1;
11922 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11923 + gmx_rx_int_en.s.jabber = 1;
11924 + /* Skipping gmx_rx_int_en.s.reserved_2_2 */
11925 + gmx_rx_int_en.s.carext = 1;
11926 + /* Skipping gmx_rx_int_en.s.reserved_0_0 */
11927 + }
11928 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
11929 + /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11930 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11931 + /*gmx_rx_int_en.s.phy_spd = 1; */
11932 + /*gmx_rx_int_en.s.phy_link = 1; */
11933 + /*gmx_rx_int_en.s.ifgerr = 1; */
11934 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11935 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11936 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11937 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11938 + gmx_rx_int_en.s.ovrerr = 1;
11939 + gmx_rx_int_en.s.niberr = 1;
11940 + gmx_rx_int_en.s.skperr = 1;
11941 + gmx_rx_int_en.s.rcverr = 1;
11942 + /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11943 + gmx_rx_int_en.s.alnerr = 1;
11944 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11945 + gmx_rx_int_en.s.jabber = 1;
11946 + gmx_rx_int_en.s.maxerr = 1;
11947 + gmx_rx_int_en.s.carext = 1;
11948 + gmx_rx_int_en.s.minerr = 1;
11949 + }
11950 + if (OCTEON_IS_MODEL(OCTEON_CN31XX)) {
11951 + /* Skipping gmx_rx_int_en.s.reserved_19_63 */
11952 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11953 + /*gmx_rx_int_en.s.phy_spd = 1; */
11954 + /*gmx_rx_int_en.s.phy_link = 1; */
11955 + /*gmx_rx_int_en.s.ifgerr = 1; */
11956 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11957 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11958 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11959 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11960 + gmx_rx_int_en.s.ovrerr = 1;
11961 + gmx_rx_int_en.s.niberr = 1;
11962 + gmx_rx_int_en.s.skperr = 1;
11963 + gmx_rx_int_en.s.rcverr = 1;
11964 + /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11965 + gmx_rx_int_en.s.alnerr = 1;
11966 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11967 + gmx_rx_int_en.s.jabber = 1;
11968 + gmx_rx_int_en.s.maxerr = 1;
11969 + gmx_rx_int_en.s.carext = 1;
11970 + gmx_rx_int_en.s.minerr = 1;
11971 + }
11972 + if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
11973 + /* Skipping gmx_rx_int_en.s.reserved_20_63 */
11974 + gmx_rx_int_en.s.pause_drp = 1;
11975 + /*gmx_rx_int_en.s.phy_dupx = 1; */
11976 + /*gmx_rx_int_en.s.phy_spd = 1; */
11977 + /*gmx_rx_int_en.s.phy_link = 1; */
11978 + /*gmx_rx_int_en.s.ifgerr = 1; */
11979 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
11980 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
11981 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
11982 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
11983 + gmx_rx_int_en.s.ovrerr = 1;
11984 + gmx_rx_int_en.s.niberr = 1;
11985 + gmx_rx_int_en.s.skperr = 1;
11986 + gmx_rx_int_en.s.rcverr = 1;
11987 + /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
11988 + gmx_rx_int_en.s.alnerr = 1;
11989 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
11990 + gmx_rx_int_en.s.jabber = 1;
11991 + gmx_rx_int_en.s.maxerr = 1;
11992 + gmx_rx_int_en.s.carext = 1;
11993 + gmx_rx_int_en.s.minerr = 1;
11994 + }
11995 + if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
11996 + /* Skipping gmx_rx_int_en.s.reserved_29_63 */
11997 + gmx_rx_int_en.s.hg2cc = 1;
11998 + gmx_rx_int_en.s.hg2fld = 1;
11999 + gmx_rx_int_en.s.undat = 1;
12000 + gmx_rx_int_en.s.uneop = 1;
12001 + gmx_rx_int_en.s.unsop = 1;
12002 + gmx_rx_int_en.s.bad_term = 1;
12003 + gmx_rx_int_en.s.bad_seq = 0;
12004 + gmx_rx_int_en.s.rem_fault = 1;
12005 + gmx_rx_int_en.s.loc_fault = 0;
12006 + gmx_rx_int_en.s.pause_drp = 1;
12007 + /* Skipping gmx_rx_int_en.s.reserved_16_18 */
12008 + /*gmx_rx_int_en.s.ifgerr = 1; */
12009 + /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
12010 + /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
12011 + /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
12012 + /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
12013 + gmx_rx_int_en.s.ovrerr = 1;
12014 + /* Skipping gmx_rx_int_en.s.reserved_9_9 */
12015 + gmx_rx_int_en.s.skperr = 1;
12016 + gmx_rx_int_en.s.rcverr = 1;
12017 + /* Skipping gmx_rx_int_en.s.reserved_5_6 */
12018 + /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
12019 + gmx_rx_int_en.s.jabber = 1;
12020 + /* Skipping gmx_rx_int_en.s.reserved_2_2 */
12021 + gmx_rx_int_en.s.carext = 1;
12022 + /* Skipping gmx_rx_int_en.s.reserved_0_0 */
12023 + }
12024 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, block), gmx_rx_int_en.u64);
12025 +}
12026 +/**
12027 + * __cvmx_interrupt_pcsx_intx_en_reg_enable enables all interrupt bits in cvmx_pcsx_intx_en_reg_t
12028 + */
12029 +void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block)
12030 +{
12031 + union cvmx_pcsx_intx_en_reg pcs_int_en_reg;
12032 + cvmx_write_csr(CVMX_PCSX_INTX_REG(index, block),
12033 + cvmx_read_csr(CVMX_PCSX_INTX_REG(index, block)));
12034 + pcs_int_en_reg.u64 = 0;
12035 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
12036 + /* Skipping pcs_int_en_reg.s.reserved_12_63 */
12037 + /*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */
12038 + pcs_int_en_reg.s.sync_bad_en = 1;
12039 + pcs_int_en_reg.s.an_bad_en = 1;
12040 + pcs_int_en_reg.s.rxlock_en = 1;
12041 + pcs_int_en_reg.s.rxbad_en = 1;
12042 + /*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */
12043 + pcs_int_en_reg.s.txbad_en = 1;
12044 + pcs_int_en_reg.s.txfifo_en = 1;
12045 + pcs_int_en_reg.s.txfifu_en = 1;
12046 + pcs_int_en_reg.s.an_err_en = 1;
12047 + /*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */
12048 + /*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */
12049 + }
12050 + if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
12051 + /* Skipping pcs_int_en_reg.s.reserved_12_63 */
12052 + /*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */
12053 + pcs_int_en_reg.s.sync_bad_en = 1;
12054 + pcs_int_en_reg.s.an_bad_en = 1;
12055 + pcs_int_en_reg.s.rxlock_en = 1;
12056 + pcs_int_en_reg.s.rxbad_en = 1;
12057 + /*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */
12058 + pcs_int_en_reg.s.txbad_en = 1;
12059 + pcs_int_en_reg.s.txfifo_en = 1;
12060 + pcs_int_en_reg.s.txfifu_en = 1;
12061 + pcs_int_en_reg.s.an_err_en = 1;
12062 + /*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */
12063 + /*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */
12064 + }
12065 + cvmx_write_csr(CVMX_PCSX_INTX_EN_REG(index, block), pcs_int_en_reg.u64);
12066 +}
12067 +/**
12068 + * __cvmx_interrupt_pcsxx_int_en_reg_enable enables all interrupt bits in cvmx_pcsxx_int_en_reg_t
12069 + */
12070 +void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index)
12071 +{
12072 + union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
12073 + cvmx_write_csr(CVMX_PCSXX_INT_REG(index),
12074 + cvmx_read_csr(CVMX_PCSXX_INT_REG(index)));
12075 + pcsx_int_en_reg.u64 = 0;
12076 + if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
12077 + /* Skipping pcsx_int_en_reg.s.reserved_6_63 */
12078 + pcsx_int_en_reg.s.algnlos_en = 1;
12079 + pcsx_int_en_reg.s.synlos_en = 1;
12080 + pcsx_int_en_reg.s.bitlckls_en = 1;
12081 + pcsx_int_en_reg.s.rxsynbad_en = 1;
12082 + pcsx_int_en_reg.s.rxbad_en = 1;
12083 + pcsx_int_en_reg.s.txflt_en = 1;
12084 + }
12085 + if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
12086 + /* Skipping pcsx_int_en_reg.s.reserved_6_63 */
12087 + pcsx_int_en_reg.s.algnlos_en = 1;
12088 + pcsx_int_en_reg.s.synlos_en = 1;
12089 + pcsx_int_en_reg.s.bitlckls_en = 0; /* Happens if XAUI module is not installed */
12090 + pcsx_int_en_reg.s.rxsynbad_en = 1;
12091 + pcsx_int_en_reg.s.rxbad_en = 1;
12092 + pcsx_int_en_reg.s.txflt_en = 1;
12093 + }
12094 + cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(index), pcsx_int_en_reg.u64);
12095 +}
12096 +
12097 +/**
12098 + * __cvmx_interrupt_spxx_int_msk_enable enables all interrupt bits in cvmx_spxx_int_msk_t
12099 + */
12100 +void __cvmx_interrupt_spxx_int_msk_enable(int index)
12101 +{
12102 + union cvmx_spxx_int_msk spx_int_msk;
12103 + cvmx_write_csr(CVMX_SPXX_INT_REG(index),
12104 + cvmx_read_csr(CVMX_SPXX_INT_REG(index)));
12105 + spx_int_msk.u64 = 0;
12106 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
12107 + /* Skipping spx_int_msk.s.reserved_12_63 */
12108 + spx_int_msk.s.calerr = 1;
12109 + spx_int_msk.s.syncerr = 1;
12110 + spx_int_msk.s.diperr = 1;
12111 + spx_int_msk.s.tpaovr = 1;
12112 + spx_int_msk.s.rsverr = 1;
12113 + spx_int_msk.s.drwnng = 1;
12114 + spx_int_msk.s.clserr = 1;
12115 + spx_int_msk.s.spiovr = 1;
12116 + /* Skipping spx_int_msk.s.reserved_2_3 */
12117 + spx_int_msk.s.abnorm = 1;
12118 + spx_int_msk.s.prtnxa = 1;
12119 + }
12120 + if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12121 + /* Skipping spx_int_msk.s.reserved_12_63 */
12122 + spx_int_msk.s.calerr = 1;
12123 + spx_int_msk.s.syncerr = 1;
12124 + spx_int_msk.s.diperr = 1;
12125 + spx_int_msk.s.tpaovr = 1;
12126 + spx_int_msk.s.rsverr = 1;
12127 + spx_int_msk.s.drwnng = 1;
12128 + spx_int_msk.s.clserr = 1;
12129 + spx_int_msk.s.spiovr = 1;
12130 + /* Skipping spx_int_msk.s.reserved_2_3 */
12131 + spx_int_msk.s.abnorm = 1;
12132 + spx_int_msk.s.prtnxa = 1;
12133 + }
12134 + cvmx_write_csr(CVMX_SPXX_INT_MSK(index), spx_int_msk.u64);
12135 +}
12136 +/**
12137 + * __cvmx_interrupt_stxx_int_msk_enable enables all interrupt bits in cvmx_stxx_int_msk_t
12138 + */
12139 +void __cvmx_interrupt_stxx_int_msk_enable(int index)
12140 +{
12141 + union cvmx_stxx_int_msk stx_int_msk;
12142 + cvmx_write_csr(CVMX_STXX_INT_REG(index),
12143 + cvmx_read_csr(CVMX_STXX_INT_REG(index)));
12144 + stx_int_msk.u64 = 0;
12145 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
12146 + /* Skipping stx_int_msk.s.reserved_8_63 */
12147 + stx_int_msk.s.frmerr = 1;
12148 + stx_int_msk.s.unxfrm = 1;
12149 + stx_int_msk.s.nosync = 1;
12150 + stx_int_msk.s.diperr = 1;
12151 + stx_int_msk.s.datovr = 1;
12152 + stx_int_msk.s.ovrbst = 1;
12153 + stx_int_msk.s.calpar1 = 1;
12154 + stx_int_msk.s.calpar0 = 1;
12155 + }
12156 + if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12157 + /* Skipping stx_int_msk.s.reserved_8_63 */
12158 + stx_int_msk.s.frmerr = 1;
12159 + stx_int_msk.s.unxfrm = 1;
12160 + stx_int_msk.s.nosync = 1;
12161 + stx_int_msk.s.diperr = 1;
12162 + stx_int_msk.s.datovr = 1;
12163 + stx_int_msk.s.ovrbst = 1;
12164 + stx_int_msk.s.calpar1 = 1;
12165 + stx_int_msk.s.calpar0 = 1;
12166 + }
12167 + cvmx_write_csr(CVMX_STXX_INT_MSK(index), stx_int_msk.u64);
12168 +}
12169 diff --git a/drivers/staging/octeon/cvmx-interrupt-rsl.c b/drivers/staging/octeon/cvmx-interrupt-rsl.c
12170 new file mode 100644
12171 index 0000000..df50048
12172 --- /dev/null
12173 +++ b/drivers/staging/octeon/cvmx-interrupt-rsl.c
12174 @@ -0,0 +1,140 @@
12175 +/***********************license start***************
12176 + * Author: Cavium Networks
12177 + *
12178 + * Contact: support@caviumnetworks.com
12179 + * This file is part of the OCTEON SDK
12180 + *
12181 + * Copyright (c) 2003-2008 Cavium Networks
12182 + *
12183 + * This file is free software; you can redistribute it and/or modify
12184 + * it under the terms of the GNU General Public License, Version 2, as
12185 + * published by the Free Software Foundation.
12186 + *
12187 + * This file is distributed in the hope that it will be useful, but
12188 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12189 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12190 + * NONINFRINGEMENT. See the GNU General Public License for more
12191 + * details.
12192 + *
12193 + * You should have received a copy of the GNU General Public License
12194 + * along with this file; if not, write to the Free Software
12195 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12196 + * or visit http://www.gnu.org/licenses/.
12197 + *
12198 + * This file may also be available under a different license from Cavium.
12199 + * Contact Cavium Networks for more information
12200 + ***********************license end**************************************/
12201 +
12202 +/*
12203 + * Utility functions to decode Octeon's RSL_INT_BLOCKS
12204 + * interrupts into error messages.
12205 + */
12206 +
12207 +#include <asm/octeon/octeon.h>
12208 +
12209 +#include "cvmx-asxx-defs.h"
12210 +#include "cvmx-gmxx-defs.h"
12211 +
12212 +#ifndef PRINT_ERROR
12213 +#define PRINT_ERROR(format, ...)
12214 +#endif
12215 +
12216 +void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block);
12217 +
12218 +/**
12219 + * Enable ASX error interrupts that exist on CN3XXX, CN50XX, and
12220 + * CN58XX.
12221 + *
12222 + * @block: Interface to enable 0-1
12223 + */
12224 +void __cvmx_interrupt_asxx_enable(int block)
12225 +{
12226 + int mask;
12227 + union cvmx_asxx_int_en csr;
12228 + /*
12229 + * CN38XX and CN58XX have two interfaces with 4 ports per
12230 + * interface. All other chips have a max of 3 ports on
12231 + * interface 0
12232 + */
12233 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
12234 + mask = 0xf; /* Set enables for 4 ports */
12235 + else
12236 + mask = 0x7; /* Set enables for 3 ports */
12237 +
12238 + /* Enable interface interrupts */
12239 + csr.u64 = cvmx_read_csr(CVMX_ASXX_INT_EN(block));
12240 + csr.s.txpsh = mask;
12241 + csr.s.txpop = mask;
12242 + csr.s.ovrflw = mask;
12243 + cvmx_write_csr(CVMX_ASXX_INT_EN(block), csr.u64);
12244 +}
12245 +/**
12246 + * Enable GMX error reporting for the supplied interface
12247 + *
12248 + * @interface: Interface to enable
12249 + */
12250 +void __cvmx_interrupt_gmxx_enable(int interface)
12251 +{
12252 + union cvmx_gmxx_inf_mode mode;
12253 + union cvmx_gmxx_tx_int_en gmx_tx_int_en;
12254 + int num_ports;
12255 + int index;
12256 +
12257 + mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
12258 +
12259 + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
12260 + if (mode.s.en) {
12261 + switch (mode.cn56xx.mode) {
12262 + case 1: /* XAUI */
12263 + num_ports = 1;
12264 + break;
12265 + case 2: /* SGMII */
12266 + case 3: /* PICMG */
12267 + num_ports = 4;
12268 + break;
12269 + default: /* Disabled */
12270 + num_ports = 0;
12271 + break;
12272 + }
12273 + } else
12274 + num_ports = 0;
12275 + } else {
12276 + if (mode.s.en) {
12277 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
12278 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
12279 + /*
12280 + * SPI on CN38XX and CN58XX report all
12281 + * errors through port 0. RGMII needs
12282 + * to check all 4 ports
12283 + */
12284 + if (mode.s.type)
12285 + num_ports = 1;
12286 + else
12287 + num_ports = 4;
12288 + } else {
12289 + /*
12290 + * CN30XX, CN31XX, and CN50XX have two
12291 + * or three ports. GMII and MII has 2,
12292 + * RGMII has three
12293 + */
12294 + if (mode.s.type)
12295 + num_ports = 2;
12296 + else
12297 + num_ports = 3;
12298 + }
12299 + } else
12300 + num_ports = 0;
12301 + }
12302 +
12303 + gmx_tx_int_en.u64 = 0;
12304 + if (num_ports) {
12305 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)
12306 + || OCTEON_IS_MODEL(OCTEON_CN58XX))
12307 + gmx_tx_int_en.s.ncb_nxa = 1;
12308 + gmx_tx_int_en.s.pko_nxa = 1;
12309 + }
12310 + gmx_tx_int_en.s.undflw = (1 << num_ports) - 1;
12311 + cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
12312 + for (index = 0; index < num_ports; index++)
12313 + __cvmx_interrupt_gmxx_rxx_int_en_enable(index, interface);
12314 +}
12315 diff --git a/drivers/staging/octeon/cvmx-ipd.h b/drivers/staging/octeon/cvmx-ipd.h
12316 new file mode 100644
12317 index 0000000..115a552
12318 --- /dev/null
12319 +++ b/drivers/staging/octeon/cvmx-ipd.h
12320 @@ -0,0 +1,338 @@
12321 +/***********************license start***************
12322 + * Author: Cavium Networks
12323 + *
12324 + * Contact: support@caviumnetworks.com
12325 + * This file is part of the OCTEON SDK
12326 + *
12327 + * Copyright (c) 2003-2008 Cavium Networks
12328 + *
12329 + * This file is free software; you can redistribute it and/or modify
12330 + * it under the terms of the GNU General Public License, Version 2, as
12331 + * published by the Free Software Foundation.
12332 + *
12333 + * This file is distributed in the hope that it will be useful, but
12334 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12335 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12336 + * NONINFRINGEMENT. See the GNU General Public License for more
12337 + * details.
12338 + *
12339 + * You should have received a copy of the GNU General Public License
12340 + * along with this file; if not, write to the Free Software
12341 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12342 + * or visit http://www.gnu.org/licenses/.
12343 + *
12344 + * This file may also be available under a different license from Cavium.
12345 + * Contact Cavium Networks for more information
12346 + ***********************license end**************************************/
12347 +
12348 +/**
12349 + *
12350 + * Interface to the hardware Input Packet Data unit.
12351 + */
12352 +
12353 +#ifndef __CVMX_IPD_H__
12354 +#define __CVMX_IPD_H__
12355 +
12356 +#include <asm/octeon/octeon-feature.h>
12357 +
12358 +#include <asm/octeon/cvmx-ipd-defs.h>
12359 +
12360 +enum cvmx_ipd_mode {
12361 + CVMX_IPD_OPC_MODE_STT = 0LL, /* All blocks DRAM, not cached in L2 */
12362 + CVMX_IPD_OPC_MODE_STF = 1LL, /* All bloccks into L2 */
12363 + CVMX_IPD_OPC_MODE_STF1_STT = 2LL, /* 1st block L2, rest DRAM */
12364 + CVMX_IPD_OPC_MODE_STF2_STT = 3LL /* 1st, 2nd blocks L2, rest DRAM */
12365 +};
12366 +
12367 +#ifndef CVMX_ENABLE_LEN_M8_FIX
12368 +#define CVMX_ENABLE_LEN_M8_FIX 0
12369 +#endif
12370 +
12371 +/* CSR typedefs have been moved to cvmx-csr-*.h */
12372 +typedef union cvmx_ipd_1st_mbuff_skip cvmx_ipd_mbuff_first_skip_t;
12373 +typedef union cvmx_ipd_1st_next_ptr_back cvmx_ipd_first_next_ptr_back_t;
12374 +
12375 +typedef cvmx_ipd_mbuff_first_skip_t cvmx_ipd_mbuff_not_first_skip_t;
12376 +typedef cvmx_ipd_first_next_ptr_back_t cvmx_ipd_second_next_ptr_back_t;
12377 +
12378 +/**
12379 + * Configure IPD
12380 + *
12381 + * @mbuff_size: Packets buffer size in 8 byte words
12382 + * @first_mbuff_skip:
12383 + * Number of 8 byte words to skip in the first buffer
12384 + * @not_first_mbuff_skip:
12385 + * Number of 8 byte words to skip in each following buffer
12386 + * @first_back: Must be same as first_mbuff_skip / 128
12387 + * @second_back:
12388 + * Must be same as not_first_mbuff_skip / 128
12389 + * @wqe_fpa_pool:
12390 + * FPA pool to get work entries from
12391 + * @cache_mode:
12392 + * @back_pres_enable_flag:
12393 + * Enable or disable port back pressure
12394 + */
12395 +static inline void cvmx_ipd_config(uint64_t mbuff_size,
12396 + uint64_t first_mbuff_skip,
12397 + uint64_t not_first_mbuff_skip,
12398 + uint64_t first_back,
12399 + uint64_t second_back,
12400 + uint64_t wqe_fpa_pool,
12401 + enum cvmx_ipd_mode cache_mode,
12402 + uint64_t back_pres_enable_flag)
12403 +{
12404 + cvmx_ipd_mbuff_first_skip_t first_skip;
12405 + cvmx_ipd_mbuff_not_first_skip_t not_first_skip;
12406 + union cvmx_ipd_packet_mbuff_size size;
12407 + cvmx_ipd_first_next_ptr_back_t first_back_struct;
12408 + cvmx_ipd_second_next_ptr_back_t second_back_struct;
12409 + union cvmx_ipd_wqe_fpa_queue wqe_pool;
12410 + union cvmx_ipd_ctl_status ipd_ctl_reg;
12411 +
12412 + first_skip.u64 = 0;
12413 + first_skip.s.skip_sz = first_mbuff_skip;
12414 + cvmx_write_csr(CVMX_IPD_1ST_MBUFF_SKIP, first_skip.u64);
12415 +
12416 + not_first_skip.u64 = 0;
12417 + not_first_skip.s.skip_sz = not_first_mbuff_skip;
12418 + cvmx_write_csr(CVMX_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.u64);
12419 +
12420 + size.u64 = 0;
12421 + size.s.mb_size = mbuff_size;
12422 + cvmx_write_csr(CVMX_IPD_PACKET_MBUFF_SIZE, size.u64);
12423 +
12424 + first_back_struct.u64 = 0;
12425 + first_back_struct.s.back = first_back;
12426 + cvmx_write_csr(CVMX_IPD_1st_NEXT_PTR_BACK, first_back_struct.u64);
12427 +
12428 + second_back_struct.u64 = 0;
12429 + second_back_struct.s.back = second_back;
12430 + cvmx_write_csr(CVMX_IPD_2nd_NEXT_PTR_BACK, second_back_struct.u64);
12431 +
12432 + wqe_pool.u64 = 0;
12433 + wqe_pool.s.wqe_pool = wqe_fpa_pool;
12434 + cvmx_write_csr(CVMX_IPD_WQE_FPA_QUEUE, wqe_pool.u64);
12435 +
12436 + ipd_ctl_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12437 + ipd_ctl_reg.s.opc_mode = cache_mode;
12438 + ipd_ctl_reg.s.pbp_en = back_pres_enable_flag;
12439 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_reg.u64);
12440 +
12441 + /* Note: the example RED code that used to be here has been moved to
12442 + cvmx_helper_setup_red */
12443 +}
12444 +
12445 +/**
12446 + * Enable IPD
12447 + */
12448 +static inline void cvmx_ipd_enable(void)
12449 +{
12450 + union cvmx_ipd_ctl_status ipd_reg;
12451 + ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12452 + if (ipd_reg.s.ipd_en) {
12453 + cvmx_dprintf
12454 + ("Warning: Enabling IPD when IPD already enabled.\n");
12455 + }
12456 + ipd_reg.s.ipd_en = 1;
12457 +#if CVMX_ENABLE_LEN_M8_FIX
12458 + if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
12459 + ipd_reg.s.len_m8 = TRUE;
12460 +#endif
12461 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
12462 +}
12463 +
12464 +/**
12465 + * Disable IPD
12466 + */
12467 +static inline void cvmx_ipd_disable(void)
12468 +{
12469 + union cvmx_ipd_ctl_status ipd_reg;
12470 + ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12471 + ipd_reg.s.ipd_en = 0;
12472 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
12473 +}
12474 +
12475 +/**
12476 + * Supportive function for cvmx_fpa_shutdown_pool.
12477 + */
12478 +static inline void cvmx_ipd_free_ptr(void)
12479 +{
12480 + /* Only CN38XXp{1,2} cannot read pointer out of the IPD */
12481 + if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)
12482 + && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
12483 + int no_wptr = 0;
12484 + union cvmx_ipd_ptr_count ipd_ptr_count;
12485 + ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
12486 +
12487 + /* Handle Work Queue Entry in cn56xx and cn52xx */
12488 + if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
12489 + union cvmx_ipd_ctl_status ipd_ctl_status;
12490 + ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12491 + if (ipd_ctl_status.s.no_wptr)
12492 + no_wptr = 1;
12493 + }
12494 +
12495 + /* Free the prefetched WQE */
12496 + if (ipd_ptr_count.s.wqev_cnt) {
12497 + union cvmx_ipd_wqe_ptr_valid ipd_wqe_ptr_valid;
12498 + ipd_wqe_ptr_valid.u64 =
12499 + cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID);
12500 + if (no_wptr)
12501 + cvmx_fpa_free(cvmx_phys_to_ptr
12502 + ((uint64_t) ipd_wqe_ptr_valid.s.
12503 + ptr << 7), CVMX_FPA_PACKET_POOL,
12504 + 0);
12505 + else
12506 + cvmx_fpa_free(cvmx_phys_to_ptr
12507 + ((uint64_t) ipd_wqe_ptr_valid.s.
12508 + ptr << 7), CVMX_FPA_WQE_POOL, 0);
12509 + }
12510 +
12511 + /* Free all WQE in the fifo */
12512 + if (ipd_ptr_count.s.wqe_pcnt) {
12513 + int i;
12514 + union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
12515 + ipd_pwp_ptr_fifo_ctl.u64 =
12516 + cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12517 + for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
12518 + ipd_pwp_ptr_fifo_ctl.s.cena = 0;
12519 + ipd_pwp_ptr_fifo_ctl.s.raddr =
12520 + ipd_pwp_ptr_fifo_ctl.s.max_cnts +
12521 + (ipd_pwp_ptr_fifo_ctl.s.wraddr +
12522 + i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
12523 + cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12524 + ipd_pwp_ptr_fifo_ctl.u64);
12525 + ipd_pwp_ptr_fifo_ctl.u64 =
12526 + cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12527 + if (no_wptr)
12528 + cvmx_fpa_free(cvmx_phys_to_ptr
12529 + ((uint64_t)
12530 + ipd_pwp_ptr_fifo_ctl.s.
12531 + ptr << 7),
12532 + CVMX_FPA_PACKET_POOL, 0);
12533 + else
12534 + cvmx_fpa_free(cvmx_phys_to_ptr
12535 + ((uint64_t)
12536 + ipd_pwp_ptr_fifo_ctl.s.
12537 + ptr << 7),
12538 + CVMX_FPA_WQE_POOL, 0);
12539 + }
12540 + ipd_pwp_ptr_fifo_ctl.s.cena = 1;
12541 + cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12542 + ipd_pwp_ptr_fifo_ctl.u64);
12543 + }
12544 +
12545 + /* Free the prefetched packet */
12546 + if (ipd_ptr_count.s.pktv_cnt) {
12547 + union cvmx_ipd_pkt_ptr_valid ipd_pkt_ptr_valid;
12548 + ipd_pkt_ptr_valid.u64 =
12549 + cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID);
12550 + cvmx_fpa_free(cvmx_phys_to_ptr
12551 + (ipd_pkt_ptr_valid.s.ptr << 7),
12552 + CVMX_FPA_PACKET_POOL, 0);
12553 + }
12554 +
12555 + /* Free the per port prefetched packets */
12556 + if (1) {
12557 + int i;
12558 + union cvmx_ipd_prc_port_ptr_fifo_ctl
12559 + ipd_prc_port_ptr_fifo_ctl;
12560 + ipd_prc_port_ptr_fifo_ctl.u64 =
12561 + cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
12562 +
12563 + for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
12564 + i++) {
12565 + ipd_prc_port_ptr_fifo_ctl.s.cena = 0;
12566 + ipd_prc_port_ptr_fifo_ctl.s.raddr =
12567 + i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
12568 + cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
12569 + ipd_prc_port_ptr_fifo_ctl.u64);
12570 + ipd_prc_port_ptr_fifo_ctl.u64 =
12571 + cvmx_read_csr
12572 + (CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
12573 + cvmx_fpa_free(cvmx_phys_to_ptr
12574 + ((uint64_t)
12575 + ipd_prc_port_ptr_fifo_ctl.s.
12576 + ptr << 7), CVMX_FPA_PACKET_POOL,
12577 + 0);
12578 + }
12579 + ipd_prc_port_ptr_fifo_ctl.s.cena = 1;
12580 + cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
12581 + ipd_prc_port_ptr_fifo_ctl.u64);
12582 + }
12583 +
12584 + /* Free all packets in the holding fifo */
12585 + if (ipd_ptr_count.s.pfif_cnt) {
12586 + int i;
12587 + union cvmx_ipd_prc_hold_ptr_fifo_ctl
12588 + ipd_prc_hold_ptr_fifo_ctl;
12589 +
12590 + ipd_prc_hold_ptr_fifo_ctl.u64 =
12591 + cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
12592 +
12593 + for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
12594 + ipd_prc_hold_ptr_fifo_ctl.s.cena = 0;
12595 + ipd_prc_hold_ptr_fifo_ctl.s.raddr =
12596 + (ipd_prc_hold_ptr_fifo_ctl.s.praddr +
12597 + i) % ipd_prc_hold_ptr_fifo_ctl.s.max_pkt;
12598 + cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
12599 + ipd_prc_hold_ptr_fifo_ctl.u64);
12600 + ipd_prc_hold_ptr_fifo_ctl.u64 =
12601 + cvmx_read_csr
12602 + (CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
12603 + cvmx_fpa_free(cvmx_phys_to_ptr
12604 + ((uint64_t)
12605 + ipd_prc_hold_ptr_fifo_ctl.s.
12606 + ptr << 7), CVMX_FPA_PACKET_POOL,
12607 + 0);
12608 + }
12609 + ipd_prc_hold_ptr_fifo_ctl.s.cena = 1;
12610 + cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
12611 + ipd_prc_hold_ptr_fifo_ctl.u64);
12612 + }
12613 +
12614 + /* Free all packets in the fifo */
12615 + if (ipd_ptr_count.s.pkt_pcnt) {
12616 + int i;
12617 + union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
12618 + ipd_pwp_ptr_fifo_ctl.u64 =
12619 + cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12620 +
12621 + for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
12622 + ipd_pwp_ptr_fifo_ctl.s.cena = 0;
12623 + ipd_pwp_ptr_fifo_ctl.s.raddr =
12624 + (ipd_pwp_ptr_fifo_ctl.s.praddr +
12625 + i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
12626 + cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12627 + ipd_pwp_ptr_fifo_ctl.u64);
12628 + ipd_pwp_ptr_fifo_ctl.u64 =
12629 + cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
12630 + cvmx_fpa_free(cvmx_phys_to_ptr
12631 + ((uint64_t) ipd_pwp_ptr_fifo_ctl.
12632 + s.ptr << 7),
12633 + CVMX_FPA_PACKET_POOL, 0);
12634 + }
12635 + ipd_pwp_ptr_fifo_ctl.s.cena = 1;
12636 + cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
12637 + ipd_pwp_ptr_fifo_ctl.u64);
12638 + }
12639 +
12640 + /* Reset the IPD to get all buffers out of it */
12641 + {
12642 + union cvmx_ipd_ctl_status ipd_ctl_status;
12643 + ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
12644 + ipd_ctl_status.s.reset = 1;
12645 + cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);
12646 + }
12647 +
12648 + /* Reset the PIP */
12649 + {
12650 + union cvmx_pip_sft_rst pip_sft_rst;
12651 + pip_sft_rst.u64 = cvmx_read_csr(CVMX_PIP_SFT_RST);
12652 + pip_sft_rst.s.rst = 1;
12653 + cvmx_write_csr(CVMX_PIP_SFT_RST, pip_sft_rst.u64);
12654 + }
12655 + }
12656 +}
12657 +
12658 +#endif /* __CVMX_IPD_H__ */
12659 diff --git a/drivers/staging/octeon/cvmx-mdio.h b/drivers/staging/octeon/cvmx-mdio.h
12660 new file mode 100644
12661 index 0000000..c987a75
12662 --- /dev/null
12663 +++ b/drivers/staging/octeon/cvmx-mdio.h
12664 @@ -0,0 +1,506 @@
12665 +/***********************license start***************
12666 + * Author: Cavium Networks
12667 + *
12668 + * Contact: support@caviumnetworks.com
12669 + * This file is part of the OCTEON SDK
12670 + *
12671 + * Copyright (c) 2003-2008 Cavium Networks
12672 + *
12673 + * This file is free software; you can redistribute it and/or modify
12674 + * it under the terms of the GNU General Public License, Version 2, as
12675 + * published by the Free Software Foundation.
12676 + *
12677 + * This file is distributed in the hope that it will be useful, but
12678 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
12679 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
12680 + * NONINFRINGEMENT. See the GNU General Public License for more
12681 + * details.
12682 + *
12683 + * You should have received a copy of the GNU General Public License
12684 + * along with this file; if not, write to the Free Software
12685 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12686 + * or visit http://www.gnu.org/licenses/.
12687 + *
12688 + * This file may also be available under a different license from Cavium.
12689 + * Contact Cavium Networks for more information
12690 + ***********************license end**************************************/
12691 +
12692 +/*
12693 + *
12694 + * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3
12695 + * clause 22 and clause 45 operations.
12696 + *
12697 + */
12698 +
12699 +#ifndef __CVMX_MIO_H__
12700 +#define __CVMX_MIO_H__
12701 +
12702 +#include "cvmx-smix-defs.h"
12703 +
12704 +/**
12705 + * PHY register 0 from the 802.3 spec
12706 + */
12707 +#define CVMX_MDIO_PHY_REG_CONTROL 0
12708 +typedef union {
12709 + uint16_t u16;
12710 + struct {
12711 + uint16_t reset:1;
12712 + uint16_t loopback:1;
12713 + uint16_t speed_lsb:1;
12714 + uint16_t autoneg_enable:1;
12715 + uint16_t power_down:1;
12716 + uint16_t isolate:1;
12717 + uint16_t restart_autoneg:1;
12718 + uint16_t duplex:1;
12719 + uint16_t collision_test:1;
12720 + uint16_t speed_msb:1;
12721 + uint16_t unidirectional_enable:1;
12722 + uint16_t reserved_0_4:5;
12723 + } s;
12724 +} cvmx_mdio_phy_reg_control_t;
12725 +
12726 +/**
12727 + * PHY register 1 from the 802.3 spec
12728 + */
12729 +#define CVMX_MDIO_PHY_REG_STATUS 1
12730 +typedef union {
12731 + uint16_t u16;
12732 + struct {
12733 + uint16_t capable_100base_t4:1;
12734 + uint16_t capable_100base_x_full:1;
12735 + uint16_t capable_100base_x_half:1;
12736 + uint16_t capable_10_full:1;
12737 + uint16_t capable_10_half:1;
12738 + uint16_t capable_100base_t2_full:1;
12739 + uint16_t capable_100base_t2_half:1;
12740 + uint16_t capable_extended_status:1;
12741 + uint16_t capable_unidirectional:1;
12742 + uint16_t capable_mf_preamble_suppression:1;
12743 + uint16_t autoneg_complete:1;
12744 + uint16_t remote_fault:1;
12745 + uint16_t capable_autoneg:1;
12746 + uint16_t link_status:1;
12747 + uint16_t jabber_detect:1;
12748 + uint16_t capable_extended_registers:1;
12749 +
12750 + } s;
12751 +} cvmx_mdio_phy_reg_status_t;
12752 +
12753 +/**
12754 + * PHY register 2 from the 802.3 spec
12755 + */
12756 +#define CVMX_MDIO_PHY_REG_ID1 2
12757 +typedef union {
12758 + uint16_t u16;
12759 + struct {
12760 + uint16_t oui_bits_3_18;
12761 + } s;
12762 +} cvmx_mdio_phy_reg_id1_t;
12763 +
12764 +/**
12765 + * PHY register 3 from the 802.3 spec
12766 + */
12767 +#define CVMX_MDIO_PHY_REG_ID2 3
12768 +typedef union {
12769 + uint16_t u16;
12770 + struct {
12771 + uint16_t oui_bits_19_24:6;
12772 + uint16_t model:6;
12773 + uint16_t revision:4;
12774 + } s;
12775 +} cvmx_mdio_phy_reg_id2_t;
12776 +
12777 +/**
12778 + * PHY register 4 from the 802.3 spec
12779 + */
12780 +#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4
12781 +typedef union {
12782 + uint16_t u16;
12783 + struct {
12784 + uint16_t next_page:1;
12785 + uint16_t reserved_14:1;
12786 + uint16_t remote_fault:1;
12787 + uint16_t reserved_12:1;
12788 + uint16_t asymmetric_pause:1;
12789 + uint16_t pause:1;
12790 + uint16_t advert_100base_t4:1;
12791 + uint16_t advert_100base_tx_full:1;
12792 + uint16_t advert_100base_tx_half:1;
12793 + uint16_t advert_10base_tx_full:1;
12794 + uint16_t advert_10base_tx_half:1;
12795 + uint16_t selector:5;
12796 + } s;
12797 +} cvmx_mdio_phy_reg_autoneg_adver_t;
12798 +
12799 +/**
12800 + * PHY register 5 from the 802.3 spec
12801 + */
12802 +#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5
12803 +typedef union {
12804 + uint16_t u16;
12805 + struct {
12806 + uint16_t next_page:1;
12807 + uint16_t ack:1;
12808 + uint16_t remote_fault:1;
12809 + uint16_t reserved_12:1;
12810 + uint16_t asymmetric_pause:1;
12811 + uint16_t pause:1;
12812 + uint16_t advert_100base_t4:1;
12813 + uint16_t advert_100base_tx_full:1;
12814 + uint16_t advert_100base_tx_half:1;
12815 + uint16_t advert_10base_tx_full:1;
12816 + uint16_t advert_10base_tx_half:1;
12817 + uint16_t selector:5;
12818 + } s;
12819 +} cvmx_mdio_phy_reg_link_partner_ability_t;
12820 +
12821 +/**
12822 + * PHY register 6 from the 802.3 spec
12823 + */
12824 +#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6
12825 +typedef union {
12826 + uint16_t u16;
12827 + struct {
12828 + uint16_t reserved_5_15:11;
12829 + uint16_t parallel_detection_fault:1;
12830 + uint16_t link_partner_next_page_capable:1;
12831 + uint16_t local_next_page_capable:1;
12832 + uint16_t page_received:1;
12833 + uint16_t link_partner_autoneg_capable:1;
12834 +
12835 + } s;
12836 +} cvmx_mdio_phy_reg_autoneg_expansion_t;
12837 +
12838 +/**
12839 + * PHY register 9 from the 802.3 spec
12840 + */
12841 +#define CVMX_MDIO_PHY_REG_CONTROL_1000 9
12842 +typedef union {
12843 + uint16_t u16;
12844 + struct {
12845 + uint16_t test_mode:3;
12846 + uint16_t manual_master_slave:1;
12847 + uint16_t master:1;
12848 + uint16_t port_type:1;
12849 + uint16_t advert_1000base_t_full:1;
12850 + uint16_t advert_1000base_t_half:1;
12851 + uint16_t reserved_0_7:8;
12852 + } s;
12853 +} cvmx_mdio_phy_reg_control_1000_t;
12854 +
12855 +/**
12856 + * PHY register 10 from the 802.3 spec
12857 + */
12858 +#define CVMX_MDIO_PHY_REG_STATUS_1000 10
12859 +typedef union {
12860 + uint16_t u16;
12861 + struct {
12862 + uint16_t master_slave_fault:1;
12863 + uint16_t is_master:1;
12864 + uint16_t local_receiver_ok:1;
12865 + uint16_t remote_receiver_ok:1;
12866 + uint16_t remote_capable_1000base_t_full:1;
12867 + uint16_t remote_capable_1000base_t_half:1;
12868 + uint16_t reserved_8_9:2;
12869 + uint16_t idle_error_count:8;
12870 + } s;
12871 +} cvmx_mdio_phy_reg_status_1000_t;
12872 +
12873 +/**
12874 + * PHY register 15 from the 802.3 spec
12875 + */
12876 +#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15
12877 +typedef union {
12878 + uint16_t u16;
12879 + struct {
12880 + uint16_t capable_1000base_x_full:1;
12881 + uint16_t capable_1000base_x_half:1;
12882 + uint16_t capable_1000base_t_full:1;
12883 + uint16_t capable_1000base_t_half:1;
12884 + uint16_t reserved_0_11:12;
12885 + } s;
12886 +} cvmx_mdio_phy_reg_extended_status_t;
12887 +
12888 +/**
12889 + * PHY register 13 from the 802.3 spec
12890 + */
12891 +#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13
12892 +typedef union {
12893 + uint16_t u16;
12894 + struct {
12895 + uint16_t function:2;
12896 + uint16_t reserved_5_13:9;
12897 + uint16_t devad:5;
12898 + } s;
12899 +} cvmx_mdio_phy_reg_mmd_control_t;
12900 +
12901 +/**
12902 + * PHY register 14 from the 802.3 spec
12903 + */
12904 +#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14
12905 +typedef union {
12906 + uint16_t u16;
12907 + struct {
12908 + uint16_t address_data:16;
12909 + } s;
12910 +} cvmx_mdio_phy_reg_mmd_address_data_t;
12911 +
12912 +/* Operating request encodings. */
12913 +#define MDIO_CLAUSE_22_WRITE 0
12914 +#define MDIO_CLAUSE_22_READ 1
12915 +
12916 +#define MDIO_CLAUSE_45_ADDRESS 0
12917 +#define MDIO_CLAUSE_45_WRITE 1
12918 +#define MDIO_CLAUSE_45_READ_INC 2
12919 +#define MDIO_CLAUSE_45_READ 3
12920 +
12921 +/* MMD identifiers, mostly for accessing devices withing XENPAK modules. */
12922 +#define CVMX_MMD_DEVICE_PMA_PMD 1
12923 +#define CVMX_MMD_DEVICE_WIS 2
12924 +#define CVMX_MMD_DEVICE_PCS 3
12925 +#define CVMX_MMD_DEVICE_PHY_XS 4
12926 +#define CVMX_MMD_DEVICE_DTS_XS 5
12927 +#define CVMX_MMD_DEVICE_TC 6
12928 +#define CVMX_MMD_DEVICE_CL22_EXT 29
12929 +#define CVMX_MMD_DEVICE_VENDOR_1 30
12930 +#define CVMX_MMD_DEVICE_VENDOR_2 31
12931 +
12932 +/* Helper function to put MDIO interface into clause 45 mode */
12933 +static inline void __cvmx_mdio_set_clause45_mode(int bus_id)
12934 +{
12935 + union cvmx_smix_clk smi_clk;
12936 + /* Put bus into clause 45 mode */
12937 + smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
12938 + smi_clk.s.mode = 1;
12939 + smi_clk.s.preamble = 1;
12940 + cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
12941 +}
12942 +
12943 +/* Helper function to put MDIO interface into clause 22 mode */
12944 +static inline void __cvmx_mdio_set_clause22_mode(int bus_id)
12945 +{
12946 + union cvmx_smix_clk smi_clk;
12947 + /* Put bus into clause 22 mode */
12948 + smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
12949 + smi_clk.s.mode = 0;
12950 + cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
12951 +}
12952 +
12953 +/**
12954 + * Perform an MII read. This function is used to read PHY
12955 + * registers controlling auto negotiation.
12956 + *
12957 + * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
12958 + * support multiple busses.
12959 + * @phy_id: The MII phy id
12960 + * @location: Register location to read
12961 + *
12962 + * Returns Result from the read or -1 on failure
12963 + */
12964 +static inline int cvmx_mdio_read(int bus_id, int phy_id, int location)
12965 +{
12966 + union cvmx_smix_cmd smi_cmd;
12967 + union cvmx_smix_rd_dat smi_rd;
12968 + int timeout = 1000;
12969 +
12970 + if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
12971 + __cvmx_mdio_set_clause22_mode(bus_id);
12972 +
12973 + smi_cmd.u64 = 0;
12974 + smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ;
12975 + smi_cmd.s.phy_adr = phy_id;
12976 + smi_cmd.s.reg_adr = location;
12977 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
12978 +
12979 + do {
12980 + cvmx_wait(1000);
12981 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
12982 + } while (smi_rd.s.pending && timeout--);
12983 +
12984 + if (smi_rd.s.val)
12985 + return smi_rd.s.dat;
12986 + else
12987 + return -1;
12988 +}
12989 +
12990 +/**
12991 + * Perform an MII write. This function is used to write PHY
12992 + * registers controlling auto negotiation.
12993 + *
12994 + * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
12995 + * support multiple busses.
12996 + * @phy_id: The MII phy id
12997 + * @location: Register location to write
12998 + * @val: Value to write
12999 + *
13000 + * Returns -1 on error
13001 + * 0 on success
13002 + */
13003 +static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val)
13004 +{
13005 + union cvmx_smix_cmd smi_cmd;
13006 + union cvmx_smix_wr_dat smi_wr;
13007 + int timeout = 1000;
13008 +
13009 + if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
13010 + __cvmx_mdio_set_clause22_mode(bus_id);
13011 +
13012 + smi_wr.u64 = 0;
13013 + smi_wr.s.dat = val;
13014 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
13015 +
13016 + smi_cmd.u64 = 0;
13017 + smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE;
13018 + smi_cmd.s.phy_adr = phy_id;
13019 + smi_cmd.s.reg_adr = location;
13020 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13021 +
13022 + do {
13023 + cvmx_wait(1000);
13024 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13025 + } while (smi_wr.s.pending && --timeout);
13026 + if (timeout <= 0)
13027 + return -1;
13028 +
13029 + return 0;
13030 +}
13031 +
13032 +/**
13033 + * Perform an IEEE 802.3 clause 45 MII read. This function is used to
13034 + * read PHY registers controlling auto negotiation.
13035 + *
13036 + * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
13037 + * support multiple busses.
13038 + * @phy_id: The MII phy id
13039 + * @device: MDIO Managable Device (MMD) id
13040 + * @location: Register location to read
13041 + *
13042 + * Returns Result from the read or -1 on failure
13043 + */
13044 +
13045 +static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
13046 + int location)
13047 +{
13048 + union cvmx_smix_cmd smi_cmd;
13049 + union cvmx_smix_rd_dat smi_rd;
13050 + union cvmx_smix_wr_dat smi_wr;
13051 + int timeout = 1000;
13052 +
13053 + if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
13054 + return -1;
13055 +
13056 + __cvmx_mdio_set_clause45_mode(bus_id);
13057 +
13058 + smi_wr.u64 = 0;
13059 + smi_wr.s.dat = location;
13060 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
13061 +
13062 + smi_cmd.u64 = 0;
13063 + smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
13064 + smi_cmd.s.phy_adr = phy_id;
13065 + smi_cmd.s.reg_adr = device;
13066 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13067 +
13068 + do {
13069 + cvmx_wait(1000);
13070 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13071 + } while (smi_wr.s.pending && --timeout);
13072 + if (timeout <= 0) {
13073 + cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
13074 + "device %2d register %2d TIME OUT(address)\n",
13075 + bus_id, phy_id, device, location);
13076 + return -1;
13077 + }
13078 +
13079 + smi_cmd.u64 = 0;
13080 + smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ;
13081 + smi_cmd.s.phy_adr = phy_id;
13082 + smi_cmd.s.reg_adr = device;
13083 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13084 +
13085 + do {
13086 + cvmx_wait(1000);
13087 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
13088 + } while (smi_rd.s.pending && timeout--);
13089 +
13090 + if (timeout <= 0) {
13091 + cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
13092 + "device %2d register %2d TIME OUT(data)\n",
13093 + bus_id, phy_id, device, location);
13094 + return -1;
13095 + }
13096 +
13097 + if (smi_rd.s.val)
13098 + return smi_rd.s.dat;
13099 + else {
13100 + cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
13101 + "device %2d register %2d INVALID READ\n",
13102 + bus_id, phy_id, device, location);
13103 + return -1;
13104 + }
13105 +}
13106 +
13107 +/**
13108 + * Perform an IEEE 802.3 clause 45 MII write. This function is used to
13109 + * write PHY registers controlling auto negotiation.
13110 + *
13111 + * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
13112 + * support multiple busses.
13113 + * @phy_id: The MII phy id
13114 + * @device: MDIO Managable Device (MMD) id
13115 + * @location: Register location to write
13116 + * @val: Value to write
13117 + *
13118 + * Returns -1 on error
13119 + * 0 on success
13120 + */
13121 +static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device,
13122 + int location, int val)
13123 +{
13124 + union cvmx_smix_cmd smi_cmd;
13125 + union cvmx_smix_wr_dat smi_wr;
13126 + int timeout = 1000;
13127 +
13128 + if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
13129 + return -1;
13130 +
13131 + __cvmx_mdio_set_clause45_mode(bus_id);
13132 +
13133 + smi_wr.u64 = 0;
13134 + smi_wr.s.dat = location;
13135 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
13136 +
13137 + smi_cmd.u64 = 0;
13138 + smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
13139 + smi_cmd.s.phy_adr = phy_id;
13140 + smi_cmd.s.reg_adr = device;
13141 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13142 +
13143 + do {
13144 + cvmx_wait(1000);
13145 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13146 + } while (smi_wr.s.pending && --timeout);
13147 + if (timeout <= 0)
13148 + return -1;
13149 +
13150 + smi_wr.u64 = 0;
13151 + smi_wr.s.dat = val;
13152 + cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
13153 +
13154 + smi_cmd.u64 = 0;
13155 + smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE;
13156 + smi_cmd.s.phy_adr = phy_id;
13157 + smi_cmd.s.reg_adr = device;
13158 + cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
13159 +
13160 + do {
13161 + cvmx_wait(1000);
13162 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
13163 + } while (smi_wr.s.pending && --timeout);
13164 + if (timeout <= 0)
13165 + return -1;
13166 +
13167 + return 0;
13168 +}
13169 +
13170 +#endif
13171 diff --git a/drivers/staging/octeon/cvmx-packet.h b/drivers/staging/octeon/cvmx-packet.h
13172 new file mode 100644
13173 index 0000000..62ffe78
13174 --- /dev/null
13175 +++ b/drivers/staging/octeon/cvmx-packet.h
13176 @@ -0,0 +1,65 @@
13177 +/***********************license start***************
13178 + * Author: Cavium Networks
13179 + *
13180 + * Contact: support@caviumnetworks.com
13181 + * This file is part of the OCTEON SDK
13182 + *
13183 + * Copyright (c) 2003-2008 Cavium Networks
13184 + *
13185 + * This file is free software; you can redistribute it and/or modify
13186 + * it under the terms of the GNU General Public License, Version 2, as
13187 + * published by the Free Software Foundation.
13188 + *
13189 + * This file is distributed in the hope that it will be useful, but
13190 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13191 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13192 + * NONINFRINGEMENT. See the GNU General Public License for more
13193 + * details.
13194 + *
13195 + * You should have received a copy of the GNU General Public License
13196 + * along with this file; if not, write to the Free Software
13197 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13198 + * or visit http://www.gnu.org/licenses/.
13199 + *
13200 + * This file may also be available under a different license from Cavium.
13201 + * Contact Cavium Networks for more information
13202 + ***********************license end**************************************/
13203 +
13204 +/**
13205 + *
13206 + * Packet buffer defines.
13207 + */
13208 +
13209 +#ifndef __CVMX_PACKET_H__
13210 +#define __CVMX_PACKET_H__
13211 +
13212 +/**
13213 + * This structure defines a buffer pointer on Octeon
13214 + */
13215 +union cvmx_buf_ptr {
13216 + void *ptr;
13217 + uint64_t u64;
13218 + struct {
13219 + /*
13220 + * if set, invert the "free" pick of the overall
13221 + * packet. HW always sets this bit to 0 on inbound
13222 + * packet
13223 + */
13224 + uint64_t i:1;
13225 + /*
13226 + * Indicates the amount to back up to get to the
13227 + * buffer start in cache lines. In most cases this is
13228 + * less than one complete cache line, so the value is
13229 + * zero.
13230 + */
13231 + uint64_t back:4;
13232 + /* The pool that the buffer came from / goes to */
13233 + uint64_t pool:3;
13234 + /* The size of the segment pointed to by addr (in bytes) */
13235 + uint64_t size:16;
13236 + /* Pointer to the first byte of the data, NOT buffer */
13237 + uint64_t addr:40;
13238 + } s;
13239 +};
13240 +
13241 +#endif /* __CVMX_PACKET_H__ */
13242 diff --git a/drivers/staging/octeon/cvmx-pcsx-defs.h b/drivers/staging/octeon/cvmx-pcsx-defs.h
13243 new file mode 100644
13244 index 0000000..d45952d
13245 --- /dev/null
13246 +++ b/drivers/staging/octeon/cvmx-pcsx-defs.h
13247 @@ -0,0 +1,370 @@
13248 +/***********************license start***************
13249 + * Author: Cavium Networks
13250 + *
13251 + * Contact: support@caviumnetworks.com
13252 + * This file is part of the OCTEON SDK
13253 + *
13254 + * Copyright (c) 2003-2008 Cavium Networks
13255 + *
13256 + * This file is free software; you can redistribute it and/or modify
13257 + * it under the terms of the GNU General Public License, Version 2, as
13258 + * published by the Free Software Foundation.
13259 + *
13260 + * This file is distributed in the hope that it will be useful, but
13261 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13262 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13263 + * NONINFRINGEMENT. See the GNU General Public License for more
13264 + * details.
13265 + *
13266 + * You should have received a copy of the GNU General Public License
13267 + * along with this file; if not, write to the Free Software
13268 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13269 + * or visit http://www.gnu.org/licenses/.
13270 + *
13271 + * This file may also be available under a different license from Cavium.
13272 + * Contact Cavium Networks for more information
13273 + ***********************license end**************************************/
13274 +
13275 +#ifndef __CVMX_PCSX_DEFS_H__
13276 +#define __CVMX_PCSX_DEFS_H__
13277 +
13278 +#define CVMX_PCSX_ANX_ADV_REG(offset, block_id) \
13279 + CVMX_ADD_IO_SEG(0x00011800B0001010ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13280 +#define CVMX_PCSX_ANX_EXT_ST_REG(offset, block_id) \
13281 + CVMX_ADD_IO_SEG(0x00011800B0001028ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13282 +#define CVMX_PCSX_ANX_LP_ABIL_REG(offset, block_id) \
13283 + CVMX_ADD_IO_SEG(0x00011800B0001018ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13284 +#define CVMX_PCSX_ANX_RESULTS_REG(offset, block_id) \
13285 + CVMX_ADD_IO_SEG(0x00011800B0001020ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13286 +#define CVMX_PCSX_INTX_EN_REG(offset, block_id) \
13287 + CVMX_ADD_IO_SEG(0x00011800B0001088ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13288 +#define CVMX_PCSX_INTX_REG(offset, block_id) \
13289 + CVMX_ADD_IO_SEG(0x00011800B0001080ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13290 +#define CVMX_PCSX_LINKX_TIMER_COUNT_REG(offset, block_id) \
13291 + CVMX_ADD_IO_SEG(0x00011800B0001040ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13292 +#define CVMX_PCSX_LOG_ANLX_REG(offset, block_id) \
13293 + CVMX_ADD_IO_SEG(0x00011800B0001090ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13294 +#define CVMX_PCSX_MISCX_CTL_REG(offset, block_id) \
13295 + CVMX_ADD_IO_SEG(0x00011800B0001078ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13296 +#define CVMX_PCSX_MRX_CONTROL_REG(offset, block_id) \
13297 + CVMX_ADD_IO_SEG(0x00011800B0001000ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13298 +#define CVMX_PCSX_MRX_STATUS_REG(offset, block_id) \
13299 + CVMX_ADD_IO_SEG(0x00011800B0001008ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13300 +#define CVMX_PCSX_RXX_STATES_REG(offset, block_id) \
13301 + CVMX_ADD_IO_SEG(0x00011800B0001058ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13302 +#define CVMX_PCSX_RXX_SYNC_REG(offset, block_id) \
13303 + CVMX_ADD_IO_SEG(0x00011800B0001050ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13304 +#define CVMX_PCSX_SGMX_AN_ADV_REG(offset, block_id) \
13305 + CVMX_ADD_IO_SEG(0x00011800B0001068ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13306 +#define CVMX_PCSX_SGMX_LP_ADV_REG(offset, block_id) \
13307 + CVMX_ADD_IO_SEG(0x00011800B0001070ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13308 +#define CVMX_PCSX_TXX_STATES_REG(offset, block_id) \
13309 + CVMX_ADD_IO_SEG(0x00011800B0001060ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13310 +#define CVMX_PCSX_TX_RXX_POLARITY_REG(offset, block_id) \
13311 + CVMX_ADD_IO_SEG(0x00011800B0001048ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
13312 +
13313 +union cvmx_pcsx_anx_adv_reg {
13314 + uint64_t u64;
13315 + struct cvmx_pcsx_anx_adv_reg_s {
13316 + uint64_t reserved_16_63:48;
13317 + uint64_t np:1;
13318 + uint64_t reserved_14_14:1;
13319 + uint64_t rem_flt:2;
13320 + uint64_t reserved_9_11:3;
13321 + uint64_t pause:2;
13322 + uint64_t hfd:1;
13323 + uint64_t fd:1;
13324 + uint64_t reserved_0_4:5;
13325 + } s;
13326 + struct cvmx_pcsx_anx_adv_reg_s cn52xx;
13327 + struct cvmx_pcsx_anx_adv_reg_s cn52xxp1;
13328 + struct cvmx_pcsx_anx_adv_reg_s cn56xx;
13329 + struct cvmx_pcsx_anx_adv_reg_s cn56xxp1;
13330 +};
13331 +
13332 +union cvmx_pcsx_anx_ext_st_reg {
13333 + uint64_t u64;
13334 + struct cvmx_pcsx_anx_ext_st_reg_s {
13335 + uint64_t reserved_16_63:48;
13336 + uint64_t thou_xfd:1;
13337 + uint64_t thou_xhd:1;
13338 + uint64_t thou_tfd:1;
13339 + uint64_t thou_thd:1;
13340 + uint64_t reserved_0_11:12;
13341 + } s;
13342 + struct cvmx_pcsx_anx_ext_st_reg_s cn52xx;
13343 + struct cvmx_pcsx_anx_ext_st_reg_s cn52xxp1;
13344 + struct cvmx_pcsx_anx_ext_st_reg_s cn56xx;
13345 + struct cvmx_pcsx_anx_ext_st_reg_s cn56xxp1;
13346 +};
13347 +
13348 +union cvmx_pcsx_anx_lp_abil_reg {
13349 + uint64_t u64;
13350 + struct cvmx_pcsx_anx_lp_abil_reg_s {
13351 + uint64_t reserved_16_63:48;
13352 + uint64_t np:1;
13353 + uint64_t ack:1;
13354 + uint64_t rem_flt:2;
13355 + uint64_t reserved_9_11:3;
13356 + uint64_t pause:2;
13357 + uint64_t hfd:1;
13358 + uint64_t fd:1;
13359 + uint64_t reserved_0_4:5;
13360 + } s;
13361 + struct cvmx_pcsx_anx_lp_abil_reg_s cn52xx;
13362 + struct cvmx_pcsx_anx_lp_abil_reg_s cn52xxp1;
13363 + struct cvmx_pcsx_anx_lp_abil_reg_s cn56xx;
13364 + struct cvmx_pcsx_anx_lp_abil_reg_s cn56xxp1;
13365 +};
13366 +
13367 +union cvmx_pcsx_anx_results_reg {
13368 + uint64_t u64;
13369 + struct cvmx_pcsx_anx_results_reg_s {
13370 + uint64_t reserved_7_63:57;
13371 + uint64_t pause:2;
13372 + uint64_t spd:2;
13373 + uint64_t an_cpt:1;
13374 + uint64_t dup:1;
13375 + uint64_t link_ok:1;
13376 + } s;
13377 + struct cvmx_pcsx_anx_results_reg_s cn52xx;
13378 + struct cvmx_pcsx_anx_results_reg_s cn52xxp1;
13379 + struct cvmx_pcsx_anx_results_reg_s cn56xx;
13380 + struct cvmx_pcsx_anx_results_reg_s cn56xxp1;
13381 +};
13382 +
13383 +union cvmx_pcsx_intx_en_reg {
13384 + uint64_t u64;
13385 + struct cvmx_pcsx_intx_en_reg_s {
13386 + uint64_t reserved_12_63:52;
13387 + uint64_t dup:1;
13388 + uint64_t sync_bad_en:1;
13389 + uint64_t an_bad_en:1;
13390 + uint64_t rxlock_en:1;
13391 + uint64_t rxbad_en:1;
13392 + uint64_t rxerr_en:1;
13393 + uint64_t txbad_en:1;
13394 + uint64_t txfifo_en:1;
13395 + uint64_t txfifu_en:1;
13396 + uint64_t an_err_en:1;
13397 + uint64_t xmit_en:1;
13398 + uint64_t lnkspd_en:1;
13399 + } s;
13400 + struct cvmx_pcsx_intx_en_reg_s cn52xx;
13401 + struct cvmx_pcsx_intx_en_reg_s cn52xxp1;
13402 + struct cvmx_pcsx_intx_en_reg_s cn56xx;
13403 + struct cvmx_pcsx_intx_en_reg_s cn56xxp1;
13404 +};
13405 +
13406 +union cvmx_pcsx_intx_reg {
13407 + uint64_t u64;
13408 + struct cvmx_pcsx_intx_reg_s {
13409 + uint64_t reserved_12_63:52;
13410 + uint64_t dup:1;
13411 + uint64_t sync_bad:1;
13412 + uint64_t an_bad:1;
13413 + uint64_t rxlock:1;
13414 + uint64_t rxbad:1;
13415 + uint64_t rxerr:1;
13416 + uint64_t txbad:1;
13417 + uint64_t txfifo:1;
13418 + uint64_t txfifu:1;
13419 + uint64_t an_err:1;
13420 + uint64_t xmit:1;
13421 + uint64_t lnkspd:1;
13422 + } s;
13423 + struct cvmx_pcsx_intx_reg_s cn52xx;
13424 + struct cvmx_pcsx_intx_reg_s cn52xxp1;
13425 + struct cvmx_pcsx_intx_reg_s cn56xx;
13426 + struct cvmx_pcsx_intx_reg_s cn56xxp1;
13427 +};
13428 +
13429 +union cvmx_pcsx_linkx_timer_count_reg {
13430 + uint64_t u64;
13431 + struct cvmx_pcsx_linkx_timer_count_reg_s {
13432 + uint64_t reserved_16_63:48;
13433 + uint64_t count:16;
13434 + } s;
13435 + struct cvmx_pcsx_linkx_timer_count_reg_s cn52xx;
13436 + struct cvmx_pcsx_linkx_timer_count_reg_s cn52xxp1;
13437 + struct cvmx_pcsx_linkx_timer_count_reg_s cn56xx;
13438 + struct cvmx_pcsx_linkx_timer_count_reg_s cn56xxp1;
13439 +};
13440 +
13441 +union cvmx_pcsx_log_anlx_reg {
13442 + uint64_t u64;
13443 + struct cvmx_pcsx_log_anlx_reg_s {
13444 + uint64_t reserved_4_63:60;
13445 + uint64_t lafifovfl:1;
13446 + uint64_t la_en:1;
13447 + uint64_t pkt_sz:2;
13448 + } s;
13449 + struct cvmx_pcsx_log_anlx_reg_s cn52xx;
13450 + struct cvmx_pcsx_log_anlx_reg_s cn52xxp1;
13451 + struct cvmx_pcsx_log_anlx_reg_s cn56xx;
13452 + struct cvmx_pcsx_log_anlx_reg_s cn56xxp1;
13453 +};
13454 +
13455 +union cvmx_pcsx_miscx_ctl_reg {
13456 + uint64_t u64;
13457 + struct cvmx_pcsx_miscx_ctl_reg_s {
13458 + uint64_t reserved_13_63:51;
13459 + uint64_t sgmii:1;
13460 + uint64_t gmxeno:1;
13461 + uint64_t loopbck2:1;
13462 + uint64_t mac_phy:1;
13463 + uint64_t mode:1;
13464 + uint64_t an_ovrd:1;
13465 + uint64_t samp_pt:7;
13466 + } s;
13467 + struct cvmx_pcsx_miscx_ctl_reg_s cn52xx;
13468 + struct cvmx_pcsx_miscx_ctl_reg_s cn52xxp1;
13469 + struct cvmx_pcsx_miscx_ctl_reg_s cn56xx;
13470 + struct cvmx_pcsx_miscx_ctl_reg_s cn56xxp1;
13471 +};
13472 +
13473 +union cvmx_pcsx_mrx_control_reg {
13474 + uint64_t u64;
13475 + struct cvmx_pcsx_mrx_control_reg_s {
13476 + uint64_t reserved_16_63:48;
13477 + uint64_t reset:1;
13478 + uint64_t loopbck1:1;
13479 + uint64_t spdlsb:1;
13480 + uint64_t an_en:1;
13481 + uint64_t pwr_dn:1;
13482 + uint64_t reserved_10_10:1;
13483 + uint64_t rst_an:1;
13484 + uint64_t dup:1;
13485 + uint64_t coltst:1;
13486 + uint64_t spdmsb:1;
13487 + uint64_t uni:1;
13488 + uint64_t reserved_0_4:5;
13489 + } s;
13490 + struct cvmx_pcsx_mrx_control_reg_s cn52xx;
13491 + struct cvmx_pcsx_mrx_control_reg_s cn52xxp1;
13492 + struct cvmx_pcsx_mrx_control_reg_s cn56xx;
13493 + struct cvmx_pcsx_mrx_control_reg_s cn56xxp1;
13494 +};
13495 +
13496 +union cvmx_pcsx_mrx_status_reg {
13497 + uint64_t u64;
13498 + struct cvmx_pcsx_mrx_status_reg_s {
13499 + uint64_t reserved_16_63:48;
13500 + uint64_t hun_t4:1;
13501 + uint64_t hun_xfd:1;
13502 + uint64_t hun_xhd:1;
13503 + uint64_t ten_fd:1;
13504 + uint64_t ten_hd:1;
13505 + uint64_t hun_t2fd:1;
13506 + uint64_t hun_t2hd:1;
13507 + uint64_t ext_st:1;
13508 + uint64_t reserved_7_7:1;
13509 + uint64_t prb_sup:1;
13510 + uint64_t an_cpt:1;
13511 + uint64_t rm_flt:1;
13512 + uint64_t an_abil:1;
13513 + uint64_t lnk_st:1;
13514 + uint64_t reserved_1_1:1;
13515 + uint64_t extnd:1;
13516 + } s;
13517 + struct cvmx_pcsx_mrx_status_reg_s cn52xx;
13518 + struct cvmx_pcsx_mrx_status_reg_s cn52xxp1;
13519 + struct cvmx_pcsx_mrx_status_reg_s cn56xx;
13520 + struct cvmx_pcsx_mrx_status_reg_s cn56xxp1;
13521 +};
13522 +
13523 +union cvmx_pcsx_rxx_states_reg {
13524 + uint64_t u64;
13525 + struct cvmx_pcsx_rxx_states_reg_s {
13526 + uint64_t reserved_16_63:48;
13527 + uint64_t rx_bad:1;
13528 + uint64_t rx_st:5;
13529 + uint64_t sync_bad:1;
13530 + uint64_t sync:4;
13531 + uint64_t an_bad:1;
13532 + uint64_t an_st:4;
13533 + } s;
13534 + struct cvmx_pcsx_rxx_states_reg_s cn52xx;
13535 + struct cvmx_pcsx_rxx_states_reg_s cn52xxp1;
13536 + struct cvmx_pcsx_rxx_states_reg_s cn56xx;
13537 + struct cvmx_pcsx_rxx_states_reg_s cn56xxp1;
13538 +};
13539 +
13540 +union cvmx_pcsx_rxx_sync_reg {
13541 + uint64_t u64;
13542 + struct cvmx_pcsx_rxx_sync_reg_s {
13543 + uint64_t reserved_2_63:62;
13544 + uint64_t sync:1;
13545 + uint64_t bit_lock:1;
13546 + } s;
13547 + struct cvmx_pcsx_rxx_sync_reg_s cn52xx;
13548 + struct cvmx_pcsx_rxx_sync_reg_s cn52xxp1;
13549 + struct cvmx_pcsx_rxx_sync_reg_s cn56xx;
13550 + struct cvmx_pcsx_rxx_sync_reg_s cn56xxp1;
13551 +};
13552 +
13553 +union cvmx_pcsx_sgmx_an_adv_reg {
13554 + uint64_t u64;
13555 + struct cvmx_pcsx_sgmx_an_adv_reg_s {
13556 + uint64_t reserved_16_63:48;
13557 + uint64_t link:1;
13558 + uint64_t ack:1;
13559 + uint64_t reserved_13_13:1;
13560 + uint64_t dup:1;
13561 + uint64_t speed:2;
13562 + uint64_t reserved_1_9:9;
13563 + uint64_t one:1;
13564 + } s;
13565 + struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xx;
13566 + struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xxp1;
13567 + struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xx;
13568 + struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xxp1;
13569 +};
13570 +
13571 +union cvmx_pcsx_sgmx_lp_adv_reg {
13572 + uint64_t u64;
13573 + struct cvmx_pcsx_sgmx_lp_adv_reg_s {
13574 + uint64_t reserved_16_63:48;
13575 + uint64_t link:1;
13576 + uint64_t reserved_13_14:2;
13577 + uint64_t dup:1;
13578 + uint64_t speed:2;
13579 + uint64_t reserved_1_9:9;
13580 + uint64_t one:1;
13581 + } s;
13582 + struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xx;
13583 + struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xxp1;
13584 + struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xx;
13585 + struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xxp1;
13586 +};
13587 +
13588 +union cvmx_pcsx_txx_states_reg {
13589 + uint64_t u64;
13590 + struct cvmx_pcsx_txx_states_reg_s {
13591 + uint64_t reserved_7_63:57;
13592 + uint64_t xmit:2;
13593 + uint64_t tx_bad:1;
13594 + uint64_t ord_st:4;
13595 + } s;
13596 + struct cvmx_pcsx_txx_states_reg_s cn52xx;
13597 + struct cvmx_pcsx_txx_states_reg_s cn52xxp1;
13598 + struct cvmx_pcsx_txx_states_reg_s cn56xx;
13599 + struct cvmx_pcsx_txx_states_reg_s cn56xxp1;
13600 +};
13601 +
13602 +union cvmx_pcsx_tx_rxx_polarity_reg {
13603 + uint64_t u64;
13604 + struct cvmx_pcsx_tx_rxx_polarity_reg_s {
13605 + uint64_t reserved_4_63:60;
13606 + uint64_t rxovrd:1;
13607 + uint64_t autorxpl:1;
13608 + uint64_t rxplrt:1;
13609 + uint64_t txplrt:1;
13610 + } s;
13611 + struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xx;
13612 + struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xxp1;
13613 + struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xx;
13614 + struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xxp1;
13615 +};
13616 +
13617 +#endif
13618 diff --git a/drivers/staging/octeon/cvmx-pcsxx-defs.h b/drivers/staging/octeon/cvmx-pcsxx-defs.h
13619 new file mode 100644
13620 index 0000000..55d120f
13621 --- /dev/null
13622 +++ b/drivers/staging/octeon/cvmx-pcsxx-defs.h
13623 @@ -0,0 +1,316 @@
13624 +/***********************license start***************
13625 + * Author: Cavium Networks
13626 + *
13627 + * Contact: support@caviumnetworks.com
13628 + * This file is part of the OCTEON SDK
13629 + *
13630 + * Copyright (c) 2003-2008 Cavium Networks
13631 + *
13632 + * This file is free software; you can redistribute it and/or modify
13633 + * it under the terms of the GNU General Public License, Version 2, as
13634 + * published by the Free Software Foundation.
13635 + *
13636 + * This file is distributed in the hope that it will be useful, but
13637 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13638 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13639 + * NONINFRINGEMENT. See the GNU General Public License for more
13640 + * details.
13641 + *
13642 + * You should have received a copy of the GNU General Public License
13643 + * along with this file; if not, write to the Free Software
13644 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13645 + * or visit http://www.gnu.org/licenses/.
13646 + *
13647 + * This file may also be available under a different license from Cavium.
13648 + * Contact Cavium Networks for more information
13649 + ***********************license end**************************************/
13650 +
13651 +#ifndef __CVMX_PCSXX_DEFS_H__
13652 +#define __CVMX_PCSXX_DEFS_H__
13653 +
13654 +#define CVMX_PCSXX_10GBX_STATUS_REG(block_id) \
13655 + CVMX_ADD_IO_SEG(0x00011800B0000828ull + (((block_id) & 1) * 0x8000000ull))
13656 +#define CVMX_PCSXX_BIST_STATUS_REG(block_id) \
13657 + CVMX_ADD_IO_SEG(0x00011800B0000870ull + (((block_id) & 1) * 0x8000000ull))
13658 +#define CVMX_PCSXX_BIT_LOCK_STATUS_REG(block_id) \
13659 + CVMX_ADD_IO_SEG(0x00011800B0000850ull + (((block_id) & 1) * 0x8000000ull))
13660 +#define CVMX_PCSXX_CONTROL1_REG(block_id) \
13661 + CVMX_ADD_IO_SEG(0x00011800B0000800ull + (((block_id) & 1) * 0x8000000ull))
13662 +#define CVMX_PCSXX_CONTROL2_REG(block_id) \
13663 + CVMX_ADD_IO_SEG(0x00011800B0000818ull + (((block_id) & 1) * 0x8000000ull))
13664 +#define CVMX_PCSXX_INT_EN_REG(block_id) \
13665 + CVMX_ADD_IO_SEG(0x00011800B0000860ull + (((block_id) & 1) * 0x8000000ull))
13666 +#define CVMX_PCSXX_INT_REG(block_id) \
13667 + CVMX_ADD_IO_SEG(0x00011800B0000858ull + (((block_id) & 1) * 0x8000000ull))
13668 +#define CVMX_PCSXX_LOG_ANL_REG(block_id) \
13669 + CVMX_ADD_IO_SEG(0x00011800B0000868ull + (((block_id) & 1) * 0x8000000ull))
13670 +#define CVMX_PCSXX_MISC_CTL_REG(block_id) \
13671 + CVMX_ADD_IO_SEG(0x00011800B0000848ull + (((block_id) & 1) * 0x8000000ull))
13672 +#define CVMX_PCSXX_RX_SYNC_STATES_REG(block_id) \
13673 + CVMX_ADD_IO_SEG(0x00011800B0000838ull + (((block_id) & 1) * 0x8000000ull))
13674 +#define CVMX_PCSXX_SPD_ABIL_REG(block_id) \
13675 + CVMX_ADD_IO_SEG(0x00011800B0000810ull + (((block_id) & 1) * 0x8000000ull))
13676 +#define CVMX_PCSXX_STATUS1_REG(block_id) \
13677 + CVMX_ADD_IO_SEG(0x00011800B0000808ull + (((block_id) & 1) * 0x8000000ull))
13678 +#define CVMX_PCSXX_STATUS2_REG(block_id) \
13679 + CVMX_ADD_IO_SEG(0x00011800B0000820ull + (((block_id) & 1) * 0x8000000ull))
13680 +#define CVMX_PCSXX_TX_RX_POLARITY_REG(block_id) \
13681 + CVMX_ADD_IO_SEG(0x00011800B0000840ull + (((block_id) & 1) * 0x8000000ull))
13682 +#define CVMX_PCSXX_TX_RX_STATES_REG(block_id) \
13683 + CVMX_ADD_IO_SEG(0x00011800B0000830ull + (((block_id) & 1) * 0x8000000ull))
13684 +
13685 +union cvmx_pcsxx_10gbx_status_reg {
13686 + uint64_t u64;
13687 + struct cvmx_pcsxx_10gbx_status_reg_s {
13688 + uint64_t reserved_13_63:51;
13689 + uint64_t alignd:1;
13690 + uint64_t pattst:1;
13691 + uint64_t reserved_4_10:7;
13692 + uint64_t l3sync:1;
13693 + uint64_t l2sync:1;
13694 + uint64_t l1sync:1;
13695 + uint64_t l0sync:1;
13696 + } s;
13697 + struct cvmx_pcsxx_10gbx_status_reg_s cn52xx;
13698 + struct cvmx_pcsxx_10gbx_status_reg_s cn52xxp1;
13699 + struct cvmx_pcsxx_10gbx_status_reg_s cn56xx;
13700 + struct cvmx_pcsxx_10gbx_status_reg_s cn56xxp1;
13701 +};
13702 +
13703 +union cvmx_pcsxx_bist_status_reg {
13704 + uint64_t u64;
13705 + struct cvmx_pcsxx_bist_status_reg_s {
13706 + uint64_t reserved_1_63:63;
13707 + uint64_t bist_status:1;
13708 + } s;
13709 + struct cvmx_pcsxx_bist_status_reg_s cn52xx;
13710 + struct cvmx_pcsxx_bist_status_reg_s cn52xxp1;
13711 + struct cvmx_pcsxx_bist_status_reg_s cn56xx;
13712 + struct cvmx_pcsxx_bist_status_reg_s cn56xxp1;
13713 +};
13714 +
13715 +union cvmx_pcsxx_bit_lock_status_reg {
13716 + uint64_t u64;
13717 + struct cvmx_pcsxx_bit_lock_status_reg_s {
13718 + uint64_t reserved_4_63:60;
13719 + uint64_t bitlck3:1;
13720 + uint64_t bitlck2:1;
13721 + uint64_t bitlck1:1;
13722 + uint64_t bitlck0:1;
13723 + } s;
13724 + struct cvmx_pcsxx_bit_lock_status_reg_s cn52xx;
13725 + struct cvmx_pcsxx_bit_lock_status_reg_s cn52xxp1;
13726 + struct cvmx_pcsxx_bit_lock_status_reg_s cn56xx;
13727 + struct cvmx_pcsxx_bit_lock_status_reg_s cn56xxp1;
13728 +};
13729 +
13730 +union cvmx_pcsxx_control1_reg {
13731 + uint64_t u64;
13732 + struct cvmx_pcsxx_control1_reg_s {
13733 + uint64_t reserved_16_63:48;
13734 + uint64_t reset:1;
13735 + uint64_t loopbck1:1;
13736 + uint64_t spdsel1:1;
13737 + uint64_t reserved_12_12:1;
13738 + uint64_t lo_pwr:1;
13739 + uint64_t reserved_7_10:4;
13740 + uint64_t spdsel0:1;
13741 + uint64_t spd:4;
13742 + uint64_t reserved_0_1:2;
13743 + } s;
13744 + struct cvmx_pcsxx_control1_reg_s cn52xx;
13745 + struct cvmx_pcsxx_control1_reg_s cn52xxp1;
13746 + struct cvmx_pcsxx_control1_reg_s cn56xx;
13747 + struct cvmx_pcsxx_control1_reg_s cn56xxp1;
13748 +};
13749 +
13750 +union cvmx_pcsxx_control2_reg {
13751 + uint64_t u64;
13752 + struct cvmx_pcsxx_control2_reg_s {
13753 + uint64_t reserved_2_63:62;
13754 + uint64_t type:2;
13755 + } s;
13756 + struct cvmx_pcsxx_control2_reg_s cn52xx;
13757 + struct cvmx_pcsxx_control2_reg_s cn52xxp1;
13758 + struct cvmx_pcsxx_control2_reg_s cn56xx;
13759 + struct cvmx_pcsxx_control2_reg_s cn56xxp1;
13760 +};
13761 +
13762 +union cvmx_pcsxx_int_en_reg {
13763 + uint64_t u64;
13764 + struct cvmx_pcsxx_int_en_reg_s {
13765 + uint64_t reserved_6_63:58;
13766 + uint64_t algnlos_en:1;
13767 + uint64_t synlos_en:1;
13768 + uint64_t bitlckls_en:1;
13769 + uint64_t rxsynbad_en:1;
13770 + uint64_t rxbad_en:1;
13771 + uint64_t txflt_en:1;
13772 + } s;
13773 + struct cvmx_pcsxx_int_en_reg_s cn52xx;
13774 + struct cvmx_pcsxx_int_en_reg_s cn52xxp1;
13775 + struct cvmx_pcsxx_int_en_reg_s cn56xx;
13776 + struct cvmx_pcsxx_int_en_reg_s cn56xxp1;
13777 +};
13778 +
13779 +union cvmx_pcsxx_int_reg {
13780 + uint64_t u64;
13781 + struct cvmx_pcsxx_int_reg_s {
13782 + uint64_t reserved_6_63:58;
13783 + uint64_t algnlos:1;
13784 + uint64_t synlos:1;
13785 + uint64_t bitlckls:1;
13786 + uint64_t rxsynbad:1;
13787 + uint64_t rxbad:1;
13788 + uint64_t txflt:1;
13789 + } s;
13790 + struct cvmx_pcsxx_int_reg_s cn52xx;
13791 + struct cvmx_pcsxx_int_reg_s cn52xxp1;
13792 + struct cvmx_pcsxx_int_reg_s cn56xx;
13793 + struct cvmx_pcsxx_int_reg_s cn56xxp1;
13794 +};
13795 +
13796 +union cvmx_pcsxx_log_anl_reg {
13797 + uint64_t u64;
13798 + struct cvmx_pcsxx_log_anl_reg_s {
13799 + uint64_t reserved_7_63:57;
13800 + uint64_t enc_mode:1;
13801 + uint64_t drop_ln:2;
13802 + uint64_t lafifovfl:1;
13803 + uint64_t la_en:1;
13804 + uint64_t pkt_sz:2;
13805 + } s;
13806 + struct cvmx_pcsxx_log_anl_reg_s cn52xx;
13807 + struct cvmx_pcsxx_log_anl_reg_s cn52xxp1;
13808 + struct cvmx_pcsxx_log_anl_reg_s cn56xx;
13809 + struct cvmx_pcsxx_log_anl_reg_s cn56xxp1;
13810 +};
13811 +
13812 +union cvmx_pcsxx_misc_ctl_reg {
13813 + uint64_t u64;
13814 + struct cvmx_pcsxx_misc_ctl_reg_s {
13815 + uint64_t reserved_4_63:60;
13816 + uint64_t tx_swap:1;
13817 + uint64_t rx_swap:1;
13818 + uint64_t xaui:1;
13819 + uint64_t gmxeno:1;
13820 + } s;
13821 + struct cvmx_pcsxx_misc_ctl_reg_s cn52xx;
13822 + struct cvmx_pcsxx_misc_ctl_reg_s cn52xxp1;
13823 + struct cvmx_pcsxx_misc_ctl_reg_s cn56xx;
13824 + struct cvmx_pcsxx_misc_ctl_reg_s cn56xxp1;
13825 +};
13826 +
13827 +union cvmx_pcsxx_rx_sync_states_reg {
13828 + uint64_t u64;
13829 + struct cvmx_pcsxx_rx_sync_states_reg_s {
13830 + uint64_t reserved_16_63:48;
13831 + uint64_t sync3st:4;
13832 + uint64_t sync2st:4;
13833 + uint64_t sync1st:4;
13834 + uint64_t sync0st:4;
13835 + } s;
13836 + struct cvmx_pcsxx_rx_sync_states_reg_s cn52xx;
13837 + struct cvmx_pcsxx_rx_sync_states_reg_s cn52xxp1;
13838 + struct cvmx_pcsxx_rx_sync_states_reg_s cn56xx;
13839 + struct cvmx_pcsxx_rx_sync_states_reg_s cn56xxp1;
13840 +};
13841 +
13842 +union cvmx_pcsxx_spd_abil_reg {
13843 + uint64_t u64;
13844 + struct cvmx_pcsxx_spd_abil_reg_s {
13845 + uint64_t reserved_2_63:62;
13846 + uint64_t tenpasst:1;
13847 + uint64_t tengb:1;
13848 + } s;
13849 + struct cvmx_pcsxx_spd_abil_reg_s cn52xx;
13850 + struct cvmx_pcsxx_spd_abil_reg_s cn52xxp1;
13851 + struct cvmx_pcsxx_spd_abil_reg_s cn56xx;
13852 + struct cvmx_pcsxx_spd_abil_reg_s cn56xxp1;
13853 +};
13854 +
13855 +union cvmx_pcsxx_status1_reg {
13856 + uint64_t u64;
13857 + struct cvmx_pcsxx_status1_reg_s {
13858 + uint64_t reserved_8_63:56;
13859 + uint64_t flt:1;
13860 + uint64_t reserved_3_6:4;
13861 + uint64_t rcv_lnk:1;
13862 + uint64_t lpable:1;
13863 + uint64_t reserved_0_0:1;
13864 + } s;
13865 + struct cvmx_pcsxx_status1_reg_s cn52xx;
13866 + struct cvmx_pcsxx_status1_reg_s cn52xxp1;
13867 + struct cvmx_pcsxx_status1_reg_s cn56xx;
13868 + struct cvmx_pcsxx_status1_reg_s cn56xxp1;
13869 +};
13870 +
13871 +union cvmx_pcsxx_status2_reg {
13872 + uint64_t u64;
13873 + struct cvmx_pcsxx_status2_reg_s {
13874 + uint64_t reserved_16_63:48;
13875 + uint64_t dev:2;
13876 + uint64_t reserved_12_13:2;
13877 + uint64_t xmtflt:1;
13878 + uint64_t rcvflt:1;
13879 + uint64_t reserved_3_9:7;
13880 + uint64_t tengb_w:1;
13881 + uint64_t tengb_x:1;
13882 + uint64_t tengb_r:1;
13883 + } s;
13884 + struct cvmx_pcsxx_status2_reg_s cn52xx;
13885 + struct cvmx_pcsxx_status2_reg_s cn52xxp1;
13886 + struct cvmx_pcsxx_status2_reg_s cn56xx;
13887 + struct cvmx_pcsxx_status2_reg_s cn56xxp1;
13888 +};
13889 +
13890 +union cvmx_pcsxx_tx_rx_polarity_reg {
13891 + uint64_t u64;
13892 + struct cvmx_pcsxx_tx_rx_polarity_reg_s {
13893 + uint64_t reserved_10_63:54;
13894 + uint64_t xor_rxplrt:4;
13895 + uint64_t xor_txplrt:4;
13896 + uint64_t rxplrt:1;
13897 + uint64_t txplrt:1;
13898 + } s;
13899 + struct cvmx_pcsxx_tx_rx_polarity_reg_s cn52xx;
13900 + struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 {
13901 + uint64_t reserved_2_63:62;
13902 + uint64_t rxplrt:1;
13903 + uint64_t txplrt:1;
13904 + } cn52xxp1;
13905 + struct cvmx_pcsxx_tx_rx_polarity_reg_s cn56xx;
13906 + struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 cn56xxp1;
13907 +};
13908 +
13909 +union cvmx_pcsxx_tx_rx_states_reg {
13910 + uint64_t u64;
13911 + struct cvmx_pcsxx_tx_rx_states_reg_s {
13912 + uint64_t reserved_14_63:50;
13913 + uint64_t term_err:1;
13914 + uint64_t syn3bad:1;
13915 + uint64_t syn2bad:1;
13916 + uint64_t syn1bad:1;
13917 + uint64_t syn0bad:1;
13918 + uint64_t rxbad:1;
13919 + uint64_t algn_st:3;
13920 + uint64_t rx_st:2;
13921 + uint64_t tx_st:3;
13922 + } s;
13923 + struct cvmx_pcsxx_tx_rx_states_reg_s cn52xx;
13924 + struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 {
13925 + uint64_t reserved_13_63:51;
13926 + uint64_t syn3bad:1;
13927 + uint64_t syn2bad:1;
13928 + uint64_t syn1bad:1;
13929 + uint64_t syn0bad:1;
13930 + uint64_t rxbad:1;
13931 + uint64_t algn_st:3;
13932 + uint64_t rx_st:2;
13933 + uint64_t tx_st:3;
13934 + } cn52xxp1;
13935 + struct cvmx_pcsxx_tx_rx_states_reg_s cn56xx;
13936 + struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 cn56xxp1;
13937 +};
13938 +
13939 +#endif
13940 diff --git a/drivers/staging/octeon/cvmx-pip-defs.h b/drivers/staging/octeon/cvmx-pip-defs.h
13941 new file mode 100644
13942 index 0000000..5a36910
13943 --- /dev/null
13944 +++ b/drivers/staging/octeon/cvmx-pip-defs.h
13945 @@ -0,0 +1,1267 @@
13946 +/***********************license start***************
13947 + * Author: Cavium Networks
13948 + *
13949 + * Contact: support@caviumnetworks.com
13950 + * This file is part of the OCTEON SDK
13951 + *
13952 + * Copyright (c) 2003-2008 Cavium Networks
13953 + *
13954 + * This file is free software; you can redistribute it and/or modify
13955 + * it under the terms of the GNU General Public License, Version 2, as
13956 + * published by the Free Software Foundation.
13957 + *
13958 + * This file is distributed in the hope that it will be useful, but
13959 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
13960 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
13961 + * NONINFRINGEMENT. See the GNU General Public License for more
13962 + * details.
13963 + *
13964 + * You should have received a copy of the GNU General Public License
13965 + * along with this file; if not, write to the Free Software
13966 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13967 + * or visit http://www.gnu.org/licenses/.
13968 + *
13969 + * This file may also be available under a different license from Cavium.
13970 + * Contact Cavium Networks for more information
13971 + ***********************license end**************************************/
13972 +
13973 +#ifndef __CVMX_PIP_DEFS_H__
13974 +#define __CVMX_PIP_DEFS_H__
13975 +
13976 +/*
13977 + * Enumeration representing the amount of packet processing
13978 + * and validation performed by the input hardware.
13979 + */
13980 +enum cvmx_pip_port_parse_mode {
13981 + /*
13982 + * Packet input doesn't perform any processing of the input
13983 + * packet.
13984 + */
13985 + CVMX_PIP_PORT_CFG_MODE_NONE = 0ull,
13986 + /*
13987 + * Full packet processing is performed with pointer starting
13988 + * at the L2 (ethernet MAC) header.
13989 + */
13990 + CVMX_PIP_PORT_CFG_MODE_SKIPL2 = 1ull,
13991 + /*
13992 + * Input packets are assumed to be IP. Results from non IP
13993 + * packets is undefined. Pointers reference the beginning of
13994 + * the IP header.
13995 + */
13996 + CVMX_PIP_PORT_CFG_MODE_SKIPIP = 2ull
13997 +};
13998 +
13999 +#define CVMX_PIP_BCK_PRS \
14000 + CVMX_ADD_IO_SEG(0x00011800A0000038ull)
14001 +#define CVMX_PIP_BIST_STATUS \
14002 + CVMX_ADD_IO_SEG(0x00011800A0000000ull)
14003 +#define CVMX_PIP_CRC_CTLX(offset) \
14004 + CVMX_ADD_IO_SEG(0x00011800A0000040ull + (((offset) & 1) * 8))
14005 +#define CVMX_PIP_CRC_IVX(offset) \
14006 + CVMX_ADD_IO_SEG(0x00011800A0000050ull + (((offset) & 1) * 8))
14007 +#define CVMX_PIP_DEC_IPSECX(offset) \
14008 + CVMX_ADD_IO_SEG(0x00011800A0000080ull + (((offset) & 3) * 8))
14009 +#define CVMX_PIP_DSA_SRC_GRP \
14010 + CVMX_ADD_IO_SEG(0x00011800A0000190ull)
14011 +#define CVMX_PIP_DSA_VID_GRP \
14012 + CVMX_ADD_IO_SEG(0x00011800A0000198ull)
14013 +#define CVMX_PIP_FRM_LEN_CHKX(offset) \
14014 + CVMX_ADD_IO_SEG(0x00011800A0000180ull + (((offset) & 1) * 8))
14015 +#define CVMX_PIP_GBL_CFG \
14016 + CVMX_ADD_IO_SEG(0x00011800A0000028ull)
14017 +#define CVMX_PIP_GBL_CTL \
14018 + CVMX_ADD_IO_SEG(0x00011800A0000020ull)
14019 +#define CVMX_PIP_HG_PRI_QOS \
14020 + CVMX_ADD_IO_SEG(0x00011800A00001A0ull)
14021 +#define CVMX_PIP_INT_EN \
14022 + CVMX_ADD_IO_SEG(0x00011800A0000010ull)
14023 +#define CVMX_PIP_INT_REG \
14024 + CVMX_ADD_IO_SEG(0x00011800A0000008ull)
14025 +#define CVMX_PIP_IP_OFFSET \
14026 + CVMX_ADD_IO_SEG(0x00011800A0000060ull)
14027 +#define CVMX_PIP_PRT_CFGX(offset) \
14028 + CVMX_ADD_IO_SEG(0x00011800A0000200ull + (((offset) & 63) * 8))
14029 +#define CVMX_PIP_PRT_TAGX(offset) \
14030 + CVMX_ADD_IO_SEG(0x00011800A0000400ull + (((offset) & 63) * 8))
14031 +#define CVMX_PIP_QOS_DIFFX(offset) \
14032 + CVMX_ADD_IO_SEG(0x00011800A0000600ull + (((offset) & 63) * 8))
14033 +#define CVMX_PIP_QOS_VLANX(offset) \
14034 + CVMX_ADD_IO_SEG(0x00011800A00000C0ull + (((offset) & 7) * 8))
14035 +#define CVMX_PIP_QOS_WATCHX(offset) \
14036 + CVMX_ADD_IO_SEG(0x00011800A0000100ull + (((offset) & 7) * 8))
14037 +#define CVMX_PIP_RAW_WORD \
14038 + CVMX_ADD_IO_SEG(0x00011800A00000B0ull)
14039 +#define CVMX_PIP_SFT_RST \
14040 + CVMX_ADD_IO_SEG(0x00011800A0000030ull)
14041 +#define CVMX_PIP_STAT0_PRTX(offset) \
14042 + CVMX_ADD_IO_SEG(0x00011800A0000800ull + (((offset) & 63) * 80))
14043 +#define CVMX_PIP_STAT1_PRTX(offset) \
14044 + CVMX_ADD_IO_SEG(0x00011800A0000808ull + (((offset) & 63) * 80))
14045 +#define CVMX_PIP_STAT2_PRTX(offset) \
14046 + CVMX_ADD_IO_SEG(0x00011800A0000810ull + (((offset) & 63) * 80))
14047 +#define CVMX_PIP_STAT3_PRTX(offset) \
14048 + CVMX_ADD_IO_SEG(0x00011800A0000818ull + (((offset) & 63) * 80))
14049 +#define CVMX_PIP_STAT4_PRTX(offset) \
14050 + CVMX_ADD_IO_SEG(0x00011800A0000820ull + (((offset) & 63) * 80))
14051 +#define CVMX_PIP_STAT5_PRTX(offset) \
14052 + CVMX_ADD_IO_SEG(0x00011800A0000828ull + (((offset) & 63) * 80))
14053 +#define CVMX_PIP_STAT6_PRTX(offset) \
14054 + CVMX_ADD_IO_SEG(0x00011800A0000830ull + (((offset) & 63) * 80))
14055 +#define CVMX_PIP_STAT7_PRTX(offset) \
14056 + CVMX_ADD_IO_SEG(0x00011800A0000838ull + (((offset) & 63) * 80))
14057 +#define CVMX_PIP_STAT8_PRTX(offset) \
14058 + CVMX_ADD_IO_SEG(0x00011800A0000840ull + (((offset) & 63) * 80))
14059 +#define CVMX_PIP_STAT9_PRTX(offset) \
14060 + CVMX_ADD_IO_SEG(0x00011800A0000848ull + (((offset) & 63) * 80))
14061 +#define CVMX_PIP_STAT_CTL \
14062 + CVMX_ADD_IO_SEG(0x00011800A0000018ull)
14063 +#define CVMX_PIP_STAT_INB_ERRSX(offset) \
14064 + CVMX_ADD_IO_SEG(0x00011800A0001A10ull + (((offset) & 63) * 32))
14065 +#define CVMX_PIP_STAT_INB_OCTSX(offset) \
14066 + CVMX_ADD_IO_SEG(0x00011800A0001A08ull + (((offset) & 63) * 32))
14067 +#define CVMX_PIP_STAT_INB_PKTSX(offset) \
14068 + CVMX_ADD_IO_SEG(0x00011800A0001A00ull + (((offset) & 63) * 32))
14069 +#define CVMX_PIP_TAG_INCX(offset) \
14070 + CVMX_ADD_IO_SEG(0x00011800A0001800ull + (((offset) & 63) * 8))
14071 +#define CVMX_PIP_TAG_MASK \
14072 + CVMX_ADD_IO_SEG(0x00011800A0000070ull)
14073 +#define CVMX_PIP_TAG_SECRET \
14074 + CVMX_ADD_IO_SEG(0x00011800A0000068ull)
14075 +#define CVMX_PIP_TODO_ENTRY \
14076 + CVMX_ADD_IO_SEG(0x00011800A0000078ull)
14077 +
14078 +union cvmx_pip_bck_prs {
14079 + uint64_t u64;
14080 + struct cvmx_pip_bck_prs_s {
14081 + uint64_t bckprs:1;
14082 + uint64_t reserved_13_62:50;
14083 + uint64_t hiwater:5;
14084 + uint64_t reserved_5_7:3;
14085 + uint64_t lowater:5;
14086 + } s;
14087 + struct cvmx_pip_bck_prs_s cn38xx;
14088 + struct cvmx_pip_bck_prs_s cn38xxp2;
14089 + struct cvmx_pip_bck_prs_s cn56xx;
14090 + struct cvmx_pip_bck_prs_s cn56xxp1;
14091 + struct cvmx_pip_bck_prs_s cn58xx;
14092 + struct cvmx_pip_bck_prs_s cn58xxp1;
14093 +};
14094 +
14095 +union cvmx_pip_bist_status {
14096 + uint64_t u64;
14097 + struct cvmx_pip_bist_status_s {
14098 + uint64_t reserved_18_63:46;
14099 + uint64_t bist:18;
14100 + } s;
14101 + struct cvmx_pip_bist_status_s cn30xx;
14102 + struct cvmx_pip_bist_status_s cn31xx;
14103 + struct cvmx_pip_bist_status_s cn38xx;
14104 + struct cvmx_pip_bist_status_s cn38xxp2;
14105 + struct cvmx_pip_bist_status_cn50xx {
14106 + uint64_t reserved_17_63:47;
14107 + uint64_t bist:17;
14108 + } cn50xx;
14109 + struct cvmx_pip_bist_status_s cn52xx;
14110 + struct cvmx_pip_bist_status_s cn52xxp1;
14111 + struct cvmx_pip_bist_status_s cn56xx;
14112 + struct cvmx_pip_bist_status_s cn56xxp1;
14113 + struct cvmx_pip_bist_status_s cn58xx;
14114 + struct cvmx_pip_bist_status_s cn58xxp1;
14115 +};
14116 +
14117 +union cvmx_pip_crc_ctlx {
14118 + uint64_t u64;
14119 + struct cvmx_pip_crc_ctlx_s {
14120 + uint64_t reserved_2_63:62;
14121 + uint64_t invres:1;
14122 + uint64_t reflect:1;
14123 + } s;
14124 + struct cvmx_pip_crc_ctlx_s cn38xx;
14125 + struct cvmx_pip_crc_ctlx_s cn38xxp2;
14126 + struct cvmx_pip_crc_ctlx_s cn58xx;
14127 + struct cvmx_pip_crc_ctlx_s cn58xxp1;
14128 +};
14129 +
14130 +union cvmx_pip_crc_ivx {
14131 + uint64_t u64;
14132 + struct cvmx_pip_crc_ivx_s {
14133 + uint64_t reserved_32_63:32;
14134 + uint64_t iv:32;
14135 + } s;
14136 + struct cvmx_pip_crc_ivx_s cn38xx;
14137 + struct cvmx_pip_crc_ivx_s cn38xxp2;
14138 + struct cvmx_pip_crc_ivx_s cn58xx;
14139 + struct cvmx_pip_crc_ivx_s cn58xxp1;
14140 +};
14141 +
14142 +union cvmx_pip_dec_ipsecx {
14143 + uint64_t u64;
14144 + struct cvmx_pip_dec_ipsecx_s {
14145 + uint64_t reserved_18_63:46;
14146 + uint64_t tcp:1;
14147 + uint64_t udp:1;
14148 + uint64_t dprt:16;
14149 + } s;
14150 + struct cvmx_pip_dec_ipsecx_s cn30xx;
14151 + struct cvmx_pip_dec_ipsecx_s cn31xx;
14152 + struct cvmx_pip_dec_ipsecx_s cn38xx;
14153 + struct cvmx_pip_dec_ipsecx_s cn38xxp2;
14154 + struct cvmx_pip_dec_ipsecx_s cn50xx;
14155 + struct cvmx_pip_dec_ipsecx_s cn52xx;
14156 + struct cvmx_pip_dec_ipsecx_s cn52xxp1;
14157 + struct cvmx_pip_dec_ipsecx_s cn56xx;
14158 + struct cvmx_pip_dec_ipsecx_s cn56xxp1;
14159 + struct cvmx_pip_dec_ipsecx_s cn58xx;
14160 + struct cvmx_pip_dec_ipsecx_s cn58xxp1;
14161 +};
14162 +
14163 +union cvmx_pip_dsa_src_grp {
14164 + uint64_t u64;
14165 + struct cvmx_pip_dsa_src_grp_s {
14166 + uint64_t map15:4;
14167 + uint64_t map14:4;
14168 + uint64_t map13:4;
14169 + uint64_t map12:4;
14170 + uint64_t map11:4;
14171 + uint64_t map10:4;
14172 + uint64_t map9:4;
14173 + uint64_t map8:4;
14174 + uint64_t map7:4;
14175 + uint64_t map6:4;
14176 + uint64_t map5:4;
14177 + uint64_t map4:4;
14178 + uint64_t map3:4;
14179 + uint64_t map2:4;
14180 + uint64_t map1:4;
14181 + uint64_t map0:4;
14182 + } s;
14183 + struct cvmx_pip_dsa_src_grp_s cn52xx;
14184 + struct cvmx_pip_dsa_src_grp_s cn52xxp1;
14185 + struct cvmx_pip_dsa_src_grp_s cn56xx;
14186 +};
14187 +
14188 +union cvmx_pip_dsa_vid_grp {
14189 + uint64_t u64;
14190 + struct cvmx_pip_dsa_vid_grp_s {
14191 + uint64_t map15:4;
14192 + uint64_t map14:4;
14193 + uint64_t map13:4;
14194 + uint64_t map12:4;
14195 + uint64_t map11:4;
14196 + uint64_t map10:4;
14197 + uint64_t map9:4;
14198 + uint64_t map8:4;
14199 + uint64_t map7:4;
14200 + uint64_t map6:4;
14201 + uint64_t map5:4;
14202 + uint64_t map4:4;
14203 + uint64_t map3:4;
14204 + uint64_t map2:4;
14205 + uint64_t map1:4;
14206 + uint64_t map0:4;
14207 + } s;
14208 + struct cvmx_pip_dsa_vid_grp_s cn52xx;
14209 + struct cvmx_pip_dsa_vid_grp_s cn52xxp1;
14210 + struct cvmx_pip_dsa_vid_grp_s cn56xx;
14211 +};
14212 +
14213 +union cvmx_pip_frm_len_chkx {
14214 + uint64_t u64;
14215 + struct cvmx_pip_frm_len_chkx_s {
14216 + uint64_t reserved_32_63:32;
14217 + uint64_t maxlen:16;
14218 + uint64_t minlen:16;
14219 + } s;
14220 + struct cvmx_pip_frm_len_chkx_s cn50xx;
14221 + struct cvmx_pip_frm_len_chkx_s cn52xx;
14222 + struct cvmx_pip_frm_len_chkx_s cn52xxp1;
14223 + struct cvmx_pip_frm_len_chkx_s cn56xx;
14224 + struct cvmx_pip_frm_len_chkx_s cn56xxp1;
14225 +};
14226 +
14227 +union cvmx_pip_gbl_cfg {
14228 + uint64_t u64;
14229 + struct cvmx_pip_gbl_cfg_s {
14230 + uint64_t reserved_19_63:45;
14231 + uint64_t tag_syn:1;
14232 + uint64_t ip6_udp:1;
14233 + uint64_t max_l2:1;
14234 + uint64_t reserved_11_15:5;
14235 + uint64_t raw_shf:3;
14236 + uint64_t reserved_3_7:5;
14237 + uint64_t nip_shf:3;
14238 + } s;
14239 + struct cvmx_pip_gbl_cfg_s cn30xx;
14240 + struct cvmx_pip_gbl_cfg_s cn31xx;
14241 + struct cvmx_pip_gbl_cfg_s cn38xx;
14242 + struct cvmx_pip_gbl_cfg_s cn38xxp2;
14243 + struct cvmx_pip_gbl_cfg_s cn50xx;
14244 + struct cvmx_pip_gbl_cfg_s cn52xx;
14245 + struct cvmx_pip_gbl_cfg_s cn52xxp1;
14246 + struct cvmx_pip_gbl_cfg_s cn56xx;
14247 + struct cvmx_pip_gbl_cfg_s cn56xxp1;
14248 + struct cvmx_pip_gbl_cfg_s cn58xx;
14249 + struct cvmx_pip_gbl_cfg_s cn58xxp1;
14250 +};
14251 +
14252 +union cvmx_pip_gbl_ctl {
14253 + uint64_t u64;
14254 + struct cvmx_pip_gbl_ctl_s {
14255 + uint64_t reserved_27_63:37;
14256 + uint64_t dsa_grp_tvid:1;
14257 + uint64_t dsa_grp_scmd:1;
14258 + uint64_t dsa_grp_sid:1;
14259 + uint64_t reserved_21_23:3;
14260 + uint64_t ring_en:1;
14261 + uint64_t reserved_17_19:3;
14262 + uint64_t ignrs:1;
14263 + uint64_t vs_wqe:1;
14264 + uint64_t vs_qos:1;
14265 + uint64_t l2_mal:1;
14266 + uint64_t tcp_flag:1;
14267 + uint64_t l4_len:1;
14268 + uint64_t l4_chk:1;
14269 + uint64_t l4_prt:1;
14270 + uint64_t l4_mal:1;
14271 + uint64_t reserved_6_7:2;
14272 + uint64_t ip6_eext:2;
14273 + uint64_t ip4_opts:1;
14274 + uint64_t ip_hop:1;
14275 + uint64_t ip_mal:1;
14276 + uint64_t ip_chk:1;
14277 + } s;
14278 + struct cvmx_pip_gbl_ctl_cn30xx {
14279 + uint64_t reserved_17_63:47;
14280 + uint64_t ignrs:1;
14281 + uint64_t vs_wqe:1;
14282 + uint64_t vs_qos:1;
14283 + uint64_t l2_mal:1;
14284 + uint64_t tcp_flag:1;
14285 + uint64_t l4_len:1;
14286 + uint64_t l4_chk:1;
14287 + uint64_t l4_prt:1;
14288 + uint64_t l4_mal:1;
14289 + uint64_t reserved_6_7:2;
14290 + uint64_t ip6_eext:2;
14291 + uint64_t ip4_opts:1;
14292 + uint64_t ip_hop:1;
14293 + uint64_t ip_mal:1;
14294 + uint64_t ip_chk:1;
14295 + } cn30xx;
14296 + struct cvmx_pip_gbl_ctl_cn30xx cn31xx;
14297 + struct cvmx_pip_gbl_ctl_cn30xx cn38xx;
14298 + struct cvmx_pip_gbl_ctl_cn30xx cn38xxp2;
14299 + struct cvmx_pip_gbl_ctl_cn30xx cn50xx;
14300 + struct cvmx_pip_gbl_ctl_s cn52xx;
14301 + struct cvmx_pip_gbl_ctl_s cn52xxp1;
14302 + struct cvmx_pip_gbl_ctl_s cn56xx;
14303 + struct cvmx_pip_gbl_ctl_cn56xxp1 {
14304 + uint64_t reserved_21_63:43;
14305 + uint64_t ring_en:1;
14306 + uint64_t reserved_17_19:3;
14307 + uint64_t ignrs:1;
14308 + uint64_t vs_wqe:1;
14309 + uint64_t vs_qos:1;
14310 + uint64_t l2_mal:1;
14311 + uint64_t tcp_flag:1;
14312 + uint64_t l4_len:1;
14313 + uint64_t l4_chk:1;
14314 + uint64_t l4_prt:1;
14315 + uint64_t l4_mal:1;
14316 + uint64_t reserved_6_7:2;
14317 + uint64_t ip6_eext:2;
14318 + uint64_t ip4_opts:1;
14319 + uint64_t ip_hop:1;
14320 + uint64_t ip_mal:1;
14321 + uint64_t ip_chk:1;
14322 + } cn56xxp1;
14323 + struct cvmx_pip_gbl_ctl_cn30xx cn58xx;
14324 + struct cvmx_pip_gbl_ctl_cn30xx cn58xxp1;
14325 +};
14326 +
14327 +union cvmx_pip_hg_pri_qos {
14328 + uint64_t u64;
14329 + struct cvmx_pip_hg_pri_qos_s {
14330 + uint64_t reserved_11_63:53;
14331 + uint64_t qos:3;
14332 + uint64_t reserved_6_7:2;
14333 + uint64_t pri:6;
14334 + } s;
14335 + struct cvmx_pip_hg_pri_qos_s cn52xx;
14336 + struct cvmx_pip_hg_pri_qos_s cn52xxp1;
14337 + struct cvmx_pip_hg_pri_qos_s cn56xx;
14338 +};
14339 +
14340 +union cvmx_pip_int_en {
14341 + uint64_t u64;
14342 + struct cvmx_pip_int_en_s {
14343 + uint64_t reserved_13_63:51;
14344 + uint64_t punyerr:1;
14345 + uint64_t lenerr:1;
14346 + uint64_t maxerr:1;
14347 + uint64_t minerr:1;
14348 + uint64_t beperr:1;
14349 + uint64_t feperr:1;
14350 + uint64_t todoovr:1;
14351 + uint64_t skprunt:1;
14352 + uint64_t badtag:1;
14353 + uint64_t prtnxa:1;
14354 + uint64_t bckprs:1;
14355 + uint64_t crcerr:1;
14356 + uint64_t pktdrp:1;
14357 + } s;
14358 + struct cvmx_pip_int_en_cn30xx {
14359 + uint64_t reserved_9_63:55;
14360 + uint64_t beperr:1;
14361 + uint64_t feperr:1;
14362 + uint64_t todoovr:1;
14363 + uint64_t skprunt:1;
14364 + uint64_t badtag:1;
14365 + uint64_t prtnxa:1;
14366 + uint64_t bckprs:1;
14367 + uint64_t crcerr:1;
14368 + uint64_t pktdrp:1;
14369 + } cn30xx;
14370 + struct cvmx_pip_int_en_cn30xx cn31xx;
14371 + struct cvmx_pip_int_en_cn30xx cn38xx;
14372 + struct cvmx_pip_int_en_cn30xx cn38xxp2;
14373 + struct cvmx_pip_int_en_cn50xx {
14374 + uint64_t reserved_12_63:52;
14375 + uint64_t lenerr:1;
14376 + uint64_t maxerr:1;
14377 + uint64_t minerr:1;
14378 + uint64_t beperr:1;
14379 + uint64_t feperr:1;
14380 + uint64_t todoovr:1;
14381 + uint64_t skprunt:1;
14382 + uint64_t badtag:1;
14383 + uint64_t prtnxa:1;
14384 + uint64_t bckprs:1;
14385 + uint64_t reserved_1_1:1;
14386 + uint64_t pktdrp:1;
14387 + } cn50xx;
14388 + struct cvmx_pip_int_en_cn52xx {
14389 + uint64_t reserved_13_63:51;
14390 + uint64_t punyerr:1;
14391 + uint64_t lenerr:1;
14392 + uint64_t maxerr:1;
14393 + uint64_t minerr:1;
14394 + uint64_t beperr:1;
14395 + uint64_t feperr:1;
14396 + uint64_t todoovr:1;
14397 + uint64_t skprunt:1;
14398 + uint64_t badtag:1;
14399 + uint64_t prtnxa:1;
14400 + uint64_t bckprs:1;
14401 + uint64_t reserved_1_1:1;
14402 + uint64_t pktdrp:1;
14403 + } cn52xx;
14404 + struct cvmx_pip_int_en_cn52xx cn52xxp1;
14405 + struct cvmx_pip_int_en_s cn56xx;
14406 + struct cvmx_pip_int_en_cn56xxp1 {
14407 + uint64_t reserved_12_63:52;
14408 + uint64_t lenerr:1;
14409 + uint64_t maxerr:1;
14410 + uint64_t minerr:1;
14411 + uint64_t beperr:1;
14412 + uint64_t feperr:1;
14413 + uint64_t todoovr:1;
14414 + uint64_t skprunt:1;
14415 + uint64_t badtag:1;
14416 + uint64_t prtnxa:1;
14417 + uint64_t bckprs:1;
14418 + uint64_t crcerr:1;
14419 + uint64_t pktdrp:1;
14420 + } cn56xxp1;
14421 + struct cvmx_pip_int_en_cn58xx {
14422 + uint64_t reserved_13_63:51;
14423 + uint64_t punyerr:1;
14424 + uint64_t reserved_9_11:3;
14425 + uint64_t beperr:1;
14426 + uint64_t feperr:1;
14427 + uint64_t todoovr:1;
14428 + uint64_t skprunt:1;
14429 + uint64_t badtag:1;
14430 + uint64_t prtnxa:1;
14431 + uint64_t bckprs:1;
14432 + uint64_t crcerr:1;
14433 + uint64_t pktdrp:1;
14434 + } cn58xx;
14435 + struct cvmx_pip_int_en_cn30xx cn58xxp1;
14436 +};
14437 +
14438 +union cvmx_pip_int_reg {
14439 + uint64_t u64;
14440 + struct cvmx_pip_int_reg_s {
14441 + uint64_t reserved_13_63:51;
14442 + uint64_t punyerr:1;
14443 + uint64_t lenerr:1;
14444 + uint64_t maxerr:1;
14445 + uint64_t minerr:1;
14446 + uint64_t beperr:1;
14447 + uint64_t feperr:1;
14448 + uint64_t todoovr:1;
14449 + uint64_t skprunt:1;
14450 + uint64_t badtag:1;
14451 + uint64_t prtnxa:1;
14452 + uint64_t bckprs:1;
14453 + uint64_t crcerr:1;
14454 + uint64_t pktdrp:1;
14455 + } s;
14456 + struct cvmx_pip_int_reg_cn30xx {
14457 + uint64_t reserved_9_63:55;
14458 + uint64_t beperr:1;
14459 + uint64_t feperr:1;
14460 + uint64_t todoovr:1;
14461 + uint64_t skprunt:1;
14462 + uint64_t badtag:1;
14463 + uint64_t prtnxa:1;
14464 + uint64_t bckprs:1;
14465 + uint64_t crcerr:1;
14466 + uint64_t pktdrp:1;
14467 + } cn30xx;
14468 + struct cvmx_pip_int_reg_cn30xx cn31xx;
14469 + struct cvmx_pip_int_reg_cn30xx cn38xx;
14470 + struct cvmx_pip_int_reg_cn30xx cn38xxp2;
14471 + struct cvmx_pip_int_reg_cn50xx {
14472 + uint64_t reserved_12_63:52;
14473 + uint64_t lenerr:1;
14474 + uint64_t maxerr:1;
14475 + uint64_t minerr:1;
14476 + uint64_t beperr:1;
14477 + uint64_t feperr:1;
14478 + uint64_t todoovr:1;
14479 + uint64_t skprunt:1;
14480 + uint64_t badtag:1;
14481 + uint64_t prtnxa:1;
14482 + uint64_t bckprs:1;
14483 + uint64_t reserved_1_1:1;
14484 + uint64_t pktdrp:1;
14485 + } cn50xx;
14486 + struct cvmx_pip_int_reg_cn52xx {
14487 + uint64_t reserved_13_63:51;
14488 + uint64_t punyerr:1;
14489 + uint64_t lenerr:1;
14490 + uint64_t maxerr:1;
14491 + uint64_t minerr:1;
14492 + uint64_t beperr:1;
14493 + uint64_t feperr:1;
14494 + uint64_t todoovr:1;
14495 + uint64_t skprunt:1;
14496 + uint64_t badtag:1;
14497 + uint64_t prtnxa:1;
14498 + uint64_t bckprs:1;
14499 + uint64_t reserved_1_1:1;
14500 + uint64_t pktdrp:1;
14501 + } cn52xx;
14502 + struct cvmx_pip_int_reg_cn52xx cn52xxp1;
14503 + struct cvmx_pip_int_reg_s cn56xx;
14504 + struct cvmx_pip_int_reg_cn56xxp1 {
14505 + uint64_t reserved_12_63:52;
14506 + uint64_t lenerr:1;
14507 + uint64_t maxerr:1;
14508 + uint64_t minerr:1;
14509 + uint64_t beperr:1;
14510 + uint64_t feperr:1;
14511 + uint64_t todoovr:1;
14512 + uint64_t skprunt:1;
14513 + uint64_t badtag:1;
14514 + uint64_t prtnxa:1;
14515 + uint64_t bckprs:1;
14516 + uint64_t crcerr:1;
14517 + uint64_t pktdrp:1;
14518 + } cn56xxp1;
14519 + struct cvmx_pip_int_reg_cn58xx {
14520 + uint64_t reserved_13_63:51;
14521 + uint64_t punyerr:1;
14522 + uint64_t reserved_9_11:3;
14523 + uint64_t beperr:1;
14524 + uint64_t feperr:1;
14525 + uint64_t todoovr:1;
14526 + uint64_t skprunt:1;
14527 + uint64_t badtag:1;
14528 + uint64_t prtnxa:1;
14529 + uint64_t bckprs:1;
14530 + uint64_t crcerr:1;
14531 + uint64_t pktdrp:1;
14532 + } cn58xx;
14533 + struct cvmx_pip_int_reg_cn30xx cn58xxp1;
14534 +};
14535 +
14536 +union cvmx_pip_ip_offset {
14537 + uint64_t u64;
14538 + struct cvmx_pip_ip_offset_s {
14539 + uint64_t reserved_3_63:61;
14540 + uint64_t offset:3;
14541 + } s;
14542 + struct cvmx_pip_ip_offset_s cn30xx;
14543 + struct cvmx_pip_ip_offset_s cn31xx;
14544 + struct cvmx_pip_ip_offset_s cn38xx;
14545 + struct cvmx_pip_ip_offset_s cn38xxp2;
14546 + struct cvmx_pip_ip_offset_s cn50xx;
14547 + struct cvmx_pip_ip_offset_s cn52xx;
14548 + struct cvmx_pip_ip_offset_s cn52xxp1;
14549 + struct cvmx_pip_ip_offset_s cn56xx;
14550 + struct cvmx_pip_ip_offset_s cn56xxp1;
14551 + struct cvmx_pip_ip_offset_s cn58xx;
14552 + struct cvmx_pip_ip_offset_s cn58xxp1;
14553 +};
14554 +
14555 +union cvmx_pip_prt_cfgx {
14556 + uint64_t u64;
14557 + struct cvmx_pip_prt_cfgx_s {
14558 + uint64_t reserved_53_63:11;
14559 + uint64_t pad_len:1;
14560 + uint64_t vlan_len:1;
14561 + uint64_t lenerr_en:1;
14562 + uint64_t maxerr_en:1;
14563 + uint64_t minerr_en:1;
14564 + uint64_t grp_wat_47:4;
14565 + uint64_t qos_wat_47:4;
14566 + uint64_t reserved_37_39:3;
14567 + uint64_t rawdrp:1;
14568 + uint64_t tag_inc:2;
14569 + uint64_t dyn_rs:1;
14570 + uint64_t inst_hdr:1;
14571 + uint64_t grp_wat:4;
14572 + uint64_t hg_qos:1;
14573 + uint64_t qos:3;
14574 + uint64_t qos_wat:4;
14575 + uint64_t qos_vsel:1;
14576 + uint64_t qos_vod:1;
14577 + uint64_t qos_diff:1;
14578 + uint64_t qos_vlan:1;
14579 + uint64_t reserved_13_15:3;
14580 + uint64_t crc_en:1;
14581 + uint64_t higig_en:1;
14582 + uint64_t dsa_en:1;
14583 + uint64_t mode:2;
14584 + uint64_t reserved_7_7:1;
14585 + uint64_t skip:7;
14586 + } s;
14587 + struct cvmx_pip_prt_cfgx_cn30xx {
14588 + uint64_t reserved_37_63:27;
14589 + uint64_t rawdrp:1;
14590 + uint64_t tag_inc:2;
14591 + uint64_t dyn_rs:1;
14592 + uint64_t inst_hdr:1;
14593 + uint64_t grp_wat:4;
14594 + uint64_t reserved_27_27:1;
14595 + uint64_t qos:3;
14596 + uint64_t qos_wat:4;
14597 + uint64_t reserved_18_19:2;
14598 + uint64_t qos_diff:1;
14599 + uint64_t qos_vlan:1;
14600 + uint64_t reserved_10_15:6;
14601 + uint64_t mode:2;
14602 + uint64_t reserved_7_7:1;
14603 + uint64_t skip:7;
14604 + } cn30xx;
14605 + struct cvmx_pip_prt_cfgx_cn30xx cn31xx;
14606 + struct cvmx_pip_prt_cfgx_cn38xx {
14607 + uint64_t reserved_37_63:27;
14608 + uint64_t rawdrp:1;
14609 + uint64_t tag_inc:2;
14610 + uint64_t dyn_rs:1;
14611 + uint64_t inst_hdr:1;
14612 + uint64_t grp_wat:4;
14613 + uint64_t reserved_27_27:1;
14614 + uint64_t qos:3;
14615 + uint64_t qos_wat:4;
14616 + uint64_t reserved_18_19:2;
14617 + uint64_t qos_diff:1;
14618 + uint64_t qos_vlan:1;
14619 + uint64_t reserved_13_15:3;
14620 + uint64_t crc_en:1;
14621 + uint64_t reserved_10_11:2;
14622 + uint64_t mode:2;
14623 + uint64_t reserved_7_7:1;
14624 + uint64_t skip:7;
14625 + } cn38xx;
14626 + struct cvmx_pip_prt_cfgx_cn38xx cn38xxp2;
14627 + struct cvmx_pip_prt_cfgx_cn50xx {
14628 + uint64_t reserved_53_63:11;
14629 + uint64_t pad_len:1;
14630 + uint64_t vlan_len:1;
14631 + uint64_t lenerr_en:1;
14632 + uint64_t maxerr_en:1;
14633 + uint64_t minerr_en:1;
14634 + uint64_t grp_wat_47:4;
14635 + uint64_t qos_wat_47:4;
14636 + uint64_t reserved_37_39:3;
14637 + uint64_t rawdrp:1;
14638 + uint64_t tag_inc:2;
14639 + uint64_t dyn_rs:1;
14640 + uint64_t inst_hdr:1;
14641 + uint64_t grp_wat:4;
14642 + uint64_t reserved_27_27:1;
14643 + uint64_t qos:3;
14644 + uint64_t qos_wat:4;
14645 + uint64_t reserved_19_19:1;
14646 + uint64_t qos_vod:1;
14647 + uint64_t qos_diff:1;
14648 + uint64_t qos_vlan:1;
14649 + uint64_t reserved_13_15:3;
14650 + uint64_t crc_en:1;
14651 + uint64_t reserved_10_11:2;
14652 + uint64_t mode:2;
14653 + uint64_t reserved_7_7:1;
14654 + uint64_t skip:7;
14655 + } cn50xx;
14656 + struct cvmx_pip_prt_cfgx_s cn52xx;
14657 + struct cvmx_pip_prt_cfgx_s cn52xxp1;
14658 + struct cvmx_pip_prt_cfgx_s cn56xx;
14659 + struct cvmx_pip_prt_cfgx_cn50xx cn56xxp1;
14660 + struct cvmx_pip_prt_cfgx_cn58xx {
14661 + uint64_t reserved_37_63:27;
14662 + uint64_t rawdrp:1;
14663 + uint64_t tag_inc:2;
14664 + uint64_t dyn_rs:1;
14665 + uint64_t inst_hdr:1;
14666 + uint64_t grp_wat:4;
14667 + uint64_t reserved_27_27:1;
14668 + uint64_t qos:3;
14669 + uint64_t qos_wat:4;
14670 + uint64_t reserved_19_19:1;
14671 + uint64_t qos_vod:1;
14672 + uint64_t qos_diff:1;
14673 + uint64_t qos_vlan:1;
14674 + uint64_t reserved_13_15:3;
14675 + uint64_t crc_en:1;
14676 + uint64_t reserved_10_11:2;
14677 + uint64_t mode:2;
14678 + uint64_t reserved_7_7:1;
14679 + uint64_t skip:7;
14680 + } cn58xx;
14681 + struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1;
14682 +};
14683 +
14684 +union cvmx_pip_prt_tagx {
14685 + uint64_t u64;
14686 + struct cvmx_pip_prt_tagx_s {
14687 + uint64_t reserved_40_63:24;
14688 + uint64_t grptagbase:4;
14689 + uint64_t grptagmask:4;
14690 + uint64_t grptag:1;
14691 + uint64_t grptag_mskip:1;
14692 + uint64_t tag_mode:2;
14693 + uint64_t inc_vs:2;
14694 + uint64_t inc_vlan:1;
14695 + uint64_t inc_prt_flag:1;
14696 + uint64_t ip6_dprt_flag:1;
14697 + uint64_t ip4_dprt_flag:1;
14698 + uint64_t ip6_sprt_flag:1;
14699 + uint64_t ip4_sprt_flag:1;
14700 + uint64_t ip6_nxth_flag:1;
14701 + uint64_t ip4_pctl_flag:1;
14702 + uint64_t ip6_dst_flag:1;
14703 + uint64_t ip4_dst_flag:1;
14704 + uint64_t ip6_src_flag:1;
14705 + uint64_t ip4_src_flag:1;
14706 + uint64_t tcp6_tag_type:2;
14707 + uint64_t tcp4_tag_type:2;
14708 + uint64_t ip6_tag_type:2;
14709 + uint64_t ip4_tag_type:2;
14710 + uint64_t non_tag_type:2;
14711 + uint64_t grp:4;
14712 + } s;
14713 + struct cvmx_pip_prt_tagx_cn30xx {
14714 + uint64_t reserved_40_63:24;
14715 + uint64_t grptagbase:4;
14716 + uint64_t grptagmask:4;
14717 + uint64_t grptag:1;
14718 + uint64_t reserved_30_30:1;
14719 + uint64_t tag_mode:2;
14720 + uint64_t inc_vs:2;
14721 + uint64_t inc_vlan:1;
14722 + uint64_t inc_prt_flag:1;
14723 + uint64_t ip6_dprt_flag:1;
14724 + uint64_t ip4_dprt_flag:1;
14725 + uint64_t ip6_sprt_flag:1;
14726 + uint64_t ip4_sprt_flag:1;
14727 + uint64_t ip6_nxth_flag:1;
14728 + uint64_t ip4_pctl_flag:1;
14729 + uint64_t ip6_dst_flag:1;
14730 + uint64_t ip4_dst_flag:1;
14731 + uint64_t ip6_src_flag:1;
14732 + uint64_t ip4_src_flag:1;
14733 + uint64_t tcp6_tag_type:2;
14734 + uint64_t tcp4_tag_type:2;
14735 + uint64_t ip6_tag_type:2;
14736 + uint64_t ip4_tag_type:2;
14737 + uint64_t non_tag_type:2;
14738 + uint64_t grp:4;
14739 + } cn30xx;
14740 + struct cvmx_pip_prt_tagx_cn30xx cn31xx;
14741 + struct cvmx_pip_prt_tagx_cn30xx cn38xx;
14742 + struct cvmx_pip_prt_tagx_cn30xx cn38xxp2;
14743 + struct cvmx_pip_prt_tagx_s cn50xx;
14744 + struct cvmx_pip_prt_tagx_s cn52xx;
14745 + struct cvmx_pip_prt_tagx_s cn52xxp1;
14746 + struct cvmx_pip_prt_tagx_s cn56xx;
14747 + struct cvmx_pip_prt_tagx_s cn56xxp1;
14748 + struct cvmx_pip_prt_tagx_cn30xx cn58xx;
14749 + struct cvmx_pip_prt_tagx_cn30xx cn58xxp1;
14750 +};
14751 +
14752 +union cvmx_pip_qos_diffx {
14753 + uint64_t u64;
14754 + struct cvmx_pip_qos_diffx_s {
14755 + uint64_t reserved_3_63:61;
14756 + uint64_t qos:3;
14757 + } s;
14758 + struct cvmx_pip_qos_diffx_s cn30xx;
14759 + struct cvmx_pip_qos_diffx_s cn31xx;
14760 + struct cvmx_pip_qos_diffx_s cn38xx;
14761 + struct cvmx_pip_qos_diffx_s cn38xxp2;
14762 + struct cvmx_pip_qos_diffx_s cn50xx;
14763 + struct cvmx_pip_qos_diffx_s cn52xx;
14764 + struct cvmx_pip_qos_diffx_s cn52xxp1;
14765 + struct cvmx_pip_qos_diffx_s cn56xx;
14766 + struct cvmx_pip_qos_diffx_s cn56xxp1;
14767 + struct cvmx_pip_qos_diffx_s cn58xx;
14768 + struct cvmx_pip_qos_diffx_s cn58xxp1;
14769 +};
14770 +
14771 +union cvmx_pip_qos_vlanx {
14772 + uint64_t u64;
14773 + struct cvmx_pip_qos_vlanx_s {
14774 + uint64_t reserved_7_63:57;
14775 + uint64_t qos1:3;
14776 + uint64_t reserved_3_3:1;
14777 + uint64_t qos:3;
14778 + } s;
14779 + struct cvmx_pip_qos_vlanx_cn30xx {
14780 + uint64_t reserved_3_63:61;
14781 + uint64_t qos:3;
14782 + } cn30xx;
14783 + struct cvmx_pip_qos_vlanx_cn30xx cn31xx;
14784 + struct cvmx_pip_qos_vlanx_cn30xx cn38xx;
14785 + struct cvmx_pip_qos_vlanx_cn30xx cn38xxp2;
14786 + struct cvmx_pip_qos_vlanx_cn30xx cn50xx;
14787 + struct cvmx_pip_qos_vlanx_s cn52xx;
14788 + struct cvmx_pip_qos_vlanx_s cn52xxp1;
14789 + struct cvmx_pip_qos_vlanx_s cn56xx;
14790 + struct cvmx_pip_qos_vlanx_cn30xx cn56xxp1;
14791 + struct cvmx_pip_qos_vlanx_cn30xx cn58xx;
14792 + struct cvmx_pip_qos_vlanx_cn30xx cn58xxp1;
14793 +};
14794 +
14795 +union cvmx_pip_qos_watchx {
14796 + uint64_t u64;
14797 + struct cvmx_pip_qos_watchx_s {
14798 + uint64_t reserved_48_63:16;
14799 + uint64_t mask:16;
14800 + uint64_t reserved_28_31:4;
14801 + uint64_t grp:4;
14802 + uint64_t reserved_23_23:1;
14803 + uint64_t qos:3;
14804 + uint64_t reserved_19_19:1;
14805 + uint64_t match_type:3;
14806 + uint64_t match_value:16;
14807 + } s;
14808 + struct cvmx_pip_qos_watchx_cn30xx {
14809 + uint64_t reserved_48_63:16;
14810 + uint64_t mask:16;
14811 + uint64_t reserved_28_31:4;
14812 + uint64_t grp:4;
14813 + uint64_t reserved_23_23:1;
14814 + uint64_t qos:3;
14815 + uint64_t reserved_18_19:2;
14816 + uint64_t match_type:2;
14817 + uint64_t match_value:16;
14818 + } cn30xx;
14819 + struct cvmx_pip_qos_watchx_cn30xx cn31xx;
14820 + struct cvmx_pip_qos_watchx_cn30xx cn38xx;
14821 + struct cvmx_pip_qos_watchx_cn30xx cn38xxp2;
14822 + struct cvmx_pip_qos_watchx_s cn50xx;
14823 + struct cvmx_pip_qos_watchx_s cn52xx;
14824 + struct cvmx_pip_qos_watchx_s cn52xxp1;
14825 + struct cvmx_pip_qos_watchx_s cn56xx;
14826 + struct cvmx_pip_qos_watchx_s cn56xxp1;
14827 + struct cvmx_pip_qos_watchx_cn30xx cn58xx;
14828 + struct cvmx_pip_qos_watchx_cn30xx cn58xxp1;
14829 +};
14830 +
14831 +union cvmx_pip_raw_word {
14832 + uint64_t u64;
14833 + struct cvmx_pip_raw_word_s {
14834 + uint64_t reserved_56_63:8;
14835 + uint64_t word:56;
14836 + } s;
14837 + struct cvmx_pip_raw_word_s cn30xx;
14838 + struct cvmx_pip_raw_word_s cn31xx;
14839 + struct cvmx_pip_raw_word_s cn38xx;
14840 + struct cvmx_pip_raw_word_s cn38xxp2;
14841 + struct cvmx_pip_raw_word_s cn50xx;
14842 + struct cvmx_pip_raw_word_s cn52xx;
14843 + struct cvmx_pip_raw_word_s cn52xxp1;
14844 + struct cvmx_pip_raw_word_s cn56xx;
14845 + struct cvmx_pip_raw_word_s cn56xxp1;
14846 + struct cvmx_pip_raw_word_s cn58xx;
14847 + struct cvmx_pip_raw_word_s cn58xxp1;
14848 +};
14849 +
14850 +union cvmx_pip_sft_rst {
14851 + uint64_t u64;
14852 + struct cvmx_pip_sft_rst_s {
14853 + uint64_t reserved_1_63:63;
14854 + uint64_t rst:1;
14855 + } s;
14856 + struct cvmx_pip_sft_rst_s cn30xx;
14857 + struct cvmx_pip_sft_rst_s cn31xx;
14858 + struct cvmx_pip_sft_rst_s cn38xx;
14859 + struct cvmx_pip_sft_rst_s cn50xx;
14860 + struct cvmx_pip_sft_rst_s cn52xx;
14861 + struct cvmx_pip_sft_rst_s cn52xxp1;
14862 + struct cvmx_pip_sft_rst_s cn56xx;
14863 + struct cvmx_pip_sft_rst_s cn56xxp1;
14864 + struct cvmx_pip_sft_rst_s cn58xx;
14865 + struct cvmx_pip_sft_rst_s cn58xxp1;
14866 +};
14867 +
14868 +union cvmx_pip_stat0_prtx {
14869 + uint64_t u64;
14870 + struct cvmx_pip_stat0_prtx_s {
14871 + uint64_t drp_pkts:32;
14872 + uint64_t drp_octs:32;
14873 + } s;
14874 + struct cvmx_pip_stat0_prtx_s cn30xx;
14875 + struct cvmx_pip_stat0_prtx_s cn31xx;
14876 + struct cvmx_pip_stat0_prtx_s cn38xx;
14877 + struct cvmx_pip_stat0_prtx_s cn38xxp2;
14878 + struct cvmx_pip_stat0_prtx_s cn50xx;
14879 + struct cvmx_pip_stat0_prtx_s cn52xx;
14880 + struct cvmx_pip_stat0_prtx_s cn52xxp1;
14881 + struct cvmx_pip_stat0_prtx_s cn56xx;
14882 + struct cvmx_pip_stat0_prtx_s cn56xxp1;
14883 + struct cvmx_pip_stat0_prtx_s cn58xx;
14884 + struct cvmx_pip_stat0_prtx_s cn58xxp1;
14885 +};
14886 +
14887 +union cvmx_pip_stat1_prtx {
14888 + uint64_t u64;
14889 + struct cvmx_pip_stat1_prtx_s {
14890 + uint64_t reserved_48_63:16;
14891 + uint64_t octs:48;
14892 + } s;
14893 + struct cvmx_pip_stat1_prtx_s cn30xx;
14894 + struct cvmx_pip_stat1_prtx_s cn31xx;
14895 + struct cvmx_pip_stat1_prtx_s cn38xx;
14896 + struct cvmx_pip_stat1_prtx_s cn38xxp2;
14897 + struct cvmx_pip_stat1_prtx_s cn50xx;
14898 + struct cvmx_pip_stat1_prtx_s cn52xx;
14899 + struct cvmx_pip_stat1_prtx_s cn52xxp1;
14900 + struct cvmx_pip_stat1_prtx_s cn56xx;
14901 + struct cvmx_pip_stat1_prtx_s cn56xxp1;
14902 + struct cvmx_pip_stat1_prtx_s cn58xx;
14903 + struct cvmx_pip_stat1_prtx_s cn58xxp1;
14904 +};
14905 +
14906 +union cvmx_pip_stat2_prtx {
14907 + uint64_t u64;
14908 + struct cvmx_pip_stat2_prtx_s {
14909 + uint64_t pkts:32;
14910 + uint64_t raw:32;
14911 + } s;
14912 + struct cvmx_pip_stat2_prtx_s cn30xx;
14913 + struct cvmx_pip_stat2_prtx_s cn31xx;
14914 + struct cvmx_pip_stat2_prtx_s cn38xx;
14915 + struct cvmx_pip_stat2_prtx_s cn38xxp2;
14916 + struct cvmx_pip_stat2_prtx_s cn50xx;
14917 + struct cvmx_pip_stat2_prtx_s cn52xx;
14918 + struct cvmx_pip_stat2_prtx_s cn52xxp1;
14919 + struct cvmx_pip_stat2_prtx_s cn56xx;
14920 + struct cvmx_pip_stat2_prtx_s cn56xxp1;
14921 + struct cvmx_pip_stat2_prtx_s cn58xx;
14922 + struct cvmx_pip_stat2_prtx_s cn58xxp1;
14923 +};
14924 +
14925 +union cvmx_pip_stat3_prtx {
14926 + uint64_t u64;
14927 + struct cvmx_pip_stat3_prtx_s {
14928 + uint64_t bcst:32;
14929 + uint64_t mcst:32;
14930 + } s;
14931 + struct cvmx_pip_stat3_prtx_s cn30xx;
14932 + struct cvmx_pip_stat3_prtx_s cn31xx;
14933 + struct cvmx_pip_stat3_prtx_s cn38xx;
14934 + struct cvmx_pip_stat3_prtx_s cn38xxp2;
14935 + struct cvmx_pip_stat3_prtx_s cn50xx;
14936 + struct cvmx_pip_stat3_prtx_s cn52xx;
14937 + struct cvmx_pip_stat3_prtx_s cn52xxp1;
14938 + struct cvmx_pip_stat3_prtx_s cn56xx;
14939 + struct cvmx_pip_stat3_prtx_s cn56xxp1;
14940 + struct cvmx_pip_stat3_prtx_s cn58xx;
14941 + struct cvmx_pip_stat3_prtx_s cn58xxp1;
14942 +};
14943 +
14944 +union cvmx_pip_stat4_prtx {
14945 + uint64_t u64;
14946 + struct cvmx_pip_stat4_prtx_s {
14947 + uint64_t h65to127:32;
14948 + uint64_t h64:32;
14949 + } s;
14950 + struct cvmx_pip_stat4_prtx_s cn30xx;
14951 + struct cvmx_pip_stat4_prtx_s cn31xx;
14952 + struct cvmx_pip_stat4_prtx_s cn38xx;
14953 + struct cvmx_pip_stat4_prtx_s cn38xxp2;
14954 + struct cvmx_pip_stat4_prtx_s cn50xx;
14955 + struct cvmx_pip_stat4_prtx_s cn52xx;
14956 + struct cvmx_pip_stat4_prtx_s cn52xxp1;
14957 + struct cvmx_pip_stat4_prtx_s cn56xx;
14958 + struct cvmx_pip_stat4_prtx_s cn56xxp1;
14959 + struct cvmx_pip_stat4_prtx_s cn58xx;
14960 + struct cvmx_pip_stat4_prtx_s cn58xxp1;
14961 +};
14962 +
14963 +union cvmx_pip_stat5_prtx {
14964 + uint64_t u64;
14965 + struct cvmx_pip_stat5_prtx_s {
14966 + uint64_t h256to511:32;
14967 + uint64_t h128to255:32;
14968 + } s;
14969 + struct cvmx_pip_stat5_prtx_s cn30xx;
14970 + struct cvmx_pip_stat5_prtx_s cn31xx;
14971 + struct cvmx_pip_stat5_prtx_s cn38xx;
14972 + struct cvmx_pip_stat5_prtx_s cn38xxp2;
14973 + struct cvmx_pip_stat5_prtx_s cn50xx;
14974 + struct cvmx_pip_stat5_prtx_s cn52xx;
14975 + struct cvmx_pip_stat5_prtx_s cn52xxp1;
14976 + struct cvmx_pip_stat5_prtx_s cn56xx;
14977 + struct cvmx_pip_stat5_prtx_s cn56xxp1;
14978 + struct cvmx_pip_stat5_prtx_s cn58xx;
14979 + struct cvmx_pip_stat5_prtx_s cn58xxp1;
14980 +};
14981 +
14982 +union cvmx_pip_stat6_prtx {
14983 + uint64_t u64;
14984 + struct cvmx_pip_stat6_prtx_s {
14985 + uint64_t h1024to1518:32;
14986 + uint64_t h512to1023:32;
14987 + } s;
14988 + struct cvmx_pip_stat6_prtx_s cn30xx;
14989 + struct cvmx_pip_stat6_prtx_s cn31xx;
14990 + struct cvmx_pip_stat6_prtx_s cn38xx;
14991 + struct cvmx_pip_stat6_prtx_s cn38xxp2;
14992 + struct cvmx_pip_stat6_prtx_s cn50xx;
14993 + struct cvmx_pip_stat6_prtx_s cn52xx;
14994 + struct cvmx_pip_stat6_prtx_s cn52xxp1;
14995 + struct cvmx_pip_stat6_prtx_s cn56xx;
14996 + struct cvmx_pip_stat6_prtx_s cn56xxp1;
14997 + struct cvmx_pip_stat6_prtx_s cn58xx;
14998 + struct cvmx_pip_stat6_prtx_s cn58xxp1;
14999 +};
15000 +
15001 +union cvmx_pip_stat7_prtx {
15002 + uint64_t u64;
15003 + struct cvmx_pip_stat7_prtx_s {
15004 + uint64_t fcs:32;
15005 + uint64_t h1519:32;
15006 + } s;
15007 + struct cvmx_pip_stat7_prtx_s cn30xx;
15008 + struct cvmx_pip_stat7_prtx_s cn31xx;
15009 + struct cvmx_pip_stat7_prtx_s cn38xx;
15010 + struct cvmx_pip_stat7_prtx_s cn38xxp2;
15011 + struct cvmx_pip_stat7_prtx_s cn50xx;
15012 + struct cvmx_pip_stat7_prtx_s cn52xx;
15013 + struct cvmx_pip_stat7_prtx_s cn52xxp1;
15014 + struct cvmx_pip_stat7_prtx_s cn56xx;
15015 + struct cvmx_pip_stat7_prtx_s cn56xxp1;
15016 + struct cvmx_pip_stat7_prtx_s cn58xx;
15017 + struct cvmx_pip_stat7_prtx_s cn58xxp1;
15018 +};
15019 +
15020 +union cvmx_pip_stat8_prtx {
15021 + uint64_t u64;
15022 + struct cvmx_pip_stat8_prtx_s {
15023 + uint64_t frag:32;
15024 + uint64_t undersz:32;
15025 + } s;
15026 + struct cvmx_pip_stat8_prtx_s cn30xx;
15027 + struct cvmx_pip_stat8_prtx_s cn31xx;
15028 + struct cvmx_pip_stat8_prtx_s cn38xx;
15029 + struct cvmx_pip_stat8_prtx_s cn38xxp2;
15030 + struct cvmx_pip_stat8_prtx_s cn50xx;
15031 + struct cvmx_pip_stat8_prtx_s cn52xx;
15032 + struct cvmx_pip_stat8_prtx_s cn52xxp1;
15033 + struct cvmx_pip_stat8_prtx_s cn56xx;
15034 + struct cvmx_pip_stat8_prtx_s cn56xxp1;
15035 + struct cvmx_pip_stat8_prtx_s cn58xx;
15036 + struct cvmx_pip_stat8_prtx_s cn58xxp1;
15037 +};
15038 +
15039 +union cvmx_pip_stat9_prtx {
15040 + uint64_t u64;
15041 + struct cvmx_pip_stat9_prtx_s {
15042 + uint64_t jabber:32;
15043 + uint64_t oversz:32;
15044 + } s;
15045 + struct cvmx_pip_stat9_prtx_s cn30xx;
15046 + struct cvmx_pip_stat9_prtx_s cn31xx;
15047 + struct cvmx_pip_stat9_prtx_s cn38xx;
15048 + struct cvmx_pip_stat9_prtx_s cn38xxp2;
15049 + struct cvmx_pip_stat9_prtx_s cn50xx;
15050 + struct cvmx_pip_stat9_prtx_s cn52xx;
15051 + struct cvmx_pip_stat9_prtx_s cn52xxp1;
15052 + struct cvmx_pip_stat9_prtx_s cn56xx;
15053 + struct cvmx_pip_stat9_prtx_s cn56xxp1;
15054 + struct cvmx_pip_stat9_prtx_s cn58xx;
15055 + struct cvmx_pip_stat9_prtx_s cn58xxp1;
15056 +};
15057 +
15058 +union cvmx_pip_stat_ctl {
15059 + uint64_t u64;
15060 + struct cvmx_pip_stat_ctl_s {
15061 + uint64_t reserved_1_63:63;
15062 + uint64_t rdclr:1;
15063 + } s;
15064 + struct cvmx_pip_stat_ctl_s cn30xx;
15065 + struct cvmx_pip_stat_ctl_s cn31xx;
15066 + struct cvmx_pip_stat_ctl_s cn38xx;
15067 + struct cvmx_pip_stat_ctl_s cn38xxp2;
15068 + struct cvmx_pip_stat_ctl_s cn50xx;
15069 + struct cvmx_pip_stat_ctl_s cn52xx;
15070 + struct cvmx_pip_stat_ctl_s cn52xxp1;
15071 + struct cvmx_pip_stat_ctl_s cn56xx;
15072 + struct cvmx_pip_stat_ctl_s cn56xxp1;
15073 + struct cvmx_pip_stat_ctl_s cn58xx;
15074 + struct cvmx_pip_stat_ctl_s cn58xxp1;
15075 +};
15076 +
15077 +union cvmx_pip_stat_inb_errsx {
15078 + uint64_t u64;
15079 + struct cvmx_pip_stat_inb_errsx_s {
15080 + uint64_t reserved_16_63:48;
15081 + uint64_t errs:16;
15082 + } s;
15083 + struct cvmx_pip_stat_inb_errsx_s cn30xx;
15084 + struct cvmx_pip_stat_inb_errsx_s cn31xx;
15085 + struct cvmx_pip_stat_inb_errsx_s cn38xx;
15086 + struct cvmx_pip_stat_inb_errsx_s cn38xxp2;
15087 + struct cvmx_pip_stat_inb_errsx_s cn50xx;
15088 + struct cvmx_pip_stat_inb_errsx_s cn52xx;
15089 + struct cvmx_pip_stat_inb_errsx_s cn52xxp1;
15090 + struct cvmx_pip_stat_inb_errsx_s cn56xx;
15091 + struct cvmx_pip_stat_inb_errsx_s cn56xxp1;
15092 + struct cvmx_pip_stat_inb_errsx_s cn58xx;
15093 + struct cvmx_pip_stat_inb_errsx_s cn58xxp1;
15094 +};
15095 +
15096 +union cvmx_pip_stat_inb_octsx {
15097 + uint64_t u64;
15098 + struct cvmx_pip_stat_inb_octsx_s {
15099 + uint64_t reserved_48_63:16;
15100 + uint64_t octs:48;
15101 + } s;
15102 + struct cvmx_pip_stat_inb_octsx_s cn30xx;
15103 + struct cvmx_pip_stat_inb_octsx_s cn31xx;
15104 + struct cvmx_pip_stat_inb_octsx_s cn38xx;
15105 + struct cvmx_pip_stat_inb_octsx_s cn38xxp2;
15106 + struct cvmx_pip_stat_inb_octsx_s cn50xx;
15107 + struct cvmx_pip_stat_inb_octsx_s cn52xx;
15108 + struct cvmx_pip_stat_inb_octsx_s cn52xxp1;
15109 + struct cvmx_pip_stat_inb_octsx_s cn56xx;
15110 + struct cvmx_pip_stat_inb_octsx_s cn56xxp1;
15111 + struct cvmx_pip_stat_inb_octsx_s cn58xx;
15112 + struct cvmx_pip_stat_inb_octsx_s cn58xxp1;
15113 +};
15114 +
15115 +union cvmx_pip_stat_inb_pktsx {
15116 + uint64_t u64;
15117 + struct cvmx_pip_stat_inb_pktsx_s {
15118 + uint64_t reserved_32_63:32;
15119 + uint64_t pkts:32;
15120 + } s;
15121 + struct cvmx_pip_stat_inb_pktsx_s cn30xx;
15122 + struct cvmx_pip_stat_inb_pktsx_s cn31xx;
15123 + struct cvmx_pip_stat_inb_pktsx_s cn38xx;
15124 + struct cvmx_pip_stat_inb_pktsx_s cn38xxp2;
15125 + struct cvmx_pip_stat_inb_pktsx_s cn50xx;
15126 + struct cvmx_pip_stat_inb_pktsx_s cn52xx;
15127 + struct cvmx_pip_stat_inb_pktsx_s cn52xxp1;
15128 + struct cvmx_pip_stat_inb_pktsx_s cn56xx;
15129 + struct cvmx_pip_stat_inb_pktsx_s cn56xxp1;
15130 + struct cvmx_pip_stat_inb_pktsx_s cn58xx;
15131 + struct cvmx_pip_stat_inb_pktsx_s cn58xxp1;
15132 +};
15133 +
15134 +union cvmx_pip_tag_incx {
15135 + uint64_t u64;
15136 + struct cvmx_pip_tag_incx_s {
15137 + uint64_t reserved_8_63:56;
15138 + uint64_t en:8;
15139 + } s;
15140 + struct cvmx_pip_tag_incx_s cn30xx;
15141 + struct cvmx_pip_tag_incx_s cn31xx;
15142 + struct cvmx_pip_tag_incx_s cn38xx;
15143 + struct cvmx_pip_tag_incx_s cn38xxp2;
15144 + struct cvmx_pip_tag_incx_s cn50xx;
15145 + struct cvmx_pip_tag_incx_s cn52xx;
15146 + struct cvmx_pip_tag_incx_s cn52xxp1;
15147 + struct cvmx_pip_tag_incx_s cn56xx;
15148 + struct cvmx_pip_tag_incx_s cn56xxp1;
15149 + struct cvmx_pip_tag_incx_s cn58xx;
15150 + struct cvmx_pip_tag_incx_s cn58xxp1;
15151 +};
15152 +
15153 +union cvmx_pip_tag_mask {
15154 + uint64_t u64;
15155 + struct cvmx_pip_tag_mask_s {
15156 + uint64_t reserved_16_63:48;
15157 + uint64_t mask:16;
15158 + } s;
15159 + struct cvmx_pip_tag_mask_s cn30xx;
15160 + struct cvmx_pip_tag_mask_s cn31xx;
15161 + struct cvmx_pip_tag_mask_s cn38xx;
15162 + struct cvmx_pip_tag_mask_s cn38xxp2;
15163 + struct cvmx_pip_tag_mask_s cn50xx;
15164 + struct cvmx_pip_tag_mask_s cn52xx;
15165 + struct cvmx_pip_tag_mask_s cn52xxp1;
15166 + struct cvmx_pip_tag_mask_s cn56xx;
15167 + struct cvmx_pip_tag_mask_s cn56xxp1;
15168 + struct cvmx_pip_tag_mask_s cn58xx;
15169 + struct cvmx_pip_tag_mask_s cn58xxp1;
15170 +};
15171 +
15172 +union cvmx_pip_tag_secret {
15173 + uint64_t u64;
15174 + struct cvmx_pip_tag_secret_s {
15175 + uint64_t reserved_32_63:32;
15176 + uint64_t dst:16;
15177 + uint64_t src:16;
15178 + } s;
15179 + struct cvmx_pip_tag_secret_s cn30xx;
15180 + struct cvmx_pip_tag_secret_s cn31xx;
15181 + struct cvmx_pip_tag_secret_s cn38xx;
15182 + struct cvmx_pip_tag_secret_s cn38xxp2;
15183 + struct cvmx_pip_tag_secret_s cn50xx;
15184 + struct cvmx_pip_tag_secret_s cn52xx;
15185 + struct cvmx_pip_tag_secret_s cn52xxp1;
15186 + struct cvmx_pip_tag_secret_s cn56xx;
15187 + struct cvmx_pip_tag_secret_s cn56xxp1;
15188 + struct cvmx_pip_tag_secret_s cn58xx;
15189 + struct cvmx_pip_tag_secret_s cn58xxp1;
15190 +};
15191 +
15192 +union cvmx_pip_todo_entry {
15193 + uint64_t u64;
15194 + struct cvmx_pip_todo_entry_s {
15195 + uint64_t val:1;
15196 + uint64_t reserved_62_62:1;
15197 + uint64_t entry:62;
15198 + } s;
15199 + struct cvmx_pip_todo_entry_s cn30xx;
15200 + struct cvmx_pip_todo_entry_s cn31xx;
15201 + struct cvmx_pip_todo_entry_s cn38xx;
15202 + struct cvmx_pip_todo_entry_s cn38xxp2;
15203 + struct cvmx_pip_todo_entry_s cn50xx;
15204 + struct cvmx_pip_todo_entry_s cn52xx;
15205 + struct cvmx_pip_todo_entry_s cn52xxp1;
15206 + struct cvmx_pip_todo_entry_s cn56xx;
15207 + struct cvmx_pip_todo_entry_s cn56xxp1;
15208 + struct cvmx_pip_todo_entry_s cn58xx;
15209 + struct cvmx_pip_todo_entry_s cn58xxp1;
15210 +};
15211 +
15212 +#endif
15213 diff --git a/drivers/staging/octeon/cvmx-pip.h b/drivers/staging/octeon/cvmx-pip.h
15214 new file mode 100644
15215 index 0000000..78dbce8
15216 --- /dev/null
15217 +++ b/drivers/staging/octeon/cvmx-pip.h
15218 @@ -0,0 +1,524 @@
15219 +/***********************license start***************
15220 + * Author: Cavium Networks
15221 + *
15222 + * Contact: support@caviumnetworks.com
15223 + * This file is part of the OCTEON SDK
15224 + *
15225 + * Copyright (c) 2003-2008 Cavium Networks
15226 + *
15227 + * This file is free software; you can redistribute it and/or modify
15228 + * it under the terms of the GNU General Public License, Version 2, as
15229 + * published by the Free Software Foundation.
15230 + *
15231 + * This file is distributed in the hope that it will be useful, but
15232 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15233 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
15234 + * NONINFRINGEMENT. See the GNU General Public License for more
15235 + * details.
15236 + *
15237 + * You should have received a copy of the GNU General Public License
15238 + * along with this file; if not, write to the Free Software
15239 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15240 + * or visit http://www.gnu.org/licenses/.
15241 + *
15242 + * This file may also be available under a different license from Cavium.
15243 + * Contact Cavium Networks for more information
15244 + ***********************license end**************************************/
15245 +
15246 +/*
15247 + * Interface to the hardware Packet Input Processing unit.
15248 + *
15249 + */
15250 +
15251 +#ifndef __CVMX_PIP_H__
15252 +#define __CVMX_PIP_H__
15253 +
15254 +#include "cvmx-wqe.h"
15255 +#include "cvmx-fpa.h"
15256 +#include "cvmx-pip-defs.h"
15257 +
15258 +#define CVMX_PIP_NUM_INPUT_PORTS 40
15259 +#define CVMX_PIP_NUM_WATCHERS 4
15260 +
15261 +/*
15262 + * Encodes the different error and exception codes
15263 + */
15264 +typedef enum {
15265 + CVMX_PIP_L4_NO_ERR = 0ull,
15266 + /*
15267 + * 1 = TCP (UDP) packet not long enough to cover TCP (UDP)
15268 + * header
15269 + */
15270 + CVMX_PIP_L4_MAL_ERR = 1ull,
15271 + /* 2 = TCP/UDP checksum failure */
15272 + CVMX_PIP_CHK_ERR = 2ull,
15273 + /*
15274 + * 3 = TCP/UDP length check (TCP/UDP length does not match IP
15275 + * length).
15276 + */
15277 + CVMX_PIP_L4_LENGTH_ERR = 3ull,
15278 + /* 4 = illegal TCP/UDP port (either source or dest port is zero) */
15279 + CVMX_PIP_BAD_PRT_ERR = 4ull,
15280 + /* 8 = TCP flags = FIN only */
15281 + CVMX_PIP_TCP_FLG8_ERR = 8ull,
15282 + /* 9 = TCP flags = 0 */
15283 + CVMX_PIP_TCP_FLG9_ERR = 9ull,
15284 + /* 10 = TCP flags = FIN+RST+* */
15285 + CVMX_PIP_TCP_FLG10_ERR = 10ull,
15286 + /* 11 = TCP flags = SYN+URG+* */
15287 + CVMX_PIP_TCP_FLG11_ERR = 11ull,
15288 + /* 12 = TCP flags = SYN+RST+* */
15289 + CVMX_PIP_TCP_FLG12_ERR = 12ull,
15290 + /* 13 = TCP flags = SYN+FIN+* */
15291 + CVMX_PIP_TCP_FLG13_ERR = 13ull
15292 +} cvmx_pip_l4_err_t;
15293 +
15294 +typedef enum {
15295 +
15296 + CVMX_PIP_IP_NO_ERR = 0ull,
15297 + /* 1 = not IPv4 or IPv6 */
15298 + CVMX_PIP_NOT_IP = 1ull,
15299 + /* 2 = IPv4 header checksum violation */
15300 + CVMX_PIP_IPV4_HDR_CHK = 2ull,
15301 + /* 3 = malformed (packet not long enough to cover IP hdr) */
15302 + CVMX_PIP_IP_MAL_HDR = 3ull,
15303 + /* 4 = malformed (packet not long enough to cover len in IP hdr) */
15304 + CVMX_PIP_IP_MAL_PKT = 4ull,
15305 + /* 5 = TTL / hop count equal zero */
15306 + CVMX_PIP_TTL_HOP = 5ull,
15307 + /* 6 = IPv4 options / IPv6 early extension headers */
15308 + CVMX_PIP_OPTS = 6ull
15309 +} cvmx_pip_ip_exc_t;
15310 +
15311 +/**
15312 + * NOTES
15313 + * late collision (data received before collision)
15314 + * late collisions cannot be detected by the receiver
15315 + * they would appear as JAM bits which would appear as bad FCS
15316 + * or carrier extend error which is CVMX_PIP_EXTEND_ERR
15317 + */
15318 +typedef enum {
15319 + /* No error */
15320 + CVMX_PIP_RX_NO_ERR = 0ull,
15321 + /* RGM+SPI 1 = partially received packet (buffering/bandwidth
15322 + * not adequate) */
15323 + CVMX_PIP_PARTIAL_ERR = 1ull,
15324 + /* RGM+SPI 2 = receive packet too large and truncated */
15325 + CVMX_PIP_JABBER_ERR = 2ull,
15326 + /*
15327 + * RGM 3 = max frame error (pkt len > max frame len) (with FCS
15328 + * error)
15329 + */
15330 + CVMX_PIP_OVER_FCS_ERR = 3ull,
15331 + /* RGM+SPI 4 = max frame error (pkt len > max frame len) */
15332 + CVMX_PIP_OVER_ERR = 4ull,
15333 + /*
15334 + * RGM 5 = nibble error (data not byte multiple - 100M and 10M
15335 + * only)
15336 + */
15337 + CVMX_PIP_ALIGN_ERR = 5ull,
15338 + /*
15339 + * RGM 6 = min frame error (pkt len < min frame len) (with FCS
15340 + * error)
15341 + */
15342 + CVMX_PIP_UNDER_FCS_ERR = 6ull,
15343 + /* RGM 7 = FCS error */
15344 + CVMX_PIP_GMX_FCS_ERR = 7ull,
15345 + /* RGM+SPI 8 = min frame error (pkt len < min frame len) */
15346 + CVMX_PIP_UNDER_ERR = 8ull,
15347 + /* RGM 9 = Frame carrier extend error */
15348 + CVMX_PIP_EXTEND_ERR = 9ull,
15349 + /*
15350 + * RGM 10 = length mismatch (len did not match len in L2
15351 + * length/type)
15352 + */
15353 + CVMX_PIP_LENGTH_ERR = 10ull,
15354 + /* RGM 11 = Frame error (some or all data bits marked err) */
15355 + CVMX_PIP_DAT_ERR = 11ull,
15356 + /* SPI 11 = DIP4 error */
15357 + CVMX_PIP_DIP_ERR = 11ull,
15358 + /*
15359 + * RGM 12 = packet was not large enough to pass the skipper -
15360 + * no inspection could occur.
15361 + */
15362 + CVMX_PIP_SKIP_ERR = 12ull,
15363 + /*
15364 + * RGM 13 = studder error (data not repeated - 100M and 10M
15365 + * only)
15366 + */
15367 + CVMX_PIP_NIBBLE_ERR = 13ull,
15368 + /* RGM+SPI 16 = FCS error */
15369 + CVMX_PIP_PIP_FCS = 16L,
15370 + /*
15371 + * RGM+SPI+PCI 17 = packet was not large enough to pass the
15372 + * skipper - no inspection could occur.
15373 + */
15374 + CVMX_PIP_PIP_SKIP_ERR = 17L,
15375 + /*
15376 + * RGM+SPI+PCI 18 = malformed l2 (packet not long enough to
15377 + * cover L2 hdr).
15378 + */
15379 + CVMX_PIP_PIP_L2_MAL_HDR = 18L
15380 + /*
15381 + * NOTES: xx = late collision (data received before collision)
15382 + * late collisions cannot be detected by the receiver
15383 + * they would appear as JAM bits which would appear as
15384 + * bad FCS or carrier extend error which is
15385 + * CVMX_PIP_EXTEND_ERR
15386 + */
15387 +} cvmx_pip_rcv_err_t;
15388 +
15389 +/**
15390 + * This defines the err_code field errors in the work Q entry
15391 + */
15392 +typedef union {
15393 + cvmx_pip_l4_err_t l4_err;
15394 + cvmx_pip_ip_exc_t ip_exc;
15395 + cvmx_pip_rcv_err_t rcv_err;
15396 +} cvmx_pip_err_t;
15397 +
15398 +/**
15399 + * Status statistics for a port
15400 + */
15401 +typedef struct {
15402 + /* Inbound octets marked to be dropped by the IPD */
15403 + uint32_t dropped_octets;
15404 + /* Inbound packets marked to be dropped by the IPD */
15405 + uint32_t dropped_packets;
15406 + /* RAW PCI Packets received by PIP per port */
15407 + uint32_t pci_raw_packets;
15408 + /* Number of octets processed by PIP */
15409 + uint32_t octets;
15410 + /* Number of packets processed by PIP */
15411 + uint32_t packets;
15412 + /*
15413 + * Number of indentified L2 multicast packets. Does not
15414 + * include broadcast packets. Only includes packets whose
15415 + * parse mode is SKIP_TO_L2
15416 + */
15417 + uint32_t multicast_packets;
15418 + /*
15419 + * Number of indentified L2 broadcast packets. Does not
15420 + * include multicast packets. Only includes packets whose
15421 + * parse mode is SKIP_TO_L2
15422 + */
15423 + uint32_t broadcast_packets;
15424 + /* Number of 64B packets */
15425 + uint32_t len_64_packets;
15426 + /* Number of 65-127B packets */
15427 + uint32_t len_65_127_packets;
15428 + /* Number of 128-255B packets */
15429 + uint32_t len_128_255_packets;
15430 + /* Number of 256-511B packets */
15431 + uint32_t len_256_511_packets;
15432 + /* Number of 512-1023B packets */
15433 + uint32_t len_512_1023_packets;
15434 + /* Number of 1024-1518B packets */
15435 + uint32_t len_1024_1518_packets;
15436 + /* Number of 1519-max packets */
15437 + uint32_t len_1519_max_packets;
15438 + /* Number of packets with FCS or Align opcode errors */
15439 + uint32_t fcs_align_err_packets;
15440 + /* Number of packets with length < min */
15441 + uint32_t runt_packets;
15442 + /* Number of packets with length < min and FCS error */
15443 + uint32_t runt_crc_packets;
15444 + /* Number of packets with length > max */
15445 + uint32_t oversize_packets;
15446 + /* Number of packets with length > max and FCS error */
15447 + uint32_t oversize_crc_packets;
15448 + /* Number of packets without GMX/SPX/PCI errors received by PIP */
15449 + uint32_t inb_packets;
15450 + /*
15451 + * Total number of octets from all packets received by PIP,
15452 + * including CRC
15453 + */
15454 + uint64_t inb_octets;
15455 + /* Number of packets with GMX/SPX/PCI errors received by PIP */
15456 + uint16_t inb_errors;
15457 +} cvmx_pip_port_status_t;
15458 +
15459 +/**
15460 + * Definition of the PIP custom header that can be prepended
15461 + * to a packet by external hardware.
15462 + */
15463 +typedef union {
15464 + uint64_t u64;
15465 + struct {
15466 + /*
15467 + * Documented as R - Set if the Packet is RAWFULL. If
15468 + * set, this header must be the full 8 bytes.
15469 + */
15470 + uint64_t rawfull:1;
15471 + /* Must be zero */
15472 + uint64_t reserved0:5;
15473 + /* PIP parse mode for this packet */
15474 + uint64_t parse_mode:2;
15475 + /* Must be zero */
15476 + uint64_t reserved1:1;
15477 + /*
15478 + * Skip amount, including this header, to the
15479 + * beginning of the packet
15480 + */
15481 + uint64_t skip_len:7;
15482 + /* Must be zero */
15483 + uint64_t reserved2:6;
15484 + /* POW input queue for this packet */
15485 + uint64_t qos:3;
15486 + /* POW input group for this packet */
15487 + uint64_t grp:4;
15488 + /*
15489 + * Flag to store this packet in the work queue entry,
15490 + * if possible
15491 + */
15492 + uint64_t rs:1;
15493 + /* POW input tag type */
15494 + uint64_t tag_type:2;
15495 + /* POW input tag */
15496 + uint64_t tag:32;
15497 + } s;
15498 +} cvmx_pip_pkt_inst_hdr_t;
15499 +
15500 +/* CSR typedefs have been moved to cvmx-csr-*.h */
15501 +
15502 +/**
15503 + * Configure an ethernet input port
15504 + *
15505 + * @port_num: Port number to configure
15506 + * @port_cfg: Port hardware configuration
15507 + * @port_tag_cfg:
15508 + * Port POW tagging configuration
15509 + */
15510 +static inline void cvmx_pip_config_port(uint64_t port_num,
15511 + union cvmx_pip_prt_cfgx port_cfg,
15512 + union cvmx_pip_prt_tagx port_tag_cfg)
15513 +{
15514 + cvmx_write_csr(CVMX_PIP_PRT_CFGX(port_num), port_cfg.u64);
15515 + cvmx_write_csr(CVMX_PIP_PRT_TAGX(port_num), port_tag_cfg.u64);
15516 +}
15517 +#if 0
15518 +/**
15519 + * @deprecated This function is a thin wrapper around the Pass1 version
15520 + * of the CVMX_PIP_QOS_WATCHX CSR; Pass2 has added a field for
15521 + * setting the group that is incompatible with this function,
15522 + * the preferred upgrade path is to use the CSR directly.
15523 + *
15524 + * Configure the global QoS packet watchers. Each watcher is
15525 + * capable of matching a field in a packet to determine the
15526 + * QoS queue for scheduling.
15527 + *
15528 + * @watcher: Watcher number to configure (0 - 3).
15529 + * @match_type: Watcher match type
15530 + * @match_value:
15531 + * Value the watcher will match against
15532 + * @qos: QoS queue for packets matching this watcher
15533 + */
15534 +static inline void cvmx_pip_config_watcher(uint64_t watcher,
15535 + cvmx_pip_qos_watch_types match_type,
15536 + uint64_t match_value, uint64_t qos)
15537 +{
15538 + cvmx_pip_port_watcher_cfg_t watcher_config;
15539 +
15540 + watcher_config.u64 = 0;
15541 + watcher_config.s.match_type = match_type;
15542 + watcher_config.s.match_value = match_value;
15543 + watcher_config.s.qos = qos;
15544 +
15545 + cvmx_write_csr(CVMX_PIP_QOS_WATCHX(watcher), watcher_config.u64);
15546 +}
15547 +#endif
15548 +/**
15549 + * Configure the VLAN priority to QoS queue mapping.
15550 + *
15551 + * @vlan_priority:
15552 + * VLAN priority (0-7)
15553 + * @qos: QoS queue for packets matching this watcher
15554 + */
15555 +static inline void cvmx_pip_config_vlan_qos(uint64_t vlan_priority,
15556 + uint64_t qos)
15557 +{
15558 + union cvmx_pip_qos_vlanx pip_qos_vlanx;
15559 + pip_qos_vlanx.u64 = 0;
15560 + pip_qos_vlanx.s.qos = qos;
15561 + cvmx_write_csr(CVMX_PIP_QOS_VLANX(vlan_priority), pip_qos_vlanx.u64);
15562 +}
15563 +
15564 +/**
15565 + * Configure the Diffserv to QoS queue mapping.
15566 + *
15567 + * @diffserv: Diffserv field value (0-63)
15568 + * @qos: QoS queue for packets matching this watcher
15569 + */
15570 +static inline void cvmx_pip_config_diffserv_qos(uint64_t diffserv, uint64_t qos)
15571 +{
15572 + union cvmx_pip_qos_diffx pip_qos_diffx;
15573 + pip_qos_diffx.u64 = 0;
15574 + pip_qos_diffx.s.qos = qos;
15575 + cvmx_write_csr(CVMX_PIP_QOS_DIFFX(diffserv), pip_qos_diffx.u64);
15576 +}
15577 +
15578 +/**
15579 + * Get the status counters for a port.
15580 + *
15581 + * @port_num: Port number to get statistics for.
15582 + * @clear: Set to 1 to clear the counters after they are read
15583 + * @status: Where to put the results.
15584 + */
15585 +static inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear,
15586 + cvmx_pip_port_status_t *status)
15587 +{
15588 + union cvmx_pip_stat_ctl pip_stat_ctl;
15589 + union cvmx_pip_stat0_prtx stat0;
15590 + union cvmx_pip_stat1_prtx stat1;
15591 + union cvmx_pip_stat2_prtx stat2;
15592 + union cvmx_pip_stat3_prtx stat3;
15593 + union cvmx_pip_stat4_prtx stat4;
15594 + union cvmx_pip_stat5_prtx stat5;
15595 + union cvmx_pip_stat6_prtx stat6;
15596 + union cvmx_pip_stat7_prtx stat7;
15597 + union cvmx_pip_stat8_prtx stat8;
15598 + union cvmx_pip_stat9_prtx stat9;
15599 + union cvmx_pip_stat_inb_pktsx pip_stat_inb_pktsx;
15600 + union cvmx_pip_stat_inb_octsx pip_stat_inb_octsx;
15601 + union cvmx_pip_stat_inb_errsx pip_stat_inb_errsx;
15602 +
15603 + pip_stat_ctl.u64 = 0;
15604 + pip_stat_ctl.s.rdclr = clear;
15605 + cvmx_write_csr(CVMX_PIP_STAT_CTL, pip_stat_ctl.u64);
15606 +
15607 + stat0.u64 = cvmx_read_csr(CVMX_PIP_STAT0_PRTX(port_num));
15608 + stat1.u64 = cvmx_read_csr(CVMX_PIP_STAT1_PRTX(port_num));
15609 + stat2.u64 = cvmx_read_csr(CVMX_PIP_STAT2_PRTX(port_num));
15610 + stat3.u64 = cvmx_read_csr(CVMX_PIP_STAT3_PRTX(port_num));
15611 + stat4.u64 = cvmx_read_csr(CVMX_PIP_STAT4_PRTX(port_num));
15612 + stat5.u64 = cvmx_read_csr(CVMX_PIP_STAT5_PRTX(port_num));
15613 + stat6.u64 = cvmx_read_csr(CVMX_PIP_STAT6_PRTX(port_num));
15614 + stat7.u64 = cvmx_read_csr(CVMX_PIP_STAT7_PRTX(port_num));
15615 + stat8.u64 = cvmx_read_csr(CVMX_PIP_STAT8_PRTX(port_num));
15616 + stat9.u64 = cvmx_read_csr(CVMX_PIP_STAT9_PRTX(port_num));
15617 + pip_stat_inb_pktsx.u64 =
15618 + cvmx_read_csr(CVMX_PIP_STAT_INB_PKTSX(port_num));
15619 + pip_stat_inb_octsx.u64 =
15620 + cvmx_read_csr(CVMX_PIP_STAT_INB_OCTSX(port_num));
15621 + pip_stat_inb_errsx.u64 =
15622 + cvmx_read_csr(CVMX_PIP_STAT_INB_ERRSX(port_num));
15623 +
15624 + status->dropped_octets = stat0.s.drp_octs;
15625 + status->dropped_packets = stat0.s.drp_pkts;
15626 + status->octets = stat1.s.octs;
15627 + status->pci_raw_packets = stat2.s.raw;
15628 + status->packets = stat2.s.pkts;
15629 + status->multicast_packets = stat3.s.mcst;
15630 + status->broadcast_packets = stat3.s.bcst;
15631 + status->len_64_packets = stat4.s.h64;
15632 + status->len_65_127_packets = stat4.s.h65to127;
15633 + status->len_128_255_packets = stat5.s.h128to255;
15634 + status->len_256_511_packets = stat5.s.h256to511;
15635 + status->len_512_1023_packets = stat6.s.h512to1023;
15636 + status->len_1024_1518_packets = stat6.s.h1024to1518;
15637 + status->len_1519_max_packets = stat7.s.h1519;
15638 + status->fcs_align_err_packets = stat7.s.fcs;
15639 + status->runt_packets = stat8.s.undersz;
15640 + status->runt_crc_packets = stat8.s.frag;
15641 + status->oversize_packets = stat9.s.oversz;
15642 + status->oversize_crc_packets = stat9.s.jabber;
15643 + status->inb_packets = pip_stat_inb_pktsx.s.pkts;
15644 + status->inb_octets = pip_stat_inb_octsx.s.octs;
15645 + status->inb_errors = pip_stat_inb_errsx.s.errs;
15646 +
15647 + if (cvmx_octeon_is_pass1()) {
15648 + /*
15649 + * Kludge to fix Octeon Pass 1 errata - Drop counts
15650 + * don't work.
15651 + */
15652 + if (status->inb_packets > status->packets)
15653 + status->dropped_packets =
15654 + status->inb_packets - status->packets;
15655 + else
15656 + status->dropped_packets = 0;
15657 + if (status->inb_octets - status->inb_packets * 4 >
15658 + status->octets)
15659 + status->dropped_octets =
15660 + status->inb_octets - status->inb_packets * 4 -
15661 + status->octets;
15662 + else
15663 + status->dropped_octets = 0;
15664 + }
15665 +}
15666 +
15667 +/**
15668 + * Configure the hardware CRC engine
15669 + *
15670 + * @interface: Interface to configure (0 or 1)
15671 + * @invert_result:
15672 + * Invert the result of the CRC
15673 + * @reflect: Reflect
15674 + * @initialization_vector:
15675 + * CRC initialization vector
15676 + */
15677 +static inline void cvmx_pip_config_crc(uint64_t interface,
15678 + uint64_t invert_result, uint64_t reflect,
15679 + uint32_t initialization_vector)
15680 +{
15681 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
15682 + union cvmx_pip_crc_ctlx config;
15683 + union cvmx_pip_crc_ivx pip_crc_ivx;
15684 +
15685 + config.u64 = 0;
15686 + config.s.invres = invert_result;
15687 + config.s.reflect = reflect;
15688 + cvmx_write_csr(CVMX_PIP_CRC_CTLX(interface), config.u64);
15689 +
15690 + pip_crc_ivx.u64 = 0;
15691 + pip_crc_ivx.s.iv = initialization_vector;
15692 + cvmx_write_csr(CVMX_PIP_CRC_IVX(interface), pip_crc_ivx.u64);
15693 + }
15694 +}
15695 +
15696 +/**
15697 + * Clear all bits in a tag mask. This should be called on
15698 + * startup before any calls to cvmx_pip_tag_mask_set. Each bit
15699 + * set in the final mask represent a byte used in the packet for
15700 + * tag generation.
15701 + *
15702 + * @mask_index: Which tag mask to clear (0..3)
15703 + */
15704 +static inline void cvmx_pip_tag_mask_clear(uint64_t mask_index)
15705 +{
15706 + uint64_t index;
15707 + union cvmx_pip_tag_incx pip_tag_incx;
15708 + pip_tag_incx.u64 = 0;
15709 + pip_tag_incx.s.en = 0;
15710 + for (index = mask_index * 16; index < (mask_index + 1) * 16; index++)
15711 + cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
15712 +}
15713 +
15714 +/**
15715 + * Sets a range of bits in the tag mask. The tag mask is used
15716 + * when the cvmx_pip_port_tag_cfg_t tag_mode is non zero.
15717 + * There are four separate masks that can be configured.
15718 + *
15719 + * @mask_index: Which tag mask to modify (0..3)
15720 + * @offset: Offset into the bitmask to set bits at. Use the GCC macro
15721 + * offsetof() to determine the offsets into packet headers.
15722 + * For example, offsetof(ethhdr, protocol) returns the offset
15723 + * of the ethernet protocol field. The bitmask selects which
15724 + * bytes to include the the tag, with bit offset X selecting
15725 + * byte at offset X from the beginning of the packet data.
15726 + * @len: Number of bytes to include. Usually this is the sizeof()
15727 + * the field.
15728 + */
15729 +static inline void cvmx_pip_tag_mask_set(uint64_t mask_index, uint64_t offset,
15730 + uint64_t len)
15731 +{
15732 + while (len--) {
15733 + union cvmx_pip_tag_incx pip_tag_incx;
15734 + uint64_t index = mask_index * 16 + offset / 8;
15735 + pip_tag_incx.u64 = cvmx_read_csr(CVMX_PIP_TAG_INCX(index));
15736 + pip_tag_incx.s.en |= 0x80 >> (offset & 0x7);
15737 + cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
15738 + offset++;
15739 + }
15740 +}
15741 +
15742 +#endif /* __CVMX_PIP_H__ */
15743 diff --git a/drivers/staging/octeon/cvmx-pko-defs.h b/drivers/staging/octeon/cvmx-pko-defs.h
15744 new file mode 100644
15745 index 0000000..50e779c
15746 --- /dev/null
15747 +++ b/drivers/staging/octeon/cvmx-pko-defs.h
15748 @@ -0,0 +1,1133 @@
15749 +/***********************license start***************
15750 + * Author: Cavium Networks
15751 + *
15752 + * Contact: support@caviumnetworks.com
15753 + * This file is part of the OCTEON SDK
15754 + *
15755 + * Copyright (c) 2003-2008 Cavium Networks
15756 + *
15757 + * This file is free software; you can redistribute it and/or modify
15758 + * it under the terms of the GNU General Public License, Version 2, as
15759 + * published by the Free Software Foundation.
15760 + *
15761 + * This file is distributed in the hope that it will be useful, but
15762 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15763 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
15764 + * NONINFRINGEMENT. See the GNU General Public License for more
15765 + * details.
15766 + *
15767 + * You should have received a copy of the GNU General Public License
15768 + * along with this file; if not, write to the Free Software
15769 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15770 + * or visit http://www.gnu.org/licenses/.
15771 + *
15772 + * This file may also be available under a different license from Cavium.
15773 + * Contact Cavium Networks for more information
15774 + ***********************license end**************************************/
15775 +
15776 +#ifndef __CVMX_PKO_DEFS_H__
15777 +#define __CVMX_PKO_DEFS_H__
15778 +
15779 +#define CVMX_PKO_MEM_COUNT0 \
15780 + CVMX_ADD_IO_SEG(0x0001180050001080ull)
15781 +#define CVMX_PKO_MEM_COUNT1 \
15782 + CVMX_ADD_IO_SEG(0x0001180050001088ull)
15783 +#define CVMX_PKO_MEM_DEBUG0 \
15784 + CVMX_ADD_IO_SEG(0x0001180050001100ull)
15785 +#define CVMX_PKO_MEM_DEBUG1 \
15786 + CVMX_ADD_IO_SEG(0x0001180050001108ull)
15787 +#define CVMX_PKO_MEM_DEBUG10 \
15788 + CVMX_ADD_IO_SEG(0x0001180050001150ull)
15789 +#define CVMX_PKO_MEM_DEBUG11 \
15790 + CVMX_ADD_IO_SEG(0x0001180050001158ull)
15791 +#define CVMX_PKO_MEM_DEBUG12 \
15792 + CVMX_ADD_IO_SEG(0x0001180050001160ull)
15793 +#define CVMX_PKO_MEM_DEBUG13 \
15794 + CVMX_ADD_IO_SEG(0x0001180050001168ull)
15795 +#define CVMX_PKO_MEM_DEBUG14 \
15796 + CVMX_ADD_IO_SEG(0x0001180050001170ull)
15797 +#define CVMX_PKO_MEM_DEBUG2 \
15798 + CVMX_ADD_IO_SEG(0x0001180050001110ull)
15799 +#define CVMX_PKO_MEM_DEBUG3 \
15800 + CVMX_ADD_IO_SEG(0x0001180050001118ull)
15801 +#define CVMX_PKO_MEM_DEBUG4 \
15802 + CVMX_ADD_IO_SEG(0x0001180050001120ull)
15803 +#define CVMX_PKO_MEM_DEBUG5 \
15804 + CVMX_ADD_IO_SEG(0x0001180050001128ull)
15805 +#define CVMX_PKO_MEM_DEBUG6 \
15806 + CVMX_ADD_IO_SEG(0x0001180050001130ull)
15807 +#define CVMX_PKO_MEM_DEBUG7 \
15808 + CVMX_ADD_IO_SEG(0x0001180050001138ull)
15809 +#define CVMX_PKO_MEM_DEBUG8 \
15810 + CVMX_ADD_IO_SEG(0x0001180050001140ull)
15811 +#define CVMX_PKO_MEM_DEBUG9 \
15812 + CVMX_ADD_IO_SEG(0x0001180050001148ull)
15813 +#define CVMX_PKO_MEM_PORT_PTRS \
15814 + CVMX_ADD_IO_SEG(0x0001180050001010ull)
15815 +#define CVMX_PKO_MEM_PORT_QOS \
15816 + CVMX_ADD_IO_SEG(0x0001180050001018ull)
15817 +#define CVMX_PKO_MEM_PORT_RATE0 \
15818 + CVMX_ADD_IO_SEG(0x0001180050001020ull)
15819 +#define CVMX_PKO_MEM_PORT_RATE1 \
15820 + CVMX_ADD_IO_SEG(0x0001180050001028ull)
15821 +#define CVMX_PKO_MEM_QUEUE_PTRS \
15822 + CVMX_ADD_IO_SEG(0x0001180050001000ull)
15823 +#define CVMX_PKO_MEM_QUEUE_QOS \
15824 + CVMX_ADD_IO_SEG(0x0001180050001008ull)
15825 +#define CVMX_PKO_REG_BIST_RESULT \
15826 + CVMX_ADD_IO_SEG(0x0001180050000080ull)
15827 +#define CVMX_PKO_REG_CMD_BUF \
15828 + CVMX_ADD_IO_SEG(0x0001180050000010ull)
15829 +#define CVMX_PKO_REG_CRC_CTLX(offset) \
15830 + CVMX_ADD_IO_SEG(0x0001180050000028ull + (((offset) & 1) * 8))
15831 +#define CVMX_PKO_REG_CRC_ENABLE \
15832 + CVMX_ADD_IO_SEG(0x0001180050000020ull)
15833 +#define CVMX_PKO_REG_CRC_IVX(offset) \
15834 + CVMX_ADD_IO_SEG(0x0001180050000038ull + (((offset) & 1) * 8))
15835 +#define CVMX_PKO_REG_DEBUG0 \
15836 + CVMX_ADD_IO_SEG(0x0001180050000098ull)
15837 +#define CVMX_PKO_REG_DEBUG1 \
15838 + CVMX_ADD_IO_SEG(0x00011800500000A0ull)
15839 +#define CVMX_PKO_REG_DEBUG2 \
15840 + CVMX_ADD_IO_SEG(0x00011800500000A8ull)
15841 +#define CVMX_PKO_REG_DEBUG3 \
15842 + CVMX_ADD_IO_SEG(0x00011800500000B0ull)
15843 +#define CVMX_PKO_REG_ENGINE_INFLIGHT \
15844 + CVMX_ADD_IO_SEG(0x0001180050000050ull)
15845 +#define CVMX_PKO_REG_ENGINE_THRESH \
15846 + CVMX_ADD_IO_SEG(0x0001180050000058ull)
15847 +#define CVMX_PKO_REG_ERROR \
15848 + CVMX_ADD_IO_SEG(0x0001180050000088ull)
15849 +#define CVMX_PKO_REG_FLAGS \
15850 + CVMX_ADD_IO_SEG(0x0001180050000000ull)
15851 +#define CVMX_PKO_REG_GMX_PORT_MODE \
15852 + CVMX_ADD_IO_SEG(0x0001180050000018ull)
15853 +#define CVMX_PKO_REG_INT_MASK \
15854 + CVMX_ADD_IO_SEG(0x0001180050000090ull)
15855 +#define CVMX_PKO_REG_QUEUE_MODE \
15856 + CVMX_ADD_IO_SEG(0x0001180050000048ull)
15857 +#define CVMX_PKO_REG_QUEUE_PTRS1 \
15858 + CVMX_ADD_IO_SEG(0x0001180050000100ull)
15859 +#define CVMX_PKO_REG_READ_IDX \
15860 + CVMX_ADD_IO_SEG(0x0001180050000008ull)
15861 +
15862 +union cvmx_pko_mem_count0 {
15863 + uint64_t u64;
15864 + struct cvmx_pko_mem_count0_s {
15865 + uint64_t reserved_32_63:32;
15866 + uint64_t count:32;
15867 + } s;
15868 + struct cvmx_pko_mem_count0_s cn30xx;
15869 + struct cvmx_pko_mem_count0_s cn31xx;
15870 + struct cvmx_pko_mem_count0_s cn38xx;
15871 + struct cvmx_pko_mem_count0_s cn38xxp2;
15872 + struct cvmx_pko_mem_count0_s cn50xx;
15873 + struct cvmx_pko_mem_count0_s cn52xx;
15874 + struct cvmx_pko_mem_count0_s cn52xxp1;
15875 + struct cvmx_pko_mem_count0_s cn56xx;
15876 + struct cvmx_pko_mem_count0_s cn56xxp1;
15877 + struct cvmx_pko_mem_count0_s cn58xx;
15878 + struct cvmx_pko_mem_count0_s cn58xxp1;
15879 +};
15880 +
15881 +union cvmx_pko_mem_count1 {
15882 + uint64_t u64;
15883 + struct cvmx_pko_mem_count1_s {
15884 + uint64_t reserved_48_63:16;
15885 + uint64_t count:48;
15886 + } s;
15887 + struct cvmx_pko_mem_count1_s cn30xx;
15888 + struct cvmx_pko_mem_count1_s cn31xx;
15889 + struct cvmx_pko_mem_count1_s cn38xx;
15890 + struct cvmx_pko_mem_count1_s cn38xxp2;
15891 + struct cvmx_pko_mem_count1_s cn50xx;
15892 + struct cvmx_pko_mem_count1_s cn52xx;
15893 + struct cvmx_pko_mem_count1_s cn52xxp1;
15894 + struct cvmx_pko_mem_count1_s cn56xx;
15895 + struct cvmx_pko_mem_count1_s cn56xxp1;
15896 + struct cvmx_pko_mem_count1_s cn58xx;
15897 + struct cvmx_pko_mem_count1_s cn58xxp1;
15898 +};
15899 +
15900 +union cvmx_pko_mem_debug0 {
15901 + uint64_t u64;
15902 + struct cvmx_pko_mem_debug0_s {
15903 + uint64_t fau:28;
15904 + uint64_t cmd:14;
15905 + uint64_t segs:6;
15906 + uint64_t size:16;
15907 + } s;
15908 + struct cvmx_pko_mem_debug0_s cn30xx;
15909 + struct cvmx_pko_mem_debug0_s cn31xx;
15910 + struct cvmx_pko_mem_debug0_s cn38xx;
15911 + struct cvmx_pko_mem_debug0_s cn38xxp2;
15912 + struct cvmx_pko_mem_debug0_s cn50xx;
15913 + struct cvmx_pko_mem_debug0_s cn52xx;
15914 + struct cvmx_pko_mem_debug0_s cn52xxp1;
15915 + struct cvmx_pko_mem_debug0_s cn56xx;
15916 + struct cvmx_pko_mem_debug0_s cn56xxp1;
15917 + struct cvmx_pko_mem_debug0_s cn58xx;
15918 + struct cvmx_pko_mem_debug0_s cn58xxp1;
15919 +};
15920 +
15921 +union cvmx_pko_mem_debug1 {
15922 + uint64_t u64;
15923 + struct cvmx_pko_mem_debug1_s {
15924 + uint64_t i:1;
15925 + uint64_t back:4;
15926 + uint64_t pool:3;
15927 + uint64_t size:16;
15928 + uint64_t ptr:40;
15929 + } s;
15930 + struct cvmx_pko_mem_debug1_s cn30xx;
15931 + struct cvmx_pko_mem_debug1_s cn31xx;
15932 + struct cvmx_pko_mem_debug1_s cn38xx;
15933 + struct cvmx_pko_mem_debug1_s cn38xxp2;
15934 + struct cvmx_pko_mem_debug1_s cn50xx;
15935 + struct cvmx_pko_mem_debug1_s cn52xx;
15936 + struct cvmx_pko_mem_debug1_s cn52xxp1;
15937 + struct cvmx_pko_mem_debug1_s cn56xx;
15938 + struct cvmx_pko_mem_debug1_s cn56xxp1;
15939 + struct cvmx_pko_mem_debug1_s cn58xx;
15940 + struct cvmx_pko_mem_debug1_s cn58xxp1;
15941 +};
15942 +
15943 +union cvmx_pko_mem_debug10 {
15944 + uint64_t u64;
15945 + struct cvmx_pko_mem_debug10_s {
15946 + uint64_t reserved_0_63:64;
15947 + } s;
15948 + struct cvmx_pko_mem_debug10_cn30xx {
15949 + uint64_t fau:28;
15950 + uint64_t cmd:14;
15951 + uint64_t segs:6;
15952 + uint64_t size:16;
15953 + } cn30xx;
15954 + struct cvmx_pko_mem_debug10_cn30xx cn31xx;
15955 + struct cvmx_pko_mem_debug10_cn30xx cn38xx;
15956 + struct cvmx_pko_mem_debug10_cn30xx cn38xxp2;
15957 + struct cvmx_pko_mem_debug10_cn50xx {
15958 + uint64_t reserved_49_63:15;
15959 + uint64_t ptrs1:17;
15960 + uint64_t reserved_17_31:15;
15961 + uint64_t ptrs2:17;
15962 + } cn50xx;
15963 + struct cvmx_pko_mem_debug10_cn50xx cn52xx;
15964 + struct cvmx_pko_mem_debug10_cn50xx cn52xxp1;
15965 + struct cvmx_pko_mem_debug10_cn50xx cn56xx;
15966 + struct cvmx_pko_mem_debug10_cn50xx cn56xxp1;
15967 + struct cvmx_pko_mem_debug10_cn50xx cn58xx;
15968 + struct cvmx_pko_mem_debug10_cn50xx cn58xxp1;
15969 +};
15970 +
15971 +union cvmx_pko_mem_debug11 {
15972 + uint64_t u64;
15973 + struct cvmx_pko_mem_debug11_s {
15974 + uint64_t i:1;
15975 + uint64_t back:4;
15976 + uint64_t pool:3;
15977 + uint64_t size:16;
15978 + uint64_t reserved_0_39:40;
15979 + } s;
15980 + struct cvmx_pko_mem_debug11_cn30xx {
15981 + uint64_t i:1;
15982 + uint64_t back:4;
15983 + uint64_t pool:3;
15984 + uint64_t size:16;
15985 + uint64_t ptr:40;
15986 + } cn30xx;
15987 + struct cvmx_pko_mem_debug11_cn30xx cn31xx;
15988 + struct cvmx_pko_mem_debug11_cn30xx cn38xx;
15989 + struct cvmx_pko_mem_debug11_cn30xx cn38xxp2;
15990 + struct cvmx_pko_mem_debug11_cn50xx {
15991 + uint64_t reserved_23_63:41;
15992 + uint64_t maj:1;
15993 + uint64_t uid:3;
15994 + uint64_t sop:1;
15995 + uint64_t len:1;
15996 + uint64_t chk:1;
15997 + uint64_t cnt:13;
15998 + uint64_t mod:3;
15999 + } cn50xx;
16000 + struct cvmx_pko_mem_debug11_cn50xx cn52xx;
16001 + struct cvmx_pko_mem_debug11_cn50xx cn52xxp1;
16002 + struct cvmx_pko_mem_debug11_cn50xx cn56xx;
16003 + struct cvmx_pko_mem_debug11_cn50xx cn56xxp1;
16004 + struct cvmx_pko_mem_debug11_cn50xx cn58xx;
16005 + struct cvmx_pko_mem_debug11_cn50xx cn58xxp1;
16006 +};
16007 +
16008 +union cvmx_pko_mem_debug12 {
16009 + uint64_t u64;
16010 + struct cvmx_pko_mem_debug12_s {
16011 + uint64_t reserved_0_63:64;
16012 + } s;
16013 + struct cvmx_pko_mem_debug12_cn30xx {
16014 + uint64_t data:64;
16015 + } cn30xx;
16016 + struct cvmx_pko_mem_debug12_cn30xx cn31xx;
16017 + struct cvmx_pko_mem_debug12_cn30xx cn38xx;
16018 + struct cvmx_pko_mem_debug12_cn30xx cn38xxp2;
16019 + struct cvmx_pko_mem_debug12_cn50xx {
16020 + uint64_t fau:28;
16021 + uint64_t cmd:14;
16022 + uint64_t segs:6;
16023 + uint64_t size:16;
16024 + } cn50xx;
16025 + struct cvmx_pko_mem_debug12_cn50xx cn52xx;
16026 + struct cvmx_pko_mem_debug12_cn50xx cn52xxp1;
16027 + struct cvmx_pko_mem_debug12_cn50xx cn56xx;
16028 + struct cvmx_pko_mem_debug12_cn50xx cn56xxp1;
16029 + struct cvmx_pko_mem_debug12_cn50xx cn58xx;
16030 + struct cvmx_pko_mem_debug12_cn50xx cn58xxp1;
16031 +};
16032 +
16033 +union cvmx_pko_mem_debug13 {
16034 + uint64_t u64;
16035 + struct cvmx_pko_mem_debug13_s {
16036 + uint64_t i:1;
16037 + uint64_t back:4;
16038 + uint64_t pool:3;
16039 + uint64_t reserved_0_55:56;
16040 + } s;
16041 + struct cvmx_pko_mem_debug13_cn30xx {
16042 + uint64_t reserved_51_63:13;
16043 + uint64_t widx:17;
16044 + uint64_t ridx2:17;
16045 + uint64_t widx2:17;
16046 + } cn30xx;
16047 + struct cvmx_pko_mem_debug13_cn30xx cn31xx;
16048 + struct cvmx_pko_mem_debug13_cn30xx cn38xx;
16049 + struct cvmx_pko_mem_debug13_cn30xx cn38xxp2;
16050 + struct cvmx_pko_mem_debug13_cn50xx {
16051 + uint64_t i:1;
16052 + uint64_t back:4;
16053 + uint64_t pool:3;
16054 + uint64_t size:16;
16055 + uint64_t ptr:40;
16056 + } cn50xx;
16057 + struct cvmx_pko_mem_debug13_cn50xx cn52xx;
16058 + struct cvmx_pko_mem_debug13_cn50xx cn52xxp1;
16059 + struct cvmx_pko_mem_debug13_cn50xx cn56xx;
16060 + struct cvmx_pko_mem_debug13_cn50xx cn56xxp1;
16061 + struct cvmx_pko_mem_debug13_cn50xx cn58xx;
16062 + struct cvmx_pko_mem_debug13_cn50xx cn58xxp1;
16063 +};
16064 +
16065 +union cvmx_pko_mem_debug14 {
16066 + uint64_t u64;
16067 + struct cvmx_pko_mem_debug14_s {
16068 + uint64_t reserved_0_63:64;
16069 + } s;
16070 + struct cvmx_pko_mem_debug14_cn30xx {
16071 + uint64_t reserved_17_63:47;
16072 + uint64_t ridx:17;
16073 + } cn30xx;
16074 + struct cvmx_pko_mem_debug14_cn30xx cn31xx;
16075 + struct cvmx_pko_mem_debug14_cn30xx cn38xx;
16076 + struct cvmx_pko_mem_debug14_cn30xx cn38xxp2;
16077 + struct cvmx_pko_mem_debug14_cn52xx {
16078 + uint64_t data:64;
16079 + } cn52xx;
16080 + struct cvmx_pko_mem_debug14_cn52xx cn52xxp1;
16081 + struct cvmx_pko_mem_debug14_cn52xx cn56xx;
16082 + struct cvmx_pko_mem_debug14_cn52xx cn56xxp1;
16083 +};
16084 +
16085 +union cvmx_pko_mem_debug2 {
16086 + uint64_t u64;
16087 + struct cvmx_pko_mem_debug2_s {
16088 + uint64_t i:1;
16089 + uint64_t back:4;
16090 + uint64_t pool:3;
16091 + uint64_t size:16;
16092 + uint64_t ptr:40;
16093 + } s;
16094 + struct cvmx_pko_mem_debug2_s cn30xx;
16095 + struct cvmx_pko_mem_debug2_s cn31xx;
16096 + struct cvmx_pko_mem_debug2_s cn38xx;
16097 + struct cvmx_pko_mem_debug2_s cn38xxp2;
16098 + struct cvmx_pko_mem_debug2_s cn50xx;
16099 + struct cvmx_pko_mem_debug2_s cn52xx;
16100 + struct cvmx_pko_mem_debug2_s cn52xxp1;
16101 + struct cvmx_pko_mem_debug2_s cn56xx;
16102 + struct cvmx_pko_mem_debug2_s cn56xxp1;
16103 + struct cvmx_pko_mem_debug2_s cn58xx;
16104 + struct cvmx_pko_mem_debug2_s cn58xxp1;
16105 +};
16106 +
16107 +union cvmx_pko_mem_debug3 {
16108 + uint64_t u64;
16109 + struct cvmx_pko_mem_debug3_s {
16110 + uint64_t reserved_0_63:64;
16111 + } s;
16112 + struct cvmx_pko_mem_debug3_cn30xx {
16113 + uint64_t i:1;
16114 + uint64_t back:4;
16115 + uint64_t pool:3;
16116 + uint64_t size:16;
16117 + uint64_t ptr:40;
16118 + } cn30xx;
16119 + struct cvmx_pko_mem_debug3_cn30xx cn31xx;
16120 + struct cvmx_pko_mem_debug3_cn30xx cn38xx;
16121 + struct cvmx_pko_mem_debug3_cn30xx cn38xxp2;
16122 + struct cvmx_pko_mem_debug3_cn50xx {
16123 + uint64_t data:64;
16124 + } cn50xx;
16125 + struct cvmx_pko_mem_debug3_cn50xx cn52xx;
16126 + struct cvmx_pko_mem_debug3_cn50xx cn52xxp1;
16127 + struct cvmx_pko_mem_debug3_cn50xx cn56xx;
16128 + struct cvmx_pko_mem_debug3_cn50xx cn56xxp1;
16129 + struct cvmx_pko_mem_debug3_cn50xx cn58xx;
16130 + struct cvmx_pko_mem_debug3_cn50xx cn58xxp1;
16131 +};
16132 +
16133 +union cvmx_pko_mem_debug4 {
16134 + uint64_t u64;
16135 + struct cvmx_pko_mem_debug4_s {
16136 + uint64_t reserved_0_63:64;
16137 + } s;
16138 + struct cvmx_pko_mem_debug4_cn30xx {
16139 + uint64_t data:64;
16140 + } cn30xx;
16141 + struct cvmx_pko_mem_debug4_cn30xx cn31xx;
16142 + struct cvmx_pko_mem_debug4_cn30xx cn38xx;
16143 + struct cvmx_pko_mem_debug4_cn30xx cn38xxp2;
16144 + struct cvmx_pko_mem_debug4_cn50xx {
16145 + uint64_t cmnd_segs:3;
16146 + uint64_t cmnd_siz:16;
16147 + uint64_t cmnd_off:6;
16148 + uint64_t uid:3;
16149 + uint64_t dread_sop:1;
16150 + uint64_t init_dwrite:1;
16151 + uint64_t chk_once:1;
16152 + uint64_t chk_mode:1;
16153 + uint64_t active:1;
16154 + uint64_t static_p:1;
16155 + uint64_t qos:3;
16156 + uint64_t qcb_ridx:5;
16157 + uint64_t qid_off_max:4;
16158 + uint64_t qid_off:4;
16159 + uint64_t qid_base:8;
16160 + uint64_t wait:1;
16161 + uint64_t minor:2;
16162 + uint64_t major:3;
16163 + } cn50xx;
16164 + struct cvmx_pko_mem_debug4_cn52xx {
16165 + uint64_t curr_siz:8;
16166 + uint64_t curr_off:16;
16167 + uint64_t cmnd_segs:6;
16168 + uint64_t cmnd_siz:16;
16169 + uint64_t cmnd_off:6;
16170 + uint64_t uid:2;
16171 + uint64_t dread_sop:1;
16172 + uint64_t init_dwrite:1;
16173 + uint64_t chk_once:1;
16174 + uint64_t chk_mode:1;
16175 + uint64_t wait:1;
16176 + uint64_t minor:2;
16177 + uint64_t major:3;
16178 + } cn52xx;
16179 + struct cvmx_pko_mem_debug4_cn52xx cn52xxp1;
16180 + struct cvmx_pko_mem_debug4_cn52xx cn56xx;
16181 + struct cvmx_pko_mem_debug4_cn52xx cn56xxp1;
16182 + struct cvmx_pko_mem_debug4_cn50xx cn58xx;
16183 + struct cvmx_pko_mem_debug4_cn50xx cn58xxp1;
16184 +};
16185 +
16186 +union cvmx_pko_mem_debug5 {
16187 + uint64_t u64;
16188 + struct cvmx_pko_mem_debug5_s {
16189 + uint64_t reserved_0_63:64;
16190 + } s;
16191 + struct cvmx_pko_mem_debug5_cn30xx {
16192 + uint64_t dwri_mod:1;
16193 + uint64_t dwri_sop:1;
16194 + uint64_t dwri_len:1;
16195 + uint64_t dwri_cnt:13;
16196 + uint64_t cmnd_siz:16;
16197 + uint64_t uid:1;
16198 + uint64_t xfer_wor:1;
16199 + uint64_t xfer_dwr:1;
16200 + uint64_t cbuf_fre:1;
16201 + uint64_t reserved_27_27:1;
16202 + uint64_t chk_mode:1;
16203 + uint64_t active:1;
16204 + uint64_t qos:3;
16205 + uint64_t qcb_ridx:5;
16206 + uint64_t qid_off:3;
16207 + uint64_t qid_base:7;
16208 + uint64_t wait:1;
16209 + uint64_t minor:2;
16210 + uint64_t major:4;
16211 + } cn30xx;
16212 + struct cvmx_pko_mem_debug5_cn30xx cn31xx;
16213 + struct cvmx_pko_mem_debug5_cn30xx cn38xx;
16214 + struct cvmx_pko_mem_debug5_cn30xx cn38xxp2;
16215 + struct cvmx_pko_mem_debug5_cn50xx {
16216 + uint64_t curr_ptr:29;
16217 + uint64_t curr_siz:16;
16218 + uint64_t curr_off:16;
16219 + uint64_t cmnd_segs:3;
16220 + } cn50xx;
16221 + struct cvmx_pko_mem_debug5_cn52xx {
16222 + uint64_t reserved_54_63:10;
16223 + uint64_t nxt_inflt:6;
16224 + uint64_t curr_ptr:40;
16225 + uint64_t curr_siz:8;
16226 + } cn52xx;
16227 + struct cvmx_pko_mem_debug5_cn52xx cn52xxp1;
16228 + struct cvmx_pko_mem_debug5_cn52xx cn56xx;
16229 + struct cvmx_pko_mem_debug5_cn52xx cn56xxp1;
16230 + struct cvmx_pko_mem_debug5_cn50xx cn58xx;
16231 + struct cvmx_pko_mem_debug5_cn50xx cn58xxp1;
16232 +};
16233 +
16234 +union cvmx_pko_mem_debug6 {
16235 + uint64_t u64;
16236 + struct cvmx_pko_mem_debug6_s {
16237 + uint64_t reserved_37_63:27;
16238 + uint64_t qid_offres:4;
16239 + uint64_t qid_offths:4;
16240 + uint64_t preempter:1;
16241 + uint64_t preemptee:1;
16242 + uint64_t preempted:1;
16243 + uint64_t active:1;
16244 + uint64_t statc:1;
16245 + uint64_t qos:3;
16246 + uint64_t qcb_ridx:5;
16247 + uint64_t qid_offmax:4;
16248 + uint64_t reserved_0_11:12;
16249 + } s;
16250 + struct cvmx_pko_mem_debug6_cn30xx {
16251 + uint64_t reserved_11_63:53;
16252 + uint64_t qid_offm:3;
16253 + uint64_t static_p:1;
16254 + uint64_t work_min:3;
16255 + uint64_t dwri_chk:1;
16256 + uint64_t dwri_uid:1;
16257 + uint64_t dwri_mod:2;
16258 + } cn30xx;
16259 + struct cvmx_pko_mem_debug6_cn30xx cn31xx;
16260 + struct cvmx_pko_mem_debug6_cn30xx cn38xx;
16261 + struct cvmx_pko_mem_debug6_cn30xx cn38xxp2;
16262 + struct cvmx_pko_mem_debug6_cn50xx {
16263 + uint64_t reserved_11_63:53;
16264 + uint64_t curr_ptr:11;
16265 + } cn50xx;
16266 + struct cvmx_pko_mem_debug6_cn52xx {
16267 + uint64_t reserved_37_63:27;
16268 + uint64_t qid_offres:4;
16269 + uint64_t qid_offths:4;
16270 + uint64_t preempter:1;
16271 + uint64_t preemptee:1;
16272 + uint64_t preempted:1;
16273 + uint64_t active:1;
16274 + uint64_t statc:1;
16275 + uint64_t qos:3;
16276 + uint64_t qcb_ridx:5;
16277 + uint64_t qid_offmax:4;
16278 + uint64_t qid_off:4;
16279 + uint64_t qid_base:8;
16280 + } cn52xx;
16281 + struct cvmx_pko_mem_debug6_cn52xx cn52xxp1;
16282 + struct cvmx_pko_mem_debug6_cn52xx cn56xx;
16283 + struct cvmx_pko_mem_debug6_cn52xx cn56xxp1;
16284 + struct cvmx_pko_mem_debug6_cn50xx cn58xx;
16285 + struct cvmx_pko_mem_debug6_cn50xx cn58xxp1;
16286 +};
16287 +
16288 +union cvmx_pko_mem_debug7 {
16289 + uint64_t u64;
16290 + struct cvmx_pko_mem_debug7_s {
16291 + uint64_t qos:5;
16292 + uint64_t tail:1;
16293 + uint64_t reserved_0_57:58;
16294 + } s;
16295 + struct cvmx_pko_mem_debug7_cn30xx {
16296 + uint64_t reserved_58_63:6;
16297 + uint64_t dwb:9;
16298 + uint64_t start:33;
16299 + uint64_t size:16;
16300 + } cn30xx;
16301 + struct cvmx_pko_mem_debug7_cn30xx cn31xx;
16302 + struct cvmx_pko_mem_debug7_cn30xx cn38xx;
16303 + struct cvmx_pko_mem_debug7_cn30xx cn38xxp2;
16304 + struct cvmx_pko_mem_debug7_cn50xx {
16305 + uint64_t qos:5;
16306 + uint64_t tail:1;
16307 + uint64_t buf_siz:13;
16308 + uint64_t buf_ptr:33;
16309 + uint64_t qcb_widx:6;
16310 + uint64_t qcb_ridx:6;
16311 + } cn50xx;
16312 + struct cvmx_pko_mem_debug7_cn50xx cn52xx;
16313 + struct cvmx_pko_mem_debug7_cn50xx cn52xxp1;
16314 + struct cvmx_pko_mem_debug7_cn50xx cn56xx;
16315 + struct cvmx_pko_mem_debug7_cn50xx cn56xxp1;
16316 + struct cvmx_pko_mem_debug7_cn50xx cn58xx;
16317 + struct cvmx_pko_mem_debug7_cn50xx cn58xxp1;
16318 +};
16319 +
16320 +union cvmx_pko_mem_debug8 {
16321 + uint64_t u64;
16322 + struct cvmx_pko_mem_debug8_s {
16323 + uint64_t reserved_59_63:5;
16324 + uint64_t tail:1;
16325 + uint64_t buf_siz:13;
16326 + uint64_t reserved_0_44:45;
16327 + } s;
16328 + struct cvmx_pko_mem_debug8_cn30xx {
16329 + uint64_t qos:5;
16330 + uint64_t tail:1;
16331 + uint64_t buf_siz:13;
16332 + uint64_t buf_ptr:33;
16333 + uint64_t qcb_widx:6;
16334 + uint64_t qcb_ridx:6;
16335 + } cn30xx;
16336 + struct cvmx_pko_mem_debug8_cn30xx cn31xx;
16337 + struct cvmx_pko_mem_debug8_cn30xx cn38xx;
16338 + struct cvmx_pko_mem_debug8_cn30xx cn38xxp2;
16339 + struct cvmx_pko_mem_debug8_cn50xx {
16340 + uint64_t reserved_28_63:36;
16341 + uint64_t doorbell:20;
16342 + uint64_t reserved_6_7:2;
16343 + uint64_t static_p:1;
16344 + uint64_t s_tail:1;
16345 + uint64_t static_q:1;
16346 + uint64_t qos:3;
16347 + } cn50xx;
16348 + struct cvmx_pko_mem_debug8_cn52xx {
16349 + uint64_t reserved_29_63:35;
16350 + uint64_t preempter:1;
16351 + uint64_t doorbell:20;
16352 + uint64_t reserved_7_7:1;
16353 + uint64_t preemptee:1;
16354 + uint64_t static_p:1;
16355 + uint64_t s_tail:1;
16356 + uint64_t static_q:1;
16357 + uint64_t qos:3;
16358 + } cn52xx;
16359 + struct cvmx_pko_mem_debug8_cn52xx cn52xxp1;
16360 + struct cvmx_pko_mem_debug8_cn52xx cn56xx;
16361 + struct cvmx_pko_mem_debug8_cn52xx cn56xxp1;
16362 + struct cvmx_pko_mem_debug8_cn50xx cn58xx;
16363 + struct cvmx_pko_mem_debug8_cn50xx cn58xxp1;
16364 +};
16365 +
16366 +union cvmx_pko_mem_debug9 {
16367 + uint64_t u64;
16368 + struct cvmx_pko_mem_debug9_s {
16369 + uint64_t reserved_49_63:15;
16370 + uint64_t ptrs0:17;
16371 + uint64_t reserved_0_31:32;
16372 + } s;
16373 + struct cvmx_pko_mem_debug9_cn30xx {
16374 + uint64_t reserved_28_63:36;
16375 + uint64_t doorbell:20;
16376 + uint64_t reserved_5_7:3;
16377 + uint64_t s_tail:1;
16378 + uint64_t static_q:1;
16379 + uint64_t qos:3;
16380 + } cn30xx;
16381 + struct cvmx_pko_mem_debug9_cn30xx cn31xx;
16382 + struct cvmx_pko_mem_debug9_cn38xx {
16383 + uint64_t reserved_28_63:36;
16384 + uint64_t doorbell:20;
16385 + uint64_t reserved_6_7:2;
16386 + uint64_t static_p:1;
16387 + uint64_t s_tail:1;
16388 + uint64_t static_q:1;
16389 + uint64_t qos:3;
16390 + } cn38xx;
16391 + struct cvmx_pko_mem_debug9_cn38xx cn38xxp2;
16392 + struct cvmx_pko_mem_debug9_cn50xx {
16393 + uint64_t reserved_49_63:15;
16394 + uint64_t ptrs0:17;
16395 + uint64_t reserved_17_31:15;
16396 + uint64_t ptrs3:17;
16397 + } cn50xx;
16398 + struct cvmx_pko_mem_debug9_cn50xx cn52xx;
16399 + struct cvmx_pko_mem_debug9_cn50xx cn52xxp1;
16400 + struct cvmx_pko_mem_debug9_cn50xx cn56xx;
16401 + struct cvmx_pko_mem_debug9_cn50xx cn56xxp1;
16402 + struct cvmx_pko_mem_debug9_cn50xx cn58xx;
16403 + struct cvmx_pko_mem_debug9_cn50xx cn58xxp1;
16404 +};
16405 +
16406 +union cvmx_pko_mem_port_ptrs {
16407 + uint64_t u64;
16408 + struct cvmx_pko_mem_port_ptrs_s {
16409 + uint64_t reserved_62_63:2;
16410 + uint64_t static_p:1;
16411 + uint64_t qos_mask:8;
16412 + uint64_t reserved_16_52:37;
16413 + uint64_t bp_port:6;
16414 + uint64_t eid:4;
16415 + uint64_t pid:6;
16416 + } s;
16417 + struct cvmx_pko_mem_port_ptrs_s cn52xx;
16418 + struct cvmx_pko_mem_port_ptrs_s cn52xxp1;
16419 + struct cvmx_pko_mem_port_ptrs_s cn56xx;
16420 + struct cvmx_pko_mem_port_ptrs_s cn56xxp1;
16421 +};
16422 +
16423 +union cvmx_pko_mem_port_qos {
16424 + uint64_t u64;
16425 + struct cvmx_pko_mem_port_qos_s {
16426 + uint64_t reserved_61_63:3;
16427 + uint64_t qos_mask:8;
16428 + uint64_t reserved_10_52:43;
16429 + uint64_t eid:4;
16430 + uint64_t pid:6;
16431 + } s;
16432 + struct cvmx_pko_mem_port_qos_s cn52xx;
16433 + struct cvmx_pko_mem_port_qos_s cn52xxp1;
16434 + struct cvmx_pko_mem_port_qos_s cn56xx;
16435 + struct cvmx_pko_mem_port_qos_s cn56xxp1;
16436 +};
16437 +
16438 +union cvmx_pko_mem_port_rate0 {
16439 + uint64_t u64;
16440 + struct cvmx_pko_mem_port_rate0_s {
16441 + uint64_t reserved_51_63:13;
16442 + uint64_t rate_word:19;
16443 + uint64_t rate_pkt:24;
16444 + uint64_t reserved_6_7:2;
16445 + uint64_t pid:6;
16446 + } s;
16447 + struct cvmx_pko_mem_port_rate0_s cn52xx;
16448 + struct cvmx_pko_mem_port_rate0_s cn52xxp1;
16449 + struct cvmx_pko_mem_port_rate0_s cn56xx;
16450 + struct cvmx_pko_mem_port_rate0_s cn56xxp1;
16451 +};
16452 +
16453 +union cvmx_pko_mem_port_rate1 {
16454 + uint64_t u64;
16455 + struct cvmx_pko_mem_port_rate1_s {
16456 + uint64_t reserved_32_63:32;
16457 + uint64_t rate_lim:24;
16458 + uint64_t reserved_6_7:2;
16459 + uint64_t pid:6;
16460 + } s;
16461 + struct cvmx_pko_mem_port_rate1_s cn52xx;
16462 + struct cvmx_pko_mem_port_rate1_s cn52xxp1;
16463 + struct cvmx_pko_mem_port_rate1_s cn56xx;
16464 + struct cvmx_pko_mem_port_rate1_s cn56xxp1;
16465 +};
16466 +
16467 +union cvmx_pko_mem_queue_ptrs {
16468 + uint64_t u64;
16469 + struct cvmx_pko_mem_queue_ptrs_s {
16470 + uint64_t s_tail:1;
16471 + uint64_t static_p:1;
16472 + uint64_t static_q:1;
16473 + uint64_t qos_mask:8;
16474 + uint64_t buf_ptr:36;
16475 + uint64_t tail:1;
16476 + uint64_t index:3;
16477 + uint64_t port:6;
16478 + uint64_t queue:7;
16479 + } s;
16480 + struct cvmx_pko_mem_queue_ptrs_s cn30xx;
16481 + struct cvmx_pko_mem_queue_ptrs_s cn31xx;
16482 + struct cvmx_pko_mem_queue_ptrs_s cn38xx;
16483 + struct cvmx_pko_mem_queue_ptrs_s cn38xxp2;
16484 + struct cvmx_pko_mem_queue_ptrs_s cn50xx;
16485 + struct cvmx_pko_mem_queue_ptrs_s cn52xx;
16486 + struct cvmx_pko_mem_queue_ptrs_s cn52xxp1;
16487 + struct cvmx_pko_mem_queue_ptrs_s cn56xx;
16488 + struct cvmx_pko_mem_queue_ptrs_s cn56xxp1;
16489 + struct cvmx_pko_mem_queue_ptrs_s cn58xx;
16490 + struct cvmx_pko_mem_queue_ptrs_s cn58xxp1;
16491 +};
16492 +
16493 +union cvmx_pko_mem_queue_qos {
16494 + uint64_t u64;
16495 + struct cvmx_pko_mem_queue_qos_s {
16496 + uint64_t reserved_61_63:3;
16497 + uint64_t qos_mask:8;
16498 + uint64_t reserved_13_52:40;
16499 + uint64_t pid:6;
16500 + uint64_t qid:7;
16501 + } s;
16502 + struct cvmx_pko_mem_queue_qos_s cn30xx;
16503 + struct cvmx_pko_mem_queue_qos_s cn31xx;
16504 + struct cvmx_pko_mem_queue_qos_s cn38xx;
16505 + struct cvmx_pko_mem_queue_qos_s cn38xxp2;
16506 + struct cvmx_pko_mem_queue_qos_s cn50xx;
16507 + struct cvmx_pko_mem_queue_qos_s cn52xx;
16508 + struct cvmx_pko_mem_queue_qos_s cn52xxp1;
16509 + struct cvmx_pko_mem_queue_qos_s cn56xx;
16510 + struct cvmx_pko_mem_queue_qos_s cn56xxp1;
16511 + struct cvmx_pko_mem_queue_qos_s cn58xx;
16512 + struct cvmx_pko_mem_queue_qos_s cn58xxp1;
16513 +};
16514 +
16515 +union cvmx_pko_reg_bist_result {
16516 + uint64_t u64;
16517 + struct cvmx_pko_reg_bist_result_s {
16518 + uint64_t reserved_0_63:64;
16519 + } s;
16520 + struct cvmx_pko_reg_bist_result_cn30xx {
16521 + uint64_t reserved_27_63:37;
16522 + uint64_t psb2:5;
16523 + uint64_t count:1;
16524 + uint64_t rif:1;
16525 + uint64_t wif:1;
16526 + uint64_t ncb:1;
16527 + uint64_t out:1;
16528 + uint64_t crc:1;
16529 + uint64_t chk:1;
16530 + uint64_t qsb:2;
16531 + uint64_t qcb:2;
16532 + uint64_t pdb:4;
16533 + uint64_t psb:7;
16534 + } cn30xx;
16535 + struct cvmx_pko_reg_bist_result_cn30xx cn31xx;
16536 + struct cvmx_pko_reg_bist_result_cn30xx cn38xx;
16537 + struct cvmx_pko_reg_bist_result_cn30xx cn38xxp2;
16538 + struct cvmx_pko_reg_bist_result_cn50xx {
16539 + uint64_t reserved_33_63:31;
16540 + uint64_t csr:1;
16541 + uint64_t iob:1;
16542 + uint64_t out_crc:1;
16543 + uint64_t out_ctl:3;
16544 + uint64_t out_sta:1;
16545 + uint64_t out_wif:1;
16546 + uint64_t prt_chk:3;
16547 + uint64_t prt_nxt:1;
16548 + uint64_t prt_psb:6;
16549 + uint64_t ncb_inb:2;
16550 + uint64_t prt_qcb:2;
16551 + uint64_t prt_qsb:3;
16552 + uint64_t dat_dat:4;
16553 + uint64_t dat_ptr:4;
16554 + } cn50xx;
16555 + struct cvmx_pko_reg_bist_result_cn52xx {
16556 + uint64_t reserved_35_63:29;
16557 + uint64_t csr:1;
16558 + uint64_t iob:1;
16559 + uint64_t out_dat:1;
16560 + uint64_t out_ctl:3;
16561 + uint64_t out_sta:1;
16562 + uint64_t out_wif:1;
16563 + uint64_t prt_chk:3;
16564 + uint64_t prt_nxt:1;
16565 + uint64_t prt_psb:8;
16566 + uint64_t ncb_inb:2;
16567 + uint64_t prt_qcb:2;
16568 + uint64_t prt_qsb:3;
16569 + uint64_t prt_ctl:2;
16570 + uint64_t dat_dat:2;
16571 + uint64_t dat_ptr:4;
16572 + } cn52xx;
16573 + struct cvmx_pko_reg_bist_result_cn52xx cn52xxp1;
16574 + struct cvmx_pko_reg_bist_result_cn52xx cn56xx;
16575 + struct cvmx_pko_reg_bist_result_cn52xx cn56xxp1;
16576 + struct cvmx_pko_reg_bist_result_cn50xx cn58xx;
16577 + struct cvmx_pko_reg_bist_result_cn50xx cn58xxp1;
16578 +};
16579 +
16580 +union cvmx_pko_reg_cmd_buf {
16581 + uint64_t u64;
16582 + struct cvmx_pko_reg_cmd_buf_s {
16583 + uint64_t reserved_23_63:41;
16584 + uint64_t pool:3;
16585 + uint64_t reserved_13_19:7;
16586 + uint64_t size:13;
16587 + } s;
16588 + struct cvmx_pko_reg_cmd_buf_s cn30xx;
16589 + struct cvmx_pko_reg_cmd_buf_s cn31xx;
16590 + struct cvmx_pko_reg_cmd_buf_s cn38xx;
16591 + struct cvmx_pko_reg_cmd_buf_s cn38xxp2;
16592 + struct cvmx_pko_reg_cmd_buf_s cn50xx;
16593 + struct cvmx_pko_reg_cmd_buf_s cn52xx;
16594 + struct cvmx_pko_reg_cmd_buf_s cn52xxp1;
16595 + struct cvmx_pko_reg_cmd_buf_s cn56xx;
16596 + struct cvmx_pko_reg_cmd_buf_s cn56xxp1;
16597 + struct cvmx_pko_reg_cmd_buf_s cn58xx;
16598 + struct cvmx_pko_reg_cmd_buf_s cn58xxp1;
16599 +};
16600 +
16601 +union cvmx_pko_reg_crc_ctlx {
16602 + uint64_t u64;
16603 + struct cvmx_pko_reg_crc_ctlx_s {
16604 + uint64_t reserved_2_63:62;
16605 + uint64_t invres:1;
16606 + uint64_t refin:1;
16607 + } s;
16608 + struct cvmx_pko_reg_crc_ctlx_s cn38xx;
16609 + struct cvmx_pko_reg_crc_ctlx_s cn38xxp2;
16610 + struct cvmx_pko_reg_crc_ctlx_s cn58xx;
16611 + struct cvmx_pko_reg_crc_ctlx_s cn58xxp1;
16612 +};
16613 +
16614 +union cvmx_pko_reg_crc_enable {
16615 + uint64_t u64;
16616 + struct cvmx_pko_reg_crc_enable_s {
16617 + uint64_t reserved_32_63:32;
16618 + uint64_t enable:32;
16619 + } s;
16620 + struct cvmx_pko_reg_crc_enable_s cn38xx;
16621 + struct cvmx_pko_reg_crc_enable_s cn38xxp2;
16622 + struct cvmx_pko_reg_crc_enable_s cn58xx;
16623 + struct cvmx_pko_reg_crc_enable_s cn58xxp1;
16624 +};
16625 +
16626 +union cvmx_pko_reg_crc_ivx {
16627 + uint64_t u64;
16628 + struct cvmx_pko_reg_crc_ivx_s {
16629 + uint64_t reserved_32_63:32;
16630 + uint64_t iv:32;
16631 + } s;
16632 + struct cvmx_pko_reg_crc_ivx_s cn38xx;
16633 + struct cvmx_pko_reg_crc_ivx_s cn38xxp2;
16634 + struct cvmx_pko_reg_crc_ivx_s cn58xx;
16635 + struct cvmx_pko_reg_crc_ivx_s cn58xxp1;
16636 +};
16637 +
16638 +union cvmx_pko_reg_debug0 {
16639 + uint64_t u64;
16640 + struct cvmx_pko_reg_debug0_s {
16641 + uint64_t asserts:64;
16642 + } s;
16643 + struct cvmx_pko_reg_debug0_cn30xx {
16644 + uint64_t reserved_17_63:47;
16645 + uint64_t asserts:17;
16646 + } cn30xx;
16647 + struct cvmx_pko_reg_debug0_cn30xx cn31xx;
16648 + struct cvmx_pko_reg_debug0_cn30xx cn38xx;
16649 + struct cvmx_pko_reg_debug0_cn30xx cn38xxp2;
16650 + struct cvmx_pko_reg_debug0_s cn50xx;
16651 + struct cvmx_pko_reg_debug0_s cn52xx;
16652 + struct cvmx_pko_reg_debug0_s cn52xxp1;
16653 + struct cvmx_pko_reg_debug0_s cn56xx;
16654 + struct cvmx_pko_reg_debug0_s cn56xxp1;
16655 + struct cvmx_pko_reg_debug0_s cn58xx;
16656 + struct cvmx_pko_reg_debug0_s cn58xxp1;
16657 +};
16658 +
16659 +union cvmx_pko_reg_debug1 {
16660 + uint64_t u64;
16661 + struct cvmx_pko_reg_debug1_s {
16662 + uint64_t asserts:64;
16663 + } s;
16664 + struct cvmx_pko_reg_debug1_s cn50xx;
16665 + struct cvmx_pko_reg_debug1_s cn52xx;
16666 + struct cvmx_pko_reg_debug1_s cn52xxp1;
16667 + struct cvmx_pko_reg_debug1_s cn56xx;
16668 + struct cvmx_pko_reg_debug1_s cn56xxp1;
16669 + struct cvmx_pko_reg_debug1_s cn58xx;
16670 + struct cvmx_pko_reg_debug1_s cn58xxp1;
16671 +};
16672 +
16673 +union cvmx_pko_reg_debug2 {
16674 + uint64_t u64;
16675 + struct cvmx_pko_reg_debug2_s {
16676 + uint64_t asserts:64;
16677 + } s;
16678 + struct cvmx_pko_reg_debug2_s cn50xx;
16679 + struct cvmx_pko_reg_debug2_s cn52xx;
16680 + struct cvmx_pko_reg_debug2_s cn52xxp1;
16681 + struct cvmx_pko_reg_debug2_s cn56xx;
16682 + struct cvmx_pko_reg_debug2_s cn56xxp1;
16683 + struct cvmx_pko_reg_debug2_s cn58xx;
16684 + struct cvmx_pko_reg_debug2_s cn58xxp1;
16685 +};
16686 +
16687 +union cvmx_pko_reg_debug3 {
16688 + uint64_t u64;
16689 + struct cvmx_pko_reg_debug3_s {
16690 + uint64_t asserts:64;
16691 + } s;
16692 + struct cvmx_pko_reg_debug3_s cn50xx;
16693 + struct cvmx_pko_reg_debug3_s cn52xx;
16694 + struct cvmx_pko_reg_debug3_s cn52xxp1;
16695 + struct cvmx_pko_reg_debug3_s cn56xx;
16696 + struct cvmx_pko_reg_debug3_s cn56xxp1;
16697 + struct cvmx_pko_reg_debug3_s cn58xx;
16698 + struct cvmx_pko_reg_debug3_s cn58xxp1;
16699 +};
16700 +
16701 +union cvmx_pko_reg_engine_inflight {
16702 + uint64_t u64;
16703 + struct cvmx_pko_reg_engine_inflight_s {
16704 + uint64_t reserved_40_63:24;
16705 + uint64_t engine9:4;
16706 + uint64_t engine8:4;
16707 + uint64_t engine7:4;
16708 + uint64_t engine6:4;
16709 + uint64_t engine5:4;
16710 + uint64_t engine4:4;
16711 + uint64_t engine3:4;
16712 + uint64_t engine2:4;
16713 + uint64_t engine1:4;
16714 + uint64_t engine0:4;
16715 + } s;
16716 + struct cvmx_pko_reg_engine_inflight_s cn52xx;
16717 + struct cvmx_pko_reg_engine_inflight_s cn52xxp1;
16718 + struct cvmx_pko_reg_engine_inflight_s cn56xx;
16719 + struct cvmx_pko_reg_engine_inflight_s cn56xxp1;
16720 +};
16721 +
16722 +union cvmx_pko_reg_engine_thresh {
16723 + uint64_t u64;
16724 + struct cvmx_pko_reg_engine_thresh_s {
16725 + uint64_t reserved_10_63:54;
16726 + uint64_t mask:10;
16727 + } s;
16728 + struct cvmx_pko_reg_engine_thresh_s cn52xx;
16729 + struct cvmx_pko_reg_engine_thresh_s cn52xxp1;
16730 + struct cvmx_pko_reg_engine_thresh_s cn56xx;
16731 + struct cvmx_pko_reg_engine_thresh_s cn56xxp1;
16732 +};
16733 +
16734 +union cvmx_pko_reg_error {
16735 + uint64_t u64;
16736 + struct cvmx_pko_reg_error_s {
16737 + uint64_t reserved_3_63:61;
16738 + uint64_t currzero:1;
16739 + uint64_t doorbell:1;
16740 + uint64_t parity:1;
16741 + } s;
16742 + struct cvmx_pko_reg_error_cn30xx {
16743 + uint64_t reserved_2_63:62;
16744 + uint64_t doorbell:1;
16745 + uint64_t parity:1;
16746 + } cn30xx;
16747 + struct cvmx_pko_reg_error_cn30xx cn31xx;
16748 + struct cvmx_pko_reg_error_cn30xx cn38xx;
16749 + struct cvmx_pko_reg_error_cn30xx cn38xxp2;
16750 + struct cvmx_pko_reg_error_s cn50xx;
16751 + struct cvmx_pko_reg_error_s cn52xx;
16752 + struct cvmx_pko_reg_error_s cn52xxp1;
16753 + struct cvmx_pko_reg_error_s cn56xx;
16754 + struct cvmx_pko_reg_error_s cn56xxp1;
16755 + struct cvmx_pko_reg_error_s cn58xx;
16756 + struct cvmx_pko_reg_error_s cn58xxp1;
16757 +};
16758 +
16759 +union cvmx_pko_reg_flags {
16760 + uint64_t u64;
16761 + struct cvmx_pko_reg_flags_s {
16762 + uint64_t reserved_4_63:60;
16763 + uint64_t reset:1;
16764 + uint64_t store_be:1;
16765 + uint64_t ena_dwb:1;
16766 + uint64_t ena_pko:1;
16767 + } s;
16768 + struct cvmx_pko_reg_flags_s cn30xx;
16769 + struct cvmx_pko_reg_flags_s cn31xx;
16770 + struct cvmx_pko_reg_flags_s cn38xx;
16771 + struct cvmx_pko_reg_flags_s cn38xxp2;
16772 + struct cvmx_pko_reg_flags_s cn50xx;
16773 + struct cvmx_pko_reg_flags_s cn52xx;
16774 + struct cvmx_pko_reg_flags_s cn52xxp1;
16775 + struct cvmx_pko_reg_flags_s cn56xx;
16776 + struct cvmx_pko_reg_flags_s cn56xxp1;
16777 + struct cvmx_pko_reg_flags_s cn58xx;
16778 + struct cvmx_pko_reg_flags_s cn58xxp1;
16779 +};
16780 +
16781 +union cvmx_pko_reg_gmx_port_mode {
16782 + uint64_t u64;
16783 + struct cvmx_pko_reg_gmx_port_mode_s {
16784 + uint64_t reserved_6_63:58;
16785 + uint64_t mode1:3;
16786 + uint64_t mode0:3;
16787 + } s;
16788 + struct cvmx_pko_reg_gmx_port_mode_s cn30xx;
16789 + struct cvmx_pko_reg_gmx_port_mode_s cn31xx;
16790 + struct cvmx_pko_reg_gmx_port_mode_s cn38xx;
16791 + struct cvmx_pko_reg_gmx_port_mode_s cn38xxp2;
16792 + struct cvmx_pko_reg_gmx_port_mode_s cn50xx;
16793 + struct cvmx_pko_reg_gmx_port_mode_s cn52xx;
16794 + struct cvmx_pko_reg_gmx_port_mode_s cn52xxp1;
16795 + struct cvmx_pko_reg_gmx_port_mode_s cn56xx;
16796 + struct cvmx_pko_reg_gmx_port_mode_s cn56xxp1;
16797 + struct cvmx_pko_reg_gmx_port_mode_s cn58xx;
16798 + struct cvmx_pko_reg_gmx_port_mode_s cn58xxp1;
16799 +};
16800 +
16801 +union cvmx_pko_reg_int_mask {
16802 + uint64_t u64;
16803 + struct cvmx_pko_reg_int_mask_s {
16804 + uint64_t reserved_3_63:61;
16805 + uint64_t currzero:1;
16806 + uint64_t doorbell:1;
16807 + uint64_t parity:1;
16808 + } s;
16809 + struct cvmx_pko_reg_int_mask_cn30xx {
16810 + uint64_t reserved_2_63:62;
16811 + uint64_t doorbell:1;
16812 + uint64_t parity:1;
16813 + } cn30xx;
16814 + struct cvmx_pko_reg_int_mask_cn30xx cn31xx;
16815 + struct cvmx_pko_reg_int_mask_cn30xx cn38xx;
16816 + struct cvmx_pko_reg_int_mask_cn30xx cn38xxp2;
16817 + struct cvmx_pko_reg_int_mask_s cn50xx;
16818 + struct cvmx_pko_reg_int_mask_s cn52xx;
16819 + struct cvmx_pko_reg_int_mask_s cn52xxp1;
16820 + struct cvmx_pko_reg_int_mask_s cn56xx;
16821 + struct cvmx_pko_reg_int_mask_s cn56xxp1;
16822 + struct cvmx_pko_reg_int_mask_s cn58xx;
16823 + struct cvmx_pko_reg_int_mask_s cn58xxp1;
16824 +};
16825 +
16826 +union cvmx_pko_reg_queue_mode {
16827 + uint64_t u64;
16828 + struct cvmx_pko_reg_queue_mode_s {
16829 + uint64_t reserved_2_63:62;
16830 + uint64_t mode:2;
16831 + } s;
16832 + struct cvmx_pko_reg_queue_mode_s cn30xx;
16833 + struct cvmx_pko_reg_queue_mode_s cn31xx;
16834 + struct cvmx_pko_reg_queue_mode_s cn38xx;
16835 + struct cvmx_pko_reg_queue_mode_s cn38xxp2;
16836 + struct cvmx_pko_reg_queue_mode_s cn50xx;
16837 + struct cvmx_pko_reg_queue_mode_s cn52xx;
16838 + struct cvmx_pko_reg_queue_mode_s cn52xxp1;
16839 + struct cvmx_pko_reg_queue_mode_s cn56xx;
16840 + struct cvmx_pko_reg_queue_mode_s cn56xxp1;
16841 + struct cvmx_pko_reg_queue_mode_s cn58xx;
16842 + struct cvmx_pko_reg_queue_mode_s cn58xxp1;
16843 +};
16844 +
16845 +union cvmx_pko_reg_queue_ptrs1 {
16846 + uint64_t u64;
16847 + struct cvmx_pko_reg_queue_ptrs1_s {
16848 + uint64_t reserved_2_63:62;
16849 + uint64_t idx3:1;
16850 + uint64_t qid7:1;
16851 + } s;
16852 + struct cvmx_pko_reg_queue_ptrs1_s cn50xx;
16853 + struct cvmx_pko_reg_queue_ptrs1_s cn52xx;
16854 + struct cvmx_pko_reg_queue_ptrs1_s cn52xxp1;
16855 + struct cvmx_pko_reg_queue_ptrs1_s cn56xx;
16856 + struct cvmx_pko_reg_queue_ptrs1_s cn56xxp1;
16857 + struct cvmx_pko_reg_queue_ptrs1_s cn58xx;
16858 + struct cvmx_pko_reg_queue_ptrs1_s cn58xxp1;
16859 +};
16860 +
16861 +union cvmx_pko_reg_read_idx {
16862 + uint64_t u64;
16863 + struct cvmx_pko_reg_read_idx_s {
16864 + uint64_t reserved_16_63:48;
16865 + uint64_t inc:8;
16866 + uint64_t index:8;
16867 + } s;
16868 + struct cvmx_pko_reg_read_idx_s cn30xx;
16869 + struct cvmx_pko_reg_read_idx_s cn31xx;
16870 + struct cvmx_pko_reg_read_idx_s cn38xx;
16871 + struct cvmx_pko_reg_read_idx_s cn38xxp2;
16872 + struct cvmx_pko_reg_read_idx_s cn50xx;
16873 + struct cvmx_pko_reg_read_idx_s cn52xx;
16874 + struct cvmx_pko_reg_read_idx_s cn52xxp1;
16875 + struct cvmx_pko_reg_read_idx_s cn56xx;
16876 + struct cvmx_pko_reg_read_idx_s cn56xxp1;
16877 + struct cvmx_pko_reg_read_idx_s cn58xx;
16878 + struct cvmx_pko_reg_read_idx_s cn58xxp1;
16879 +};
16880 +
16881 +#endif
16882 diff --git a/drivers/staging/octeon/cvmx-pko.c b/drivers/staging/octeon/cvmx-pko.c
16883 new file mode 100644
16884 index 0000000..00db915
16885 --- /dev/null
16886 +++ b/drivers/staging/octeon/cvmx-pko.c
16887 @@ -0,0 +1,506 @@
16888 +/***********************license start***************
16889 + * Author: Cavium Networks
16890 + *
16891 + * Contact: support@caviumnetworks.com
16892 + * This file is part of the OCTEON SDK
16893 + *
16894 + * Copyright (c) 2003-2008 Cavium Networks
16895 + *
16896 + * This file is free software; you can redistribute it and/or modify
16897 + * it under the terms of the GNU General Public License, Version 2, as
16898 + * published by the Free Software Foundation.
16899 + *
16900 + * This file is distributed in the hope that it will be useful, but
16901 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
16902 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16903 + * NONINFRINGEMENT. See the GNU General Public License for more
16904 + * details.
16905 + *
16906 + * You should have received a copy of the GNU General Public License
16907 + * along with this file; if not, write to the Free Software
16908 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16909 + * or visit http://www.gnu.org/licenses/.
16910 + *
16911 + * This file may also be available under a different license from Cavium.
16912 + * Contact Cavium Networks for more information
16913 + ***********************license end**************************************/
16914 +
16915 +/*
16916 + * Support library for the hardware Packet Output unit.
16917 + */
16918 +
16919 +#include <asm/octeon/octeon.h>
16920 +
16921 +#include "cvmx-config.h"
16922 +#include "cvmx-pko.h"
16923 +#include "cvmx-helper.h"
16924 +
16925 +/**
16926 + * Internal state of packet output
16927 + */
16928 +
16929 +/**
16930 + * Call before any other calls to initialize the packet
16931 + * output system. This does chip global config, and should only be
16932 + * done by one core.
16933 + */
16934 +
16935 +void cvmx_pko_initialize_global(void)
16936 +{
16937 + int i;
16938 + uint64_t priority = 8;
16939 + union cvmx_pko_reg_cmd_buf config;
16940 +
16941 + /*
16942 + * Set the size of the PKO command buffers to an odd number of
16943 + * 64bit words. This allows the normal two word send to stay
16944 + * aligned and never span a comamnd word buffer.
16945 + */
16946 + config.u64 = 0;
16947 + config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL;
16948 + config.s.size = CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE / 8 - 1;
16949 +
16950 + cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);
16951 +
16952 + for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++)
16953 + cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1,
16954 + &priority);
16955 +
16956 + /*
16957 + * If we aren't using all of the queues optimize PKO's
16958 + * internal memory.
16959 + */
16960 + if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)
16961 + || OCTEON_IS_MODEL(OCTEON_CN56XX)
16962 + || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
16963 + int num_interfaces = cvmx_helper_get_number_of_interfaces();
16964 + int last_port =
16965 + cvmx_helper_get_last_ipd_port(num_interfaces - 1);
16966 + int max_queues =
16967 + cvmx_pko_get_base_queue(last_port) +
16968 + cvmx_pko_get_num_queues(last_port);
16969 + if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
16970 + if (max_queues <= 32)
16971 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
16972 + else if (max_queues <= 64)
16973 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
16974 + } else {
16975 + if (max_queues <= 64)
16976 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
16977 + else if (max_queues <= 128)
16978 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
16979 + }
16980 + }
16981 +}
16982 +
16983 +/**
16984 + * This function does per-core initialization required by the PKO routines.
16985 + * This must be called on all cores that will do packet output, and must
16986 + * be called after the FPA has been initialized and filled with pages.
16987 + *
16988 + * Returns 0 on success
16989 + * !0 on failure
16990 + */
16991 +int cvmx_pko_initialize_local(void)
16992 +{
16993 + /* Nothing to do */
16994 + return 0;
16995 +}
16996 +
16997 +/**
16998 + * Enables the packet output hardware. It must already be
16999 + * configured.
17000 + */
17001 +void cvmx_pko_enable(void)
17002 +{
17003 + union cvmx_pko_reg_flags flags;
17004 +
17005 + flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
17006 + if (flags.s.ena_pko)
17007 + cvmx_dprintf
17008 + ("Warning: Enabling PKO when PKO already enabled.\n");
17009 +
17010 + flags.s.ena_dwb = 1;
17011 + flags.s.ena_pko = 1;
17012 + /*
17013 + * always enable big endian for 3-word command. Does nothing
17014 + * for 2-word.
17015 + */
17016 + flags.s.store_be = 1;
17017 + cvmx_write_csr(CVMX_PKO_REG_FLAGS, flags.u64);
17018 +}
17019 +
17020 +/**
17021 + * Disables the packet output. Does not affect any configuration.
17022 + */
17023 +void cvmx_pko_disable(void)
17024 +{
17025 + union cvmx_pko_reg_flags pko_reg_flags;
17026 + pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
17027 + pko_reg_flags.s.ena_pko = 0;
17028 + cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
17029 +}
17030 +
17031 +
17032 +/**
17033 + * Reset the packet output.
17034 + */
17035 +static void __cvmx_pko_reset(void)
17036 +{
17037 + union cvmx_pko_reg_flags pko_reg_flags;
17038 + pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
17039 + pko_reg_flags.s.reset = 1;
17040 + cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
17041 +}
17042 +
17043 +/**
17044 + * Shutdown and free resources required by packet output.
17045 + */
17046 +void cvmx_pko_shutdown(void)
17047 +{
17048 + union cvmx_pko_mem_queue_ptrs config;
17049 + int queue;
17050 +
17051 + cvmx_pko_disable();
17052 +
17053 + for (queue = 0; queue < CVMX_PKO_MAX_OUTPUT_QUEUES; queue++) {
17054 + config.u64 = 0;
17055 + config.s.tail = 1;
17056 + config.s.index = 0;
17057 + config.s.port = CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID;
17058 + config.s.queue = queue & 0x7f;
17059 + config.s.qos_mask = 0;
17060 + config.s.buf_ptr = 0;
17061 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
17062 + union cvmx_pko_reg_queue_ptrs1 config1;
17063 + config1.u64 = 0;
17064 + config1.s.qid7 = queue >> 7;
17065 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
17066 + }
17067 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
17068 + cvmx_cmd_queue_shutdown(CVMX_CMD_QUEUE_PKO(queue));
17069 + }
17070 + __cvmx_pko_reset();
17071 +}
17072 +
17073 +/**
17074 + * Configure a output port and the associated queues for use.
17075 + *
17076 + * @port: Port to configure.
17077 + * @base_queue: First queue number to associate with this port.
17078 + * @num_queues: Number of queues to associate with this port
17079 + * @priority: Array of priority levels for each queue. Values are
17080 + * allowed to be 0-8. A value of 8 get 8 times the traffic
17081 + * of a value of 1. A value of 0 indicates that no rounds
17082 + * will be participated in. These priorities can be changed
17083 + * on the fly while the pko is enabled. A priority of 9
17084 + * indicates that static priority should be used. If static
17085 + * priority is used all queues with static priority must be
17086 + * contiguous starting at the base_queue, and lower numbered
17087 + * queues have higher priority than higher numbered queues.
17088 + * There must be num_queues elements in the array.
17089 + */
17090 +cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue,
17091 + uint64_t num_queues,
17092 + const uint64_t priority[])
17093 +{
17094 + cvmx_pko_status_t result_code;
17095 + uint64_t queue;
17096 + union cvmx_pko_mem_queue_ptrs config;
17097 + union cvmx_pko_reg_queue_ptrs1 config1;
17098 + int static_priority_base = -1;
17099 + int static_priority_end = -1;
17100 +
17101 + if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS)
17102 + && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) {
17103 + cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid port %llu\n",
17104 + (unsigned long long)port);
17105 + return CVMX_PKO_INVALID_PORT;
17106 + }
17107 +
17108 + if (base_queue + num_queues > CVMX_PKO_MAX_OUTPUT_QUEUES) {
17109 + cvmx_dprintf
17110 + ("ERROR: cvmx_pko_config_port: Invalid queue range %llu\n",
17111 + (unsigned long long)(base_queue + num_queues));
17112 + return CVMX_PKO_INVALID_QUEUE;
17113 + }
17114 +
17115 + if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
17116 + /*
17117 + * Validate the static queue priority setup and set
17118 + * static_priority_base and static_priority_end
17119 + * accordingly.
17120 + */
17121 + for (queue = 0; queue < num_queues; queue++) {
17122 + /* Find first queue of static priority */
17123 + if (static_priority_base == -1
17124 + && priority[queue] ==
17125 + CVMX_PKO_QUEUE_STATIC_PRIORITY)
17126 + static_priority_base = queue;
17127 + /* Find last queue of static priority */
17128 + if (static_priority_base != -1
17129 + && static_priority_end == -1
17130 + && priority[queue] != CVMX_PKO_QUEUE_STATIC_PRIORITY
17131 + && queue)
17132 + static_priority_end = queue - 1;
17133 + else if (static_priority_base != -1
17134 + && static_priority_end == -1
17135 + && queue == num_queues - 1)
17136 + /* all queues are static priority */
17137 + static_priority_end = queue;
17138 + /*
17139 + * Check to make sure all static priority
17140 + * queues are contiguous. Also catches some
17141 + * cases of static priorites not starting at
17142 + * queue 0.
17143 + */
17144 + if (static_priority_end != -1
17145 + && (int)queue > static_priority_end
17146 + && priority[queue] ==
17147 + CVMX_PKO_QUEUE_STATIC_PRIORITY) {
17148 + cvmx_dprintf("ERROR: cvmx_pko_config_port: "
17149 + "Static priority queues aren't "
17150 + "contiguous or don't start at "
17151 + "base queue. q: %d, eq: %d\n",
17152 + (int)queue, static_priority_end);
17153 + return CVMX_PKO_INVALID_PRIORITY;
17154 + }
17155 + }
17156 + if (static_priority_base > 0) {
17157 + cvmx_dprintf("ERROR: cvmx_pko_config_port: Static "
17158 + "priority queues don't start at base "
17159 + "queue. sq: %d\n",
17160 + static_priority_base);
17161 + return CVMX_PKO_INVALID_PRIORITY;
17162 + }
17163 +#if 0
17164 + cvmx_dprintf("Port %d: Static priority queue base: %d, "
17165 + "end: %d\n", port,
17166 + static_priority_base, static_priority_end);
17167 +#endif
17168 + }
17169 + /*
17170 + * At this point, static_priority_base and static_priority_end
17171 + * are either both -1, or are valid start/end queue
17172 + * numbers.
17173 + */
17174 +
17175 + result_code = CVMX_PKO_SUCCESS;
17176 +
17177 +#ifdef PKO_DEBUG
17178 + cvmx_dprintf("num queues: %d (%lld,%lld)\n", num_queues,
17179 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE0,
17180 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE1);
17181 +#endif
17182 +
17183 + for (queue = 0; queue < num_queues; queue++) {
17184 + uint64_t *buf_ptr = NULL;
17185 +
17186 + config1.u64 = 0;
17187 + config1.s.idx3 = queue >> 3;
17188 + config1.s.qid7 = (base_queue + queue) >> 7;
17189 +
17190 + config.u64 = 0;
17191 + config.s.tail = queue == (num_queues - 1);
17192 + config.s.index = queue;
17193 + config.s.port = port;
17194 + config.s.queue = base_queue + queue;
17195 +
17196 + if (!cvmx_octeon_is_pass1()) {
17197 + config.s.static_p = static_priority_base >= 0;
17198 + config.s.static_q = (int)queue <= static_priority_end;
17199 + config.s.s_tail = (int)queue == static_priority_end;
17200 + }
17201 + /*
17202 + * Convert the priority into an enable bit field. Try
17203 + * to space the bits out evenly so the packet don't
17204 + * get grouped up
17205 + */
17206 + switch ((int)priority[queue]) {
17207 + case 0:
17208 + config.s.qos_mask = 0x00;
17209 + break;
17210 + case 1:
17211 + config.s.qos_mask = 0x01;
17212 + break;
17213 + case 2:
17214 + config.s.qos_mask = 0x11;
17215 + break;
17216 + case 3:
17217 + config.s.qos_mask = 0x49;
17218 + break;
17219 + case 4:
17220 + config.s.qos_mask = 0x55;
17221 + break;
17222 + case 5:
17223 + config.s.qos_mask = 0x57;
17224 + break;
17225 + case 6:
17226 + config.s.qos_mask = 0x77;
17227 + break;
17228 + case 7:
17229 + config.s.qos_mask = 0x7f;
17230 + break;
17231 + case 8:
17232 + config.s.qos_mask = 0xff;
17233 + break;
17234 + case CVMX_PKO_QUEUE_STATIC_PRIORITY:
17235 + /* Pass 1 will fall through to the error case */
17236 + if (!cvmx_octeon_is_pass1()) {
17237 + config.s.qos_mask = 0xff;
17238 + break;
17239 + }
17240 + default:
17241 + cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid "
17242 + "priority %llu\n",
17243 + (unsigned long long)priority[queue]);
17244 + config.s.qos_mask = 0xff;
17245 + result_code = CVMX_PKO_INVALID_PRIORITY;
17246 + break;
17247 + }
17248 +
17249 + if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
17250 + cvmx_cmd_queue_result_t cmd_res =
17251 + cvmx_cmd_queue_initialize(CVMX_CMD_QUEUE_PKO
17252 + (base_queue + queue),
17253 + CVMX_PKO_MAX_QUEUE_DEPTH,
17254 + CVMX_FPA_OUTPUT_BUFFER_POOL,
17255 + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
17256 + -
17257 + CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST
17258 + * 8);
17259 + if (cmd_res != CVMX_CMD_QUEUE_SUCCESS) {
17260 + switch (cmd_res) {
17261 + case CVMX_CMD_QUEUE_NO_MEMORY:
17262 + cvmx_dprintf("ERROR: "
17263 + "cvmx_pko_config_port: "
17264 + "Unable to allocate "
17265 + "output buffer.\n");
17266 + return CVMX_PKO_NO_MEMORY;
17267 + case CVMX_CMD_QUEUE_ALREADY_SETUP:
17268 + cvmx_dprintf
17269 + ("ERROR: cvmx_pko_config_port: Port already setup.\n");
17270 + return CVMX_PKO_PORT_ALREADY_SETUP;
17271 + case CVMX_CMD_QUEUE_INVALID_PARAM:
17272 + default:
17273 + cvmx_dprintf
17274 + ("ERROR: cvmx_pko_config_port: Command queue initialization failed.\n");
17275 + return CVMX_PKO_CMD_QUEUE_INIT_ERROR;
17276 + }
17277 + }
17278 +
17279 + buf_ptr =
17280 + (uint64_t *)
17281 + cvmx_cmd_queue_buffer(CVMX_CMD_QUEUE_PKO
17282 + (base_queue + queue));
17283 + config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr);
17284 + } else
17285 + config.s.buf_ptr = 0;
17286 +
17287 + CVMX_SYNCWS;
17288 +
17289 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX))
17290 + cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
17291 + cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
17292 + }
17293 +
17294 + return result_code;
17295 +}
17296 +
17297 +#ifdef PKO_DEBUG
17298 +/**
17299 + * Show map of ports -> queues for different cores.
17300 + */
17301 +void cvmx_pko_show_queue_map()
17302 +{
17303 + int core, port;
17304 + int pko_output_ports = 36;
17305 +
17306 + cvmx_dprintf("port");
17307 + for (port = 0; port < pko_output_ports; port++)
17308 + cvmx_dprintf("%3d ", port);
17309 + cvmx_dprintf("\n");
17310 +
17311 + for (core = 0; core < CVMX_MAX_CORES; core++) {
17312 + cvmx_dprintf("\n%2d: ", core);
17313 + for (port = 0; port < pko_output_ports; port++) {
17314 + cvmx_dprintf("%3d ",
17315 + cvmx_pko_get_base_queue_per_core(port,
17316 + core));
17317 + }
17318 + }
17319 + cvmx_dprintf("\n");
17320 +}
17321 +#endif
17322 +
17323 +/**
17324 + * Rate limit a PKO port to a max packets/sec. This function is only
17325 + * supported on CN51XX and higher, excluding CN58XX.
17326 + *
17327 + * @port: Port to rate limit
17328 + * @packets_s: Maximum packet/sec
17329 + * @burst: Maximum number of packets to burst in a row before rate
17330 + * limiting cuts in.
17331 + *
17332 + * Returns Zero on success, negative on failure
17333 + */
17334 +int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst)
17335 +{
17336 + union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
17337 + union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
17338 +
17339 + pko_mem_port_rate0.u64 = 0;
17340 + pko_mem_port_rate0.s.pid = port;
17341 + pko_mem_port_rate0.s.rate_pkt =
17342 + cvmx_sysinfo_get()->cpu_clock_hz / packets_s / 16;
17343 + /* No cost per word since we are limited by packets/sec, not bits/sec */
17344 + pko_mem_port_rate0.s.rate_word = 0;
17345 +
17346 + pko_mem_port_rate1.u64 = 0;
17347 + pko_mem_port_rate1.s.pid = port;
17348 + pko_mem_port_rate1.s.rate_lim =
17349 + ((uint64_t) pko_mem_port_rate0.s.rate_pkt * burst) >> 8;
17350 +
17351 + cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
17352 + cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
17353 + return 0;
17354 +}
17355 +
17356 +/**
17357 + * Rate limit a PKO port to a max bits/sec. This function is only
17358 + * supported on CN51XX and higher, excluding CN58XX.
17359 + *
17360 + * @port: Port to rate limit
17361 + * @bits_s: PKO rate limit in bits/sec
17362 + * @burst: Maximum number of bits to burst before rate
17363 + * limiting cuts in.
17364 + *
17365 + * Returns Zero on success, negative on failure
17366 + */
17367 +int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst)
17368 +{
17369 + union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
17370 + union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
17371 + uint64_t clock_rate = cvmx_sysinfo_get()->cpu_clock_hz;
17372 + uint64_t tokens_per_bit = clock_rate * 16 / bits_s;
17373 +
17374 + pko_mem_port_rate0.u64 = 0;
17375 + pko_mem_port_rate0.s.pid = port;
17376 + /*
17377 + * Each packet has a 12 bytes of interframe gap, an 8 byte
17378 + * preamble, and a 4 byte CRC. These are not included in the
17379 + * per word count. Multiply by 8 to covert to bits and divide
17380 + * by 256 for limit granularity.
17381 + */
17382 + pko_mem_port_rate0.s.rate_pkt = (12 + 8 + 4) * 8 * tokens_per_bit / 256;
17383 + /* Each 8 byte word has 64bits */
17384 + pko_mem_port_rate0.s.rate_word = 64 * tokens_per_bit;
17385 +
17386 + pko_mem_port_rate1.u64 = 0;
17387 + pko_mem_port_rate1.s.pid = port;
17388 + pko_mem_port_rate1.s.rate_lim = tokens_per_bit * burst / 256;
17389 +
17390 + cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
17391 + cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
17392 + return 0;
17393 +}
17394 diff --git a/drivers/staging/octeon/cvmx-pko.h b/drivers/staging/octeon/cvmx-pko.h
17395 new file mode 100644
17396 index 0000000..f068c19
17397 --- /dev/null
17398 +++ b/drivers/staging/octeon/cvmx-pko.h
17399 @@ -0,0 +1,610 @@
17400 +/***********************license start***************
17401 + * Author: Cavium Networks
17402 + *
17403 + * Contact: support@caviumnetworks.com
17404 + * This file is part of the OCTEON SDK
17405 + *
17406 + * Copyright (c) 2003-2008 Cavium Networks
17407 + *
17408 + * This file is free software; you can redistribute it and/or modify
17409 + * it under the terms of the GNU General Public License, Version 2, as
17410 + * published by the Free Software Foundation.
17411 + *
17412 + * This file is distributed in the hope that it will be useful, but
17413 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
17414 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
17415 + * NONINFRINGEMENT. See the GNU General Public License for more
17416 + * details.
17417 + *
17418 + * You should have received a copy of the GNU General Public License
17419 + * along with this file; if not, write to the Free Software
17420 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17421 + * or visit http://www.gnu.org/licenses/.
17422 + *
17423 + * This file may also be available under a different license from Cavium.
17424 + * Contact Cavium Networks for more information
17425 + ***********************license end**************************************/
17426 +
17427 +/**
17428 + *
17429 + * Interface to the hardware Packet Output unit.
17430 + *
17431 + * Starting with SDK 1.7.0, the PKO output functions now support
17432 + * two types of locking. CVMX_PKO_LOCK_ATOMIC_TAG continues to
17433 + * function similarly to previous SDKs by using POW atomic tags
17434 + * to preserve ordering and exclusivity. As a new option, you
17435 + * can now pass CVMX_PKO_LOCK_CMD_QUEUE which uses a ll/sc
17436 + * memory based locking instead. This locking has the advantage
17437 + * of not affecting the tag state but doesn't preserve packet
17438 + * ordering. CVMX_PKO_LOCK_CMD_QUEUE is appropriate in most
17439 + * generic code while CVMX_PKO_LOCK_CMD_QUEUE should be used
17440 + * with hand tuned fast path code.
17441 + *
17442 + * Some of other SDK differences visible to the command command
17443 + * queuing:
17444 + * - PKO indexes are no longer stored in the FAU. A large
17445 + * percentage of the FAU register block used to be tied up
17446 + * maintaining PKO queue pointers. These are now stored in a
17447 + * global named block.
17448 + * - The PKO <b>use_locking</b> parameter can now have a global
17449 + * effect. Since all application use the same named block,
17450 + * queue locking correctly applies across all operating
17451 + * systems when using CVMX_PKO_LOCK_CMD_QUEUE.
17452 + * - PKO 3 word commands are now supported. Use
17453 + * cvmx_pko_send_packet_finish3().
17454 + *
17455 + */
17456 +
17457 +#ifndef __CVMX_PKO_H__
17458 +#define __CVMX_PKO_H__
17459 +
17460 +#include "cvmx-fpa.h"
17461 +#include "cvmx-pow.h"
17462 +#include "cvmx-cmd-queue.h"
17463 +#include "cvmx-pko-defs.h"
17464 +
17465 +/* Adjust the command buffer size by 1 word so that in the case of using only
17466 + * two word PKO commands no command words stradle buffers. The useful values
17467 + * for this are 0 and 1. */
17468 +#define CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST (1)
17469 +
17470 +#define CVMX_PKO_MAX_OUTPUT_QUEUES_STATIC 256
17471 +#define CVMX_PKO_MAX_OUTPUT_QUEUES ((OCTEON_IS_MODEL(OCTEON_CN31XX) || \
17472 + OCTEON_IS_MODEL(OCTEON_CN3010) || OCTEON_IS_MODEL(OCTEON_CN3005) || \
17473 + OCTEON_IS_MODEL(OCTEON_CN50XX)) ? 32 : \
17474 + (OCTEON_IS_MODEL(OCTEON_CN58XX) || \
17475 + OCTEON_IS_MODEL(OCTEON_CN56XX)) ? 256 : 128)
17476 +#define CVMX_PKO_NUM_OUTPUT_PORTS 40
17477 +/* use this for queues that are not used */
17478 +#define CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63
17479 +#define CVMX_PKO_QUEUE_STATIC_PRIORITY 9
17480 +#define CVMX_PKO_ILLEGAL_QUEUE 0xFFFF
17481 +#define CVMX_PKO_MAX_QUEUE_DEPTH 0
17482 +
17483 +typedef enum {
17484 + CVMX_PKO_SUCCESS,
17485 + CVMX_PKO_INVALID_PORT,
17486 + CVMX_PKO_INVALID_QUEUE,
17487 + CVMX_PKO_INVALID_PRIORITY,
17488 + CVMX_PKO_NO_MEMORY,
17489 + CVMX_PKO_PORT_ALREADY_SETUP,
17490 + CVMX_PKO_CMD_QUEUE_INIT_ERROR
17491 +} cvmx_pko_status_t;
17492 +
17493 +/**
17494 + * This enumeration represents the differnet locking modes supported by PKO.
17495 + */
17496 +typedef enum {
17497 + /*
17498 + * PKO doesn't do any locking. It is the responsibility of the
17499 + * application to make sure that no other core is accessing
17500 + * the same queue at the smae time
17501 + */
17502 + CVMX_PKO_LOCK_NONE = 0,
17503 + /*
17504 + * PKO performs an atomic tagswitch to insure exclusive access
17505 + * to the output queue. This will maintain packet ordering on
17506 + * output.
17507 + */
17508 + CVMX_PKO_LOCK_ATOMIC_TAG = 1,
17509 + /*
17510 + * PKO uses the common command queue locks to insure exclusive
17511 + * access to the output queue. This is a memory based
17512 + * ll/sc. This is the most portable locking mechanism.
17513 + */
17514 + CVMX_PKO_LOCK_CMD_QUEUE = 2,
17515 +} cvmx_pko_lock_t;
17516 +
17517 +typedef struct {
17518 + uint32_t packets;
17519 + uint64_t octets;
17520 + uint64_t doorbell;
17521 +} cvmx_pko_port_status_t;
17522 +
17523 +/**
17524 + * This structure defines the address to use on a packet enqueue
17525 + */
17526 +typedef union {
17527 + uint64_t u64;
17528 + struct {
17529 + /* Must CVMX_IO_SEG */
17530 + uint64_t mem_space:2;
17531 + /* Must be zero */
17532 + uint64_t reserved:13;
17533 + /* Must be one */
17534 + uint64_t is_io:1;
17535 + /* The ID of the device on the non-coherent bus */
17536 + uint64_t did:8;
17537 + /* Must be zero */
17538 + uint64_t reserved2:4;
17539 + /* Must be zero */
17540 + uint64_t reserved3:18;
17541 + /*
17542 + * The hardware likes to have the output port in
17543 + * addition to the output queue,
17544 + */
17545 + uint64_t port:6;
17546 + /*
17547 + * The output queue to send the packet to (0-127 are
17548 + * legal)
17549 + */
17550 + uint64_t queue:9;
17551 + /* Must be zero */
17552 + uint64_t reserved4:3;
17553 + } s;
17554 +} cvmx_pko_doorbell_address_t;
17555 +
17556 +/**
17557 + * Structure of the first packet output command word.
17558 + */
17559 +typedef union {
17560 + uint64_t u64;
17561 + struct {
17562 + /*
17563 + * The size of the reg1 operation - could be 8, 16,
17564 + * 32, or 64 bits.
17565 + */
17566 + uint64_t size1:2;
17567 + /*
17568 + * The size of the reg0 operation - could be 8, 16,
17569 + * 32, or 64 bits.
17570 + */
17571 + uint64_t size0:2;
17572 + /*
17573 + * If set, subtract 1, if clear, subtract packet
17574 + * size.
17575 + */
17576 + uint64_t subone1:1;
17577 + /*
17578 + * The register, subtract will be done if reg1 is
17579 + * non-zero.
17580 + */
17581 + uint64_t reg1:11;
17582 + /* If set, subtract 1, if clear, subtract packet size */
17583 + uint64_t subone0:1;
17584 + /* The register, subtract will be done if reg0 is non-zero */
17585 + uint64_t reg0:11;
17586 + /*
17587 + * When set, interpret segment pointer and segment
17588 + * bytes in little endian order.
17589 + */
17590 + uint64_t le:1;
17591 + /*
17592 + * When set, packet data not allocated in L2 cache by
17593 + * PKO.
17594 + */
17595 + uint64_t n2:1;
17596 + /*
17597 + * If set and rsp is set, word3 contains a pointer to
17598 + * a work queue entry.
17599 + */
17600 + uint64_t wqp:1;
17601 + /* If set, the hardware will send a response when done */
17602 + uint64_t rsp:1;
17603 + /*
17604 + * If set, the supplied pkt_ptr is really a pointer to
17605 + * a list of pkt_ptr's.
17606 + */
17607 + uint64_t gather:1;
17608 + /*
17609 + * If ipoffp1 is non zero, (ipoffp1-1) is the number
17610 + * of bytes to IP header, and the hardware will
17611 + * calculate and insert the UDP/TCP checksum.
17612 + */
17613 + uint64_t ipoffp1:7;
17614 + /*
17615 + * If set, ignore the I bit (force to zero) from all
17616 + * pointer structures.
17617 + */
17618 + uint64_t ignore_i:1;
17619 + /*
17620 + * If clear, the hardware will attempt to free the
17621 + * buffers containing the packet.
17622 + */
17623 + uint64_t dontfree:1;
17624 + /*
17625 + * The total number of segs in the packet, if gather
17626 + * set, also gather list length.
17627 + */
17628 + uint64_t segs:6;
17629 + /* Including L2, but no trailing CRC */
17630 + uint64_t total_bytes:16;
17631 + } s;
17632 +} cvmx_pko_command_word0_t;
17633 +
17634 +/* CSR typedefs have been moved to cvmx-csr-*.h */
17635 +
17636 +/**
17637 + * Definition of internal state for Packet output processing
17638 + */
17639 +typedef struct {
17640 + /* ptr to start of buffer, offset kept in FAU reg */
17641 + uint64_t *start_ptr;
17642 +} cvmx_pko_state_elem_t;
17643 +
17644 +/**
17645 + * Call before any other calls to initialize the packet
17646 + * output system.
17647 + */
17648 +extern void cvmx_pko_initialize_global(void);
17649 +extern int cvmx_pko_initialize_local(void);
17650 +
17651 +/**
17652 + * Enables the packet output hardware. It must already be
17653 + * configured.
17654 + */
17655 +extern void cvmx_pko_enable(void);
17656 +
17657 +/**
17658 + * Disables the packet output. Does not affect any configuration.
17659 + */
17660 +extern void cvmx_pko_disable(void);
17661 +
17662 +/**
17663 + * Shutdown and free resources required by packet output.
17664 + */
17665 +
17666 +extern void cvmx_pko_shutdown(void);
17667 +
17668 +/**
17669 + * Configure a output port and the associated queues for use.
17670 + *
17671 + * @port: Port to configure.
17672 + * @base_queue: First queue number to associate with this port.
17673 + * @num_queues: Number of queues t oassociate with this port
17674 + * @priority: Array of priority levels for each queue. Values are
17675 + * allowed to be 1-8. A value of 8 get 8 times the traffic
17676 + * of a value of 1. There must be num_queues elements in the
17677 + * array.
17678 + */
17679 +extern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port,
17680 + uint64_t base_queue,
17681 + uint64_t num_queues,
17682 + const uint64_t priority[]);
17683 +
17684 +/**
17685 + * Ring the packet output doorbell. This tells the packet
17686 + * output hardware that "len" command words have been added
17687 + * to its pending list. This command includes the required
17688 + * CVMX_SYNCWS before the doorbell ring.
17689 + *
17690 + * @port: Port the packet is for
17691 + * @queue: Queue the packet is for
17692 + * @len: Length of the command in 64 bit words
17693 + */
17694 +static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
17695 + uint64_t len)
17696 +{
17697 + cvmx_pko_doorbell_address_t ptr;
17698 +
17699 + ptr.u64 = 0;
17700 + ptr.s.mem_space = CVMX_IO_SEG;
17701 + ptr.s.did = CVMX_OCT_DID_PKT_SEND;
17702 + ptr.s.is_io = 1;
17703 + ptr.s.port = port;
17704 + ptr.s.queue = queue;
17705 + /*
17706 + * Need to make sure output queue data is in DRAM before
17707 + * doorbell write.
17708 + */
17709 + CVMX_SYNCWS;
17710 + cvmx_write_io(ptr.u64, len);
17711 +}
17712 +
17713 +/**
17714 + * Prepare to send a packet. This may initiate a tag switch to
17715 + * get exclusive access to the output queue structure, and
17716 + * performs other prep work for the packet send operation.
17717 + *
17718 + * cvmx_pko_send_packet_finish() MUST be called after this function is called,
17719 + * and must be called with the same port/queue/use_locking arguments.
17720 + *
17721 + * The use_locking parameter allows the caller to use three
17722 + * possible locking modes.
17723 + * - CVMX_PKO_LOCK_NONE
17724 + * - PKO doesn't do any locking. It is the responsibility
17725 + * of the application to make sure that no other core
17726 + * is accessing the same queue at the smae time.
17727 + * - CVMX_PKO_LOCK_ATOMIC_TAG
17728 + * - PKO performs an atomic tagswitch to insure exclusive
17729 + * access to the output queue. This will maintain
17730 + * packet ordering on output.
17731 + * - CVMX_PKO_LOCK_CMD_QUEUE
17732 + * - PKO uses the common command queue locks to insure
17733 + * exclusive access to the output queue. This is a
17734 + * memory based ll/sc. This is the most portable
17735 + * locking mechanism.
17736 + *
17737 + * NOTE: If atomic locking is used, the POW entry CANNOT be
17738 + * descheduled, as it does not contain a valid WQE pointer.
17739 + *
17740 + * @port: Port to send it on
17741 + * @queue: Queue to use
17742 + * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17743 + * CVMX_PKO_LOCK_CMD_QUEUE
17744 + */
17745 +
17746 +static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
17747 + cvmx_pko_lock_t use_locking)
17748 +{
17749 + if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
17750 + /*
17751 + * Must do a full switch here to handle all cases. We
17752 + * use a fake WQE pointer, as the POW does not access
17753 + * this memory. The WQE pointer and group are only
17754 + * used if this work is descheduled, which is not
17755 + * supported by the
17756 + * cvmx_pko_send_packet_prepare/cvmx_pko_send_packet_finish
17757 + * combination. Note that this is a special case in
17758 + * which these fake values can be used - this is not a
17759 + * general technique.
17760 + */
17761 + uint32_t tag =
17762 + CVMX_TAG_SW_BITS_INTERNAL << CVMX_TAG_SW_SHIFT |
17763 + CVMX_TAG_SUBGROUP_PKO << CVMX_TAG_SUBGROUP_SHIFT |
17764 + (CVMX_TAG_SUBGROUP_MASK & queue);
17765 + cvmx_pow_tag_sw_full((cvmx_wqe_t *) cvmx_phys_to_ptr(0x80), tag,
17766 + CVMX_POW_TAG_TYPE_ATOMIC, 0);
17767 + }
17768 +}
17769 +
17770 +/**
17771 + * Complete packet output. cvmx_pko_send_packet_prepare() must be
17772 + * called exactly once before this, and the same parameters must be
17773 + * passed to both cvmx_pko_send_packet_prepare() and
17774 + * cvmx_pko_send_packet_finish().
17775 + *
17776 + * @port: Port to send it on
17777 + * @queue: Queue to use
17778 + * @pko_command:
17779 + * PKO HW command word
17780 + * @packet: Packet to send
17781 + * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17782 + * CVMX_PKO_LOCK_CMD_QUEUE
17783 + *
17784 + * Returns returns CVMX_PKO_SUCCESS on success, or error code on
17785 + * failure of output
17786 + */
17787 +static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
17788 + uint64_t port,
17789 + uint64_t queue,
17790 + cvmx_pko_command_word0_t pko_command,
17791 + union cvmx_buf_ptr packet,
17792 + cvmx_pko_lock_t use_locking)
17793 +{
17794 + cvmx_cmd_queue_result_t result;
17795 + if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
17796 + cvmx_pow_tag_sw_wait();
17797 + result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
17798 + (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
17799 + pko_command.u64, packet.u64);
17800 + if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
17801 + cvmx_pko_doorbell(port, queue, 2);
17802 + return CVMX_PKO_SUCCESS;
17803 + } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
17804 + || (result == CVMX_CMD_QUEUE_FULL)) {
17805 + return CVMX_PKO_NO_MEMORY;
17806 + } else {
17807 + return CVMX_PKO_INVALID_QUEUE;
17808 + }
17809 +}
17810 +
17811 +/**
17812 + * Complete packet output. cvmx_pko_send_packet_prepare() must be
17813 + * called exactly once before this, and the same parameters must be
17814 + * passed to both cvmx_pko_send_packet_prepare() and
17815 + * cvmx_pko_send_packet_finish().
17816 + *
17817 + * @port: Port to send it on
17818 + * @queue: Queue to use
17819 + * @pko_command:
17820 + * PKO HW command word
17821 + * @packet: Packet to send
17822 + * @addr: Plysical address of a work queue entry or physical address
17823 + * to zero on complete.
17824 + * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
17825 + * CVMX_PKO_LOCK_CMD_QUEUE
17826 + *
17827 + * Returns returns CVMX_PKO_SUCCESS on success, or error code on
17828 + * failure of output
17829 + */
17830 +static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
17831 + uint64_t port,
17832 + uint64_t queue,
17833 + cvmx_pko_command_word0_t pko_command,
17834 + union cvmx_buf_ptr packet,
17835 + uint64_t addr,
17836 + cvmx_pko_lock_t use_locking)
17837 +{
17838 + cvmx_cmd_queue_result_t result;
17839 + if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
17840 + cvmx_pow_tag_sw_wait();
17841 + result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
17842 + (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
17843 + pko_command.u64, packet.u64, addr);
17844 + if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
17845 + cvmx_pko_doorbell(port, queue, 3);
17846 + return CVMX_PKO_SUCCESS;
17847 + } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
17848 + || (result == CVMX_CMD_QUEUE_FULL)) {
17849 + return CVMX_PKO_NO_MEMORY;
17850 + } else {
17851 + return CVMX_PKO_INVALID_QUEUE;
17852 + }
17853 +}
17854 +
17855 +/**
17856 + * Return the pko output queue associated with a port and a specific core.
17857 + * In normal mode (PKO lockless operation is disabled), the value returned
17858 + * is the base queue.
17859 + *
17860 + * @port: Port number
17861 + * @core: Core to get queue for
17862 + *
17863 + * Returns Core-specific output queue
17864 + */
17865 +static inline int cvmx_pko_get_base_queue_per_core(int port, int core)
17866 +{
17867 +#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
17868 +#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16
17869 +#endif
17870 +#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
17871 +#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16
17872 +#endif
17873 +
17874 + if (port < CVMX_PKO_MAX_PORTS_INTERFACE0)
17875 + return port * CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + core;
17876 + else if (port >= 16 && port < 16 + CVMX_PKO_MAX_PORTS_INTERFACE1)
17877 + return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17878 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + (port -
17879 + 16) *
17880 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + core;
17881 + else if ((port >= 32) && (port < 36))
17882 + return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17883 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
17884 + CVMX_PKO_MAX_PORTS_INTERFACE1 *
17885 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + (port -
17886 + 32) *
17887 + CVMX_PKO_QUEUES_PER_PORT_PCI;
17888 + else if ((port >= 36) && (port < 40))
17889 + return CVMX_PKO_MAX_PORTS_INTERFACE0 *
17890 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
17891 + CVMX_PKO_MAX_PORTS_INTERFACE1 *
17892 + CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 +
17893 + 4 * CVMX_PKO_QUEUES_PER_PORT_PCI + (port -
17894 + 36) *
17895 + CVMX_PKO_QUEUES_PER_PORT_LOOP;
17896 + else
17897 + /* Given the limit on the number of ports we can map to
17898 + * CVMX_MAX_OUTPUT_QUEUES_STATIC queues (currently 256,
17899 + * divided among all cores), the remaining unmapped ports
17900 + * are assigned an illegal queue number */
17901 + return CVMX_PKO_ILLEGAL_QUEUE;
17902 +}
17903 +
17904 +/**
17905 + * For a given port number, return the base pko output queue
17906 + * for the port.
17907 + *
17908 + * @port: Port number
17909 + * Returns Base output queue
17910 + */
17911 +static inline int cvmx_pko_get_base_queue(int port)
17912 +{
17913 + return cvmx_pko_get_base_queue_per_core(port, 0);
17914 +}
17915 +
17916 +/**
17917 + * For a given port number, return the number of pko output queues.
17918 + *
17919 + * @port: Port number
17920 + * Returns Number of output queues
17921 + */
17922 +static inline int cvmx_pko_get_num_queues(int port)
17923 +{
17924 + if (port < 16)
17925 + return CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
17926 + else if (port < 32)
17927 + return CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
17928 + else if (port < 36)
17929 + return CVMX_PKO_QUEUES_PER_PORT_PCI;
17930 + else if (port < 40)
17931 + return CVMX_PKO_QUEUES_PER_PORT_LOOP;
17932 + else
17933 + return 0;
17934 +}
17935 +
17936 +/**
17937 + * Get the status counters for a port.
17938 + *
17939 + * @port_num: Port number to get statistics for.
17940 + * @clear: Set to 1 to clear the counters after they are read
17941 + * @status: Where to put the results.
17942 + */
17943 +static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
17944 + cvmx_pko_port_status_t *status)
17945 +{
17946 + union cvmx_pko_reg_read_idx pko_reg_read_idx;
17947 + union cvmx_pko_mem_count0 pko_mem_count0;
17948 + union cvmx_pko_mem_count1 pko_mem_count1;
17949 +
17950 + pko_reg_read_idx.u64 = 0;
17951 + pko_reg_read_idx.s.index = port_num;
17952 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17953 +
17954 + pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0);
17955 + status->packets = pko_mem_count0.s.count;
17956 + if (clear) {
17957 + pko_mem_count0.s.count = port_num;
17958 + cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64);
17959 + }
17960 +
17961 + pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1);
17962 + status->octets = pko_mem_count1.s.count;
17963 + if (clear) {
17964 + pko_mem_count1.s.count = port_num;
17965 + cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64);
17966 + }
17967 +
17968 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
17969 + union cvmx_pko_mem_debug9 debug9;
17970 + pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
17971 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17972 + debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
17973 + status->doorbell = debug9.cn38xx.doorbell;
17974 + } else {
17975 + union cvmx_pko_mem_debug8 debug8;
17976 + pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
17977 + cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
17978 + debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
17979 + status->doorbell = debug8.cn58xx.doorbell;
17980 + }
17981 +}
17982 +
17983 +/**
17984 + * Rate limit a PKO port to a max packets/sec. This function is only
17985 + * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
17986 + *
17987 + * @port: Port to rate limit
17988 + * @packets_s: Maximum packet/sec
17989 + * @burst: Maximum number of packets to burst in a row before rate
17990 + * limiting cuts in.
17991 + *
17992 + * Returns Zero on success, negative on failure
17993 + */
17994 +extern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst);
17995 +
17996 +/**
17997 + * Rate limit a PKO port to a max bits/sec. This function is only
17998 + * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
17999 + *
18000 + * @port: Port to rate limit
18001 + * @bits_s: PKO rate limit in bits/sec
18002 + * @burst: Maximum number of bits to burst before rate
18003 + * limiting cuts in.
18004 + *
18005 + * Returns Zero on success, negative on failure
18006 + */
18007 +extern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst);
18008 +
18009 +#endif /* __CVMX_PKO_H__ */
18010 diff --git a/drivers/staging/octeon/cvmx-pow.h b/drivers/staging/octeon/cvmx-pow.h
18011 new file mode 100644
18012 index 0000000..c5d66f2
18013 --- /dev/null
18014 +++ b/drivers/staging/octeon/cvmx-pow.h
18015 @@ -0,0 +1,1982 @@
18016 +/***********************license start***************
18017 + * Author: Cavium Networks
18018 + *
18019 + * Contact: support@caviumnetworks.com
18020 + * This file is part of the OCTEON SDK
18021 + *
18022 + * Copyright (c) 2003-2008 Cavium Networks
18023 + *
18024 + * This file is free software; you can redistribute it and/or modify
18025 + * it under the terms of the GNU General Public License, Version 2, as
18026 + * published by the Free Software Foundation.
18027 + *
18028 + * This file is distributed in the hope that it will be useful, but
18029 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
18030 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
18031 + * NONINFRINGEMENT. See the GNU General Public License for more
18032 + * details.
18033 + *
18034 + * You should have received a copy of the GNU General Public License
18035 + * along with this file; if not, write to the Free Software
18036 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18037 + * or visit http://www.gnu.org/licenses/.
18038 + *
18039 + * This file may also be available under a different license from Cavium.
18040 + * Contact Cavium Networks for more information
18041 + ***********************license end**************************************/
18042 +
18043 +/**
18044 + * Interface to the hardware Packet Order / Work unit.
18045 + *
18046 + * New, starting with SDK 1.7.0, cvmx-pow supports a number of
18047 + * extended consistency checks. The define
18048 + * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW
18049 + * internal state checks to find common programming errors. If
18050 + * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default
18051 + * enabled. For example, cvmx-pow will check for the following
18052 + * program errors or POW state inconsistency.
18053 + * - Requesting a POW operation with an active tag switch in
18054 + * progress.
18055 + * - Waiting for a tag switch to complete for an excessively
18056 + * long period. This is normally a sign of an error in locking
18057 + * causing deadlock.
18058 + * - Illegal tag switches from NULL_NULL.
18059 + * - Illegal tag switches from NULL.
18060 + * - Illegal deschedule request.
18061 + * - WQE pointer not matching the one attached to the core by
18062 + * the POW.
18063 + *
18064 + */
18065 +
18066 +#ifndef __CVMX_POW_H__
18067 +#define __CVMX_POW_H__
18068 +
18069 +#include <asm/octeon/cvmx-pow-defs.h>
18070 +
18071 +#include "cvmx-scratch.h"
18072 +#include "cvmx-wqe.h"
18073 +
18074 +/* Default to having all POW constancy checks turned on */
18075 +#ifndef CVMX_ENABLE_POW_CHECKS
18076 +#define CVMX_ENABLE_POW_CHECKS 1
18077 +#endif
18078 +
18079 +enum cvmx_pow_tag_type {
18080 + /* Tag ordering is maintained */
18081 + CVMX_POW_TAG_TYPE_ORDERED = 0L,
18082 + /* Tag ordering is maintained, and at most one PP has the tag */
18083 + CVMX_POW_TAG_TYPE_ATOMIC = 1L,
18084 + /*
18085 + * The work queue entry from the order - NEVER tag switch from
18086 + * NULL to NULL
18087 + */
18088 + CVMX_POW_TAG_TYPE_NULL = 2L,
18089 + /* A tag switch to NULL, and there is no space reserved in POW
18090 + * - NEVER tag switch to NULL_NULL
18091 + * - NEVER tag switch from NULL_NULL
18092 + * - NULL_NULL is entered at the beginning of time and on a deschedule.
18093 + * - NULL_NULL can be exited by a new work request. A NULL_SWITCH
18094 + * load can also switch the state to NULL
18095 + */
18096 + CVMX_POW_TAG_TYPE_NULL_NULL = 3L
18097 +};
18098 +
18099 +/**
18100 + * Wait flag values for pow functions.
18101 + */
18102 +typedef enum {
18103 + CVMX_POW_WAIT = 1,
18104 + CVMX_POW_NO_WAIT = 0,
18105 +} cvmx_pow_wait_t;
18106 +
18107 +/**
18108 + * POW tag operations. These are used in the data stored to the POW.
18109 + */
18110 +typedef enum {
18111 + /*
18112 + * switch the tag (only) for this PP
18113 + * - the previous tag should be non-NULL in this case
18114 + * - tag switch response required
18115 + * - fields used: op, type, tag
18116 + */
18117 + CVMX_POW_TAG_OP_SWTAG = 0L,
18118 + /*
18119 + * switch the tag for this PP, with full information
18120 + * - this should be used when the previous tag is NULL
18121 + * - tag switch response required
18122 + * - fields used: address, op, grp, type, tag
18123 + */
18124 + CVMX_POW_TAG_OP_SWTAG_FULL = 1L,
18125 + /*
18126 + * switch the tag (and/or group) for this PP and de-schedule
18127 + * - OK to keep the tag the same and only change the group
18128 + * - fields used: op, no_sched, grp, type, tag
18129 + */
18130 + CVMX_POW_TAG_OP_SWTAG_DESCH = 2L,
18131 + /*
18132 + * just de-schedule
18133 + * - fields used: op, no_sched
18134 + */
18135 + CVMX_POW_TAG_OP_DESCH = 3L,
18136 + /*
18137 + * create an entirely new work queue entry
18138 + * - fields used: address, op, qos, grp, type, tag
18139 + */
18140 + CVMX_POW_TAG_OP_ADDWQ = 4L,
18141 + /*
18142 + * just update the work queue pointer and grp for this PP
18143 + * - fields used: address, op, grp
18144 + */
18145 + CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L,
18146 + /*
18147 + * set the no_sched bit on the de-schedule list
18148 + *
18149 + * - does nothing if the selected entry is not on the
18150 + * de-schedule list
18151 + *
18152 + * - does nothing if the stored work queue pointer does not
18153 + * match the address field
18154 + *
18155 + * - fields used: address, index, op
18156 + *
18157 + * Before issuing a *_NSCHED operation, SW must guarantee
18158 + * that all prior deschedules and set/clr NSCHED operations
18159 + * are complete and all prior switches are complete. The
18160 + * hardware provides the opsdone bit and swdone bit for SW
18161 + * polling. After issuing a *_NSCHED operation, SW must
18162 + * guarantee that the set/clr NSCHED is complete before any
18163 + * subsequent operations.
18164 + */
18165 + CVMX_POW_TAG_OP_SET_NSCHED = 6L,
18166 + /*
18167 + * clears the no_sched bit on the de-schedule list
18168 + *
18169 + * - does nothing if the selected entry is not on the
18170 + * de-schedule list
18171 + *
18172 + * - does nothing if the stored work queue pointer does not
18173 + * match the address field
18174 + *
18175 + * - fields used: address, index, op
18176 + *
18177 + * Before issuing a *_NSCHED operation, SW must guarantee that
18178 + * all prior deschedules and set/clr NSCHED operations are
18179 + * complete and all prior switches are complete. The hardware
18180 + * provides the opsdone bit and swdone bit for SW
18181 + * polling. After issuing a *_NSCHED operation, SW must
18182 + * guarantee that the set/clr NSCHED is complete before any
18183 + * subsequent operations.
18184 + */
18185 + CVMX_POW_TAG_OP_CLR_NSCHED = 7L,
18186 + /* do nothing */
18187 + CVMX_POW_TAG_OP_NOP = 15L
18188 +} cvmx_pow_tag_op_t;
18189 +
18190 +/**
18191 + * This structure defines the store data on a store to POW
18192 + */
18193 +typedef union {
18194 + uint64_t u64;
18195 + struct {
18196 + /*
18197 + * Don't reschedule this entry. no_sched is used for
18198 + * CVMX_POW_TAG_OP_SWTAG_DESCH and
18199 + * CVMX_POW_TAG_OP_DESCH
18200 + */
18201 + uint64_t no_sched:1;
18202 + uint64_t unused:2;
18203 + /* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */
18204 + uint64_t index:13;
18205 + /* The operation to perform */
18206 + cvmx_pow_tag_op_t op:4;
18207 + uint64_t unused2:2;
18208 + /*
18209 + * The QOS level for the packet. qos is only used for
18210 + * CVMX_POW_TAG_OP_ADDWQ
18211 + */
18212 + uint64_t qos:3;
18213 + /*
18214 + * The group that the work queue entry will be
18215 + * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ,
18216 + * CVMX_POW_TAG_OP_SWTAG_FULL,
18217 + * CVMX_POW_TAG_OP_SWTAG_DESCH, and
18218 + * CVMX_POW_TAG_OP_UPDATE_WQP_GRP
18219 + */
18220 + uint64_t grp:4;
18221 + /*
18222 + * The type of the tag. type is used for everything
18223 + * except CVMX_POW_TAG_OP_DESCH,
18224 + * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
18225 + * CVMX_POW_TAG_OP_*_NSCHED
18226 + */
18227 + uint64_t type:3;
18228 + /*
18229 + * The actual tag. tag is used for everything except
18230 + * CVMX_POW_TAG_OP_DESCH,
18231 + * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
18232 + * CVMX_POW_TAG_OP_*_NSCHED
18233 + */
18234 + uint64_t tag:32;
18235 + } s;
18236 +} cvmx_pow_tag_req_t;
18237 +
18238 +/**
18239 + * This structure describes the address to load stuff from POW
18240 + */
18241 +typedef union {
18242 + uint64_t u64;
18243 +
18244 + /**
18245 + * Address for new work request loads (did<2:0> == 0)
18246 + */
18247 + struct {
18248 + /* Mips64 address region. Should be CVMX_IO_SEG */
18249 + uint64_t mem_region:2;
18250 + /* Must be zero */
18251 + uint64_t reserved_49_61:13;
18252 + /* Must be one */
18253 + uint64_t is_io:1;
18254 + /* the ID of POW -- did<2:0> == 0 in this case */
18255 + uint64_t did:8;
18256 + /* Must be zero */
18257 + uint64_t reserved_4_39:36;
18258 + /*
18259 + * If set, don't return load response until work is
18260 + * available.
18261 + */
18262 + uint64_t wait:1;
18263 + /* Must be zero */
18264 + uint64_t reserved_0_2:3;
18265 + } swork;
18266 +
18267 + /**
18268 + * Address for loads to get POW internal status
18269 + */
18270 + struct {
18271 + /* Mips64 address region. Should be CVMX_IO_SEG */
18272 + uint64_t mem_region:2;
18273 + /* Must be zero */
18274 + uint64_t reserved_49_61:13;
18275 + /* Must be one */
18276 + uint64_t is_io:1;
18277 + /* the ID of POW -- did<2:0> == 1 in this case */
18278 + uint64_t did:8;
18279 + /* Must be zero */
18280 + uint64_t reserved_10_39:30;
18281 + /* The core id to get status for */
18282 + uint64_t coreid:4;
18283 + /*
18284 + * If set and get_cur is set, return reverse tag-list
18285 + * pointer rather than forward tag-list pointer.
18286 + */
18287 + uint64_t get_rev:1;
18288 + /*
18289 + * If set, return current status rather than pending
18290 + * status.
18291 + */
18292 + uint64_t get_cur:1;
18293 + /*
18294 + * If set, get the work-queue pointer rather than
18295 + * tag/type.
18296 + */
18297 + uint64_t get_wqp:1;
18298 + /* Must be zero */
18299 + uint64_t reserved_0_2:3;
18300 + } sstatus;
18301 +
18302 + /**
18303 + * Address for memory loads to get POW internal state
18304 + */
18305 + struct {
18306 + /* Mips64 address region. Should be CVMX_IO_SEG */
18307 + uint64_t mem_region:2;
18308 + /* Must be zero */
18309 + uint64_t reserved_49_61:13;
18310 + /* Must be one */
18311 + uint64_t is_io:1;
18312 + /* the ID of POW -- did<2:0> == 2 in this case */
18313 + uint64_t did:8;
18314 + /* Must be zero */
18315 + uint64_t reserved_16_39:24;
18316 + /* POW memory index */
18317 + uint64_t index:11;
18318 + /*
18319 + * If set, return deschedule information rather than
18320 + * the standard response for work-queue index (invalid
18321 + * if the work-queue entry is not on the deschedule
18322 + * list).
18323 + */
18324 + uint64_t get_des:1;
18325 + /*
18326 + * If set, get the work-queue pointer rather than
18327 + * tag/type (no effect when get_des set).
18328 + */
18329 + uint64_t get_wqp:1;
18330 + /* Must be zero */
18331 + uint64_t reserved_0_2:3;
18332 + } smemload;
18333 +
18334 + /**
18335 + * Address for index/pointer loads
18336 + */
18337 + struct {
18338 + /* Mips64 address region. Should be CVMX_IO_SEG */
18339 + uint64_t mem_region:2;
18340 + /* Must be zero */
18341 + uint64_t reserved_49_61:13;
18342 + /* Must be one */
18343 + uint64_t is_io:1;
18344 + /* the ID of POW -- did<2:0> == 3 in this case */
18345 + uint64_t did:8;
18346 + /* Must be zero */
18347 + uint64_t reserved_9_39:31;
18348 + /*
18349 + * when {get_rmt ==0 AND get_des_get_tail == 0}, this
18350 + * field selects one of eight POW internal-input
18351 + * queues (0-7), one per QOS level; values 8-15 are
18352 + * illegal in this case; when {get_rmt ==0 AND
18353 + * get_des_get_tail == 1}, this field selects one of
18354 + * 16 deschedule lists (per group); when get_rmt ==1,
18355 + * this field selects one of 16 memory-input queue
18356 + * lists. The two memory-input queue lists associated
18357 + * with each QOS level are:
18358 + *
18359 + * - qosgrp = 0, qosgrp = 8: QOS0
18360 + * - qosgrp = 1, qosgrp = 9: QOS1
18361 + * - qosgrp = 2, qosgrp = 10: QOS2
18362 + * - qosgrp = 3, qosgrp = 11: QOS3
18363 + * - qosgrp = 4, qosgrp = 12: QOS4
18364 + * - qosgrp = 5, qosgrp = 13: QOS5
18365 + * - qosgrp = 6, qosgrp = 14: QOS6
18366 + * - qosgrp = 7, qosgrp = 15: QOS7
18367 + */
18368 + uint64_t qosgrp:4;
18369 + /*
18370 + * If set and get_rmt is clear, return deschedule list
18371 + * indexes rather than indexes for the specified qos
18372 + * level; if set and get_rmt is set, return the tail
18373 + * pointer rather than the head pointer for the
18374 + * specified qos level.
18375 + */
18376 + uint64_t get_des_get_tail:1;
18377 + /*
18378 + * If set, return remote pointers rather than the
18379 + * local indexes for the specified qos level.
18380 + */
18381 + uint64_t get_rmt:1;
18382 + /* Must be zero */
18383 + uint64_t reserved_0_2:3;
18384 + } sindexload;
18385 +
18386 + /**
18387 + * address for NULL_RD request (did<2:0> == 4) when this is read,
18388 + * HW attempts to change the state to NULL if it is NULL_NULL (the
18389 + * hardware cannot switch from NULL_NULL to NULL if a POW entry is
18390 + * not available - software may need to recover by finishing
18391 + * another piece of work before a POW entry can ever become
18392 + * available.)
18393 + */
18394 + struct {
18395 + /* Mips64 address region. Should be CVMX_IO_SEG */
18396 + uint64_t mem_region:2;
18397 + /* Must be zero */
18398 + uint64_t reserved_49_61:13;
18399 + /* Must be one */
18400 + uint64_t is_io:1;
18401 + /* the ID of POW -- did<2:0> == 4 in this case */
18402 + uint64_t did:8;
18403 + /* Must be zero */
18404 + uint64_t reserved_0_39:40;
18405 + } snull_rd;
18406 +} cvmx_pow_load_addr_t;
18407 +
18408 +/**
18409 + * This structure defines the response to a load/SENDSINGLE to POW
18410 + * (except CSR reads)
18411 + */
18412 +typedef union {
18413 + uint64_t u64;
18414 +
18415 + /**
18416 + * Response to new work request loads
18417 + */
18418 + struct {
18419 + /*
18420 + * Set when no new work queue entry was returned. *
18421 + * If there was de-scheduled work, the HW will
18422 + * definitely return it. When this bit is set, it
18423 + * could mean either mean:
18424 + *
18425 + * - There was no work, or
18426 + *
18427 + * - There was no work that the HW could find. This
18428 + * case can happen, regardless of the wait bit value
18429 + * in the original request, when there is work in
18430 + * the IQ's that is too deep down the list.
18431 + */
18432 + uint64_t no_work:1;
18433 + /* Must be zero */
18434 + uint64_t reserved_40_62:23;
18435 + /* 36 in O1 -- the work queue pointer */
18436 + uint64_t addr:40;
18437 + } s_work;
18438 +
18439 + /**
18440 + * Result for a POW Status Load (when get_cur==0 and get_wqp==0)
18441 + */
18442 + struct {
18443 + uint64_t reserved_62_63:2;
18444 + /* Set when there is a pending non-NULL SWTAG or
18445 + * SWTAG_FULL, and the POW entry has not left the list
18446 + * for the original tag. */
18447 + uint64_t pend_switch:1;
18448 + /* Set when SWTAG_FULL and pend_switch is set. */
18449 + uint64_t pend_switch_full:1;
18450 + /*
18451 + * Set when there is a pending NULL SWTAG, or an
18452 + * implicit switch to NULL.
18453 + */
18454 + uint64_t pend_switch_null:1;
18455 + /* Set when there is a pending DESCHED or SWTAG_DESCHED. */
18456 + uint64_t pend_desched:1;
18457 + /*
18458 + * Set when there is a pending SWTAG_DESCHED and
18459 + * pend_desched is set.
18460 + */
18461 + uint64_t pend_desched_switch:1;
18462 + /* Set when nosched is desired and pend_desched is set. */
18463 + uint64_t pend_nosched:1;
18464 + /* Set when there is a pending GET_WORK. */
18465 + uint64_t pend_new_work:1;
18466 + /*
18467 + * When pend_new_work is set, this bit indicates that
18468 + * the wait bit was set.
18469 + */
18470 + uint64_t pend_new_work_wait:1;
18471 + /* Set when there is a pending NULL_RD. */
18472 + uint64_t pend_null_rd:1;
18473 + /* Set when there is a pending CLR_NSCHED. */
18474 + uint64_t pend_nosched_clr:1;
18475 + uint64_t reserved_51:1;
18476 + /* This is the index when pend_nosched_clr is set. */
18477 + uint64_t pend_index:11;
18478 + /*
18479 + * This is the new_grp when (pend_desched AND
18480 + * pend_desched_switch) is set.
18481 + */
18482 + uint64_t pend_grp:4;
18483 + uint64_t reserved_34_35:2;
18484 + /*
18485 + * This is the tag type when pend_switch or
18486 + * (pend_desched AND pend_desched_switch) are set.
18487 + */
18488 + uint64_t pend_type:2;
18489 + /*
18490 + * - this is the tag when pend_switch or (pend_desched
18491 + * AND pend_desched_switch) are set.
18492 + */
18493 + uint64_t pend_tag:32;
18494 + } s_sstatus0;
18495 +
18496 + /**
18497 + * Result for a POW Status Load (when get_cur==0 and get_wqp==1)
18498 + */
18499 + struct {
18500 + uint64_t reserved_62_63:2;
18501 + /*
18502 + * Set when there is a pending non-NULL SWTAG or
18503 + * SWTAG_FULL, and the POW entry has not left the list
18504 + * for the original tag.
18505 + */
18506 + uint64_t pend_switch:1;
18507 + /* Set when SWTAG_FULL and pend_switch is set. */
18508 + uint64_t pend_switch_full:1;
18509 + /*
18510 + * Set when there is a pending NULL SWTAG, or an
18511 + * implicit switch to NULL.
18512 + */
18513 + uint64_t pend_switch_null:1;
18514 + /*
18515 + * Set when there is a pending DESCHED or
18516 + * SWTAG_DESCHED.
18517 + */
18518 + uint64_t pend_desched:1;
18519 + /*
18520 + * Set when there is a pending SWTAG_DESCHED and
18521 + * pend_desched is set.
18522 + */
18523 + uint64_t pend_desched_switch:1;
18524 + /* Set when nosched is desired and pend_desched is set. */
18525 + uint64_t pend_nosched:1;
18526 + /* Set when there is a pending GET_WORK. */
18527 + uint64_t pend_new_work:1;
18528 + /*
18529 + * When pend_new_work is set, this bit indicates that
18530 + * the wait bit was set.
18531 + */
18532 + uint64_t pend_new_work_wait:1;
18533 + /* Set when there is a pending NULL_RD. */
18534 + uint64_t pend_null_rd:1;
18535 + /* Set when there is a pending CLR_NSCHED. */
18536 + uint64_t pend_nosched_clr:1;
18537 + uint64_t reserved_51:1;
18538 + /* This is the index when pend_nosched_clr is set. */
18539 + uint64_t pend_index:11;
18540 + /*
18541 + * This is the new_grp when (pend_desched AND
18542 + * pend_desched_switch) is set.
18543 + */
18544 + uint64_t pend_grp:4;
18545 + /* This is the wqp when pend_nosched_clr is set. */
18546 + uint64_t pend_wqp:36;
18547 + } s_sstatus1;
18548 +
18549 + /**
18550 + * Result for a POW Status Load (when get_cur==1, get_wqp==0, and
18551 + * get_rev==0)
18552 + */
18553 + struct {
18554 + uint64_t reserved_62_63:2;
18555 + /*
18556 + * Points to the next POW entry in the tag list when
18557 + * tail == 0 (and tag_type is not NULL or NULL_NULL).
18558 + */
18559 + uint64_t link_index:11;
18560 + /* The POW entry attached to the core. */
18561 + uint64_t index:11;
18562 + /*
18563 + * The group attached to the core (updated when new
18564 + * tag list entered on SWTAG_FULL).
18565 + */
18566 + uint64_t grp:4;
18567 + /*
18568 + * Set when this POW entry is at the head of its tag
18569 + * list (also set when in the NULL or NULL_NULL
18570 + * state).
18571 + */
18572 + uint64_t head:1;
18573 + /*
18574 + * Set when this POW entry is at the tail of its tag
18575 + * list (also set when in the NULL or NULL_NULL
18576 + * state).
18577 + */
18578 + uint64_t tail:1;
18579 + /*
18580 + * The tag type attached to the core (updated when new
18581 + * tag list entered on SWTAG, SWTAG_FULL, or
18582 + * SWTAG_DESCHED).
18583 + */
18584 + uint64_t tag_type:2;
18585 + /*
18586 + * The tag attached to the core (updated when new tag
18587 + * list entered on SWTAG, SWTAG_FULL, or
18588 + * SWTAG_DESCHED).
18589 + */
18590 + uint64_t tag:32;
18591 + } s_sstatus2;
18592 +
18593 + /**
18594 + * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1)
18595 + */
18596 + struct {
18597 + uint64_t reserved_62_63:2;
18598 + /*
18599 + * Points to the prior POW entry in the tag list when
18600 + * head == 0 (and tag_type is not NULL or
18601 + * NULL_NULL). This field is unpredictable when the
18602 + * core's state is NULL or NULL_NULL.
18603 + */
18604 + uint64_t revlink_index:11;
18605 + /* The POW entry attached to the core. */
18606 + uint64_t index:11;
18607 + /*
18608 + * The group attached to the core (updated when new
18609 + * tag list entered on SWTAG_FULL).
18610 + */
18611 + uint64_t grp:4;
18612 + /* Set when this POW entry is at the head of its tag
18613 + * list (also set when in the NULL or NULL_NULL
18614 + * state).
18615 + */
18616 + uint64_t head:1;
18617 + /*
18618 + * Set when this POW entry is at the tail of its tag
18619 + * list (also set when in the NULL or NULL_NULL
18620 + * state).
18621 + */
18622 + uint64_t tail:1;
18623 + /*
18624 + * The tag type attached to the core (updated when new
18625 + * tag list entered on SWTAG, SWTAG_FULL, or
18626 + * SWTAG_DESCHED).
18627 + */
18628 + uint64_t tag_type:2;
18629 + /*
18630 + * The tag attached to the core (updated when new tag
18631 + * list entered on SWTAG, SWTAG_FULL, or
18632 + * SWTAG_DESCHED).
18633 + */
18634 + uint64_t tag:32;
18635 + } s_sstatus3;
18636 +
18637 + /**
18638 + * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
18639 + * get_rev==0)
18640 + */
18641 + struct {
18642 + uint64_t reserved_62_63:2;
18643 + /*
18644 + * Points to the next POW entry in the tag list when
18645 + * tail == 0 (and tag_type is not NULL or NULL_NULL).
18646 + */
18647 + uint64_t link_index:11;
18648 + /* The POW entry attached to the core. */
18649 + uint64_t index:11;
18650 + /*
18651 + * The group attached to the core (updated when new
18652 + * tag list entered on SWTAG_FULL).
18653 + */
18654 + uint64_t grp:4;
18655 + /*
18656 + * The wqp attached to the core (updated when new tag
18657 + * list entered on SWTAG_FULL).
18658 + */
18659 + uint64_t wqp:36;
18660 + } s_sstatus4;
18661 +
18662 + /**
18663 + * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
18664 + * get_rev==1)
18665 + */
18666 + struct {
18667 + uint64_t reserved_62_63:2;
18668 + /*
18669 + * Points to the prior POW entry in the tag list when
18670 + * head == 0 (and tag_type is not NULL or
18671 + * NULL_NULL). This field is unpredictable when the
18672 + * core's state is NULL or NULL_NULL.
18673 + */
18674 + uint64_t revlink_index:11;
18675 + /* The POW entry attached to the core. */
18676 + uint64_t index:11;
18677 + /*
18678 + * The group attached to the core (updated when new
18679 + * tag list entered on SWTAG_FULL).
18680 + */
18681 + uint64_t grp:4;
18682 + /*
18683 + * The wqp attached to the core (updated when new tag
18684 + * list entered on SWTAG_FULL).
18685 + */
18686 + uint64_t wqp:36;
18687 + } s_sstatus5;
18688 +
18689 + /**
18690 + * Result For POW Memory Load (get_des == 0 and get_wqp == 0)
18691 + */
18692 + struct {
18693 + uint64_t reserved_51_63:13;
18694 + /*
18695 + * The next entry in the input, free, descheduled_head
18696 + * list (unpredictable if entry is the tail of the
18697 + * list).
18698 + */
18699 + uint64_t next_index:11;
18700 + /* The group of the POW entry. */
18701 + uint64_t grp:4;
18702 + uint64_t reserved_35:1;
18703 + /*
18704 + * Set when this POW entry is at the tail of its tag
18705 + * list (also set when in the NULL or NULL_NULL
18706 + * state).
18707 + */
18708 + uint64_t tail:1;
18709 + /* The tag type of the POW entry. */
18710 + uint64_t tag_type:2;
18711 + /* The tag of the POW entry. */
18712 + uint64_t tag:32;
18713 + } s_smemload0;
18714 +
18715 + /**
18716 + * Result For POW Memory Load (get_des == 0 and get_wqp == 1)
18717 + */
18718 + struct {
18719 + uint64_t reserved_51_63:13;
18720 + /*
18721 + * The next entry in the input, free, descheduled_head
18722 + * list (unpredictable if entry is the tail of the
18723 + * list).
18724 + */
18725 + uint64_t next_index:11;
18726 + /* The group of the POW entry. */
18727 + uint64_t grp:4;
18728 + /* The WQP held in the POW entry. */
18729 + uint64_t wqp:36;
18730 + } s_smemload1;
18731 +
18732 + /**
18733 + * Result For POW Memory Load (get_des == 1)
18734 + */
18735 + struct {
18736 + uint64_t reserved_51_63:13;
18737 + /*
18738 + * The next entry in the tag list connected to the
18739 + * descheduled head.
18740 + */
18741 + uint64_t fwd_index:11;
18742 + /* The group of the POW entry. */
18743 + uint64_t grp:4;
18744 + /* The nosched bit for the POW entry. */
18745 + uint64_t nosched:1;
18746 + /* There is a pending tag switch */
18747 + uint64_t pend_switch:1;
18748 + /*
18749 + * The next tag type for the new tag list when
18750 + * pend_switch is set.
18751 + */
18752 + uint64_t pend_type:2;
18753 + /*
18754 + * The next tag for the new tag list when pend_switch
18755 + * is set.
18756 + */
18757 + uint64_t pend_tag:32;
18758 + } s_smemload2;
18759 +
18760 + /**
18761 + * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0)
18762 + */
18763 + struct {
18764 + uint64_t reserved_52_63:12;
18765 + /*
18766 + * set when there is one or more POW entries on the
18767 + * free list.
18768 + */
18769 + uint64_t free_val:1;
18770 + /*
18771 + * set when there is exactly one POW entry on the free
18772 + * list.
18773 + */
18774 + uint64_t free_one:1;
18775 + uint64_t reserved_49:1;
18776 + /*
18777 + * when free_val is set, indicates the first entry on
18778 + * the free list.
18779 + */
18780 + uint64_t free_head:11;
18781 + uint64_t reserved_37:1;
18782 + /*
18783 + * when free_val is set, indicates the last entry on
18784 + * the free list.
18785 + */
18786 + uint64_t free_tail:11;
18787 + /*
18788 + * set when there is one or more POW entries on the
18789 + * input Q list selected by qosgrp.
18790 + */
18791 + uint64_t loc_val:1;
18792 + /*
18793 + * set when there is exactly one POW entry on the
18794 + * input Q list selected by qosgrp.
18795 + */
18796 + uint64_t loc_one:1;
18797 + uint64_t reserved_23:1;
18798 + /*
18799 + * when loc_val is set, indicates the first entry on
18800 + * the input Q list selected by qosgrp.
18801 + */
18802 + uint64_t loc_head:11;
18803 + uint64_t reserved_11:1;
18804 + /*
18805 + * when loc_val is set, indicates the last entry on
18806 + * the input Q list selected by qosgrp.
18807 + */
18808 + uint64_t loc_tail:11;
18809 + } sindexload0;
18810 +
18811 + /**
18812 + * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1)
18813 + */
18814 + struct {
18815 + uint64_t reserved_52_63:12;
18816 + /*
18817 + * set when there is one or more POW entries on the
18818 + * nosched list.
18819 + */
18820 + uint64_t nosched_val:1;
18821 + /*
18822 + * set when there is exactly one POW entry on the
18823 + * nosched list.
18824 + */
18825 + uint64_t nosched_one:1;
18826 + uint64_t reserved_49:1;
18827 + /*
18828 + * when nosched_val is set, indicates the first entry
18829 + * on the nosched list.
18830 + */
18831 + uint64_t nosched_head:11;
18832 + uint64_t reserved_37:1;
18833 + /*
18834 + * when nosched_val is set, indicates the last entry
18835 + * on the nosched list.
18836 + */
18837 + uint64_t nosched_tail:11;
18838 + /*
18839 + * set when there is one or more descheduled heads on
18840 + * the descheduled list selected by qosgrp.
18841 + */
18842 + uint64_t des_val:1;
18843 + /*
18844 + * set when there is exactly one descheduled head on
18845 + * the descheduled list selected by qosgrp.
18846 + */
18847 + uint64_t des_one:1;
18848 + uint64_t reserved_23:1;
18849 + /*
18850 + * when des_val is set, indicates the first
18851 + * descheduled head on the descheduled list selected
18852 + * by qosgrp.
18853 + */
18854 + uint64_t des_head:11;
18855 + uint64_t reserved_11:1;
18856 + /*
18857 + * when des_val is set, indicates the last descheduled
18858 + * head on the descheduled list selected by qosgrp.
18859 + */
18860 + uint64_t des_tail:11;
18861 + } sindexload1;
18862 +
18863 + /**
18864 + * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0)
18865 + */
18866 + struct {
18867 + uint64_t reserved_39_63:25;
18868 + /*
18869 + * Set when this DRAM list is the current head
18870 + * (i.e. is the next to be reloaded when the POW
18871 + * hardware reloads a POW entry from DRAM). The POW
18872 + * hardware alternates between the two DRAM lists
18873 + * associated with a QOS level when it reloads work
18874 + * from DRAM into the POW unit.
18875 + */
18876 + uint64_t rmt_is_head:1;
18877 + /*
18878 + * Set when the DRAM portion of the input Q list
18879 + * selected by qosgrp contains one or more pieces of
18880 + * work.
18881 + */
18882 + uint64_t rmt_val:1;
18883 + /*
18884 + * Set when the DRAM portion of the input Q list
18885 + * selected by qosgrp contains exactly one piece of
18886 + * work.
18887 + */
18888 + uint64_t rmt_one:1;
18889 + /*
18890 + * When rmt_val is set, indicates the first piece of
18891 + * work on the DRAM input Q list selected by
18892 + * qosgrp.
18893 + */
18894 + uint64_t rmt_head:36;
18895 + } sindexload2;
18896 +
18897 + /**
18898 + * Result For POW Index/Pointer Load (get_rmt ==
18899 + * 1/get_des_get_tail == 1)
18900 + */
18901 + struct {
18902 + uint64_t reserved_39_63:25;
18903 + /*
18904 + * set when this DRAM list is the current head
18905 + * (i.e. is the next to be reloaded when the POW
18906 + * hardware reloads a POW entry from DRAM). The POW
18907 + * hardware alternates between the two DRAM lists
18908 + * associated with a QOS level when it reloads work
18909 + * from DRAM into the POW unit.
18910 + */
18911 + uint64_t rmt_is_head:1;
18912 + /*
18913 + * set when the DRAM portion of the input Q list
18914 + * selected by qosgrp contains one or more pieces of
18915 + * work.
18916 + */
18917 + uint64_t rmt_val:1;
18918 + /*
18919 + * set when the DRAM portion of the input Q list
18920 + * selected by qosgrp contains exactly one piece of
18921 + * work.
18922 + */
18923 + uint64_t rmt_one:1;
18924 + /*
18925 + * when rmt_val is set, indicates the last piece of
18926 + * work on the DRAM input Q list selected by
18927 + * qosgrp.
18928 + */
18929 + uint64_t rmt_tail:36;
18930 + } sindexload3;
18931 +
18932 + /**
18933 + * Response to NULL_RD request loads
18934 + */
18935 + struct {
18936 + uint64_t unused:62;
18937 + /* of type cvmx_pow_tag_type_t. state is one of the
18938 + * following:
18939 + *
18940 + * - CVMX_POW_TAG_TYPE_ORDERED
18941 + * - CVMX_POW_TAG_TYPE_ATOMIC
18942 + * - CVMX_POW_TAG_TYPE_NULL
18943 + * - CVMX_POW_TAG_TYPE_NULL_NULL
18944 + */
18945 + uint64_t state:2;
18946 + } s_null_rd;
18947 +
18948 +} cvmx_pow_tag_load_resp_t;
18949 +
18950 +/**
18951 + * This structure describes the address used for stores to the POW.
18952 + * The store address is meaningful on stores to the POW. The
18953 + * hardware assumes that an aligned 64-bit store was used for all
18954 + * these stores. Note the assumption that the work queue entry is
18955 + * aligned on an 8-byte boundary (since the low-order 3 address bits
18956 + * must be zero). Note that not all fields are used by all
18957 + * operations.
18958 + *
18959 + * NOTE: The following is the behavior of the pending switch bit at the PP
18960 + * for POW stores (i.e. when did<7:3> == 0xc)
18961 + * - did<2:0> == 0 => pending switch bit is set
18962 + * - did<2:0> == 1 => no affect on the pending switch bit
18963 + * - did<2:0> == 3 => pending switch bit is cleared
18964 + * - did<2:0> == 7 => no affect on the pending switch bit
18965 + * - did<2:0> == others => must not be used
18966 + * - No other loads/stores have an affect on the pending switch bit
18967 + * - The switch bus from POW can clear the pending switch bit
18968 + *
18969 + * NOTE: did<2:0> == 2 is used by the HW for a special single-cycle
18970 + * ADDWQ command that only contains the pointer). SW must never use
18971 + * did<2:0> == 2.
18972 + */
18973 +typedef union {
18974 + /**
18975 + * Unsigned 64 bit integer representation of store address
18976 + */
18977 + uint64_t u64;
18978 +
18979 + struct {
18980 + /* Memory region. Should be CVMX_IO_SEG in most cases */
18981 + uint64_t mem_reg:2;
18982 + uint64_t reserved_49_61:13; /* Must be zero */
18983 + uint64_t is_io:1; /* Must be one */
18984 + /* Device ID of POW. Note that different sub-dids are used. */
18985 + uint64_t did:8;
18986 + uint64_t reserved_36_39:4; /* Must be zero */
18987 + /* Address field. addr<2:0> must be zero */
18988 + uint64_t addr:36;
18989 + } stag;
18990 +} cvmx_pow_tag_store_addr_t;
18991 +
18992 +/**
18993 + * decode of the store data when an IOBDMA SENDSINGLE is sent to POW
18994 + */
18995 +typedef union {
18996 + uint64_t u64;
18997 +
18998 + struct {
18999 + /*
19000 + * the (64-bit word) location in scratchpad to write
19001 + * to (if len != 0)
19002 + */
19003 + uint64_t scraddr:8;
19004 + /* the number of words in the response (0 => no response) */
19005 + uint64_t len:8;
19006 + /* the ID of the device on the non-coherent bus */
19007 + uint64_t did:8;
19008 + uint64_t unused:36;
19009 + /* if set, don't return load response until work is available */
19010 + uint64_t wait:1;
19011 + uint64_t unused2:3;
19012 + } s;
19013 +
19014 +} cvmx_pow_iobdma_store_t;
19015 +
19016 +/* CSR typedefs have been moved to cvmx-csr-*.h */
19017 +
19018 +/**
19019 + * Get the POW tag for this core. This returns the current
19020 + * tag type, tag, group, and POW entry index associated with
19021 + * this core. Index is only valid if the tag type isn't NULL_NULL.
19022 + * If a tag switch is pending this routine returns the tag before
19023 + * the tag switch, not after.
19024 + *
19025 + * Returns Current tag
19026 + */
19027 +static inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void)
19028 +{
19029 + cvmx_pow_load_addr_t load_addr;
19030 + cvmx_pow_tag_load_resp_t load_resp;
19031 + cvmx_pow_tag_req_t result;
19032 +
19033 + load_addr.u64 = 0;
19034 + load_addr.sstatus.mem_region = CVMX_IO_SEG;
19035 + load_addr.sstatus.is_io = 1;
19036 + load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
19037 + load_addr.sstatus.coreid = cvmx_get_core_num();
19038 + load_addr.sstatus.get_cur = 1;
19039 + load_resp.u64 = cvmx_read_csr(load_addr.u64);
19040 + result.u64 = 0;
19041 + result.s.grp = load_resp.s_sstatus2.grp;
19042 + result.s.index = load_resp.s_sstatus2.index;
19043 + result.s.type = load_resp.s_sstatus2.tag_type;
19044 + result.s.tag = load_resp.s_sstatus2.tag;
19045 + return result;
19046 +}
19047 +
19048 +/**
19049 + * Get the POW WQE for this core. This returns the work queue
19050 + * entry currently associated with this core.
19051 + *
19052 + * Returns WQE pointer
19053 + */
19054 +static inline cvmx_wqe_t *cvmx_pow_get_current_wqp(void)
19055 +{
19056 + cvmx_pow_load_addr_t load_addr;
19057 + cvmx_pow_tag_load_resp_t load_resp;
19058 +
19059 + load_addr.u64 = 0;
19060 + load_addr.sstatus.mem_region = CVMX_IO_SEG;
19061 + load_addr.sstatus.is_io = 1;
19062 + load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
19063 + load_addr.sstatus.coreid = cvmx_get_core_num();
19064 + load_addr.sstatus.get_cur = 1;
19065 + load_addr.sstatus.get_wqp = 1;
19066 + load_resp.u64 = cvmx_read_csr(load_addr.u64);
19067 + return (cvmx_wqe_t *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp);
19068 +}
19069 +
19070 +#ifndef CVMX_MF_CHORD
19071 +#define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30)
19072 +#endif
19073 +
19074 +/**
19075 + * Print a warning if a tag switch is pending for this core
19076 + *
19077 + * @function: Function name checking for a pending tag switch
19078 + */
19079 +static inline void __cvmx_pow_warn_if_pending_switch(const char *function)
19080 +{
19081 + uint64_t switch_complete;
19082 + CVMX_MF_CHORD(switch_complete);
19083 + if (!switch_complete)
19084 + pr_warning("%s called with tag switch in progress\n", function);
19085 +}
19086 +
19087 +/**
19088 + * Waits for a tag switch to complete by polling the completion bit.
19089 + * Note that switches to NULL complete immediately and do not need
19090 + * to be waited for.
19091 + */
19092 +static inline void cvmx_pow_tag_sw_wait(void)
19093 +{
19094 + const uint64_t MAX_CYCLES = 1ull << 31;
19095 + uint64_t switch_complete;
19096 + uint64_t start_cycle = cvmx_get_cycle();
19097 + while (1) {
19098 + CVMX_MF_CHORD(switch_complete);
19099 + if (unlikely(switch_complete))
19100 + break;
19101 + if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) {
19102 + pr_warning("Tag switch is taking a long time, "
19103 + "possible deadlock\n");
19104 + start_cycle = -MAX_CYCLES - 1;
19105 + }
19106 + }
19107 +}
19108 +
19109 +/**
19110 + * Synchronous work request. Requests work from the POW.
19111 + * This function does NOT wait for previous tag switches to complete,
19112 + * so the caller must ensure that there is not a pending tag switch.
19113 + *
19114 + * @wait: When set, call stalls until work becomes avaiable, or times out.
19115 + * If not set, returns immediately.
19116 + *
19117 + * Returns Returns the WQE pointer from POW. Returns NULL if no work
19118 + * was available.
19119 + */
19120 +static inline cvmx_wqe_t *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t
19121 + wait)
19122 +{
19123 + cvmx_pow_load_addr_t ptr;
19124 + cvmx_pow_tag_load_resp_t result;
19125 +
19126 + if (CVMX_ENABLE_POW_CHECKS)
19127 + __cvmx_pow_warn_if_pending_switch(__func__);
19128 +
19129 + ptr.u64 = 0;
19130 + ptr.swork.mem_region = CVMX_IO_SEG;
19131 + ptr.swork.is_io = 1;
19132 + ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG;
19133 + ptr.swork.wait = wait;
19134 +
19135 + result.u64 = cvmx_read_csr(ptr.u64);
19136 +
19137 + if (result.s_work.no_work)
19138 + return NULL;
19139 + else
19140 + return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
19141 +}
19142 +
19143 +/**
19144 + * Synchronous work request. Requests work from the POW.
19145 + * This function waits for any previous tag switch to complete before
19146 + * requesting the new work.
19147 + *
19148 + * @wait: When set, call stalls until work becomes avaiable, or times out.
19149 + * If not set, returns immediately.
19150 + *
19151 + * Returns Returns the WQE pointer from POW. Returns NULL if no work
19152 + * was available.
19153 + */
19154 +static inline cvmx_wqe_t *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
19155 +{
19156 + if (CVMX_ENABLE_POW_CHECKS)
19157 + __cvmx_pow_warn_if_pending_switch(__func__);
19158 +
19159 + /* Must not have a switch pending when requesting work */
19160 + cvmx_pow_tag_sw_wait();
19161 + return cvmx_pow_work_request_sync_nocheck(wait);
19162 +
19163 +}
19164 +
19165 +/**
19166 + * Synchronous null_rd request. Requests a switch out of NULL_NULL POW state.
19167 + * This function waits for any previous tag switch to complete before
19168 + * requesting the null_rd.
19169 + *
19170 + * Returns Returns the POW state of type cvmx_pow_tag_type_t.
19171 + */
19172 +static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void)
19173 +{
19174 + cvmx_pow_load_addr_t ptr;
19175 + cvmx_pow_tag_load_resp_t result;
19176 +
19177 + if (CVMX_ENABLE_POW_CHECKS)
19178 + __cvmx_pow_warn_if_pending_switch(__func__);
19179 +
19180 + /* Must not have a switch pending when requesting work */
19181 + cvmx_pow_tag_sw_wait();
19182 +
19183 + ptr.u64 = 0;
19184 + ptr.snull_rd.mem_region = CVMX_IO_SEG;
19185 + ptr.snull_rd.is_io = 1;
19186 + ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD;
19187 +
19188 + result.u64 = cvmx_read_csr(ptr.u64);
19189 +
19190 + return (enum cvmx_pow_tag_type) result.s_null_rd.state;
19191 +}
19192 +
19193 +/**
19194 + * Asynchronous work request. Work is requested from the POW unit,
19195 + * and should later be checked with function
19196 + * cvmx_pow_work_response_async. This function does NOT wait for
19197 + * previous tag switches to complete, so the caller must ensure that
19198 + * there is not a pending tag switch.
19199 + *
19200 + * @scr_addr: Scratch memory address that response will be returned
19201 + * to, which is either a valid WQE, or a response with the
19202 + * invalid bit set. Byte address, must be 8 byte aligned.
19203 + *
19204 + * @wait: 1 to cause response to wait for work to become available (or
19205 + * timeout), 0 to cause response to return immediately
19206 + */
19207 +static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
19208 + cvmx_pow_wait_t wait)
19209 +{
19210 + cvmx_pow_iobdma_store_t data;
19211 +
19212 + if (CVMX_ENABLE_POW_CHECKS)
19213 + __cvmx_pow_warn_if_pending_switch(__func__);
19214 +
19215 + /* scr_addr must be 8 byte aligned */
19216 + data.s.scraddr = scr_addr >> 3;
19217 + data.s.len = 1;
19218 + data.s.did = CVMX_OCT_DID_TAG_SWTAG;
19219 + data.s.wait = wait;
19220 + cvmx_send_single(data.u64);
19221 +}
19222 +
19223 +/**
19224 + * Asynchronous work request. Work is requested from the POW unit,
19225 + * and should later be checked with function
19226 + * cvmx_pow_work_response_async. This function waits for any previous
19227 + * tag switch to complete before requesting the new work.
19228 + *
19229 + * @scr_addr: Scratch memory address that response will be returned
19230 + * to, which is either a valid WQE, or a response with the
19231 + * invalid bit set. Byte address, must be 8 byte aligned.
19232 + *
19233 + * @wait: 1 to cause response to wait for work to become available (or
19234 + * timeout), 0 to cause response to return immediately
19235 + */
19236 +static inline void cvmx_pow_work_request_async(int scr_addr,
19237 + cvmx_pow_wait_t wait)
19238 +{
19239 + if (CVMX_ENABLE_POW_CHECKS)
19240 + __cvmx_pow_warn_if_pending_switch(__func__);
19241 +
19242 + /* Must not have a switch pending when requesting work */
19243 + cvmx_pow_tag_sw_wait();
19244 + cvmx_pow_work_request_async_nocheck(scr_addr, wait);
19245 +}
19246 +
19247 +/**
19248 + * Gets result of asynchronous work request. Performs a IOBDMA sync
19249 + * to wait for the response.
19250 + *
19251 + * @scr_addr: Scratch memory address to get result from Byte address,
19252 + * must be 8 byte aligned.
19253 + *
19254 + * Returns Returns the WQE from the scratch register, or NULL if no
19255 + * work was available.
19256 + */
19257 +static inline cvmx_wqe_t *cvmx_pow_work_response_async(int scr_addr)
19258 +{
19259 + cvmx_pow_tag_load_resp_t result;
19260 +
19261 + CVMX_SYNCIOBDMA;
19262 + result.u64 = cvmx_scratch_read64(scr_addr);
19263 +
19264 + if (result.s_work.no_work)
19265 + return NULL;
19266 + else
19267 + return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
19268 +}
19269 +
19270 +/**
19271 + * Checks if a work queue entry pointer returned by a work
19272 + * request is valid. It may be invalid due to no work
19273 + * being available or due to a timeout.
19274 + *
19275 + * @wqe_ptr: pointer to a work queue entry returned by the POW
19276 + *
19277 + * Returns 0 if pointer is valid
19278 + * 1 if invalid (no work was returned)
19279 + */
19280 +static inline uint64_t cvmx_pow_work_invalid(cvmx_wqe_t *wqe_ptr)
19281 +{
19282 + return wqe_ptr == NULL;
19283 +}
19284 +
19285 +/**
19286 + * Starts a tag switch to the provided tag value and tag type.
19287 + * Completion for the tag switch must be checked for separately. This
19288 + * function does NOT update the work queue entry in dram to match tag
19289 + * value and type, so the application must keep track of these if they
19290 + * are important to the application. This tag switch command must not
19291 + * be used for switches to NULL, as the tag switch pending bit will be
19292 + * set by the switch request, but never cleared by the hardware.
19293 + *
19294 + * NOTE: This should not be used when switching from a NULL tag. Use
19295 + * cvmx_pow_tag_sw_full() instead.
19296 + *
19297 + * This function does no checks, so the caller must ensure that any
19298 + * previous tag switch has completed.
19299 + *
19300 + * @tag: new tag value
19301 + * @tag_type: new tag type (ordered or atomic)
19302 + */
19303 +static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag,
19304 + enum cvmx_pow_tag_type tag_type)
19305 +{
19306 + cvmx_addr_t ptr;
19307 + cvmx_pow_tag_req_t tag_req;
19308 +
19309 + if (CVMX_ENABLE_POW_CHECKS) {
19310 + cvmx_pow_tag_req_t current_tag;
19311 + __cvmx_pow_warn_if_pending_switch(__func__);
19312 + current_tag = cvmx_pow_get_current_tag();
19313 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19314 + pr_warning("%s called with NULL_NULL tag\n",
19315 + __func__);
19316 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19317 + pr_warning("%s called with NULL tag\n", __func__);
19318 + if ((current_tag.s.type == tag_type)
19319 + && (current_tag.s.tag == tag))
19320 + pr_warning("%s called to perform a tag switch to the "
19321 + "same tag\n",
19322 + __func__);
19323 + if (tag_type == CVMX_POW_TAG_TYPE_NULL)
19324 + pr_warning("%s called to perform a tag switch to "
19325 + "NULL. Use cvmx_pow_tag_sw_null() instead\n",
19326 + __func__);
19327 + }
19328 +
19329 + /*
19330 + * Note that WQE in DRAM is not updated here, as the POW does
19331 + * not read from DRAM once the WQE is in flight. See hardware
19332 + * manual for complete details. It is the application's
19333 + * responsibility to keep track of the current tag value if
19334 + * that is important.
19335 + */
19336 +
19337 + tag_req.u64 = 0;
19338 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
19339 + tag_req.s.tag = tag;
19340 + tag_req.s.type = tag_type;
19341 +
19342 + ptr.u64 = 0;
19343 + ptr.sio.mem_region = CVMX_IO_SEG;
19344 + ptr.sio.is_io = 1;
19345 + ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
19346 +
19347 + /* once this store arrives at POW, it will attempt the switch
19348 + software must wait for the switch to complete separately */
19349 + cvmx_write_io(ptr.u64, tag_req.u64);
19350 +}
19351 +
19352 +/**
19353 + * Starts a tag switch to the provided tag value and tag type.
19354 + * Completion for the tag switch must be checked for separately. This
19355 + * function does NOT update the work queue entry in dram to match tag
19356 + * value and type, so the application must keep track of these if they
19357 + * are important to the application. This tag switch command must not
19358 + * be used for switches to NULL, as the tag switch pending bit will be
19359 + * set by the switch request, but never cleared by the hardware.
19360 + *
19361 + * NOTE: This should not be used when switching from a NULL tag. Use
19362 + * cvmx_pow_tag_sw_full() instead.
19363 + *
19364 + * This function waits for any previous tag switch to complete, and also
19365 + * displays an error on tag switches to NULL.
19366 + *
19367 + * @tag: new tag value
19368 + * @tag_type: new tag type (ordered or atomic)
19369 + */
19370 +static inline void cvmx_pow_tag_sw(uint32_t tag,
19371 + enum cvmx_pow_tag_type tag_type)
19372 +{
19373 + if (CVMX_ENABLE_POW_CHECKS)
19374 + __cvmx_pow_warn_if_pending_switch(__func__);
19375 +
19376 + /*
19377 + * Note that WQE in DRAM is not updated here, as the POW does
19378 + * not read from DRAM once the WQE is in flight. See hardware
19379 + * manual for complete details. It is the application's
19380 + * responsibility to keep track of the current tag value if
19381 + * that is important.
19382 + */
19383 +
19384 + /*
19385 + * Ensure that there is not a pending tag switch, as a tag
19386 + * switch cannot be started if a previous switch is still
19387 + * pending.
19388 + */
19389 + cvmx_pow_tag_sw_wait();
19390 + cvmx_pow_tag_sw_nocheck(tag, tag_type);
19391 +}
19392 +
19393 +/**
19394 + * Starts a tag switch to the provided tag value and tag type.
19395 + * Completion for the tag switch must be checked for separately. This
19396 + * function does NOT update the work queue entry in dram to match tag
19397 + * value and type, so the application must keep track of these if they
19398 + * are important to the application. This tag switch command must not
19399 + * be used for switches to NULL, as the tag switch pending bit will be
19400 + * set by the switch request, but never cleared by the hardware.
19401 + *
19402 + * This function must be used for tag switches from NULL.
19403 + *
19404 + * This function does no checks, so the caller must ensure that any
19405 + * previous tag switch has completed.
19406 + *
19407 + * @wqp: pointer to work queue entry to submit. This entry is
19408 + * updated to match the other parameters
19409 + * @tag: tag value to be assigned to work queue entry
19410 + * @tag_type: type of tag
19411 + * @group: group value for the work queue entry.
19412 + */
19413 +static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag,
19414 + enum cvmx_pow_tag_type tag_type,
19415 + uint64_t group)
19416 +{
19417 + cvmx_addr_t ptr;
19418 + cvmx_pow_tag_req_t tag_req;
19419 +
19420 + if (CVMX_ENABLE_POW_CHECKS) {
19421 + cvmx_pow_tag_req_t current_tag;
19422 + __cvmx_pow_warn_if_pending_switch(__func__);
19423 + current_tag = cvmx_pow_get_current_tag();
19424 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19425 + pr_warning("%s called with NULL_NULL tag\n",
19426 + __func__);
19427 + if ((current_tag.s.type == tag_type)
19428 + && (current_tag.s.tag == tag))
19429 + pr_warning("%s called to perform a tag switch to "
19430 + "the same tag\n",
19431 + __func__);
19432 + if (tag_type == CVMX_POW_TAG_TYPE_NULL)
19433 + pr_warning("%s called to perform a tag switch to "
19434 + "NULL. Use cvmx_pow_tag_sw_null() instead\n",
19435 + __func__);
19436 + if (wqp != cvmx_phys_to_ptr(0x80))
19437 + if (wqp != cvmx_pow_get_current_wqp())
19438 + pr_warning("%s passed WQE(%p) doesn't match "
19439 + "the address in the POW(%p)\n",
19440 + __func__, wqp,
19441 + cvmx_pow_get_current_wqp());
19442 + }
19443 +
19444 + /*
19445 + * Note that WQE in DRAM is not updated here, as the POW does
19446 + * not read from DRAM once the WQE is in flight. See hardware
19447 + * manual for complete details. It is the application's
19448 + * responsibility to keep track of the current tag value if
19449 + * that is important.
19450 + */
19451 +
19452 + tag_req.u64 = 0;
19453 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL;
19454 + tag_req.s.tag = tag;
19455 + tag_req.s.type = tag_type;
19456 + tag_req.s.grp = group;
19457 +
19458 + ptr.u64 = 0;
19459 + ptr.sio.mem_region = CVMX_IO_SEG;
19460 + ptr.sio.is_io = 1;
19461 + ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
19462 + ptr.sio.offset = CAST64(wqp);
19463 +
19464 + /*
19465 + * once this store arrives at POW, it will attempt the switch
19466 + * software must wait for the switch to complete separately.
19467 + */
19468 + cvmx_write_io(ptr.u64, tag_req.u64);
19469 +}
19470 +
19471 +/**
19472 + * Starts a tag switch to the provided tag value and tag type.
19473 + * Completion for the tag switch must be checked for separately. This
19474 + * function does NOT update the work queue entry in dram to match tag
19475 + * value and type, so the application must keep track of these if they
19476 + * are important to the application. This tag switch command must not
19477 + * be used for switches to NULL, as the tag switch pending bit will be
19478 + * set by the switch request, but never cleared by the hardware.
19479 + *
19480 + * This function must be used for tag switches from NULL.
19481 + *
19482 + * This function waits for any pending tag switches to complete
19483 + * before requesting the tag switch.
19484 + *
19485 + * @wqp: pointer to work queue entry to submit. This entry is updated
19486 + * to match the other parameters
19487 + * @tag: tag value to be assigned to work queue entry
19488 + * @tag_type: type of tag
19489 + * @group: group value for the work queue entry.
19490 + */
19491 +static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag,
19492 + enum cvmx_pow_tag_type tag_type,
19493 + uint64_t group)
19494 +{
19495 + if (CVMX_ENABLE_POW_CHECKS)
19496 + __cvmx_pow_warn_if_pending_switch(__func__);
19497 +
19498 + /*
19499 + * Ensure that there is not a pending tag switch, as a tag
19500 + * switch cannot be started if a previous switch is still
19501 + * pending.
19502 + */
19503 + cvmx_pow_tag_sw_wait();
19504 + cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group);
19505 +}
19506 +
19507 +/**
19508 + * Switch to a NULL tag, which ends any ordering or
19509 + * synchronization provided by the POW for the current
19510 + * work queue entry. This operation completes immediatly,
19511 + * so completetion should not be waited for.
19512 + * This function does NOT wait for previous tag switches to complete,
19513 + * so the caller must ensure that any previous tag switches have completed.
19514 + */
19515 +static inline void cvmx_pow_tag_sw_null_nocheck(void)
19516 +{
19517 + cvmx_addr_t ptr;
19518 + cvmx_pow_tag_req_t tag_req;
19519 +
19520 + if (CVMX_ENABLE_POW_CHECKS) {
19521 + cvmx_pow_tag_req_t current_tag;
19522 + __cvmx_pow_warn_if_pending_switch(__func__);
19523 + current_tag = cvmx_pow_get_current_tag();
19524 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19525 + pr_warning("%s called with NULL_NULL tag\n",
19526 + __func__);
19527 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19528 + pr_warning("%s called when we already have a "
19529 + "NULL tag\n",
19530 + __func__);
19531 + }
19532 +
19533 + tag_req.u64 = 0;
19534 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
19535 + tag_req.s.type = CVMX_POW_TAG_TYPE_NULL;
19536 +
19537 + ptr.u64 = 0;
19538 + ptr.sio.mem_region = CVMX_IO_SEG;
19539 + ptr.sio.is_io = 1;
19540 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
19541 +
19542 + cvmx_write_io(ptr.u64, tag_req.u64);
19543 +
19544 + /* switch to NULL completes immediately */
19545 +}
19546 +
19547 +/**
19548 + * Switch to a NULL tag, which ends any ordering or
19549 + * synchronization provided by the POW for the current
19550 + * work queue entry. This operation completes immediatly,
19551 + * so completetion should not be waited for.
19552 + * This function waits for any pending tag switches to complete
19553 + * before requesting the switch to NULL.
19554 + */
19555 +static inline void cvmx_pow_tag_sw_null(void)
19556 +{
19557 + if (CVMX_ENABLE_POW_CHECKS)
19558 + __cvmx_pow_warn_if_pending_switch(__func__);
19559 +
19560 + /*
19561 + * Ensure that there is not a pending tag switch, as a tag
19562 + * switch cannot be started if a previous switch is still
19563 + * pending.
19564 + */
19565 + cvmx_pow_tag_sw_wait();
19566 + cvmx_pow_tag_sw_null_nocheck();
19567 +
19568 + /* switch to NULL completes immediately */
19569 +}
19570 +
19571 +/**
19572 + * Submits work to an input queue. This function updates the work
19573 + * queue entry in DRAM to match the arguments given. Note that the
19574 + * tag provided is for the work queue entry submitted, and is
19575 + * unrelated to the tag that the core currently holds.
19576 + *
19577 + * @wqp: pointer to work queue entry to submit. This entry is
19578 + * updated to match the other parameters
19579 + * @tag: tag value to be assigned to work queue entry
19580 + * @tag_type: type of tag
19581 + * @qos: Input queue to add to.
19582 + * @grp: group value for the work queue entry.
19583 + */
19584 +static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag,
19585 + enum cvmx_pow_tag_type tag_type,
19586 + uint64_t qos, uint64_t grp)
19587 +{
19588 + cvmx_addr_t ptr;
19589 + cvmx_pow_tag_req_t tag_req;
19590 +
19591 + wqp->qos = qos;
19592 + wqp->tag = tag;
19593 + wqp->tag_type = tag_type;
19594 + wqp->grp = grp;
19595 +
19596 + tag_req.u64 = 0;
19597 + tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ;
19598 + tag_req.s.type = tag_type;
19599 + tag_req.s.tag = tag;
19600 + tag_req.s.qos = qos;
19601 + tag_req.s.grp = grp;
19602 +
19603 + ptr.u64 = 0;
19604 + ptr.sio.mem_region = CVMX_IO_SEG;
19605 + ptr.sio.is_io = 1;
19606 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
19607 + ptr.sio.offset = cvmx_ptr_to_phys(wqp);
19608 +
19609 + /*
19610 + * SYNC write to memory before the work submit. This is
19611 + * necessary as POW may read values from DRAM at this time.
19612 + */
19613 + CVMX_SYNCWS;
19614 + cvmx_write_io(ptr.u64, tag_req.u64);
19615 +}
19616 +
19617 +/**
19618 + * This function sets the group mask for a core. The group mask
19619 + * indicates which groups each core will accept work from. There are
19620 + * 16 groups.
19621 + *
19622 + * @core_num: core to apply mask to
19623 + * @mask: Group mask. There are 16 groups, so only bits 0-15 are valid,
19624 + * representing groups 0-15.
19625 + * Each 1 bit in the mask enables the core to accept work from
19626 + * the corresponding group.
19627 + */
19628 +static inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask)
19629 +{
19630 + union cvmx_pow_pp_grp_mskx grp_msk;
19631 +
19632 + grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
19633 + grp_msk.s.grp_msk = mask;
19634 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
19635 +}
19636 +
19637 +/**
19638 + * This function sets POW static priorities for a core. Each input queue has
19639 + * an associated priority value.
19640 + *
19641 + * @core_num: core to apply priorities to
19642 + * @priority: Vector of 8 priorities, one per POW Input Queue (0-7).
19643 + * Highest priority is 0 and lowest is 7. A priority value
19644 + * of 0xF instructs POW to skip the Input Queue when
19645 + * scheduling to this specific core.
19646 + * NOTE: priorities should not have gaps in values, meaning
19647 + * {0,1,1,1,1,1,1,1} is a valid configuration while
19648 + * {0,2,2,2,2,2,2,2} is not.
19649 + */
19650 +static inline void cvmx_pow_set_priority(uint64_t core_num,
19651 + const uint8_t priority[])
19652 +{
19653 + /* POW priorities are supported on CN5xxx and later */
19654 + if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
19655 + union cvmx_pow_pp_grp_mskx grp_msk;
19656 +
19657 + grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
19658 + grp_msk.s.qos0_pri = priority[0];
19659 + grp_msk.s.qos1_pri = priority[1];
19660 + grp_msk.s.qos2_pri = priority[2];
19661 + grp_msk.s.qos3_pri = priority[3];
19662 + grp_msk.s.qos4_pri = priority[4];
19663 + grp_msk.s.qos5_pri = priority[5];
19664 + grp_msk.s.qos6_pri = priority[6];
19665 + grp_msk.s.qos7_pri = priority[7];
19666 +
19667 + /* Detect gaps between priorities and flag error */
19668 + {
19669 + int i;
19670 + uint32_t prio_mask = 0;
19671 +
19672 + for (i = 0; i < 8; i++)
19673 + if (priority[i] != 0xF)
19674 + prio_mask |= 1 << priority[i];
19675 +
19676 + if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) {
19677 + pr_err("POW static priorities should be "
19678 + "contiguous (0x%llx)\n",
19679 + (unsigned long long)prio_mask);
19680 + return;
19681 + }
19682 + }
19683 +
19684 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
19685 + }
19686 +}
19687 +
19688 +/**
19689 + * Performs a tag switch and then an immediate deschedule. This completes
19690 + * immediatly, so completion must not be waited for. This function does NOT
19691 + * update the wqe in DRAM to match arguments.
19692 + *
19693 + * This function does NOT wait for any prior tag switches to complete, so the
19694 + * calling code must do this.
19695 + *
19696 + * Note the following CAVEAT of the Octeon HW behavior when
19697 + * re-scheduling DE-SCHEDULEd items whose (next) state is
19698 + * ORDERED:
19699 + * - If there are no switches pending at the time that the
19700 + * HW executes the de-schedule, the HW will only re-schedule
19701 + * the head of the FIFO associated with the given tag. This
19702 + * means that in many respects, the HW treats this ORDERED
19703 + * tag as an ATOMIC tag. Note that in the SWTAG_DESCH
19704 + * case (to an ORDERED tag), the HW will do the switch
19705 + * before the deschedule whenever it is possible to do
19706 + * the switch immediately, so it may often look like
19707 + * this case.
19708 + * - If there is a pending switch to ORDERED at the time
19709 + * the HW executes the de-schedule, the HW will perform
19710 + * the switch at the time it re-schedules, and will be
19711 + * able to reschedule any/all of the entries with the
19712 + * same tag.
19713 + * Due to this behavior, the RECOMMENDATION to software is
19714 + * that they have a (next) state of ATOMIC when they
19715 + * DE-SCHEDULE. If an ORDERED tag is what was really desired,
19716 + * SW can choose to immediately switch to an ORDERED tag
19717 + * after the work (that has an ATOMIC tag) is re-scheduled.
19718 + * Note that since there are never any tag switches pending
19719 + * when the HW re-schedules, this switch can be IMMEDIATE upon
19720 + * the reception of the pointer during the re-schedule.
19721 + *
19722 + * @tag: New tag value
19723 + * @tag_type: New tag type
19724 + * @group: New group value
19725 + * @no_sched: Control whether this work queue entry will be rescheduled.
19726 + * - 1 : don't schedule this work
19727 + * - 0 : allow this work to be scheduled.
19728 + */
19729 +static inline void cvmx_pow_tag_sw_desched_nocheck(
19730 + uint32_t tag,
19731 + enum cvmx_pow_tag_type tag_type,
19732 + uint64_t group,
19733 + uint64_t no_sched)
19734 +{
19735 + cvmx_addr_t ptr;
19736 + cvmx_pow_tag_req_t tag_req;
19737 +
19738 + if (CVMX_ENABLE_POW_CHECKS) {
19739 + cvmx_pow_tag_req_t current_tag;
19740 + __cvmx_pow_warn_if_pending_switch(__func__);
19741 + current_tag = cvmx_pow_get_current_tag();
19742 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19743 + pr_warning("%s called with NULL_NULL tag\n",
19744 + __func__);
19745 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19746 + pr_warning("%s called with NULL tag. Deschedule not "
19747 + "allowed from NULL state\n",
19748 + __func__);
19749 + if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC)
19750 + && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC))
19751 + pr_warning("%s called where neither the before or "
19752 + "after tag is ATOMIC\n",
19753 + __func__);
19754 + }
19755 +
19756 + tag_req.u64 = 0;
19757 + tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH;
19758 + tag_req.s.tag = tag;
19759 + tag_req.s.type = tag_type;
19760 + tag_req.s.grp = group;
19761 + tag_req.s.no_sched = no_sched;
19762 +
19763 + ptr.u64 = 0;
19764 + ptr.sio.mem_region = CVMX_IO_SEG;
19765 + ptr.sio.is_io = 1;
19766 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
19767 + /*
19768 + * since TAG3 is used, this store will clear the local pending
19769 + * switch bit.
19770 + */
19771 + cvmx_write_io(ptr.u64, tag_req.u64);
19772 +}
19773 +
19774 +/**
19775 + * Performs a tag switch and then an immediate deschedule. This completes
19776 + * immediatly, so completion must not be waited for. This function does NOT
19777 + * update the wqe in DRAM to match arguments.
19778 + *
19779 + * This function waits for any prior tag switches to complete, so the
19780 + * calling code may call this function with a pending tag switch.
19781 + *
19782 + * Note the following CAVEAT of the Octeon HW behavior when
19783 + * re-scheduling DE-SCHEDULEd items whose (next) state is
19784 + * ORDERED:
19785 + * - If there are no switches pending at the time that the
19786 + * HW executes the de-schedule, the HW will only re-schedule
19787 + * the head of the FIFO associated with the given tag. This
19788 + * means that in many respects, the HW treats this ORDERED
19789 + * tag as an ATOMIC tag. Note that in the SWTAG_DESCH
19790 + * case (to an ORDERED tag), the HW will do the switch
19791 + * before the deschedule whenever it is possible to do
19792 + * the switch immediately, so it may often look like
19793 + * this case.
19794 + * - If there is a pending switch to ORDERED at the time
19795 + * the HW executes the de-schedule, the HW will perform
19796 + * the switch at the time it re-schedules, and will be
19797 + * able to reschedule any/all of the entries with the
19798 + * same tag.
19799 + * Due to this behavior, the RECOMMENDATION to software is
19800 + * that they have a (next) state of ATOMIC when they
19801 + * DE-SCHEDULE. If an ORDERED tag is what was really desired,
19802 + * SW can choose to immediately switch to an ORDERED tag
19803 + * after the work (that has an ATOMIC tag) is re-scheduled.
19804 + * Note that since there are never any tag switches pending
19805 + * when the HW re-schedules, this switch can be IMMEDIATE upon
19806 + * the reception of the pointer during the re-schedule.
19807 + *
19808 + * @tag: New tag value
19809 + * @tag_type: New tag type
19810 + * @group: New group value
19811 + * @no_sched: Control whether this work queue entry will be rescheduled.
19812 + * - 1 : don't schedule this work
19813 + * - 0 : allow this work to be scheduled.
19814 + */
19815 +static inline void cvmx_pow_tag_sw_desched(uint32_t tag,
19816 + enum cvmx_pow_tag_type tag_type,
19817 + uint64_t group, uint64_t no_sched)
19818 +{
19819 + if (CVMX_ENABLE_POW_CHECKS)
19820 + __cvmx_pow_warn_if_pending_switch(__func__);
19821 +
19822 + /* Need to make sure any writes to the work queue entry are complete */
19823 + CVMX_SYNCWS;
19824 + /*
19825 + * Ensure that there is not a pending tag switch, as a tag
19826 + * switch cannot be started if a previous switch is still
19827 + * pending.
19828 + */
19829 + cvmx_pow_tag_sw_wait();
19830 + cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched);
19831 +}
19832 +
19833 +/**
19834 + * Descchedules the current work queue entry.
19835 + *
19836 + * @no_sched: no schedule flag value to be set on the work queue
19837 + * entry. If this is set the entry will not be
19838 + * rescheduled.
19839 + */
19840 +static inline void cvmx_pow_desched(uint64_t no_sched)
19841 +{
19842 + cvmx_addr_t ptr;
19843 + cvmx_pow_tag_req_t tag_req;
19844 +
19845 + if (CVMX_ENABLE_POW_CHECKS) {
19846 + cvmx_pow_tag_req_t current_tag;
19847 + __cvmx_pow_warn_if_pending_switch(__func__);
19848 + current_tag = cvmx_pow_get_current_tag();
19849 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
19850 + pr_warning("%s called with NULL_NULL tag\n",
19851 + __func__);
19852 + if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
19853 + pr_warning("%s called with NULL tag. Deschedule not "
19854 + "expected from NULL state\n",
19855 + __func__);
19856 + }
19857 +
19858 + /* Need to make sure any writes to the work queue entry are complete */
19859 + CVMX_SYNCWS;
19860 +
19861 + tag_req.u64 = 0;
19862 + tag_req.s.op = CVMX_POW_TAG_OP_DESCH;
19863 + tag_req.s.no_sched = no_sched;
19864 +
19865 + ptr.u64 = 0;
19866 + ptr.sio.mem_region = CVMX_IO_SEG;
19867 + ptr.sio.is_io = 1;
19868 + ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
19869 + /*
19870 + * since TAG3 is used, this store will clear the local pending
19871 + * switch bit.
19872 + */
19873 + cvmx_write_io(ptr.u64, tag_req.u64);
19874 +}
19875 +
19876 +/****************************************************
19877 +* Define usage of bits within the 32 bit tag values.
19878 +*****************************************************/
19879 +
19880 +/*
19881 + * Number of bits of the tag used by software. The SW bits are always
19882 + * a contiguous block of the high starting at bit 31. The hardware
19883 + * bits are always the low bits. By default, the top 8 bits of the
19884 + * tag are reserved for software, and the low 24 are set by the IPD
19885 + * unit.
19886 + */
19887 +#define CVMX_TAG_SW_BITS (8)
19888 +#define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS)
19889 +
19890 +/* Below is the list of values for the top 8 bits of the tag. */
19891 +/*
19892 + * Tag values with top byte of this value are reserved for internal
19893 + * executive uses.
19894 + */
19895 +#define CVMX_TAG_SW_BITS_INTERNAL 0x1
19896 +/* The executive divides the remaining 24 bits as follows:
19897 + * - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup
19898 + *
19899 + * - the lower 16 bits (bits 15 - 0 of the tag) define are the value
19900 + * with the subgroup
19901 + *
19902 + * Note that this section describes the format of tags generated by
19903 + * software - refer to the hardware documentation for a description of
19904 + * the tags values generated by the packet input hardware. Subgroups
19905 + * are defined here.
19906 + */
19907 +/* Mask for the value portion of the tag */
19908 +#define CVMX_TAG_SUBGROUP_MASK 0xFFFF
19909 +#define CVMX_TAG_SUBGROUP_SHIFT 16
19910 +#define CVMX_TAG_SUBGROUP_PKO 0x1
19911 +
19912 +/* End of executive tag subgroup definitions */
19913 +
19914 +/*
19915 + * The remaining values software bit values 0x2 - 0xff are available
19916 + * for application use.
19917 + */
19918 +
19919 +/**
19920 + * This function creates a 32 bit tag value from the two values provided.
19921 + *
19922 + * @sw_bits: The upper bits (number depends on configuration) are set
19923 + * to this value. The remainder of bits are set by the
19924 + * hw_bits parameter.
19925 + *
19926 + * @hw_bits: The lower bits (number depends on configuration) are set
19927 + * to this value. The remainder of bits are set by the
19928 + * sw_bits parameter.
19929 + *
19930 + * Returns 32 bit value of the combined hw and sw bits.
19931 + */
19932 +static inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits)
19933 +{
19934 + return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) <<
19935 + CVMX_TAG_SW_SHIFT) |
19936 + (hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS));
19937 +}
19938 +
19939 +/**
19940 + * Extracts the bits allocated for software use from the tag
19941 + *
19942 + * @tag: 32 bit tag value
19943 + *
19944 + * Returns N bit software tag value, where N is configurable with the
19945 + * CVMX_TAG_SW_BITS define
19946 + */
19947 +static inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag)
19948 +{
19949 + return (tag >> (32 - CVMX_TAG_SW_BITS)) &
19950 + cvmx_build_mask(CVMX_TAG_SW_BITS);
19951 +}
19952 +
19953 +/**
19954 + *
19955 + * Extracts the bits allocated for hardware use from the tag
19956 + *
19957 + * @tag: 32 bit tag value
19958 + *
19959 + * Returns (32 - N) bit software tag value, where N is configurable
19960 + * with the CVMX_TAG_SW_BITS define
19961 + */
19962 +static inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag)
19963 +{
19964 + return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS);
19965 +}
19966 +
19967 +/**
19968 + * Store the current POW internal state into the supplied
19969 + * buffer. It is recommended that you pass a buffer of at least
19970 + * 128KB. The format of the capture may change based on SDK
19971 + * version and Octeon chip.
19972 + *
19973 + * @buffer: Buffer to store capture into
19974 + * @buffer_size:
19975 + * The size of the supplied buffer
19976 + *
19977 + * Returns Zero on sucess, negative on failure
19978 + */
19979 +extern int cvmx_pow_capture(void *buffer, int buffer_size);
19980 +
19981 +/**
19982 + * Dump a POW capture to the console in a human readable format.
19983 + *
19984 + * @buffer: POW capture from cvmx_pow_capture()
19985 + * @buffer_size:
19986 + * Size of the buffer
19987 + */
19988 +extern void cvmx_pow_display(void *buffer, int buffer_size);
19989 +
19990 +/**
19991 + * Return the number of POW entries supported by this chip
19992 + *
19993 + * Returns Number of POW entries
19994 + */
19995 +extern int cvmx_pow_get_num_entries(void);
19996 +
19997 +#endif /* __CVMX_POW_H__ */
19998 diff --git a/drivers/staging/octeon/cvmx-scratch.h b/drivers/staging/octeon/cvmx-scratch.h
19999 new file mode 100644
20000 index 0000000..96b70cf
20001 --- /dev/null
20002 +++ b/drivers/staging/octeon/cvmx-scratch.h
20003 @@ -0,0 +1,139 @@
20004 +/***********************license start***************
20005 + * Author: Cavium Networks
20006 + *
20007 + * Contact: support@caviumnetworks.com
20008 + * This file is part of the OCTEON SDK
20009 + *
20010 + * Copyright (c) 2003-2008 Cavium Networks
20011 + *
20012 + * This file is free software; you can redistribute it and/or modify
20013 + * it under the terms of the GNU General Public License, Version 2, as
20014 + * published by the Free Software Foundation.
20015 + *
20016 + * This file is distributed in the hope that it will be useful, but
20017 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20018 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20019 + * NONINFRINGEMENT. See the GNU General Public License for more
20020 + * details.
20021 + *
20022 + * You should have received a copy of the GNU General Public License
20023 + * along with this file; if not, write to the Free Software
20024 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20025 + * or visit http://www.gnu.org/licenses/.
20026 + *
20027 + * This file may also be available under a different license from Cavium.
20028 + * Contact Cavium Networks for more information
20029 + ***********************license end**************************************/
20030 +
20031 +/**
20032 + *
20033 + * This file provides support for the processor local scratch memory.
20034 + * Scratch memory is byte addressable - all addresses are byte addresses.
20035 + *
20036 + */
20037 +
20038 +#ifndef __CVMX_SCRATCH_H__
20039 +#define __CVMX_SCRATCH_H__
20040 +
20041 +/*
20042 + * Note: This define must be a long, not a long long in order to
20043 + * compile without warnings for both 32bit and 64bit.
20044 + */
20045 +#define CVMX_SCRATCH_BASE (-32768l) /* 0xffffffffffff8000 */
20046 +
20047 +/**
20048 + * Reads an 8 bit value from the processor local scratchpad memory.
20049 + *
20050 + * @address: byte address to read from
20051 + *
20052 + * Returns value read
20053 + */
20054 +static inline uint8_t cvmx_scratch_read8(uint64_t address)
20055 +{
20056 + return *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address);
20057 +}
20058 +
20059 +/**
20060 + * Reads a 16 bit value from the processor local scratchpad memory.
20061 + *
20062 + * @address: byte address to read from
20063 + *
20064 + * Returns value read
20065 + */
20066 +static inline uint16_t cvmx_scratch_read16(uint64_t address)
20067 +{
20068 + return *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address);
20069 +}
20070 +
20071 +/**
20072 + * Reads a 32 bit value from the processor local scratchpad memory.
20073 + *
20074 + * @address: byte address to read from
20075 + *
20076 + * Returns value read
20077 + */
20078 +static inline uint32_t cvmx_scratch_read32(uint64_t address)
20079 +{
20080 + return *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address);
20081 +}
20082 +
20083 +/**
20084 + * Reads a 64 bit value from the processor local scratchpad memory.
20085 + *
20086 + * @address: byte address to read from
20087 + *
20088 + * Returns value read
20089 + */
20090 +static inline uint64_t cvmx_scratch_read64(uint64_t address)
20091 +{
20092 + return *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address);
20093 +}
20094 +
20095 +/**
20096 + * Writes an 8 bit value to the processor local scratchpad memory.
20097 + *
20098 + * @address: byte address to write to
20099 + * @value: value to write
20100 + */
20101 +static inline void cvmx_scratch_write8(uint64_t address, uint64_t value)
20102 +{
20103 + *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address) =
20104 + (uint8_t) value;
20105 +}
20106 +
20107 +/**
20108 + * Writes a 32 bit value to the processor local scratchpad memory.
20109 + *
20110 + * @address: byte address to write to
20111 + * @value: value to write
20112 + */
20113 +static inline void cvmx_scratch_write16(uint64_t address, uint64_t value)
20114 +{
20115 + *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address) =
20116 + (uint16_t) value;
20117 +}
20118 +
20119 +/**
20120 + * Writes a 16 bit value to the processor local scratchpad memory.
20121 + *
20122 + * @address: byte address to write to
20123 + * @value: value to write
20124 + */
20125 +static inline void cvmx_scratch_write32(uint64_t address, uint64_t value)
20126 +{
20127 + *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address) =
20128 + (uint32_t) value;
20129 +}
20130 +
20131 +/**
20132 + * Writes a 64 bit value to the processor local scratchpad memory.
20133 + *
20134 + * @address: byte address to write to
20135 + * @value: value to write
20136 + */
20137 +static inline void cvmx_scratch_write64(uint64_t address, uint64_t value)
20138 +{
20139 + *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address) = value;
20140 +}
20141 +
20142 +#endif /* __CVMX_SCRATCH_H__ */
20143 diff --git a/drivers/staging/octeon/cvmx-smix-defs.h b/drivers/staging/octeon/cvmx-smix-defs.h
20144 new file mode 100644
20145 index 0000000..9ae45fc
20146 --- /dev/null
20147 +++ b/drivers/staging/octeon/cvmx-smix-defs.h
20148 @@ -0,0 +1,178 @@
20149 +/***********************license start***************
20150 + * Author: Cavium Networks
20151 + *
20152 + * Contact: support@caviumnetworks.com
20153 + * This file is part of the OCTEON SDK
20154 + *
20155 + * Copyright (c) 2003-2008 Cavium Networks
20156 + *
20157 + * This file is free software; you can redistribute it and/or modify
20158 + * it under the terms of the GNU General Public License, Version 2, as
20159 + * published by the Free Software Foundation.
20160 + *
20161 + * This file is distributed in the hope that it will be useful, but
20162 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20163 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20164 + * NONINFRINGEMENT. See the GNU General Public License for more
20165 + * details.
20166 + *
20167 + * You should have received a copy of the GNU General Public License
20168 + * along with this file; if not, write to the Free Software
20169 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20170 + * or visit http://www.gnu.org/licenses/.
20171 + *
20172 + * This file may also be available under a different license from Cavium.
20173 + * Contact Cavium Networks for more information
20174 + ***********************license end**************************************/
20175 +
20176 +#ifndef __CVMX_SMIX_DEFS_H__
20177 +#define __CVMX_SMIX_DEFS_H__
20178 +
20179 +#define CVMX_SMIX_CLK(offset) \
20180 + CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
20181 +#define CVMX_SMIX_CMD(offset) \
20182 + CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
20183 +#define CVMX_SMIX_EN(offset) \
20184 + CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
20185 +#define CVMX_SMIX_RD_DAT(offset) \
20186 + CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
20187 +#define CVMX_SMIX_WR_DAT(offset) \
20188 + CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
20189 +
20190 +union cvmx_smix_clk {
20191 + uint64_t u64;
20192 + struct cvmx_smix_clk_s {
20193 + uint64_t reserved_25_63:39;
20194 + uint64_t mode:1;
20195 + uint64_t reserved_21_23:3;
20196 + uint64_t sample_hi:5;
20197 + uint64_t sample_mode:1;
20198 + uint64_t reserved_14_14:1;
20199 + uint64_t clk_idle:1;
20200 + uint64_t preamble:1;
20201 + uint64_t sample:4;
20202 + uint64_t phase:8;
20203 + } s;
20204 + struct cvmx_smix_clk_cn30xx {
20205 + uint64_t reserved_21_63:43;
20206 + uint64_t sample_hi:5;
20207 + uint64_t reserved_14_15:2;
20208 + uint64_t clk_idle:1;
20209 + uint64_t preamble:1;
20210 + uint64_t sample:4;
20211 + uint64_t phase:8;
20212 + } cn30xx;
20213 + struct cvmx_smix_clk_cn30xx cn31xx;
20214 + struct cvmx_smix_clk_cn30xx cn38xx;
20215 + struct cvmx_smix_clk_cn30xx cn38xxp2;
20216 + struct cvmx_smix_clk_cn50xx {
20217 + uint64_t reserved_25_63:39;
20218 + uint64_t mode:1;
20219 + uint64_t reserved_21_23:3;
20220 + uint64_t sample_hi:5;
20221 + uint64_t reserved_14_15:2;
20222 + uint64_t clk_idle:1;
20223 + uint64_t preamble:1;
20224 + uint64_t sample:4;
20225 + uint64_t phase:8;
20226 + } cn50xx;
20227 + struct cvmx_smix_clk_s cn52xx;
20228 + struct cvmx_smix_clk_cn50xx cn52xxp1;
20229 + struct cvmx_smix_clk_s cn56xx;
20230 + struct cvmx_smix_clk_cn50xx cn56xxp1;
20231 + struct cvmx_smix_clk_cn30xx cn58xx;
20232 + struct cvmx_smix_clk_cn30xx cn58xxp1;
20233 +};
20234 +
20235 +union cvmx_smix_cmd {
20236 + uint64_t u64;
20237 + struct cvmx_smix_cmd_s {
20238 + uint64_t reserved_18_63:46;
20239 + uint64_t phy_op:2;
20240 + uint64_t reserved_13_15:3;
20241 + uint64_t phy_adr:5;
20242 + uint64_t reserved_5_7:3;
20243 + uint64_t reg_adr:5;
20244 + } s;
20245 + struct cvmx_smix_cmd_cn30xx {
20246 + uint64_t reserved_17_63:47;
20247 + uint64_t phy_op:1;
20248 + uint64_t reserved_13_15:3;
20249 + uint64_t phy_adr:5;
20250 + uint64_t reserved_5_7:3;
20251 + uint64_t reg_adr:5;
20252 + } cn30xx;
20253 + struct cvmx_smix_cmd_cn30xx cn31xx;
20254 + struct cvmx_smix_cmd_cn30xx cn38xx;
20255 + struct cvmx_smix_cmd_cn30xx cn38xxp2;
20256 + struct cvmx_smix_cmd_s cn50xx;
20257 + struct cvmx_smix_cmd_s cn52xx;
20258 + struct cvmx_smix_cmd_s cn52xxp1;
20259 + struct cvmx_smix_cmd_s cn56xx;
20260 + struct cvmx_smix_cmd_s cn56xxp1;
20261 + struct cvmx_smix_cmd_cn30xx cn58xx;
20262 + struct cvmx_smix_cmd_cn30xx cn58xxp1;
20263 +};
20264 +
20265 +union cvmx_smix_en {
20266 + uint64_t u64;
20267 + struct cvmx_smix_en_s {
20268 + uint64_t reserved_1_63:63;
20269 + uint64_t en:1;
20270 + } s;
20271 + struct cvmx_smix_en_s cn30xx;
20272 + struct cvmx_smix_en_s cn31xx;
20273 + struct cvmx_smix_en_s cn38xx;
20274 + struct cvmx_smix_en_s cn38xxp2;
20275 + struct cvmx_smix_en_s cn50xx;
20276 + struct cvmx_smix_en_s cn52xx;
20277 + struct cvmx_smix_en_s cn52xxp1;
20278 + struct cvmx_smix_en_s cn56xx;
20279 + struct cvmx_smix_en_s cn56xxp1;
20280 + struct cvmx_smix_en_s cn58xx;
20281 + struct cvmx_smix_en_s cn58xxp1;
20282 +};
20283 +
20284 +union cvmx_smix_rd_dat {
20285 + uint64_t u64;
20286 + struct cvmx_smix_rd_dat_s {
20287 + uint64_t reserved_18_63:46;
20288 + uint64_t pending:1;
20289 + uint64_t val:1;
20290 + uint64_t dat:16;
20291 + } s;
20292 + struct cvmx_smix_rd_dat_s cn30xx;
20293 + struct cvmx_smix_rd_dat_s cn31xx;
20294 + struct cvmx_smix_rd_dat_s cn38xx;
20295 + struct cvmx_smix_rd_dat_s cn38xxp2;
20296 + struct cvmx_smix_rd_dat_s cn50xx;
20297 + struct cvmx_smix_rd_dat_s cn52xx;
20298 + struct cvmx_smix_rd_dat_s cn52xxp1;
20299 + struct cvmx_smix_rd_dat_s cn56xx;
20300 + struct cvmx_smix_rd_dat_s cn56xxp1;
20301 + struct cvmx_smix_rd_dat_s cn58xx;
20302 + struct cvmx_smix_rd_dat_s cn58xxp1;
20303 +};
20304 +
20305 +union cvmx_smix_wr_dat {
20306 + uint64_t u64;
20307 + struct cvmx_smix_wr_dat_s {
20308 + uint64_t reserved_18_63:46;
20309 + uint64_t pending:1;
20310 + uint64_t val:1;
20311 + uint64_t dat:16;
20312 + } s;
20313 + struct cvmx_smix_wr_dat_s cn30xx;
20314 + struct cvmx_smix_wr_dat_s cn31xx;
20315 + struct cvmx_smix_wr_dat_s cn38xx;
20316 + struct cvmx_smix_wr_dat_s cn38xxp2;
20317 + struct cvmx_smix_wr_dat_s cn50xx;
20318 + struct cvmx_smix_wr_dat_s cn52xx;
20319 + struct cvmx_smix_wr_dat_s cn52xxp1;
20320 + struct cvmx_smix_wr_dat_s cn56xx;
20321 + struct cvmx_smix_wr_dat_s cn56xxp1;
20322 + struct cvmx_smix_wr_dat_s cn58xx;
20323 + struct cvmx_smix_wr_dat_s cn58xxp1;
20324 +};
20325 +
20326 +#endif
20327 diff --git a/drivers/staging/octeon/cvmx-spi.c b/drivers/staging/octeon/cvmx-spi.c
20328 new file mode 100644
20329 index 0000000..82794d9
20330 --- /dev/null
20331 +++ b/drivers/staging/octeon/cvmx-spi.c
20332 @@ -0,0 +1,667 @@
20333 +/***********************license start***************
20334 + * Author: Cavium Networks
20335 + *
20336 + * Contact: support@caviumnetworks.com
20337 + * This file is part of the OCTEON SDK
20338 + *
20339 + * Copyright (c) 2003-2008 Cavium Networks
20340 + *
20341 + * This file is free software; you can redistribute it and/or modify
20342 + * it under the terms of the GNU General Public License, Version 2, as
20343 + * published by the Free Software Foundation.
20344 + *
20345 + * This file is distributed in the hope that it will be useful, but
20346 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
20347 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
20348 + * NONINFRINGEMENT. See the GNU General Public License for more
20349 + * details.
20350 + *
20351 + * You should have received a copy of the GNU General Public License
20352 + * along with this file; if not, write to the Free Software
20353 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20354 + * or visit http://www.gnu.org/licenses/.
20355 + *
20356 + * This file may also be available under a different license from Cavium.
20357 + * Contact Cavium Networks for more information
20358 + ***********************license end**************************************/
20359 +
20360 +/*
20361 + *
20362 + * Support library for the SPI
20363 + */
20364 +#include <asm/octeon/octeon.h>
20365 +
20366 +#include "cvmx-config.h"
20367 +
20368 +#include "cvmx-pko.h"
20369 +#include "cvmx-spi.h"
20370 +
20371 +#include "cvmx-spxx-defs.h"
20372 +#include "cvmx-stxx-defs.h"
20373 +#include "cvmx-srxx-defs.h"
20374 +
20375 +#define INVOKE_CB(function_p, args...) \
20376 + do { \
20377 + if (function_p) { \
20378 + res = function_p(args); \
20379 + if (res) \
20380 + return res; \
20381 + } \
20382 + } while (0)
20383 +
20384 +#if CVMX_ENABLE_DEBUG_PRINTS
20385 +static const char *modes[] =
20386 + { "UNKNOWN", "TX Halfplex", "Rx Halfplex", "Duplex" };
20387 +#endif
20388 +
20389 +/* Default callbacks, can be overridden
20390 + * using cvmx_spi_get_callbacks/cvmx_spi_set_callbacks
20391 + */
20392 +static cvmx_spi_callbacks_t cvmx_spi_callbacks = {
20393 + .reset_cb = cvmx_spi_reset_cb,
20394 + .calendar_setup_cb = cvmx_spi_calendar_setup_cb,
20395 + .clock_detect_cb = cvmx_spi_clock_detect_cb,
20396 + .training_cb = cvmx_spi_training_cb,
20397 + .calendar_sync_cb = cvmx_spi_calendar_sync_cb,
20398 + .interface_up_cb = cvmx_spi_interface_up_cb
20399 +};
20400 +
20401 +/**
20402 + * Get current SPI4 initialization callbacks
20403 + *
20404 + * @callbacks: Pointer to the callbacks structure.to fill
20405 + *
20406 + * Returns Pointer to cvmx_spi_callbacks_t structure.
20407 + */
20408 +void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks)
20409 +{
20410 + memcpy(callbacks, &cvmx_spi_callbacks, sizeof(cvmx_spi_callbacks));
20411 +}
20412 +
20413 +/**
20414 + * Set new SPI4 initialization callbacks
20415 + *
20416 + * @new_callbacks: Pointer to an updated callbacks structure.
20417 + */
20418 +void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks)
20419 +{
20420 + memcpy(&cvmx_spi_callbacks, new_callbacks, sizeof(cvmx_spi_callbacks));
20421 +}
20422 +
20423 +/**
20424 + * Initialize and start the SPI interface.
20425 + *
20426 + * @interface: The identifier of the packet interface to configure and
20427 + * use as a SPI interface.
20428 + * @mode: The operating mode for the SPI interface. The interface
20429 + * can operate as a full duplex (both Tx and Rx data paths
20430 + * active) or as a halfplex (either the Tx data path is
20431 + * active or the Rx data path is active, but not both).
20432 + * @timeout: Timeout to wait for clock synchronization in seconds
20433 + * @num_ports: Number of SPI ports to configure
20434 + *
20435 + * Returns Zero on success, negative of failure.
20436 + */
20437 +int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout,
20438 + int num_ports)
20439 +{
20440 + int res = -1;
20441 +
20442 + if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
20443 + return res;
20444 +
20445 + /* Callback to perform SPI4 reset */
20446 + INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
20447 +
20448 + /* Callback to perform calendar setup */
20449 + INVOKE_CB(cvmx_spi_callbacks.calendar_setup_cb, interface, mode,
20450 + num_ports);
20451 +
20452 + /* Callback to perform clock detection */
20453 + INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
20454 +
20455 + /* Callback to perform SPI4 link training */
20456 + INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
20457 +
20458 + /* Callback to perform calendar sync */
20459 + INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
20460 + timeout);
20461 +
20462 + /* Callback to handle interface coming up */
20463 + INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
20464 +
20465 + return res;
20466 +}
20467 +
20468 +/**
20469 + * This routine restarts the SPI interface after it has lost synchronization
20470 + * with its correspondent system.
20471 + *
20472 + * @interface: The identifier of the packet interface to configure and
20473 + * use as a SPI interface.
20474 + * @mode: The operating mode for the SPI interface. The interface
20475 + * can operate as a full duplex (both Tx and Rx data paths
20476 + * active) or as a halfplex (either the Tx data path is
20477 + * active or the Rx data path is active, but not both).
20478 + * @timeout: Timeout to wait for clock synchronization in seconds
20479 + *
20480 + * Returns Zero on success, negative of failure.
20481 + */
20482 +int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout)
20483 +{
20484 + int res = -1;
20485 +
20486 + if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
20487 + return res;
20488 +
20489 + cvmx_dprintf("SPI%d: Restart %s\n", interface, modes[mode]);
20490 +
20491 + /* Callback to perform SPI4 reset */
20492 + INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
20493 +
20494 + /* NOTE: Calendar setup is not performed during restart */
20495 + /* Refer to cvmx_spi_start_interface() for the full sequence */
20496 +
20497 + /* Callback to perform clock detection */
20498 + INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
20499 +
20500 + /* Callback to perform SPI4 link training */
20501 + INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
20502 +
20503 + /* Callback to perform calendar sync */
20504 + INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
20505 + timeout);
20506 +
20507 + /* Callback to handle interface coming up */
20508 + INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
20509 +
20510 + return res;
20511 +}
20512 +
20513 +/**
20514 + * Callback to perform SPI4 reset
20515 + *
20516 + * @interface: The identifier of the packet interface to configure and
20517 + * use as a SPI interface.
20518 + * @mode: The operating mode for the SPI interface. The interface
20519 + * can operate as a full duplex (both Tx and Rx data paths
20520 + * active) or as a halfplex (either the Tx data path is
20521 + * active or the Rx data path is active, but not both).
20522 + *
20523 + * Returns Zero on success, non-zero error code on failure (will cause
20524 + * SPI initialization to abort)
20525 + */
20526 +int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode)
20527 +{
20528 + union cvmx_spxx_dbg_deskew_ctl spxx_dbg_deskew_ctl;
20529 + union cvmx_spxx_clk_ctl spxx_clk_ctl;
20530 + union cvmx_spxx_bist_stat spxx_bist_stat;
20531 + union cvmx_spxx_int_msk spxx_int_msk;
20532 + union cvmx_stxx_int_msk stxx_int_msk;
20533 + union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
20534 + int index;
20535 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20536 +
20537 + /* Disable SPI error events while we run BIST */
20538 + spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
20539 + cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
20540 + stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
20541 + cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
20542 +
20543 + /* Run BIST in the SPI interface */
20544 + cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), 0);
20545 + cvmx_write_csr(CVMX_STXX_COM_CTL(interface), 0);
20546 + spxx_clk_ctl.u64 = 0;
20547 + spxx_clk_ctl.s.runbist = 1;
20548 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20549 + cvmx_wait(10 * MS);
20550 + spxx_bist_stat.u64 = cvmx_read_csr(CVMX_SPXX_BIST_STAT(interface));
20551 + if (spxx_bist_stat.s.stat0)
20552 + cvmx_dprintf
20553 + ("ERROR SPI%d: BIST failed on receive datapath FIFO\n",
20554 + interface);
20555 + if (spxx_bist_stat.s.stat1)
20556 + cvmx_dprintf("ERROR SPI%d: BIST failed on RX calendar table\n",
20557 + interface);
20558 + if (spxx_bist_stat.s.stat2)
20559 + cvmx_dprintf("ERROR SPI%d: BIST failed on TX calendar table\n",
20560 + interface);
20561 +
20562 + /* Clear the calendar table after BIST to fix parity errors */
20563 + for (index = 0; index < 32; index++) {
20564 + union cvmx_srxx_spi4_calx srxx_spi4_calx;
20565 + union cvmx_stxx_spi4_calx stxx_spi4_calx;
20566 +
20567 + srxx_spi4_calx.u64 = 0;
20568 + srxx_spi4_calx.s.oddpar = 1;
20569 + cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface),
20570 + srxx_spi4_calx.u64);
20571 +
20572 + stxx_spi4_calx.u64 = 0;
20573 + stxx_spi4_calx.s.oddpar = 1;
20574 + cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface),
20575 + stxx_spi4_calx.u64);
20576 + }
20577 +
20578 + /* Re enable reporting of error interrupts */
20579 + cvmx_write_csr(CVMX_SPXX_INT_REG(interface),
20580 + cvmx_read_csr(CVMX_SPXX_INT_REG(interface)));
20581 + cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
20582 + cvmx_write_csr(CVMX_STXX_INT_REG(interface),
20583 + cvmx_read_csr(CVMX_STXX_INT_REG(interface)));
20584 + cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
20585 +
20586 + /* Setup the CLKDLY right in the middle */
20587 + spxx_clk_ctl.u64 = 0;
20588 + spxx_clk_ctl.s.seetrn = 0;
20589 + spxx_clk_ctl.s.clkdly = 0x10;
20590 + spxx_clk_ctl.s.runbist = 0;
20591 + spxx_clk_ctl.s.statdrv = 0;
20592 + /* This should always be on the opposite edge as statdrv */
20593 + spxx_clk_ctl.s.statrcv = 1;
20594 + spxx_clk_ctl.s.sndtrn = 0;
20595 + spxx_clk_ctl.s.drptrn = 0;
20596 + spxx_clk_ctl.s.rcvtrn = 0;
20597 + spxx_clk_ctl.s.srxdlck = 0;
20598 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20599 + cvmx_wait(100 * MS);
20600 +
20601 + /* Reset SRX0 DLL */
20602 + spxx_clk_ctl.s.srxdlck = 1;
20603 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20604 +
20605 + /* Waiting for Inf0 Spi4 RX DLL to lock */
20606 + cvmx_wait(100 * MS);
20607 +
20608 + /* Enable dynamic alignment */
20609 + spxx_trn4_ctl.s.trntest = 0;
20610 + spxx_trn4_ctl.s.jitter = 1;
20611 + spxx_trn4_ctl.s.clr_boot = 1;
20612 + spxx_trn4_ctl.s.set_boot = 0;
20613 + if (OCTEON_IS_MODEL(OCTEON_CN58XX))
20614 + spxx_trn4_ctl.s.maxdist = 3;
20615 + else
20616 + spxx_trn4_ctl.s.maxdist = 8;
20617 + spxx_trn4_ctl.s.macro_en = 1;
20618 + spxx_trn4_ctl.s.mux_en = 1;
20619 + cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64);
20620 +
20621 + spxx_dbg_deskew_ctl.u64 = 0;
20622 + cvmx_write_csr(CVMX_SPXX_DBG_DESKEW_CTL(interface),
20623 + spxx_dbg_deskew_ctl.u64);
20624 +
20625 + return 0;
20626 +}
20627 +
20628 +/**
20629 + * Callback to setup calendar and miscellaneous settings before clock detection
20630 + *
20631 + * @interface: The identifier of the packet interface to configure and
20632 + * use as a SPI interface.
20633 + * @mode: The operating mode for the SPI interface. The interface
20634 + * can operate as a full duplex (both Tx and Rx data paths
20635 + * active) or as a halfplex (either the Tx data path is
20636 + * active or the Rx data path is active, but not both).
20637 + * @num_ports: Number of ports to configure on SPI
20638 + *
20639 + * Returns Zero on success, non-zero error code on failure (will cause
20640 + * SPI initialization to abort)
20641 + */
20642 +int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
20643 + int num_ports)
20644 +{
20645 + int port;
20646 + int index;
20647 + if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20648 + union cvmx_srxx_com_ctl srxx_com_ctl;
20649 + union cvmx_srxx_spi4_stat srxx_spi4_stat;
20650 +
20651 + /* SRX0 number of Ports */
20652 + srxx_com_ctl.u64 = 0;
20653 + srxx_com_ctl.s.prts = num_ports - 1;
20654 + srxx_com_ctl.s.st_en = 0;
20655 + srxx_com_ctl.s.inf_en = 0;
20656 + cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20657 +
20658 + /* SRX0 Calendar Table. This round robbins through all ports */
20659 + port = 0;
20660 + index = 0;
20661 + while (port < num_ports) {
20662 + union cvmx_srxx_spi4_calx srxx_spi4_calx;
20663 + srxx_spi4_calx.u64 = 0;
20664 + srxx_spi4_calx.s.prt0 = port++;
20665 + srxx_spi4_calx.s.prt1 = port++;
20666 + srxx_spi4_calx.s.prt2 = port++;
20667 + srxx_spi4_calx.s.prt3 = port++;
20668 + srxx_spi4_calx.s.oddpar =
20669 + ~(cvmx_dpop(srxx_spi4_calx.u64) & 1);
20670 + cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface),
20671 + srxx_spi4_calx.u64);
20672 + index++;
20673 + }
20674 + srxx_spi4_stat.u64 = 0;
20675 + srxx_spi4_stat.s.len = num_ports;
20676 + srxx_spi4_stat.s.m = 1;
20677 + cvmx_write_csr(CVMX_SRXX_SPI4_STAT(interface),
20678 + srxx_spi4_stat.u64);
20679 + }
20680 +
20681 + if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20682 + union cvmx_stxx_arb_ctl stxx_arb_ctl;
20683 + union cvmx_gmxx_tx_spi_max gmxx_tx_spi_max;
20684 + union cvmx_gmxx_tx_spi_thresh gmxx_tx_spi_thresh;
20685 + union cvmx_gmxx_tx_spi_ctl gmxx_tx_spi_ctl;
20686 + union cvmx_stxx_spi4_stat stxx_spi4_stat;
20687 + union cvmx_stxx_spi4_dat stxx_spi4_dat;
20688 +
20689 + /* STX0 Config */
20690 + stxx_arb_ctl.u64 = 0;
20691 + stxx_arb_ctl.s.igntpa = 0;
20692 + stxx_arb_ctl.s.mintrn = 0;
20693 + cvmx_write_csr(CVMX_STXX_ARB_CTL(interface), stxx_arb_ctl.u64);
20694 +
20695 + gmxx_tx_spi_max.u64 = 0;
20696 + gmxx_tx_spi_max.s.max1 = 8;
20697 + gmxx_tx_spi_max.s.max2 = 4;
20698 + gmxx_tx_spi_max.s.slice = 0;
20699 + cvmx_write_csr(CVMX_GMXX_TX_SPI_MAX(interface),
20700 + gmxx_tx_spi_max.u64);
20701 +
20702 + gmxx_tx_spi_thresh.u64 = 0;
20703 + gmxx_tx_spi_thresh.s.thresh = 4;
20704 + cvmx_write_csr(CVMX_GMXX_TX_SPI_THRESH(interface),
20705 + gmxx_tx_spi_thresh.u64);
20706 +
20707 + gmxx_tx_spi_ctl.u64 = 0;
20708 + gmxx_tx_spi_ctl.s.tpa_clr = 0;
20709 + gmxx_tx_spi_ctl.s.cont_pkt = 0;
20710 + cvmx_write_csr(CVMX_GMXX_TX_SPI_CTL(interface),
20711 + gmxx_tx_spi_ctl.u64);
20712 +
20713 + /* STX0 Training Control */
20714 + stxx_spi4_dat.u64 = 0;
20715 + /*Minimum needed by dynamic alignment */
20716 + stxx_spi4_dat.s.alpha = 32;
20717 + stxx_spi4_dat.s.max_t = 0xFFFF; /*Minimum interval is 0x20 */
20718 + cvmx_write_csr(CVMX_STXX_SPI4_DAT(interface),
20719 + stxx_spi4_dat.u64);
20720 +
20721 + /* STX0 Calendar Table. This round robbins through all ports */
20722 + port = 0;
20723 + index = 0;
20724 + while (port < num_ports) {
20725 + union cvmx_stxx_spi4_calx stxx_spi4_calx;
20726 + stxx_spi4_calx.u64 = 0;
20727 + stxx_spi4_calx.s.prt0 = port++;
20728 + stxx_spi4_calx.s.prt1 = port++;
20729 + stxx_spi4_calx.s.prt2 = port++;
20730 + stxx_spi4_calx.s.prt3 = port++;
20731 + stxx_spi4_calx.s.oddpar =
20732 + ~(cvmx_dpop(stxx_spi4_calx.u64) & 1);
20733 + cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface),
20734 + stxx_spi4_calx.u64);
20735 + index++;
20736 + }
20737 + stxx_spi4_stat.u64 = 0;
20738 + stxx_spi4_stat.s.len = num_ports;
20739 + stxx_spi4_stat.s.m = 1;
20740 + cvmx_write_csr(CVMX_STXX_SPI4_STAT(interface),
20741 + stxx_spi4_stat.u64);
20742 + }
20743 +
20744 + return 0;
20745 +}
20746 +
20747 +/**
20748 + * Callback to perform clock detection
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 clock synchronization 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_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20762 +{
20763 + int clock_transitions;
20764 + union cvmx_spxx_clk_stat stat;
20765 + uint64_t timeout_time;
20766 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20767 +
20768 + /*
20769 + * Regardless of operating mode, both Tx and Rx clocks must be
20770 + * present for the SPI interface to operate.
20771 + */
20772 + cvmx_dprintf("SPI%d: Waiting to see TsClk...\n", interface);
20773 + timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20774 + /*
20775 + * Require 100 clock transitions in order to avoid any noise
20776 + * in the beginning.
20777 + */
20778 + clock_transitions = 100;
20779 + do {
20780 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20781 + if (stat.s.s4clk0 && stat.s.s4clk1 && clock_transitions) {
20782 + /*
20783 + * We've seen a clock transition, so decrement
20784 + * the number we still need.
20785 + */
20786 + clock_transitions--;
20787 + cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20788 + stat.s.s4clk0 = 0;
20789 + stat.s.s4clk1 = 0;
20790 + }
20791 + if (cvmx_get_cycle() > timeout_time) {
20792 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20793 + return -1;
20794 + }
20795 + } while (stat.s.s4clk0 == 0 || stat.s.s4clk1 == 0);
20796 +
20797 + cvmx_dprintf("SPI%d: Waiting to see RsClk...\n", interface);
20798 + timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20799 + /*
20800 + * Require 100 clock transitions in order to avoid any noise in the
20801 + * beginning.
20802 + */
20803 + clock_transitions = 100;
20804 + do {
20805 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20806 + if (stat.s.d4clk0 && stat.s.d4clk1 && clock_transitions) {
20807 + /*
20808 + * We've seen a clock transition, so decrement
20809 + * the number we still need
20810 + */
20811 + clock_transitions--;
20812 + cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20813 + stat.s.d4clk0 = 0;
20814 + stat.s.d4clk1 = 0;
20815 + }
20816 + if (cvmx_get_cycle() > timeout_time) {
20817 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20818 + return -1;
20819 + }
20820 + } while (stat.s.d4clk0 == 0 || stat.s.d4clk1 == 0);
20821 +
20822 + return 0;
20823 +}
20824 +
20825 +/**
20826 + * Callback to perform link training
20827 + *
20828 + * @interface: The identifier of the packet interface to configure and
20829 + * use as a SPI interface.
20830 + * @mode: The operating mode for the SPI interface. The interface
20831 + * can operate as a full duplex (both Tx and Rx data paths
20832 + * active) or as a halfplex (either the Tx data path is
20833 + * active or the Rx data path is active, but not both).
20834 + * @timeout: Timeout to wait for link to be trained (in seconds)
20835 + *
20836 + * Returns Zero on success, non-zero error code on failure (will cause
20837 + * SPI initialization to abort)
20838 + */
20839 +int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20840 +{
20841 + union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
20842 + union cvmx_spxx_clk_stat stat;
20843 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20844 + uint64_t timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20845 + int rx_training_needed;
20846 +
20847 + /* SRX0 & STX0 Inf0 Links are configured - begin training */
20848 + union cvmx_spxx_clk_ctl spxx_clk_ctl;
20849 + spxx_clk_ctl.u64 = 0;
20850 + spxx_clk_ctl.s.seetrn = 0;
20851 + spxx_clk_ctl.s.clkdly = 0x10;
20852 + spxx_clk_ctl.s.runbist = 0;
20853 + spxx_clk_ctl.s.statdrv = 0;
20854 + /* This should always be on the opposite edge as statdrv */
20855 + spxx_clk_ctl.s.statrcv = 1;
20856 + spxx_clk_ctl.s.sndtrn = 1;
20857 + spxx_clk_ctl.s.drptrn = 1;
20858 + spxx_clk_ctl.s.rcvtrn = 1;
20859 + spxx_clk_ctl.s.srxdlck = 1;
20860 + cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
20861 + cvmx_wait(1000 * MS);
20862 +
20863 + /* SRX0 clear the boot bit */
20864 + spxx_trn4_ctl.u64 = cvmx_read_csr(CVMX_SPXX_TRN4_CTL(interface));
20865 + spxx_trn4_ctl.s.clr_boot = 1;
20866 + cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64);
20867 +
20868 + /* Wait for the training sequence to complete */
20869 + cvmx_dprintf("SPI%d: Waiting for training\n", interface);
20870 + cvmx_wait(1000 * MS);
20871 + /* Wait a really long time here */
20872 + timeout_time = cvmx_get_cycle() + 1000ull * MS * 600;
20873 + /*
20874 + * The HRM says we must wait for 34 + 16 * MAXDIST training sequences.
20875 + * We'll be pessimistic and wait for a lot more.
20876 + */
20877 + rx_training_needed = 500;
20878 + do {
20879 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20880 + if (stat.s.srxtrn && rx_training_needed) {
20881 + rx_training_needed--;
20882 + cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
20883 + stat.s.srxtrn = 0;
20884 + }
20885 + if (cvmx_get_cycle() > timeout_time) {
20886 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20887 + return -1;
20888 + }
20889 + } while (stat.s.srxtrn == 0);
20890 +
20891 + return 0;
20892 +}
20893 +
20894 +/**
20895 + * Callback to perform calendar data synchronization
20896 + *
20897 + * @interface: The identifier of the packet interface to configure and
20898 + * use as a SPI interface.
20899 + * @mode: The operating mode for the SPI interface. The interface
20900 + * can operate as a full duplex (both Tx and Rx data paths
20901 + * active) or as a halfplex (either the Tx data path is
20902 + * active or the Rx data path is active, but not both).
20903 + * @timeout: Timeout to wait for calendar data in seconds
20904 + *
20905 + * Returns Zero on success, non-zero error code on failure (will cause
20906 + * SPI initialization to abort)
20907 + */
20908 +int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout)
20909 +{
20910 + uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
20911 + if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20912 + /* SRX0 interface should be good, send calendar data */
20913 + union cvmx_srxx_com_ctl srxx_com_ctl;
20914 + cvmx_dprintf
20915 + ("SPI%d: Rx is synchronized, start sending calendar data\n",
20916 + interface);
20917 + srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface));
20918 + srxx_com_ctl.s.inf_en = 1;
20919 + srxx_com_ctl.s.st_en = 1;
20920 + cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20921 + }
20922 +
20923 + if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20924 + /* STX0 has achieved sync */
20925 + /* The corespondant board should be sending calendar data */
20926 + /* Enable the STX0 STAT receiver. */
20927 + union cvmx_spxx_clk_stat stat;
20928 + uint64_t timeout_time;
20929 + union cvmx_stxx_com_ctl stxx_com_ctl;
20930 + stxx_com_ctl.u64 = 0;
20931 + stxx_com_ctl.s.st_en = 1;
20932 + cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64);
20933 +
20934 + /* Waiting for calendar sync on STX0 STAT */
20935 + cvmx_dprintf("SPI%d: Waiting to sync on STX[%d] STAT\n",
20936 + interface, interface);
20937 + timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
20938 + /* SPX0_CLK_STAT - SPX0_CLK_STAT[STXCAL] should be 1 (bit10) */
20939 + do {
20940 + stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
20941 + if (cvmx_get_cycle() > timeout_time) {
20942 + cvmx_dprintf("SPI%d: Timeout\n", interface);
20943 + return -1;
20944 + }
20945 + } while (stat.s.stxcal == 0);
20946 + }
20947 +
20948 + return 0;
20949 +}
20950 +
20951 +/**
20952 + * Callback to handle interface up
20953 + *
20954 + * @interface: The identifier of the packet interface to configure and
20955 + * use as a SPI interface.
20956 + * @mode: The operating mode for the SPI interface. The interface
20957 + * can operate as a full duplex (both Tx and Rx data paths
20958 + * active) or as a halfplex (either the Tx data path is
20959 + * active or the Rx data path is active, but not both).
20960 + *
20961 + * Returns Zero on success, non-zero error code on failure (will cause
20962 + * SPI initialization to abort)
20963 + */
20964 +int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode)
20965 +{
20966 + union cvmx_gmxx_rxx_frm_min gmxx_rxx_frm_min;
20967 + union cvmx_gmxx_rxx_frm_max gmxx_rxx_frm_max;
20968 + union cvmx_gmxx_rxx_jabber gmxx_rxx_jabber;
20969 +
20970 + if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
20971 + union cvmx_srxx_com_ctl srxx_com_ctl;
20972 + srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface));
20973 + srxx_com_ctl.s.inf_en = 1;
20974 + cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
20975 + cvmx_dprintf("SPI%d: Rx is now up\n", interface);
20976 + }
20977 +
20978 + if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
20979 + union cvmx_stxx_com_ctl stxx_com_ctl;
20980 + stxx_com_ctl.u64 = cvmx_read_csr(CVMX_STXX_COM_CTL(interface));
20981 + stxx_com_ctl.s.inf_en = 1;
20982 + cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64);
20983 + cvmx_dprintf("SPI%d: Tx is now up\n", interface);
20984 + }
20985 +
20986 + gmxx_rxx_frm_min.u64 = 0;
20987 + gmxx_rxx_frm_min.s.len = 64;
20988 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MIN(0, interface),
20989 + gmxx_rxx_frm_min.u64);
20990 + gmxx_rxx_frm_max.u64 = 0;
20991 + gmxx_rxx_frm_max.s.len = 64 * 1024 - 4;
20992 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(0, interface),
20993 + gmxx_rxx_frm_max.u64);
20994 + gmxx_rxx_jabber.u64 = 0;
20995 + gmxx_rxx_jabber.s.cnt = 64 * 1024 - 4;
20996 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER(0, interface), gmxx_rxx_jabber.u64);
20997 +
20998 + return 0;
20999 +}
21000 diff --git a/drivers/staging/octeon/cvmx-spi.h b/drivers/staging/octeon/cvmx-spi.h
21001 new file mode 100644
21002 index 0000000..e814648
21003 --- /dev/null
21004 +++ b/drivers/staging/octeon/cvmx-spi.h
21005 @@ -0,0 +1,269 @@
21006 +/***********************license start***************
21007 + * Author: Cavium Networks
21008 + *
21009 + * Contact: support@caviumnetworks.com
21010 + * This file is part of the OCTEON SDK
21011 + *
21012 + * Copyright (c) 2003-2008 Cavium Networks
21013 + *
21014 + * This file is free software; you can redistribute it and/or modify
21015 + * it under the terms of the GNU General Public License, Version 2, as
21016 + * published by the Free Software Foundation.
21017 + *
21018 + * This file is distributed in the hope that it will be useful, but
21019 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21020 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21021 + * NONINFRINGEMENT. See the GNU General Public License for more
21022 + * details.
21023 + *
21024 + * You should have received a copy of the GNU General Public License
21025 + * along with this file; if not, write to the Free Software
21026 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21027 + * or visit http://www.gnu.org/licenses/.
21028 + *
21029 + * This file may also be available under a different license from Cavium.
21030 + * Contact Cavium Networks for more information
21031 + ***********************license end**************************************/
21032 +
21033 +/*
21034 + *
21035 + * This file contains defines for the SPI interface
21036 + */
21037 +#ifndef __CVMX_SPI_H__
21038 +#define __CVMX_SPI_H__
21039 +
21040 +#include "cvmx-gmxx-defs.h"
21041 +
21042 +/* CSR typedefs have been moved to cvmx-csr-*.h */
21043 +
21044 +typedef enum {
21045 + CVMX_SPI_MODE_UNKNOWN = 0,
21046 + CVMX_SPI_MODE_TX_HALFPLEX = 1,
21047 + CVMX_SPI_MODE_RX_HALFPLEX = 2,
21048 + CVMX_SPI_MODE_DUPLEX = 3
21049 +} cvmx_spi_mode_t;
21050 +
21051 +/** Callbacks structure to customize SPI4 initialization sequence */
21052 +typedef struct {
21053 + /** Called to reset SPI4 DLL */
21054 + int (*reset_cb) (int interface, cvmx_spi_mode_t mode);
21055 +
21056 + /** Called to setup calendar */
21057 + int (*calendar_setup_cb) (int interface, cvmx_spi_mode_t mode,
21058 + int num_ports);
21059 +
21060 + /** Called for Tx and Rx clock detection */
21061 + int (*clock_detect_cb) (int interface, cvmx_spi_mode_t mode,
21062 + int timeout);
21063 +
21064 + /** Called to perform link training */
21065 + int (*training_cb) (int interface, cvmx_spi_mode_t mode, int timeout);
21066 +
21067 + /** Called for calendar data synchronization */
21068 + int (*calendar_sync_cb) (int interface, cvmx_spi_mode_t mode,
21069 + int timeout);
21070 +
21071 + /** Called when interface is up */
21072 + int (*interface_up_cb) (int interface, cvmx_spi_mode_t mode);
21073 +
21074 +} cvmx_spi_callbacks_t;
21075 +
21076 +/**
21077 + * Return true if the supplied interface is configured for SPI
21078 + *
21079 + * @interface: Interface to check
21080 + * Returns True if interface is SPI
21081 + */
21082 +static inline int cvmx_spi_is_spi_interface(int interface)
21083 +{
21084 + uint64_t gmxState = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
21085 + return (gmxState & 0x2) && (gmxState & 0x1);
21086 +}
21087 +
21088 +/**
21089 + * Initialize and start the SPI interface.
21090 + *
21091 + * @interface: The identifier of the packet interface to configure and
21092 + * use as a SPI interface.
21093 + * @mode: The operating mode for the SPI interface. The interface
21094 + * can operate as a full duplex (both Tx and Rx data paths
21095 + * active) or as a halfplex (either the Tx data path is
21096 + * active or the Rx data path is active, but not both).
21097 + * @timeout: Timeout to wait for clock synchronization in seconds
21098 + * @num_ports: Number of SPI ports to configure
21099 + *
21100 + * Returns Zero on success, negative of failure.
21101 + */
21102 +extern int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode,
21103 + int timeout, int num_ports);
21104 +
21105 +/**
21106 + * This routine restarts the SPI interface after it has lost synchronization
21107 + * with its corespondant system.
21108 + *
21109 + * @interface: The identifier of the packet interface to configure and
21110 + * use as a SPI interface.
21111 + * @mode: The operating mode for the SPI interface. The interface
21112 + * can operate as a full duplex (both Tx and Rx data paths
21113 + * active) or as a halfplex (either the Tx data path is
21114 + * active or the Rx data path is active, but not both).
21115 + * @timeout: Timeout to wait for clock synchronization in seconds
21116 + * Returns Zero on success, negative of failure.
21117 + */
21118 +extern int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode,
21119 + int timeout);
21120 +
21121 +/**
21122 + * Return non-zero if the SPI interface has a SPI4000 attached
21123 + *
21124 + * @interface: SPI interface the SPI4000 is connected to
21125 + *
21126 + * Returns
21127 + */
21128 +static inline int cvmx_spi4000_is_present(int interface)
21129 +{
21130 + return 0;
21131 +}
21132 +
21133 +/**
21134 + * Initialize the SPI4000 for use
21135 + *
21136 + * @interface: SPI interface the SPI4000 is connected to
21137 + */
21138 +static inline int cvmx_spi4000_initialize(int interface)
21139 +{
21140 + return 0;
21141 +}
21142 +
21143 +/**
21144 + * Poll all the SPI4000 port and check its speed
21145 + *
21146 + * @interface: Interface the SPI4000 is on
21147 + * @port: Port to poll (0-9)
21148 + * Returns Status of the port. 0=down. All other values the port is up.
21149 + */
21150 +static inline union cvmx_gmxx_rxx_rx_inbnd cvmx_spi4000_check_speed(
21151 + int interface,
21152 + int port)
21153 +{
21154 + union cvmx_gmxx_rxx_rx_inbnd r;
21155 + r.u64 = 0;
21156 + return r;
21157 +}
21158 +
21159 +/**
21160 + * Get current SPI4 initialization callbacks
21161 + *
21162 + * @callbacks: Pointer to the callbacks structure.to fill
21163 + *
21164 + * Returns Pointer to cvmx_spi_callbacks_t structure.
21165 + */
21166 +extern void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks);
21167 +
21168 +/**
21169 + * Set new SPI4 initialization callbacks
21170 + *
21171 + * @new_callbacks: Pointer to an updated callbacks structure.
21172 + */
21173 +extern void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks);
21174 +
21175 +/**
21176 + * Callback to perform SPI4 reset
21177 + *
21178 + * @interface: The identifier of the packet interface to configure and
21179 + * use as a SPI interface.
21180 + * @mode: The operating mode for the SPI interface. The interface
21181 + * can operate as a full duplex (both Tx and Rx data paths
21182 + * active) or as a halfplex (either the Tx data path is
21183 + * active or the Rx data path is active, but not both).
21184 + *
21185 + * Returns Zero on success, non-zero error code on failure (will cause
21186 + * SPI initialization to abort)
21187 + */
21188 +extern int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode);
21189 +
21190 +/**
21191 + * Callback to setup calendar and miscellaneous settings before clock
21192 + * detection
21193 + *
21194 + * @interface: The identifier of the packet interface to configure and
21195 + * use as a SPI interface.
21196 + * @mode: The operating mode for the SPI interface. The interface
21197 + * can operate as a full duplex (both Tx and Rx data paths
21198 + * active) or as a halfplex (either the Tx data path is
21199 + * active or the Rx data path is active, but not both).
21200 + * @num_ports: Number of ports to configure on SPI
21201 + *
21202 + * Returns Zero on success, non-zero error code on failure (will cause
21203 + * SPI initialization to abort)
21204 + */
21205 +extern int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
21206 + int num_ports);
21207 +
21208 +/**
21209 + * Callback to perform clock detection
21210 + *
21211 + * @interface: The identifier of the packet interface to configure and
21212 + * use as a SPI interface.
21213 + * @mode: The operating mode for the SPI interface. The interface
21214 + * can operate as a full duplex (both Tx and Rx data paths
21215 + * active) or as a halfplex (either the Tx data path is
21216 + * active or the Rx data path is active, but not both).
21217 + * @timeout: Timeout to wait for clock synchronization in seconds
21218 + *
21219 + * Returns Zero on success, non-zero error code on failure (will cause
21220 + * SPI initialization to abort)
21221 + */
21222 +extern int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode,
21223 + int timeout);
21224 +
21225 +/**
21226 + * Callback to perform link training
21227 + *
21228 + * @interface: The identifier of the packet interface to configure and
21229 + * use as a SPI interface.
21230 + * @mode: The operating mode for the SPI interface. The interface
21231 + * can operate as a full duplex (both Tx and Rx data paths
21232 + * active) or as a halfplex (either the Tx data path is
21233 + * active or the Rx data path is active, but not both).
21234 + * @timeout: Timeout to wait for link to be trained (in seconds)
21235 + *
21236 + * Returns Zero on success, non-zero error code on failure (will cause
21237 + * SPI initialization to abort)
21238 + */
21239 +extern int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode,
21240 + int timeout);
21241 +
21242 +/**
21243 + * Callback to perform calendar data synchronization
21244 + *
21245 + * @interface: The identifier of the packet interface to configure and
21246 + * use as a SPI interface.
21247 + * @mode: The operating mode for the SPI interface. The interface
21248 + * can operate as a full duplex (both Tx and Rx data paths
21249 + * active) or as a halfplex (either the Tx data path is
21250 + * active or the Rx data path is active, but not both).
21251 + * @timeout: Timeout to wait for calendar data in seconds
21252 + *
21253 + * Returns Zero on success, non-zero error code on failure (will cause
21254 + * SPI initialization to abort)
21255 + */
21256 +extern int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode,
21257 + int timeout);
21258 +
21259 +/**
21260 + * Callback to handle interface up
21261 + *
21262 + * @interface: The identifier of the packet interface to configure and
21263 + * use as a SPI interface.
21264 + * @mode: The operating mode for the SPI interface. The interface
21265 + * can operate as a full duplex (both Tx and Rx data paths
21266 + * active) or as a halfplex (either the Tx data path is
21267 + * active or the Rx data path is active, but not both).
21268 + *
21269 + * Returns Zero on success, non-zero error code on failure (will cause
21270 + * SPI initialization to abort)
21271 + */
21272 +extern int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode);
21273 +
21274 +#endif /* __CVMX_SPI_H__ */
21275 diff --git a/drivers/staging/octeon/cvmx-spxx-defs.h b/drivers/staging/octeon/cvmx-spxx-defs.h
21276 new file mode 100644
21277 index 0000000..b16940e
21278 --- /dev/null
21279 +++ b/drivers/staging/octeon/cvmx-spxx-defs.h
21280 @@ -0,0 +1,347 @@
21281 +/***********************license start***************
21282 + * Author: Cavium Networks
21283 + *
21284 + * Contact: support@caviumnetworks.com
21285 + * This file is part of the OCTEON SDK
21286 + *
21287 + * Copyright (c) 2003-2008 Cavium Networks
21288 + *
21289 + * This file is free software; you can redistribute it and/or modify
21290 + * it under the terms of the GNU General Public License, Version 2, as
21291 + * published by the Free Software Foundation.
21292 + *
21293 + * This file is distributed in the hope that it will be useful, but
21294 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21295 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21296 + * NONINFRINGEMENT. See the GNU General Public License for more
21297 + * details.
21298 + *
21299 + * You should have received a copy of the GNU General Public License
21300 + * along with this file; if not, write to the Free Software
21301 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21302 + * or visit http://www.gnu.org/licenses/.
21303 + *
21304 + * This file may also be available under a different license from Cavium.
21305 + * Contact Cavium Networks for more information
21306 + ***********************license end**************************************/
21307 +
21308 +#ifndef __CVMX_SPXX_DEFS_H__
21309 +#define __CVMX_SPXX_DEFS_H__
21310 +
21311 +#define CVMX_SPXX_BCKPRS_CNT(block_id) \
21312 + CVMX_ADD_IO_SEG(0x0001180090000340ull + (((block_id) & 1) * 0x8000000ull))
21313 +#define CVMX_SPXX_BIST_STAT(block_id) \
21314 + CVMX_ADD_IO_SEG(0x00011800900007F8ull + (((block_id) & 1) * 0x8000000ull))
21315 +#define CVMX_SPXX_CLK_CTL(block_id) \
21316 + CVMX_ADD_IO_SEG(0x0001180090000348ull + (((block_id) & 1) * 0x8000000ull))
21317 +#define CVMX_SPXX_CLK_STAT(block_id) \
21318 + CVMX_ADD_IO_SEG(0x0001180090000350ull + (((block_id) & 1) * 0x8000000ull))
21319 +#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) \
21320 + CVMX_ADD_IO_SEG(0x0001180090000368ull + (((block_id) & 1) * 0x8000000ull))
21321 +#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) \
21322 + CVMX_ADD_IO_SEG(0x0001180090000370ull + (((block_id) & 1) * 0x8000000ull))
21323 +#define CVMX_SPXX_DRV_CTL(block_id) \
21324 + CVMX_ADD_IO_SEG(0x0001180090000358ull + (((block_id) & 1) * 0x8000000ull))
21325 +#define CVMX_SPXX_ERR_CTL(block_id) \
21326 + CVMX_ADD_IO_SEG(0x0001180090000320ull + (((block_id) & 1) * 0x8000000ull))
21327 +#define CVMX_SPXX_INT_DAT(block_id) \
21328 + CVMX_ADD_IO_SEG(0x0001180090000318ull + (((block_id) & 1) * 0x8000000ull))
21329 +#define CVMX_SPXX_INT_MSK(block_id) \
21330 + CVMX_ADD_IO_SEG(0x0001180090000308ull + (((block_id) & 1) * 0x8000000ull))
21331 +#define CVMX_SPXX_INT_REG(block_id) \
21332 + CVMX_ADD_IO_SEG(0x0001180090000300ull + (((block_id) & 1) * 0x8000000ull))
21333 +#define CVMX_SPXX_INT_SYNC(block_id) \
21334 + CVMX_ADD_IO_SEG(0x0001180090000310ull + (((block_id) & 1) * 0x8000000ull))
21335 +#define CVMX_SPXX_TPA_ACC(block_id) \
21336 + CVMX_ADD_IO_SEG(0x0001180090000338ull + (((block_id) & 1) * 0x8000000ull))
21337 +#define CVMX_SPXX_TPA_MAX(block_id) \
21338 + CVMX_ADD_IO_SEG(0x0001180090000330ull + (((block_id) & 1) * 0x8000000ull))
21339 +#define CVMX_SPXX_TPA_SEL(block_id) \
21340 + CVMX_ADD_IO_SEG(0x0001180090000328ull + (((block_id) & 1) * 0x8000000ull))
21341 +#define CVMX_SPXX_TRN4_CTL(block_id) \
21342 + CVMX_ADD_IO_SEG(0x0001180090000360ull + (((block_id) & 1) * 0x8000000ull))
21343 +
21344 +union cvmx_spxx_bckprs_cnt {
21345 + uint64_t u64;
21346 + struct cvmx_spxx_bckprs_cnt_s {
21347 + uint64_t reserved_32_63:32;
21348 + uint64_t cnt:32;
21349 + } s;
21350 + struct cvmx_spxx_bckprs_cnt_s cn38xx;
21351 + struct cvmx_spxx_bckprs_cnt_s cn38xxp2;
21352 + struct cvmx_spxx_bckprs_cnt_s cn58xx;
21353 + struct cvmx_spxx_bckprs_cnt_s cn58xxp1;
21354 +};
21355 +
21356 +union cvmx_spxx_bist_stat {
21357 + uint64_t u64;
21358 + struct cvmx_spxx_bist_stat_s {
21359 + uint64_t reserved_3_63:61;
21360 + uint64_t stat2:1;
21361 + uint64_t stat1:1;
21362 + uint64_t stat0:1;
21363 + } s;
21364 + struct cvmx_spxx_bist_stat_s cn38xx;
21365 + struct cvmx_spxx_bist_stat_s cn38xxp2;
21366 + struct cvmx_spxx_bist_stat_s cn58xx;
21367 + struct cvmx_spxx_bist_stat_s cn58xxp1;
21368 +};
21369 +
21370 +union cvmx_spxx_clk_ctl {
21371 + uint64_t u64;
21372 + struct cvmx_spxx_clk_ctl_s {
21373 + uint64_t reserved_17_63:47;
21374 + uint64_t seetrn:1;
21375 + uint64_t reserved_12_15:4;
21376 + uint64_t clkdly:5;
21377 + uint64_t runbist:1;
21378 + uint64_t statdrv:1;
21379 + uint64_t statrcv:1;
21380 + uint64_t sndtrn:1;
21381 + uint64_t drptrn:1;
21382 + uint64_t rcvtrn:1;
21383 + uint64_t srxdlck:1;
21384 + } s;
21385 + struct cvmx_spxx_clk_ctl_s cn38xx;
21386 + struct cvmx_spxx_clk_ctl_s cn38xxp2;
21387 + struct cvmx_spxx_clk_ctl_s cn58xx;
21388 + struct cvmx_spxx_clk_ctl_s cn58xxp1;
21389 +};
21390 +
21391 +union cvmx_spxx_clk_stat {
21392 + uint64_t u64;
21393 + struct cvmx_spxx_clk_stat_s {
21394 + uint64_t reserved_11_63:53;
21395 + uint64_t stxcal:1;
21396 + uint64_t reserved_9_9:1;
21397 + uint64_t srxtrn:1;
21398 + uint64_t s4clk1:1;
21399 + uint64_t s4clk0:1;
21400 + uint64_t d4clk1:1;
21401 + uint64_t d4clk0:1;
21402 + uint64_t reserved_0_3:4;
21403 + } s;
21404 + struct cvmx_spxx_clk_stat_s cn38xx;
21405 + struct cvmx_spxx_clk_stat_s cn38xxp2;
21406 + struct cvmx_spxx_clk_stat_s cn58xx;
21407 + struct cvmx_spxx_clk_stat_s cn58xxp1;
21408 +};
21409 +
21410 +union cvmx_spxx_dbg_deskew_ctl {
21411 + uint64_t u64;
21412 + struct cvmx_spxx_dbg_deskew_ctl_s {
21413 + uint64_t reserved_30_63:34;
21414 + uint64_t fallnop:1;
21415 + uint64_t fall8:1;
21416 + uint64_t reserved_26_27:2;
21417 + uint64_t sstep_go:1;
21418 + uint64_t sstep:1;
21419 + uint64_t reserved_22_23:2;
21420 + uint64_t clrdly:1;
21421 + uint64_t dec:1;
21422 + uint64_t inc:1;
21423 + uint64_t mux:1;
21424 + uint64_t offset:5;
21425 + uint64_t bitsel:5;
21426 + uint64_t offdly:6;
21427 + uint64_t dllfrc:1;
21428 + uint64_t dlldis:1;
21429 + } s;
21430 + struct cvmx_spxx_dbg_deskew_ctl_s cn38xx;
21431 + struct cvmx_spxx_dbg_deskew_ctl_s cn38xxp2;
21432 + struct cvmx_spxx_dbg_deskew_ctl_s cn58xx;
21433 + struct cvmx_spxx_dbg_deskew_ctl_s cn58xxp1;
21434 +};
21435 +
21436 +union cvmx_spxx_dbg_deskew_state {
21437 + uint64_t u64;
21438 + struct cvmx_spxx_dbg_deskew_state_s {
21439 + uint64_t reserved_9_63:55;
21440 + uint64_t testres:1;
21441 + uint64_t unxterm:1;
21442 + uint64_t muxsel:2;
21443 + uint64_t offset:5;
21444 + } s;
21445 + struct cvmx_spxx_dbg_deskew_state_s cn38xx;
21446 + struct cvmx_spxx_dbg_deskew_state_s cn38xxp2;
21447 + struct cvmx_spxx_dbg_deskew_state_s cn58xx;
21448 + struct cvmx_spxx_dbg_deskew_state_s cn58xxp1;
21449 +};
21450 +
21451 +union cvmx_spxx_drv_ctl {
21452 + uint64_t u64;
21453 + struct cvmx_spxx_drv_ctl_s {
21454 + uint64_t reserved_0_63:64;
21455 + } s;
21456 + struct cvmx_spxx_drv_ctl_cn38xx {
21457 + uint64_t reserved_16_63:48;
21458 + uint64_t stx4ncmp:4;
21459 + uint64_t stx4pcmp:4;
21460 + uint64_t srx4cmp:8;
21461 + } cn38xx;
21462 + struct cvmx_spxx_drv_ctl_cn38xx cn38xxp2;
21463 + struct cvmx_spxx_drv_ctl_cn58xx {
21464 + uint64_t reserved_24_63:40;
21465 + uint64_t stx4ncmp:4;
21466 + uint64_t stx4pcmp:4;
21467 + uint64_t reserved_10_15:6;
21468 + uint64_t srx4cmp:10;
21469 + } cn58xx;
21470 + struct cvmx_spxx_drv_ctl_cn58xx cn58xxp1;
21471 +};
21472 +
21473 +union cvmx_spxx_err_ctl {
21474 + uint64_t u64;
21475 + struct cvmx_spxx_err_ctl_s {
21476 + uint64_t reserved_9_63:55;
21477 + uint64_t prtnxa:1;
21478 + uint64_t dipcls:1;
21479 + uint64_t dippay:1;
21480 + uint64_t reserved_4_5:2;
21481 + uint64_t errcnt:4;
21482 + } s;
21483 + struct cvmx_spxx_err_ctl_s cn38xx;
21484 + struct cvmx_spxx_err_ctl_s cn38xxp2;
21485 + struct cvmx_spxx_err_ctl_s cn58xx;
21486 + struct cvmx_spxx_err_ctl_s cn58xxp1;
21487 +};
21488 +
21489 +union cvmx_spxx_int_dat {
21490 + uint64_t u64;
21491 + struct cvmx_spxx_int_dat_s {
21492 + uint64_t reserved_32_63:32;
21493 + uint64_t mul:1;
21494 + uint64_t reserved_14_30:17;
21495 + uint64_t calbnk:2;
21496 + uint64_t rsvop:4;
21497 + uint64_t prt:8;
21498 + } s;
21499 + struct cvmx_spxx_int_dat_s cn38xx;
21500 + struct cvmx_spxx_int_dat_s cn38xxp2;
21501 + struct cvmx_spxx_int_dat_s cn58xx;
21502 + struct cvmx_spxx_int_dat_s cn58xxp1;
21503 +};
21504 +
21505 +union cvmx_spxx_int_msk {
21506 + uint64_t u64;
21507 + struct cvmx_spxx_int_msk_s {
21508 + uint64_t reserved_12_63:52;
21509 + uint64_t calerr:1;
21510 + uint64_t syncerr:1;
21511 + uint64_t diperr:1;
21512 + uint64_t tpaovr:1;
21513 + uint64_t rsverr:1;
21514 + uint64_t drwnng:1;
21515 + uint64_t clserr:1;
21516 + uint64_t spiovr:1;
21517 + uint64_t reserved_2_3:2;
21518 + uint64_t abnorm:1;
21519 + uint64_t prtnxa:1;
21520 + } s;
21521 + struct cvmx_spxx_int_msk_s cn38xx;
21522 + struct cvmx_spxx_int_msk_s cn38xxp2;
21523 + struct cvmx_spxx_int_msk_s cn58xx;
21524 + struct cvmx_spxx_int_msk_s cn58xxp1;
21525 +};
21526 +
21527 +union cvmx_spxx_int_reg {
21528 + uint64_t u64;
21529 + struct cvmx_spxx_int_reg_s {
21530 + uint64_t reserved_32_63:32;
21531 + uint64_t spf:1;
21532 + uint64_t reserved_12_30:19;
21533 + uint64_t calerr:1;
21534 + uint64_t syncerr:1;
21535 + uint64_t diperr:1;
21536 + uint64_t tpaovr:1;
21537 + uint64_t rsverr:1;
21538 + uint64_t drwnng:1;
21539 + uint64_t clserr:1;
21540 + uint64_t spiovr:1;
21541 + uint64_t reserved_2_3:2;
21542 + uint64_t abnorm:1;
21543 + uint64_t prtnxa:1;
21544 + } s;
21545 + struct cvmx_spxx_int_reg_s cn38xx;
21546 + struct cvmx_spxx_int_reg_s cn38xxp2;
21547 + struct cvmx_spxx_int_reg_s cn58xx;
21548 + struct cvmx_spxx_int_reg_s cn58xxp1;
21549 +};
21550 +
21551 +union cvmx_spxx_int_sync {
21552 + uint64_t u64;
21553 + struct cvmx_spxx_int_sync_s {
21554 + uint64_t reserved_12_63:52;
21555 + uint64_t calerr:1;
21556 + uint64_t syncerr:1;
21557 + uint64_t diperr:1;
21558 + uint64_t tpaovr:1;
21559 + uint64_t rsverr:1;
21560 + uint64_t drwnng:1;
21561 + uint64_t clserr:1;
21562 + uint64_t spiovr:1;
21563 + uint64_t reserved_2_3:2;
21564 + uint64_t abnorm:1;
21565 + uint64_t prtnxa:1;
21566 + } s;
21567 + struct cvmx_spxx_int_sync_s cn38xx;
21568 + struct cvmx_spxx_int_sync_s cn38xxp2;
21569 + struct cvmx_spxx_int_sync_s cn58xx;
21570 + struct cvmx_spxx_int_sync_s cn58xxp1;
21571 +};
21572 +
21573 +union cvmx_spxx_tpa_acc {
21574 + uint64_t u64;
21575 + struct cvmx_spxx_tpa_acc_s {
21576 + uint64_t reserved_32_63:32;
21577 + uint64_t cnt:32;
21578 + } s;
21579 + struct cvmx_spxx_tpa_acc_s cn38xx;
21580 + struct cvmx_spxx_tpa_acc_s cn38xxp2;
21581 + struct cvmx_spxx_tpa_acc_s cn58xx;
21582 + struct cvmx_spxx_tpa_acc_s cn58xxp1;
21583 +};
21584 +
21585 +union cvmx_spxx_tpa_max {
21586 + uint64_t u64;
21587 + struct cvmx_spxx_tpa_max_s {
21588 + uint64_t reserved_32_63:32;
21589 + uint64_t max:32;
21590 + } s;
21591 + struct cvmx_spxx_tpa_max_s cn38xx;
21592 + struct cvmx_spxx_tpa_max_s cn38xxp2;
21593 + struct cvmx_spxx_tpa_max_s cn58xx;
21594 + struct cvmx_spxx_tpa_max_s cn58xxp1;
21595 +};
21596 +
21597 +union cvmx_spxx_tpa_sel {
21598 + uint64_t u64;
21599 + struct cvmx_spxx_tpa_sel_s {
21600 + uint64_t reserved_4_63:60;
21601 + uint64_t prtsel:4;
21602 + } s;
21603 + struct cvmx_spxx_tpa_sel_s cn38xx;
21604 + struct cvmx_spxx_tpa_sel_s cn38xxp2;
21605 + struct cvmx_spxx_tpa_sel_s cn58xx;
21606 + struct cvmx_spxx_tpa_sel_s cn58xxp1;
21607 +};
21608 +
21609 +union cvmx_spxx_trn4_ctl {
21610 + uint64_t u64;
21611 + struct cvmx_spxx_trn4_ctl_s {
21612 + uint64_t reserved_13_63:51;
21613 + uint64_t trntest:1;
21614 + uint64_t jitter:3;
21615 + uint64_t clr_boot:1;
21616 + uint64_t set_boot:1;
21617 + uint64_t maxdist:5;
21618 + uint64_t macro_en:1;
21619 + uint64_t mux_en:1;
21620 + } s;
21621 + struct cvmx_spxx_trn4_ctl_s cn38xx;
21622 + struct cvmx_spxx_trn4_ctl_s cn38xxp2;
21623 + struct cvmx_spxx_trn4_ctl_s cn58xx;
21624 + struct cvmx_spxx_trn4_ctl_s cn58xxp1;
21625 +};
21626 +
21627 +#endif
21628 diff --git a/drivers/staging/octeon/cvmx-srxx-defs.h b/drivers/staging/octeon/cvmx-srxx-defs.h
21629 new file mode 100644
21630 index 0000000..d82b366
21631 --- /dev/null
21632 +++ b/drivers/staging/octeon/cvmx-srxx-defs.h
21633 @@ -0,0 +1,126 @@
21634 +/***********************license start***************
21635 + * Author: Cavium Networks
21636 + *
21637 + * Contact: support@caviumnetworks.com
21638 + * This file is part of the OCTEON SDK
21639 + *
21640 + * Copyright (c) 2003-2008 Cavium Networks
21641 + *
21642 + * This file is free software; you can redistribute it and/or modify
21643 + * it under the terms of the GNU General Public License, Version 2, as
21644 + * published by the Free Software Foundation.
21645 + *
21646 + * This file is distributed in the hope that it will be useful, but
21647 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21648 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21649 + * NONINFRINGEMENT. See the GNU General Public License for more
21650 + * details.
21651 + *
21652 + * You should have received a copy of the GNU General Public License
21653 + * along with this file; if not, write to the Free Software
21654 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21655 + * or visit http://www.gnu.org/licenses/.
21656 + *
21657 + * This file may also be available under a different license from Cavium.
21658 + * Contact Cavium Networks for more information
21659 + ***********************license end**************************************/
21660 +
21661 +#ifndef __CVMX_SRXX_DEFS_H__
21662 +#define __CVMX_SRXX_DEFS_H__
21663 +
21664 +#define CVMX_SRXX_COM_CTL(block_id) \
21665 + CVMX_ADD_IO_SEG(0x0001180090000200ull + (((block_id) & 1) * 0x8000000ull))
21666 +#define CVMX_SRXX_IGN_RX_FULL(block_id) \
21667 + CVMX_ADD_IO_SEG(0x0001180090000218ull + (((block_id) & 1) * 0x8000000ull))
21668 +#define CVMX_SRXX_SPI4_CALX(offset, block_id) \
21669 + CVMX_ADD_IO_SEG(0x0001180090000000ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
21670 +#define CVMX_SRXX_SPI4_STAT(block_id) \
21671 + CVMX_ADD_IO_SEG(0x0001180090000208ull + (((block_id) & 1) * 0x8000000ull))
21672 +#define CVMX_SRXX_SW_TICK_CTL(block_id) \
21673 + CVMX_ADD_IO_SEG(0x0001180090000220ull + (((block_id) & 1) * 0x8000000ull))
21674 +#define CVMX_SRXX_SW_TICK_DAT(block_id) \
21675 + CVMX_ADD_IO_SEG(0x0001180090000228ull + (((block_id) & 1) * 0x8000000ull))
21676 +
21677 +union cvmx_srxx_com_ctl {
21678 + uint64_t u64;
21679 + struct cvmx_srxx_com_ctl_s {
21680 + uint64_t reserved_8_63:56;
21681 + uint64_t prts:4;
21682 + uint64_t st_en:1;
21683 + uint64_t reserved_1_2:2;
21684 + uint64_t inf_en:1;
21685 + } s;
21686 + struct cvmx_srxx_com_ctl_s cn38xx;
21687 + struct cvmx_srxx_com_ctl_s cn38xxp2;
21688 + struct cvmx_srxx_com_ctl_s cn58xx;
21689 + struct cvmx_srxx_com_ctl_s cn58xxp1;
21690 +};
21691 +
21692 +union cvmx_srxx_ign_rx_full {
21693 + uint64_t u64;
21694 + struct cvmx_srxx_ign_rx_full_s {
21695 + uint64_t reserved_16_63:48;
21696 + uint64_t ignore:16;
21697 + } s;
21698 + struct cvmx_srxx_ign_rx_full_s cn38xx;
21699 + struct cvmx_srxx_ign_rx_full_s cn38xxp2;
21700 + struct cvmx_srxx_ign_rx_full_s cn58xx;
21701 + struct cvmx_srxx_ign_rx_full_s cn58xxp1;
21702 +};
21703 +
21704 +union cvmx_srxx_spi4_calx {
21705 + uint64_t u64;
21706 + struct cvmx_srxx_spi4_calx_s {
21707 + uint64_t reserved_17_63:47;
21708 + uint64_t oddpar:1;
21709 + uint64_t prt3:4;
21710 + uint64_t prt2:4;
21711 + uint64_t prt1:4;
21712 + uint64_t prt0:4;
21713 + } s;
21714 + struct cvmx_srxx_spi4_calx_s cn38xx;
21715 + struct cvmx_srxx_spi4_calx_s cn38xxp2;
21716 + struct cvmx_srxx_spi4_calx_s cn58xx;
21717 + struct cvmx_srxx_spi4_calx_s cn58xxp1;
21718 +};
21719 +
21720 +union cvmx_srxx_spi4_stat {
21721 + uint64_t u64;
21722 + struct cvmx_srxx_spi4_stat_s {
21723 + uint64_t reserved_16_63:48;
21724 + uint64_t m:8;
21725 + uint64_t reserved_7_7:1;
21726 + uint64_t len:7;
21727 + } s;
21728 + struct cvmx_srxx_spi4_stat_s cn38xx;
21729 + struct cvmx_srxx_spi4_stat_s cn38xxp2;
21730 + struct cvmx_srxx_spi4_stat_s cn58xx;
21731 + struct cvmx_srxx_spi4_stat_s cn58xxp1;
21732 +};
21733 +
21734 +union cvmx_srxx_sw_tick_ctl {
21735 + uint64_t u64;
21736 + struct cvmx_srxx_sw_tick_ctl_s {
21737 + uint64_t reserved_14_63:50;
21738 + uint64_t eop:1;
21739 + uint64_t sop:1;
21740 + uint64_t mod:4;
21741 + uint64_t opc:4;
21742 + uint64_t adr:4;
21743 + } s;
21744 + struct cvmx_srxx_sw_tick_ctl_s cn38xx;
21745 + struct cvmx_srxx_sw_tick_ctl_s cn58xx;
21746 + struct cvmx_srxx_sw_tick_ctl_s cn58xxp1;
21747 +};
21748 +
21749 +union cvmx_srxx_sw_tick_dat {
21750 + uint64_t u64;
21751 + struct cvmx_srxx_sw_tick_dat_s {
21752 + uint64_t dat:64;
21753 + } s;
21754 + struct cvmx_srxx_sw_tick_dat_s cn38xx;
21755 + struct cvmx_srxx_sw_tick_dat_s cn58xx;
21756 + struct cvmx_srxx_sw_tick_dat_s cn58xxp1;
21757 +};
21758 +
21759 +#endif
21760 diff --git a/drivers/staging/octeon/cvmx-stxx-defs.h b/drivers/staging/octeon/cvmx-stxx-defs.h
21761 new file mode 100644
21762 index 0000000..4f209b6
21763 --- /dev/null
21764 +++ b/drivers/staging/octeon/cvmx-stxx-defs.h
21765 @@ -0,0 +1,292 @@
21766 +/***********************license start***************
21767 + * Author: Cavium Networks
21768 + *
21769 + * Contact: support@caviumnetworks.com
21770 + * This file is part of the OCTEON SDK
21771 + *
21772 + * Copyright (c) 2003-2008 Cavium Networks
21773 + *
21774 + * This file is free software; you can redistribute it and/or modify
21775 + * it under the terms of the GNU General Public License, Version 2, as
21776 + * published by the Free Software Foundation.
21777 + *
21778 + * This file is distributed in the hope that it will be useful, but
21779 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21780 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
21781 + * NONINFRINGEMENT. See the GNU General Public License for more
21782 + * details.
21783 + *
21784 + * You should have received a copy of the GNU General Public License
21785 + * along with this file; if not, write to the Free Software
21786 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21787 + * or visit http://www.gnu.org/licenses/.
21788 + *
21789 + * This file may also be available under a different license from Cavium.
21790 + * Contact Cavium Networks for more information
21791 + ***********************license end**************************************/
21792 +
21793 +#ifndef __CVMX_STXX_DEFS_H__
21794 +#define __CVMX_STXX_DEFS_H__
21795 +
21796 +#define CVMX_STXX_ARB_CTL(block_id) \
21797 + CVMX_ADD_IO_SEG(0x0001180090000608ull + (((block_id) & 1) * 0x8000000ull))
21798 +#define CVMX_STXX_BCKPRS_CNT(block_id) \
21799 + CVMX_ADD_IO_SEG(0x0001180090000688ull + (((block_id) & 1) * 0x8000000ull))
21800 +#define CVMX_STXX_COM_CTL(block_id) \
21801 + CVMX_ADD_IO_SEG(0x0001180090000600ull + (((block_id) & 1) * 0x8000000ull))
21802 +#define CVMX_STXX_DIP_CNT(block_id) \
21803 + CVMX_ADD_IO_SEG(0x0001180090000690ull + (((block_id) & 1) * 0x8000000ull))
21804 +#define CVMX_STXX_IGN_CAL(block_id) \
21805 + CVMX_ADD_IO_SEG(0x0001180090000610ull + (((block_id) & 1) * 0x8000000ull))
21806 +#define CVMX_STXX_INT_MSK(block_id) \
21807 + CVMX_ADD_IO_SEG(0x00011800900006A0ull + (((block_id) & 1) * 0x8000000ull))
21808 +#define CVMX_STXX_INT_REG(block_id) \
21809 + CVMX_ADD_IO_SEG(0x0001180090000698ull + (((block_id) & 1) * 0x8000000ull))
21810 +#define CVMX_STXX_INT_SYNC(block_id) \
21811 + CVMX_ADD_IO_SEG(0x00011800900006A8ull + (((block_id) & 1) * 0x8000000ull))
21812 +#define CVMX_STXX_MIN_BST(block_id) \
21813 + CVMX_ADD_IO_SEG(0x0001180090000618ull + (((block_id) & 1) * 0x8000000ull))
21814 +#define CVMX_STXX_SPI4_CALX(offset, block_id) \
21815 + CVMX_ADD_IO_SEG(0x0001180090000400ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
21816 +#define CVMX_STXX_SPI4_DAT(block_id) \
21817 + CVMX_ADD_IO_SEG(0x0001180090000628ull + (((block_id) & 1) * 0x8000000ull))
21818 +#define CVMX_STXX_SPI4_STAT(block_id) \
21819 + CVMX_ADD_IO_SEG(0x0001180090000630ull + (((block_id) & 1) * 0x8000000ull))
21820 +#define CVMX_STXX_STAT_BYTES_HI(block_id) \
21821 + CVMX_ADD_IO_SEG(0x0001180090000648ull + (((block_id) & 1) * 0x8000000ull))
21822 +#define CVMX_STXX_STAT_BYTES_LO(block_id) \
21823 + CVMX_ADD_IO_SEG(0x0001180090000680ull + (((block_id) & 1) * 0x8000000ull))
21824 +#define CVMX_STXX_STAT_CTL(block_id) \
21825 + CVMX_ADD_IO_SEG(0x0001180090000638ull + (((block_id) & 1) * 0x8000000ull))
21826 +#define CVMX_STXX_STAT_PKT_XMT(block_id) \
21827 + CVMX_ADD_IO_SEG(0x0001180090000640ull + (((block_id) & 1) * 0x8000000ull))
21828 +
21829 +union cvmx_stxx_arb_ctl {
21830 + uint64_t u64;
21831 + struct cvmx_stxx_arb_ctl_s {
21832 + uint64_t reserved_6_63:58;
21833 + uint64_t mintrn:1;
21834 + uint64_t reserved_4_4:1;
21835 + uint64_t igntpa:1;
21836 + uint64_t reserved_0_2:3;
21837 + } s;
21838 + struct cvmx_stxx_arb_ctl_s cn38xx;
21839 + struct cvmx_stxx_arb_ctl_s cn38xxp2;
21840 + struct cvmx_stxx_arb_ctl_s cn58xx;
21841 + struct cvmx_stxx_arb_ctl_s cn58xxp1;
21842 +};
21843 +
21844 +union cvmx_stxx_bckprs_cnt {
21845 + uint64_t u64;
21846 + struct cvmx_stxx_bckprs_cnt_s {
21847 + uint64_t reserved_32_63:32;
21848 + uint64_t cnt:32;
21849 + } s;
21850 + struct cvmx_stxx_bckprs_cnt_s cn38xx;
21851 + struct cvmx_stxx_bckprs_cnt_s cn38xxp2;
21852 + struct cvmx_stxx_bckprs_cnt_s cn58xx;
21853 + struct cvmx_stxx_bckprs_cnt_s cn58xxp1;
21854 +};
21855 +
21856 +union cvmx_stxx_com_ctl {
21857 + uint64_t u64;
21858 + struct cvmx_stxx_com_ctl_s {
21859 + uint64_t reserved_4_63:60;
21860 + uint64_t st_en:1;
21861 + uint64_t reserved_1_2:2;
21862 + uint64_t inf_en:1;
21863 + } s;
21864 + struct cvmx_stxx_com_ctl_s cn38xx;
21865 + struct cvmx_stxx_com_ctl_s cn38xxp2;
21866 + struct cvmx_stxx_com_ctl_s cn58xx;
21867 + struct cvmx_stxx_com_ctl_s cn58xxp1;
21868 +};
21869 +
21870 +union cvmx_stxx_dip_cnt {
21871 + uint64_t u64;
21872 + struct cvmx_stxx_dip_cnt_s {
21873 + uint64_t reserved_8_63:56;
21874 + uint64_t frmmax:4;
21875 + uint64_t dipmax:4;
21876 + } s;
21877 + struct cvmx_stxx_dip_cnt_s cn38xx;
21878 + struct cvmx_stxx_dip_cnt_s cn38xxp2;
21879 + struct cvmx_stxx_dip_cnt_s cn58xx;
21880 + struct cvmx_stxx_dip_cnt_s cn58xxp1;
21881 +};
21882 +
21883 +union cvmx_stxx_ign_cal {
21884 + uint64_t u64;
21885 + struct cvmx_stxx_ign_cal_s {
21886 + uint64_t reserved_16_63:48;
21887 + uint64_t igntpa:16;
21888 + } s;
21889 + struct cvmx_stxx_ign_cal_s cn38xx;
21890 + struct cvmx_stxx_ign_cal_s cn38xxp2;
21891 + struct cvmx_stxx_ign_cal_s cn58xx;
21892 + struct cvmx_stxx_ign_cal_s cn58xxp1;
21893 +};
21894 +
21895 +union cvmx_stxx_int_msk {
21896 + uint64_t u64;
21897 + struct cvmx_stxx_int_msk_s {
21898 + uint64_t reserved_8_63:56;
21899 + uint64_t frmerr:1;
21900 + uint64_t unxfrm:1;
21901 + uint64_t nosync:1;
21902 + uint64_t diperr:1;
21903 + uint64_t datovr:1;
21904 + uint64_t ovrbst:1;
21905 + uint64_t calpar1:1;
21906 + uint64_t calpar0:1;
21907 + } s;
21908 + struct cvmx_stxx_int_msk_s cn38xx;
21909 + struct cvmx_stxx_int_msk_s cn38xxp2;
21910 + struct cvmx_stxx_int_msk_s cn58xx;
21911 + struct cvmx_stxx_int_msk_s cn58xxp1;
21912 +};
21913 +
21914 +union cvmx_stxx_int_reg {
21915 + uint64_t u64;
21916 + struct cvmx_stxx_int_reg_s {
21917 + uint64_t reserved_9_63:55;
21918 + uint64_t syncerr:1;
21919 + uint64_t frmerr:1;
21920 + uint64_t unxfrm:1;
21921 + uint64_t nosync:1;
21922 + uint64_t diperr:1;
21923 + uint64_t datovr:1;
21924 + uint64_t ovrbst:1;
21925 + uint64_t calpar1:1;
21926 + uint64_t calpar0:1;
21927 + } s;
21928 + struct cvmx_stxx_int_reg_s cn38xx;
21929 + struct cvmx_stxx_int_reg_s cn38xxp2;
21930 + struct cvmx_stxx_int_reg_s cn58xx;
21931 + struct cvmx_stxx_int_reg_s cn58xxp1;
21932 +};
21933 +
21934 +union cvmx_stxx_int_sync {
21935 + uint64_t u64;
21936 + struct cvmx_stxx_int_sync_s {
21937 + uint64_t reserved_8_63:56;
21938 + uint64_t frmerr:1;
21939 + uint64_t unxfrm:1;
21940 + uint64_t nosync:1;
21941 + uint64_t diperr:1;
21942 + uint64_t datovr:1;
21943 + uint64_t ovrbst:1;
21944 + uint64_t calpar1:1;
21945 + uint64_t calpar0:1;
21946 + } s;
21947 + struct cvmx_stxx_int_sync_s cn38xx;
21948 + struct cvmx_stxx_int_sync_s cn38xxp2;
21949 + struct cvmx_stxx_int_sync_s cn58xx;
21950 + struct cvmx_stxx_int_sync_s cn58xxp1;
21951 +};
21952 +
21953 +union cvmx_stxx_min_bst {
21954 + uint64_t u64;
21955 + struct cvmx_stxx_min_bst_s {
21956 + uint64_t reserved_9_63:55;
21957 + uint64_t minb:9;
21958 + } s;
21959 + struct cvmx_stxx_min_bst_s cn38xx;
21960 + struct cvmx_stxx_min_bst_s cn38xxp2;
21961 + struct cvmx_stxx_min_bst_s cn58xx;
21962 + struct cvmx_stxx_min_bst_s cn58xxp1;
21963 +};
21964 +
21965 +union cvmx_stxx_spi4_calx {
21966 + uint64_t u64;
21967 + struct cvmx_stxx_spi4_calx_s {
21968 + uint64_t reserved_17_63:47;
21969 + uint64_t oddpar:1;
21970 + uint64_t prt3:4;
21971 + uint64_t prt2:4;
21972 + uint64_t prt1:4;
21973 + uint64_t prt0:4;
21974 + } s;
21975 + struct cvmx_stxx_spi4_calx_s cn38xx;
21976 + struct cvmx_stxx_spi4_calx_s cn38xxp2;
21977 + struct cvmx_stxx_spi4_calx_s cn58xx;
21978 + struct cvmx_stxx_spi4_calx_s cn58xxp1;
21979 +};
21980 +
21981 +union cvmx_stxx_spi4_dat {
21982 + uint64_t u64;
21983 + struct cvmx_stxx_spi4_dat_s {
21984 + uint64_t reserved_32_63:32;
21985 + uint64_t alpha:16;
21986 + uint64_t max_t:16;
21987 + } s;
21988 + struct cvmx_stxx_spi4_dat_s cn38xx;
21989 + struct cvmx_stxx_spi4_dat_s cn38xxp2;
21990 + struct cvmx_stxx_spi4_dat_s cn58xx;
21991 + struct cvmx_stxx_spi4_dat_s cn58xxp1;
21992 +};
21993 +
21994 +union cvmx_stxx_spi4_stat {
21995 + uint64_t u64;
21996 + struct cvmx_stxx_spi4_stat_s {
21997 + uint64_t reserved_16_63:48;
21998 + uint64_t m:8;
21999 + uint64_t reserved_7_7:1;
22000 + uint64_t len:7;
22001 + } s;
22002 + struct cvmx_stxx_spi4_stat_s cn38xx;
22003 + struct cvmx_stxx_spi4_stat_s cn38xxp2;
22004 + struct cvmx_stxx_spi4_stat_s cn58xx;
22005 + struct cvmx_stxx_spi4_stat_s cn58xxp1;
22006 +};
22007 +
22008 +union cvmx_stxx_stat_bytes_hi {
22009 + uint64_t u64;
22010 + struct cvmx_stxx_stat_bytes_hi_s {
22011 + uint64_t reserved_32_63:32;
22012 + uint64_t cnt:32;
22013 + } s;
22014 + struct cvmx_stxx_stat_bytes_hi_s cn38xx;
22015 + struct cvmx_stxx_stat_bytes_hi_s cn38xxp2;
22016 + struct cvmx_stxx_stat_bytes_hi_s cn58xx;
22017 + struct cvmx_stxx_stat_bytes_hi_s cn58xxp1;
22018 +};
22019 +
22020 +union cvmx_stxx_stat_bytes_lo {
22021 + uint64_t u64;
22022 + struct cvmx_stxx_stat_bytes_lo_s {
22023 + uint64_t reserved_32_63:32;
22024 + uint64_t cnt:32;
22025 + } s;
22026 + struct cvmx_stxx_stat_bytes_lo_s cn38xx;
22027 + struct cvmx_stxx_stat_bytes_lo_s cn38xxp2;
22028 + struct cvmx_stxx_stat_bytes_lo_s cn58xx;
22029 + struct cvmx_stxx_stat_bytes_lo_s cn58xxp1;
22030 +};
22031 +
22032 +union cvmx_stxx_stat_ctl {
22033 + uint64_t u64;
22034 + struct cvmx_stxx_stat_ctl_s {
22035 + uint64_t reserved_5_63:59;
22036 + uint64_t clr:1;
22037 + uint64_t bckprs:4;
22038 + } s;
22039 + struct cvmx_stxx_stat_ctl_s cn38xx;
22040 + struct cvmx_stxx_stat_ctl_s cn38xxp2;
22041 + struct cvmx_stxx_stat_ctl_s cn58xx;
22042 + struct cvmx_stxx_stat_ctl_s cn58xxp1;
22043 +};
22044 +
22045 +union cvmx_stxx_stat_pkt_xmt {
22046 + uint64_t u64;
22047 + struct cvmx_stxx_stat_pkt_xmt_s {
22048 + uint64_t reserved_32_63:32;
22049 + uint64_t cnt:32;
22050 + } s;
22051 + struct cvmx_stxx_stat_pkt_xmt_s cn38xx;
22052 + struct cvmx_stxx_stat_pkt_xmt_s cn38xxp2;
22053 + struct cvmx_stxx_stat_pkt_xmt_s cn58xx;
22054 + struct cvmx_stxx_stat_pkt_xmt_s cn58xxp1;
22055 +};
22056 +
22057 +#endif
22058 diff --git a/drivers/staging/octeon/cvmx-wqe.h b/drivers/staging/octeon/cvmx-wqe.h
22059 new file mode 100644
22060 index 0000000..6536109
22061 --- /dev/null
22062 +++ b/drivers/staging/octeon/cvmx-wqe.h
22063 @@ -0,0 +1,397 @@
22064 +/***********************license start***************
22065 + * Author: Cavium Networks
22066 + *
22067 + * Contact: support@caviumnetworks.com
22068 + * This file is part of the OCTEON SDK
22069 + *
22070 + * Copyright (c) 2003-2008 Cavium Networks
22071 + *
22072 + * This file is free software; you can redistribute it and/or modify
22073 + * it under the terms of the GNU General Public License, Version 2, as
22074 + * published by the Free Software Foundation.
22075 + *
22076 + * This file is distributed in the hope that it will be useful, but
22077 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22078 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22079 + * NONINFRINGEMENT. See the GNU General Public License for more
22080 + * details.
22081 + *
22082 + * You should have received a copy of the GNU General Public License
22083 + * along with this file; if not, write to the Free Software
22084 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22085 + * or visit http://www.gnu.org/licenses/.
22086 + *
22087 + * This file may also be available under a different license from Cavium.
22088 + * Contact Cavium Networks for more information
22089 + ***********************license end**************************************/
22090 +
22091 +/**
22092 + *
22093 + * This header file defines the work queue entry (wqe) data structure.
22094 + * Since this is a commonly used structure that depends on structures
22095 + * from several hardware blocks, those definitions have been placed
22096 + * in this file to create a single point of definition of the wqe
22097 + * format.
22098 + * Data structures are still named according to the block that they
22099 + * relate to.
22100 + *
22101 + */
22102 +
22103 +#ifndef __CVMX_WQE_H__
22104 +#define __CVMX_WQE_H__
22105 +
22106 +#include "cvmx-packet.h"
22107 +
22108 +
22109 +#define OCT_TAG_TYPE_STRING(x) \
22110 + (((x) == CVMX_POW_TAG_TYPE_ORDERED) ? "ORDERED" : \
22111 + (((x) == CVMX_POW_TAG_TYPE_ATOMIC) ? "ATOMIC" : \
22112 + (((x) == CVMX_POW_TAG_TYPE_NULL) ? "NULL" : \
22113 + "NULL_NULL")))
22114 +
22115 +/**
22116 + * HW decode / err_code in work queue entry
22117 + */
22118 +typedef union {
22119 + uint64_t u64;
22120 +
22121 + /* Use this struct if the hardware determines that the packet is IP */
22122 + struct {
22123 + /* HW sets this to the number of buffers used by this packet */
22124 + uint64_t bufs:8;
22125 + /* HW sets to the number of L2 bytes prior to the IP */
22126 + uint64_t ip_offset:8;
22127 + /* set to 1 if we found DSA/VLAN in the L2 */
22128 + uint64_t vlan_valid:1;
22129 + /* Set to 1 if the DSA/VLAN tag is stacked */
22130 + uint64_t vlan_stacked:1;
22131 + uint64_t unassigned:1;
22132 + /* HW sets to the DSA/VLAN CFI flag (valid when vlan_valid) */
22133 + uint64_t vlan_cfi:1;
22134 + /* HW sets to the DSA/VLAN_ID field (valid when vlan_valid) */
22135 + uint64_t vlan_id:12;
22136 + /* Ring Identifier (if PCIe). Requires PIP_GBL_CTL[RING_EN]=1 */
22137 + uint64_t pr:4;
22138 + uint64_t unassigned2:8;
22139 + /* the packet needs to be decompressed */
22140 + uint64_t dec_ipcomp:1;
22141 + /* the packet is either TCP or UDP */
22142 + uint64_t tcp_or_udp:1;
22143 + /* the packet needs to be decrypted (ESP or AH) */
22144 + uint64_t dec_ipsec:1;
22145 + /* the packet is IPv6 */
22146 + uint64_t is_v6:1;
22147 +
22148 + /*
22149 + * (rcv_error, not_IP, IP_exc, is_frag, L4_error,
22150 + * software, etc.).
22151 + */
22152 +
22153 + /*
22154 + * reserved for software use, hardware will clear on
22155 + * packet creation.
22156 + */
22157 + uint64_t software:1;
22158 + /* exceptional conditions below */
22159 + /* the receive interface hardware detected an L4 error
22160 + * (only applies if !is_frag) (only applies if
22161 + * !rcv_error && !not_IP && !IP_exc && !is_frag)
22162 + * failure indicated in err_code below, decode:
22163 + *
22164 + * - 1 = Malformed L4
22165 + * - 2 = L4 Checksum Error: the L4 checksum value is
22166 + * - 3 = UDP Length Error: The UDP length field would
22167 + * make the UDP data longer than what remains in
22168 + * the IP packet (as defined by the IP header
22169 + * length field).
22170 + * - 4 = Bad L4 Port: either the source or destination
22171 + * TCP/UDP port is 0.
22172 + * - 8 = TCP FIN Only: the packet is TCP and only the
22173 + * FIN flag set.
22174 + * - 9 = TCP No Flags: the packet is TCP and no flags
22175 + * are set.
22176 + * - 10 = TCP FIN RST: the packet is TCP and both FIN
22177 + * and RST are set.
22178 + * - 11 = TCP SYN URG: the packet is TCP and both SYN
22179 + * and URG are set.
22180 + * - 12 = TCP SYN RST: the packet is TCP and both SYN
22181 + * and RST are set.
22182 + * - 13 = TCP SYN FIN: the packet is TCP and both SYN
22183 + * and FIN are set.
22184 + */
22185 + uint64_t L4_error:1;
22186 + /* set if the packet is a fragment */
22187 + uint64_t is_frag:1;
22188 + /* the receive interface hardware detected an IP error
22189 + * / exception (only applies if !rcv_error && !not_IP)
22190 + * failure indicated in err_code below, decode:
22191 + *
22192 + * - 1 = Not IP: the IP version field is neither 4 nor
22193 + * 6.
22194 + * - 2 = IPv4 Header Checksum Error: the IPv4 header
22195 + * has a checksum violation.
22196 + * - 3 = IP Malformed Header: the packet is not long
22197 + * enough to contain the IP header.
22198 + * - 4 = IP Malformed: the packet is not long enough
22199 + * to contain the bytes indicated by the IP
22200 + * header. Pad is allowed.
22201 + * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6
22202 + * Hop Count field are zero.
22203 + * - 6 = IP Options
22204 + */
22205 + uint64_t IP_exc:1;
22206 + /*
22207 + * Set if the hardware determined that the packet is a
22208 + * broadcast.
22209 + */
22210 + uint64_t is_bcast:1;
22211 + /*
22212 + * St if the hardware determined that the packet is a
22213 + * multi-cast.
22214 + */
22215 + uint64_t is_mcast:1;
22216 + /*
22217 + * Set if the packet may not be IP (must be zero in
22218 + * this case).
22219 + */
22220 + uint64_t not_IP:1;
22221 + /*
22222 + * The receive interface hardware detected a receive
22223 + * error (must be zero in this case).
22224 + */
22225 + uint64_t rcv_error:1;
22226 + /* lower err_code = first-level descriptor of the
22227 + * work */
22228 + /* zero for packet submitted by hardware that isn't on
22229 + * the slow path */
22230 + /* type is cvmx_pip_err_t */
22231 + uint64_t err_code:8;
22232 + } s;
22233 +
22234 + /* use this to get at the 16 vlan bits */
22235 + struct {
22236 + uint64_t unused1:16;
22237 + uint64_t vlan:16;
22238 + uint64_t unused2:32;
22239 + } svlan;
22240 +
22241 + /*
22242 + * use this struct if the hardware could not determine that
22243 + * the packet is ip.
22244 + */
22245 + struct {
22246 + /*
22247 + * HW sets this to the number of buffers used by this
22248 + * packet.
22249 + */
22250 + uint64_t bufs:8;
22251 + uint64_t unused:8;
22252 + /* set to 1 if we found DSA/VLAN in the L2 */
22253 + uint64_t vlan_valid:1;
22254 + /* Set to 1 if the DSA/VLAN tag is stacked */
22255 + uint64_t vlan_stacked:1;
22256 + uint64_t unassigned:1;
22257 + /*
22258 + * HW sets to the DSA/VLAN CFI flag (valid when
22259 + * vlan_valid)
22260 + */
22261 + uint64_t vlan_cfi:1;
22262 + /*
22263 + * HW sets to the DSA/VLAN_ID field (valid when
22264 + * vlan_valid).
22265 + */
22266 + uint64_t vlan_id:12;
22267 + /*
22268 + * Ring Identifier (if PCIe). Requires
22269 + * PIP_GBL_CTL[RING_EN]=1
22270 + */
22271 + uint64_t pr:4;
22272 + uint64_t unassigned2:12;
22273 + /*
22274 + * reserved for software use, hardware will clear on
22275 + * packet creation.
22276 + */
22277 + uint64_t software:1;
22278 + uint64_t unassigned3:1;
22279 + /*
22280 + * set if the hardware determined that the packet is
22281 + * rarp.
22282 + */
22283 + uint64_t is_rarp:1;
22284 + /*
22285 + * set if the hardware determined that the packet is
22286 + * arp
22287 + */
22288 + uint64_t is_arp:1;
22289 + /*
22290 + * set if the hardware determined that the packet is a
22291 + * broadcast.
22292 + */
22293 + uint64_t is_bcast:1;
22294 + /*
22295 + * set if the hardware determined that the packet is a
22296 + * multi-cast
22297 + */
22298 + uint64_t is_mcast:1;
22299 + /*
22300 + * set if the packet may not be IP (must be one in
22301 + * this case)
22302 + */
22303 + uint64_t not_IP:1;
22304 + /* The receive interface hardware detected a receive
22305 + * error. Failure indicated in err_code below,
22306 + * decode:
22307 + *
22308 + * - 1 = partial error: a packet was partially
22309 + * received, but internal buffering / bandwidth
22310 + * was not adequate to receive the entire
22311 + * packet.
22312 + * - 2 = jabber error: the RGMII packet was too large
22313 + * and is truncated.
22314 + * - 3 = overrun error: the RGMII packet is longer
22315 + * than allowed and had an FCS error.
22316 + * - 4 = oversize error: the RGMII packet is longer
22317 + * than allowed.
22318 + * - 5 = alignment error: the RGMII packet is not an
22319 + * integer number of bytes
22320 + * and had an FCS error (100M and 10M only).
22321 + * - 6 = fragment error: the RGMII packet is shorter
22322 + * than allowed and had an FCS error.
22323 + * - 7 = GMX FCS error: the RGMII packet had an FCS
22324 + * error.
22325 + * - 8 = undersize error: the RGMII packet is shorter
22326 + * than allowed.
22327 + * - 9 = extend error: the RGMII packet had an extend
22328 + * error.
22329 + * - 10 = length mismatch error: the RGMII packet had
22330 + * a length that did not match the length field
22331 + * in the L2 HDR.
22332 + * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII
22333 + * packet had one or more data reception errors
22334 + * (RXERR) or the SPI4 packet had one or more
22335 + * DIP4 errors.
22336 + * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII
22337 + * packet was not large enough to cover the
22338 + * skipped bytes or the SPI4 packet was
22339 + * terminated with an About EOPS.
22340 + * - 13 = RGMII nibble error/SPI4 Port NXA Error: the
22341 + * RGMII packet had a studder error (data not
22342 + * repeated - 10/100M only) or the SPI4 packet
22343 + * was sent to an NXA.
22344 + * - 16 = FCS error: a SPI4.2 packet had an FCS error.
22345 + * - 17 = Skip error: a packet was not large enough to
22346 + * cover the skipped bytes.
22347 + * - 18 = L2 header malformed: the packet is not long
22348 + * enough to contain the L2.
22349 + */
22350 +
22351 + uint64_t rcv_error:1;
22352 + /*
22353 + * lower err_code = first-level descriptor of the
22354 + * work
22355 + */
22356 + /*
22357 + * zero for packet submitted by hardware that isn't on
22358 + * the slow path
22359 + */
22360 + /* type is cvmx_pip_err_t (union, so can't use directly */
22361 + uint64_t err_code:8;
22362 + } snoip;
22363 +
22364 +} cvmx_pip_wqe_word2;
22365 +
22366 +/**
22367 + * Work queue entry format
22368 + *
22369 + * must be 8-byte aligned
22370 + */
22371 +typedef struct {
22372 +
22373 + /*****************************************************************
22374 + * WORD 0
22375 + * HW WRITE: the following 64 bits are filled by HW when a packet arrives
22376 + */
22377 +
22378 + /**
22379 + * raw chksum result generated by the HW
22380 + */
22381 + uint16_t hw_chksum;
22382 + /**
22383 + * Field unused by hardware - available for software
22384 + */
22385 + uint8_t unused;
22386 + /**
22387 + * Next pointer used by hardware for list maintenance.
22388 + * May be written/read by HW before the work queue
22389 + * entry is scheduled to a PP
22390 + * (Only 36 bits used in Octeon 1)
22391 + */
22392 + uint64_t next_ptr:40;
22393 +
22394 + /*****************************************************************
22395 + * WORD 1
22396 + * HW WRITE: the following 64 bits are filled by HW when a packet arrives
22397 + */
22398 +
22399 + /**
22400 + * HW sets to the total number of bytes in the packet
22401 + */
22402 + uint64_t len:16;
22403 + /**
22404 + * HW sets this to input physical port
22405 + */
22406 + uint64_t ipprt:6;
22407 +
22408 + /**
22409 + * HW sets this to what it thought the priority of the input packet was
22410 + */
22411 + uint64_t qos:3;
22412 +
22413 + /**
22414 + * the group that the work queue entry will be scheduled to
22415 + */
22416 + uint64_t grp:4;
22417 + /**
22418 + * the type of the tag (ORDERED, ATOMIC, NULL)
22419 + */
22420 + uint64_t tag_type:3;
22421 + /**
22422 + * the synchronization/ordering tag
22423 + */
22424 + uint64_t tag:32;
22425 +
22426 + /**
22427 + * WORD 2 HW WRITE: the following 64-bits are filled in by
22428 + * hardware when a packet arrives This indicates a variety of
22429 + * status and error conditions.
22430 + */
22431 + cvmx_pip_wqe_word2 word2;
22432 +
22433 + /**
22434 + * Pointer to the first segment of the packet.
22435 + */
22436 + union cvmx_buf_ptr packet_ptr;
22437 +
22438 + /**
22439 + * HW WRITE: octeon will fill in a programmable amount from the
22440 + * packet, up to (at most, but perhaps less) the amount
22441 + * needed to fill the work queue entry to 128 bytes
22442 + *
22443 + * If the packet is recognized to be IP, the hardware starts
22444 + * (except that the IPv4 header is padded for appropriate
22445 + * alignment) writing here where the IP header starts. If the
22446 + * packet is not recognized to be IP, the hardware starts
22447 + * writing the beginning of the packet here.
22448 + */
22449 + uint8_t packet_data[96];
22450 +
22451 + /**
22452 + * If desired, SW can make the work Q entry any length. For the
22453 + * purposes of discussion here, Assume 128B always, as this is all that
22454 + * the hardware deals with.
22455 + *
22456 + */
22457 +
22458 +} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;
22459 +
22460 +#endif /* __CVMX_WQE_H__ */
22461 diff --git a/drivers/staging/octeon/ethernet-common.c b/drivers/staging/octeon/ethernet-common.c
22462 new file mode 100644
22463 index 0000000..3e6f5b8
22464 --- /dev/null
22465 +++ b/drivers/staging/octeon/ethernet-common.c
22466 @@ -0,0 +1,328 @@
22467 +/**********************************************************************
22468 + * Author: Cavium Networks
22469 + *
22470 + * Contact: support@caviumnetworks.com
22471 + * This file is part of the OCTEON SDK
22472 + *
22473 + * Copyright (c) 2003-2007 Cavium Networks
22474 + *
22475 + * This file is free software; you can redistribute it and/or modify
22476 + * it under the terms of the GNU General Public License, Version 2, as
22477 + * published by the Free Software Foundation.
22478 + *
22479 + * This file is distributed in the hope that it will be useful, but
22480 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22481 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22482 + * NONINFRINGEMENT. See the GNU General Public License for more
22483 + * details.
22484 + *
22485 + * You should have received a copy of the GNU General Public License
22486 + * along with this file; if not, write to the Free Software
22487 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22488 + * or visit http://www.gnu.org/licenses/.
22489 + *
22490 + * This file may also be available under a different license from Cavium.
22491 + * Contact Cavium Networks for more information
22492 +**********************************************************************/
22493 +#include <linux/kernel.h>
22494 +#include <linux/mii.h>
22495 +#include <net/dst.h>
22496 +
22497 +#include <asm/atomic.h>
22498 +#include <asm/octeon/octeon.h>
22499 +
22500 +#include "ethernet-defines.h"
22501 +#include "ethernet-tx.h"
22502 +#include "ethernet-mdio.h"
22503 +#include "ethernet-util.h"
22504 +#include "octeon-ethernet.h"
22505 +#include "ethernet-common.h"
22506 +
22507 +#include "cvmx-pip.h"
22508 +#include "cvmx-pko.h"
22509 +#include "cvmx-fau.h"
22510 +#include "cvmx-helper.h"
22511 +
22512 +#include "cvmx-gmxx-defs.h"
22513 +
22514 +/**
22515 + * Get the low level ethernet statistics
22516 + *
22517 + * @dev: Device to get the statistics from
22518 + * Returns Pointer to the statistics
22519 + */
22520 +static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
22521 +{
22522 + cvmx_pip_port_status_t rx_status;
22523 + cvmx_pko_port_status_t tx_status;
22524 + struct octeon_ethernet *priv = netdev_priv(dev);
22525 +
22526 + if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
22527 + if (octeon_is_simulation()) {
22528 + /* The simulator doesn't support statistics */
22529 + memset(&rx_status, 0, sizeof(rx_status));
22530 + memset(&tx_status, 0, sizeof(tx_status));
22531 + } else {
22532 + cvmx_pip_get_port_status(priv->port, 1, &rx_status);
22533 + cvmx_pko_get_port_status(priv->port, 1, &tx_status);
22534 + }
22535 +
22536 + priv->stats.rx_packets += rx_status.inb_packets;
22537 + priv->stats.tx_packets += tx_status.packets;
22538 + priv->stats.rx_bytes += rx_status.inb_octets;
22539 + priv->stats.tx_bytes += tx_status.octets;
22540 + priv->stats.multicast += rx_status.multicast_packets;
22541 + priv->stats.rx_crc_errors += rx_status.inb_errors;
22542 + priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
22543 +
22544 + /*
22545 + * The drop counter must be incremented atomically
22546 + * since the RX tasklet also increments it.
22547 + */
22548 +#ifdef CONFIG_64BIT
22549 + atomic64_add(rx_status.dropped_packets,
22550 + (atomic64_t *)&priv->stats.rx_dropped);
22551 +#else
22552 + atomic_add(rx_status.dropped_packets,
22553 + (atomic_t *)&priv->stats.rx_dropped);
22554 +#endif
22555 + }
22556 +
22557 + return &priv->stats;
22558 +}
22559 +
22560 +/**
22561 + * Set the multicast list. Currently unimplemented.
22562 + *
22563 + * @dev: Device to work on
22564 + */
22565 +static void cvm_oct_common_set_multicast_list(struct net_device *dev)
22566 +{
22567 + union cvmx_gmxx_prtx_cfg gmx_cfg;
22568 + struct octeon_ethernet *priv = netdev_priv(dev);
22569 + int interface = INTERFACE(priv->port);
22570 + int index = INDEX(priv->port);
22571 +
22572 + if ((interface < 2)
22573 + && (cvmx_helper_interface_get_mode(interface) !=
22574 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
22575 + union cvmx_gmxx_rxx_adr_ctl control;
22576 + control.u64 = 0;
22577 + control.s.bcst = 1; /* Allow broadcast MAC addresses */
22578 +
22579 + if (dev->mc_list || (dev->flags & IFF_ALLMULTI) ||
22580 + (dev->flags & IFF_PROMISC))
22581 + /* Force accept multicast packets */
22582 + control.s.mcst = 2;
22583 + else
22584 + /* Force reject multicat packets */
22585 + control.s.mcst = 1;
22586 +
22587 + if (dev->flags & IFF_PROMISC)
22588 + /*
22589 + * Reject matches if promisc. Since CAM is
22590 + * shut off, should accept everything.
22591 + */
22592 + control.s.cam_mode = 0;
22593 + else
22594 + /* Filter packets based on the CAM */
22595 + control.s.cam_mode = 1;
22596 +
22597 + gmx_cfg.u64 =
22598 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
22599 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22600 + gmx_cfg.u64 & ~1ull);
22601 +
22602 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
22603 + control.u64);
22604 + if (dev->flags & IFF_PROMISC)
22605 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
22606 + (index, interface), 0);
22607 + else
22608 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
22609 + (index, interface), 1);
22610 +
22611 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22612 + gmx_cfg.u64);
22613 + }
22614 +}
22615 +
22616 +/**
22617 + * Set the hardware MAC address for a device
22618 + *
22619 + * @dev: Device to change the MAC address for
22620 + * @addr: Address structure to change it too. MAC address is addr + 2.
22621 + * Returns Zero on success
22622 + */
22623 +static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
22624 +{
22625 + struct octeon_ethernet *priv = netdev_priv(dev);
22626 + union cvmx_gmxx_prtx_cfg gmx_cfg;
22627 + int interface = INTERFACE(priv->port);
22628 + int index = INDEX(priv->port);
22629 +
22630 + memcpy(dev->dev_addr, addr + 2, 6);
22631 +
22632 + if ((interface < 2)
22633 + && (cvmx_helper_interface_get_mode(interface) !=
22634 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
22635 + int i;
22636 + uint8_t *ptr = addr;
22637 + uint64_t mac = 0;
22638 + for (i = 0; i < 6; i++)
22639 + mac = (mac << 8) | (uint64_t) (ptr[i + 2]);
22640 +
22641 + gmx_cfg.u64 =
22642 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
22643 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22644 + gmx_cfg.u64 & ~1ull);
22645 +
22646 + cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
22647 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
22648 + ptr[2]);
22649 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
22650 + ptr[3]);
22651 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
22652 + ptr[4]);
22653 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
22654 + ptr[5]);
22655 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
22656 + ptr[6]);
22657 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
22658 + ptr[7]);
22659 + cvm_oct_common_set_multicast_list(dev);
22660 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
22661 + gmx_cfg.u64);
22662 + }
22663 + return 0;
22664 +}
22665 +
22666 +/**
22667 + * Change the link MTU. Unimplemented
22668 + *
22669 + * @dev: Device to change
22670 + * @new_mtu: The new MTU
22671 + *
22672 + * Returns Zero on success
22673 + */
22674 +static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
22675 +{
22676 + struct octeon_ethernet *priv = netdev_priv(dev);
22677 + int interface = INTERFACE(priv->port);
22678 + int index = INDEX(priv->port);
22679 +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
22680 + int vlan_bytes = 4;
22681 +#else
22682 + int vlan_bytes = 0;
22683 +#endif
22684 +
22685 + /*
22686 + * Limit the MTU to make sure the ethernet packets are between
22687 + * 64 bytes and 65535 bytes.
22688 + */
22689 + if ((new_mtu + 14 + 4 + vlan_bytes < 64)
22690 + || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
22691 + pr_err("MTU must be between %d and %d.\n",
22692 + 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes);
22693 + return -EINVAL;
22694 + }
22695 + dev->mtu = new_mtu;
22696 +
22697 + if ((interface < 2)
22698 + && (cvmx_helper_interface_get_mode(interface) !=
22699 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
22700 + /* Add ethernet header and FCS, and VLAN if configured. */
22701 + int max_packet = new_mtu + 14 + 4 + vlan_bytes;
22702 +
22703 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
22704 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
22705 + /* Signal errors on packets larger than the MTU */
22706 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface),
22707 + max_packet);
22708 + } else {
22709 + /*
22710 + * Set the hardware to truncate packets larger
22711 + * than the MTU and smaller the 64 bytes.
22712 + */
22713 + union cvmx_pip_frm_len_chkx frm_len_chk;
22714 + frm_len_chk.u64 = 0;
22715 + frm_len_chk.s.minlen = 64;
22716 + frm_len_chk.s.maxlen = max_packet;
22717 + cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
22718 + frm_len_chk.u64);
22719 + }
22720 + /*
22721 + * Set the hardware to truncate packets larger than
22722 + * the MTU. The jabber register must be set to a
22723 + * multiple of 8 bytes, so round up.
22724 + */
22725 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
22726 + (max_packet + 7) & ~7u);
22727 + }
22728 + return 0;
22729 +}
22730 +
22731 +/**
22732 + * Per network device initialization
22733 + *
22734 + * @dev: Device to initialize
22735 + * Returns Zero on success
22736 + */
22737 +int cvm_oct_common_init(struct net_device *dev)
22738 +{
22739 + static int count;
22740 + char mac[8] = { 0x00, 0x00,
22741 + octeon_bootinfo->mac_addr_base[0],
22742 + octeon_bootinfo->mac_addr_base[1],
22743 + octeon_bootinfo->mac_addr_base[2],
22744 + octeon_bootinfo->mac_addr_base[3],
22745 + octeon_bootinfo->mac_addr_base[4],
22746 + octeon_bootinfo->mac_addr_base[5] + count
22747 + };
22748 + struct octeon_ethernet *priv = netdev_priv(dev);
22749 +
22750 + /*
22751 + * Force the interface to use the POW send if always_use_pow
22752 + * was specified or it is in the pow send list.
22753 + */
22754 + if ((pow_send_group != -1)
22755 + && (always_use_pow || strstr(pow_send_list, dev->name)))
22756 + priv->queue = -1;
22757 +
22758 + if (priv->queue != -1) {
22759 + dev->hard_start_xmit = cvm_oct_xmit;
22760 + if (USE_HW_TCPUDP_CHECKSUM)
22761 + dev->features |= NETIF_F_IP_CSUM;
22762 + } else
22763 + dev->hard_start_xmit = cvm_oct_xmit_pow;
22764 + count++;
22765 +
22766 + dev->get_stats = cvm_oct_common_get_stats;
22767 + dev->set_mac_address = cvm_oct_common_set_mac_address;
22768 + dev->set_multicast_list = cvm_oct_common_set_multicast_list;
22769 + dev->change_mtu = cvm_oct_common_change_mtu;
22770 + dev->do_ioctl = cvm_oct_ioctl;
22771 + /* We do our own locking, Linux doesn't need to */
22772 + dev->features |= NETIF_F_LLTX;
22773 + SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
22774 +#ifdef CONFIG_NET_POLL_CONTROLLER
22775 + dev->poll_controller = cvm_oct_poll_controller;
22776 +#endif
22777 +
22778 + cvm_oct_mdio_setup_device(dev);
22779 + dev->set_mac_address(dev, mac);
22780 + dev->change_mtu(dev, dev->mtu);
22781 +
22782 + /*
22783 + * Zero out stats for port so we won't mistakenly show
22784 + * counters from the bootloader.
22785 + */
22786 + memset(dev->get_stats(dev), 0, sizeof(struct net_device_stats));
22787 +
22788 + return 0;
22789 +}
22790 +
22791 +void cvm_oct_common_uninit(struct net_device *dev)
22792 +{
22793 + /* Currently nothing to do */
22794 +}
22795 diff --git a/drivers/staging/octeon/ethernet-common.h b/drivers/staging/octeon/ethernet-common.h
22796 new file mode 100644
22797 index 0000000..2bd9cd7
22798 --- /dev/null
22799 +++ b/drivers/staging/octeon/ethernet-common.h
22800 @@ -0,0 +1,29 @@
22801 +/*********************************************************************
22802 + * Author: Cavium Networks
22803 + *
22804 + * Contact: support@caviumnetworks.com
22805 + * This file is part of the OCTEON SDK
22806 + *
22807 + * Copyright (c) 2003-2007 Cavium Networks
22808 + *
22809 + * This file is free software; you can redistribute it and/or modify
22810 + * it under the terms of the GNU General Public License, Version 2, as
22811 + * published by the Free Software Foundation.
22812 + *
22813 + * This file is distributed in the hope that it will be useful, but
22814 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22815 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22816 + * NONINFRINGEMENT. See the GNU General Public License for more
22817 + * details.
22818 + *
22819 + * You should have received a copy of the GNU General Public License
22820 + * along with this file; if not, write to the Free Software
22821 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22822 + * or visit http://www.gnu.org/licenses/.
22823 + *
22824 + * This file may also be available under a different license from Cavium.
22825 + * Contact Cavium Networks for more information
22826 +*********************************************************************/
22827 +
22828 +int cvm_oct_common_init(struct net_device *dev);
22829 +void cvm_oct_common_uninit(struct net_device *dev);
22830 diff --git a/drivers/staging/octeon/ethernet-defines.h b/drivers/staging/octeon/ethernet-defines.h
22831 new file mode 100644
22832 index 0000000..8f7374e
22833 --- /dev/null
22834 +++ b/drivers/staging/octeon/ethernet-defines.h
22835 @@ -0,0 +1,134 @@
22836 +/**********************************************************************
22837 + * Author: Cavium Networks
22838 + *
22839 + * Contact: support@caviumnetworks.com
22840 + * This file is part of the OCTEON SDK
22841 + *
22842 + * Copyright (c) 2003-2007 Cavium Networks
22843 + *
22844 + * This file is free software; you can redistribute it and/or modify
22845 + * it under the terms of the GNU General Public License, Version 2, as
22846 + * published by the Free Software Foundation.
22847 + *
22848 + * This file is distributed in the hope that it will be useful, but
22849 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22850 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22851 + * NONINFRINGEMENT. See the GNU General Public License for more
22852 + * details.
22853 + *
22854 + * You should have received a copy of the GNU General Public License
22855 + * along with this file; if not, write to the Free Software
22856 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22857 + * or visit http://www.gnu.org/licenses/.
22858 + *
22859 + * This file may also be available under a different license from Cavium.
22860 + * Contact Cavium Networks for more information
22861 +**********************************************************************/
22862 +
22863 +/*
22864 + * A few defines are used to control the operation of this driver:
22865 + * CONFIG_CAVIUM_RESERVE32
22866 + * This kernel config options controls the amount of memory configured
22867 + * in a wired TLB entry for all processes to share. If this is set, the
22868 + * driver will use this memory instead of kernel memory for pools. This
22869 + * allows 32bit userspace application to access the buffers, but also
22870 + * requires all received packets to be copied.
22871 + * CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
22872 + * This kernel config option allows the user to control the number of
22873 + * packet and work queue buffers allocated by the driver. If this is zero,
22874 + * the driver uses the default from below.
22875 + * USE_SKBUFFS_IN_HW
22876 + * Tells the driver to populate the packet buffers with kernel skbuffs.
22877 + * This allows the driver to receive packets without copying them. It also
22878 + * means that 32bit userspace can't access the packet buffers.
22879 + * USE_32BIT_SHARED
22880 + * This define tells the driver to allocate memory for buffers from the
22881 + * 32bit sahred region instead of the kernel memory space.
22882 + * USE_HW_TCPUDP_CHECKSUM
22883 + * Controls if the Octeon TCP/UDP checksum engine is used for packet
22884 + * output. If this is zero, the kernel will perform the checksum in
22885 + * software.
22886 + * USE_MULTICORE_RECEIVE
22887 + * Process receive interrupts on multiple cores. This spreads the network
22888 + * load across the first 8 processors. If ths is zero, only one core
22889 + * processes incomming packets.
22890 + * USE_ASYNC_IOBDMA
22891 + * Use asynchronous IO access to hardware. This uses Octeon's asynchronous
22892 + * IOBDMAs to issue IO accesses without stalling. Set this to zero
22893 + * to disable this. Note that IOBDMAs require CVMSEG.
22894 + * REUSE_SKBUFFS_WITHOUT_FREE
22895 + * Allows the TX path to free an skbuff into the FPA hardware pool. This
22896 + * can significantly improve performance for forwarding and bridging, but
22897 + * may be somewhat dangerous. Checks are made, but if any buffer is reused
22898 + * without the proper Linux cleanup, the networking stack may have very
22899 + * bizarre bugs.
22900 + */
22901 +#ifndef __ETHERNET_DEFINES_H__
22902 +#define __ETHERNET_DEFINES_H__
22903 +
22904 +#include "cvmx-config.h"
22905 +
22906 +
22907 +#define OCTEON_ETHERNET_VERSION "1.9"
22908 +
22909 +#ifndef CONFIG_CAVIUM_RESERVE32
22910 +#define CONFIG_CAVIUM_RESERVE32 0
22911 +#endif
22912 +
22913 +#if CONFIG_CAVIUM_RESERVE32
22914 +#define USE_32BIT_SHARED 1
22915 +#define USE_SKBUFFS_IN_HW 0
22916 +#define REUSE_SKBUFFS_WITHOUT_FREE 0
22917 +#else
22918 +#define USE_32BIT_SHARED 0
22919 +#define USE_SKBUFFS_IN_HW 1
22920 +#ifdef CONFIG_NETFILTER
22921 +#define REUSE_SKBUFFS_WITHOUT_FREE 0
22922 +#else
22923 +#define REUSE_SKBUFFS_WITHOUT_FREE 1
22924 +#endif
22925 +#endif
22926 +
22927 +/* Max interrupts per second per core */
22928 +#define INTERRUPT_LIMIT 10000
22929 +
22930 +/* Don't limit the number of interrupts */
22931 +/*#define INTERRUPT_LIMIT 0 */
22932 +#define USE_HW_TCPUDP_CHECKSUM 1
22933 +
22934 +#define USE_MULTICORE_RECEIVE 1
22935 +
22936 +/* Enable Random Early Dropping under load */
22937 +#define USE_RED 1
22938 +#define USE_ASYNC_IOBDMA (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0)
22939 +
22940 +/*
22941 + * Allow SW based preamble removal at 10Mbps to workaround PHYs giving
22942 + * us bad preambles.
22943 + */
22944 +#define USE_10MBPS_PREAMBLE_WORKAROUND 1
22945 +/*
22946 + * Use this to have all FPA frees also tell the L2 not to write data
22947 + * to memory.
22948 + */
22949 +#define DONT_WRITEBACK(x) (x)
22950 +/* Use this to not have FPA frees control L2 */
22951 +/*#define DONT_WRITEBACK(x) 0 */
22952 +
22953 +/* Maximum number of packets to process per interrupt. */
22954 +#define MAX_RX_PACKETS 120
22955 +#define MAX_OUT_QUEUE_DEPTH 1000
22956 +
22957 +#ifndef CONFIG_SMP
22958 +#undef USE_MULTICORE_RECEIVE
22959 +#define USE_MULTICORE_RECEIVE 0
22960 +#endif
22961 +
22962 +#define IP_PROTOCOL_TCP 6
22963 +#define IP_PROTOCOL_UDP 0x11
22964 +
22965 +#define FAU_NUM_PACKET_BUFFERS_TO_FREE (CVMX_FAU_REG_END - sizeof(uint32_t))
22966 +#define TOTAL_NUMBER_OF_PORTS (CVMX_PIP_NUM_INPUT_PORTS+1)
22967 +
22968 +
22969 +#endif /* __ETHERNET_DEFINES_H__ */
22970 diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
22971 new file mode 100644
22972 index 0000000..93cab0a
22973 --- /dev/null
22974 +++ b/drivers/staging/octeon/ethernet-mdio.c
22975 @@ -0,0 +1,231 @@
22976 +/**********************************************************************
22977 + * Author: Cavium Networks
22978 + *
22979 + * Contact: support@caviumnetworks.com
22980 + * This file is part of the OCTEON SDK
22981 + *
22982 + * Copyright (c) 2003-2007 Cavium Networks
22983 + *
22984 + * This file is free software; you can redistribute it and/or modify
22985 + * it under the terms of the GNU General Public License, Version 2, as
22986 + * published by the Free Software Foundation.
22987 + *
22988 + * This file is distributed in the hope that it will be useful, but
22989 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
22990 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
22991 + * NONINFRINGEMENT. See the GNU General Public License for more
22992 + * details.
22993 + *
22994 + * You should have received a copy of the GNU General Public License
22995 + * along with this file; if not, write to the Free Software
22996 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22997 + * or visit http://www.gnu.org/licenses/.
22998 + *
22999 + * This file may also be available under a different license from Cavium.
23000 + * Contact Cavium Networks for more information
23001 +**********************************************************************/
23002 +#include <linux/kernel.h>
23003 +#include <linux/ethtool.h>
23004 +#include <linux/mii.h>
23005 +#include <net/dst.h>
23006 +
23007 +#include <asm/octeon/octeon.h>
23008 +
23009 +#include "ethernet-defines.h"
23010 +#include "octeon-ethernet.h"
23011 +#include "ethernet-mdio.h"
23012 +
23013 +#include "cvmx-helper-board.h"
23014 +
23015 +#include "cvmx-smix-defs.h"
23016 +
23017 +DECLARE_MUTEX(mdio_sem);
23018 +
23019 +/**
23020 + * Perform an MII read. Called by the generic MII routines
23021 + *
23022 + * @dev: Device to perform read for
23023 + * @phy_id: The MII phy id
23024 + * @location: Register location to read
23025 + * Returns Result from the read or zero on failure
23026 + */
23027 +static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location)
23028 +{
23029 + union cvmx_smix_cmd smi_cmd;
23030 + union cvmx_smix_rd_dat smi_rd;
23031 +
23032 + smi_cmd.u64 = 0;
23033 + smi_cmd.s.phy_op = 1;
23034 + smi_cmd.s.phy_adr = phy_id;
23035 + smi_cmd.s.reg_adr = location;
23036 + cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
23037 +
23038 + do {
23039 + if (!in_interrupt())
23040 + yield();
23041 + smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0));
23042 + } while (smi_rd.s.pending);
23043 +
23044 + if (smi_rd.s.val)
23045 + return smi_rd.s.dat;
23046 + else
23047 + return 0;
23048 +}
23049 +
23050 +static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id,
23051 + int location)
23052 +{
23053 + return 0xffff;
23054 +}
23055 +
23056 +/**
23057 + * Perform an MII write. Called by the generic MII routines
23058 + *
23059 + * @dev: Device to perform write for
23060 + * @phy_id: The MII phy id
23061 + * @location: Register location to write
23062 + * @val: Value to write
23063 + */
23064 +static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location,
23065 + int val)
23066 +{
23067 + union cvmx_smix_cmd smi_cmd;
23068 + union cvmx_smix_wr_dat smi_wr;
23069 +
23070 + smi_wr.u64 = 0;
23071 + smi_wr.s.dat = val;
23072 + cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64);
23073 +
23074 + smi_cmd.u64 = 0;
23075 + smi_cmd.s.phy_op = 0;
23076 + smi_cmd.s.phy_adr = phy_id;
23077 + smi_cmd.s.reg_adr = location;
23078 + cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
23079 +
23080 + do {
23081 + if (!in_interrupt())
23082 + yield();
23083 + smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0));
23084 + } while (smi_wr.s.pending);
23085 +}
23086 +
23087 +static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id,
23088 + int location, int val)
23089 +{
23090 +}
23091 +
23092 +static void cvm_oct_get_drvinfo(struct net_device *dev,
23093 + struct ethtool_drvinfo *info)
23094 +{
23095 + strcpy(info->driver, "cavium-ethernet");
23096 + strcpy(info->version, OCTEON_ETHERNET_VERSION);
23097 + strcpy(info->bus_info, "Builtin");
23098 +}
23099 +
23100 +static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
23101 +{
23102 + struct octeon_ethernet *priv = netdev_priv(dev);
23103 + int ret;
23104 +
23105 + down(&mdio_sem);
23106 + ret = mii_ethtool_gset(&priv->mii_info, cmd);
23107 + up(&mdio_sem);
23108 +
23109 + return ret;
23110 +}
23111 +
23112 +static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
23113 +{
23114 + struct octeon_ethernet *priv = netdev_priv(dev);
23115 + int ret;
23116 +
23117 + down(&mdio_sem);
23118 + ret = mii_ethtool_sset(&priv->mii_info, cmd);
23119 + up(&mdio_sem);
23120 +
23121 + return ret;
23122 +}
23123 +
23124 +static int cvm_oct_nway_reset(struct net_device *dev)
23125 +{
23126 + struct octeon_ethernet *priv = netdev_priv(dev);
23127 + int ret;
23128 +
23129 + down(&mdio_sem);
23130 + ret = mii_nway_restart(&priv->mii_info);
23131 + up(&mdio_sem);
23132 +
23133 + return ret;
23134 +}
23135 +
23136 +static u32 cvm_oct_get_link(struct net_device *dev)
23137 +{
23138 + struct octeon_ethernet *priv = netdev_priv(dev);
23139 + u32 ret;
23140 +
23141 + down(&mdio_sem);
23142 + ret = mii_link_ok(&priv->mii_info);
23143 + up(&mdio_sem);
23144 +
23145 + return ret;
23146 +}
23147 +
23148 +struct ethtool_ops cvm_oct_ethtool_ops = {
23149 + .get_drvinfo = cvm_oct_get_drvinfo,
23150 + .get_settings = cvm_oct_get_settings,
23151 + .set_settings = cvm_oct_set_settings,
23152 + .nway_reset = cvm_oct_nway_reset,
23153 + .get_link = cvm_oct_get_link,
23154 + .get_sg = ethtool_op_get_sg,
23155 + .get_tx_csum = ethtool_op_get_tx_csum,
23156 +};
23157 +
23158 +/**
23159 + * IOCTL support for PHY control
23160 + *
23161 + * @dev: Device to change
23162 + * @rq: the request
23163 + * @cmd: the command
23164 + * Returns Zero on success
23165 + */
23166 +int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
23167 +{
23168 + struct octeon_ethernet *priv = netdev_priv(dev);
23169 + struct mii_ioctl_data *data = if_mii(rq);
23170 + unsigned int duplex_chg;
23171 + int ret;
23172 +
23173 + down(&mdio_sem);
23174 + ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg);
23175 + up(&mdio_sem);
23176 +
23177 + return ret;
23178 +}
23179 +
23180 +/**
23181 + * Setup the MDIO device structures
23182 + *
23183 + * @dev: Device to setup
23184 + *
23185 + * Returns Zero on success, negative on failure
23186 + */
23187 +int cvm_oct_mdio_setup_device(struct net_device *dev)
23188 +{
23189 + struct octeon_ethernet *priv = netdev_priv(dev);
23190 + int phy_id = cvmx_helper_board_get_mii_address(priv->port);
23191 + if (phy_id != -1) {
23192 + priv->mii_info.dev = dev;
23193 + priv->mii_info.phy_id = phy_id;
23194 + priv->mii_info.phy_id_mask = 0xff;
23195 + priv->mii_info.supports_gmii = 1;
23196 + priv->mii_info.reg_num_mask = 0x1f;
23197 + priv->mii_info.mdio_read = cvm_oct_mdio_read;
23198 + priv->mii_info.mdio_write = cvm_oct_mdio_write;
23199 + } else {
23200 + /* Supply dummy MDIO routines so the kernel won't crash
23201 + if the user tries to read them */
23202 + priv->mii_info.mdio_read = cvm_oct_mdio_dummy_read;
23203 + priv->mii_info.mdio_write = cvm_oct_mdio_dummy_write;
23204 + }
23205 + return 0;
23206 +}
23207 diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h
23208 new file mode 100644
23209 index 0000000..6314141
23210 --- /dev/null
23211 +++ b/drivers/staging/octeon/ethernet-mdio.h
23212 @@ -0,0 +1,46 @@
23213 +/*********************************************************************
23214 + * Author: Cavium Networks
23215 + *
23216 + * Contact: support@caviumnetworks.com
23217 + * This file is part of the OCTEON SDK
23218 + *
23219 + * Copyright (c) 2003-2007 Cavium Networks
23220 + *
23221 + * This file is free software; you can redistribute it and/or modify
23222 + * it under the terms of the GNU General Public License, Version 2, as
23223 + * published by the Free Software Foundation.
23224 + *
23225 + * This file is distributed in the hope that it will be useful, but
23226 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23227 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23228 + * NONINFRINGEMENT. See the GNU General Public License for more
23229 + * details.
23230 + *
23231 + * You should have received a copy of the GNU General Public License
23232 + * along with this file; if not, write to the Free Software
23233 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23234 + * or visit http://www.gnu.org/licenses/.
23235 + *
23236 + * This file may also be available under a different license from Cavium.
23237 + * Contact Cavium Networks for more information
23238 +*********************************************************************/
23239 +#include <linux/module.h>
23240 +#include <linux/kernel.h>
23241 +#include <linux/netdevice.h>
23242 +#include <linux/init.h>
23243 +#include <linux/etherdevice.h>
23244 +#include <linux/ip.h>
23245 +#include <linux/string.h>
23246 +#include <linux/ethtool.h>
23247 +#include <linux/mii.h>
23248 +#include <linux/seq_file.h>
23249 +#include <linux/proc_fs.h>
23250 +#include <net/dst.h>
23251 +#ifdef CONFIG_XFRM
23252 +#include <linux/xfrm.h>
23253 +#include <net/xfrm.h>
23254 +#endif /* CONFIG_XFRM */
23255 +
23256 +extern struct ethtool_ops cvm_oct_ethtool_ops;
23257 +int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
23258 +int cvm_oct_mdio_setup_device(struct net_device *dev);
23259 diff --git a/drivers/staging/octeon/ethernet-mem.c b/drivers/staging/octeon/ethernet-mem.c
23260 new file mode 100644
23261 index 0000000..b595903
23262 --- /dev/null
23263 +++ b/drivers/staging/octeon/ethernet-mem.c
23264 @@ -0,0 +1,198 @@
23265 +/**********************************************************************
23266 + * Author: Cavium Networks
23267 + *
23268 + * Contact: support@caviumnetworks.com
23269 + * This file is part of the OCTEON SDK
23270 + *
23271 + * Copyright (c) 2003-2007 Cavium Networks
23272 + *
23273 + * This file is free software; you can redistribute it and/or modify
23274 + * it under the terms of the GNU General Public License, Version 2, as
23275 + * published by the Free Software Foundation.
23276 + *
23277 + * This file is distributed in the hope that it will be useful, but
23278 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23279 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23280 + * NONINFRINGEMENT. See the GNU General Public License for more
23281 + * details.
23282 + *
23283 + * You should have received a copy of the GNU General Public License
23284 + * along with this file; if not, write to the Free Software
23285 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23286 + * or visit http://www.gnu.org/licenses/.
23287 + *
23288 + * This file may also be available under a different license from Cavium.
23289 + * Contact Cavium Networks for more information
23290 +**********************************************************************/
23291 +#include <linux/kernel.h>
23292 +#include <linux/netdevice.h>
23293 +#include <linux/mii.h>
23294 +#include <net/dst.h>
23295 +
23296 +#include <asm/octeon/octeon.h>
23297 +
23298 +#include "ethernet-defines.h"
23299 +
23300 +#include "cvmx-fpa.h"
23301 +
23302 +/**
23303 + * Fill the supplied hardware pool with skbuffs
23304 + *
23305 + * @pool: Pool to allocate an skbuff for
23306 + * @size: Size of the buffer needed for the pool
23307 + * @elements: Number of buffers to allocate
23308 + */
23309 +static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements)
23310 +{
23311 + int freed = elements;
23312 + while (freed) {
23313 +
23314 + struct sk_buff *skb = dev_alloc_skb(size + 128);
23315 + if (unlikely(skb == NULL)) {
23316 + pr_warning
23317 + ("Failed to allocate skb for hardware pool %d\n",
23318 + pool);
23319 + break;
23320 + }
23321 +
23322 + skb_reserve(skb, 128 - (((unsigned long)skb->data) & 0x7f));
23323 + *(struct sk_buff **)(skb->data - sizeof(void *)) = skb;
23324 + cvmx_fpa_free(skb->data, pool, DONT_WRITEBACK(size / 128));
23325 + freed--;
23326 + }
23327 + return elements - freed;
23328 +}
23329 +
23330 +/**
23331 + * Free the supplied hardware pool of skbuffs
23332 + *
23333 + * @pool: Pool to allocate an skbuff for
23334 + * @size: Size of the buffer needed for the pool
23335 + * @elements: Number of buffers to allocate
23336 + */
23337 +static void cvm_oct_free_hw_skbuff(int pool, int size, int elements)
23338 +{
23339 + char *memory;
23340 +
23341 + do {
23342 + memory = cvmx_fpa_alloc(pool);
23343 + if (memory) {
23344 + struct sk_buff *skb =
23345 + *(struct sk_buff **)(memory - sizeof(void *));
23346 + elements--;
23347 + dev_kfree_skb(skb);
23348 + }
23349 + } while (memory);
23350 +
23351 + if (elements < 0)
23352 + pr_warning("Freeing of pool %u had too many skbuffs (%d)\n",
23353 + pool, elements);
23354 + else if (elements > 0)
23355 + pr_warning("Freeing of pool %u is missing %d skbuffs\n",
23356 + pool, elements);
23357 +}
23358 +
23359 +/**
23360 + * This function fills a hardware pool with memory. Depending
23361 + * on the config defines, this memory might come from the
23362 + * kernel or global 32bit memory allocated with
23363 + * cvmx_bootmem_alloc.
23364 + *
23365 + * @pool: Pool to populate
23366 + * @size: Size of each buffer in the pool
23367 + * @elements: Number of buffers to allocate
23368 + */
23369 +static int cvm_oct_fill_hw_memory(int pool, int size, int elements)
23370 +{
23371 + char *memory;
23372 + int freed = elements;
23373 +
23374 + if (USE_32BIT_SHARED) {
23375 + extern uint64_t octeon_reserve32_memory;
23376 +
23377 + memory =
23378 + cvmx_bootmem_alloc_range(elements * size, 128,
23379 + octeon_reserve32_memory,
23380 + octeon_reserve32_memory +
23381 + (CONFIG_CAVIUM_RESERVE32 << 20) -
23382 + 1);
23383 + if (memory == NULL)
23384 + panic("Unable to allocate %u bytes for FPA pool %d\n",
23385 + elements * size, pool);
23386 +
23387 + pr_notice("Memory range %p - %p reserved for "
23388 + "hardware\n", memory,
23389 + memory + elements * size - 1);
23390 +
23391 + while (freed) {
23392 + cvmx_fpa_free(memory, pool, 0);
23393 + memory += size;
23394 + freed--;
23395 + }
23396 + } else {
23397 + while (freed) {
23398 + /* We need to force alignment to 128 bytes here */
23399 + memory = kmalloc(size + 127, GFP_ATOMIC);
23400 + if (unlikely(memory == NULL)) {
23401 + pr_warning("Unable to allocate %u bytes for "
23402 + "FPA pool %d\n",
23403 + elements * size, pool);
23404 + break;
23405 + }
23406 + memory = (char *)(((unsigned long)memory + 127) & -128);
23407 + cvmx_fpa_free(memory, pool, 0);
23408 + freed--;
23409 + }
23410 + }
23411 + return elements - freed;
23412 +}
23413 +
23414 +/**
23415 + * Free memory previously allocated with cvm_oct_fill_hw_memory
23416 + *
23417 + * @pool: FPA pool to free
23418 + * @size: Size of each buffer in the pool
23419 + * @elements: Number of buffers that should be in the pool
23420 + */
23421 +static void cvm_oct_free_hw_memory(int pool, int size, int elements)
23422 +{
23423 + if (USE_32BIT_SHARED) {
23424 + pr_warning("Warning: 32 shared memory is not freeable\n");
23425 + } else {
23426 + char *memory;
23427 + do {
23428 + memory = cvmx_fpa_alloc(pool);
23429 + if (memory) {
23430 + elements--;
23431 + kfree(phys_to_virt(cvmx_ptr_to_phys(memory)));
23432 + }
23433 + } while (memory);
23434 +
23435 + if (elements < 0)
23436 + pr_warning("Freeing of pool %u had too many "
23437 + "buffers (%d)\n",
23438 + pool, elements);
23439 + else if (elements > 0)
23440 + pr_warning("Warning: Freeing of pool %u is "
23441 + "missing %d buffers\n",
23442 + pool, elements);
23443 + }
23444 +}
23445 +
23446 +int cvm_oct_mem_fill_fpa(int pool, int size, int elements)
23447 +{
23448 + int freed;
23449 + if (USE_SKBUFFS_IN_HW)
23450 + freed = cvm_oct_fill_hw_skbuff(pool, size, elements);
23451 + else
23452 + freed = cvm_oct_fill_hw_memory(pool, size, elements);
23453 + return freed;
23454 +}
23455 +
23456 +void cvm_oct_mem_empty_fpa(int pool, int size, int elements)
23457 +{
23458 + if (USE_SKBUFFS_IN_HW)
23459 + cvm_oct_free_hw_skbuff(pool, size, elements);
23460 + else
23461 + cvm_oct_free_hw_memory(pool, size, elements);
23462 +}
23463 diff --git a/drivers/staging/octeon/ethernet-mem.h b/drivers/staging/octeon/ethernet-mem.h
23464 new file mode 100644
23465 index 0000000..713f2ed
23466 --- /dev/null
23467 +++ b/drivers/staging/octeon/ethernet-mem.h
23468 @@ -0,0 +1,29 @@
23469 +/*********************************************************************
23470 + * Author: Cavium Networks
23471 + *
23472 + * Contact: support@caviumnetworks.com
23473 + * This file is part of the OCTEON SDK
23474 + *
23475 + * Copyright (c) 2003-2007 Cavium Networks
23476 + *
23477 + * This file is free software; you can redistribute it and/or modify
23478 + * it under the terms of the GNU General Public License, Version 2, as
23479 + * published by the Free Software Foundation.
23480 + *
23481 + * This file is distributed in the hope that it will be useful, but
23482 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23483 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23484 + * NONINFRINGEMENT. See the GNU General Public License for more
23485 + * details.
23486 + *
23487 + * You should have received a copy of the GNU General Public License
23488 + * along with this file; if not, write to the Free Software
23489 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23490 + * or visit http://www.gnu.org/licenses/.
23491 + *
23492 + * This file may also be available under a different license from Cavium.
23493 + * Contact Cavium Networks for more information
23494 +********************************************************************/
23495 +
23496 +int cvm_oct_mem_fill_fpa(int pool, int size, int elements);
23497 +void cvm_oct_mem_empty_fpa(int pool, int size, int elements);
23498 diff --git a/drivers/staging/octeon/ethernet-proc.c b/drivers/staging/octeon/ethernet-proc.c
23499 new file mode 100644
23500 index 0000000..8fa88fc
23501 --- /dev/null
23502 +++ b/drivers/staging/octeon/ethernet-proc.c
23503 @@ -0,0 +1,256 @@
23504 +/**********************************************************************
23505 + * Author: Cavium Networks
23506 + *
23507 + * Contact: support@caviumnetworks.com
23508 + * This file is part of the OCTEON SDK
23509 + *
23510 + * Copyright (c) 2003-2007 Cavium Networks
23511 + *
23512 + * This file is free software; you can redistribute it and/or modify
23513 + * it under the terms of the GNU General Public License, Version 2, as
23514 + * published by the Free Software Foundation.
23515 + *
23516 + * This file is distributed in the hope that it will be useful, but
23517 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23518 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23519 + * NONINFRINGEMENT. See the GNU General Public License for more
23520 + * details.
23521 + *
23522 + * You should have received a copy of the GNU General Public License
23523 + * along with this file; if not, write to the Free Software
23524 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23525 + * or visit http://www.gnu.org/licenses/.
23526 + *
23527 + * This file may also be available under a different license from Cavium.
23528 + * Contact Cavium Networks for more information
23529 +**********************************************************************/
23530 +#include <linux/kernel.h>
23531 +#include <linux/mii.h>
23532 +#include <linux/seq_file.h>
23533 +#include <linux/proc_fs.h>
23534 +#include <net/dst.h>
23535 +
23536 +#include <asm/octeon/octeon.h>
23537 +
23538 +#include "octeon-ethernet.h"
23539 +#include "ethernet-defines.h"
23540 +
23541 +#include "cvmx-helper.h"
23542 +#include "cvmx-pip.h"
23543 +
23544 +static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev,
23545 + int phy_id, int offset)
23546 +{
23547 + struct octeon_ethernet *priv = netdev_priv(dev);
23548 +
23549 + priv->mii_info.mdio_write(dev, phy_id, 0x1d, 0xcc00 | offset);
23550 + return ((uint64_t) priv->mii_info.
23551 + mdio_read(dev, phy_id,
23552 + 0x1e) << 16) | (uint64_t) priv->mii_info.
23553 + mdio_read(dev, phy_id, 0x1f);
23554 +}
23555 +
23556 +static int cvm_oct_stats_switch_show(struct seq_file *m, void *v)
23557 +{
23558 + static const int ports[] = { 0, 1, 2, 3, 9, -1 };
23559 + struct net_device *dev = cvm_oct_device[0];
23560 + int index = 0;
23561 +
23562 + while (ports[index] != -1) {
23563 +
23564 + /* Latch port */
23565 + struct octeon_ethernet *priv = netdev_priv(dev);
23566 +
23567 + priv->mii_info.mdio_write(dev, 0x1b, 0x1d,
23568 + 0xdc00 | ports[index]);
23569 + seq_printf(m, "\nSwitch Port %d\n", ports[index]);
23570 + seq_printf(m, "InGoodOctets: %12llu\t"
23571 + "OutOctets: %12llu\t"
23572 + "64 Octets: %12llu\n",
23573 + cvm_oct_stats_read_switch(dev, 0x1b,
23574 + 0x00) |
23575 + (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32),
23576 + cvm_oct_stats_read_switch(dev, 0x1b,
23577 + 0x0E) |
23578 + (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32),
23579 + cvm_oct_stats_read_switch(dev, 0x1b, 0x08));
23580 +
23581 + seq_printf(m, "InBadOctets: %12llu\t"
23582 + "OutUnicast: %12llu\t"
23583 + "65-127 Octets: %12llu\n",
23584 + cvm_oct_stats_read_switch(dev, 0x1b, 0x02),
23585 + cvm_oct_stats_read_switch(dev, 0x1b, 0x10),
23586 + cvm_oct_stats_read_switch(dev, 0x1b, 0x09));
23587 +
23588 + seq_printf(m, "InUnicast: %12llu\t"
23589 + "OutBroadcasts: %12llu\t"
23590 + "128-255 Octets: %12llu\n",
23591 + cvm_oct_stats_read_switch(dev, 0x1b, 0x04),
23592 + cvm_oct_stats_read_switch(dev, 0x1b, 0x13),
23593 + cvm_oct_stats_read_switch(dev, 0x1b, 0x0A));
23594 +
23595 + seq_printf(m, "InBroadcasts: %12llu\t"
23596 + "OutMulticasts: %12llu\t"
23597 + "256-511 Octets: %12llu\n",
23598 + cvm_oct_stats_read_switch(dev, 0x1b, 0x06),
23599 + cvm_oct_stats_read_switch(dev, 0x1b, 0x12),
23600 + cvm_oct_stats_read_switch(dev, 0x1b, 0x0B));
23601 +
23602 + seq_printf(m, "InMulticasts: %12llu\t"
23603 + "OutPause: %12llu\t"
23604 + "512-1023 Octets:%12llu\n",
23605 + cvm_oct_stats_read_switch(dev, 0x1b, 0x07),
23606 + cvm_oct_stats_read_switch(dev, 0x1b, 0x15),
23607 + cvm_oct_stats_read_switch(dev, 0x1b, 0x0C));
23608 +
23609 + seq_printf(m, "InPause: %12llu\t"
23610 + "Excessive: %12llu\t"
23611 + "1024-Max Octets:%12llu\n",
23612 + cvm_oct_stats_read_switch(dev, 0x1b, 0x16),
23613 + cvm_oct_stats_read_switch(dev, 0x1b, 0x11),
23614 + cvm_oct_stats_read_switch(dev, 0x1b, 0x0D));
23615 +
23616 + seq_printf(m, "InUndersize: %12llu\t"
23617 + "Collisions: %12llu\n",
23618 + cvm_oct_stats_read_switch(dev, 0x1b, 0x18),
23619 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1E));
23620 +
23621 + seq_printf(m, "InFragments: %12llu\t"
23622 + "Deferred: %12llu\n",
23623 + cvm_oct_stats_read_switch(dev, 0x1b, 0x19),
23624 + cvm_oct_stats_read_switch(dev, 0x1b, 0x05));
23625 +
23626 + seq_printf(m, "InOversize: %12llu\t"
23627 + "Single: %12llu\n",
23628 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1A),
23629 + cvm_oct_stats_read_switch(dev, 0x1b, 0x14));
23630 +
23631 + seq_printf(m, "InJabber: %12llu\t"
23632 + "Multiple: %12llu\n",
23633 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1B),
23634 + cvm_oct_stats_read_switch(dev, 0x1b, 0x17));
23635 +
23636 + seq_printf(m, "In RxErr: %12llu\t"
23637 + "OutFCSErr: %12llu\n",
23638 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1C),
23639 + cvm_oct_stats_read_switch(dev, 0x1b, 0x03));
23640 +
23641 + seq_printf(m, "InFCSErr: %12llu\t"
23642 + "Late: %12llu\n",
23643 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1D),
23644 + cvm_oct_stats_read_switch(dev, 0x1b, 0x1F));
23645 + index++;
23646 + }
23647 + return 0;
23648 +}
23649 +
23650 +/**
23651 + * User is reading /proc/octeon_ethernet_stats
23652 + *
23653 + * @m:
23654 + * @v:
23655 + * Returns
23656 + */
23657 +static int cvm_oct_stats_show(struct seq_file *m, void *v)
23658 +{
23659 + struct octeon_ethernet *priv;
23660 + int port;
23661 +
23662 + for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
23663 +
23664 + if (cvm_oct_device[port]) {
23665 + priv = netdev_priv(cvm_oct_device[port]);
23666 +
23667 + seq_printf(m, "\nOcteon Port %d (%s)\n", port,
23668 + cvm_oct_device[port]->name);
23669 + seq_printf(m,
23670 + "rx_packets: %12lu\t"
23671 + "tx_packets: %12lu\n",
23672 + priv->stats.rx_packets,
23673 + priv->stats.tx_packets);
23674 + seq_printf(m,
23675 + "rx_bytes: %12lu\t"
23676 + "tx_bytes: %12lu\n",
23677 + priv->stats.rx_bytes, priv->stats.tx_bytes);
23678 + seq_printf(m,
23679 + "rx_errors: %12lu\t"
23680 + "tx_errors: %12lu\n",
23681 + priv->stats.rx_errors,
23682 + priv->stats.tx_errors);
23683 + seq_printf(m,
23684 + "rx_dropped: %12lu\t"
23685 + "tx_dropped: %12lu\n",
23686 + priv->stats.rx_dropped,
23687 + priv->stats.tx_dropped);
23688 + seq_printf(m,
23689 + "rx_length_errors: %12lu\t"
23690 + "tx_aborted_errors: %12lu\n",
23691 + priv->stats.rx_length_errors,
23692 + priv->stats.tx_aborted_errors);
23693 + seq_printf(m,
23694 + "rx_over_errors: %12lu\t"
23695 + "tx_carrier_errors: %12lu\n",
23696 + priv->stats.rx_over_errors,
23697 + priv->stats.tx_carrier_errors);
23698 + seq_printf(m,
23699 + "rx_crc_errors: %12lu\t"
23700 + "tx_fifo_errors: %12lu\n",
23701 + priv->stats.rx_crc_errors,
23702 + priv->stats.tx_fifo_errors);
23703 + seq_printf(m,
23704 + "rx_frame_errors: %12lu\t"
23705 + "tx_heartbeat_errors: %12lu\n",
23706 + priv->stats.rx_frame_errors,
23707 + priv->stats.tx_heartbeat_errors);
23708 + seq_printf(m,
23709 + "rx_fifo_errors: %12lu\t"
23710 + "tx_window_errors: %12lu\n",
23711 + priv->stats.rx_fifo_errors,
23712 + priv->stats.tx_window_errors);
23713 + seq_printf(m,
23714 + "rx_missed_errors: %12lu\t"
23715 + "multicast: %12lu\n",
23716 + priv->stats.rx_missed_errors,
23717 + priv->stats.multicast);
23718 + }
23719 + }
23720 +
23721 + if (cvm_oct_device[0]) {
23722 + priv = netdev_priv(cvm_oct_device[0]);
23723 + if (priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
23724 + cvm_oct_stats_switch_show(m, v);
23725 + }
23726 + return 0;
23727 +}
23728 +
23729 +/**
23730 + * /proc/octeon_ethernet_stats was openned. Use the single_open iterator
23731 + *
23732 + * @inode:
23733 + * @file:
23734 + * Returns
23735 + */
23736 +static int cvm_oct_stats_open(struct inode *inode, struct file *file)
23737 +{
23738 + return single_open(file, cvm_oct_stats_show, NULL);
23739 +}
23740 +
23741 +static const struct file_operations cvm_oct_stats_operations = {
23742 + .open = cvm_oct_stats_open,
23743 + .read = seq_read,
23744 + .llseek = seq_lseek,
23745 + .release = single_release,
23746 +};
23747 +
23748 +void cvm_oct_proc_initialize(void)
23749 +{
23750 + struct proc_dir_entry *entry =
23751 + create_proc_entry("octeon_ethernet_stats", 0, NULL);
23752 + if (entry)
23753 + entry->proc_fops = &cvm_oct_stats_operations;
23754 +}
23755 +
23756 +void cvm_oct_proc_shutdown(void)
23757 +{
23758 + remove_proc_entry("octeon_ethernet_stats", NULL);
23759 +}
23760 diff --git a/drivers/staging/octeon/ethernet-proc.h b/drivers/staging/octeon/ethernet-proc.h
23761 new file mode 100644
23762 index 0000000..82c7d9f
23763 --- /dev/null
23764 +++ b/drivers/staging/octeon/ethernet-proc.h
23765 @@ -0,0 +1,29 @@
23766 +/*********************************************************************
23767 + * Author: Cavium Networks
23768 + *
23769 + * Contact: support@caviumnetworks.com
23770 + * This file is part of the OCTEON SDK
23771 + *
23772 + * Copyright (c) 2003-2007 Cavium Networks
23773 + *
23774 + * This file is free software; you can redistribute it and/or modify
23775 + * it under the terms of the GNU General Public License, Version 2, as
23776 + * published by the Free Software Foundation.
23777 + *
23778 + * This file is distributed in the hope that it will be useful, but
23779 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23780 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23781 + * NONINFRINGEMENT. See the GNU General Public License for more
23782 + * details.
23783 + *
23784 + * You should have received a copy of the GNU General Public License
23785 + * along with this file; if not, write to the Free Software
23786 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23787 + * or visit http://www.gnu.org/licenses/.
23788 + *
23789 + * This file may also be available under a different license from Cavium.
23790 + * Contact Cavium Networks for more information
23791 +*********************************************************************/
23792 +
23793 +void cvm_oct_proc_initialize(void);
23794 +void cvm_oct_proc_shutdown(void);
23795 diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
23796 new file mode 100644
23797 index 0000000..8579f16
23798 --- /dev/null
23799 +++ b/drivers/staging/octeon/ethernet-rgmii.c
23800 @@ -0,0 +1,397 @@
23801 +/*********************************************************************
23802 + * Author: Cavium Networks
23803 + *
23804 + * Contact: support@caviumnetworks.com
23805 + * This file is part of the OCTEON SDK
23806 + *
23807 + * Copyright (c) 2003-2007 Cavium Networks
23808 + *
23809 + * This file is free software; you can redistribute it and/or modify
23810 + * it under the terms of the GNU General Public License, Version 2, as
23811 + * published by the Free Software Foundation.
23812 + *
23813 + * This file is distributed in the hope that it will be useful, but
23814 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
23815 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
23816 + * NONINFRINGEMENT. See the GNU General Public License for more
23817 + * details.
23818 + *
23819 + * You should have received a copy of the GNU General Public License
23820 + * along with this file; if not, write to the Free Software
23821 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23822 + * or visit http://www.gnu.org/licenses/.
23823 + *
23824 + * This file may also be available under a different license from Cavium.
23825 + * Contact Cavium Networks for more information
23826 +**********************************************************************/
23827 +#include <linux/kernel.h>
23828 +#include <linux/netdevice.h>
23829 +#include <linux/mii.h>
23830 +#include <net/dst.h>
23831 +
23832 +#include <asm/octeon/octeon.h>
23833 +
23834 +#include "ethernet-defines.h"
23835 +#include "octeon-ethernet.h"
23836 +#include "ethernet-common.h"
23837 +#include "ethernet-util.h"
23838 +
23839 +#include "cvmx-helper.h"
23840 +
23841 +#include <asm/octeon/cvmx-ipd-defs.h>
23842 +#include <asm/octeon/cvmx-npi-defs.h>
23843 +#include "cvmx-gmxx-defs.h"
23844 +
23845 +DEFINE_SPINLOCK(global_register_lock);
23846 +
23847 +static int number_rgmii_ports;
23848 +
23849 +static void cvm_oct_rgmii_poll(struct net_device *dev)
23850 +{
23851 + struct octeon_ethernet *priv = netdev_priv(dev);
23852 + unsigned long flags;
23853 + cvmx_helper_link_info_t link_info;
23854 +
23855 + /*
23856 + * Take the global register lock since we are going to touch
23857 + * registers that affect more than one port.
23858 + */
23859 + spin_lock_irqsave(&global_register_lock, flags);
23860 +
23861 + link_info = cvmx_helper_link_get(priv->port);
23862 + if (link_info.u64 == priv->link_info) {
23863 +
23864 + /*
23865 + * If the 10Mbps preamble workaround is supported and we're
23866 + * at 10Mbps we may need to do some special checking.
23867 + */
23868 + if (USE_10MBPS_PREAMBLE_WORKAROUND && (link_info.s.speed == 10)) {
23869 +
23870 + /*
23871 + * Read the GMXX_RXX_INT_REG[PCTERR] bit and
23872 + * see if we are getting preamble errors.
23873 + */
23874 + int interface = INTERFACE(priv->port);
23875 + int index = INDEX(priv->port);
23876 + union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
23877 + gmxx_rxx_int_reg.u64 =
23878 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
23879 + (index, interface));
23880 + if (gmxx_rxx_int_reg.s.pcterr) {
23881 +
23882 + /*
23883 + * We are getting preamble errors at
23884 + * 10Mbps. Most likely the PHY is
23885 + * giving us packets with mis aligned
23886 + * preambles. In order to get these
23887 + * packets we need to disable preamble
23888 + * checking and do it in software.
23889 + */
23890 + union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
23891 + union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
23892 +
23893 + /* Disable preamble checking */
23894 + gmxx_rxx_frm_ctl.u64 =
23895 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
23896 + (index, interface));
23897 + gmxx_rxx_frm_ctl.s.pre_chk = 0;
23898 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL
23899 + (index, interface),
23900 + gmxx_rxx_frm_ctl.u64);
23901 +
23902 + /* Disable FCS stripping */
23903 + ipd_sub_port_fcs.u64 =
23904 + cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
23905 + ipd_sub_port_fcs.s.port_bit &=
23906 + 0xffffffffull ^ (1ull << priv->port);
23907 + cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS,
23908 + ipd_sub_port_fcs.u64);
23909 +
23910 + /* Clear any error bits */
23911 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
23912 + (index, interface),
23913 + gmxx_rxx_int_reg.u64);
23914 + DEBUGPRINT("%s: Using 10Mbps with software "
23915 + "preamble removal\n",
23916 + dev->name);
23917 + }
23918 + }
23919 + spin_unlock_irqrestore(&global_register_lock, flags);
23920 + return;
23921 + }
23922 +
23923 + /* If the 10Mbps preamble workaround is allowed we need to on
23924 + preamble checking, FCS stripping, and clear error bits on
23925 + every speed change. If errors occur during 10Mbps operation
23926 + the above code will change this stuff */
23927 + if (USE_10MBPS_PREAMBLE_WORKAROUND) {
23928 +
23929 + union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
23930 + union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
23931 + union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
23932 + int interface = INTERFACE(priv->port);
23933 + int index = INDEX(priv->port);
23934 +
23935 + /* Enable preamble checking */
23936 + gmxx_rxx_frm_ctl.u64 =
23937 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
23938 + gmxx_rxx_frm_ctl.s.pre_chk = 1;
23939 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface),
23940 + gmxx_rxx_frm_ctl.u64);
23941 + /* Enable FCS stripping */
23942 + ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
23943 + ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port;
23944 + cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
23945 + /* Clear any error bits */
23946 + gmxx_rxx_int_reg.u64 =
23947 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, interface));
23948 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface),
23949 + gmxx_rxx_int_reg.u64);
23950 + }
23951 +
23952 + link_info = cvmx_helper_link_autoconf(priv->port);
23953 + priv->link_info = link_info.u64;
23954 + spin_unlock_irqrestore(&global_register_lock, flags);
23955 +
23956 + /* Tell Linux */
23957 + if (link_info.s.link_up) {
23958 +
23959 + if (!netif_carrier_ok(dev))
23960 + netif_carrier_on(dev);
23961 + if (priv->queue != -1)
23962 + DEBUGPRINT
23963 + ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
23964 + dev->name, link_info.s.speed,
23965 + (link_info.s.full_duplex) ? "Full" : "Half",
23966 + priv->port, priv->queue);
23967 + else
23968 + DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
23969 + dev->name, link_info.s.speed,
23970 + (link_info.s.full_duplex) ? "Full" : "Half",
23971 + priv->port);
23972 + } else {
23973 +
23974 + if (netif_carrier_ok(dev))
23975 + netif_carrier_off(dev);
23976 + DEBUGPRINT("%s: Link down\n", dev->name);
23977 + }
23978 +}
23979 +
23980 +static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id)
23981 +{
23982 + union cvmx_npi_rsl_int_blocks rsl_int_blocks;
23983 + int index;
23984 + irqreturn_t return_status = IRQ_NONE;
23985 +
23986 + rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
23987 +
23988 + /* Check and see if this interrupt was caused by the GMX0 block */
23989 + if (rsl_int_blocks.s.gmx0) {
23990 +
23991 + int interface = 0;
23992 + /* Loop through every port of this interface */
23993 + for (index = 0;
23994 + index < cvmx_helper_ports_on_interface(interface);
23995 + index++) {
23996 +
23997 + /* Read the GMX interrupt status bits */
23998 + union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
23999 + gmx_rx_int_reg.u64 =
24000 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
24001 + (index, interface));
24002 + gmx_rx_int_reg.u64 &=
24003 + cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
24004 + (index, interface));
24005 + /* Poll the port if inband status changed */
24006 + if (gmx_rx_int_reg.s.phy_dupx
24007 + || gmx_rx_int_reg.s.phy_link
24008 + || gmx_rx_int_reg.s.phy_spd) {
24009 +
24010 + struct net_device *dev =
24011 + cvm_oct_device[cvmx_helper_get_ipd_port
24012 + (interface, index)];
24013 + if (dev)
24014 + cvm_oct_rgmii_poll(dev);
24015 + gmx_rx_int_reg.u64 = 0;
24016 + gmx_rx_int_reg.s.phy_dupx = 1;
24017 + gmx_rx_int_reg.s.phy_link = 1;
24018 + gmx_rx_int_reg.s.phy_spd = 1;
24019 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
24020 + (index, interface),
24021 + gmx_rx_int_reg.u64);
24022 + return_status = IRQ_HANDLED;
24023 + }
24024 + }
24025 + }
24026 +
24027 + /* Check and see if this interrupt was caused by the GMX1 block */
24028 + if (rsl_int_blocks.s.gmx1) {
24029 +
24030 + int interface = 1;
24031 + /* Loop through every port of this interface */
24032 + for (index = 0;
24033 + index < cvmx_helper_ports_on_interface(interface);
24034 + index++) {
24035 +
24036 + /* Read the GMX interrupt status bits */
24037 + union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
24038 + gmx_rx_int_reg.u64 =
24039 + cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
24040 + (index, interface));
24041 + gmx_rx_int_reg.u64 &=
24042 + cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
24043 + (index, interface));
24044 + /* Poll the port if inband status changed */
24045 + if (gmx_rx_int_reg.s.phy_dupx
24046 + || gmx_rx_int_reg.s.phy_link
24047 + || gmx_rx_int_reg.s.phy_spd) {
24048 +
24049 + struct net_device *dev =
24050 + cvm_oct_device[cvmx_helper_get_ipd_port
24051 + (interface, index)];
24052 + if (dev)
24053 + cvm_oct_rgmii_poll(dev);
24054 + gmx_rx_int_reg.u64 = 0;
24055 + gmx_rx_int_reg.s.phy_dupx = 1;
24056 + gmx_rx_int_reg.s.phy_link = 1;
24057 + gmx_rx_int_reg.s.phy_spd = 1;
24058 + cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
24059 + (index, interface),
24060 + gmx_rx_int_reg.u64);
24061 + return_status = IRQ_HANDLED;
24062 + }
24063 + }
24064 + }
24065 + return return_status;
24066 +}
24067 +
24068 +static int cvm_oct_rgmii_open(struct net_device *dev)
24069 +{
24070 + union cvmx_gmxx_prtx_cfg gmx_cfg;
24071 + struct octeon_ethernet *priv = netdev_priv(dev);
24072 + int interface = INTERFACE(priv->port);
24073 + int index = INDEX(priv->port);
24074 + cvmx_helper_link_info_t link_info;
24075 +
24076 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
24077 + gmx_cfg.s.en = 1;
24078 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
24079 +
24080 + if (!octeon_is_simulation()) {
24081 + link_info = cvmx_helper_link_get(priv->port);
24082 + if (!link_info.s.link_up)
24083 + netif_carrier_off(dev);
24084 + }
24085 +
24086 + return 0;
24087 +}
24088 +
24089 +static int cvm_oct_rgmii_stop(struct net_device *dev)
24090 +{
24091 + union cvmx_gmxx_prtx_cfg gmx_cfg;
24092 + struct octeon_ethernet *priv = netdev_priv(dev);
24093 + int interface = INTERFACE(priv->port);
24094 + int index = INDEX(priv->port);
24095 +
24096 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
24097 + gmx_cfg.s.en = 0;
24098 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
24099 + return 0;
24100 +}
24101 +
24102 +int cvm_oct_rgmii_init(struct net_device *dev)
24103 +{
24104 + struct octeon_ethernet *priv = netdev_priv(dev);
24105 + int r;
24106 +
24107 + cvm_oct_common_init(dev);
24108 + dev->open = cvm_oct_rgmii_open;
24109 + dev->stop = cvm_oct_rgmii_stop;
24110 + dev->stop(dev);
24111 +
24112 + /*
24113 + * Due to GMX errata in CN3XXX series chips, it is necessary
24114 + * to take the link down immediately whne the PHY changes
24115 + * state. In order to do this we call the poll function every
24116 + * time the RGMII inband status changes. This may cause
24117 + * problems if the PHY doesn't implement inband status
24118 + * properly.
24119 + */
24120 + if (number_rgmii_ports == 0) {
24121 + r = request_irq(OCTEON_IRQ_RML, cvm_oct_rgmii_rml_interrupt,
24122 + IRQF_SHARED, "RGMII", &number_rgmii_ports);
24123 + }
24124 + number_rgmii_ports++;
24125 +
24126 + /*
24127 + * Only true RGMII ports need to be polled. In GMII mode, port
24128 + * 0 is really a RGMII port.
24129 + */
24130 + if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
24131 + && (priv->port == 0))
24132 + || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
24133 +
24134 + if (!octeon_is_simulation()) {
24135 +
24136 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
24137 + int interface = INTERFACE(priv->port);
24138 + int index = INDEX(priv->port);
24139 +
24140 + /*
24141 + * Enable interrupts on inband status changes
24142 + * for this port.
24143 + */
24144 + gmx_rx_int_en.u64 =
24145 + cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
24146 + (index, interface));
24147 + gmx_rx_int_en.s.phy_dupx = 1;
24148 + gmx_rx_int_en.s.phy_link = 1;
24149 + gmx_rx_int_en.s.phy_spd = 1;
24150 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
24151 + gmx_rx_int_en.u64);
24152 + priv->poll = cvm_oct_rgmii_poll;
24153 + }
24154 + }
24155 +
24156 + return 0;
24157 +}
24158 +
24159 +void cvm_oct_rgmii_uninit(struct net_device *dev)
24160 +{
24161 + struct octeon_ethernet *priv = netdev_priv(dev);
24162 + cvm_oct_common_uninit(dev);
24163 +
24164 + /*
24165 + * Only true RGMII ports need to be polled. In GMII mode, port
24166 + * 0 is really a RGMII port.
24167 + */
24168 + if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
24169 + && (priv->port == 0))
24170 + || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
24171 +
24172 + if (!octeon_is_simulation()) {
24173 +
24174 + union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
24175 + int interface = INTERFACE(priv->port);
24176 + int index = INDEX(priv->port);
24177 +
24178 + /*
24179 + * Disable interrupts on inband status changes
24180 + * for this port.
24181 + */
24182 + gmx_rx_int_en.u64 =
24183 + cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
24184 + (index, interface));
24185 + gmx_rx_int_en.s.phy_dupx = 0;
24186 + gmx_rx_int_en.s.phy_link = 0;
24187 + gmx_rx_int_en.s.phy_spd = 0;
24188 + cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
24189 + gmx_rx_int_en.u64);
24190 + }
24191 + }
24192 +
24193 + /* Remove the interrupt handler when the last port is removed. */
24194 + number_rgmii_ports--;
24195 + if (number_rgmii_ports == 0)
24196 + free_irq(OCTEON_IRQ_RML, &number_rgmii_ports);
24197 +}
24198 diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
24199 new file mode 100644
24200 index 0000000..1b237b7
24201 --- /dev/null
24202 +++ b/drivers/staging/octeon/ethernet-rx.c
24203 @@ -0,0 +1,505 @@
24204 +/**********************************************************************
24205 + * Author: Cavium Networks
24206 + *
24207 + * Contact: support@caviumnetworks.com
24208 + * This file is part of the OCTEON SDK
24209 + *
24210 + * Copyright (c) 2003-2007 Cavium Networks
24211 + *
24212 + * This file is free software; you can redistribute it and/or modify
24213 + * it under the terms of the GNU General Public License, Version 2, as
24214 + * published by the Free Software Foundation.
24215 + *
24216 + * This file is distributed in the hope that it will be useful, but
24217 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24218 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24219 + * NONINFRINGEMENT. See the GNU General Public License for more
24220 + * details.
24221 + *
24222 + * You should have received a copy of the GNU General Public License
24223 + * along with this file; if not, write to the Free Software
24224 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24225 + * or visit http://www.gnu.org/licenses/.
24226 + *
24227 + * This file may also be available under a different license from Cavium.
24228 + * Contact Cavium Networks for more information
24229 +**********************************************************************/
24230 +#include <linux/module.h>
24231 +#include <linux/kernel.h>
24232 +#include <linux/cache.h>
24233 +#include <linux/netdevice.h>
24234 +#include <linux/init.h>
24235 +#include <linux/etherdevice.h>
24236 +#include <linux/ip.h>
24237 +#include <linux/string.h>
24238 +#include <linux/prefetch.h>
24239 +#include <linux/ethtool.h>
24240 +#include <linux/mii.h>
24241 +#include <linux/seq_file.h>
24242 +#include <linux/proc_fs.h>
24243 +#include <net/dst.h>
24244 +#ifdef CONFIG_XFRM
24245 +#include <linux/xfrm.h>
24246 +#include <net/xfrm.h>
24247 +#endif /* CONFIG_XFRM */
24248 +
24249 +#include <asm/atomic.h>
24250 +
24251 +#include <asm/octeon/octeon.h>
24252 +
24253 +#include "ethernet-defines.h"
24254 +#include "octeon-ethernet.h"
24255 +#include "ethernet-mem.h"
24256 +#include "ethernet-util.h"
24257 +
24258 +#include "cvmx-helper.h"
24259 +#include "cvmx-wqe.h"
24260 +#include "cvmx-fau.h"
24261 +#include "cvmx-pow.h"
24262 +#include "cvmx-pip.h"
24263 +#include "cvmx-scratch.h"
24264 +
24265 +#include "cvmx-gmxx-defs.h"
24266 +
24267 +struct cvm_tasklet_wrapper {
24268 + struct tasklet_struct t;
24269 +};
24270 +
24271 +/*
24272 + * Aligning the tasklet_struct on cachline boundries seems to decrease
24273 + * throughput even though in theory it would reduce contantion on the
24274 + * cache lines containing the locks.
24275 + */
24276 +
24277 +static struct cvm_tasklet_wrapper cvm_oct_tasklet[NR_CPUS];
24278 +
24279 +/**
24280 + * Interrupt handler. The interrupt occurs whenever the POW
24281 + * transitions from 0->1 packets in our group.
24282 + *
24283 + * @cpl:
24284 + * @dev_id:
24285 + * @regs:
24286 + * Returns
24287 + */
24288 +irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
24289 +{
24290 + /* Acknowledge the interrupt */
24291 + if (INTERRUPT_LIMIT)
24292 + cvmx_write_csr(CVMX_POW_WQ_INT, 1 << pow_receive_group);
24293 + else
24294 + cvmx_write_csr(CVMX_POW_WQ_INT, 0x10001 << pow_receive_group);
24295 + preempt_disable();
24296 + tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
24297 + preempt_enable();
24298 + return IRQ_HANDLED;
24299 +}
24300 +
24301 +#ifdef CONFIG_NET_POLL_CONTROLLER
24302 +/**
24303 + * This is called when the kernel needs to manually poll the
24304 + * device. For Octeon, this is simply calling the interrupt
24305 + * handler. We actually poll all the devices, not just the
24306 + * one supplied.
24307 + *
24308 + * @dev: Device to poll. Unused
24309 + */
24310 +void cvm_oct_poll_controller(struct net_device *dev)
24311 +{
24312 + preempt_disable();
24313 + tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
24314 + preempt_enable();
24315 +}
24316 +#endif
24317 +
24318 +/**
24319 + * This is called on receive errors, and determines if the packet
24320 + * can be dropped early-on in cvm_oct_tasklet_rx().
24321 + *
24322 + * @work: Work queue entry pointing to the packet.
24323 + * Returns Non-zero if the packet can be dropped, zero otherwise.
24324 + */
24325 +static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
24326 +{
24327 + if ((work->word2.snoip.err_code == 10) && (work->len <= 64)) {
24328 + /*
24329 + * Ignore length errors on min size packets. Some
24330 + * equipment incorrectly pads packets to 64+4FCS
24331 + * instead of 60+4FCS. Note these packets still get
24332 + * counted as frame errors.
24333 + */
24334 + } else
24335 + if (USE_10MBPS_PREAMBLE_WORKAROUND
24336 + && ((work->word2.snoip.err_code == 5)
24337 + || (work->word2.snoip.err_code == 7))) {
24338 +
24339 + /*
24340 + * We received a packet with either an alignment error
24341 + * or a FCS error. This may be signalling that we are
24342 + * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK}
24343 + * off. If this is the case we need to parse the
24344 + * packet to determine if we can remove a non spec
24345 + * preamble and generate a correct packet.
24346 + */
24347 + int interface = cvmx_helper_get_interface_num(work->ipprt);
24348 + int index = cvmx_helper_get_interface_index_num(work->ipprt);
24349 + union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
24350 + gmxx_rxx_frm_ctl.u64 =
24351 + cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
24352 + if (gmxx_rxx_frm_ctl.s.pre_chk == 0) {
24353 +
24354 + uint8_t *ptr =
24355 + cvmx_phys_to_ptr(work->packet_ptr.s.addr);
24356 + int i = 0;
24357 +
24358 + while (i < work->len - 1) {
24359 + if (*ptr != 0x55)
24360 + break;
24361 + ptr++;
24362 + i++;
24363 + }
24364 +
24365 + if (*ptr == 0xd5) {
24366 + /*
24367 + DEBUGPRINT("Port %d received 0xd5 preamble\n", work->ipprt);
24368 + */
24369 + work->packet_ptr.s.addr += i + 1;
24370 + work->len -= i + 5;
24371 + } else if ((*ptr & 0xf) == 0xd) {
24372 + /*
24373 + DEBUGPRINT("Port %d received 0x?d preamble\n", work->ipprt);
24374 + */
24375 + work->packet_ptr.s.addr += i;
24376 + work->len -= i + 4;
24377 + for (i = 0; i < work->len; i++) {
24378 + *ptr =
24379 + ((*ptr & 0xf0) >> 4) |
24380 + ((*(ptr + 1) & 0xf) << 4);
24381 + ptr++;
24382 + }
24383 + } else {
24384 + DEBUGPRINT("Port %d unknown preamble, packet "
24385 + "dropped\n",
24386 + work->ipprt);
24387 + /*
24388 + cvmx_helper_dump_packet(work);
24389 + */
24390 + cvm_oct_free_work(work);
24391 + return 1;
24392 + }
24393 + }
24394 + } else {
24395 + DEBUGPRINT("Port %d receive error code %d, packet dropped\n",
24396 + work->ipprt, work->word2.snoip.err_code);
24397 + cvm_oct_free_work(work);
24398 + return 1;
24399 + }
24400 +
24401 + return 0;
24402 +}
24403 +
24404 +/**
24405 + * Tasklet function that is scheduled on a core when an interrupt occurs.
24406 + *
24407 + * @unused:
24408 + */
24409 +void cvm_oct_tasklet_rx(unsigned long unused)
24410 +{
24411 + const int coreid = cvmx_get_core_num();
24412 + uint64_t old_group_mask;
24413 + uint64_t old_scratch;
24414 + int rx_count = 0;
24415 + int number_to_free;
24416 + int num_freed;
24417 + int packet_not_copied;
24418 +
24419 + /* Prefetch cvm_oct_device since we know we need it soon */
24420 + prefetch(cvm_oct_device);
24421 +
24422 + if (USE_ASYNC_IOBDMA) {
24423 + /* Save scratch in case userspace is using it */
24424 + CVMX_SYNCIOBDMA;
24425 + old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
24426 + }
24427 +
24428 + /* Only allow work for our group (and preserve priorities) */
24429 + old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));
24430 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
24431 + (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group);
24432 +
24433 + if (USE_ASYNC_IOBDMA)
24434 + cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
24435 +
24436 + while (1) {
24437 + struct sk_buff *skb = NULL;
24438 + int skb_in_hw;
24439 + cvmx_wqe_t *work;
24440 +
24441 + if (USE_ASYNC_IOBDMA) {
24442 + work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);
24443 + } else {
24444 + if ((INTERRUPT_LIMIT == 0)
24445 + || likely(rx_count < MAX_RX_PACKETS))
24446 + work =
24447 + cvmx_pow_work_request_sync
24448 + (CVMX_POW_NO_WAIT);
24449 + else
24450 + work = NULL;
24451 + }
24452 + prefetch(work);
24453 + if (work == NULL)
24454 + break;
24455 +
24456 + /*
24457 + * Limit each core to processing MAX_RX_PACKETS
24458 + * packets without a break. This way the RX can't
24459 + * starve the TX task.
24460 + */
24461 + if (USE_ASYNC_IOBDMA) {
24462 +
24463 + if ((INTERRUPT_LIMIT == 0)
24464 + || likely(rx_count < MAX_RX_PACKETS))
24465 + cvmx_pow_work_request_async_nocheck
24466 + (CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
24467 + else {
24468 + cvmx_scratch_write64(CVMX_SCR_SCRATCH,
24469 + 0x8000000000000000ull);
24470 + cvmx_pow_tag_sw_null_nocheck();
24471 + }
24472 + }
24473 +
24474 + skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1;
24475 + if (likely(skb_in_hw)) {
24476 + skb =
24477 + *(struct sk_buff
24478 + **)(cvm_oct_get_buffer_ptr(work->packet_ptr) -
24479 + sizeof(void *));
24480 + prefetch(&skb->head);
24481 + prefetch(&skb->len);
24482 + }
24483 + prefetch(cvm_oct_device[work->ipprt]);
24484 +
24485 + rx_count++;
24486 + /* Immediately throw away all packets with receive errors */
24487 + if (unlikely(work->word2.snoip.rcv_error)) {
24488 + if (cvm_oct_check_rcv_error(work))
24489 + continue;
24490 + }
24491 +
24492 + /*
24493 + * We can only use the zero copy path if skbuffs are
24494 + * in the FPA pool and the packet fits in a single
24495 + * buffer.
24496 + */
24497 + if (likely(skb_in_hw)) {
24498 + /*
24499 + * This calculation was changed in case the
24500 + * skb header is using a different address
24501 + * aliasing type than the buffer. It doesn't
24502 + * make any differnece now, but the new one is
24503 + * more correct.
24504 + */
24505 + skb->data =
24506 + skb->head + work->packet_ptr.s.addr -
24507 + cvmx_ptr_to_phys(skb->head);
24508 + prefetch(skb->data);
24509 + skb->len = work->len;
24510 + skb_set_tail_pointer(skb, skb->len);
24511 + packet_not_copied = 1;
24512 + } else {
24513 +
24514 + /*
24515 + * We have to copy the packet. First allocate
24516 + * an skbuff for it.
24517 + */
24518 + skb = dev_alloc_skb(work->len);
24519 + if (!skb) {
24520 + DEBUGPRINT("Port %d failed to allocate "
24521 + "skbuff, packet dropped\n",
24522 + work->ipprt);
24523 + cvm_oct_free_work(work);
24524 + continue;
24525 + }
24526 +
24527 + /*
24528 + * Check if we've received a packet that was
24529 + * entirely stored in the work entry. This is
24530 + * untested.
24531 + */
24532 + if (unlikely(work->word2.s.bufs == 0)) {
24533 + uint8_t *ptr = work->packet_data;
24534 +
24535 + if (likely(!work->word2.s.not_IP)) {
24536 + /*
24537 + * The beginning of the packet
24538 + * moves for IP packets.
24539 + */
24540 + if (work->word2.s.is_v6)
24541 + ptr += 2;
24542 + else
24543 + ptr += 6;
24544 + }
24545 + memcpy(skb_put(skb, work->len), ptr, work->len);
24546 + /* No packet buffers to free */
24547 + } else {
24548 + int segments = work->word2.s.bufs;
24549 + union cvmx_buf_ptr segment_ptr =
24550 + work->packet_ptr;
24551 + int len = work->len;
24552 +
24553 + while (segments--) {
24554 + union cvmx_buf_ptr next_ptr =
24555 + *(union cvmx_buf_ptr *)
24556 + cvmx_phys_to_ptr(segment_ptr.s.
24557 + addr - 8);
24558 + /*
24559 + * Octeon Errata PKI-100: The segment size is
24560 + * wrong. Until it is fixed, calculate the
24561 + * segment size based on the packet pool
24562 + * buffer size. When it is fixed, the
24563 + * following line should be replaced with this
24564 + * one: int segment_size =
24565 + * segment_ptr.s.size;
24566 + */
24567 + int segment_size =
24568 + CVMX_FPA_PACKET_POOL_SIZE -
24569 + (segment_ptr.s.addr -
24570 + (((segment_ptr.s.addr >> 7) -
24571 + segment_ptr.s.back) << 7));
24572 + /* Don't copy more than what is left
24573 + in the packet */
24574 + if (segment_size > len)
24575 + segment_size = len;
24576 + /* Copy the data into the packet */
24577 + memcpy(skb_put(skb, segment_size),
24578 + cvmx_phys_to_ptr(segment_ptr.s.
24579 + addr),
24580 + segment_size);
24581 + /* Reduce the amount of bytes left
24582 + to copy */
24583 + len -= segment_size;
24584 + segment_ptr = next_ptr;
24585 + }
24586 + }
24587 + packet_not_copied = 0;
24588 + }
24589 +
24590 + if (likely((work->ipprt < TOTAL_NUMBER_OF_PORTS) &&
24591 + cvm_oct_device[work->ipprt])) {
24592 + struct net_device *dev = cvm_oct_device[work->ipprt];
24593 + struct octeon_ethernet *priv = netdev_priv(dev);
24594 +
24595 + /* Only accept packets for devices
24596 + that are currently up */
24597 + if (likely(dev->flags & IFF_UP)) {
24598 + skb->protocol = eth_type_trans(skb, dev);
24599 + skb->dev = dev;
24600 +
24601 + if (unlikely
24602 + (work->word2.s.not_IP
24603 + || work->word2.s.IP_exc
24604 + || work->word2.s.L4_error))
24605 + skb->ip_summed = CHECKSUM_NONE;
24606 + else
24607 + skb->ip_summed = CHECKSUM_UNNECESSARY;
24608 +
24609 + /* Increment RX stats for virtual ports */
24610 + if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) {
24611 +#ifdef CONFIG_64BIT
24612 + atomic64_add(1, (atomic64_t *)&priv->stats.rx_packets);
24613 + atomic64_add(skb->len, (atomic64_t *)&priv->stats.rx_bytes);
24614 +#else
24615 + atomic_add(1, (atomic_t *)&priv->stats.rx_packets);
24616 + atomic_add(skb->len, (atomic_t *)&priv->stats.rx_bytes);
24617 +#endif
24618 + }
24619 + netif_receive_skb(skb);
24620 + } else {
24621 + /*
24622 + * Drop any packet received for a
24623 + * device that isn't up.
24624 + */
24625 + /*
24626 + DEBUGPRINT("%s: Device not up, packet dropped\n",
24627 + dev->name);
24628 + */
24629 +#ifdef CONFIG_64BIT
24630 + atomic64_add(1, (atomic64_t *)&priv->stats.rx_dropped);
24631 +#else
24632 + atomic_add(1, (atomic_t *)&priv->stats.rx_dropped);
24633 +#endif
24634 + dev_kfree_skb_irq(skb);
24635 + }
24636 + } else {
24637 + /*
24638 + * Drop any packet received for a device that
24639 + * doesn't exist.
24640 + */
24641 + DEBUGPRINT("Port %d not controlled by Linux, packet "
24642 + "dropped\n",
24643 + work->ipprt);
24644 + dev_kfree_skb_irq(skb);
24645 + }
24646 + /*
24647 + * Check to see if the skbuff and work share the same
24648 + * packet buffer.
24649 + */
24650 + if (USE_SKBUFFS_IN_HW && likely(packet_not_copied)) {
24651 + /*
24652 + * This buffer needs to be replaced, increment
24653 + * the number of buffers we need to free by
24654 + * one.
24655 + */
24656 + cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
24657 + 1);
24658 +
24659 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL,
24660 + DONT_WRITEBACK(1));
24661 + } else {
24662 + cvm_oct_free_work(work);
24663 + }
24664 + }
24665 +
24666 + /* Restore the original POW group mask */
24667 + cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask);
24668 + if (USE_ASYNC_IOBDMA) {
24669 + /* Restore the scratch area */
24670 + cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
24671 + }
24672 +
24673 + if (USE_SKBUFFS_IN_HW) {
24674 + /* Refill the packet buffer pool */
24675 + number_to_free =
24676 + cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
24677 +
24678 + if (number_to_free > 0) {
24679 + cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
24680 + -number_to_free);
24681 + num_freed =
24682 + cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL,
24683 + CVMX_FPA_PACKET_POOL_SIZE,
24684 + number_to_free);
24685 + if (num_freed != number_to_free) {
24686 + cvmx_fau_atomic_add32
24687 + (FAU_NUM_PACKET_BUFFERS_TO_FREE,
24688 + number_to_free - num_freed);
24689 + }
24690 + }
24691 + }
24692 +}
24693 +
24694 +void cvm_oct_rx_initialize(void)
24695 +{
24696 + int i;
24697 + /* Initialize all of the tasklets */
24698 + for (i = 0; i < NR_CPUS; i++)
24699 + tasklet_init(&cvm_oct_tasklet[i].t, cvm_oct_tasklet_rx, 0);
24700 +}
24701 +
24702 +void cvm_oct_rx_shutdown(void)
24703 +{
24704 + int i;
24705 + /* Shutdown all of the tasklets */
24706 + for (i = 0; i < NR_CPUS; i++)
24707 + tasklet_kill(&cvm_oct_tasklet[i].t);
24708 +}
24709 diff --git a/drivers/staging/octeon/ethernet-rx.h b/drivers/staging/octeon/ethernet-rx.h
24710 new file mode 100644
24711 index 0000000..a9b72b8
24712 --- /dev/null
24713 +++ b/drivers/staging/octeon/ethernet-rx.h
24714 @@ -0,0 +1,33 @@
24715 +/*********************************************************************
24716 + * Author: Cavium Networks
24717 + *
24718 + * Contact: support@caviumnetworks.com
24719 + * This file is part of the OCTEON SDK
24720 + *
24721 + * Copyright (c) 2003-2007 Cavium Networks
24722 + *
24723 + * This file is free software; you can redistribute it and/or modify
24724 + * it under the terms of the GNU General Public License, Version 2, as
24725 + * published by the Free Software Foundation.
24726 + *
24727 + * This file is distributed in the hope that it will be useful, but
24728 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24729 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24730 + * NONINFRINGEMENT. See the GNU General Public License for more
24731 + * details.
24732 + *
24733 + * You should have received a copy of the GNU General Public License
24734 + * along with this file; if not, write to the Free Software
24735 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24736 + * or visit http://www.gnu.org/licenses/.
24737 + *
24738 + * This file may also be available under a different license from Cavium.
24739 + * Contact Cavium Networks for more information
24740 +*********************************************************************/
24741 +
24742 +irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id);
24743 +void cvm_oct_poll_controller(struct net_device *dev);
24744 +void cvm_oct_tasklet_rx(unsigned long unused);
24745 +
24746 +void cvm_oct_rx_initialize(void);
24747 +void cvm_oct_rx_shutdown(void);
24748 diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
24749 new file mode 100644
24750 index 0000000..58fa39c
24751 --- /dev/null
24752 +++ b/drivers/staging/octeon/ethernet-sgmii.c
24753 @@ -0,0 +1,129 @@
24754 +/**********************************************************************
24755 + * Author: Cavium Networks
24756 + *
24757 + * Contact: support@caviumnetworks.com
24758 + * This file is part of the OCTEON SDK
24759 + *
24760 + * Copyright (c) 2003-2007 Cavium Networks
24761 + *
24762 + * This file is free software; you can redistribute it and/or modify
24763 + * it under the terms of the GNU General Public License, Version 2, as
24764 + * published by the Free Software Foundation.
24765 + *
24766 + * This file is distributed in the hope that it will be useful, but
24767 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24768 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24769 + * NONINFRINGEMENT. See the GNU General Public License for more
24770 + * details.
24771 + *
24772 + * You should have received a copy of the GNU General Public License
24773 + * along with this file; if not, write to the Free Software
24774 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24775 + * or visit http://www.gnu.org/licenses/.
24776 + *
24777 + * This file may also be available under a different license from Cavium.
24778 + * Contact Cavium Networks for more information
24779 +**********************************************************************/
24780 +#include <linux/kernel.h>
24781 +#include <linux/netdevice.h>
24782 +#include <linux/mii.h>
24783 +#include <net/dst.h>
24784 +
24785 +#include <asm/octeon/octeon.h>
24786 +
24787 +#include "ethernet-defines.h"
24788 +#include "octeon-ethernet.h"
24789 +#include "ethernet-util.h"
24790 +#include "ethernet-common.h"
24791 +
24792 +#include "cvmx-helper.h"
24793 +
24794 +#include "cvmx-gmxx-defs.h"
24795 +
24796 +static int cvm_oct_sgmii_open(struct net_device *dev)
24797 +{
24798 + union cvmx_gmxx_prtx_cfg gmx_cfg;
24799 + struct octeon_ethernet *priv = netdev_priv(dev);
24800 + int interface = INTERFACE(priv->port);
24801 + int index = INDEX(priv->port);
24802 + cvmx_helper_link_info_t link_info;
24803 +
24804 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
24805 + gmx_cfg.s.en = 1;
24806 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
24807 +
24808 + if (!octeon_is_simulation()) {
24809 + link_info = cvmx_helper_link_get(priv->port);
24810 + if (!link_info.s.link_up)
24811 + netif_carrier_off(dev);
24812 + }
24813 +
24814 + return 0;
24815 +}
24816 +
24817 +static int cvm_oct_sgmii_stop(struct net_device *dev)
24818 +{
24819 + union cvmx_gmxx_prtx_cfg gmx_cfg;
24820 + struct octeon_ethernet *priv = netdev_priv(dev);
24821 + int interface = INTERFACE(priv->port);
24822 + int index = INDEX(priv->port);
24823 +
24824 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
24825 + gmx_cfg.s.en = 0;
24826 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
24827 + return 0;
24828 +}
24829 +
24830 +static void cvm_oct_sgmii_poll(struct net_device *dev)
24831 +{
24832 + struct octeon_ethernet *priv = netdev_priv(dev);
24833 + cvmx_helper_link_info_t link_info;
24834 +
24835 + link_info = cvmx_helper_link_get(priv->port);
24836 + if (link_info.u64 == priv->link_info)
24837 + return;
24838 +
24839 + link_info = cvmx_helper_link_autoconf(priv->port);
24840 + priv->link_info = link_info.u64;
24841 +
24842 + /* Tell Linux */
24843 + if (link_info.s.link_up) {
24844 +
24845 + if (!netif_carrier_ok(dev))
24846 + netif_carrier_on(dev);
24847 + if (priv->queue != -1)
24848 + DEBUGPRINT
24849 + ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
24850 + dev->name, link_info.s.speed,
24851 + (link_info.s.full_duplex) ? "Full" : "Half",
24852 + priv->port, priv->queue);
24853 + else
24854 + DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
24855 + dev->name, link_info.s.speed,
24856 + (link_info.s.full_duplex) ? "Full" : "Half",
24857 + priv->port);
24858 + } else {
24859 + if (netif_carrier_ok(dev))
24860 + netif_carrier_off(dev);
24861 + DEBUGPRINT("%s: Link down\n", dev->name);
24862 + }
24863 +}
24864 +
24865 +int cvm_oct_sgmii_init(struct net_device *dev)
24866 +{
24867 + struct octeon_ethernet *priv = netdev_priv(dev);
24868 + cvm_oct_common_init(dev);
24869 + dev->open = cvm_oct_sgmii_open;
24870 + dev->stop = cvm_oct_sgmii_stop;
24871 + dev->stop(dev);
24872 + if (!octeon_is_simulation())
24873 + priv->poll = cvm_oct_sgmii_poll;
24874 +
24875 + /* FIXME: Need autoneg logic */
24876 + return 0;
24877 +}
24878 +
24879 +void cvm_oct_sgmii_uninit(struct net_device *dev)
24880 +{
24881 + cvm_oct_common_uninit(dev);
24882 +}
24883 diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c
24884 new file mode 100644
24885 index 0000000..e0971bb
24886 --- /dev/null
24887 +++ b/drivers/staging/octeon/ethernet-spi.c
24888 @@ -0,0 +1,323 @@
24889 +/**********************************************************************
24890 + * Author: Cavium Networks
24891 + *
24892 + * Contact: support@caviumnetworks.com
24893 + * This file is part of the OCTEON SDK
24894 + *
24895 + * Copyright (c) 2003-2007 Cavium Networks
24896 + *
24897 + * This file is free software; you can redistribute it and/or modify
24898 + * it under the terms of the GNU General Public License, Version 2, as
24899 + * published by the Free Software Foundation.
24900 + *
24901 + * This file is distributed in the hope that it will be useful, but
24902 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
24903 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
24904 + * NONINFRINGEMENT. See the GNU General Public License for more
24905 + * details.
24906 + *
24907 + * You should have received a copy of the GNU General Public License
24908 + * along with this file; if not, write to the Free Software
24909 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24910 + * or visit http://www.gnu.org/licenses/.
24911 + *
24912 + * This file may also be available under a different license from Cavium.
24913 + * Contact Cavium Networks for more information
24914 +**********************************************************************/
24915 +#include <linux/kernel.h>
24916 +#include <linux/netdevice.h>
24917 +#include <linux/mii.h>
24918 +#include <net/dst.h>
24919 +
24920 +#include <asm/octeon/octeon.h>
24921 +
24922 +#include "ethernet-defines.h"
24923 +#include "octeon-ethernet.h"
24924 +#include "ethernet-common.h"
24925 +#include "ethernet-util.h"
24926 +
24927 +#include "cvmx-spi.h"
24928 +
24929 +#include <asm/octeon/cvmx-npi-defs.h>
24930 +#include "cvmx-spxx-defs.h"
24931 +#include "cvmx-stxx-defs.h"
24932 +
24933 +static int number_spi_ports;
24934 +static int need_retrain[2] = { 0, 0 };
24935 +
24936 +static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
24937 +{
24938 + irqreturn_t return_status = IRQ_NONE;
24939 + union cvmx_npi_rsl_int_blocks rsl_int_blocks;
24940 +
24941 + /* Check and see if this interrupt was caused by the GMX block */
24942 + rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
24943 + if (rsl_int_blocks.s.spx1) { /* 19 - SPX1_INT_REG & STX1_INT_REG */
24944 +
24945 + union cvmx_spxx_int_reg spx_int_reg;
24946 + union cvmx_stxx_int_reg stx_int_reg;
24947 +
24948 + spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(1));
24949 + cvmx_write_csr(CVMX_SPXX_INT_REG(1), spx_int_reg.u64);
24950 + if (!need_retrain[1]) {
24951 +
24952 + spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(1));
24953 + if (spx_int_reg.s.spf)
24954 + pr_err("SPI1: SRX Spi4 interface down\n");
24955 + if (spx_int_reg.s.calerr)
24956 + pr_err("SPI1: SRX Spi4 Calendar table "
24957 + "parity error\n");
24958 + if (spx_int_reg.s.syncerr)
24959 + pr_err("SPI1: SRX Consecutive Spi4 DIP4 "
24960 + "errors have exceeded "
24961 + "SPX_ERR_CTL[ERRCNT]\n");
24962 + if (spx_int_reg.s.diperr)
24963 + pr_err("SPI1: SRX Spi4 DIP4 error\n");
24964 + if (spx_int_reg.s.tpaovr)
24965 + pr_err("SPI1: SRX Selected port has hit "
24966 + "TPA overflow\n");
24967 + if (spx_int_reg.s.rsverr)
24968 + pr_err("SPI1: SRX Spi4 reserved control "
24969 + "word detected\n");
24970 + if (spx_int_reg.s.drwnng)
24971 + pr_err("SPI1: SRX Spi4 receive FIFO "
24972 + "drowning/overflow\n");
24973 + if (spx_int_reg.s.clserr)
24974 + pr_err("SPI1: SRX Spi4 packet closed on "
24975 + "non-16B alignment without EOP\n");
24976 + if (spx_int_reg.s.spiovr)
24977 + pr_err("SPI1: SRX Spi4 async FIFO overflow\n");
24978 + if (spx_int_reg.s.abnorm)
24979 + pr_err("SPI1: SRX Abnormal packet "
24980 + "termination (ERR bit)\n");
24981 + if (spx_int_reg.s.prtnxa)
24982 + pr_err("SPI1: SRX Port out of range\n");
24983 + }
24984 +
24985 + stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(1));
24986 + cvmx_write_csr(CVMX_STXX_INT_REG(1), stx_int_reg.u64);
24987 + if (!need_retrain[1]) {
24988 +
24989 + stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(1));
24990 + if (stx_int_reg.s.syncerr)
24991 + pr_err("SPI1: STX Interface encountered a "
24992 + "fatal error\n");
24993 + if (stx_int_reg.s.frmerr)
24994 + pr_err("SPI1: STX FRMCNT has exceeded "
24995 + "STX_DIP_CNT[MAXFRM]\n");
24996 + if (stx_int_reg.s.unxfrm)
24997 + pr_err("SPI1: STX Unexpected framing "
24998 + "sequence\n");
24999 + if (stx_int_reg.s.nosync)
25000 + pr_err("SPI1: STX ERRCNT has exceeded "
25001 + "STX_DIP_CNT[MAXDIP]\n");
25002 + if (stx_int_reg.s.diperr)
25003 + pr_err("SPI1: STX DIP2 error on the Spi4 "
25004 + "Status channel\n");
25005 + if (stx_int_reg.s.datovr)
25006 + pr_err("SPI1: STX Spi4 FIFO overflow error\n");
25007 + if (stx_int_reg.s.ovrbst)
25008 + pr_err("SPI1: STX Transmit packet burst "
25009 + "too big\n");
25010 + if (stx_int_reg.s.calpar1)
25011 + pr_err("SPI1: STX Calendar Table Parity "
25012 + "Error Bank1\n");
25013 + if (stx_int_reg.s.calpar0)
25014 + pr_err("SPI1: STX Calendar Table Parity "
25015 + "Error Bank0\n");
25016 + }
25017 +
25018 + cvmx_write_csr(CVMX_SPXX_INT_MSK(1), 0);
25019 + cvmx_write_csr(CVMX_STXX_INT_MSK(1), 0);
25020 + need_retrain[1] = 1;
25021 + return_status = IRQ_HANDLED;
25022 + }
25023 +
25024 + if (rsl_int_blocks.s.spx0) { /* 18 - SPX0_INT_REG & STX0_INT_REG */
25025 + union cvmx_spxx_int_reg spx_int_reg;
25026 + union cvmx_stxx_int_reg stx_int_reg;
25027 +
25028 + spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(0));
25029 + cvmx_write_csr(CVMX_SPXX_INT_REG(0), spx_int_reg.u64);
25030 + if (!need_retrain[0]) {
25031 +
25032 + spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(0));
25033 + if (spx_int_reg.s.spf)
25034 + pr_err("SPI0: SRX Spi4 interface down\n");
25035 + if (spx_int_reg.s.calerr)
25036 + pr_err("SPI0: SRX Spi4 Calendar table "
25037 + "parity error\n");
25038 + if (spx_int_reg.s.syncerr)
25039 + pr_err("SPI0: SRX Consecutive Spi4 DIP4 "
25040 + "errors have exceeded "
25041 + "SPX_ERR_CTL[ERRCNT]\n");
25042 + if (spx_int_reg.s.diperr)
25043 + pr_err("SPI0: SRX Spi4 DIP4 error\n");
25044 + if (spx_int_reg.s.tpaovr)
25045 + pr_err("SPI0: SRX Selected port has hit "
25046 + "TPA overflow\n");
25047 + if (spx_int_reg.s.rsverr)
25048 + pr_err("SPI0: SRX Spi4 reserved control "
25049 + "word detected\n");
25050 + if (spx_int_reg.s.drwnng)
25051 + pr_err("SPI0: SRX Spi4 receive FIFO "
25052 + "drowning/overflow\n");
25053 + if (spx_int_reg.s.clserr)
25054 + pr_err("SPI0: SRX Spi4 packet closed on "
25055 + "non-16B alignment without EOP\n");
25056 + if (spx_int_reg.s.spiovr)
25057 + pr_err("SPI0: SRX Spi4 async FIFO overflow\n");
25058 + if (spx_int_reg.s.abnorm)
25059 + pr_err("SPI0: SRX Abnormal packet "
25060 + "termination (ERR bit)\n");
25061 + if (spx_int_reg.s.prtnxa)
25062 + pr_err("SPI0: SRX Port out of range\n");
25063 + }
25064 +
25065 + stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(0));
25066 + cvmx_write_csr(CVMX_STXX_INT_REG(0), stx_int_reg.u64);
25067 + if (!need_retrain[0]) {
25068 +
25069 + stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(0));
25070 + if (stx_int_reg.s.syncerr)
25071 + pr_err("SPI0: STX Interface encountered a "
25072 + "fatal error\n");
25073 + if (stx_int_reg.s.frmerr)
25074 + pr_err("SPI0: STX FRMCNT has exceeded "
25075 + "STX_DIP_CNT[MAXFRM]\n");
25076 + if (stx_int_reg.s.unxfrm)
25077 + pr_err("SPI0: STX Unexpected framing "
25078 + "sequence\n");
25079 + if (stx_int_reg.s.nosync)
25080 + pr_err("SPI0: STX ERRCNT has exceeded "
25081 + "STX_DIP_CNT[MAXDIP]\n");
25082 + if (stx_int_reg.s.diperr)
25083 + pr_err("SPI0: STX DIP2 error on the Spi4 "
25084 + "Status channel\n");
25085 + if (stx_int_reg.s.datovr)
25086 + pr_err("SPI0: STX Spi4 FIFO overflow error\n");
25087 + if (stx_int_reg.s.ovrbst)
25088 + pr_err("SPI0: STX Transmit packet burst "
25089 + "too big\n");
25090 + if (stx_int_reg.s.calpar1)
25091 + pr_err("SPI0: STX Calendar Table Parity "
25092 + "Error Bank1\n");
25093 + if (stx_int_reg.s.calpar0)
25094 + pr_err("SPI0: STX Calendar Table Parity "
25095 + "Error Bank0\n");
25096 + }
25097 +
25098 + cvmx_write_csr(CVMX_SPXX_INT_MSK(0), 0);
25099 + cvmx_write_csr(CVMX_STXX_INT_MSK(0), 0);
25100 + need_retrain[0] = 1;
25101 + return_status = IRQ_HANDLED;
25102 + }
25103 +
25104 + return return_status;
25105 +}
25106 +
25107 +static void cvm_oct_spi_enable_error_reporting(int interface)
25108 +{
25109 + union cvmx_spxx_int_msk spxx_int_msk;
25110 + union cvmx_stxx_int_msk stxx_int_msk;
25111 +
25112 + spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
25113 + spxx_int_msk.s.calerr = 1;
25114 + spxx_int_msk.s.syncerr = 1;
25115 + spxx_int_msk.s.diperr = 1;
25116 + spxx_int_msk.s.tpaovr = 1;
25117 + spxx_int_msk.s.rsverr = 1;
25118 + spxx_int_msk.s.drwnng = 1;
25119 + spxx_int_msk.s.clserr = 1;
25120 + spxx_int_msk.s.spiovr = 1;
25121 + spxx_int_msk.s.abnorm = 1;
25122 + spxx_int_msk.s.prtnxa = 1;
25123 + cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
25124 +
25125 + stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
25126 + stxx_int_msk.s.frmerr = 1;
25127 + stxx_int_msk.s.unxfrm = 1;
25128 + stxx_int_msk.s.nosync = 1;
25129 + stxx_int_msk.s.diperr = 1;
25130 + stxx_int_msk.s.datovr = 1;
25131 + stxx_int_msk.s.ovrbst = 1;
25132 + stxx_int_msk.s.calpar1 = 1;
25133 + stxx_int_msk.s.calpar0 = 1;
25134 + cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
25135 +}
25136 +
25137 +static void cvm_oct_spi_poll(struct net_device *dev)
25138 +{
25139 + static int spi4000_port;
25140 + struct octeon_ethernet *priv = netdev_priv(dev);
25141 + int interface;
25142 +
25143 + for (interface = 0; interface < 2; interface++) {
25144 +
25145 + if ((priv->port == interface * 16) && need_retrain[interface]) {
25146 +
25147 + if (cvmx_spi_restart_interface
25148 + (interface, CVMX_SPI_MODE_DUPLEX, 10) == 0) {
25149 + need_retrain[interface] = 0;
25150 + cvm_oct_spi_enable_error_reporting(interface);
25151 + }
25152 + }
25153 +
25154 + /*
25155 + * The SPI4000 TWSI interface is very slow. In order
25156 + * not to bring the system to a crawl, we only poll a
25157 + * single port every second. This means negotiation
25158 + * speed changes take up to 10 seconds, but at least
25159 + * we don't waste absurd amounts of time waiting for
25160 + * TWSI.
25161 + */
25162 + if (priv->port == spi4000_port) {
25163 + /*
25164 + * This function does nothing if it is called on an
25165 + * interface without a SPI4000.
25166 + */
25167 + cvmx_spi4000_check_speed(interface, priv->port);
25168 + /*
25169 + * Normal ordering increments. By decrementing
25170 + * we only match once per iteration.
25171 + */
25172 + spi4000_port--;
25173 + if (spi4000_port < 0)
25174 + spi4000_port = 10;
25175 + }
25176 + }
25177 +}
25178 +
25179 +int cvm_oct_spi_init(struct net_device *dev)
25180 +{
25181 + int r;
25182 + struct octeon_ethernet *priv = netdev_priv(dev);
25183 +
25184 + if (number_spi_ports == 0) {
25185 + r = request_irq(OCTEON_IRQ_RML, cvm_oct_spi_rml_interrupt,
25186 + IRQF_SHARED, "SPI", &number_spi_ports);
25187 + }
25188 + number_spi_ports++;
25189 +
25190 + if ((priv->port == 0) || (priv->port == 16)) {
25191 + cvm_oct_spi_enable_error_reporting(INTERFACE(priv->port));
25192 + priv->poll = cvm_oct_spi_poll;
25193 + }
25194 + cvm_oct_common_init(dev);
25195 + return 0;
25196 +}
25197 +
25198 +void cvm_oct_spi_uninit(struct net_device *dev)
25199 +{
25200 + int interface;
25201 +
25202 + cvm_oct_common_uninit(dev);
25203 + number_spi_ports--;
25204 + if (number_spi_ports == 0) {
25205 + for (interface = 0; interface < 2; interface++) {
25206 + cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
25207 + cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
25208 + }
25209 + free_irq(8 + 46, &number_spi_ports);
25210 + }
25211 +}
25212 diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c
25213 new file mode 100644
25214 index 0000000..77b7122
25215 --- /dev/null
25216 +++ b/drivers/staging/octeon/ethernet-tx.c
25217 @@ -0,0 +1,634 @@
25218 +/*********************************************************************
25219 + * Author: Cavium Networks
25220 + *
25221 + * Contact: support@caviumnetworks.com
25222 + * This file is part of the OCTEON SDK
25223 + *
25224 + * Copyright (c) 2003-2007 Cavium Networks
25225 + *
25226 + * This file is free software; you can redistribute it and/or modify
25227 + * it under the terms of the GNU General Public License, Version 2, as
25228 + * published by the Free Software Foundation.
25229 + *
25230 + * This file is distributed in the hope that it will be useful, but
25231 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25232 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25233 + * NONINFRINGEMENT. See the GNU General Public License for more
25234 + * details.
25235 + *
25236 + * You should have received a copy of the GNU General Public License
25237 + * along with this file; if not, write to the Free Software
25238 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25239 + * or visit http://www.gnu.org/licenses/.
25240 + *
25241 + * This file may also be available under a different license from Cavium.
25242 + * Contact Cavium Networks for more information
25243 +*********************************************************************/
25244 +#include <linux/module.h>
25245 +#include <linux/kernel.h>
25246 +#include <linux/netdevice.h>
25247 +#include <linux/init.h>
25248 +#include <linux/etherdevice.h>
25249 +#include <linux/ip.h>
25250 +#include <linux/string.h>
25251 +#include <linux/ethtool.h>
25252 +#include <linux/mii.h>
25253 +#include <linux/seq_file.h>
25254 +#include <linux/proc_fs.h>
25255 +#include <net/dst.h>
25256 +#ifdef CONFIG_XFRM
25257 +#include <linux/xfrm.h>
25258 +#include <net/xfrm.h>
25259 +#endif /* CONFIG_XFRM */
25260 +
25261 +#include <asm/atomic.h>
25262 +
25263 +#include <asm/octeon/octeon.h>
25264 +
25265 +#include "ethernet-defines.h"
25266 +#include "octeon-ethernet.h"
25267 +#include "ethernet-util.h"
25268 +
25269 +#include "cvmx-wqe.h"
25270 +#include "cvmx-fau.h"
25271 +#include "cvmx-pko.h"
25272 +#include "cvmx-helper.h"
25273 +
25274 +#include "cvmx-gmxx-defs.h"
25275 +
25276 +/*
25277 + * You can define GET_SKBUFF_QOS() to override how the skbuff output
25278 + * function determines which output queue is used. The default
25279 + * implementation always uses the base queue for the port. If, for
25280 + * example, you wanted to use the skb->priority fieid, define
25281 + * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority)
25282 + */
25283 +#ifndef GET_SKBUFF_QOS
25284 +#define GET_SKBUFF_QOS(skb) 0
25285 +#endif
25286 +
25287 +/**
25288 + * Packet transmit
25289 + *
25290 + * @skb: Packet to send
25291 + * @dev: Device info structure
25292 + * Returns Always returns zero
25293 + */
25294 +int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
25295 +{
25296 + cvmx_pko_command_word0_t pko_command;
25297 + union cvmx_buf_ptr hw_buffer;
25298 + uint64_t old_scratch;
25299 + uint64_t old_scratch2;
25300 + int dropped;
25301 + int qos;
25302 + struct octeon_ethernet *priv = netdev_priv(dev);
25303 + int32_t in_use;
25304 + int32_t buffers_to_free;
25305 +#if REUSE_SKBUFFS_WITHOUT_FREE
25306 + unsigned char *fpa_head;
25307 +#endif
25308 +
25309 + /*
25310 + * Prefetch the private data structure. It is larger that one
25311 + * cache line.
25312 + */
25313 + prefetch(priv);
25314 +
25315 + /* Start off assuming no drop */
25316 + dropped = 0;
25317 +
25318 + /*
25319 + * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
25320 + * completely remove "qos" in the event neither interface
25321 + * supports multiple queues per port.
25322 + */
25323 + if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
25324 + (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
25325 + qos = GET_SKBUFF_QOS(skb);
25326 + if (qos <= 0)
25327 + qos = 0;
25328 + else if (qos >= cvmx_pko_get_num_queues(priv->port))
25329 + qos = 0;
25330 + } else
25331 + qos = 0;
25332 +
25333 + if (USE_ASYNC_IOBDMA) {
25334 + /* Save scratch in case userspace is using it */
25335 + CVMX_SYNCIOBDMA;
25336 + old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
25337 + old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
25338 +
25339 + /*
25340 + * Assume we're going to be able t osend this
25341 + * packet. Fetch and increment the number of pending
25342 + * packets for output.
25343 + */
25344 + cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8,
25345 + FAU_NUM_PACKET_BUFFERS_TO_FREE,
25346 + 0);
25347 + cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
25348 + priv->fau + qos * 4, 1);
25349 + }
25350 +
25351 + /*
25352 + * The CN3XXX series of parts has an errata (GMX-401) which
25353 + * causes the GMX block to hang if a collision occurs towards
25354 + * the end of a <68 byte packet. As a workaround for this, we
25355 + * pad packets to be 68 bytes whenever we are in half duplex
25356 + * mode. We don't handle the case of having a small packet but
25357 + * no room to add the padding. The kernel should always give
25358 + * us at least a cache line
25359 + */
25360 + if ((skb->len < 64) && OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
25361 + union cvmx_gmxx_prtx_cfg gmx_prt_cfg;
25362 + int interface = INTERFACE(priv->port);
25363 + int index = INDEX(priv->port);
25364 +
25365 + if (interface < 2) {
25366 + /* We only need to pad packet in half duplex mode */
25367 + gmx_prt_cfg.u64 =
25368 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
25369 + if (gmx_prt_cfg.s.duplex == 0) {
25370 + int add_bytes = 64 - skb->len;
25371 + if ((skb_tail_pointer(skb) + add_bytes) <=
25372 + skb_end_pointer(skb))
25373 + memset(__skb_put(skb, add_bytes), 0,
25374 + add_bytes);
25375 + }
25376 + }
25377 + }
25378 +
25379 + /* Build the PKO buffer pointer */
25380 + hw_buffer.u64 = 0;
25381 + hw_buffer.s.addr = cvmx_ptr_to_phys(skb->data);
25382 + hw_buffer.s.pool = 0;
25383 + hw_buffer.s.size =
25384 + (unsigned long)skb_end_pointer(skb) - (unsigned long)skb->head;
25385 +
25386 + /* Build the PKO command */
25387 + pko_command.u64 = 0;
25388 + pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */
25389 + pko_command.s.segs = 1;
25390 + pko_command.s.total_bytes = skb->len;
25391 + pko_command.s.size0 = CVMX_FAU_OP_SIZE_32;
25392 + pko_command.s.subone0 = 1;
25393 +
25394 + pko_command.s.dontfree = 1;
25395 + pko_command.s.reg0 = priv->fau + qos * 4;
25396 + /*
25397 + * See if we can put this skb in the FPA pool. Any strange
25398 + * behavior from the Linux networking stack will most likely
25399 + * be caused by a bug in the following code. If some field is
25400 + * in use by the network stack and get carried over when a
25401 + * buffer is reused, bad thing may happen. If in doubt and
25402 + * you dont need the absolute best performance, disable the
25403 + * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has
25404 + * shown a 25% increase in performance under some loads.
25405 + */
25406 +#if REUSE_SKBUFFS_WITHOUT_FREE
25407 + fpa_head = skb->head + 128 - ((unsigned long)skb->head & 0x7f);
25408 + if (unlikely(skb->data < fpa_head)) {
25409 + /*
25410 + * printk("TX buffer beginning can't meet FPA
25411 + * alignment constraints\n");
25412 + */
25413 + goto dont_put_skbuff_in_hw;
25414 + }
25415 + if (unlikely
25416 + ((skb_end_pointer(skb) - fpa_head) < CVMX_FPA_PACKET_POOL_SIZE)) {
25417 + /*
25418 + printk("TX buffer isn't large enough for the FPA\n");
25419 + */
25420 + goto dont_put_skbuff_in_hw;
25421 + }
25422 + if (unlikely(skb_shared(skb))) {
25423 + /*
25424 + printk("TX buffer sharing data with someone else\n");
25425 + */
25426 + goto dont_put_skbuff_in_hw;
25427 + }
25428 + if (unlikely(skb_cloned(skb))) {
25429 + /*
25430 + printk("TX buffer has been cloned\n");
25431 + */
25432 + goto dont_put_skbuff_in_hw;
25433 + }
25434 + if (unlikely(skb_header_cloned(skb))) {
25435 + /*
25436 + printk("TX buffer header has been cloned\n");
25437 + */
25438 + goto dont_put_skbuff_in_hw;
25439 + }
25440 + if (unlikely(skb->destructor)) {
25441 + /*
25442 + printk("TX buffer has a destructor\n");
25443 + */
25444 + goto dont_put_skbuff_in_hw;
25445 + }
25446 + if (unlikely(skb_shinfo(skb)->nr_frags)) {
25447 + /*
25448 + printk("TX buffer has fragments\n");
25449 + */
25450 + goto dont_put_skbuff_in_hw;
25451 + }
25452 + if (unlikely
25453 + (skb->truesize !=
25454 + sizeof(*skb) + skb_end_pointer(skb) - skb->head)) {
25455 + /*
25456 + printk("TX buffer truesize has been changed\n");
25457 + */
25458 + goto dont_put_skbuff_in_hw;
25459 + }
25460 +
25461 + /*
25462 + * We can use this buffer in the FPA. We don't need the FAU
25463 + * update anymore
25464 + */
25465 + pko_command.s.reg0 = 0;
25466 + pko_command.s.dontfree = 0;
25467 +
25468 + hw_buffer.s.back = (skb->data - fpa_head) >> 7;
25469 + *(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
25470 +
25471 + /*
25472 + * The skbuff will be reused without ever being freed. We must
25473 + * cleanup a bunch of Linux stuff.
25474 + */
25475 + dst_release(skb->dst);
25476 + skb->dst = NULL;
25477 +#ifdef CONFIG_XFRM
25478 + secpath_put(skb->sp);
25479 + skb->sp = NULL;
25480 +#endif
25481 + nf_reset(skb);
25482 +
25483 +#ifdef CONFIG_NET_SCHED
25484 + skb->tc_index = 0;
25485 +#ifdef CONFIG_NET_CLS_ACT
25486 + skb->tc_verd = 0;
25487 +#endif /* CONFIG_NET_CLS_ACT */
25488 +#endif /* CONFIG_NET_SCHED */
25489 +
25490 +dont_put_skbuff_in_hw:
25491 +#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
25492 +
25493 + /* Check if we can use the hardware checksumming */
25494 + if (USE_HW_TCPUDP_CHECKSUM && (skb->protocol == htons(ETH_P_IP)) &&
25495 + (ip_hdr(skb)->version == 4) && (ip_hdr(skb)->ihl == 5) &&
25496 + ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == 1 << 14))
25497 + && ((ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
25498 + || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP))) {
25499 + /* Use hardware checksum calc */
25500 + pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
25501 + }
25502 +
25503 + if (USE_ASYNC_IOBDMA) {
25504 + /* Get the number of skbuffs in use by the hardware */
25505 + CVMX_SYNCIOBDMA;
25506 + in_use = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
25507 + buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
25508 + } else {
25509 + /* Get the number of skbuffs in use by the hardware */
25510 + in_use = cvmx_fau_fetch_and_add32(priv->fau + qos * 4, 1);
25511 + buffers_to_free =
25512 + cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
25513 + }
25514 +
25515 + /*
25516 + * If we're sending faster than the receive can free them then
25517 + * don't do the HW free.
25518 + */
25519 + if ((buffers_to_free < -100) && !pko_command.s.dontfree) {
25520 + pko_command.s.dontfree = 1;
25521 + pko_command.s.reg0 = priv->fau + qos * 4;
25522 + }
25523 +
25524 + cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
25525 + CVMX_PKO_LOCK_CMD_QUEUE);
25526 +
25527 + /* Drop this packet if we have too many already queued to the HW */
25528 + if (unlikely
25529 + (skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) {
25530 + /*
25531 + DEBUGPRINT("%s: Tx dropped. Too many queued\n", dev->name);
25532 + */
25533 + dropped = 1;
25534 + }
25535 + /* Send the packet to the output queue */
25536 + else if (unlikely
25537 + (cvmx_pko_send_packet_finish
25538 + (priv->port, priv->queue + qos, pko_command, hw_buffer,
25539 + CVMX_PKO_LOCK_CMD_QUEUE))) {
25540 + DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
25541 + dropped = 1;
25542 + }
25543 +
25544 + if (USE_ASYNC_IOBDMA) {
25545 + /* Restore the scratch area */
25546 + cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
25547 + cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2);
25548 + }
25549 +
25550 + if (unlikely(dropped)) {
25551 + dev_kfree_skb_any(skb);
25552 + cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
25553 + priv->stats.tx_dropped++;
25554 + } else {
25555 + if (USE_SKBUFFS_IN_HW) {
25556 + /* Put this packet on the queue to be freed later */
25557 + if (pko_command.s.dontfree)
25558 + skb_queue_tail(&priv->tx_free_list[qos], skb);
25559 + else {
25560 + cvmx_fau_atomic_add32
25561 + (FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
25562 + cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
25563 + }
25564 + } else {
25565 + /* Put this packet on the queue to be freed later */
25566 + skb_queue_tail(&priv->tx_free_list[qos], skb);
25567 + }
25568 + }
25569 +
25570 + /* Free skbuffs not in use by the hardware, possibly two at a time */
25571 + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) {
25572 + spin_lock(&priv->tx_free_list[qos].lock);
25573 + /*
25574 + * Check again now that we have the lock. It might
25575 + * have changed.
25576 + */
25577 + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use)
25578 + dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
25579 + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use)
25580 + dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
25581 + spin_unlock(&priv->tx_free_list[qos].lock);
25582 + }
25583 +
25584 + return 0;
25585 +}
25586 +
25587 +/**
25588 + * Packet transmit to the POW
25589 + *
25590 + * @skb: Packet to send
25591 + * @dev: Device info structure
25592 + * Returns Always returns zero
25593 + */
25594 +int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
25595 +{
25596 + struct octeon_ethernet *priv = netdev_priv(dev);
25597 + void *packet_buffer;
25598 + void *copy_location;
25599 +
25600 + /* Get a work queue entry */
25601 + cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL);
25602 + if (unlikely(work == NULL)) {
25603 + DEBUGPRINT("%s: Failed to allocate a work queue entry\n",
25604 + dev->name);
25605 + priv->stats.tx_dropped++;
25606 + dev_kfree_skb(skb);
25607 + return 0;
25608 + }
25609 +
25610 + /* Get a packet buffer */
25611 + packet_buffer = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL);
25612 + if (unlikely(packet_buffer == NULL)) {
25613 + DEBUGPRINT("%s: Failed to allocate a packet buffer\n",
25614 + dev->name);
25615 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
25616 + priv->stats.tx_dropped++;
25617 + dev_kfree_skb(skb);
25618 + return 0;
25619 + }
25620 +
25621 + /*
25622 + * Calculate where we need to copy the data to. We need to
25623 + * leave 8 bytes for a next pointer (unused). We also need to
25624 + * include any configure skip. Then we need to align the IP
25625 + * packet src and dest into the same 64bit word. The below
25626 + * calculation may add a little extra, but that doesn't
25627 + * hurt.
25628 + */
25629 + copy_location = packet_buffer + sizeof(uint64_t);
25630 + copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6;
25631 +
25632 + /*
25633 + * We have to copy the packet since whoever processes this
25634 + * packet will free it to a hardware pool. We can't use the
25635 + * trick of counting outstanding packets like in
25636 + * cvm_oct_xmit.
25637 + */
25638 + memcpy(copy_location, skb->data, skb->len);
25639 +
25640 + /*
25641 + * Fill in some of the work queue fields. We may need to add
25642 + * more if the software at the other end needs them.
25643 + */
25644 + work->hw_chksum = skb->csum;
25645 + work->len = skb->len;
25646 + work->ipprt = priv->port;
25647 + work->qos = priv->port & 0x7;
25648 + work->grp = pow_send_group;
25649 + work->tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
25650 + work->tag = pow_send_group; /* FIXME */
25651 + /* Default to zero. Sets of zero later are commented out */
25652 + work->word2.u64 = 0;
25653 + work->word2.s.bufs = 1;
25654 + work->packet_ptr.u64 = 0;
25655 + work->packet_ptr.s.addr = cvmx_ptr_to_phys(copy_location);
25656 + work->packet_ptr.s.pool = CVMX_FPA_PACKET_POOL;
25657 + work->packet_ptr.s.size = CVMX_FPA_PACKET_POOL_SIZE;
25658 + work->packet_ptr.s.back = (copy_location - packet_buffer) >> 7;
25659 +
25660 + if (skb->protocol == htons(ETH_P_IP)) {
25661 + work->word2.s.ip_offset = 14;
25662 +#if 0
25663 + work->word2.s.vlan_valid = 0; /* FIXME */
25664 + work->word2.s.vlan_cfi = 0; /* FIXME */
25665 + work->word2.s.vlan_id = 0; /* FIXME */
25666 + work->word2.s.dec_ipcomp = 0; /* FIXME */
25667 +#endif
25668 + work->word2.s.tcp_or_udp =
25669 + (ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
25670 + || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP);
25671 +#if 0
25672 + /* FIXME */
25673 + work->word2.s.dec_ipsec = 0;
25674 + /* We only support IPv4 right now */
25675 + work->word2.s.is_v6 = 0;
25676 + /* Hardware would set to zero */
25677 + work->word2.s.software = 0;
25678 + /* No error, packet is internal */
25679 + work->word2.s.L4_error = 0;
25680 +#endif
25681 + work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0)
25682 + || (ip_hdr(skb)->frag_off ==
25683 + 1 << 14));
25684 +#if 0
25685 + /* Assume Linux is sending a good packet */
25686 + work->word2.s.IP_exc = 0;
25687 +#endif
25688 + work->word2.s.is_bcast = (skb->pkt_type == PACKET_BROADCAST);
25689 + work->word2.s.is_mcast = (skb->pkt_type == PACKET_MULTICAST);
25690 +#if 0
25691 + /* This is an IP packet */
25692 + work->word2.s.not_IP = 0;
25693 + /* No error, packet is internal */
25694 + work->word2.s.rcv_error = 0;
25695 + /* No error, packet is internal */
25696 + work->word2.s.err_code = 0;
25697 +#endif
25698 +
25699 + /*
25700 + * When copying the data, include 4 bytes of the
25701 + * ethernet header to align the same way hardware
25702 + * does.
25703 + */
25704 + memcpy(work->packet_data, skb->data + 10,
25705 + sizeof(work->packet_data));
25706 + } else {
25707 +#if 0
25708 + work->word2.snoip.vlan_valid = 0; /* FIXME */
25709 + work->word2.snoip.vlan_cfi = 0; /* FIXME */
25710 + work->word2.snoip.vlan_id = 0; /* FIXME */
25711 + work->word2.snoip.software = 0; /* Hardware would set to zero */
25712 +#endif
25713 + work->word2.snoip.is_rarp = skb->protocol == htons(ETH_P_RARP);
25714 + work->word2.snoip.is_arp = skb->protocol == htons(ETH_P_ARP);
25715 + work->word2.snoip.is_bcast =
25716 + (skb->pkt_type == PACKET_BROADCAST);
25717 + work->word2.snoip.is_mcast =
25718 + (skb->pkt_type == PACKET_MULTICAST);
25719 + work->word2.snoip.not_IP = 1; /* IP was done up above */
25720 +#if 0
25721 + /* No error, packet is internal */
25722 + work->word2.snoip.rcv_error = 0;
25723 + /* No error, packet is internal */
25724 + work->word2.snoip.err_code = 0;
25725 +#endif
25726 + memcpy(work->packet_data, skb->data, sizeof(work->packet_data));
25727 + }
25728 +
25729 + /* Submit the packet to the POW */
25730 + cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos,
25731 + work->grp);
25732 + priv->stats.tx_packets++;
25733 + priv->stats.tx_bytes += skb->len;
25734 + dev_kfree_skb(skb);
25735 + return 0;
25736 +}
25737 +
25738 +/**
25739 + * Transmit a work queue entry out of the ethernet port. Both
25740 + * the work queue entry and the packet data can optionally be
25741 + * freed. The work will be freed on error as well.
25742 + *
25743 + * @dev: Device to transmit out.
25744 + * @work_queue_entry:
25745 + * Work queue entry to send
25746 + * @do_free: True if the work queue entry and packet data should be
25747 + * freed. If false, neither will be freed.
25748 + * @qos: Index into the queues for this port to transmit on. This
25749 + * is used to implement QoS if their are multiple queues per
25750 + * port. This parameter must be between 0 and the number of
25751 + * queues per port minus 1. Values outside of this range will
25752 + * be change to zero.
25753 + *
25754 + * Returns Zero on success, negative on failure.
25755 + */
25756 +int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
25757 + int do_free, int qos)
25758 +{
25759 + unsigned long flags;
25760 + union cvmx_buf_ptr hw_buffer;
25761 + cvmx_pko_command_word0_t pko_command;
25762 + int dropped;
25763 + struct octeon_ethernet *priv = netdev_priv(dev);
25764 + cvmx_wqe_t *work = work_queue_entry;
25765 +
25766 + if (!(dev->flags & IFF_UP)) {
25767 + DEBUGPRINT("%s: Device not up\n", dev->name);
25768 + if (do_free)
25769 + cvm_oct_free_work(work);
25770 + return -1;
25771 + }
25772 +
25773 + /* The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to completely
25774 + remove "qos" in the event neither interface supports
25775 + multiple queues per port */
25776 + if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
25777 + (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
25778 + if (qos <= 0)
25779 + qos = 0;
25780 + else if (qos >= cvmx_pko_get_num_queues(priv->port))
25781 + qos = 0;
25782 + } else
25783 + qos = 0;
25784 +
25785 + /* Start off assuming no drop */
25786 + dropped = 0;
25787 +
25788 + local_irq_save(flags);
25789 + cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
25790 + CVMX_PKO_LOCK_CMD_QUEUE);
25791 +
25792 + /* Build the PKO buffer pointer */
25793 + hw_buffer.u64 = 0;
25794 + hw_buffer.s.addr = work->packet_ptr.s.addr;
25795 + hw_buffer.s.pool = CVMX_FPA_PACKET_POOL;
25796 + hw_buffer.s.size = CVMX_FPA_PACKET_POOL_SIZE;
25797 + hw_buffer.s.back = work->packet_ptr.s.back;
25798 +
25799 + /* Build the PKO command */
25800 + pko_command.u64 = 0;
25801 + pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */
25802 + pko_command.s.dontfree = !do_free;
25803 + pko_command.s.segs = work->word2.s.bufs;
25804 + pko_command.s.total_bytes = work->len;
25805 +
25806 + /* Check if we can use the hardware checksumming */
25807 + if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc))
25808 + pko_command.s.ipoffp1 = 0;
25809 + else
25810 + pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
25811 +
25812 + /* Send the packet to the output queue */
25813 + if (unlikely
25814 + (cvmx_pko_send_packet_finish
25815 + (priv->port, priv->queue + qos, pko_command, hw_buffer,
25816 + CVMX_PKO_LOCK_CMD_QUEUE))) {
25817 + DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
25818 + dropped = -1;
25819 + }
25820 + local_irq_restore(flags);
25821 +
25822 + if (unlikely(dropped)) {
25823 + if (do_free)
25824 + cvm_oct_free_work(work);
25825 + priv->stats.tx_dropped++;
25826 + } else if (do_free)
25827 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
25828 +
25829 + return dropped;
25830 +}
25831 +EXPORT_SYMBOL(cvm_oct_transmit_qos);
25832 +
25833 +/**
25834 + * This function frees all skb that are currenty queued for TX.
25835 + *
25836 + * @dev: Device being shutdown
25837 + */
25838 +void cvm_oct_tx_shutdown(struct net_device *dev)
25839 +{
25840 + struct octeon_ethernet *priv = netdev_priv(dev);
25841 + unsigned long flags;
25842 + int qos;
25843 +
25844 + for (qos = 0; qos < 16; qos++) {
25845 + spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
25846 + while (skb_queue_len(&priv->tx_free_list[qos]))
25847 + dev_kfree_skb_any(__skb_dequeue
25848 + (&priv->tx_free_list[qos]));
25849 + spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
25850 + }
25851 +}
25852 diff --git a/drivers/staging/octeon/ethernet-tx.h b/drivers/staging/octeon/ethernet-tx.h
25853 new file mode 100644
25854 index 0000000..5106236
25855 --- /dev/null
25856 +++ b/drivers/staging/octeon/ethernet-tx.h
25857 @@ -0,0 +1,32 @@
25858 +/*********************************************************************
25859 + * Author: Cavium Networks
25860 + *
25861 + * Contact: support@caviumnetworks.com
25862 + * This file is part of the OCTEON SDK
25863 + *
25864 + * Copyright (c) 2003-2007 Cavium Networks
25865 + *
25866 + * This file is free software; you can redistribute it and/or modify
25867 + * it under the terms of the GNU General Public License, Version 2, as
25868 + * published by the Free Software Foundation.
25869 + *
25870 + * This file is distributed in the hope that it will be useful, but
25871 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25872 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25873 + * NONINFRINGEMENT. See the GNU General Public License for more
25874 + * details.
25875 + *
25876 + * You should have received a copy of the GNU General Public License
25877 + * along with this file; if not, write to the Free Software
25878 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25879 + * or visit http://www.gnu.org/licenses/.
25880 + *
25881 + * This file may also be available under a different license from Cavium.
25882 + * Contact Cavium Networks for more information
25883 +*********************************************************************/
25884 +
25885 +int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev);
25886 +int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev);
25887 +int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
25888 + int do_free, int qos);
25889 +void cvm_oct_tx_shutdown(struct net_device *dev);
25890 diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h
25891 new file mode 100644
25892 index 0000000..37b6659
25893 --- /dev/null
25894 +++ b/drivers/staging/octeon/ethernet-util.h
25895 @@ -0,0 +1,81 @@
25896 +/**********************************************************************
25897 + * Author: Cavium Networks
25898 + *
25899 + * Contact: support@caviumnetworks.com
25900 + * This file is part of the OCTEON SDK
25901 + *
25902 + * Copyright (c) 2003-2007 Cavium Networks
25903 + *
25904 + * This file is free software; you can redistribute it and/or modify
25905 + * it under the terms of the GNU General Public License, Version 2, as
25906 + * published by the Free Software Foundation.
25907 + *
25908 + * This file is distributed in the hope that it will be useful, but
25909 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25910 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25911 + * NONINFRINGEMENT. See the GNU General Public License for more
25912 + * details.
25913 + *
25914 + * You should have received a copy of the GNU General Public License
25915 + * along with this file; if not, write to the Free Software
25916 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25917 + * or visit http://www.gnu.org/licenses/.
25918 + *
25919 + * This file may also be available under a different license from Cavium.
25920 + * Contact Cavium Networks for more information
25921 +*********************************************************************/
25922 +
25923 +#define DEBUGPRINT(format, ...) do { if (printk_ratelimit()) \
25924 + printk(format, ##__VA_ARGS__); \
25925 + } while (0)
25926 +
25927 +/**
25928 + * Given a packet data address, return a pointer to the
25929 + * beginning of the packet buffer.
25930 + *
25931 + * @packet_ptr: Packet data hardware address
25932 + * Returns Packet buffer pointer
25933 + */
25934 +static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr)
25935 +{
25936 + return cvmx_phys_to_ptr(((packet_ptr.s.addr >> 7) - packet_ptr.s.back)
25937 + << 7);
25938 +}
25939 +
25940 +/**
25941 + * Given an IPD/PKO port number, return the logical interface it is
25942 + * on.
25943 + *
25944 + * @ipd_port: Port to check
25945 + *
25946 + * Returns Logical interface
25947 + */
25948 +static inline int INTERFACE(int ipd_port)
25949 +{
25950 + if (ipd_port < 32) /* Interface 0 or 1 for RGMII,GMII,SPI, etc */
25951 + return ipd_port >> 4;
25952 + else if (ipd_port < 36) /* Interface 2 for NPI */
25953 + return 2;
25954 + else if (ipd_port < 40) /* Interface 3 for loopback */
25955 + return 3;
25956 + else if (ipd_port == 40) /* Non existant interface for POW0 */
25957 + return 4;
25958 + else
25959 + panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);
25960 +}
25961 +
25962 +/**
25963 + * Given an IPD/PKO port number, return the port's index on a
25964 + * logical interface.
25965 + *
25966 + * @ipd_port: Port to check
25967 + *
25968 + * Returns Index into interface port list
25969 + */
25970 +static inline int INDEX(int ipd_port)
25971 +{
25972 + if (ipd_port < 32)
25973 + return ipd_port & 15;
25974 + else
25975 + return ipd_port & 3;
25976 +}
25977 diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c
25978 new file mode 100644
25979 index 0000000..f08eb32
25980 --- /dev/null
25981 +++ b/drivers/staging/octeon/ethernet-xaui.c
25982 @@ -0,0 +1,127 @@
25983 +/**********************************************************************
25984 + * Author: Cavium Networks
25985 + *
25986 + * Contact: support@caviumnetworks.com
25987 + * This file is part of the OCTEON SDK
25988 + *
25989 + * Copyright (c) 2003-2007 Cavium Networks
25990 + *
25991 + * This file is free software; you can redistribute it and/or modify
25992 + * it under the terms of the GNU General Public License, Version 2, as
25993 + * published by the Free Software Foundation.
25994 + *
25995 + * This file is distributed in the hope that it will be useful, but
25996 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
25997 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
25998 + * NONINFRINGEMENT. See the GNU General Public License for more
25999 + * details.
26000 + *
26001 + * You should have received a copy of the GNU General Public License
26002 + * along with this file; if not, write to the Free Software
26003 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26004 + * or visit http://www.gnu.org/licenses/.
26005 + *
26006 + * This file may also be available under a different license from Cavium.
26007 + * Contact Cavium Networks for more information
26008 +**********************************************************************/
26009 +#include <linux/kernel.h>
26010 +#include <linux/netdevice.h>
26011 +#include <linux/mii.h>
26012 +#include <net/dst.h>
26013 +
26014 +#include <asm/octeon/octeon.h>
26015 +
26016 +#include "ethernet-defines.h"
26017 +#include "octeon-ethernet.h"
26018 +#include "ethernet-common.h"
26019 +#include "ethernet-util.h"
26020 +
26021 +#include "cvmx-helper.h"
26022 +
26023 +#include "cvmx-gmxx-defs.h"
26024 +
26025 +static int cvm_oct_xaui_open(struct net_device *dev)
26026 +{
26027 + union cvmx_gmxx_prtx_cfg gmx_cfg;
26028 + struct octeon_ethernet *priv = netdev_priv(dev);
26029 + int interface = INTERFACE(priv->port);
26030 + int index = INDEX(priv->port);
26031 + cvmx_helper_link_info_t link_info;
26032 +
26033 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
26034 + gmx_cfg.s.en = 1;
26035 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
26036 +
26037 + if (!octeon_is_simulation()) {
26038 + link_info = cvmx_helper_link_get(priv->port);
26039 + if (!link_info.s.link_up)
26040 + netif_carrier_off(dev);
26041 + }
26042 + return 0;
26043 +}
26044 +
26045 +static int cvm_oct_xaui_stop(struct net_device *dev)
26046 +{
26047 + union cvmx_gmxx_prtx_cfg gmx_cfg;
26048 + struct octeon_ethernet *priv = netdev_priv(dev);
26049 + int interface = INTERFACE(priv->port);
26050 + int index = INDEX(priv->port);
26051 +
26052 + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
26053 + gmx_cfg.s.en = 0;
26054 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
26055 + return 0;
26056 +}
26057 +
26058 +static void cvm_oct_xaui_poll(struct net_device *dev)
26059 +{
26060 + struct octeon_ethernet *priv = netdev_priv(dev);
26061 + cvmx_helper_link_info_t link_info;
26062 +
26063 + link_info = cvmx_helper_link_get(priv->port);
26064 + if (link_info.u64 == priv->link_info)
26065 + return;
26066 +
26067 + link_info = cvmx_helper_link_autoconf(priv->port);
26068 + priv->link_info = link_info.u64;
26069 +
26070 + /* Tell Linux */
26071 + if (link_info.s.link_up) {
26072 +
26073 + if (!netif_carrier_ok(dev))
26074 + netif_carrier_on(dev);
26075 + if (priv->queue != -1)
26076 + DEBUGPRINT
26077 + ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
26078 + dev->name, link_info.s.speed,
26079 + (link_info.s.full_duplex) ? "Full" : "Half",
26080 + priv->port, priv->queue);
26081 + else
26082 + DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
26083 + dev->name, link_info.s.speed,
26084 + (link_info.s.full_duplex) ? "Full" : "Half",
26085 + priv->port);
26086 + } else {
26087 + if (netif_carrier_ok(dev))
26088 + netif_carrier_off(dev);
26089 + DEBUGPRINT("%s: Link down\n", dev->name);
26090 + }
26091 +}
26092 +
26093 +int cvm_oct_xaui_init(struct net_device *dev)
26094 +{
26095 + struct octeon_ethernet *priv = netdev_priv(dev);
26096 + cvm_oct_common_init(dev);
26097 + dev->open = cvm_oct_xaui_open;
26098 + dev->stop = cvm_oct_xaui_stop;
26099 + dev->stop(dev);
26100 + if (!octeon_is_simulation())
26101 + priv->poll = cvm_oct_xaui_poll;
26102 +
26103 + return 0;
26104 +}
26105 +
26106 +void cvm_oct_xaui_uninit(struct net_device *dev)
26107 +{
26108 + cvm_oct_common_uninit(dev);
26109 +}
26110 diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
26111 new file mode 100644
26112 index 0000000..e8ef9e0
26113 --- /dev/null
26114 +++ b/drivers/staging/octeon/ethernet.c
26115 @@ -0,0 +1,507 @@
26116 +/**********************************************************************
26117 + * Author: Cavium Networks
26118 + *
26119 + * Contact: support@caviumnetworks.com
26120 + * This file is part of the OCTEON SDK
26121 + *
26122 + * Copyright (c) 2003-2007 Cavium Networks
26123 + *
26124 + * This file is free software; you can redistribute it and/or modify
26125 + * it under the terms of the GNU General Public License, Version 2, as
26126 + * published by the Free Software Foundation.
26127 + *
26128 + * This file is distributed in the hope that it will be useful, but
26129 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
26130 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
26131 + * NONINFRINGEMENT. See the GNU General Public License for more
26132 + * details.
26133 + *
26134 + * You should have received a copy of the GNU General Public License
26135 + * along with this file; if not, write to the Free Software
26136 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26137 + * or visit http://www.gnu.org/licenses/.
26138 + *
26139 + * This file may also be available under a different license from Cavium.
26140 + * Contact Cavium Networks for more information
26141 +**********************************************************************/
26142 +#include <linux/kernel.h>
26143 +#include <linux/init.h>
26144 +#include <linux/module.h>
26145 +#include <linux/netdevice.h>
26146 +#include <linux/etherdevice.h>
26147 +#include <linux/delay.h>
26148 +#include <linux/mii.h>
26149 +
26150 +#include <net/dst.h>
26151 +
26152 +#include <asm/octeon/octeon.h>
26153 +
26154 +#include "ethernet-defines.h"
26155 +#include "ethernet-mem.h"
26156 +#include "ethernet-rx.h"
26157 +#include "ethernet-tx.h"
26158 +#include "ethernet-util.h"
26159 +#include "ethernet-proc.h"
26160 +#include "ethernet-common.h"
26161 +#include "octeon-ethernet.h"
26162 +
26163 +#include "cvmx-pip.h"
26164 +#include "cvmx-pko.h"
26165 +#include "cvmx-fau.h"
26166 +#include "cvmx-ipd.h"
26167 +#include "cvmx-helper.h"
26168 +
26169 +#include "cvmx-smix-defs.h"
26170 +
26171 +#if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \
26172 + && CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
26173 +int num_packet_buffers = CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS;
26174 +#else
26175 +int num_packet_buffers = 1024;
26176 +#endif
26177 +module_param(num_packet_buffers, int, 0444);
26178 +MODULE_PARM_DESC(num_packet_buffers, "\n"
26179 + "\tNumber of packet buffers to allocate and store in the\n"
26180 + "\tFPA. By default, 1024 packet buffers are used unless\n"
26181 + "\tCONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS is defined.");
26182 +
26183 +int pow_receive_group = 15;
26184 +module_param(pow_receive_group, int, 0444);
26185 +MODULE_PARM_DESC(pow_receive_group, "\n"
26186 + "\tPOW group to receive packets from. All ethernet hardware\n"
26187 + "\twill be configured to send incomming packets to this POW\n"
26188 + "\tgroup. Also any other software can submit packets to this\n"
26189 + "\tgroup for the kernel to process.");
26190 +
26191 +int pow_send_group = -1;
26192 +module_param(pow_send_group, int, 0644);
26193 +MODULE_PARM_DESC(pow_send_group, "\n"
26194 + "\tPOW group to send packets to other software on. This\n"
26195 + "\tcontrols the creation of the virtual device pow0.\n"
26196 + "\talways_use_pow also depends on this value.");
26197 +
26198 +int always_use_pow;
26199 +module_param(always_use_pow, int, 0444);
26200 +MODULE_PARM_DESC(always_use_pow, "\n"
26201 + "\tWhen set, always send to the pow group. This will cause\n"
26202 + "\tpackets sent to real ethernet devices to be sent to the\n"
26203 + "\tPOW group instead of the hardware. Unless some other\n"
26204 + "\tapplication changes the config, packets will still be\n"
26205 + "\treceived from the low level hardware. Use this option\n"
26206 + "\tto allow a CVMX app to intercept all packets from the\n"
26207 + "\tlinux kernel. You must specify pow_send_group along with\n"
26208 + "\tthis option.");
26209 +
26210 +char pow_send_list[128] = "";
26211 +module_param_string(pow_send_list, pow_send_list, sizeof(pow_send_list), 0444);
26212 +MODULE_PARM_DESC(pow_send_list, "\n"
26213 + "\tComma separated list of ethernet devices that should use the\n"
26214 + "\tPOW for transmit instead of the actual ethernet hardware. This\n"
26215 + "\tis a per port version of always_use_pow. always_use_pow takes\n"
26216 + "\tprecedence over this list. For example, setting this to\n"
26217 + "\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n"
26218 + "\tusing the pow_send_group.");
26219 +
26220 +static int disable_core_queueing = 1;
26221 +module_param(disable_core_queueing, int, 0444);
26222 +MODULE_PARM_DESC(disable_core_queueing, "\n"
26223 + "\tWhen set the networking core's tx_queue_len is set to zero. This\n"
26224 + "\tallows packets to be sent without lock contention in the packet\n"
26225 + "\tscheduler resulting in some cases in improved throughput.\n");
26226 +
26227 +/**
26228 + * Periodic timer to check auto negotiation
26229 + */
26230 +static struct timer_list cvm_oct_poll_timer;
26231 +
26232 +/**
26233 + * Array of every ethernet device owned by this driver indexed by
26234 + * the ipd input port number.
26235 + */
26236 +struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
26237 +
26238 +extern struct semaphore mdio_sem;
26239 +
26240 +/**
26241 + * Periodic timer tick for slow management operations
26242 + *
26243 + * @arg: Device to check
26244 + */
26245 +static void cvm_do_timer(unsigned long arg)
26246 +{
26247 + static int port;
26248 + if (port < CVMX_PIP_NUM_INPUT_PORTS) {
26249 + if (cvm_oct_device[port]) {
26250 + int queues_per_port;
26251 + int qos;
26252 + struct octeon_ethernet *priv =
26253 + netdev_priv(cvm_oct_device[port]);
26254 + if (priv->poll) {
26255 + /* skip polling if we don't get the lock */
26256 + if (!down_trylock(&mdio_sem)) {
26257 + priv->poll(cvm_oct_device[port]);
26258 + up(&mdio_sem);
26259 + }
26260 + }
26261 +
26262 + queues_per_port = cvmx_pko_get_num_queues(port);
26263 + /* Drain any pending packets in the free list */
26264 + for (qos = 0; qos < queues_per_port; qos++) {
26265 + if (skb_queue_len(&priv->tx_free_list[qos])) {
26266 + spin_lock(&priv->tx_free_list[qos].
26267 + lock);
26268 + while (skb_queue_len
26269 + (&priv->tx_free_list[qos]) >
26270 + cvmx_fau_fetch_and_add32(priv->
26271 + fau +
26272 + qos * 4,
26273 + 0))
26274 + dev_kfree_skb(__skb_dequeue
26275 + (&priv->
26276 + tx_free_list
26277 + [qos]));
26278 + spin_unlock(&priv->tx_free_list[qos].
26279 + lock);
26280 + }
26281 + }
26282 + cvm_oct_device[port]->get_stats(cvm_oct_device[port]);
26283 + }
26284 + port++;
26285 + /* Poll the next port in a 50th of a second.
26286 + This spreads the polling of ports out a little bit */
26287 + mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50);
26288 + } else {
26289 + port = 0;
26290 + /* All ports have been polled. Start the next iteration through
26291 + the ports in one second */
26292 + mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
26293 + }
26294 +}
26295 +
26296 +/**
26297 + * Configure common hardware for all interfaces
26298 + */
26299 +static __init void cvm_oct_configure_common_hw(void)
26300 +{
26301 + int r;
26302 + /* Setup the FPA */
26303 + cvmx_fpa_enable();
26304 + cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
26305 + num_packet_buffers);
26306 + cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
26307 + num_packet_buffers);
26308 + if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
26309 + cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
26310 + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
26311 +
26312 + if (USE_RED)
26313 + cvmx_helper_setup_red(num_packet_buffers / 4,
26314 + num_packet_buffers / 8);
26315 +
26316 + /* Enable the MII interface */
26317 + if (!octeon_is_simulation())
26318 + cvmx_write_csr(CVMX_SMIX_EN(0), 1);
26319 +
26320 + /* Register an IRQ hander for to receive POW interrupts */
26321 + r = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
26322 + cvm_oct_do_interrupt, IRQF_SHARED, "Ethernet",
26323 + cvm_oct_device);
26324 +
26325 +#if defined(CONFIG_SMP) && 0
26326 + if (USE_MULTICORE_RECEIVE) {
26327 + irq_set_affinity(OCTEON_IRQ_WORKQ0 + pow_receive_group,
26328 + cpu_online_mask);
26329 + }
26330 +#endif
26331 +}
26332 +
26333 +/**
26334 + * Free a work queue entry received in a intercept callback.
26335 + *
26336 + * @work_queue_entry:
26337 + * Work queue entry to free
26338 + * Returns Zero on success, Negative on failure.
26339 + */
26340 +int cvm_oct_free_work(void *work_queue_entry)
26341 +{
26342 + cvmx_wqe_t *work = work_queue_entry;
26343 +
26344 + int segments = work->word2.s.bufs;
26345 + union cvmx_buf_ptr segment_ptr = work->packet_ptr;
26346 +
26347 + while (segments--) {
26348 + union cvmx_buf_ptr next_ptr = *(union cvmx_buf_ptr *)
26349 + cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
26350 + if (unlikely(!segment_ptr.s.i))
26351 + cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr),
26352 + segment_ptr.s.pool,
26353 + DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE /
26354 + 128));
26355 + segment_ptr = next_ptr;
26356 + }
26357 + cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
26358 +
26359 + return 0;
26360 +}
26361 +EXPORT_SYMBOL(cvm_oct_free_work);
26362 +
26363 +/**
26364 + * Module/ driver initialization. Creates the linux network
26365 + * devices.
26366 + *
26367 + * Returns Zero on success
26368 + */
26369 +static int __init cvm_oct_init_module(void)
26370 +{
26371 + int num_interfaces;
26372 + int interface;
26373 + int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
26374 + int qos;
26375 +
26376 + pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
26377 +
26378 + cvm_oct_proc_initialize();
26379 + cvm_oct_rx_initialize();
26380 + cvm_oct_configure_common_hw();
26381 +
26382 + cvmx_helper_initialize_packet_io_global();
26383 +
26384 + /* Change the input group for all ports before input is enabled */
26385 + num_interfaces = cvmx_helper_get_number_of_interfaces();
26386 + for (interface = 0; interface < num_interfaces; interface++) {
26387 + int num_ports = cvmx_helper_ports_on_interface(interface);
26388 + int port;
26389 +
26390 + for (port = cvmx_helper_get_ipd_port(interface, 0);
26391 + port < cvmx_helper_get_ipd_port(interface, num_ports);
26392 + port++) {
26393 + union cvmx_pip_prt_tagx pip_prt_tagx;
26394 + pip_prt_tagx.u64 =
26395 + cvmx_read_csr(CVMX_PIP_PRT_TAGX(port));
26396 + pip_prt_tagx.s.grp = pow_receive_group;
26397 + cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
26398 + pip_prt_tagx.u64);
26399 + }
26400 + }
26401 +
26402 + cvmx_helper_ipd_and_packet_input_enable();
26403 +
26404 + memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
26405 +
26406 + /*
26407 + * Initialize the FAU used for counting packet buffers that
26408 + * need to be freed.
26409 + */
26410 + cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
26411 +
26412 + if ((pow_send_group != -1)) {
26413 + struct net_device *dev;
26414 + pr_info("\tConfiguring device for POW only access\n");
26415 + dev = alloc_etherdev(sizeof(struct octeon_ethernet));
26416 + if (dev) {
26417 + /* Initialize the device private structure. */
26418 + struct octeon_ethernet *priv = netdev_priv(dev);
26419 + memset(priv, 0, sizeof(struct octeon_ethernet));
26420 +
26421 + dev->init = cvm_oct_common_init;
26422 + priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
26423 + priv->port = CVMX_PIP_NUM_INPUT_PORTS;
26424 + priv->queue = -1;
26425 + strcpy(dev->name, "pow%d");
26426 + for (qos = 0; qos < 16; qos++)
26427 + skb_queue_head_init(&priv->tx_free_list[qos]);
26428 +
26429 + if (register_netdev(dev) < 0) {
26430 + pr_err("Failed to register ethernet "
26431 + "device for POW\n");
26432 + kfree(dev);
26433 + } else {
26434 + cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
26435 + pr_info("%s: POW send group %d, receive "
26436 + "group %d\n",
26437 + dev->name, pow_send_group,
26438 + pow_receive_group);
26439 + }
26440 + } else {
26441 + pr_err("Failed to allocate ethernet device "
26442 + "for POW\n");
26443 + }
26444 + }
26445 +
26446 + num_interfaces = cvmx_helper_get_number_of_interfaces();
26447 + for (interface = 0; interface < num_interfaces; interface++) {
26448 + cvmx_helper_interface_mode_t imode =
26449 + cvmx_helper_interface_get_mode(interface);
26450 + int num_ports = cvmx_helper_ports_on_interface(interface);
26451 + int port;
26452 +
26453 + for (port = cvmx_helper_get_ipd_port(interface, 0);
26454 + port < cvmx_helper_get_ipd_port(interface, num_ports);
26455 + port++) {
26456 + struct octeon_ethernet *priv;
26457 + struct net_device *dev =
26458 + alloc_etherdev(sizeof(struct octeon_ethernet));
26459 + if (!dev) {
26460 + pr_err("Failed to allocate ethernet device "
26461 + "for port %d\n", port);
26462 + continue;
26463 + }
26464 + if (disable_core_queueing)
26465 + dev->tx_queue_len = 0;
26466 +
26467 + /* Initialize the device private structure. */
26468 + priv = netdev_priv(dev);
26469 + memset(priv, 0, sizeof(struct octeon_ethernet));
26470 +
26471 + priv->imode = imode;
26472 + priv->port = port;
26473 + priv->queue = cvmx_pko_get_base_queue(priv->port);
26474 + priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
26475 + for (qos = 0; qos < 16; qos++)
26476 + skb_queue_head_init(&priv->tx_free_list[qos]);
26477 + for (qos = 0; qos < cvmx_pko_get_num_queues(port);
26478 + qos++)
26479 + cvmx_fau_atomic_write32(priv->fau + qos * 4, 0);
26480 +
26481 + switch (priv->imode) {
26482 +
26483 + /* These types don't support ports to IPD/PKO */
26484 + case CVMX_HELPER_INTERFACE_MODE_DISABLED:
26485 + case CVMX_HELPER_INTERFACE_MODE_PCIE:
26486 + case CVMX_HELPER_INTERFACE_MODE_PICMG:
26487 + break;
26488 +
26489 + case CVMX_HELPER_INTERFACE_MODE_NPI:
26490 + dev->init = cvm_oct_common_init;
26491 + dev->uninit = cvm_oct_common_uninit;
26492 + strcpy(dev->name, "npi%d");
26493 + break;
26494 +
26495 + case CVMX_HELPER_INTERFACE_MODE_XAUI:
26496 + dev->init = cvm_oct_xaui_init;
26497 + dev->uninit = cvm_oct_xaui_uninit;
26498 + strcpy(dev->name, "xaui%d");
26499 + break;
26500 +
26501 + case CVMX_HELPER_INTERFACE_MODE_LOOP:
26502 + dev->init = cvm_oct_common_init;
26503 + dev->uninit = cvm_oct_common_uninit;
26504 + strcpy(dev->name, "loop%d");
26505 + break;
26506 +
26507 + case CVMX_HELPER_INTERFACE_MODE_SGMII:
26508 + dev->init = cvm_oct_sgmii_init;
26509 + dev->uninit = cvm_oct_sgmii_uninit;
26510 + strcpy(dev->name, "eth%d");
26511 + break;
26512 +
26513 + case CVMX_HELPER_INTERFACE_MODE_SPI:
26514 + dev->init = cvm_oct_spi_init;
26515 + dev->uninit = cvm_oct_spi_uninit;
26516 + strcpy(dev->name, "spi%d");
26517 + break;
26518 +
26519 + case CVMX_HELPER_INTERFACE_MODE_RGMII:
26520 + case CVMX_HELPER_INTERFACE_MODE_GMII:
26521 + dev->init = cvm_oct_rgmii_init;
26522 + dev->uninit = cvm_oct_rgmii_uninit;
26523 + strcpy(dev->name, "eth%d");
26524 + break;
26525 + }
26526 +
26527 + if (!dev->init) {
26528 + kfree(dev);
26529 + } else if (register_netdev(dev) < 0) {
26530 + pr_err("Failed to register ethernet device "
26531 + "for interface %d, port %d\n",
26532 + interface, priv->port);
26533 + kfree(dev);
26534 + } else {
26535 + cvm_oct_device[priv->port] = dev;
26536 + fau -=
26537 + cvmx_pko_get_num_queues(priv->port) *
26538 + sizeof(uint32_t);
26539 + }
26540 + }
26541 + }
26542 +
26543 + if (INTERRUPT_LIMIT) {
26544 + /*
26545 + * Set the POW timer rate to give an interrupt at most
26546 + * INTERRUPT_LIMIT times per second.
26547 + */
26548 + cvmx_write_csr(CVMX_POW_WQ_INT_PC,
26549 + octeon_bootinfo->eclock_hz / (INTERRUPT_LIMIT *
26550 + 16 * 256) << 8);
26551 +
26552 + /*
26553 + * Enable POW timer interrupt. It will count when
26554 + * there are packets available.
26555 + */
26556 + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
26557 + 0x1ful << 24);
26558 + } else {
26559 + /* Enable POW interrupt when our port has at least one packet */
26560 + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1001);
26561 + }
26562 +
26563 + /* Enable the poll timer for checking RGMII status */
26564 + init_timer(&cvm_oct_poll_timer);
26565 + cvm_oct_poll_timer.data = 0;
26566 + cvm_oct_poll_timer.function = cvm_do_timer;
26567 + mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
26568 +
26569 + return 0;
26570 +}
26571 +
26572 +/**
26573 + * Module / driver shutdown
26574 + *
26575 + * Returns Zero on success
26576 + */
26577 +static void __exit cvm_oct_cleanup_module(void)
26578 +{
26579 + int port;
26580 +
26581 + /* Disable POW interrupt */
26582 + cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
26583 +
26584 + cvmx_ipd_disable();
26585 +
26586 + /* Free the interrupt handler */
26587 + free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
26588 +
26589 + del_timer(&cvm_oct_poll_timer);
26590 + cvm_oct_rx_shutdown();
26591 + cvmx_pko_disable();
26592 +
26593 + /* Free the ethernet devices */
26594 + for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
26595 + if (cvm_oct_device[port]) {
26596 + cvm_oct_tx_shutdown(cvm_oct_device[port]);
26597 + unregister_netdev(cvm_oct_device[port]);
26598 + kfree(cvm_oct_device[port]);
26599 + cvm_oct_device[port] = NULL;
26600 + }
26601 + }
26602 +
26603 + cvmx_pko_shutdown();
26604 + cvm_oct_proc_shutdown();
26605 +
26606 + cvmx_ipd_free_ptr();
26607 +
26608 + /* Free the HW pools */
26609 + cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
26610 + num_packet_buffers);
26611 + cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
26612 + num_packet_buffers);
26613 + if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
26614 + cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
26615 + CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
26616 +}
26617 +
26618 +MODULE_LICENSE("GPL");
26619 +MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
26620 +MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver.");
26621 +module_init(cvm_oct_init_module);
26622 +module_exit(cvm_oct_cleanup_module);
26623 diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
26624 new file mode 100644
26625 index 0000000..b319907
26626 --- /dev/null
26627 +++ b/drivers/staging/octeon/octeon-ethernet.h
26628 @@ -0,0 +1,127 @@
26629 +/**********************************************************************
26630 + * Author: Cavium Networks
26631 + *
26632 + * Contact: support@caviumnetworks.com
26633 + * This file is part of the OCTEON SDK
26634 + *
26635 + * Copyright (c) 2003-2007 Cavium Networks
26636 + *
26637 + * This file is free software; you can redistribute it and/or modify
26638 + * it under the terms of the GNU General Public License, Version 2, as
26639 + * published by the Free Software Foundation.
26640 + *
26641 + * This file is distributed in the hope that it will be useful, but
26642 + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
26643 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
26644 + * NONINFRINGEMENT. See the GNU General Public License for more
26645 + * details.
26646 + *
26647 + * You should have received a copy of the GNU General Public License
26648 + * along with this file; if not, write to the Free Software
26649 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26650 + * or visit http://www.gnu.org/licenses/.
26651 + *
26652 + * This file may also be available under a different license from Cavium.
26653 + * Contact Cavium Networks for more information
26654 +**********************************************************************/
26655 +
26656 +/*
26657 + * External interface for the Cavium Octeon ethernet driver.
26658 + */
26659 +#ifndef OCTEON_ETHERNET_H
26660 +#define OCTEON_ETHERNET_H
26661 +
26662 +/**
26663 + * This is the definition of the Ethernet driver's private
26664 + * driver state stored in netdev_priv(dev).
26665 + */
26666 +struct octeon_ethernet {
26667 + /* PKO hardware output port */
26668 + int port;
26669 + /* PKO hardware queue for the port */
26670 + int queue;
26671 + /* Hardware fetch and add to count outstanding tx buffers */
26672 + int fau;
26673 + /*
26674 + * Type of port. This is one of the enums in
26675 + * cvmx_helper_interface_mode_t
26676 + */
26677 + int imode;
26678 + /* List of outstanding tx buffers per queue */
26679 + struct sk_buff_head tx_free_list[16];
26680 + /* Device statistics */
26681 + struct net_device_stats stats
26682 +; /* Generic MII info structure */
26683 + struct mii_if_info mii_info;
26684 + /* Last negotiated link state */
26685 + uint64_t link_info;
26686 + /* Called periodically to check link status */
26687 + void (*poll) (struct net_device *dev);
26688 +};
26689 +
26690 +/**
26691 + * Free a work queue entry received in a intercept callback.
26692 + *
26693 + * @work_queue_entry:
26694 + * Work queue entry to free
26695 + * Returns Zero on success, Negative on failure.
26696 + */
26697 +int cvm_oct_free_work(void *work_queue_entry);
26698 +
26699 +/**
26700 + * Transmit a work queue entry out of the ethernet port. Both
26701 + * the work queue entry and the packet data can optionally be
26702 + * freed. The work will be freed on error as well.
26703 + *
26704 + * @dev: Device to transmit out.
26705 + * @work_queue_entry:
26706 + * Work queue entry to send
26707 + * @do_free: True if the work queue entry and packet data should be
26708 + * freed. If false, neither will be freed.
26709 + * @qos: Index into the queues for this port to transmit on. This
26710 + * is used to implement QoS if their are multiple queues per
26711 + * port. This parameter must be between 0 and the number of
26712 + * queues per port minus 1. Values outside of this range will
26713 + * be change to zero.
26714 + *
26715 + * Returns Zero on success, negative on failure.
26716 + */
26717 +int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
26718 + int do_free, int qos);
26719 +
26720 +/**
26721 + * Transmit a work queue entry out of the ethernet port. Both
26722 + * the work queue entry and the packet data can optionally be
26723 + * freed. The work will be freed on error as well. This simply
26724 + * wraps cvmx_oct_transmit_qos() for backwards compatability.
26725 + *
26726 + * @dev: Device to transmit out.
26727 + * @work_queue_entry:
26728 + * Work queue entry to send
26729 + * @do_free: True if the work queue entry and packet data should be
26730 + * freed. If false, neither will be freed.
26731 + *
26732 + * Returns Zero on success, negative on failure.
26733 + */
26734 +static inline int cvm_oct_transmit(struct net_device *dev,
26735 + void *work_queue_entry, int do_free)
26736 +{
26737 + return cvm_oct_transmit_qos(dev, work_queue_entry, do_free, 0);
26738 +}
26739 +
26740 +extern int cvm_oct_rgmii_init(struct net_device *dev);
26741 +extern void cvm_oct_rgmii_uninit(struct net_device *dev);
26742 +extern int cvm_oct_sgmii_init(struct net_device *dev);
26743 +extern void cvm_oct_sgmii_uninit(struct net_device *dev);
26744 +extern int cvm_oct_spi_init(struct net_device *dev);
26745 +extern void cvm_oct_spi_uninit(struct net_device *dev);
26746 +extern int cvm_oct_xaui_init(struct net_device *dev);
26747 +extern void cvm_oct_xaui_uninit(struct net_device *dev);
26748 +
26749 +extern int always_use_pow;
26750 +extern int pow_send_group;
26751 +extern int pow_receive_group;
26752 +extern char pow_send_list[];
26753 +extern struct net_device *cvm_oct_device[];
26754 +
26755 +#endif
26756 --
26757 1.6.0.6
26758