1*4882a593Smuzhiyun /***********************license start***************
2*4882a593Smuzhiyun * Author: Cavium Networks
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Contact: support@caviumnetworks.com
5*4882a593Smuzhiyun * This file is part of the OCTEON SDK
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Copyright (c) 2003-2008 Cavium Networks
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * This file is free software; you can redistribute it and/or modify
10*4882a593Smuzhiyun * it under the terms of the GNU General Public License, Version 2, as
11*4882a593Smuzhiyun * published by the Free Software Foundation.
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * This file is distributed in the hope that it will be useful, but
14*4882a593Smuzhiyun * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15*4882a593Smuzhiyun * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16*4882a593Smuzhiyun * NONINFRINGEMENT. See the GNU General Public License for more
17*4882a593Smuzhiyun * details.
18*4882a593Smuzhiyun *
19*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License
20*4882a593Smuzhiyun * along with this file; if not, write to the Free Software
21*4882a593Smuzhiyun * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22*4882a593Smuzhiyun * or visit http://www.gnu.org/licenses/.
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun * This file may also be available under a different license from Cavium.
25*4882a593Smuzhiyun * Contact Cavium Networks for more information
26*4882a593Smuzhiyun ***********************license end**************************************/
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /**
29*4882a593Smuzhiyun *
30*4882a593Smuzhiyun * This header file defines the work queue entry (wqe) data structure.
31*4882a593Smuzhiyun * Since this is a commonly used structure that depends on structures
32*4882a593Smuzhiyun * from several hardware blocks, those definitions have been placed
33*4882a593Smuzhiyun * in this file to create a single point of definition of the wqe
34*4882a593Smuzhiyun * format.
35*4882a593Smuzhiyun * Data structures are still named according to the block that they
36*4882a593Smuzhiyun * relate to.
37*4882a593Smuzhiyun *
38*4882a593Smuzhiyun */
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #ifndef __CVMX_WQE_H__
41*4882a593Smuzhiyun #define __CVMX_WQE_H__
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #include <asm/octeon/cvmx-packet.h>
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun #define OCT_TAG_TYPE_STRING(x) \
47*4882a593Smuzhiyun (((x) == CVMX_POW_TAG_TYPE_ORDERED) ? "ORDERED" : \
48*4882a593Smuzhiyun (((x) == CVMX_POW_TAG_TYPE_ATOMIC) ? "ATOMIC" : \
49*4882a593Smuzhiyun (((x) == CVMX_POW_TAG_TYPE_NULL) ? "NULL" : \
50*4882a593Smuzhiyun "NULL_NULL")))
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun /**
53*4882a593Smuzhiyun * HW decode / err_code in work queue entry
54*4882a593Smuzhiyun */
55*4882a593Smuzhiyun typedef union {
56*4882a593Smuzhiyun uint64_t u64;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun /* Use this struct if the hardware determines that the packet is IP */
59*4882a593Smuzhiyun struct {
60*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
61*4882a593Smuzhiyun /* HW sets this to the number of buffers used by this packet */
62*4882a593Smuzhiyun uint64_t bufs:8;
63*4882a593Smuzhiyun /* HW sets to the number of L2 bytes prior to the IP */
64*4882a593Smuzhiyun uint64_t ip_offset:8;
65*4882a593Smuzhiyun /* set to 1 if we found DSA/VLAN in the L2 */
66*4882a593Smuzhiyun uint64_t vlan_valid:1;
67*4882a593Smuzhiyun /* Set to 1 if the DSA/VLAN tag is stacked */
68*4882a593Smuzhiyun uint64_t vlan_stacked:1;
69*4882a593Smuzhiyun uint64_t unassigned:1;
70*4882a593Smuzhiyun /* HW sets to the DSA/VLAN CFI flag (valid when vlan_valid) */
71*4882a593Smuzhiyun uint64_t vlan_cfi:1;
72*4882a593Smuzhiyun /* HW sets to the DSA/VLAN_ID field (valid when vlan_valid) */
73*4882a593Smuzhiyun uint64_t vlan_id:12;
74*4882a593Smuzhiyun /* Ring Identifier (if PCIe). Requires PIP_GBL_CTL[RING_EN]=1 */
75*4882a593Smuzhiyun uint64_t pr:4;
76*4882a593Smuzhiyun uint64_t unassigned2:8;
77*4882a593Smuzhiyun /* the packet needs to be decompressed */
78*4882a593Smuzhiyun uint64_t dec_ipcomp:1;
79*4882a593Smuzhiyun /* the packet is either TCP or UDP */
80*4882a593Smuzhiyun uint64_t tcp_or_udp:1;
81*4882a593Smuzhiyun /* the packet needs to be decrypted (ESP or AH) */
82*4882a593Smuzhiyun uint64_t dec_ipsec:1;
83*4882a593Smuzhiyun /* the packet is IPv6 */
84*4882a593Smuzhiyun uint64_t is_v6:1;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /*
87*4882a593Smuzhiyun * (rcv_error, not_IP, IP_exc, is_frag, L4_error,
88*4882a593Smuzhiyun * software, etc.).
89*4882a593Smuzhiyun */
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /*
92*4882a593Smuzhiyun * reserved for software use, hardware will clear on
93*4882a593Smuzhiyun * packet creation.
94*4882a593Smuzhiyun */
95*4882a593Smuzhiyun uint64_t software:1;
96*4882a593Smuzhiyun /* exceptional conditions below */
97*4882a593Smuzhiyun /* the receive interface hardware detected an L4 error
98*4882a593Smuzhiyun * (only applies if !is_frag) (only applies if
99*4882a593Smuzhiyun * !rcv_error && !not_IP && !IP_exc && !is_frag)
100*4882a593Smuzhiyun * failure indicated in err_code below, decode:
101*4882a593Smuzhiyun *
102*4882a593Smuzhiyun * - 1 = Malformed L4
103*4882a593Smuzhiyun * - 2 = L4 Checksum Error: the L4 checksum value is
104*4882a593Smuzhiyun * - 3 = UDP Length Error: The UDP length field would
105*4882a593Smuzhiyun * make the UDP data longer than what remains in
106*4882a593Smuzhiyun * the IP packet (as defined by the IP header
107*4882a593Smuzhiyun * length field).
108*4882a593Smuzhiyun * - 4 = Bad L4 Port: either the source or destination
109*4882a593Smuzhiyun * TCP/UDP port is 0.
110*4882a593Smuzhiyun * - 8 = TCP FIN Only: the packet is TCP and only the
111*4882a593Smuzhiyun * FIN flag set.
112*4882a593Smuzhiyun * - 9 = TCP No Flags: the packet is TCP and no flags
113*4882a593Smuzhiyun * are set.
114*4882a593Smuzhiyun * - 10 = TCP FIN RST: the packet is TCP and both FIN
115*4882a593Smuzhiyun * and RST are set.
116*4882a593Smuzhiyun * - 11 = TCP SYN URG: the packet is TCP and both SYN
117*4882a593Smuzhiyun * and URG are set.
118*4882a593Smuzhiyun * - 12 = TCP SYN RST: the packet is TCP and both SYN
119*4882a593Smuzhiyun * and RST are set.
120*4882a593Smuzhiyun * - 13 = TCP SYN FIN: the packet is TCP and both SYN
121*4882a593Smuzhiyun * and FIN are set.
122*4882a593Smuzhiyun */
123*4882a593Smuzhiyun uint64_t L4_error:1;
124*4882a593Smuzhiyun /* set if the packet is a fragment */
125*4882a593Smuzhiyun uint64_t is_frag:1;
126*4882a593Smuzhiyun /* the receive interface hardware detected an IP error
127*4882a593Smuzhiyun * / exception (only applies if !rcv_error && !not_IP)
128*4882a593Smuzhiyun * failure indicated in err_code below, decode:
129*4882a593Smuzhiyun *
130*4882a593Smuzhiyun * - 1 = Not IP: the IP version field is neither 4 nor
131*4882a593Smuzhiyun * 6.
132*4882a593Smuzhiyun * - 2 = IPv4 Header Checksum Error: the IPv4 header
133*4882a593Smuzhiyun * has a checksum violation.
134*4882a593Smuzhiyun * - 3 = IP Malformed Header: the packet is not long
135*4882a593Smuzhiyun * enough to contain the IP header.
136*4882a593Smuzhiyun * - 4 = IP Malformed: the packet is not long enough
137*4882a593Smuzhiyun * to contain the bytes indicated by the IP
138*4882a593Smuzhiyun * header. Pad is allowed.
139*4882a593Smuzhiyun * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6
140*4882a593Smuzhiyun * Hop Count field are zero.
141*4882a593Smuzhiyun * - 6 = IP Options
142*4882a593Smuzhiyun */
143*4882a593Smuzhiyun uint64_t IP_exc:1;
144*4882a593Smuzhiyun /*
145*4882a593Smuzhiyun * Set if the hardware determined that the packet is a
146*4882a593Smuzhiyun * broadcast.
147*4882a593Smuzhiyun */
148*4882a593Smuzhiyun uint64_t is_bcast:1;
149*4882a593Smuzhiyun /*
150*4882a593Smuzhiyun * St if the hardware determined that the packet is a
151*4882a593Smuzhiyun * multi-cast.
152*4882a593Smuzhiyun */
153*4882a593Smuzhiyun uint64_t is_mcast:1;
154*4882a593Smuzhiyun /*
155*4882a593Smuzhiyun * Set if the packet may not be IP (must be zero in
156*4882a593Smuzhiyun * this case).
157*4882a593Smuzhiyun */
158*4882a593Smuzhiyun uint64_t not_IP:1;
159*4882a593Smuzhiyun /*
160*4882a593Smuzhiyun * The receive interface hardware detected a receive
161*4882a593Smuzhiyun * error (must be zero in this case).
162*4882a593Smuzhiyun */
163*4882a593Smuzhiyun uint64_t rcv_error:1;
164*4882a593Smuzhiyun /* lower err_code = first-level descriptor of the
165*4882a593Smuzhiyun * work */
166*4882a593Smuzhiyun /* zero for packet submitted by hardware that isn't on
167*4882a593Smuzhiyun * the slow path */
168*4882a593Smuzhiyun /* type is cvmx_pip_err_t */
169*4882a593Smuzhiyun uint64_t err_code:8;
170*4882a593Smuzhiyun #else
171*4882a593Smuzhiyun uint64_t err_code:8;
172*4882a593Smuzhiyun uint64_t rcv_error:1;
173*4882a593Smuzhiyun uint64_t not_IP:1;
174*4882a593Smuzhiyun uint64_t is_mcast:1;
175*4882a593Smuzhiyun uint64_t is_bcast:1;
176*4882a593Smuzhiyun uint64_t IP_exc:1;
177*4882a593Smuzhiyun uint64_t is_frag:1;
178*4882a593Smuzhiyun uint64_t L4_error:1;
179*4882a593Smuzhiyun uint64_t software:1;
180*4882a593Smuzhiyun uint64_t is_v6:1;
181*4882a593Smuzhiyun uint64_t dec_ipsec:1;
182*4882a593Smuzhiyun uint64_t tcp_or_udp:1;
183*4882a593Smuzhiyun uint64_t dec_ipcomp:1;
184*4882a593Smuzhiyun uint64_t unassigned2:4;
185*4882a593Smuzhiyun uint64_t unassigned2a:4;
186*4882a593Smuzhiyun uint64_t pr:4;
187*4882a593Smuzhiyun uint64_t vlan_id:12;
188*4882a593Smuzhiyun uint64_t vlan_cfi:1;
189*4882a593Smuzhiyun uint64_t unassigned:1;
190*4882a593Smuzhiyun uint64_t vlan_stacked:1;
191*4882a593Smuzhiyun uint64_t vlan_valid:1;
192*4882a593Smuzhiyun uint64_t ip_offset:8;
193*4882a593Smuzhiyun uint64_t bufs:8;
194*4882a593Smuzhiyun #endif
195*4882a593Smuzhiyun } s;
196*4882a593Smuzhiyun struct {
197*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
198*4882a593Smuzhiyun uint64_t bufs:8;
199*4882a593Smuzhiyun uint64_t ip_offset:8;
200*4882a593Smuzhiyun uint64_t vlan_valid:1;
201*4882a593Smuzhiyun uint64_t vlan_stacked:1;
202*4882a593Smuzhiyun uint64_t unassigned:1;
203*4882a593Smuzhiyun uint64_t vlan_cfi:1;
204*4882a593Smuzhiyun uint64_t vlan_id:12;
205*4882a593Smuzhiyun uint64_t port:12; /* MAC/PIP port number. */
206*4882a593Smuzhiyun uint64_t dec_ipcomp:1;
207*4882a593Smuzhiyun uint64_t tcp_or_udp:1;
208*4882a593Smuzhiyun uint64_t dec_ipsec:1;
209*4882a593Smuzhiyun uint64_t is_v6:1;
210*4882a593Smuzhiyun uint64_t software:1;
211*4882a593Smuzhiyun uint64_t L4_error:1;
212*4882a593Smuzhiyun uint64_t is_frag:1;
213*4882a593Smuzhiyun uint64_t IP_exc:1;
214*4882a593Smuzhiyun uint64_t is_bcast:1;
215*4882a593Smuzhiyun uint64_t is_mcast:1;
216*4882a593Smuzhiyun uint64_t not_IP:1;
217*4882a593Smuzhiyun uint64_t rcv_error:1;
218*4882a593Smuzhiyun uint64_t err_code:8;
219*4882a593Smuzhiyun #else
220*4882a593Smuzhiyun uint64_t err_code:8;
221*4882a593Smuzhiyun uint64_t rcv_error:1;
222*4882a593Smuzhiyun uint64_t not_IP:1;
223*4882a593Smuzhiyun uint64_t is_mcast:1;
224*4882a593Smuzhiyun uint64_t is_bcast:1;
225*4882a593Smuzhiyun uint64_t IP_exc:1;
226*4882a593Smuzhiyun uint64_t is_frag:1;
227*4882a593Smuzhiyun uint64_t L4_error:1;
228*4882a593Smuzhiyun uint64_t software:1;
229*4882a593Smuzhiyun uint64_t is_v6:1;
230*4882a593Smuzhiyun uint64_t dec_ipsec:1;
231*4882a593Smuzhiyun uint64_t tcp_or_udp:1;
232*4882a593Smuzhiyun uint64_t dec_ipcomp:1;
233*4882a593Smuzhiyun uint64_t port:12;
234*4882a593Smuzhiyun uint64_t vlan_id:12;
235*4882a593Smuzhiyun uint64_t vlan_cfi:1;
236*4882a593Smuzhiyun uint64_t unassigned:1;
237*4882a593Smuzhiyun uint64_t vlan_stacked:1;
238*4882a593Smuzhiyun uint64_t vlan_valid:1;
239*4882a593Smuzhiyun uint64_t ip_offset:8;
240*4882a593Smuzhiyun uint64_t bufs:8;
241*4882a593Smuzhiyun #endif
242*4882a593Smuzhiyun } s_cn68xx;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun /* use this to get at the 16 vlan bits */
245*4882a593Smuzhiyun struct {
246*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
247*4882a593Smuzhiyun uint64_t unused1:16;
248*4882a593Smuzhiyun uint64_t vlan:16;
249*4882a593Smuzhiyun uint64_t unused2:32;
250*4882a593Smuzhiyun #else
251*4882a593Smuzhiyun uint64_t unused2:32;
252*4882a593Smuzhiyun uint64_t vlan:16;
253*4882a593Smuzhiyun uint64_t unused1:16;
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun #endif
256*4882a593Smuzhiyun } svlan;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /*
259*4882a593Smuzhiyun * use this struct if the hardware could not determine that
260*4882a593Smuzhiyun * the packet is ip.
261*4882a593Smuzhiyun */
262*4882a593Smuzhiyun struct {
263*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
264*4882a593Smuzhiyun /*
265*4882a593Smuzhiyun * HW sets this to the number of buffers used by this
266*4882a593Smuzhiyun * packet.
267*4882a593Smuzhiyun */
268*4882a593Smuzhiyun uint64_t bufs:8;
269*4882a593Smuzhiyun uint64_t unused:8;
270*4882a593Smuzhiyun /* set to 1 if we found DSA/VLAN in the L2 */
271*4882a593Smuzhiyun uint64_t vlan_valid:1;
272*4882a593Smuzhiyun /* Set to 1 if the DSA/VLAN tag is stacked */
273*4882a593Smuzhiyun uint64_t vlan_stacked:1;
274*4882a593Smuzhiyun uint64_t unassigned:1;
275*4882a593Smuzhiyun /*
276*4882a593Smuzhiyun * HW sets to the DSA/VLAN CFI flag (valid when
277*4882a593Smuzhiyun * vlan_valid)
278*4882a593Smuzhiyun */
279*4882a593Smuzhiyun uint64_t vlan_cfi:1;
280*4882a593Smuzhiyun /*
281*4882a593Smuzhiyun * HW sets to the DSA/VLAN_ID field (valid when
282*4882a593Smuzhiyun * vlan_valid).
283*4882a593Smuzhiyun */
284*4882a593Smuzhiyun uint64_t vlan_id:12;
285*4882a593Smuzhiyun /*
286*4882a593Smuzhiyun * Ring Identifier (if PCIe). Requires
287*4882a593Smuzhiyun * PIP_GBL_CTL[RING_EN]=1
288*4882a593Smuzhiyun */
289*4882a593Smuzhiyun uint64_t pr:4;
290*4882a593Smuzhiyun uint64_t unassigned2:12;
291*4882a593Smuzhiyun /*
292*4882a593Smuzhiyun * reserved for software use, hardware will clear on
293*4882a593Smuzhiyun * packet creation.
294*4882a593Smuzhiyun */
295*4882a593Smuzhiyun uint64_t software:1;
296*4882a593Smuzhiyun uint64_t unassigned3:1;
297*4882a593Smuzhiyun /*
298*4882a593Smuzhiyun * set if the hardware determined that the packet is
299*4882a593Smuzhiyun * rarp.
300*4882a593Smuzhiyun */
301*4882a593Smuzhiyun uint64_t is_rarp:1;
302*4882a593Smuzhiyun /*
303*4882a593Smuzhiyun * set if the hardware determined that the packet is
304*4882a593Smuzhiyun * arp
305*4882a593Smuzhiyun */
306*4882a593Smuzhiyun uint64_t is_arp:1;
307*4882a593Smuzhiyun /*
308*4882a593Smuzhiyun * set if the hardware determined that the packet is a
309*4882a593Smuzhiyun * broadcast.
310*4882a593Smuzhiyun */
311*4882a593Smuzhiyun uint64_t is_bcast:1;
312*4882a593Smuzhiyun /*
313*4882a593Smuzhiyun * set if the hardware determined that the packet is a
314*4882a593Smuzhiyun * multi-cast
315*4882a593Smuzhiyun */
316*4882a593Smuzhiyun uint64_t is_mcast:1;
317*4882a593Smuzhiyun /*
318*4882a593Smuzhiyun * set if the packet may not be IP (must be one in
319*4882a593Smuzhiyun * this case)
320*4882a593Smuzhiyun */
321*4882a593Smuzhiyun uint64_t not_IP:1;
322*4882a593Smuzhiyun /* The receive interface hardware detected a receive
323*4882a593Smuzhiyun * error. Failure indicated in err_code below,
324*4882a593Smuzhiyun * decode:
325*4882a593Smuzhiyun *
326*4882a593Smuzhiyun * - 1 = partial error: a packet was partially
327*4882a593Smuzhiyun * received, but internal buffering / bandwidth
328*4882a593Smuzhiyun * was not adequate to receive the entire
329*4882a593Smuzhiyun * packet.
330*4882a593Smuzhiyun * - 2 = jabber error: the RGMII packet was too large
331*4882a593Smuzhiyun * and is truncated.
332*4882a593Smuzhiyun * - 3 = overrun error: the RGMII packet is longer
333*4882a593Smuzhiyun * than allowed and had an FCS error.
334*4882a593Smuzhiyun * - 4 = oversize error: the RGMII packet is longer
335*4882a593Smuzhiyun * than allowed.
336*4882a593Smuzhiyun * - 5 = alignment error: the RGMII packet is not an
337*4882a593Smuzhiyun * integer number of bytes
338*4882a593Smuzhiyun * and had an FCS error (100M and 10M only).
339*4882a593Smuzhiyun * - 6 = fragment error: the RGMII packet is shorter
340*4882a593Smuzhiyun * than allowed and had an FCS error.
341*4882a593Smuzhiyun * - 7 = GMX FCS error: the RGMII packet had an FCS
342*4882a593Smuzhiyun * error.
343*4882a593Smuzhiyun * - 8 = undersize error: the RGMII packet is shorter
344*4882a593Smuzhiyun * than allowed.
345*4882a593Smuzhiyun * - 9 = extend error: the RGMII packet had an extend
346*4882a593Smuzhiyun * error.
347*4882a593Smuzhiyun * - 10 = length mismatch error: the RGMII packet had
348*4882a593Smuzhiyun * a length that did not match the length field
349*4882a593Smuzhiyun * in the L2 HDR.
350*4882a593Smuzhiyun * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII
351*4882a593Smuzhiyun * packet had one or more data reception errors
352*4882a593Smuzhiyun * (RXERR) or the SPI4 packet had one or more
353*4882a593Smuzhiyun * DIP4 errors.
354*4882a593Smuzhiyun * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII
355*4882a593Smuzhiyun * packet was not large enough to cover the
356*4882a593Smuzhiyun * skipped bytes or the SPI4 packet was
357*4882a593Smuzhiyun * terminated with an About EOPS.
358*4882a593Smuzhiyun * - 13 = RGMII nibble error/SPI4 Port NXA Error: the
359*4882a593Smuzhiyun * RGMII packet had a studder error (data not
360*4882a593Smuzhiyun * repeated - 10/100M only) or the SPI4 packet
361*4882a593Smuzhiyun * was sent to an NXA.
362*4882a593Smuzhiyun * - 16 = FCS error: a SPI4.2 packet had an FCS error.
363*4882a593Smuzhiyun * - 17 = Skip error: a packet was not large enough to
364*4882a593Smuzhiyun * cover the skipped bytes.
365*4882a593Smuzhiyun * - 18 = L2 header malformed: the packet is not long
366*4882a593Smuzhiyun * enough to contain the L2.
367*4882a593Smuzhiyun */
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun uint64_t rcv_error:1;
370*4882a593Smuzhiyun /*
371*4882a593Smuzhiyun * lower err_code = first-level descriptor of the
372*4882a593Smuzhiyun * work
373*4882a593Smuzhiyun */
374*4882a593Smuzhiyun /*
375*4882a593Smuzhiyun * zero for packet submitted by hardware that isn't on
376*4882a593Smuzhiyun * the slow path
377*4882a593Smuzhiyun */
378*4882a593Smuzhiyun /* type is cvmx_pip_err_t (union, so can't use directly */
379*4882a593Smuzhiyun uint64_t err_code:8;
380*4882a593Smuzhiyun #else
381*4882a593Smuzhiyun uint64_t err_code:8;
382*4882a593Smuzhiyun uint64_t rcv_error:1;
383*4882a593Smuzhiyun uint64_t not_IP:1;
384*4882a593Smuzhiyun uint64_t is_mcast:1;
385*4882a593Smuzhiyun uint64_t is_bcast:1;
386*4882a593Smuzhiyun uint64_t is_arp:1;
387*4882a593Smuzhiyun uint64_t is_rarp:1;
388*4882a593Smuzhiyun uint64_t unassigned3:1;
389*4882a593Smuzhiyun uint64_t software:1;
390*4882a593Smuzhiyun uint64_t unassigned2:4;
391*4882a593Smuzhiyun uint64_t unassigned2a:8;
392*4882a593Smuzhiyun uint64_t pr:4;
393*4882a593Smuzhiyun uint64_t vlan_id:12;
394*4882a593Smuzhiyun uint64_t vlan_cfi:1;
395*4882a593Smuzhiyun uint64_t unassigned:1;
396*4882a593Smuzhiyun uint64_t vlan_stacked:1;
397*4882a593Smuzhiyun uint64_t vlan_valid:1;
398*4882a593Smuzhiyun uint64_t unused:8;
399*4882a593Smuzhiyun uint64_t bufs:8;
400*4882a593Smuzhiyun #endif
401*4882a593Smuzhiyun } snoip;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun } cvmx_pip_wqe_word2;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun union cvmx_pip_wqe_word0 {
406*4882a593Smuzhiyun struct {
407*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
408*4882a593Smuzhiyun /**
409*4882a593Smuzhiyun * raw chksum result generated by the HW
410*4882a593Smuzhiyun */
411*4882a593Smuzhiyun uint16_t hw_chksum;
412*4882a593Smuzhiyun /**
413*4882a593Smuzhiyun * Field unused by hardware - available for software
414*4882a593Smuzhiyun */
415*4882a593Smuzhiyun uint8_t unused;
416*4882a593Smuzhiyun /**
417*4882a593Smuzhiyun * Next pointer used by hardware for list maintenance.
418*4882a593Smuzhiyun * May be written/read by HW before the work queue
419*4882a593Smuzhiyun * entry is scheduled to a PP (Only 36 bits used in
420*4882a593Smuzhiyun * Octeon 1)
421*4882a593Smuzhiyun */
422*4882a593Smuzhiyun uint64_t next_ptr:40;
423*4882a593Smuzhiyun #else
424*4882a593Smuzhiyun uint64_t next_ptr:40;
425*4882a593Smuzhiyun uint8_t unused;
426*4882a593Smuzhiyun uint16_t hw_chksum;
427*4882a593Smuzhiyun #endif
428*4882a593Smuzhiyun } cn38xx;
429*4882a593Smuzhiyun struct {
430*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
431*4882a593Smuzhiyun uint64_t l4ptr:8; /* 56..63 */
432*4882a593Smuzhiyun uint64_t unused0:8; /* 48..55 */
433*4882a593Smuzhiyun uint64_t l3ptr:8; /* 40..47 */
434*4882a593Smuzhiyun uint64_t l2ptr:8; /* 32..39 */
435*4882a593Smuzhiyun uint64_t unused1:18; /* 14..31 */
436*4882a593Smuzhiyun uint64_t bpid:6; /* 8..13 */
437*4882a593Smuzhiyun uint64_t unused2:2; /* 6..7 */
438*4882a593Smuzhiyun uint64_t pknd:6; /* 0..5 */
439*4882a593Smuzhiyun #else
440*4882a593Smuzhiyun uint64_t pknd:6; /* 0..5 */
441*4882a593Smuzhiyun uint64_t unused2:2; /* 6..7 */
442*4882a593Smuzhiyun uint64_t bpid:6; /* 8..13 */
443*4882a593Smuzhiyun uint64_t unused1:18; /* 14..31 */
444*4882a593Smuzhiyun uint64_t l2ptr:8; /* 32..39 */
445*4882a593Smuzhiyun uint64_t l3ptr:8; /* 40..47 */
446*4882a593Smuzhiyun uint64_t unused0:8; /* 48..55 */
447*4882a593Smuzhiyun uint64_t l4ptr:8; /* 56..63 */
448*4882a593Smuzhiyun #endif
449*4882a593Smuzhiyun } cn68xx;
450*4882a593Smuzhiyun };
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun union cvmx_wqe_word0 {
453*4882a593Smuzhiyun uint64_t u64;
454*4882a593Smuzhiyun union cvmx_pip_wqe_word0 pip;
455*4882a593Smuzhiyun };
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun union cvmx_wqe_word1 {
458*4882a593Smuzhiyun uint64_t u64;
459*4882a593Smuzhiyun struct {
460*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
461*4882a593Smuzhiyun uint64_t len:16;
462*4882a593Smuzhiyun uint64_t varies:14;
463*4882a593Smuzhiyun /**
464*4882a593Smuzhiyun * the type of the tag (ORDERED, ATOMIC, NULL)
465*4882a593Smuzhiyun */
466*4882a593Smuzhiyun uint64_t tag_type:2;
467*4882a593Smuzhiyun uint64_t tag:32;
468*4882a593Smuzhiyun #else
469*4882a593Smuzhiyun uint64_t tag:32;
470*4882a593Smuzhiyun uint64_t tag_type:2;
471*4882a593Smuzhiyun uint64_t varies:14;
472*4882a593Smuzhiyun uint64_t len:16;
473*4882a593Smuzhiyun #endif
474*4882a593Smuzhiyun };
475*4882a593Smuzhiyun struct {
476*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
477*4882a593Smuzhiyun uint64_t len:16;
478*4882a593Smuzhiyun uint64_t zero_0:1;
479*4882a593Smuzhiyun /**
480*4882a593Smuzhiyun * HW sets this to what it thought the priority of
481*4882a593Smuzhiyun * the input packet was
482*4882a593Smuzhiyun */
483*4882a593Smuzhiyun uint64_t qos:3;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun uint64_t zero_1:1;
486*4882a593Smuzhiyun /**
487*4882a593Smuzhiyun * the group that the work queue entry will be scheduled to
488*4882a593Smuzhiyun */
489*4882a593Smuzhiyun uint64_t grp:6;
490*4882a593Smuzhiyun uint64_t zero_2:3;
491*4882a593Smuzhiyun uint64_t tag_type:2;
492*4882a593Smuzhiyun uint64_t tag:32;
493*4882a593Smuzhiyun #else
494*4882a593Smuzhiyun uint64_t tag:32;
495*4882a593Smuzhiyun uint64_t tag_type:2;
496*4882a593Smuzhiyun uint64_t zero_2:3;
497*4882a593Smuzhiyun uint64_t grp:6;
498*4882a593Smuzhiyun uint64_t zero_1:1;
499*4882a593Smuzhiyun uint64_t qos:3;
500*4882a593Smuzhiyun uint64_t zero_0:1;
501*4882a593Smuzhiyun uint64_t len:16;
502*4882a593Smuzhiyun #endif
503*4882a593Smuzhiyun } cn68xx;
504*4882a593Smuzhiyun struct {
505*4882a593Smuzhiyun #ifdef __BIG_ENDIAN_BITFIELD
506*4882a593Smuzhiyun /**
507*4882a593Smuzhiyun * HW sets to the total number of bytes in the packet
508*4882a593Smuzhiyun */
509*4882a593Smuzhiyun uint64_t len:16;
510*4882a593Smuzhiyun /**
511*4882a593Smuzhiyun * HW sets this to input physical port
512*4882a593Smuzhiyun */
513*4882a593Smuzhiyun uint64_t ipprt:6;
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun /**
516*4882a593Smuzhiyun * HW sets this to what it thought the priority of
517*4882a593Smuzhiyun * the input packet was
518*4882a593Smuzhiyun */
519*4882a593Smuzhiyun uint64_t qos:3;
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun /**
522*4882a593Smuzhiyun * the group that the work queue entry will be scheduled to
523*4882a593Smuzhiyun */
524*4882a593Smuzhiyun uint64_t grp:4;
525*4882a593Smuzhiyun /**
526*4882a593Smuzhiyun * the type of the tag (ORDERED, ATOMIC, NULL)
527*4882a593Smuzhiyun */
528*4882a593Smuzhiyun uint64_t tag_type:3;
529*4882a593Smuzhiyun /**
530*4882a593Smuzhiyun * the synchronization/ordering tag
531*4882a593Smuzhiyun */
532*4882a593Smuzhiyun uint64_t tag:32;
533*4882a593Smuzhiyun #else
534*4882a593Smuzhiyun uint64_t tag:32;
535*4882a593Smuzhiyun uint64_t tag_type:2;
536*4882a593Smuzhiyun uint64_t zero_2:1;
537*4882a593Smuzhiyun uint64_t grp:4;
538*4882a593Smuzhiyun uint64_t qos:3;
539*4882a593Smuzhiyun uint64_t ipprt:6;
540*4882a593Smuzhiyun uint64_t len:16;
541*4882a593Smuzhiyun #endif
542*4882a593Smuzhiyun } cn38xx;
543*4882a593Smuzhiyun };
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun /**
546*4882a593Smuzhiyun * Work queue entry format
547*4882a593Smuzhiyun *
548*4882a593Smuzhiyun * must be 8-byte aligned
549*4882a593Smuzhiyun */
550*4882a593Smuzhiyun struct cvmx_wqe {
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun /*****************************************************************
553*4882a593Smuzhiyun * WORD 0
554*4882a593Smuzhiyun * HW WRITE: the following 64 bits are filled by HW when a packet arrives
555*4882a593Smuzhiyun */
556*4882a593Smuzhiyun union cvmx_wqe_word0 word0;
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun /*****************************************************************
559*4882a593Smuzhiyun * WORD 1
560*4882a593Smuzhiyun * HW WRITE: the following 64 bits are filled by HW when a packet arrives
561*4882a593Smuzhiyun */
562*4882a593Smuzhiyun union cvmx_wqe_word1 word1;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun /**
565*4882a593Smuzhiyun * WORD 2 HW WRITE: the following 64-bits are filled in by
566*4882a593Smuzhiyun * hardware when a packet arrives This indicates a variety of
567*4882a593Smuzhiyun * status and error conditions.
568*4882a593Smuzhiyun */
569*4882a593Smuzhiyun cvmx_pip_wqe_word2 word2;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun /**
572*4882a593Smuzhiyun * Pointer to the first segment of the packet.
573*4882a593Smuzhiyun */
574*4882a593Smuzhiyun union cvmx_buf_ptr packet_ptr;
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun /**
577*4882a593Smuzhiyun * HW WRITE: octeon will fill in a programmable amount from the
578*4882a593Smuzhiyun * packet, up to (at most, but perhaps less) the amount
579*4882a593Smuzhiyun * needed to fill the work queue entry to 128 bytes
580*4882a593Smuzhiyun *
581*4882a593Smuzhiyun * If the packet is recognized to be IP, the hardware starts
582*4882a593Smuzhiyun * (except that the IPv4 header is padded for appropriate
583*4882a593Smuzhiyun * alignment) writing here where the IP header starts. If the
584*4882a593Smuzhiyun * packet is not recognized to be IP, the hardware starts
585*4882a593Smuzhiyun * writing the beginning of the packet here.
586*4882a593Smuzhiyun */
587*4882a593Smuzhiyun uint8_t packet_data[96];
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun /**
590*4882a593Smuzhiyun * If desired, SW can make the work Q entry any length. For the
591*4882a593Smuzhiyun * purposes of discussion here, Assume 128B always, as this is all that
592*4882a593Smuzhiyun * the hardware deals with.
593*4882a593Smuzhiyun *
594*4882a593Smuzhiyun */
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun } CVMX_CACHE_LINE_ALIGNED;
597*4882a593Smuzhiyun
cvmx_wqe_get_port(struct cvmx_wqe * work)598*4882a593Smuzhiyun static inline int cvmx_wqe_get_port(struct cvmx_wqe *work)
599*4882a593Smuzhiyun {
600*4882a593Smuzhiyun int port;
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
603*4882a593Smuzhiyun port = work->word2.s_cn68xx.port;
604*4882a593Smuzhiyun else
605*4882a593Smuzhiyun port = work->word1.cn38xx.ipprt;
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun return port;
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun
cvmx_wqe_set_port(struct cvmx_wqe * work,int port)610*4882a593Smuzhiyun static inline void cvmx_wqe_set_port(struct cvmx_wqe *work, int port)
611*4882a593Smuzhiyun {
612*4882a593Smuzhiyun if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
613*4882a593Smuzhiyun work->word2.s_cn68xx.port = port;
614*4882a593Smuzhiyun else
615*4882a593Smuzhiyun work->word1.cn38xx.ipprt = port;
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun
cvmx_wqe_get_grp(struct cvmx_wqe * work)618*4882a593Smuzhiyun static inline int cvmx_wqe_get_grp(struct cvmx_wqe *work)
619*4882a593Smuzhiyun {
620*4882a593Smuzhiyun int grp;
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
623*4882a593Smuzhiyun grp = work->word1.cn68xx.grp;
624*4882a593Smuzhiyun else
625*4882a593Smuzhiyun grp = work->word1.cn38xx.grp;
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun return grp;
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun
cvmx_wqe_set_grp(struct cvmx_wqe * work,int grp)630*4882a593Smuzhiyun static inline void cvmx_wqe_set_grp(struct cvmx_wqe *work, int grp)
631*4882a593Smuzhiyun {
632*4882a593Smuzhiyun if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
633*4882a593Smuzhiyun work->word1.cn68xx.grp = grp;
634*4882a593Smuzhiyun else
635*4882a593Smuzhiyun work->word1.cn38xx.grp = grp;
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
cvmx_wqe_get_qos(struct cvmx_wqe * work)638*4882a593Smuzhiyun static inline int cvmx_wqe_get_qos(struct cvmx_wqe *work)
639*4882a593Smuzhiyun {
640*4882a593Smuzhiyun int qos;
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
643*4882a593Smuzhiyun qos = work->word1.cn68xx.qos;
644*4882a593Smuzhiyun else
645*4882a593Smuzhiyun qos = work->word1.cn38xx.qos;
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun return qos;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun
cvmx_wqe_set_qos(struct cvmx_wqe * work,int qos)650*4882a593Smuzhiyun static inline void cvmx_wqe_set_qos(struct cvmx_wqe *work, int qos)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
653*4882a593Smuzhiyun work->word1.cn68xx.qos = qos;
654*4882a593Smuzhiyun else
655*4882a593Smuzhiyun work->word1.cn38xx.qos = qos;
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun
658*4882a593Smuzhiyun #endif /* __CVMX_WQE_H__ */
659