]>
Commit | Line | Data |
---|---|---|
80ff0fd3 DD |
1 | /***********************license start*************** |
2 | * Author: Cavium Networks | |
3 | * | |
4 | * Contact: support@caviumnetworks.com | |
5 | * This file is part of the OCTEON SDK | |
6 | * | |
7 | * Copyright (c) 2003-2008 Cavium Networks | |
8 | * | |
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. | |
12 | * | |
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 | |
17 | * details. | |
18 | * | |
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/. | |
23 | * | |
24 | * This file may also be available under a different license from Cavium. | |
25 | * Contact Cavium Networks for more information | |
26 | ***********************license end**************************************/ | |
27 | ||
28 | /* | |
29 | * Interface to the hardware Packet Input Processing unit. | |
30 | * | |
31 | */ | |
32 | ||
33 | #ifndef __CVMX_PIP_H__ | |
34 | #define __CVMX_PIP_H__ | |
35 | ||
a1ce3928 DH |
36 | #include <asm/octeon/cvmx-wqe.h> |
37 | #include <asm/octeon/cvmx-fpa.h> | |
38 | #include <asm/octeon/cvmx-pip-defs.h> | |
80ff0fd3 | 39 | |
70342287 RB |
40 | #define CVMX_PIP_NUM_INPUT_PORTS 40 |
41 | #define CVMX_PIP_NUM_WATCHERS 4 | |
80ff0fd3 DD |
42 | |
43 | /* | |
44 | * Encodes the different error and exception codes | |
45 | */ | |
46 | typedef enum { | |
47 | CVMX_PIP_L4_NO_ERR = 0ull, | |
48 | /* | |
49 | * 1 = TCP (UDP) packet not long enough to cover TCP (UDP) | |
50 | * header | |
51 | */ | |
52 | CVMX_PIP_L4_MAL_ERR = 1ull, | |
53 | /* 2 = TCP/UDP checksum failure */ | |
54 | CVMX_PIP_CHK_ERR = 2ull, | |
55 | /* | |
56 | * 3 = TCP/UDP length check (TCP/UDP length does not match IP | |
57 | * length). | |
58 | */ | |
59 | CVMX_PIP_L4_LENGTH_ERR = 3ull, | |
60 | /* 4 = illegal TCP/UDP port (either source or dest port is zero) */ | |
61 | CVMX_PIP_BAD_PRT_ERR = 4ull, | |
62 | /* 8 = TCP flags = FIN only */ | |
63 | CVMX_PIP_TCP_FLG8_ERR = 8ull, | |
64 | /* 9 = TCP flags = 0 */ | |
65 | CVMX_PIP_TCP_FLG9_ERR = 9ull, | |
66 | /* 10 = TCP flags = FIN+RST+* */ | |
67 | CVMX_PIP_TCP_FLG10_ERR = 10ull, | |
68 | /* 11 = TCP flags = SYN+URG+* */ | |
69 | CVMX_PIP_TCP_FLG11_ERR = 11ull, | |
70 | /* 12 = TCP flags = SYN+RST+* */ | |
71 | CVMX_PIP_TCP_FLG12_ERR = 12ull, | |
72 | /* 13 = TCP flags = SYN+FIN+* */ | |
73 | CVMX_PIP_TCP_FLG13_ERR = 13ull | |
74 | } cvmx_pip_l4_err_t; | |
75 | ||
76 | typedef enum { | |
77 | ||
78 | CVMX_PIP_IP_NO_ERR = 0ull, | |
79 | /* 1 = not IPv4 or IPv6 */ | |
80 | CVMX_PIP_NOT_IP = 1ull, | |
81 | /* 2 = IPv4 header checksum violation */ | |
82 | CVMX_PIP_IPV4_HDR_CHK = 2ull, | |
83 | /* 3 = malformed (packet not long enough to cover IP hdr) */ | |
84 | CVMX_PIP_IP_MAL_HDR = 3ull, | |
85 | /* 4 = malformed (packet not long enough to cover len in IP hdr) */ | |
86 | CVMX_PIP_IP_MAL_PKT = 4ull, | |
87 | /* 5 = TTL / hop count equal zero */ | |
88 | CVMX_PIP_TTL_HOP = 5ull, | |
89 | /* 6 = IPv4 options / IPv6 early extension headers */ | |
90 | CVMX_PIP_OPTS = 6ull | |
91 | } cvmx_pip_ip_exc_t; | |
92 | ||
93 | /** | |
94 | * NOTES | |
70342287 RB |
95 | * late collision (data received before collision) |
96 | * late collisions cannot be detected by the receiver | |
97 | * they would appear as JAM bits which would appear as bad FCS | |
98 | * or carrier extend error which is CVMX_PIP_EXTEND_ERR | |
80ff0fd3 DD |
99 | */ |
100 | typedef enum { | |
101 | /* No error */ | |
102 | CVMX_PIP_RX_NO_ERR = 0ull, | |
103 | /* RGM+SPI 1 = partially received packet (buffering/bandwidth | |
104 | * not adequate) */ | |
105 | CVMX_PIP_PARTIAL_ERR = 1ull, | |
106 | /* RGM+SPI 2 = receive packet too large and truncated */ | |
107 | CVMX_PIP_JABBER_ERR = 2ull, | |
108 | /* | |
109 | * RGM 3 = max frame error (pkt len > max frame len) (with FCS | |
110 | * error) | |
111 | */ | |
112 | CVMX_PIP_OVER_FCS_ERR = 3ull, | |
113 | /* RGM+SPI 4 = max frame error (pkt len > max frame len) */ | |
114 | CVMX_PIP_OVER_ERR = 4ull, | |
115 | /* | |
116 | * RGM 5 = nibble error (data not byte multiple - 100M and 10M | |
117 | * only) | |
118 | */ | |
119 | CVMX_PIP_ALIGN_ERR = 5ull, | |
120 | /* | |
121 | * RGM 6 = min frame error (pkt len < min frame len) (with FCS | |
122 | * error) | |
123 | */ | |
124 | CVMX_PIP_UNDER_FCS_ERR = 6ull, | |
70342287 | 125 | /* RGM 7 = FCS error */ |
80ff0fd3 DD |
126 | CVMX_PIP_GMX_FCS_ERR = 7ull, |
127 | /* RGM+SPI 8 = min frame error (pkt len < min frame len) */ | |
128 | CVMX_PIP_UNDER_ERR = 8ull, | |
70342287 | 129 | /* RGM 9 = Frame carrier extend error */ |
80ff0fd3 DD |
130 | CVMX_PIP_EXTEND_ERR = 9ull, |
131 | /* | |
132 | * RGM 10 = length mismatch (len did not match len in L2 | |
133 | * length/type) | |
134 | */ | |
135 | CVMX_PIP_LENGTH_ERR = 10ull, | |
136 | /* RGM 11 = Frame error (some or all data bits marked err) */ | |
137 | CVMX_PIP_DAT_ERR = 11ull, | |
138 | /* SPI 11 = DIP4 error */ | |
139 | CVMX_PIP_DIP_ERR = 11ull, | |
140 | /* | |
141 | * RGM 12 = packet was not large enough to pass the skipper - | |
142 | * no inspection could occur. | |
143 | */ | |
144 | CVMX_PIP_SKIP_ERR = 12ull, | |
145 | /* | |
146 | * RGM 13 = studder error (data not repeated - 100M and 10M | |
147 | * only) | |
148 | */ | |
149 | CVMX_PIP_NIBBLE_ERR = 13ull, | |
150 | /* RGM+SPI 16 = FCS error */ | |
151 | CVMX_PIP_PIP_FCS = 16L, | |
152 | /* | |
153 | * RGM+SPI+PCI 17 = packet was not large enough to pass the | |
154 | * skipper - no inspection could occur. | |
155 | */ | |
156 | CVMX_PIP_PIP_SKIP_ERR = 17L, | |
157 | /* | |
158 | * RGM+SPI+PCI 18 = malformed l2 (packet not long enough to | |
159 | * cover L2 hdr). | |
160 | */ | |
161 | CVMX_PIP_PIP_L2_MAL_HDR = 18L | |
162 | /* | |
163 | * NOTES: xx = late collision (data received before collision) | |
70342287 RB |
164 | * late collisions cannot be detected by the receiver |
165 | * they would appear as JAM bits which would appear as | |
166 | * bad FCS or carrier extend error which is | |
167 | * CVMX_PIP_EXTEND_ERR | |
80ff0fd3 DD |
168 | */ |
169 | } cvmx_pip_rcv_err_t; | |
170 | ||
171 | /** | |
172 | * This defines the err_code field errors in the work Q entry | |
173 | */ | |
174 | typedef union { | |
175 | cvmx_pip_l4_err_t l4_err; | |
176 | cvmx_pip_ip_exc_t ip_exc; | |
177 | cvmx_pip_rcv_err_t rcv_err; | |
178 | } cvmx_pip_err_t; | |
179 | ||
180 | /** | |
181 | * Status statistics for a port | |
182 | */ | |
183 | typedef struct { | |
184 | /* Inbound octets marked to be dropped by the IPD */ | |
185 | uint32_t dropped_octets; | |
186 | /* Inbound packets marked to be dropped by the IPD */ | |
187 | uint32_t dropped_packets; | |
188 | /* RAW PCI Packets received by PIP per port */ | |
189 | uint32_t pci_raw_packets; | |
190 | /* Number of octets processed by PIP */ | |
191 | uint32_t octets; | |
192 | /* Number of packets processed by PIP */ | |
193 | uint32_t packets; | |
194 | /* | |
70342287 | 195 | * Number of indentified L2 multicast packets. Does not |
80ff0fd3 DD |
196 | * include broadcast packets. Only includes packets whose |
197 | * parse mode is SKIP_TO_L2 | |
198 | */ | |
199 | uint32_t multicast_packets; | |
200 | /* | |
70342287 | 201 | * Number of indentified L2 broadcast packets. Does not |
80ff0fd3 DD |
202 | * include multicast packets. Only includes packets whose |
203 | * parse mode is SKIP_TO_L2 | |
204 | */ | |
205 | uint32_t broadcast_packets; | |
206 | /* Number of 64B packets */ | |
207 | uint32_t len_64_packets; | |
208 | /* Number of 65-127B packets */ | |
209 | uint32_t len_65_127_packets; | |
210 | /* Number of 128-255B packets */ | |
211 | uint32_t len_128_255_packets; | |
212 | /* Number of 256-511B packets */ | |
213 | uint32_t len_256_511_packets; | |
214 | /* Number of 512-1023B packets */ | |
215 | uint32_t len_512_1023_packets; | |
216 | /* Number of 1024-1518B packets */ | |
217 | uint32_t len_1024_1518_packets; | |
218 | /* Number of 1519-max packets */ | |
219 | uint32_t len_1519_max_packets; | |
220 | /* Number of packets with FCS or Align opcode errors */ | |
221 | uint32_t fcs_align_err_packets; | |
222 | /* Number of packets with length < min */ | |
223 | uint32_t runt_packets; | |
224 | /* Number of packets with length < min and FCS error */ | |
225 | uint32_t runt_crc_packets; | |
226 | /* Number of packets with length > max */ | |
227 | uint32_t oversize_packets; | |
228 | /* Number of packets with length > max and FCS error */ | |
229 | uint32_t oversize_crc_packets; | |
230 | /* Number of packets without GMX/SPX/PCI errors received by PIP */ | |
231 | uint32_t inb_packets; | |
232 | /* | |
233 | * Total number of octets from all packets received by PIP, | |
234 | * including CRC | |
235 | */ | |
236 | uint64_t inb_octets; | |
237 | /* Number of packets with GMX/SPX/PCI errors received by PIP */ | |
238 | uint16_t inb_errors; | |
239 | } cvmx_pip_port_status_t; | |
240 | ||
241 | /** | |
242 | * Definition of the PIP custom header that can be prepended | |
243 | * to a packet by external hardware. | |
244 | */ | |
245 | typedef union { | |
246 | uint64_t u64; | |
247 | struct { | |
248 | /* | |
249 | * Documented as R - Set if the Packet is RAWFULL. If | |
250 | * set, this header must be the full 8 bytes. | |
251 | */ | |
252 | uint64_t rawfull:1; | |
253 | /* Must be zero */ | |
254 | uint64_t reserved0:5; | |
255 | /* PIP parse mode for this packet */ | |
256 | uint64_t parse_mode:2; | |
257 | /* Must be zero */ | |
258 | uint64_t reserved1:1; | |
259 | /* | |
260 | * Skip amount, including this header, to the | |
261 | * beginning of the packet | |
262 | */ | |
263 | uint64_t skip_len:7; | |
264 | /* Must be zero */ | |
265 | uint64_t reserved2:6; | |
266 | /* POW input queue for this packet */ | |
267 | uint64_t qos:3; | |
268 | /* POW input group for this packet */ | |
269 | uint64_t grp:4; | |
270 | /* | |
271 | * Flag to store this packet in the work queue entry, | |
272 | * if possible | |
273 | */ | |
274 | uint64_t rs:1; | |
275 | /* POW input tag type */ | |
276 | uint64_t tag_type:2; | |
277 | /* POW input tag */ | |
278 | uint64_t tag:32; | |
279 | } s; | |
280 | } cvmx_pip_pkt_inst_hdr_t; | |
281 | ||
282 | /* CSR typedefs have been moved to cvmx-csr-*.h */ | |
283 | ||
284 | /** | |
285 | * Configure an ethernet input port | |
286 | * | |
287 | * @port_num: Port number to configure | |
288 | * @port_cfg: Port hardware configuration | |
289 | * @port_tag_cfg: | |
70342287 | 290 | * Port POW tagging configuration |
80ff0fd3 DD |
291 | */ |
292 | static inline void cvmx_pip_config_port(uint64_t port_num, | |
293 | union cvmx_pip_prt_cfgx port_cfg, | |
294 | union cvmx_pip_prt_tagx port_tag_cfg) | |
295 | { | |
296 | cvmx_write_csr(CVMX_PIP_PRT_CFGX(port_num), port_cfg.u64); | |
297 | cvmx_write_csr(CVMX_PIP_PRT_TAGX(port_num), port_tag_cfg.u64); | |
298 | } | |
299 | #if 0 | |
300 | /** | |
70342287 RB |
301 | * @deprecated This function is a thin wrapper around the Pass1 version |
302 | * of the CVMX_PIP_QOS_WATCHX CSR; Pass2 has added a field for | |
303 | * setting the group that is incompatible with this function, | |
304 | * the preferred upgrade path is to use the CSR directly. | |
80ff0fd3 DD |
305 | * |
306 | * Configure the global QoS packet watchers. Each watcher is | |
307 | * capable of matching a field in a packet to determine the | |
308 | * QoS queue for scheduling. | |
309 | * | |
70342287 | 310 | * @watcher: Watcher number to configure (0 - 3). |
80ff0fd3 DD |
311 | * @match_type: Watcher match type |
312 | * @match_value: | |
70342287 RB |
313 | * Value the watcher will match against |
314 | * @qos: QoS queue for packets matching this watcher | |
80ff0fd3 DD |
315 | */ |
316 | static inline void cvmx_pip_config_watcher(uint64_t watcher, | |
317 | cvmx_pip_qos_watch_types match_type, | |
318 | uint64_t match_value, uint64_t qos) | |
319 | { | |
320 | cvmx_pip_port_watcher_cfg_t watcher_config; | |
321 | ||
322 | watcher_config.u64 = 0; | |
323 | watcher_config.s.match_type = match_type; | |
324 | watcher_config.s.match_value = match_value; | |
325 | watcher_config.s.qos = qos; | |
326 | ||
327 | cvmx_write_csr(CVMX_PIP_QOS_WATCHX(watcher), watcher_config.u64); | |
328 | } | |
329 | #endif | |
330 | /** | |
331 | * Configure the VLAN priority to QoS queue mapping. | |
332 | * | |
333 | * @vlan_priority: | |
70342287 | 334 | * VLAN priority (0-7) |
80ff0fd3 DD |
335 | * @qos: QoS queue for packets matching this watcher |
336 | */ | |
337 | static inline void cvmx_pip_config_vlan_qos(uint64_t vlan_priority, | |
338 | uint64_t qos) | |
339 | { | |
340 | union cvmx_pip_qos_vlanx pip_qos_vlanx; | |
341 | pip_qos_vlanx.u64 = 0; | |
342 | pip_qos_vlanx.s.qos = qos; | |
343 | cvmx_write_csr(CVMX_PIP_QOS_VLANX(vlan_priority), pip_qos_vlanx.u64); | |
344 | } | |
345 | ||
346 | /** | |
347 | * Configure the Diffserv to QoS queue mapping. | |
348 | * | |
349 | * @diffserv: Diffserv field value (0-63) | |
350 | * @qos: QoS queue for packets matching this watcher | |
351 | */ | |
352 | static inline void cvmx_pip_config_diffserv_qos(uint64_t diffserv, uint64_t qos) | |
353 | { | |
354 | union cvmx_pip_qos_diffx pip_qos_diffx; | |
355 | pip_qos_diffx.u64 = 0; | |
356 | pip_qos_diffx.s.qos = qos; | |
357 | cvmx_write_csr(CVMX_PIP_QOS_DIFFX(diffserv), pip_qos_diffx.u64); | |
358 | } | |
359 | ||
360 | /** | |
361 | * Get the status counters for a port. | |
362 | * | |
363 | * @port_num: Port number to get statistics for. | |
364 | * @clear: Set to 1 to clear the counters after they are read | |
365 | * @status: Where to put the results. | |
366 | */ | |
367 | static inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear, | |
368 | cvmx_pip_port_status_t *status) | |
369 | { | |
370 | union cvmx_pip_stat_ctl pip_stat_ctl; | |
371 | union cvmx_pip_stat0_prtx stat0; | |
372 | union cvmx_pip_stat1_prtx stat1; | |
373 | union cvmx_pip_stat2_prtx stat2; | |
374 | union cvmx_pip_stat3_prtx stat3; | |
375 | union cvmx_pip_stat4_prtx stat4; | |
376 | union cvmx_pip_stat5_prtx stat5; | |
377 | union cvmx_pip_stat6_prtx stat6; | |
378 | union cvmx_pip_stat7_prtx stat7; | |
379 | union cvmx_pip_stat8_prtx stat8; | |
380 | union cvmx_pip_stat9_prtx stat9; | |
381 | union cvmx_pip_stat_inb_pktsx pip_stat_inb_pktsx; | |
382 | union cvmx_pip_stat_inb_octsx pip_stat_inb_octsx; | |
383 | union cvmx_pip_stat_inb_errsx pip_stat_inb_errsx; | |
384 | ||
385 | pip_stat_ctl.u64 = 0; | |
386 | pip_stat_ctl.s.rdclr = clear; | |
387 | cvmx_write_csr(CVMX_PIP_STAT_CTL, pip_stat_ctl.u64); | |
388 | ||
389 | stat0.u64 = cvmx_read_csr(CVMX_PIP_STAT0_PRTX(port_num)); | |
390 | stat1.u64 = cvmx_read_csr(CVMX_PIP_STAT1_PRTX(port_num)); | |
391 | stat2.u64 = cvmx_read_csr(CVMX_PIP_STAT2_PRTX(port_num)); | |
392 | stat3.u64 = cvmx_read_csr(CVMX_PIP_STAT3_PRTX(port_num)); | |
393 | stat4.u64 = cvmx_read_csr(CVMX_PIP_STAT4_PRTX(port_num)); | |
394 | stat5.u64 = cvmx_read_csr(CVMX_PIP_STAT5_PRTX(port_num)); | |
395 | stat6.u64 = cvmx_read_csr(CVMX_PIP_STAT6_PRTX(port_num)); | |
396 | stat7.u64 = cvmx_read_csr(CVMX_PIP_STAT7_PRTX(port_num)); | |
397 | stat8.u64 = cvmx_read_csr(CVMX_PIP_STAT8_PRTX(port_num)); | |
398 | stat9.u64 = cvmx_read_csr(CVMX_PIP_STAT9_PRTX(port_num)); | |
399 | pip_stat_inb_pktsx.u64 = | |
400 | cvmx_read_csr(CVMX_PIP_STAT_INB_PKTSX(port_num)); | |
401 | pip_stat_inb_octsx.u64 = | |
402 | cvmx_read_csr(CVMX_PIP_STAT_INB_OCTSX(port_num)); | |
403 | pip_stat_inb_errsx.u64 = | |
404 | cvmx_read_csr(CVMX_PIP_STAT_INB_ERRSX(port_num)); | |
405 | ||
406 | status->dropped_octets = stat0.s.drp_octs; | |
407 | status->dropped_packets = stat0.s.drp_pkts; | |
408 | status->octets = stat1.s.octs; | |
409 | status->pci_raw_packets = stat2.s.raw; | |
410 | status->packets = stat2.s.pkts; | |
411 | status->multicast_packets = stat3.s.mcst; | |
412 | status->broadcast_packets = stat3.s.bcst; | |
413 | status->len_64_packets = stat4.s.h64; | |
414 | status->len_65_127_packets = stat4.s.h65to127; | |
415 | status->len_128_255_packets = stat5.s.h128to255; | |
416 | status->len_256_511_packets = stat5.s.h256to511; | |
417 | status->len_512_1023_packets = stat6.s.h512to1023; | |
418 | status->len_1024_1518_packets = stat6.s.h1024to1518; | |
419 | status->len_1519_max_packets = stat7.s.h1519; | |
420 | status->fcs_align_err_packets = stat7.s.fcs; | |
421 | status->runt_packets = stat8.s.undersz; | |
422 | status->runt_crc_packets = stat8.s.frag; | |
423 | status->oversize_packets = stat9.s.oversz; | |
424 | status->oversize_crc_packets = stat9.s.jabber; | |
425 | status->inb_packets = pip_stat_inb_pktsx.s.pkts; | |
426 | status->inb_octets = pip_stat_inb_octsx.s.octs; | |
427 | status->inb_errors = pip_stat_inb_errsx.s.errs; | |
428 | ||
429 | if (cvmx_octeon_is_pass1()) { | |
430 | /* | |
431 | * Kludge to fix Octeon Pass 1 errata - Drop counts | |
432 | * don't work. | |
433 | */ | |
434 | if (status->inb_packets > status->packets) | |
435 | status->dropped_packets = | |
436 | status->inb_packets - status->packets; | |
437 | else | |
438 | status->dropped_packets = 0; | |
439 | if (status->inb_octets - status->inb_packets * 4 > | |
440 | status->octets) | |
441 | status->dropped_octets = | |
442 | status->inb_octets - status->inb_packets * 4 - | |
443 | status->octets; | |
444 | else | |
445 | status->dropped_octets = 0; | |
446 | } | |
447 | } | |
448 | ||
449 | /** | |
450 | * Configure the hardware CRC engine | |
451 | * | |
452 | * @interface: Interface to configure (0 or 1) | |
453 | * @invert_result: | |
70342287 | 454 | * Invert the result of the CRC |
80ff0fd3 DD |
455 | * @reflect: Reflect |
456 | * @initialization_vector: | |
70342287 | 457 | * CRC initialization vector |
80ff0fd3 DD |
458 | */ |
459 | static inline void cvmx_pip_config_crc(uint64_t interface, | |
460 | uint64_t invert_result, uint64_t reflect, | |
461 | uint32_t initialization_vector) | |
462 | { | |
463 | if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) { | |
464 | union cvmx_pip_crc_ctlx config; | |
465 | union cvmx_pip_crc_ivx pip_crc_ivx; | |
466 | ||
467 | config.u64 = 0; | |
468 | config.s.invres = invert_result; | |
469 | config.s.reflect = reflect; | |
470 | cvmx_write_csr(CVMX_PIP_CRC_CTLX(interface), config.u64); | |
471 | ||
472 | pip_crc_ivx.u64 = 0; | |
473 | pip_crc_ivx.s.iv = initialization_vector; | |
474 | cvmx_write_csr(CVMX_PIP_CRC_IVX(interface), pip_crc_ivx.u64); | |
475 | } | |
476 | } | |
477 | ||
478 | /** | |
479 | * Clear all bits in a tag mask. This should be called on | |
480 | * startup before any calls to cvmx_pip_tag_mask_set. Each bit | |
481 | * set in the final mask represent a byte used in the packet for | |
482 | * tag generation. | |
483 | * | |
484 | * @mask_index: Which tag mask to clear (0..3) | |
485 | */ | |
486 | static inline void cvmx_pip_tag_mask_clear(uint64_t mask_index) | |
487 | { | |
488 | uint64_t index; | |
489 | union cvmx_pip_tag_incx pip_tag_incx; | |
490 | pip_tag_incx.u64 = 0; | |
491 | pip_tag_incx.s.en = 0; | |
492 | for (index = mask_index * 16; index < (mask_index + 1) * 16; index++) | |
493 | cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64); | |
494 | } | |
495 | ||
496 | /** | |
497 | * Sets a range of bits in the tag mask. The tag mask is used | |
498 | * when the cvmx_pip_port_tag_cfg_t tag_mode is non zero. | |
499 | * There are four separate masks that can be configured. | |
500 | * | |
501 | * @mask_index: Which tag mask to modify (0..3) | |
502 | * @offset: Offset into the bitmask to set bits at. Use the GCC macro | |
70342287 RB |
503 | * offsetof() to determine the offsets into packet headers. |
504 | * For example, offsetof(ethhdr, protocol) returns the offset | |
505 | * of the ethernet protocol field. The bitmask selects which | |
506 | * bytes to include the the tag, with bit offset X selecting | |
507 | * byte at offset X from the beginning of the packet data. | |
80ff0fd3 | 508 | * @len: Number of bytes to include. Usually this is the sizeof() |
70342287 | 509 | * the field. |
80ff0fd3 DD |
510 | */ |
511 | static inline void cvmx_pip_tag_mask_set(uint64_t mask_index, uint64_t offset, | |
512 | uint64_t len) | |
513 | { | |
514 | while (len--) { | |
515 | union cvmx_pip_tag_incx pip_tag_incx; | |
516 | uint64_t index = mask_index * 16 + offset / 8; | |
517 | pip_tag_incx.u64 = cvmx_read_csr(CVMX_PIP_TAG_INCX(index)); | |
518 | pip_tag_incx.s.en |= 0x80 >> (offset & 0x7); | |
519 | cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64); | |
520 | offset++; | |
521 | } | |
522 | } | |
523 | ||
524 | #endif /* __CVMX_PIP_H__ */ |