1 /***********************license start***************
2 * Author: Cavium Networks
4 * Contact: support@caviumnetworks.com
5 * This file is part of the OCTEON SDK
7 * Copyright (c) 2003-2008 Cavium Networks
9 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License, Version 2, as
11 * published by the Free Software Foundation.
13 * This file is distributed in the hope that it will be useful, but
14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16 * NONINFRINGEMENT. See the GNU General Public License for more
19 * You should have received a copy of the GNU General Public License
20 * along with this file; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * or visit http://www.gnu.org/licenses/.
24 * This file may also be available under a different license from Cavium.
25 * Contact Cavium Networks for more information
26 ***********************license end**************************************/
30 * This header file defines the work queue entry (wqe) data structure.
31 * Since this is a commonly used structure that depends on structures
32 * from several hardware blocks, those definitions have been placed
33 * in this file to create a single point of definition of the wqe
35 * Data structures are still named according to the block that they
40 #ifndef __CVMX_WQE_H__
41 #define __CVMX_WQE_H__
43 #include <asm/octeon/cvmx-packet.h>
46 #define OCT_TAG_TYPE_STRING(x) \
47 (((x) == CVMX_POW_TAG_TYPE_ORDERED) ? "ORDERED" : \
48 (((x) == CVMX_POW_TAG_TYPE_ATOMIC) ? "ATOMIC" : \
49 (((x) == CVMX_POW_TAG_TYPE_NULL) ? "NULL" : \
53 * HW decode / err_code in work queue entry
58 /* Use this struct if the hardware determines that the packet is IP */
60 #ifdef __BIG_ENDIAN_BITFIELD
61 /* HW sets this to the number of buffers used by this packet */
63 /* HW sets to the number of L2 bytes prior to the IP */
65 /* set to 1 if we found DSA/VLAN in the L2 */
66 uint64_t vlan_valid
:1;
67 /* Set to 1 if the DSA/VLAN tag is stacked */
68 uint64_t vlan_stacked
:1;
69 uint64_t unassigned
:1;
70 /* HW sets to the DSA/VLAN CFI flag (valid when vlan_valid) */
72 /* HW sets to the DSA/VLAN_ID field (valid when vlan_valid) */
74 /* Ring Identifier (if PCIe). Requires PIP_GBL_CTL[RING_EN]=1 */
76 uint64_t unassigned2
:8;
77 /* the packet needs to be decompressed */
78 uint64_t dec_ipcomp
:1;
79 /* the packet is either TCP or UDP */
80 uint64_t tcp_or_udp
:1;
81 /* the packet needs to be decrypted (ESP or AH) */
83 /* the packet is IPv6 */
87 * (rcv_error, not_IP, IP_exc, is_frag, L4_error,
92 * reserved for software use, hardware will clear on
96 /* exceptional conditions below */
97 /* the receive interface hardware detected an L4 error
98 * (only applies if !is_frag) (only applies if
99 * !rcv_error && !not_IP && !IP_exc && !is_frag)
100 * failure indicated in err_code below, decode:
103 * - 2 = L4 Checksum Error: the L4 checksum value is
104 * - 3 = UDP Length Error: The UDP length field would
105 * make the UDP data longer than what remains in
106 * the IP packet (as defined by the IP header
108 * - 4 = Bad L4 Port: either the source or destination
110 * - 8 = TCP FIN Only: the packet is TCP and only the
112 * - 9 = TCP No Flags: the packet is TCP and no flags
114 * - 10 = TCP FIN RST: the packet is TCP and both FIN
116 * - 11 = TCP SYN URG: the packet is TCP and both SYN
118 * - 12 = TCP SYN RST: the packet is TCP and both SYN
120 * - 13 = TCP SYN FIN: the packet is TCP and both SYN
124 /* set if the packet is a fragment */
126 /* the receive interface hardware detected an IP error
127 * / exception (only applies if !rcv_error && !not_IP)
128 * failure indicated in err_code below, decode:
130 * - 1 = Not IP: the IP version field is neither 4 nor
132 * - 2 = IPv4 Header Checksum Error: the IPv4 header
133 * has a checksum violation.
134 * - 3 = IP Malformed Header: the packet is not long
135 * enough to contain the IP header.
136 * - 4 = IP Malformed: the packet is not long enough
137 * to contain the bytes indicated by the IP
138 * header. Pad is allowed.
139 * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6
140 * Hop Count field are zero.
145 * Set if the hardware determined that the packet is a
150 * St if the hardware determined that the packet is a
155 * Set if the packet may not be IP (must be zero in
160 * The receive interface hardware detected a receive
161 * error (must be zero in this case).
163 uint64_t rcv_error
:1;
164 /* lower err_code = first-level descriptor of the
166 /* zero for packet submitted by hardware that isn't on
168 /* type is cvmx_pip_err_t */
172 uint64_t rcv_error
:1;
181 uint64_t dec_ipsec
:1;
182 uint64_t tcp_or_udp
:1;
183 uint64_t dec_ipcomp
:1;
184 uint64_t unassigned2
:4;
185 uint64_t unassigned2a
:4;
189 uint64_t unassigned
:1;
190 uint64_t vlan_stacked
:1;
191 uint64_t vlan_valid
:1;
192 uint64_t ip_offset
:8;
197 #ifdef __BIG_ENDIAN_BITFIELD
199 uint64_t ip_offset
:8;
200 uint64_t vlan_valid
:1;
201 uint64_t vlan_stacked
:1;
202 uint64_t unassigned
:1;
205 uint64_t port
:12; /* MAC/PIP port number. */
206 uint64_t dec_ipcomp
:1;
207 uint64_t tcp_or_udp
:1;
208 uint64_t dec_ipsec
:1;
217 uint64_t rcv_error
:1;
221 uint64_t rcv_error
:1;
230 uint64_t dec_ipsec
:1;
231 uint64_t tcp_or_udp
:1;
232 uint64_t dec_ipcomp
:1;
236 uint64_t unassigned
:1;
237 uint64_t vlan_stacked
:1;
238 uint64_t vlan_valid
:1;
239 uint64_t ip_offset
:8;
244 /* use this to get at the 16 vlan bits */
246 #ifdef __BIG_ENDIAN_BITFIELD
259 * use this struct if the hardware could not determine that
263 #ifdef __BIG_ENDIAN_BITFIELD
265 * HW sets this to the number of buffers used by this
270 /* set to 1 if we found DSA/VLAN in the L2 */
271 uint64_t vlan_valid
:1;
272 /* Set to 1 if the DSA/VLAN tag is stacked */
273 uint64_t vlan_stacked
:1;
274 uint64_t unassigned
:1;
276 * HW sets to the DSA/VLAN CFI flag (valid when
281 * HW sets to the DSA/VLAN_ID field (valid when
286 * Ring Identifier (if PCIe). Requires
287 * PIP_GBL_CTL[RING_EN]=1
290 uint64_t unassigned2
:12;
292 * reserved for software use, hardware will clear on
296 uint64_t unassigned3
:1;
298 * set if the hardware determined that the packet is
303 * set if the hardware determined that the packet is
308 * set if the hardware determined that the packet is a
313 * set if the hardware determined that the packet is a
318 * set if the packet may not be IP (must be one in
322 /* The receive interface hardware detected a receive
323 * error. Failure indicated in err_code below,
326 * - 1 = partial error: a packet was partially
327 * received, but internal buffering / bandwidth
328 * was not adequate to receive the entire
330 * - 2 = jabber error: the RGMII packet was too large
332 * - 3 = overrun error: the RGMII packet is longer
333 * than allowed and had an FCS error.
334 * - 4 = oversize error: the RGMII packet is longer
336 * - 5 = alignment error: the RGMII packet is not an
337 * integer number of bytes
338 * and had an FCS error (100M and 10M only).
339 * - 6 = fragment error: the RGMII packet is shorter
340 * than allowed and had an FCS error.
341 * - 7 = GMX FCS error: the RGMII packet had an FCS
343 * - 8 = undersize error: the RGMII packet is shorter
345 * - 9 = extend error: the RGMII packet had an extend
347 * - 10 = length mismatch error: the RGMII packet had
348 * a length that did not match the length field
350 * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII
351 * packet had one or more data reception errors
352 * (RXERR) or the SPI4 packet had one or more
354 * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII
355 * packet was not large enough to cover the
356 * skipped bytes or the SPI4 packet was
357 * terminated with an About EOPS.
358 * - 13 = RGMII nibble error/SPI4 Port NXA Error: the
359 * RGMII packet had a studder error (data not
360 * repeated - 10/100M only) or the SPI4 packet
361 * was sent to an NXA.
362 * - 16 = FCS error: a SPI4.2 packet had an FCS error.
363 * - 17 = Skip error: a packet was not large enough to
364 * cover the skipped bytes.
365 * - 18 = L2 header malformed: the packet is not long
366 * enough to contain the L2.
369 uint64_t rcv_error
:1;
371 * lower err_code = first-level descriptor of the
375 * zero for packet submitted by hardware that isn't on
378 /* type is cvmx_pip_err_t (union, so can't use directly */
382 uint64_t rcv_error
:1;
388 uint64_t unassigned3
:1;
390 uint64_t unassigned2
:4;
391 uint64_t unassigned2a
:8;
395 uint64_t unassigned
:1;
396 uint64_t vlan_stacked
:1;
397 uint64_t vlan_valid
:1;
403 } cvmx_pip_wqe_word2
;
405 union cvmx_pip_wqe_word0
{
407 #ifdef __BIG_ENDIAN_BITFIELD
409 * raw chksum result generated by the HW
413 * Field unused by hardware - available for software
417 * Next pointer used by hardware for list maintenance.
418 * May be written/read by HW before the work queue
419 * entry is scheduled to a PP (Only 36 bits used in
422 uint64_t next_ptr
:40;
424 uint64_t next_ptr
:40;
430 #ifdef __BIG_ENDIAN_BITFIELD
431 uint64_t l4ptr
:8; /* 56..63 */
432 uint64_t unused0
:8; /* 48..55 */
433 uint64_t l3ptr
:8; /* 40..47 */
434 uint64_t l2ptr
:8; /* 32..39 */
435 uint64_t unused1
:18; /* 14..31 */
436 uint64_t bpid
:6; /* 8..13 */
437 uint64_t unused2
:2; /* 6..7 */
438 uint64_t pknd
:6; /* 0..5 */
440 uint64_t pknd
:6; /* 0..5 */
441 uint64_t unused2
:2; /* 6..7 */
442 uint64_t bpid
:6; /* 8..13 */
443 uint64_t unused1
:18; /* 14..31 */
444 uint64_t l2ptr
:8; /* 32..39 */
445 uint64_t l3ptr
:8; /* 40..47 */
446 uint64_t unused0
:8; /* 48..55 */
447 uint64_t l4ptr
:8; /* 56..63 */
452 union cvmx_wqe_word0
{
454 union cvmx_pip_wqe_word0 pip
;
457 union cvmx_wqe_word1
{
460 #ifdef __BIG_ENDIAN_BITFIELD
464 * the type of the tag (ORDERED, ATOMIC, NULL)
476 #ifdef __BIG_ENDIAN_BITFIELD
480 * HW sets this to what it thought the priority of
481 * the input packet was
487 * the group that the work queue entry will be scheduled to
505 #ifdef __BIG_ENDIAN_BITFIELD
507 * HW sets to the total number of bytes in the packet
511 * HW sets this to input physical port
516 * HW sets this to what it thought the priority of
517 * the input packet was
522 * the group that the work queue entry will be scheduled to
526 * the type of the tag (ORDERED, ATOMIC, NULL)
530 * the synchronization/ordering tag
546 * Work queue entry format
548 * must be 8-byte aligned
552 /*****************************************************************
554 * HW WRITE: the following 64 bits are filled by HW when a packet arrives
556 union cvmx_wqe_word0 word0
;
558 /*****************************************************************
560 * HW WRITE: the following 64 bits are filled by HW when a packet arrives
562 union cvmx_wqe_word1 word1
;
565 * WORD 2 HW WRITE: the following 64-bits are filled in by
566 * hardware when a packet arrives This indicates a variety of
567 * status and error conditions.
569 cvmx_pip_wqe_word2 word2
;
572 * Pointer to the first segment of the packet.
574 union cvmx_buf_ptr packet_ptr
;
577 * HW WRITE: octeon will fill in a programmable amount from the
578 * packet, up to (at most, but perhaps less) the amount
579 * needed to fill the work queue entry to 128 bytes
581 * If the packet is recognized to be IP, the hardware starts
582 * (except that the IPv4 header is padded for appropriate
583 * alignment) writing here where the IP header starts. If the
584 * packet is not recognized to be IP, the hardware starts
585 * writing the beginning of the packet here.
587 uint8_t packet_data
[96];
590 * If desired, SW can make the work Q entry any length. For the
591 * purposes of discussion here, Assume 128B always, as this is all that
592 * the hardware deals with.
596 } CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t
;
598 static inline int cvmx_wqe_get_port(cvmx_wqe_t
*work
)
602 if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE
))
603 port
= work
->word2
.s_cn68xx
.port
;
605 port
= work
->word1
.cn38xx
.ipprt
;
610 static inline void cvmx_wqe_set_port(cvmx_wqe_t
*work
, int port
)
612 if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE
))
613 work
->word2
.s_cn68xx
.port
= port
;
615 work
->word1
.cn38xx
.ipprt
= port
;
618 static inline int cvmx_wqe_get_grp(cvmx_wqe_t
*work
)
622 if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE
))
623 grp
= work
->word1
.cn68xx
.grp
;
625 grp
= work
->word1
.cn38xx
.grp
;
630 static inline void cvmx_wqe_set_grp(cvmx_wqe_t
*work
, int grp
)
632 if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE
))
633 work
->word1
.cn68xx
.grp
= grp
;
635 work
->word1
.cn38xx
.grp
= grp
;
638 static inline int cvmx_wqe_get_qos(cvmx_wqe_t
*work
)
642 if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE
))
643 qos
= work
->word1
.cn68xx
.qos
;
645 qos
= work
->word1
.cn38xx
.qos
;
650 static inline void cvmx_wqe_set_qos(cvmx_wqe_t
*work
, int qos
)
652 if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE
))
653 work
->word1
.cn68xx
.qos
= qos
;
655 work
->word1
.cn38xx
.qos
= qos
;
658 #endif /* __CVMX_WQE_H__ */