1210284Sjmallett/***********************license start***************
2215990Sjmallett * Copyright (c) 2003-2010  Cavium Networks (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.
17210284Sjmallett
18215990Sjmallett *   * Neither the name of Cavium Networks 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.
22210284Sjmallett
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.
27210284Sjmallett
28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29215990Sjmallett * AND WITH ALL FAULTS AND CAVIUM  NETWORKS 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.
38215990Sjmallett ***********************license end**************************************/
39210284Sjmallett
40210284Sjmallett
41210284Sjmallett/**
42210284Sjmallett * @file
43210284Sjmallett *
44210284Sjmallett * Interface to the hardware Packet Input Processing unit.
45210284Sjmallett *
46215990Sjmallett * <hr>$Revision: 49504 $<hr>
47210284Sjmallett */
48210284Sjmallett
49210284Sjmallett
50210284Sjmallett#ifndef __CVMX_PIP_H__
51210284Sjmallett#define __CVMX_PIP_H__
52210284Sjmallett
53210284Sjmallett#include "cvmx-wqe.h"
54210284Sjmallett#include "cvmx-fpa.h"
55215990Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
56215990Sjmallett#include "cvmx-pip-defs.h"
57215990Sjmallett#else
58210284Sjmallett#ifndef CVMX_DONT_INCLUDE_CONFIG
59210284Sjmallett#include "executive-config.h"
60210284Sjmallett#endif
61215990Sjmallett#endif
62210284Sjmallett
63215990Sjmallett
64210284Sjmallett#ifdef	__cplusplus
65210284Sjmallettextern "C" {
66210284Sjmallett#endif
67210284Sjmallett
68215990Sjmallett#define CVMX_PIP_NUM_INPUT_PORTS                44
69210284Sjmallett
70215990Sjmallett/*
71215990Sjmallett * Encodes the different error and exception codes
72215990Sjmallett */
73210284Sjmalletttypedef enum
74210284Sjmallett{
75210284Sjmallett    CVMX_PIP_L4_NO_ERR       = 0ull,
76215990Sjmallett    /*        1  = TCP (UDP) packet not long enough to cover TCP (UDP) header */
77210284Sjmallett    CVMX_PIP_L4_MAL_ERR     = 1ull,
78215990Sjmallett    /*        2  = TCP/UDP checksum failure */
79210284Sjmallett    CVMX_PIP_CHK_ERR        = 2ull,
80215990Sjmallett    /*        3  = TCP/UDP length check (TCP/UDP length does not match IP length) */
81210284Sjmallett    CVMX_PIP_L4_LENGTH_ERR  = 3ull,
82215990Sjmallett    /*        4  = illegal TCP/UDP port (either source or dest port is zero) */
83210284Sjmallett    CVMX_PIP_BAD_PRT_ERR    = 4ull,
84215990Sjmallett    /*        8  = TCP flags = FIN only */
85210284Sjmallett    CVMX_PIP_TCP_FLG8_ERR   = 8ull,
86215990Sjmallett    /*        9  = TCP flags = 0 */
87210284Sjmallett    CVMX_PIP_TCP_FLG9_ERR   = 9ull,
88215990Sjmallett    /*        10 = TCP flags = FIN+RST+* */
89210284Sjmallett    CVMX_PIP_TCP_FLG10_ERR  = 10ull,
90215990Sjmallett    /*        11 = TCP flags = SYN+URG+* */
91210284Sjmallett    CVMX_PIP_TCP_FLG11_ERR  = 11ull,
92215990Sjmallett    /*        12 = TCP flags = SYN+RST+* */
93210284Sjmallett    CVMX_PIP_TCP_FLG12_ERR  = 12ull,
94215990Sjmallett    /*        13 = TCP flags = SYN+FIN+* */
95210284Sjmallett    CVMX_PIP_TCP_FLG13_ERR  = 13ull
96210284Sjmallett} cvmx_pip_l4_err_t;
97210284Sjmallett
98210284Sjmalletttypedef enum
99210284Sjmallett{
100210284Sjmallett
101210284Sjmallett    CVMX_PIP_IP_NO_ERR      = 0ull,
102215990Sjmallett    /*        1 = not IPv4 or IPv6 */
103210284Sjmallett    CVMX_PIP_NOT_IP        = 1ull,
104215990Sjmallett    /*        2 = IPv4 header checksum violation */
105210284Sjmallett    CVMX_PIP_IPV4_HDR_CHK  = 2ull,
106215990Sjmallett    /*        3 = malformed (packet not long enough to cover IP hdr) */
107210284Sjmallett    CVMX_PIP_IP_MAL_HDR    = 3ull,
108215990Sjmallett    /*        4 = malformed (packet not long enough to cover len in IP hdr) */
109210284Sjmallett    CVMX_PIP_IP_MAL_PKT    = 4ull,
110215990Sjmallett    /*        5 = TTL / hop count equal zero */
111210284Sjmallett    CVMX_PIP_TTL_HOP       = 5ull,
112215990Sjmallett    /*        6 = IPv4 options / IPv6 early extension headers */
113210284Sjmallett    CVMX_PIP_OPTS          = 6ull
114210284Sjmallett} cvmx_pip_ip_exc_t;
115210284Sjmallett
116210284Sjmallett
117210284Sjmallett/**
118210284Sjmallett * NOTES
119210284Sjmallett *       late collision (data received before collision)
120210284Sjmallett *            late collisions cannot be detected by the receiver
121210284Sjmallett *            they would appear as JAM bits which would appear as bad FCS
122210284Sjmallett *            or carrier extend error which is CVMX_PIP_EXTEND_ERR
123210284Sjmallett */
124210284Sjmalletttypedef enum
125210284Sjmallett{
126210284Sjmallett    /**
127210284Sjmallett     * No error
128210284Sjmallett     */
129210284Sjmallett    CVMX_PIP_RX_NO_ERR      = 0ull,
130210284Sjmallett
131215990Sjmallett    CVMX_PIP_PARTIAL_ERR   = 1ull,  /* RGM+SPI            1 = partially received packet (buffering/bandwidth not adequate) */
132215990Sjmallett    CVMX_PIP_JABBER_ERR    = 2ull,  /* RGM+SPI            2 = receive packet too large and truncated */
133215990Sjmallett    CVMX_PIP_OVER_FCS_ERR  = 3ull,  /* RGM                3 = max frame error (pkt len > max frame len) (with FCS error) */
134215990Sjmallett    CVMX_PIP_OVER_ERR      = 4ull,  /* RGM+SPI            4 = max frame error (pkt len > max frame len) */
135215990Sjmallett    CVMX_PIP_ALIGN_ERR     = 5ull,  /* RGM                5 = nibble error (data not byte multiple - 100M and 10M only) */
136215990Sjmallett    CVMX_PIP_UNDER_FCS_ERR = 6ull,  /* RGM                6 = min frame error (pkt len < min frame len) (with FCS error) */
137215990Sjmallett    CVMX_PIP_GMX_FCS_ERR   = 7ull,  /* RGM                7 = FCS error */
138215990Sjmallett    CVMX_PIP_UNDER_ERR     = 8ull,  /* RGM+SPI            8 = min frame error (pkt len < min frame len) */
139215990Sjmallett    CVMX_PIP_EXTEND_ERR    = 9ull,  /* RGM                9 = Frame carrier extend error */
140215990Sjmallett    CVMX_PIP_TERMINATE_ERR = 9ull,  /* XAUI               9 = Packet was terminated with an idle cycle */
141215990Sjmallett    CVMX_PIP_LENGTH_ERR    = 10ull, /* RGM               10 = length mismatch (len did not match len in L2 length/type) */
142215990Sjmallett    CVMX_PIP_DAT_ERR       = 11ull, /* RGM               11 = Frame error (some or all data bits marked err) */
143215990Sjmallett    CVMX_PIP_DIP_ERR       = 11ull, /*     SPI           11 = DIP4 error */
144215990Sjmallett    CVMX_PIP_SKIP_ERR      = 12ull, /* RGM               12 = packet was not large enough to pass the skipper - no inspection could occur */
145215990Sjmallett    CVMX_PIP_NIBBLE_ERR    = 13ull, /* RGM               13 = studder error (data not repeated - 100M and 10M only) */
146215990Sjmallett    CVMX_PIP_PIP_FCS       = 16L, /* RGM+SPI           16 = FCS error */
147215990Sjmallett    CVMX_PIP_PIP_SKIP_ERR  = 17L, /* RGM+SPI+PCI       17 = packet was not large enough to pass the skipper - no inspection could occur */
148215990Sjmallett    CVMX_PIP_PIP_L2_MAL_HDR= 18L, /* RGM+SPI+PCI       18 = malformed l2 (packet not long enough to cover L2 hdr) */
149215990Sjmallett    CVMX_PIP_PUNY_ERR      = 47L  /* SGMII             47 = PUNY error (packet was 4B or less when FCS stripping is enabled) */
150215990Sjmallett    /* NOTES
151215990Sjmallett     *       xx = late collision (data received before collision)
152215990Sjmallett     *            late collisions cannot be detected by the receiver
153215990Sjmallett     *            they would appear as JAM bits which would appear as bad FCS
154215990Sjmallett     *            or carrier extend error which is CVMX_PIP_EXTEND_ERR
155215990Sjmallett     */
156210284Sjmallett} cvmx_pip_rcv_err_t;
157210284Sjmallett
158210284Sjmallett/**
159210284Sjmallett * This defines the err_code field errors in the work Q entry
160210284Sjmallett */
161210284Sjmalletttypedef union
162210284Sjmallett{
163210284Sjmallett    cvmx_pip_l4_err_t  l4_err;
164210284Sjmallett    cvmx_pip_ip_exc_t  ip_exc;
165210284Sjmallett    cvmx_pip_rcv_err_t rcv_err;
166210284Sjmallett} cvmx_pip_err_t;
167210284Sjmallett
168210284Sjmallett
169210284Sjmallett/**
170210284Sjmallett * Status statistics for a port
171210284Sjmallett */
172210284Sjmalletttypedef struct
173210284Sjmallett{
174210284Sjmallett    uint32_t    dropped_octets;         /**< Inbound octets marked to be dropped by the IPD */
175210284Sjmallett    uint32_t    dropped_packets;        /**< Inbound packets marked to be dropped by the IPD */
176210284Sjmallett    uint32_t    pci_raw_packets;        /**< RAW PCI Packets received by PIP per port */
177210284Sjmallett    uint32_t    octets;                 /**< Number of octets processed by PIP */
178210284Sjmallett    uint32_t    packets;                /**< Number of packets processed by PIP */
179210284Sjmallett    uint32_t    multicast_packets;      /**< Number of indentified L2 multicast packets.
180210284Sjmallett                                            Does not include broadcast packets.
181210284Sjmallett                                            Only includes packets whose parse mode is
182210284Sjmallett                                            SKIP_TO_L2 */
183210284Sjmallett    uint32_t    broadcast_packets;      /**< Number of indentified L2 broadcast packets.
184210284Sjmallett                                            Does not include multicast packets.
185210284Sjmallett                                            Only includes packets whose parse mode is
186210284Sjmallett                                            SKIP_TO_L2 */
187210284Sjmallett    uint32_t    len_64_packets;         /**< Number of 64B packets */
188210284Sjmallett    uint32_t    len_65_127_packets;     /**< Number of 65-127B packets */
189210284Sjmallett    uint32_t    len_128_255_packets;    /**< Number of 128-255B packets */
190210284Sjmallett    uint32_t    len_256_511_packets;    /**< Number of 256-511B packets */
191210284Sjmallett    uint32_t    len_512_1023_packets;   /**< Number of 512-1023B packets */
192210284Sjmallett    uint32_t    len_1024_1518_packets;  /**< Number of 1024-1518B packets */
193210284Sjmallett    uint32_t    len_1519_max_packets;   /**< Number of 1519-max packets */
194210284Sjmallett    uint32_t    fcs_align_err_packets;  /**< Number of packets with FCS or Align opcode errors */
195210284Sjmallett    uint32_t    runt_packets;           /**< Number of packets with length < min */
196210284Sjmallett    uint32_t    runt_crc_packets;       /**< Number of packets with length < min and FCS error */
197210284Sjmallett    uint32_t    oversize_packets;       /**< Number of packets with length > max */
198210284Sjmallett    uint32_t    oversize_crc_packets;   /**< Number of packets with length > max and FCS error */
199210284Sjmallett    uint32_t    inb_packets;            /**< Number of packets without GMX/SPX/PCI errors received by PIP */
200210284Sjmallett    uint64_t    inb_octets;             /**< Total number of octets from all packets received by PIP, including CRC */
201210284Sjmallett    uint16_t    inb_errors;             /**< Number of packets with GMX/SPX/PCI errors received by PIP */
202210284Sjmallett} cvmx_pip_port_status_t;
203210284Sjmallett
204210284Sjmallett
205210284Sjmallett/**
206210284Sjmallett * Definition of the PIP custom header that can be prepended
207210284Sjmallett * to a packet by external hardware.
208210284Sjmallett */
209210284Sjmalletttypedef union
210210284Sjmallett{
211210284Sjmallett    uint64_t    u64;
212210284Sjmallett    struct
213210284Sjmallett    {
214210284Sjmallett        uint64_t                    rawfull     : 1;    /**< Documented as R - Set if the Packet is RAWFULL. If set,
215210284Sjmallett                                                            this header must be the full 8 bytes */
216210284Sjmallett        uint64_t                    reserved0   : 5;    /**< Must be zero */
217210284Sjmallett        cvmx_pip_port_parse_mode_t  parse_mode  : 2;    /**< PIP parse mode for this packet */
218210284Sjmallett        uint64_t                    reserved1   : 1;    /**< Must be zero */
219210284Sjmallett        uint64_t                    skip_len    : 7;    /**< Skip amount, including this header, to the beginning of the packet */
220215990Sjmallett        uint64_t                    reserved2   : 2;    /**< Must be zero */
221215990Sjmallett        uint64_t                    nqos        : 1;    /**< Must be 0 when PKT_INST_HDR[R] = 0.
222215990Sjmallett                                                             When set to 1, NQOS prevents PIP from directly using
223215990Sjmallett                                                             PKT_INST_HDR[QOS] for the QOS value in WQE.
224215990Sjmallett                                                             When PIP_GBL_CTL[IHMSK_DIS] = 1, Octeon2 does not use NQOS */
225215990Sjmallett        uint64_t                    ngrp        : 1;    /**< Must be 0 when PKT_INST_HDR[R] = 0.
226215990Sjmallett                                                             When set to 1, NGPR prevents PIP from directly using
227215990Sjmallett                                                             PKT_INST_HDR[GPR] for the GPR value in WQE.
228215990Sjmallett                                                             When PIP_GBL_CTL[IHMSK_DIS] = 1, Octeon2 does not use NGRP */
229215990Sjmallett        uint64_t                    ntt         : 1;    /**< Must be 0 when PKT_INST_HDR[R] = 0.
230215990Sjmallett                                                             When set to 1, NTT prevents PIP from directly using
231215990Sjmallett                                                             PKT_INST_HDR[TT] for the TT value in WQE.
232215990Sjmallett                                                             When PIP_GBL_CTL[IHMSK_DIS] = 1, Octeon2 does not use NTT */
233215990Sjmallett        uint64_t                    ntag        : 1;    /**< Must be 0 when PKT_INST_HDR[R] = 0.
234215990Sjmallett                                                             When set to 1, NTAG prevents PIP from directly using
235215990Sjmallett                                                             PKT_INST_HDR[TAG] for the TAG value in WQE.
236215990Sjmallett                                                             When PIP_GBL_CTL[IHMSK_DIS] = 1, Octeon2 does not use NTAG */
237210284Sjmallett        uint64_t                    qos         : 3;    /**< POW input queue for this packet */
238210284Sjmallett        uint64_t                    grp         : 4;    /**< POW input group for this packet */
239210284Sjmallett        uint64_t                    rs          : 1;    /**< Flag to store this packet in the work queue entry, if possible */
240210284Sjmallett        cvmx_pow_tag_type_t         tag_type    : 2;    /**< POW input tag type */
241210284Sjmallett        uint64_t                    tag         : 32;   /**< POW input tag */
242210284Sjmallett    } s;
243210284Sjmallett} cvmx_pip_pkt_inst_hdr_t;
244210284Sjmallett
245215990Sjmallett/* CSR typedefs have been moved to cvmx-pip-defs.h */
246210284Sjmallett
247210284Sjmallett/**
248210284Sjmallett * Configure an ethernet input port
249210284Sjmallett *
250210284Sjmallett * @param port_num Port number to configure
251210284Sjmallett * @param port_cfg Port hardware configuration
252210284Sjmallett * @param port_tag_cfg
253210284Sjmallett *                 Port POW tagging configuration
254210284Sjmallett */
255210284Sjmallettstatic inline void cvmx_pip_config_port(uint64_t port_num,
256215990Sjmallett                                        cvmx_pip_prt_cfgx_t port_cfg,
257215990Sjmallett                                        cvmx_pip_prt_tagx_t port_tag_cfg)
258210284Sjmallett{
259210284Sjmallett    cvmx_write_csr(CVMX_PIP_PRT_CFGX(port_num), port_cfg.u64);
260210284Sjmallett    cvmx_write_csr(CVMX_PIP_PRT_TAGX(port_num), port_tag_cfg.u64);
261210284Sjmallett}
262210284Sjmallett
263210284Sjmallett
264210284Sjmallett/**
265210284Sjmallett * @deprecated      This function is a thin wrapper around the Pass1 version
266210284Sjmallett *                  of the CVMX_PIP_QOS_WATCHX CSR; Pass2 has added a field for
267210284Sjmallett *                  setting the group that is incompatible with this function,
268210284Sjmallett *                  the preferred upgrade path is to use the CSR directly.
269210284Sjmallett *
270210284Sjmallett * Configure the global QoS packet watchers. Each watcher is
271210284Sjmallett * capable of matching a field in a packet to determine the
272210284Sjmallett * QoS queue for scheduling.
273210284Sjmallett *
274210284Sjmallett * @param watcher    Watcher number to configure (0 - 3).
275210284Sjmallett * @param match_type Watcher match type
276210284Sjmallett * @param match_value
277210284Sjmallett *                   Value the watcher will match against
278210284Sjmallett * @param qos        QoS queue for packets matching this watcher
279210284Sjmallett */
280210284Sjmallettstatic inline void cvmx_pip_config_watcher(uint64_t watcher,
281210284Sjmallett                                           cvmx_pip_qos_watch_types match_type,
282210284Sjmallett                                           uint64_t match_value, uint64_t qos)
283210284Sjmallett{
284215990Sjmallett    cvmx_pip_qos_watchx_t watcher_config;
285210284Sjmallett
286210284Sjmallett    watcher_config.u64 = 0;
287210284Sjmallett    watcher_config.s.match_type = match_type;
288210284Sjmallett    watcher_config.s.match_value = match_value;
289210284Sjmallett    watcher_config.s.qos = qos;
290210284Sjmallett
291210284Sjmallett    cvmx_write_csr(CVMX_PIP_QOS_WATCHX(watcher), watcher_config.u64);
292210284Sjmallett}
293210284Sjmallett
294210284Sjmallett
295210284Sjmallett/**
296210284Sjmallett * Configure the VLAN priority to QoS queue mapping.
297210284Sjmallett *
298210284Sjmallett * @param vlan_priority
299210284Sjmallett *               VLAN priority (0-7)
300210284Sjmallett * @param qos    QoS queue for packets matching this watcher
301210284Sjmallett */
302210284Sjmallettstatic inline void cvmx_pip_config_vlan_qos(uint64_t vlan_priority, uint64_t qos)
303210284Sjmallett{
304210284Sjmallett    cvmx_pip_qos_vlanx_t pip_qos_vlanx;
305210284Sjmallett    pip_qos_vlanx.u64 = 0;
306210284Sjmallett    pip_qos_vlanx.s.qos = qos;
307210284Sjmallett    cvmx_write_csr(CVMX_PIP_QOS_VLANX(vlan_priority), pip_qos_vlanx.u64);
308210284Sjmallett}
309210284Sjmallett
310210284Sjmallett
311210284Sjmallett/**
312210284Sjmallett * Configure the Diffserv to QoS queue mapping.
313210284Sjmallett *
314210284Sjmallett * @param diffserv Diffserv field value (0-63)
315210284Sjmallett * @param qos      QoS queue for packets matching this watcher
316210284Sjmallett */
317210284Sjmallettstatic inline void cvmx_pip_config_diffserv_qos(uint64_t diffserv, uint64_t qos)
318210284Sjmallett{
319210284Sjmallett    cvmx_pip_qos_diffx_t pip_qos_diffx;
320210284Sjmallett    pip_qos_diffx.u64 = 0;
321210284Sjmallett    pip_qos_diffx.s.qos = qos;
322210284Sjmallett    cvmx_write_csr(CVMX_PIP_QOS_DIFFX(diffserv), pip_qos_diffx.u64);
323210284Sjmallett}
324210284Sjmallett
325210284Sjmallett
326210284Sjmallett/**
327210284Sjmallett * Get the status counters for a port.
328210284Sjmallett *
329210284Sjmallett * @param port_num Port number to get statistics for.
330210284Sjmallett * @param clear    Set to 1 to clear the counters after they are read
331210284Sjmallett * @param status   Where to put the results.
332210284Sjmallett */
333210284Sjmallettstatic inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear, cvmx_pip_port_status_t *status)
334210284Sjmallett{
335210284Sjmallett    cvmx_pip_stat_ctl_t pip_stat_ctl;
336210284Sjmallett    cvmx_pip_stat0_prtx_t stat0;
337210284Sjmallett    cvmx_pip_stat1_prtx_t stat1;
338210284Sjmallett    cvmx_pip_stat2_prtx_t stat2;
339210284Sjmallett    cvmx_pip_stat3_prtx_t stat3;
340210284Sjmallett    cvmx_pip_stat4_prtx_t stat4;
341210284Sjmallett    cvmx_pip_stat5_prtx_t stat5;
342210284Sjmallett    cvmx_pip_stat6_prtx_t stat6;
343210284Sjmallett    cvmx_pip_stat7_prtx_t stat7;
344210284Sjmallett    cvmx_pip_stat8_prtx_t stat8;
345210284Sjmallett    cvmx_pip_stat9_prtx_t stat9;
346210284Sjmallett    cvmx_pip_stat_inb_pktsx_t pip_stat_inb_pktsx;
347210284Sjmallett    cvmx_pip_stat_inb_octsx_t pip_stat_inb_octsx;
348210284Sjmallett    cvmx_pip_stat_inb_errsx_t pip_stat_inb_errsx;
349210284Sjmallett
350210284Sjmallett    pip_stat_ctl.u64 = 0;
351210284Sjmallett    pip_stat_ctl.s.rdclr = clear;
352210284Sjmallett    cvmx_write_csr(CVMX_PIP_STAT_CTL, pip_stat_ctl.u64);
353210284Sjmallett
354215990Sjmallett    if (port_num >= 40)
355215990Sjmallett    {
356215990Sjmallett        stat0.u64 = cvmx_read_csr(CVMX_PIP_XSTAT0_PRTX(port_num));
357215990Sjmallett        stat1.u64 = cvmx_read_csr(CVMX_PIP_XSTAT1_PRTX(port_num));
358215990Sjmallett        stat2.u64 = cvmx_read_csr(CVMX_PIP_XSTAT2_PRTX(port_num));
359215990Sjmallett        stat3.u64 = cvmx_read_csr(CVMX_PIP_XSTAT3_PRTX(port_num));
360215990Sjmallett        stat4.u64 = cvmx_read_csr(CVMX_PIP_XSTAT4_PRTX(port_num));
361215990Sjmallett        stat5.u64 = cvmx_read_csr(CVMX_PIP_XSTAT5_PRTX(port_num));
362215990Sjmallett        stat6.u64 = cvmx_read_csr(CVMX_PIP_XSTAT6_PRTX(port_num));
363215990Sjmallett        stat7.u64 = cvmx_read_csr(CVMX_PIP_XSTAT7_PRTX(port_num));
364215990Sjmallett        stat8.u64 = cvmx_read_csr(CVMX_PIP_XSTAT8_PRTX(port_num));
365215990Sjmallett        stat9.u64 = cvmx_read_csr(CVMX_PIP_XSTAT9_PRTX(port_num));
366215990Sjmallett    }
367215990Sjmallett    else
368215990Sjmallett    {
369215990Sjmallett        stat0.u64 = cvmx_read_csr(CVMX_PIP_STAT0_PRTX(port_num));
370215990Sjmallett        stat1.u64 = cvmx_read_csr(CVMX_PIP_STAT1_PRTX(port_num));
371215990Sjmallett        stat2.u64 = cvmx_read_csr(CVMX_PIP_STAT2_PRTX(port_num));
372215990Sjmallett        stat3.u64 = cvmx_read_csr(CVMX_PIP_STAT3_PRTX(port_num));
373215990Sjmallett        stat4.u64 = cvmx_read_csr(CVMX_PIP_STAT4_PRTX(port_num));
374215990Sjmallett        stat5.u64 = cvmx_read_csr(CVMX_PIP_STAT5_PRTX(port_num));
375215990Sjmallett        stat6.u64 = cvmx_read_csr(CVMX_PIP_STAT6_PRTX(port_num));
376215990Sjmallett        stat7.u64 = cvmx_read_csr(CVMX_PIP_STAT7_PRTX(port_num));
377215990Sjmallett        stat8.u64 = cvmx_read_csr(CVMX_PIP_STAT8_PRTX(port_num));
378215990Sjmallett        stat9.u64 = cvmx_read_csr(CVMX_PIP_STAT9_PRTX(port_num));
379215990Sjmallett    }
380210284Sjmallett    pip_stat_inb_pktsx.u64 = cvmx_read_csr(CVMX_PIP_STAT_INB_PKTSX(port_num));
381210284Sjmallett    pip_stat_inb_octsx.u64 = cvmx_read_csr(CVMX_PIP_STAT_INB_OCTSX(port_num));
382210284Sjmallett    pip_stat_inb_errsx.u64 = cvmx_read_csr(CVMX_PIP_STAT_INB_ERRSX(port_num));
383210284Sjmallett
384210284Sjmallett    status->dropped_octets          = stat0.s.drp_octs;
385210284Sjmallett    status->dropped_packets         = stat0.s.drp_pkts;
386210284Sjmallett    status->octets                  = stat1.s.octs;
387210284Sjmallett    status->pci_raw_packets         = stat2.s.raw;
388210284Sjmallett    status->packets                 = stat2.s.pkts;
389210284Sjmallett    status->multicast_packets       = stat3.s.mcst;
390210284Sjmallett    status->broadcast_packets       = stat3.s.bcst;
391210284Sjmallett    status->len_64_packets          = stat4.s.h64;
392210284Sjmallett    status->len_65_127_packets      = stat4.s.h65to127;
393210284Sjmallett    status->len_128_255_packets     = stat5.s.h128to255;
394210284Sjmallett    status->len_256_511_packets     = stat5.s.h256to511;
395210284Sjmallett    status->len_512_1023_packets    = stat6.s.h512to1023;
396210284Sjmallett    status->len_1024_1518_packets   = stat6.s.h1024to1518;
397210284Sjmallett    status->len_1519_max_packets    = stat7.s.h1519;
398210284Sjmallett    status->fcs_align_err_packets   = stat7.s.fcs;
399210284Sjmallett    status->runt_packets            = stat8.s.undersz;
400210284Sjmallett    status->runt_crc_packets        = stat8.s.frag;
401210284Sjmallett    status->oversize_packets        = stat9.s.oversz;
402210284Sjmallett    status->oversize_crc_packets    = stat9.s.jabber;
403210284Sjmallett    status->inb_packets             = pip_stat_inb_pktsx.s.pkts;
404210284Sjmallett    status->inb_octets              = pip_stat_inb_octsx.s.octs;
405210284Sjmallett    status->inb_errors              = pip_stat_inb_errsx.s.errs;
406210284Sjmallett
407210284Sjmallett}
408210284Sjmallett
409210284Sjmallett
410210284Sjmallett/**
411210284Sjmallett * Configure the hardware CRC engine
412210284Sjmallett *
413210284Sjmallett * @param interface Interface to configure (0 or 1)
414210284Sjmallett * @param invert_result
415210284Sjmallett *                 Invert the result of the CRC
416210284Sjmallett * @param reflect  Reflect
417210284Sjmallett * @param initialization_vector
418210284Sjmallett *                 CRC initialization vector
419210284Sjmallett */
420210284Sjmallettstatic inline void cvmx_pip_config_crc(uint64_t interface, uint64_t invert_result, uint64_t reflect, uint32_t initialization_vector)
421210284Sjmallett{
422210284Sjmallett    if ((OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
423210284Sjmallett    {
424210284Sjmallett        cvmx_pip_crc_ctlx_t config;
425210284Sjmallett        cvmx_pip_crc_ivx_t pip_crc_ivx;
426210284Sjmallett
427210284Sjmallett        config.u64 = 0;
428210284Sjmallett        config.s.invres = invert_result;
429210284Sjmallett        config.s.reflect = reflect;
430210284Sjmallett        cvmx_write_csr(CVMX_PIP_CRC_CTLX(interface), config.u64);
431210284Sjmallett
432210284Sjmallett        pip_crc_ivx.u64 = 0;
433210284Sjmallett        pip_crc_ivx.s.iv = initialization_vector;
434210284Sjmallett        cvmx_write_csr(CVMX_PIP_CRC_IVX(interface), pip_crc_ivx.u64);
435210284Sjmallett    }
436210284Sjmallett}
437210284Sjmallett
438210284Sjmallett
439210284Sjmallett/**
440210284Sjmallett * Clear all bits in a tag mask. This should be called on
441210284Sjmallett * startup before any calls to cvmx_pip_tag_mask_set. Each bit
442210284Sjmallett * set in the final mask represent a byte used in the packet for
443210284Sjmallett * tag generation.
444210284Sjmallett *
445210284Sjmallett * @param mask_index Which tag mask to clear (0..3)
446210284Sjmallett */
447210284Sjmallettstatic inline void cvmx_pip_tag_mask_clear(uint64_t mask_index)
448210284Sjmallett{
449210284Sjmallett    uint64_t index;
450210284Sjmallett    cvmx_pip_tag_incx_t pip_tag_incx;
451210284Sjmallett    pip_tag_incx.u64 = 0;
452210284Sjmallett    pip_tag_incx.s.en = 0;
453210284Sjmallett    for (index=mask_index*16; index<(mask_index+1)*16; index++)
454210284Sjmallett        cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
455210284Sjmallett}
456210284Sjmallett
457210284Sjmallett
458210284Sjmallett/**
459210284Sjmallett * Sets a range of bits in the tag mask. The tag mask is used
460210284Sjmallett * when the cvmx_pip_port_tag_cfg_t tag_mode is non zero.
461210284Sjmallett * There are four separate masks that can be configured.
462210284Sjmallett *
463210284Sjmallett * @param mask_index Which tag mask to modify (0..3)
464210284Sjmallett * @param offset     Offset into the bitmask to set bits at. Use the GCC macro
465210284Sjmallett *                   offsetof() to determine the offsets into packet headers.
466210284Sjmallett *                   For example, offsetof(ethhdr, protocol) returns the offset
467210284Sjmallett *                   of the ethernet protocol field.  The bitmask selects which bytes
468210284Sjmallett *                   to include the the tag, with bit offset X selecting byte at offset X
469210284Sjmallett *                   from the beginning of the packet data.
470210284Sjmallett * @param len        Number of bytes to include. Usually this is the sizeof()
471210284Sjmallett *                   the field.
472210284Sjmallett */
473210284Sjmallettstatic inline void cvmx_pip_tag_mask_set(uint64_t mask_index, uint64_t offset, uint64_t len)
474210284Sjmallett{
475210284Sjmallett    while (len--)
476210284Sjmallett    {
477210284Sjmallett        cvmx_pip_tag_incx_t pip_tag_incx;
478210284Sjmallett        uint64_t index = mask_index*16 + offset/8;
479210284Sjmallett        pip_tag_incx.u64 = cvmx_read_csr(CVMX_PIP_TAG_INCX(index));
480210284Sjmallett        pip_tag_incx.s.en |= 0x80 >> (offset & 0x7);
481210284Sjmallett        cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
482210284Sjmallett        offset++;
483210284Sjmallett    }
484210284Sjmallett}
485210284Sjmallett
486210284Sjmallett#ifdef	__cplusplus
487210284Sjmallett}
488210284Sjmallett#endif
489210284Sjmallett
490210284Sjmallett#endif  /*  __CVMX_PIP_H__ */
491