1210284Sjmallett/***********************license start***************
2232812Sjmallett * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3215990Sjmallett * reserved.
4210284Sjmallett *
5210284Sjmallett *
6215990Sjmallett * Redistribution and use in source and binary forms, with or without
7215990Sjmallett * modification, are permitted provided that the following conditions are
8215990Sjmallett * met:
9210284Sjmallett *
10215990Sjmallett *   * Redistributions of source code must retain the above copyright
11215990Sjmallett *     notice, this list of conditions and the following disclaimer.
12210284Sjmallett *
13215990Sjmallett *   * Redistributions in binary form must reproduce the above
14215990Sjmallett *     copyright notice, this list of conditions and the following
15215990Sjmallett *     disclaimer in the documentation and/or other materials provided
16215990Sjmallett *     with the distribution.
17215990Sjmallett
18232812Sjmallett *   * Neither the name of Cavium Inc. nor the names of
19215990Sjmallett *     its contributors may be used to endorse or promote products
20215990Sjmallett *     derived from this software without specific prior written
21215990Sjmallett *     permission.
22215990Sjmallett
23215990Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24215990Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25215990Sjmallett * regulations, and may be subject to export or import  regulations in other
26215990Sjmallett * countries.
27215990Sjmallett
28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38210284Sjmallett ***********************license end**************************************/
39210284Sjmallett
40210284Sjmallett
41210284Sjmallett
42210284Sjmallett
43210284Sjmallett
44210284Sjmallett
45215990Sjmallett
46210284Sjmallett/**
47210284Sjmallett * @file
48210284Sjmallett *
49215990Sjmallett * Interface to the CN31XX, CN38XX, and CN58XX hardware DFA engine.
50210284Sjmallett *
51232812Sjmallett * <hr>$Revision: 70030 $<hr>
52210284Sjmallett */
53210284Sjmallett
54210284Sjmallett#ifndef __CVMX_DFA_H__
55210284Sjmallett#define __CVMX_DFA_H__
56210284Sjmallett#include "cvmx-llm.h"
57210284Sjmallett#include "cvmx-wqe.h"
58210284Sjmallett#include "cvmx-fpa.h"
59210284Sjmallett
60210284Sjmallett#include "executive-config.h"
61210284Sjmallett#ifdef CVMX_ENABLE_DFA_FUNCTIONS
62210284Sjmallett#include "cvmx-config.h"
63210284Sjmallett#endif
64210284Sjmallett
65210284Sjmallett#define ENABLE_DEPRECATED   /* Set to enable the old 18/36 bit names */
66210284Sjmallett
67210284Sjmallett#ifdef	__cplusplus
68210284Sjmallettextern "C" {
69210284Sjmallett#endif
70210284Sjmallett
71210284Sjmallett
72210284Sjmallett/* Maximum nodes available in a small encoding */
73210284Sjmallett#define CVMX_DFA_NODESM_MAX_NODES       ((OCTEON_IS_MODEL(OCTEON_CN31XX)) ? 0x8000 : 0x20000)
74210284Sjmallett#define CVMX_DFA_NODESM_SIZE            512     /* Size of each node for small encoding */
75210284Sjmallett#define CVMX_DFA_NODELG_SIZE            1024    /* Size of each node for large encoding */
76210284Sjmallett#define CVMX_DFA_NODESM_LAST_TERMINAL  (CVMX_DFA_NODESM_MAX_NODES-1)
77210284Sjmallett
78210284Sjmallett#ifdef ENABLE_DEPRECATED
79210284Sjmallett/* These defines are for compatability with old code. They are deprecated */
80210284Sjmallett#define CVMX_DFA_NODE18_SIZE            CVMX_DFA_NODESM_SIZE
81210284Sjmallett#define CVMX_DFA_NODE36_SIZE            CVMX_DFA_NODELG_SIZE
82210284Sjmallett#define CVMX_DFA_NODE18_MAX_NODES       CVMX_DFA_NODESM_MAX_NODES
83210284Sjmallett#define CVMX_DFA_NODE18_LAST_TERMINAL   CVMX_DFA_NODESM_LAST_TERMINAL
84210284Sjmallett#endif
85210284Sjmallett
86210284Sjmallett/**
87210284Sjmallett * Which type of memory encoding is this graph using. Make sure you setup
88210284Sjmallett * the LLM to match.
89210284Sjmallett */
90210284Sjmalletttypedef enum
91210284Sjmallett{
92210284Sjmallett    CVMX_DFA_GRAPH_TYPE_SM              = 0,
93210284Sjmallett    CVMX_DFA_GRAPH_TYPE_LG              = 1,
94210284Sjmallett#ifdef ENABLE_DEPRECATED
95210284Sjmallett    CVMX_DFA_GRAPH_TYPE_18b             = 0,    /* Deprecated */
96210284Sjmallett    CVMX_DFA_GRAPH_TYPE_36b             = 1     /* Deprecated */
97210284Sjmallett#endif
98210284Sjmallett} cvmx_dfa_graph_type_t;
99210284Sjmallett
100210284Sjmallett/**
101210284Sjmallett * The possible node types.
102210284Sjmallett */
103210284Sjmalletttypedef enum
104210284Sjmallett{
105210284Sjmallett    CVMX_DFA_NODE_TYPE_NORMAL           = 0,    /**< Node is a branch */
106210284Sjmallett    CVMX_DFA_NODE_TYPE_MARKED           = 1,    /**< Node is marked special */
107210284Sjmallett    CVMX_DFA_NODE_TYPE_TERMINAL         = 2     /**< Node is a terminal leaf */
108210284Sjmallett} cvmx_dfa_node_type_t;
109210284Sjmallett
110210284Sjmallett/**
111210284Sjmallett * The possible reasons the DFA stopped processing.
112210284Sjmallett */
113210284Sjmalletttypedef enum
114210284Sjmallett{
115210284Sjmallett    CVMX_DFA_STOP_REASON_DATA_GONE      = 0,    /**< DFA ran out of data */
116210284Sjmallett    CVMX_DFA_STOP_REASON_PARITY_ERROR   = 1,    /**< DFA encountered a memory error */
117210284Sjmallett    CVMX_DFA_STOP_REASON_FULL           = 2,    /**< DFA is full */
118210284Sjmallett    CVMX_DFA_STOP_REASON_TERMINAL       = 3     /**< DFA hit a terminal */
119210284Sjmallett} cvmx_dfa_stop_reason_t;
120210284Sjmallett
121210284Sjmallett/**
122210284Sjmallett * This format describes the DFA pointers in small mode
123210284Sjmallett */
124210284Sjmalletttypedef union
125210284Sjmallett{
126210284Sjmallett    uint64_t u64;
127210284Sjmallett    struct
128210284Sjmallett    {
129210284Sjmallett        uint64_t                mbz         :32;/**< Must be zero */
130210284Sjmallett        uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
131210284Sjmallett        uint64_t                next_node1  :15;/**< Next node if an odd character match */
132210284Sjmallett        uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
133210284Sjmallett        uint64_t                next_node0  :15;/**< Next node if an even character match */
134210284Sjmallett    } w32;
135210284Sjmallett    struct
136210284Sjmallett    {
137210284Sjmallett        uint64_t                mbz         :28;/**< Must be zero */
138210284Sjmallett        uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
139210284Sjmallett        uint64_t                next_node1  :17;/**< Next node if an odd character match */
140210284Sjmallett        uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
141210284Sjmallett        uint64_t                next_node0  :17;/**< Next node if an even character match */
142210284Sjmallett    } w36;
143210284Sjmallett    struct /**< @ this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1.  */
144210284Sjmallett    {
145210284Sjmallett        uint64_t                mbz         :28;/**< Must be zero */
146210284Sjmallett        uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
147210284Sjmallett        uint64_t                per_node_repl1  : 1;/**< enable for extra replicaiton for next node (CN58XX) */
148210284Sjmallett        uint64_t                next_node_repl1 : 2;/**< extra replicaiton for next node (CN58XX) (if per_node_repl1 is set) */
149210284Sjmallett        uint64_t                next_node1  :14;/**< Next node if an odd character match - IWORD3[Msize], if per_node_repl1==1. */
150210284Sjmallett        uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
151210284Sjmallett        uint64_t                per_node_repl0  : 1;/**< enable for extra replicaiton for next node (CN58XX) */
152210284Sjmallett        uint64_t                next_node_repl0 : 2;/**< extra replicaiton for next node (CN58XX) (if per_node_repl0 is set) */
153210284Sjmallett        uint64_t                next_node0  :14;/**< Next node if an odd character match - IWORD3[Msize], if per_node_repl0==1. */
154210284Sjmallett    } w36nrepl_en; /**< use when next_node_repl[01] is 1. */
155210284Sjmallett    struct /**< this structure only applies starting in CN58XX and if DFA_CFG[NRPL_ENA] == 1 and IWORD0[NREPLEN] == 1.  */
156210284Sjmallett    {
157210284Sjmallett        uint64_t                mbz         :28;/**< Must be zero */
158210284Sjmallett        uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
159210284Sjmallett        uint64_t                per_node_repl1  : 1;/**< enable for extra replicaiton for next node (CN58XX) */
160210284Sjmallett        uint64_t                next_node1  :16;/**< Next node if an odd character match, if per_node_repl1==0. */
161210284Sjmallett        uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
162210284Sjmallett        uint64_t                per_node_repl0  : 1;/**< enable for extra replicaiton for next node (CN58XX) */
163210284Sjmallett        uint64_t                next_node0  :16;/**< Next node if an odd character match, if per_node_repl0==0. */
164210284Sjmallett    } w36nrepl_dis; /**< use when next_node_repl[01] is 0. */
165210284Sjmallett#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
166210284Sjmallett#if CVMX_COMPILED_FOR(OCTEON_CN31XX)
167210284Sjmallett    struct /**< @deprecated unnamed reference to members */
168210284Sjmallett    {
169210284Sjmallett        uint64_t                mbz         :32;/**< Must be zero */
170210284Sjmallett        uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
171210284Sjmallett        uint64_t                next_node1  :15;/**< Next node if an odd character match */
172210284Sjmallett        uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
173210284Sjmallett        uint64_t                next_node0  :15;/**< Next node if an even character match */
174210284Sjmallett    };
175210284Sjmallett#elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
176210284Sjmallett    struct /**< @deprecated unnamed reference to members */
177210284Sjmallett    {
178210284Sjmallett        uint64_t                mbz         :28;/**< Must be zero */
179210284Sjmallett        uint64_t                p1          : 1;/**< Set if next_node1 is odd parity */
180210284Sjmallett        uint64_t                next_node1  :17;/**< Next node if an odd character match */
181210284Sjmallett        uint64_t                p0          : 1;/**< Set if next_node0 is odd parity */
182210284Sjmallett        uint64_t                next_node0  :17;/**< Next node if an even character match */
183210284Sjmallett    };
184210284Sjmallett#else
185210284Sjmallett    /* Other chips don't support the deprecated unnamed unions */
186210284Sjmallett#endif
187210284Sjmallett#endif
188210284Sjmallett} cvmx_dfa_node_next_sm_t;
189210284Sjmallett
190210284Sjmallett/**
191210284Sjmallett * This format describes the DFA pointers in large mode
192210284Sjmallett */
193210284Sjmalletttypedef union
194210284Sjmallett{
195210284Sjmallett    uint64_t u64;
196210284Sjmallett    struct
197210284Sjmallett    {
198210284Sjmallett        uint64_t                mbz         :32;/**< Must be zero */
199210284Sjmallett        uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
200210284Sjmallett        cvmx_dfa_node_type_t    type        : 2;/**< Node type */
201210284Sjmallett        uint64_t                mbz2        : 3;/**< Must be zero */
202210284Sjmallett        uint64_t                next_node   :20;/**< Next node */
203210284Sjmallett    } w32;
204210284Sjmallett    struct
205210284Sjmallett    {
206210284Sjmallett        uint64_t                mbz         :28;/**< Must be zero */
207210284Sjmallett        uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
208210284Sjmallett        cvmx_dfa_node_type_t    type        : 2;/**< Node type */
209210284Sjmallett        uint64_t                extra_bits     : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
210210284Sjmallett        uint64_t                next_node_repl : 2;/**< extra replicaiton for next node (PASS3/CN58XX), Must be zero previously */
211210284Sjmallett        uint64_t                next_node   :20;/**< Next node ID,  Note, combine with next_node_repl to use as start_node
212210284Sjmallett                                                     for continuation, as in cvmx_dfa_node_next_lgb_t. */
213210284Sjmallett    } w36;
214210284Sjmallett#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
215210284Sjmallett#if CVMX_COMPILED_FOR(OCTEON_CN31XX)
216210284Sjmallett    struct /**< @deprecated unnamed reference to members */
217210284Sjmallett    {
218210284Sjmallett        uint64_t                mbz         :32;/**< Must be zero */
219210284Sjmallett        uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
220210284Sjmallett        cvmx_dfa_node_type_t    type        : 2;/**< Node type */
221210284Sjmallett        uint64_t                mbz2        : 3;/**< Must be zero */
222210284Sjmallett        uint64_t                next_node   :20;/**< Next node */
223210284Sjmallett    };
224210284Sjmallett#elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
225210284Sjmallett    struct /**< @deprecated unnamed reference to members */
226210284Sjmallett    {
227210284Sjmallett        uint64_t                mbz         :28;/**< Must be zero */
228210284Sjmallett        uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
229210284Sjmallett        cvmx_dfa_node_type_t    type        : 2;/**< Node type */
230210284Sjmallett        uint64_t                extra_bits     : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
231210284Sjmallett        uint64_t                next_node_repl : 2;/**< extra replicaiton for next node (PASS3/CN58XX), Must be zero previously */
232210284Sjmallett        uint64_t                next_node   :20;/**< Next node ID,  Note, combine with next_node_repl to use as start_node
233210284Sjmallett                                                     for continuation, as in cvmx_dfa_node_next_lgb_t. */
234210284Sjmallett    };
235210284Sjmallett#else
236210284Sjmallett    /* Other chips don't support the deprecated unnamed unions */
237210284Sjmallett#endif
238210284Sjmallett#endif
239210284Sjmallett} cvmx_dfa_node_next_lg_t;
240210284Sjmallett
241210284Sjmallett/**
242210284Sjmallett * This format describes the DFA pointers in large mode, another way
243210284Sjmallett */
244210284Sjmalletttypedef union
245210284Sjmallett{
246210284Sjmallett    uint64_t u64;
247210284Sjmallett    struct
248210284Sjmallett    {
249210284Sjmallett        uint64_t                mbz         :32;/**< Must be zero */
250210284Sjmallett        uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
251210284Sjmallett        uint64_t  		type_terminal : 1;/**< Node type */
252210284Sjmallett        uint64_t	        type_marked   : 1;/**< Node type */
253210284Sjmallett        uint64_t                mbz2        : 3;/**< Must be zero */
254210284Sjmallett        uint64_t                next_node   :20;/**< Next node */
255210284Sjmallett    } w32;
256210284Sjmallett    struct
257210284Sjmallett    {
258210284Sjmallett        uint64_t                mbz         :28;/**< Must be zero */
259210284Sjmallett        uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
260210284Sjmallett        uint64_t                type_terminal : 1;/**< Node type */
261210284Sjmallett        uint64_t                type_marked   : 1;/**< Node type */
262210284Sjmallett        uint64_t                extra_bits     : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
263210284Sjmallett        uint64_t                next_node_id_and_repl   :22;/**< Next node ID (and repl for PASS3/CN58XX or repl=0 if not),
264210284Sjmallett                                                                 use this as start node for continuation. */
265210284Sjmallett    } w36;
266210284Sjmallett#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
267210284Sjmallett#if CVMX_COMPILED_FOR(OCTEON_CN31XX)
268210284Sjmallett    struct /**< @deprecated unnamed reference to members */
269210284Sjmallett    {
270210284Sjmallett        uint64_t                mbz         :32;/**< Must be zero */
271210284Sjmallett        uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
272210284Sjmallett        uint64_t  		type_terminal : 1;/**< Node type */
273210284Sjmallett        uint64_t	        type_marked   : 1;/**< Node type */
274210284Sjmallett        uint64_t                mbz2        : 3;/**< Must be zero */
275210284Sjmallett        uint64_t                next_node   :20;/**< Next node */
276210284Sjmallett    };
277210284Sjmallett#elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
278210284Sjmallett    struct /**< @deprecated unnamed reference to members */
279210284Sjmallett    {
280210284Sjmallett        uint64_t                mbz         :28;/**< Must be zero */
281210284Sjmallett        uint64_t                ecc         : 7;/**< ECC checksum on the rest of the bits */
282210284Sjmallett        uint64_t                type_terminal : 1;/**< Node type */
283210284Sjmallett        uint64_t                type_marked   : 1;/**< Node type */
284210284Sjmallett        uint64_t                extra_bits     : 5;/**< bits copied to report (PASS3/CN58XX), Must be zero previously */
285210284Sjmallett        uint64_t                next_node_id_and_repl   :22;/**< Next node ID (and repl for PASS3/CN58XX or repl=0 if not),
286210284Sjmallett                                                                 use this as start node for continuation. */
287210284Sjmallett    };
288210284Sjmallett#else
289210284Sjmallett    /* Other chips don't support the deprecated unnamed unions */
290210284Sjmallett#endif
291210284Sjmallett#endif
292210284Sjmallett} cvmx_dfa_node_next_lgb_t;
293210284Sjmallett
294210284Sjmallett/**
295210284Sjmallett * This format describes the DFA pointers in large mode
296210284Sjmallett */
297210284Sjmalletttypedef union
298210284Sjmallett{
299210284Sjmallett    uint64_t u64;
300210284Sjmallett    struct
301210284Sjmallett    {
302210284Sjmallett        uint64_t                mbz         :27;/**< Must be zero */
303210284Sjmallett        uint64_t                x0          : 1;/**< XOR of the rest of the bits */
304210284Sjmallett        uint64_t                reserved    : 4;/**< Must be zero */
305210284Sjmallett        uint64_t                data        :32;/**< LLM Data */
306210284Sjmallett    } w32;
307210284Sjmallett    struct
308210284Sjmallett    {
309210284Sjmallett        uint64_t                mbz         :27;/**< Must be zero */
310210284Sjmallett        uint64_t                x0          : 1;/**< XOR of the rest of the bits */
311210284Sjmallett        uint64_t                data        :36;/**< LLM Data */
312210284Sjmallett    } w36;
313210284Sjmallett#if defined(ENABLE_DEPRECATED) && !OCTEON_IS_COMMON_BINARY()
314210284Sjmallett#if CVMX_COMPILED_FOR(OCTEON_CN31XX)
315210284Sjmallett    struct /**< @deprecated unnamed reference to members */
316210284Sjmallett    {
317210284Sjmallett        uint64_t                mbz         :27;/**< Must be zero */
318210284Sjmallett        uint64_t                x0          : 1;/**< XOR of the rest of the bits */
319210284Sjmallett        uint64_t                reserved    : 4;/**< Must be zero */
320210284Sjmallett        uint64_t                data        :32;/**< LLM Data */
321210284Sjmallett    };
322210284Sjmallett#elif CVMX_COMPILED_FOR(OCTEON_CN38XX)
323210284Sjmallett    struct /**< @deprecated unnamed reference to members */
324210284Sjmallett    {
325210284Sjmallett        uint64_t                mbz         :27;/**< Must be zero */
326210284Sjmallett        uint64_t                x0          : 1;/**< XOR of the rest of the bits */
327210284Sjmallett        uint64_t                data        :36;/**< LLM Data */
328210284Sjmallett    };
329210284Sjmallett#else
330210284Sjmallett    /* Other chips don't support the deprecated unnamed unions */
331210284Sjmallett#endif
332210284Sjmallett#endif
333210284Sjmallett} cvmx_dfa_node_next_read_t;
334210284Sjmallett
335210284Sjmallett/**
336210284Sjmallett * This structure defines the data format in the low-latency memory
337210284Sjmallett */
338210284Sjmalletttypedef union
339210284Sjmallett{
340210284Sjmallett    uint64_t u64;
341210284Sjmallett    cvmx_dfa_node_next_sm_t     sm;     /**< This format describes the DFA pointers in small mode */
342210284Sjmallett    cvmx_dfa_node_next_lg_t     lg;     /**< This format describes the DFA pointers in large mode */
343210284Sjmallett    cvmx_dfa_node_next_lgb_t    lgb;    /**< This format describes the DFA pointers in large mode, another way */
344210284Sjmallett    cvmx_dfa_node_next_read_t   read;   /**< This format describes the DFA pointers in large mode */
345210284Sjmallett#ifdef ENABLE_DEPRECATED
346210284Sjmallett    cvmx_dfa_node_next_sm_t     s18;    /**< Deprecated */
347210284Sjmallett    cvmx_dfa_node_next_lg_t     s36;    /**< Deprecated */
348210284Sjmallett    cvmx_dfa_node_next_lgb_t    s36b;   /**< Deprecated */
349210284Sjmallett#endif
350210284Sjmallett} cvmx_dfa_node_next_t;
351210284Sjmallett
352210284Sjmallett/**
353210284Sjmallett * These structures define a DFA instruction
354210284Sjmallett */
355210284Sjmalletttypedef union
356210284Sjmallett{
357210284Sjmallett    uint64_t u64[4];
358210284Sjmallett    uint32_t u32;
359210284Sjmallett    struct
360210284Sjmallett    {
361210284Sjmallett        // WORD 0
362210284Sjmallett        uint64_t gxor                   : 8;   /**< Graph XOR value (PASS3/CN58XX), Must be zero for other chips
363210284Sjmallett                                                     or if DFA_CFG[GXOR_ENA] == 0.  */
364210284Sjmallett        uint64_t nxoren                 : 1;   /**< Node XOR enable (PASS3/CN58XX), Must be zero for other chips
365210284Sjmallett                                                     or if DFA_CFG[NXOR_ENA] == 0.  */
366210284Sjmallett        uint64_t nreplen                : 1;   /**< Node Replication mode enable (PASS3/CN58XX), Must be zero for other chips
367210284Sjmallett                                                     or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0.  */
368210284Sjmallett#if 0
369210284Sjmallett        uint64_t snrepl                 : 2;   /**< Start_Node Replication (PASS3/CN58XX), Must be zero for other chips
370210284Sjmallett                                                     or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0 or IWORD0[NREPLEN] == 0.  */
371210284Sjmallett        uint64_t start_node_id          : 20;   /**< Node to start the walk from */
372210284Sjmallett#else
373210284Sjmallett        uint64_t start_node             : 22;   /**< Node to start the walk from, includes ID and snrepl, see notes above. */
374210284Sjmallett#endif
375210284Sjmallett
376210284Sjmallett        uint64_t unused02               :  2;   /**< Must be zero */
377210284Sjmallett        cvmx_llm_replication_t replication : 2; /**< Type of memory replication to use */
378210284Sjmallett        uint64_t unused03               :  3;   /**< Must be zero */
379210284Sjmallett        cvmx_dfa_graph_type_t type      :  1;   /**< Type of graph */
380210284Sjmallett        uint64_t unused04               :  4;   /**< Must be zero */
381210284Sjmallett        uint64_t base                   : 20;   /**< All tables start on 1KB boundary */
382210284Sjmallett
383210284Sjmallett        // WORD 1
384210284Sjmallett        uint64_t input_length           : 16;   /**< In bytes, # pointers in gather case */
385210284Sjmallett        uint64_t use_gather             :  1;   /**< Set to use gather */
386210284Sjmallett        uint64_t no_L2_alloc            :  1;   /**< Set to disable loading of the L2 cache by the DFA */
387210284Sjmallett        uint64_t full_block_write       :  1;   /**< If set, HW can write entire cache blocks @ result_ptr */
388210284Sjmallett        uint64_t little_endian          :  1;   /**< Affects only packet data, not instruction, gather list, or result */
389210284Sjmallett        uint64_t unused1                :  8;   /**< Must be zero */
390210284Sjmallett        uint64_t data_ptr               : 36;   /**< Either directly points to data or the gather list. If gather list,
391210284Sjmallett                                                    data_ptr<2:0> must be zero (i.e. 8B aligned) */
392210284Sjmallett        // WORD 2
393210284Sjmallett        uint64_t max_results            : 16;   /**< in 64-bit quantities, mbz for store */
394210284Sjmallett        uint64_t unused2                : 12;   /**< Must be zero */
395210284Sjmallett        uint64_t result_ptr             : 36;   /**< must be 128 byte aligned */
396210284Sjmallett
397210284Sjmallett        // WORD 3
398210284Sjmallett        uint64_t tsize                  :  8;   /**< tsize*256 is the number of terminal nodes for GRAPH_TYPE_SM */
399210284Sjmallett        uint64_t msize                  : 16;   /**< msize is the number of marked nodes for GRAPH_TYPE_SM */
400210284Sjmallett        uint64_t unused3                :  4;   /**< Must be zero */
401210284Sjmallett        uint64_t wq_ptr                 : 36;   /**< 0 for no work queue entry creation */
402210284Sjmallett    } s;
403210284Sjmallett} cvmx_dfa_command_t;
404210284Sjmallett
405210284Sjmallett/**
406210284Sjmallett * Format of the first result word written by the hardware.
407210284Sjmallett */
408210284Sjmalletttypedef union
409210284Sjmallett{
410210284Sjmallett    uint64_t u64;
411210284Sjmallett    struct
412210284Sjmallett    {
413210284Sjmallett        cvmx_dfa_stop_reason_t  reas        : 2;/**< Reason the DFA stopped */
414210284Sjmallett        uint64_t                mbz         :44;/**< Zero */
415210284Sjmallett        uint64_t                last_marked : 1;/**< Set if the last entry written is marked */
416210284Sjmallett        uint64_t                done        : 1;/**< Set to 1 when the DFA completes */
417210284Sjmallett        uint64_t                num_entries :16;/**< Number of result words written */
418210284Sjmallett    } s;
419210284Sjmallett} cvmx_dfa_result0_t;
420210284Sjmallett
421210284Sjmallett/**
422210284Sjmallett * Format of the second result word and subsequent result words written by the hardware.
423210284Sjmallett */
424210284Sjmalletttypedef union
425210284Sjmallett{
426210284Sjmallett    uint64_t u64;
427210284Sjmallett    struct
428210284Sjmallett    {
429210284Sjmallett        uint64_t byte_offset    : 16;   /**< Number of bytes consumed */
430210284Sjmallett        uint64_t extra_bits_high:  4;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
431210284Sjmallett                                             then set to <27:24> of the last next-node pointer. Else set to 0x0.  */
432210284Sjmallett        uint64_t prev_node      : 20;   /**< Index of the previous node */
433210284Sjmallett        uint64_t extra_bits_low :  2;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
434210284Sjmallett                                             then set to <23:22> of the last next-node pointer. Else set to 0x0.  */
435210284Sjmallett        uint64_t next_node_repl :  2;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1, then set
436210284Sjmallett                                             to next_node_repl (<21:20>) of the last next-node pointer. Else set to 0x0.  */
437210284Sjmallett        uint64_t current_node   : 20;   /**< Index of the current node */
438210284Sjmallett    } s;
439210284Sjmallett    struct
440210284Sjmallett    {
441210284Sjmallett        uint64_t byte_offset    : 16;   /**< Number of bytes consumed */
442210284Sjmallett        uint64_t extra_bits_high:  4;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
443210284Sjmallett                                             then set to <27:24> of the last next-node pointer. Else set to 0x0.  */
444210284Sjmallett        uint64_t prev_node      : 20;   /**< Index of the previous node */
445210284Sjmallett        uint64_t extra_bits_low :  2;   /**< If PASS3 or CN58XX and DFA_CFG[NRPL_ENA] == 1 and IWORD0[Ty] == 1,
446210284Sjmallett                                             then set to <23:22> of the last next-node pointer. Else set to 0x0.  */
447210284Sjmallett        uint64_t curr_id_and_repl:22;   /**< Use ths as start_node for continuation. */
448210284Sjmallett    } s2;
449210284Sjmallett} cvmx_dfa_result1_t;
450210284Sjmallett
451210284Sjmallett/**
452210284Sjmallett * Abstract DFA graph
453210284Sjmallett */
454210284Sjmalletttypedef struct
455210284Sjmallett{
456210284Sjmallett    cvmx_llm_replication_t      replication;        /**< Level of memory replication to use. Must match the LLM setup */
457210284Sjmallett    cvmx_dfa_graph_type_t       type;               /**< Type of graph */
458210284Sjmallett    uint64_t                    base_address;       /**< LLM start address of the graph */
459210284Sjmallett    union {
460210284Sjmallett        struct {
461210284Sjmallett            uint64_t            gxor         : 8;   /**< Graph XOR value (PASS3/CN58XX), Must be zero for other chips
462210284Sjmallett                                                          or if DFA_CFG[GXOR_ENA] == 0.  */
463210284Sjmallett            uint64_t            nxoren       : 1;   /**< Node XOR enable (PASS3/CN58XX), Must be zero for other chips
464210284Sjmallett                                                          or if DFA_CFG[NXOR_ENA] == 0.  */
465210284Sjmallett            uint64_t            nreplen      : 1;   /**< Node Replication mode enable (PASS3/CN58XX), Must be zero for other chips
466210284Sjmallett                                                          or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0.  */
467210284Sjmallett            uint64_t            snrepl       : 2;   /**< Start_Node Replication (PASS3/CN58XX), Must be zero for other chips
468210284Sjmallett                                                          or if DFA_CFG[NRPL_ENA] == 0 or IWORD0[Ty] == 0 or IWORD0[NREPLEN] == 0.*/
469210284Sjmallett            uint64_t            start_node_id : 20; /**< Start node index for the root of the graph */
470210284Sjmallett        };
471210284Sjmallett        uint32_t                start_node;         /**< Start node index for the root of the graph, incl. snrepl (PASS3/CN58XX)
472210284Sjmallett                                                           NOTE: for backwards compatibility this name includes the the
473210284Sjmallett                                                                 gxor, nxoren, nreplen, and snrepl fields which will all be
474210284Sjmallett                                                                 zero in applicaitons existing before the introduction of these
475210284Sjmallett                                                                 fields, so that existing applicaiton do not need to change. */
476210284Sjmallett    };
477210284Sjmallett    int                         num_terminal_nodes; /**< Number of terminal nodes in the graph. Only needed for small graphs. */
478210284Sjmallett    int                         num_marked_nodes;   /**< Number of marked nodes in the graph. Only needed for small graphs. */
479210284Sjmallett} cvmx_dfa_graph_t;
480210284Sjmallett
481210284Sjmallett/**
482210284Sjmallett * DFA internal global state -- stored in 8 bytes of FAU
483210284Sjmallett */
484210284Sjmalletttypedef union
485210284Sjmallett{
486210284Sjmallett    uint64_t u64;
487210284Sjmallett    struct {
488210284Sjmallett#define CVMX_DFA_STATE_TICKET_BIT_POS 16
489232812Sjmallett#ifdef __BIG_ENDIAN_BITFIELD
490210284Sjmallett	// NOTE:  must clear LSB of base_address_div16 due to ticket overflow
491210284Sjmallett	uint32_t		base_address_div16;  /**< Current DFA instruction queue chunck base address/16 (clear LSB). */
492210284Sjmallett	uint8_t			ticket_loops;	     /**< bits [15:8] of total number of tickets requested. */
493210284Sjmallett	uint8_t			ticket;		     /**< bits [7:0] of total number of tickets requested (current ticket held). */
494210284Sjmallett	// NOTE: index and now_serving are written together
495210284Sjmallett	uint8_t			now_serving;	     /**< current ticket being served (or ready to be served). */
496210284Sjmallett	uint8_t			index;		     /**< index into current chunk: (base_address_div16*16)[index] = next entry. */
497210284Sjmallett#else	// NOTE: little endian mode probably won't work
498210284Sjmallett	uint8_t			index;
499210284Sjmallett	uint8_t			now_serving;
500210284Sjmallett	uint8_t			ticket;
501210284Sjmallett	uint8_t			ticket_loops;
502210284Sjmallett	uint32_t		base_address_div16;
503210284Sjmallett#endif
504210284Sjmallett    } s;
505210284Sjmallett    struct {	// a bitfield version of the same thing to extract base address while clearing carry.
506232812Sjmallett#ifdef __BIG_ENDIAN_BITFIELD
507210284Sjmallett	uint64_t		base_address_div32	: 31;	/**< Current DFA instruction queue chunck base address/32. */
508210284Sjmallett	uint64_t		carry			: 1;	/**< Carry out from total_tickets. */
509210284Sjmallett	uint64_t		total_tickets		: 16;	/**< Total tickets. */
510210284Sjmallett	uint64_t		now_serving		: 8 ;	/**< current ticket being served (or ready to be served). */
511210284Sjmallett	uint64_t		index			: 8 ;   /**< index into current chunk. */
512210284Sjmallett#else	// NOTE: little endian mode probably won't work
513210284Sjmallett	uint64_t		index			: 8 ;
514210284Sjmallett	uint64_t		now_serving		: 8 ;
515210284Sjmallett	uint64_t		total_tickets		: 16;
516210284Sjmallett	uint64_t		carry			: 1;
517210284Sjmallett	uint64_t		base_address_div32	: 31;
518210284Sjmallett#endif
519210284Sjmallett    } s2;
520210284Sjmallett} cvmx_dfa_state_t;
521210284Sjmallett
522215990Sjmallett/* CSR typedefs have been moved to cvmx-dfa-defs.h */
523210284Sjmallett
524210284Sjmallett/**
525210284Sjmallett * Write a small node edge to LLM.
526210284Sjmallett *
527210284Sjmallett * @param graph  Graph to modify
528210284Sjmallett * @param source_node
529210284Sjmallett *               Source node for this edge
530210284Sjmallett * @param match_index
531210284Sjmallett *               Index into the node edge table. This is the match character/2.
532210284Sjmallett * @param destination_node0
533210284Sjmallett *               Destination if the character matches (match_index*2).
534210284Sjmallett * @param destination_node1
535210284Sjmallett *               Destination if the character matches (match_index*2+1).
536210284Sjmallett */
537210284Sjmallettstatic inline void cvmx_dfa_write_edge_sm(const cvmx_dfa_graph_t *graph,
538210284Sjmallett                                         uint64_t source_node, uint64_t match_index,
539210284Sjmallett                                         uint64_t destination_node0, uint64_t destination_node1)
540210284Sjmallett{
541210284Sjmallett    cvmx_llm_address_t address;
542210284Sjmallett    cvmx_dfa_node_next_t    next_ptr;
543210284Sjmallett
544210284Sjmallett    address.u64 = graph->base_address + source_node * CVMX_DFA_NODESM_SIZE + match_index * 4;
545210284Sjmallett
546210284Sjmallett    next_ptr.u64 = 0;
547210284Sjmallett    if (OCTEON_IS_MODEL(OCTEON_CN31XX))
548210284Sjmallett    {
549210284Sjmallett        next_ptr.sm.w32.next_node0 = destination_node0;
550210284Sjmallett        next_ptr.sm.w32.p0 = cvmx_llm_parity(destination_node0);
551210284Sjmallett
552210284Sjmallett        next_ptr.sm.w32.next_node1 = destination_node1;
553210284Sjmallett        next_ptr.sm.w32.p1 = cvmx_llm_parity(destination_node1);
554210284Sjmallett    }
555210284Sjmallett    else
556210284Sjmallett    {
557210284Sjmallett        next_ptr.sm.w36.next_node0 = destination_node0;
558210284Sjmallett        next_ptr.sm.w36.p0 = cvmx_llm_parity(destination_node0);
559210284Sjmallett
560210284Sjmallett        next_ptr.sm.w36.next_node1 = destination_node1;
561210284Sjmallett        next_ptr.sm.w36.p1 = cvmx_llm_parity(destination_node1);
562210284Sjmallett    }
563210284Sjmallett
564210284Sjmallett    cvmx_llm_write36(address, next_ptr.u64, 0);
565210284Sjmallett}
566210284Sjmallett#ifdef ENABLE_DEPRECATED
567210284Sjmallett#define cvmx_dfa_write_edge18 cvmx_dfa_write_edge_sm
568210284Sjmallett#endif
569210284Sjmallett
570210284Sjmallett
571210284Sjmallett/**
572210284Sjmallett * Write a large node edge to LLM.
573210284Sjmallett *
574210284Sjmallett * @param graph  Graph to modify
575210284Sjmallett * @param source_node
576210284Sjmallett *               Source node for this edge
577210284Sjmallett * @param match  Character to match before taking this edge.
578210284Sjmallett * @param destination_node
579210284Sjmallett *               Destination node of the edge.
580210284Sjmallett * @param destination_type
581210284Sjmallett *               Node type at the end of this edge.
582210284Sjmallett */
583210284Sjmallettstatic inline void cvmx_dfa_write_node_lg(const cvmx_dfa_graph_t *graph,
584210284Sjmallett                                         uint64_t source_node, unsigned char match,
585210284Sjmallett                                         uint64_t destination_node, cvmx_dfa_node_type_t destination_type)
586210284Sjmallett{
587210284Sjmallett    cvmx_llm_address_t      address;
588210284Sjmallett    cvmx_dfa_node_next_t    next_ptr;
589210284Sjmallett
590210284Sjmallett    address.u64 = graph->base_address + source_node * CVMX_DFA_NODELG_SIZE + (uint64_t)match * 4;
591210284Sjmallett
592210284Sjmallett    next_ptr.u64 = 0;
593210284Sjmallett    if (OCTEON_IS_MODEL(OCTEON_CN31XX))
594210284Sjmallett    {
595210284Sjmallett        next_ptr.lg.w32.type = destination_type;
596210284Sjmallett        next_ptr.lg.w32.next_node = destination_node;
597210284Sjmallett        next_ptr.lg.w32.ecc = cvmx_llm_ecc(next_ptr.u64);
598210284Sjmallett    }
599210284Sjmallett    else
600210284Sjmallett    {
601210284Sjmallett        next_ptr.lg.w36.type = destination_type;
602210284Sjmallett        next_ptr.lg.w36.next_node = destination_node;
603210284Sjmallett        next_ptr.lg.w36.ecc = cvmx_llm_ecc(next_ptr.u64);
604210284Sjmallett    }
605210284Sjmallett
606210284Sjmallett    cvmx_llm_write36(address, next_ptr.u64, 0);
607210284Sjmallett}
608210284Sjmallett#ifdef ENABLE_DEPRECATED
609210284Sjmallett#define cvmx_dfa_write_node36 cvmx_dfa_write_node_lg
610210284Sjmallett#endif
611210284Sjmallett
612210284Sjmallett/**
613210284Sjmallett * Ring the DFA doorbell telling it that new commands are
614210284Sjmallett * available.
615210284Sjmallett *
616210284Sjmallett * @param num_commands
617210284Sjmallett *               Number of new commands
618210284Sjmallett */
619210284Sjmallettstatic inline void cvmx_dfa_write_doorbell(uint64_t num_commands)
620210284Sjmallett{
621210284Sjmallett    CVMX_SYNCWS;
622210284Sjmallett    cvmx_write_csr(CVMX_DFA_DBELL, num_commands);
623210284Sjmallett}
624210284Sjmallett
625210284Sjmallett/**
626210284Sjmallett * @INTERNAL
627210284Sjmallett * Write a new command to the DFA. Calls to this function
628210284Sjmallett * are internally synchronized across all processors, and
629210284Sjmallett * the doorbell is rung during this function.
630210284Sjmallett *
631210284Sjmallett * @param command Command to write
632210284Sjmallett */
633210284Sjmallett
634210284Sjmallett#ifdef CVMX_ENABLE_DFA_FUNCTIONS
635210284Sjmallettstatic inline void __cvmx_dfa_write_command(cvmx_dfa_command_t *command)
636210284Sjmallett{
637210284Sjmallett    cvmx_dfa_state_t cvmx_dfa_state;
638210284Sjmallett    uint64_t my_ticket;	// needs to wrap to 8 bits
639210284Sjmallett    uint64_t index;
640210284Sjmallett    cvmx_dfa_command_t *head;
641210284Sjmallett
642210284Sjmallett    CVMX_PREFETCH0(command);
643210284Sjmallett    // take a ticket.
644210284Sjmallett    cvmx_dfa_state.u64 = cvmx_fau_fetch_and_add64(CVMX_FAU_DFA_STATE, 1ull<<CVMX_DFA_STATE_TICKET_BIT_POS);
645210284Sjmallett    my_ticket = cvmx_dfa_state.s.ticket;
646210284Sjmallett
647210284Sjmallett    // see if it is our turn
648210284Sjmallett    while (my_ticket != cvmx_dfa_state.s.now_serving) {
649210284Sjmallett	int delta = my_ticket - cvmx_dfa_state.s.now_serving;
650210284Sjmallett	if (delta < 0) delta += 256;
651210284Sjmallett	cvmx_wait(10*delta);	// reduce polling load on system
652210284Sjmallett	cvmx_dfa_state.u64 = cvmx_fau_fetch_and_add64(CVMX_FAU_DFA_STATE, 0);		// poll for my_ticket==now_serving
653210284Sjmallett    }
654210284Sjmallett
655210284Sjmallett    // compute index and instruction queue head pointer
656210284Sjmallett    index = cvmx_dfa_state.s.index;
657210284Sjmallett
658210284Sjmallett    // NOTE: the DFA only supports 36-bit addressing
659210284Sjmallett    head = &((CASTPTR(cvmx_dfa_command_t, (cvmx_dfa_state.s2.base_address_div32 * 32ull))[index]));
660210284Sjmallett    head = (cvmx_dfa_command_t*)cvmx_phys_to_ptr(CAST64(head));	// NOTE: since we are not storing bit 63 of address, we must set it now
661210284Sjmallett
662210284Sjmallett    // copy the command to the instruction queue
663210284Sjmallett    *head++ = *command;
664210284Sjmallett
665210284Sjmallett    // check if a new chunk is needed
666210284Sjmallett    if (cvmx_unlikely((++index >= ((CVMX_FPA_DFA_POOL_SIZE-8)/sizeof(cvmx_dfa_command_t))))) {
667210284Sjmallett        uint64_t *new_base = (uint64_t*)cvmx_fpa_alloc(CVMX_FPA_DFA_POOL);	// could make this async
668210284Sjmallett        if (new_base) {
669210284Sjmallett	    // put the link into the instruction queue's "Next Chunk Buffer Ptr"
670210284Sjmallett            *(uint64_t *)head = cvmx_ptr_to_phys(new_base);
671210284Sjmallett	    // update our state (note 32-bit write to not disturb other fields)
672210284Sjmallett            cvmx_fau_atomic_write32((cvmx_fau_reg_32_t)(CVMX_FAU_DFA_STATE + (CAST64(&cvmx_dfa_state.s.base_address_div16)-CAST64(&cvmx_dfa_state))),
673210284Sjmallett		    (CAST64(new_base))/16);
674210284Sjmallett        }
675210284Sjmallett        else {
676210284Sjmallett            cvmx_dprintf("__cvmx_dfa_write_command: Out of memory. Expect crashes.\n");
677210284Sjmallett        }
678210284Sjmallett	index=0;
679210284Sjmallett    }
680210284Sjmallett
681210284Sjmallett    cvmx_dfa_write_doorbell(1);
682210284Sjmallett
683210284Sjmallett    // update index and now_serving in the DFA state FAU location (NOTE: this write16 updates to 8-bit values.)
684210284Sjmallett    // NOTE: my_ticket+1 carry out is lost due to write16 and index has already been wrapped to fit in uint8.
685210284Sjmallett    cvmx_fau_atomic_write16((cvmx_fau_reg_16_t)(CVMX_FAU_DFA_STATE+(CAST64(&cvmx_dfa_state.s.now_serving) - CAST64(&cvmx_dfa_state))),
686210284Sjmallett	    ((my_ticket+1)<<8) | index);
687210284Sjmallett}
688210284Sjmallett
689210284Sjmallett
690210284Sjmallett/**
691210284Sjmallett * Submit work to the DFA units for processing
692210284Sjmallett *
693210284Sjmallett * @param graph   Graph to process
694210284Sjmallett * @param start_node
695210284Sjmallett *                The node to start (or continue) walking from
696210284Sjmallett *                includes. start_node_id and snrepl (PASS3/CN58XX), but gxor,
697210284Sjmallett *                nxoren, and nreplen are taken from the graph structure
698210284Sjmallett * @param input   The input to match against
699210284Sjmallett * @param input_length
700210284Sjmallett *                The length of the input in bytes
701210284Sjmallett * @param use_gather
702210284Sjmallett *		  The input and input_length are of a gather list
703210284Sjmallett * @param is_little_endian
704210284Sjmallett *                Set to 1 if the input is in little endian format and must
705210284Sjmallett *                be swapped before compare.
706210284Sjmallett * @param result  Location the DFA should put the results in. This must be
707210284Sjmallett *                an area sized in multiples of a cache line.
708210284Sjmallett * @param max_results
709210284Sjmallett *                The maximum number of 64-bit result1 words after result0.
710210284Sjmallett *                That is, "size of the result area in 64-bit words" - 1.
711210284Sjmallett *                max_results must be at least 1.
712210284Sjmallett * @param work    Work queue entry to submit when DFA completes. Can be NULL.
713210284Sjmallett */
714210284Sjmallettstatic inline void cvmx_dfa_submit(const cvmx_dfa_graph_t *graph, int start_node,
715210284Sjmallett                                  void *input, int input_length, int use_gather, int is_little_endian,
716210284Sjmallett                                  cvmx_dfa_result0_t *result, int max_results, cvmx_wqe_t *work)
717210284Sjmallett{
718210284Sjmallett    cvmx_dfa_command_t command;
719210284Sjmallett
720210284Sjmallett    /* Make sure the result's first 64bit word is zero so we can tell when the
721210284Sjmallett        DFA is done. */
722210284Sjmallett    result->u64 = 0;
723210284Sjmallett
724210284Sjmallett    // WORD 0
725210284Sjmallett    command.u64[0] = 0;
726210284Sjmallett    command.s.gxor          = graph->gxor;      // (PASS3/CN58XX)
727210284Sjmallett    command.s.nxoren        = graph->nxoren;    // (PASS3/CN58XX)
728210284Sjmallett    command.s.nreplen       = graph->nreplen;   // (PASS3/CN58XX)
729210284Sjmallett    command.s.start_node    = start_node;       // includes snrepl (PASS3/CN58XX)
730210284Sjmallett    command.s.replication   = graph->replication;
731210284Sjmallett    command.s.type          = graph->type;
732210284Sjmallett    command.s.base          = graph->base_address>>10;
733210284Sjmallett
734210284Sjmallett    // WORD 1
735210284Sjmallett    command.u64[1] = 0;
736210284Sjmallett    command.s.input_length  = input_length;
737210284Sjmallett    command.s.use_gather   = use_gather;
738210284Sjmallett    command.s.no_L2_alloc   = 0;
739210284Sjmallett    command.s.full_block_write = 1;
740210284Sjmallett    command.s.little_endian = is_little_endian;
741210284Sjmallett    command.s.data_ptr      = cvmx_ptr_to_phys(input);
742210284Sjmallett
743210284Sjmallett    // WORD 2
744210284Sjmallett    command.u64[2] = 0;
745210284Sjmallett    command.s.max_results   = max_results;
746210284Sjmallett    command.s.result_ptr    = cvmx_ptr_to_phys(result);
747210284Sjmallett
748210284Sjmallett    // WORD 3
749210284Sjmallett    command.u64[3] = 0;
750210284Sjmallett    if (graph->type == CVMX_DFA_GRAPH_TYPE_SM)
751210284Sjmallett    {
752210284Sjmallett        command.s.tsize     = (graph->num_terminal_nodes + 255) / 256;
753210284Sjmallett        command.s.msize     = graph->num_marked_nodes;
754210284Sjmallett    }
755210284Sjmallett    command.s.wq_ptr        = cvmx_ptr_to_phys(work);
756210284Sjmallett
757210284Sjmallett    __cvmx_dfa_write_command(&command);	// NOTE: this does synchronization and rings doorbell
758210284Sjmallett}
759210284Sjmallett#endif
760210284Sjmallett
761210284Sjmallett/**
762210284Sjmallett * DFA gather list element
763210284Sjmallett */
764210284Sjmalletttypedef struct {
765210284Sjmallett    uint64_t length         : 16;   /**< length of piece of data at addr */
766210284Sjmallett    uint64_t reserved       : 12;   /**< reserved, set to 0 */
767210284Sjmallett    uint64_t addr           : 36;   /**< pointer to piece of data */
768210284Sjmallett} cvmx_dfa_gather_entry_t;
769210284Sjmallett
770210284Sjmallett
771210284Sjmallett/**
772210284Sjmallett * Check if a DFA has completed processing
773210284Sjmallett *
774210284Sjmallett * @param result_ptr Result area the DFA is using
775210284Sjmallett * @return Non zero if the DFA is done
776210284Sjmallett */
777210284Sjmallettstatic inline uint64_t cvmx_dfa_is_done(cvmx_dfa_result0_t *result_ptr)
778210284Sjmallett{
779210284Sjmallett    /* DFA sets the first result 64bit word to non zero when it's done */
780210284Sjmallett    return ((volatile cvmx_dfa_result0_t *)result_ptr)->s.done;
781210284Sjmallett}
782210284Sjmallett
783210284Sjmallett
784210284Sjmallett#ifdef CVMX_ENABLE_DFA_FUNCTIONS
785210284Sjmallett/**
786210284Sjmallett * Initialize the DFA hardware before use
787210284Sjmallett * Returns 0 on success, -1 on failure
788210284Sjmallett */
789210284Sjmallettint cvmx_dfa_initialize(void);
790210284Sjmallett
791210284Sjmallett
792210284Sjmallett/**
793210284Sjmallett * Shutdown and cleanup resources used by the DFA
794210284Sjmallett */
795210284Sjmallettvoid cvmx_dfa_shutdown(void);
796210284Sjmallett#endif
797210284Sjmallett
798210284Sjmallett#ifdef	__cplusplus
799210284Sjmallett}
800210284Sjmallett#endif
801210284Sjmallett
802210284Sjmallett#endif /* __CVMX_DFA_H__ */
803