-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpfe_gpi.t2t
392 lines (281 loc) · 17.3 KB
/
pfe_gpi.t2t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
== GPI ==[pfe_gpi]
Generic Packet Interface?
The GPI is the interface between memory and a peripheral. For EGPIs, that
peripheral is an EMAC block (ethernet MAC). For HGPI, it is the HIF.
On the Rx path, the GPI reads packets from the peripheral, allocates one or
more buffers depending on the size of the packet, and writes data and metadata
into those buffers.
The GPI can use either DDR buffers, LMEM buffers, or both, depending on the
configuration in [GPI_RX_CONFIG #pfe_gpi_reg_rx_config].
On the Tx path, TODO.
=== GPI Rx buffer format ===[pfe_gpi_rx_buf_format]
Large packets are split into fragments; each fragment is stored in its own
allocated buffer, and starts with a [header #pfe_gpi_rx_buf_header] indicating
where the next fragment is located. The header of the first fragment contains
the packet metadata, such as packet length. That metadata is not repeated in
the next segments. Also, the header is not written at all in the last fragment
(it contains whatever garbage was last written there), so you must rely on the
packet length from the header of the first fragment to know when you have
reached the last fragment.
When both LMEM and DDR buffers are used, the first fragment is always stored in
LMEM for fast processing by the PEs, while the next fragments are stored in DDR
buffers. Also, in that mode of operation, at least one DDR buffer is allocated,
even if the packet is small enough to be entirely stored in a single LMEM
buffer; that DDR buffer will not be used by the GPI in that case.
GPI Rx fragments are stored into memory in the following format.
|| Offset | Size | Description ||
| 0x0 | HDR_SIZE | [Fragment Rx header #pfe_gpi_rx_buf_header] |
| HDR_SIZE | DATA_OFFSET - HDR_SIZE | Free space for PE use |
| DATA_OFFSET | BUF_SIZE - DATA_OFFSET | Fragment data |
HDR_SIZE, BUF_SIZE and DATA_OFFSET can be configured using registers
[HDR_SIZE #pfe_gpi_reg_hdr_size], [BUF_SIZE #pfe_gpi_reg_buf_size],
[DDR_DATA_OFFSET #pfe_gpi_reg_ddr_data_offset] and
[LMEM_DATA_OFFSET #pfe_gpi_reg_lmem_data_offset].
==== GPI Rx fragment header ====[pfe_gpi_rx_buf_header]
Byte order is big-endian.
|| Name | Offset | Size | Description ||
| next_ptr | 0x0 | 4 | Pointer to the buffer containing the next fragment of the packet data that didn't fit into this buffer. Not written in last fragment. |
| length | 0x4 | 2 | (First fragment only) Total packet length. Depending on the GEMAC configuration, it may include the FCS. |
| phyno | 0x6 | 2 | (First fragment only) Input physical port number. 0=EGPI1, 1=EGPI2, other values unknown |
| status | 0x8 | 4 | (First fragment only) GEMAC status bits [63:32] |
| status2 | 0xc | 4 | (First fragment only) GEMAC status bits [31:0] |
GEMAC status bits:
|| Name | Bit range | Description ||
| OVERFLOW_ERR? | 60 | ? |
| UDP_CHECKSUM_CORRECT? | 59 | UDP checksum is correct? |
| TCP_CHECKSUM_CORRECT? | 58 | TCP checksum is correct? |
| IP_CHECKSUM_CORRECT? | 57 | IP checksum is correct? |
| UNICAST_HASH_MATCH? | 56 | Destination matches unicast hash |
| CUMULATIVE_ARC_HIT? | 55 | ? |
| MC_HASH_MATCH? | 54 | Destination matches multicast hash |
| CODE_ERR? | 53 | ? |
| TOO_LONG_ERR? | 52 | ? |
| TOO_SHORT_ERR? | 51 | ? |
| CRC_ERR? | 50 | ? |
| LENGTH_ERR? | 49 | ? |
| CUMULATIVE_ERR? (also called BAD_FRAME_ERR) | 48 | ? |
| SPEC32_ADD_MATCH | 31 | Destination address matches the one programmed in SPEC32_ADD_[BOT|TOP] registers |
| SPEC31_ADD_MATCH | 30 | Destination address matches the one programmed in SPEC31_ADD_[BOT|TOP] registers |
| SPEC30_ADD_MATCH | 29 | Destination address matches the one programmed in SPEC30_ADD_[BOT|TOP] registers |
| SPEC29_ADD_MATCH | 28 | Destination address matches the one programmed in SPEC29_ADD_[BOT|TOP] registers |
| SPEC28_ADD_MATCH | 27 | Destination address matches the one programmed in SPEC28_ADD_[BOT|TOP] registers |
| SPEC27_ADD_MATCH | 26 | Destination address matches the one programmed in SPEC27_ADD_[BOT|TOP] registers |
| SPEC26_ADD_MATCH | 25 | Destination address matches the one programmed in SPEC26_ADD_[BOT|TOP] registers |
| SPEC25_ADD_MATCH | 24 | Destination address matches the one programmed in SPEC25_ADD_[BOT|TOP] registers |
| SPEC24_ADD_MATCH | 23 | Destination address matches the one programmed in SPEC24_ADD_[BOT|TOP] registers |
| SPEC23_ADD_MATCH | 22 | Destination address matches the one programmed in SPEC23_ADD_[BOT|TOP] registers |
| SPEC22_ADD_MATCH | 21 | Destination address matches the one programmed in SPEC22_ADD_[BOT|TOP] registers |
| SPEC21_ADD_MATCH | 20 | Destination address matches the one programmed in SPEC21_ADD_[BOT|TOP] registers |
| SPEC20_ADD_MATCH | 19 | Destination address matches the one programmed in SPEC20_ADD_[BOT|TOP] registers |
| SPEC19_ADD_MATCH | 18 | Destination address matches the one programmed in SPEC19_ADD_[BOT|TOP] registers |
| SPEC18_ADD_MATCH | 17 | Destination address matches the one programmed in SPEC18_ADD_[BOT|TOP] registers |
| SPEC17_ADD_MATCH | 16 | Destination address matches the one programmed in SPEC17_ADD_[BOT|TOP] registers |
| SPEC16_ADD_MATCH | 15 | Destination address matches the one programmed in SPEC16_ADD_[BOT|TOP] registers |
| SPEC15_ADD_MATCH | 14 | Destination address matches the one programmed in SPEC15_ADD_[BOT|TOP] registers |
| SPEC14_ADD_MATCH | 13 | Destination address matches the one programmed in SPEC14_ADD_[BOT|TOP] registers |
| SPEC13_ADD_MATCH | 12 | Destination address matches the one programmed in SPEC13_ADD_[BOT|TOP] registers |
| SPEC12_ADD_MATCH | 11 | Destination address matches the one programmed in SPEC12_ADD_[BOT|TOP] registers |
| SPEC11_ADD_MATCH | 10 | Destination address matches the one programmed in SPEC11_ADD_[BOT|TOP] registers |
| SPEC10_ADD_MATCH | 9 | Destination address matches the one programmed in SPEC10_ADD_[BOT|TOP] registers |
| SPEC9_ADD_MATCH | 8 | Destination address matches the one programmed in SPEC9_ADD_[BOT|TOP] registers |
| SPEC8_ADD_MATCH | 7 | Destination address matches the one programmed in SPEC8_ADD_[BOT|TOP] registers |
| SPEC7_ADD_MATCH | 6 | Destination address matches the one programmed in SPEC7_ADD_[BOT|TOP] registers |
| SPEC6_ADD_MATCH | 5 | Destination address matches the one programmed in SPEC6_ADD_[BOT|TOP] registers |
| SPEC5_ADD_MATCH | 4 | Destination address matches the one programmed in SPEC5_ADD_[BOT|TOP] registers |
| SPEC4_ADD_MATCH | 3 | Destination address matches the one programmed in SPEC4_ADD_[BOT|TOP] registers |
| SPEC3_ADD_MATCH | 2 | Destination address matches the one programmed in SPEC3_ADD_[BOT|TOP] registers |
| SPEC2_ADD_MATCH | 1 | Destination address matches the one programmed in SPEC2_ADD_[BOT|TOP] registers |
| SPEC1_ADD_MATCH | 0 | Destination address matches the one programmed in SPEC1_ADD_[BOT|TOP] registers |
=== GPI Tx buffer format ===[pfe_gpi_tx_buf_format]
==== GPI Tx pre-header ====[pfe_gpi_tx_buf_preheader]
Byte order is big-endian.
|| Name | Offset | Size | Description ||
| start_data_off | 0x0 | 1 | Packet data start offset, relative to the start of this pre-header. |
| start_buf_off | 0x1 | 1 | This Tx pre-header start, relative to the start of the DDR buffer. |
| pkt_length | 0x2 | 2 | Total packet length |
| act_phyno | 0x4 | 1 | action / PHY number. 7-4: action low nibble 3-0: PHY number |
| queueno | 0x5 | 1 | action / queue number. 7-4: action high nibble 3-0: queue number |
| unused | 0x6 | 2 | Unused |
Action bitfield:
|| Name | Bit range | Description ||
| IPCHKSUM_REPLACE | 6 | |
| DONT_FREE_BUFFER | 5 | Do not free the buffer after Tx completion |
| VLAN_REPLACE | 3 | |
| TCPCHKSUM_REPLACE | 2 | |
| VLAN_ADD | 1 | |
| SRC_MAC_REPLACE | 0 | |
=== GPI registers ===[pfe_gpi_regs]
|| GPI instance | Base offset in CBUS ||
| EGPI1 | 0x210000 |
| EGPI2 | 0x230000 |
| HGPI | 0x290000 |
| EGPI3 | 0x340000 |
|| GPI | Associated 'PHY' ||
| EGPI1 | EMAC1 |
| EGPI2 | EMAC2 |
| EGPI3 | EMAC3 |
| HGPI | HIF |
|| Symbol | Offset | Description ||
| [VERSION #pfe_gpi_reg_version] | 0x000 | GPI silicon revision register |
| [CTRL #pfe_gpi_reg_ctrl] | 0x004 | GPI control register |
| [RX_CONFIG #pfe_gpi_reg_rx_config] | 0x008 | GPI Rx config register |
| [HDR_SIZE #pfe_gpi_reg_hdr_size] | 0x00c | GPI header size register |
| [BUF_SIZE #pfe_gpi_reg_buf_size] | 0x010 | GPI buffer size register |
| [LMEM_ALLOC_ADDR #pfe_gpi_reg_lmem_alloc_addr] | 0x014 | GPI LMEM alloc address register |
| [LMEM_FREE_ADDR #pfe_gpi_reg_lmem_free_addr] | 0x018 | GPI LMEM free address register |
| [DDR_ALLOC_ADDR #pfe_gpi_reg_ddr_alloc_addr] | 0x01c | GPI DDR alloc address register |
| [DDR_FREE_ADDR #pfe_gpi_reg_ddr_free_addr] | 0x020 | GPI DDR free address register |
| [CLASS_ADDR #pfe_gpi_reg_class_addr] | 0x024 | GPI CLASS address register |
| [DRX_FIFO #pfe_gpi_reg_drx_fifo] | 0x028 | |
| [TRX_FIFO #pfe_gpi_reg_trx_fifo] | 0x02c | |
| [INQ_PKTPTR #pfe_gpi_reg_inq_pktptr] | 0x030 | GPI packet IN Queue FIFO |
| [DDR_DATA_OFFSET #pfe_gpi_reg_ddr_data_offset] | 0x034 | GPI data offset for DDR packets |
| [LMEM_DATA_OFFSET #pfe_gpi_reg_lmem_data_offset] | 0x038 | GPI data offset for LMEM packets |
| [TMLF_TX #pfe_gpi_reg_tmlf_tx] | 0x04c | |
| [DTX_ASEQ #pfe_gpi_reg_dtx_aseq] | 0x050 | |
| [FIFO_STATUS #pfe_gpi_reg_fifo_status] | 0x054 | GPI FIFO status register |
| [FIFO_DEBUG #pfe_gpi_reg_fifo_debug] | 0x058 | GPI FIFO debug register |
| [TX_PAUSE_TIME #pfe_gpi_reg_tx_pause_time] | 0x05c | GPI Tx pause time register |
| [LMEM_SEC_BUF_DATA_OFFSET #pfe_gpi_reg_lmem_sec_buf_data_offset] | 0x060 | ? |
| [DDR_SEC_BUF_DATA_OFFSET #pfe_gpi_reg_ddr_sec_buf_data_offset] | 0x064 | ? |
| [TOE_CHKSUM_EN #pfe_gpi_reg_toe_checksum_en] | 0x068 | |
| [OVERRUN_DROPCNT #pfe_gpi_reg_overrun_dropcnt] | 0x06c | GPI dropped packets counter register |
==== VERSION (GPI_BASE + 0x000) ====[pfe_gpi_reg_version]
GPI silicon revision. 0x50 on my c2k chip.
|| Symbol | Bit range | R/W | Description ||
| VERSION | ?-0 | R | GPI silicon revision |
==== CTRL (GPI_BASE + 0x004) ====[pfe_gpi_reg_ctrl]
GPI control register. The ENABLE bit must be set prior attempting to access
the other GPI registers (except GPI_VERSION), otherwise the transaction may
hang forever (or until the watchdog kicks in).
Performing a software reset will not reset the value of the configuration
registers, only the internal state will be cleared.
|| Symbol | Bit range | R/W | Description ||
| SW_RESET | 1 | RW | Perform software reset. Self-clearing. |
| ENABLE | 0 | RW | GPI enable. 0=disable 1=enable |
==== RX_CONFIG (GPI_BASE + 0x008) ====[pfe_gpi_reg_rx_config]
Rx configuration register.
Depending on their size, the packets may be written to LMEM for small packets, or DDR for larger ones.
|| Symbol | Bit range | R/W | Description ||
| LMEM_RTRY_CNT | 31-16 | RW | LMEM write retry counter. Typical value is 0x40. |
| DDR_BUF_EN | 1 | RW | Enable use of buffers in DDR |
| LMEM_BUF_EN | 0 | RW | Enable use of buffers in LMEM |
==== HDR_SIZE (GPI_BASE + 0x00c) ====[pfe_gpi_reg_hdr_size]
Header size configuration register.
Depending on whether packets are written to DDR or LMEM, the size of the header
may differ. This register allows configuration of the header size for LMEM and
DDR buffers.
|| Symbol | Bit range | R/W | Description ||
| DDR_HDR_SIZE | 31-16 | RW | Header size for buffers in DDR. Typical value: 0x100 |
| LMEM_HDR_SIZE | 15-0 | RW | Header size for buffers in LMEM. Typical value: 0x10 |
==== BUF_SIZE (GPI_BASE + 0x010) ====[pfe_gpi_reg_buf_size]
Buffer size configuration register.
Depending on whether packets are written to DDR or LMEM, the size of the buffer
may differ. This register allows configuration of the buffer size for LMEM and
DDR buffers. The header size is included in the buffer size.
|| Symbol | Bit range | R/W | Description ||
| DDR_BUF_SIZE | 31-16 | RW | Size of DDR buffers. Typical value: 0x800 |
| LMEM_BUF_SIZE | 15-0 | RW | Size of LMEM buffers Typical value: 0x80 |
==== LMEM_ALLOC_ADDR (GPI_BASE + 0x014) ====[pfe_gpi_reg_lmem_alloc_addr]
Address in the PE address space of the
[BMU_ALLOC_CTRL #pfe_bmu_reg_alloc_ctrl] register of the [BMU #pfe_bmu]
instance to use to allocate a new buffer in LMEM. Each read operation to the
specified address must return the address of a newly-allocated buffer, or 0 if
no buffer is available.
The buffer size for the BMU must be greater or equal to the one configured in
the GPI.
|| Symbol | Bit range | R/W | Description ||
| LMEM_ALLOC_ADDR | 31-0 | RW | Address of the BMU buffer allocation register to use for LMEM buffer allocation. |
==== LMEM_FREE_ADDR (GPI_BASE + 0x018) ====[pfe_gpi_reg_lmem_free_addr]
Address in the PE address space of the
[BMU_FREE_CTRL #pfe_bmu_reg_free_ctrl] register of the [BMU #pfe_bmu]
instance to used to manage buffers in LMEM. The addresses of buffers to free
will be written at that address.
|| Symbol | Bit range | R/W | Description ||
| LMEM_FREE_ADDR | 31-0 | RW | Address of the BMU buffer allocation register to use for LMEM buffer allocation. |
==== DDR_ALLOC_ADDR (GPI_BASE + 0x01c) ====[pfe_gpi_reg_ddr_alloc_addr]
Address in the PE address space of the
[BMU_ALLOC_CTRL #pfe_bmu_reg_alloc_ctrl] register of the [BMU #pfe_bmu]
instance to use to allocate a new buffer in DDR. Each read operation to the
specified address must return the address of a newly-allocated buffer, or 0 if
no buffer is available.
The buffer size for the BMU must be greater or equal to the one configured in
the GPI.
|| Symbol | Bit range | R/W | Description ||
| DDR_ALLOC_ADDR | 31-0 | RW | Address of the BMU buffer allocation register to use for DDR buffer allocation. |
==== DDR_FREE_ADDR (GPI_BASE + 0x020) ====[pfe_gpi_reg_ddr_free_addr]
Address in the PE address space of the
[BMU_FREE_CTRL #pfe_bmu_reg_free_ctrl] register of the [BMU #pfe_bmu]
instance to used to manage buffers in DDR. The addresses of buffers to free
will be written at that address.
|| Symbol | Bit range | R/W | Description ||
| DDR_FREE_ADDR | 31-0 | RW | Address of the BMU buffer allocation register to use for DDR buffer allocation. |
==== CLASS_ADDR (GPI_BASE + 0x024) ====[pfe_gpi_reg_class_addr]
Address in the PE address space of the INQ_PKTPTR FIFO register in the
[CLASS_CSR block #pfe_class_csr].
The GPI will write the address of the first buffer to this location. This
buffer follows the format defined in the
[GPI Rx buffer format #pfe_gpi_rx_buf_format].
|| Symbol | Bit range | R/W | Description ||
| CLASS_ADDR | 31-0 | RW | Address of CLASS FIFO. |
==== DRX_FIFO (GPI_BASE + 0x028) ====[pfe_gpi_reg_drx_fifo]
Data? Rx FIFO depth? register?
|| Symbol | Bit range | R/W | Description ||
| ? | 15-0 | RW | ? Default value: 0x80 |
==== TRX_FIFO (GPI_BASE + 0x02c) ====[pfe_gpi_reg_trx_fifo]
? Rx FIFO depth? register?
|| Symbol | Bit range | R/W | Description ||
| ? | 15-0 | RW | ? Default value: 0x80 |
==== INQ_PKTPTR (GPI_BASE + 0x030) ====[pfe_gpi_reg_inq_pktptr]
Tx packet descriptor address FIFO?
The address of the packet descriptor for the packet to send can be written into
this register?
|| Symbol | Bit range | R/W | Description ||
| PKTPTR | 31-0 | RW | Address of the Tx descriptor of the packet to send? |
==== DDR_DATA_OFFSET (GPI_BASE + 0x034) ====[pfe_gpi_reg_ddr_data_offset]
Offset in the DDR buffer where data starts.
|| Symbol | Bit range | R/W | Description ||
| DATA_OFFSET | 8-0 | RW | Offset in the DDR buffer to the start of data region. Typical value: 0x100 |
==== LMEM_DATA_OFFSET (GPI_BASE + 0x038) ====[pfe_gpi_reg_lmem_data_offset]
Offset in the LMEM buffer where data starts.
|| Symbol | Bit range | R/W | Description ||
| DATA_OFFSET | 7-0 | RW | Offset in the LMEM buffer to the start of data region. Typical value: 0x10 |
==== TMLF_TX (GPI_BASE + 0x04c) ====[pfe_gpi_reg_tmlf_tx]
Something to do with TMU?
|| Symbol | Bit range | R/W | Description ||
| TMLF_TXTHRES | 7-0 | RW | Something Tx threshold value. Typical value: 0xbc |
==== DTX_ASEQ (GPI_BASE + 0x050) ====[pfe_gpi_reg_dtx_aseq]
Unknown.
|| Symbol | Bit range | R/W | Description ||
| ASEQ_LEN | 7-0 | RW | Unknown. Typical value: 0x40. EGPI1 has value 0x50. |
==== FIFO_STATUS (GPI_BASE + 0x054) ====[pfe_gpi_reg_fifo_status]
Some FIFO status register. Format unknown.
|| Symbol | Bit range | R/W | Description ||
| STICK? | 0 | RW | Keep Tx on hold? |
==== FIFO_DEBUG (GPI_BASE + 0x058) ====[pfe_gpi_reg_fifo_debug]
Number of Tx/Rx packets/bytes queued in the FIFO.
|| Symbol | Bit range | R/W | Description ||
| TX_PKTS | 29-24 | R | Tx packets |
| RX_PKTS | 23-18 | R | Rx packets |
| TX_BYTES | 17-9 | R | Tx bytes |
| RX_BYTES | 8-0 | R | Rx bytes |
==== TX_PAUSE_TIME (GPI_BASE + 0x05c) ====[pfe_gpi_reg_tx_pause_time]
Tx pause frame time?
|| Symbol | Bit range | R/W | Description ||
| TXPAUSE | 15-0 | RW | Tx pause time? Time unit unknown. Typical value: 0xffff |
==== LMEM_SEC_BUF_DATA_OFFSET (GPI_BASE + 0x060) ====[pfe_gpi_reg_lmem_sec_buf_data_offset]
Purpose unknown. Maybe offset to additional security context?
|| Symbol | Bit range | R/W | Description ||
| DATA_OFFSET | 15-0 | RW | Typical value: 0x0 |
==== DDR_SEC_BUF_DATA_OFFSET (GPI_BASE + 0x064) ====[pfe_gpi_reg_ddr_sec_buf_data_offset]
Purpose unknown. Maybe offset to additional security context?
|| Symbol | Bit range | R/W | Description ||
| DATA_OFFSET | 15-0 | RW | Typical value: 0x0 |
==== TOE_CHKSUM_EN (GPI_BASE + 0x068) ====[pfe_gpi_reg_toe_checksum_en]
Control some kind of checksum offloading?
|| Symbol | Bit range | R/W | Description ||
| TOE_CHKSUM_EN | 0 | RW | Enable checksum ??? |
==== OVERRUN_DROPCNT (GPI_BASE + 0x06c) ====[pfe_gpi_reg_overrun_dropcnt]
Counter of dropped packets.
|| Symbol | Bit range | R/W | Description ||
| DROPCNT | 31-0 | RW | Number of dropped packets. |