![](/images/new-backgrounds/1167723/167723103x1.webp)
IXP1200 Network Processor Family ATM
237:[42]: | 0 | ETHER_RX_PACKET_ENQUEUE_ETHER |
238:[43]: 1805817712 | ATM_TX_CRC_PDU_DQ | |
239:[44]: 1688091717 | ATM_TX_CRC_PDU_ENQ | |
240:[45]: 1688086138 | ATM_RX_CRC_PDU_DQ | |
241:[46]: 1688086138 | ATM_RX_CRC_PDU_ENQ | |
242:[47]: | 0 | ATM_RX_IPR_FULLQ |
243:[48]: | 0 | ATM_RX_CRC_CHK_FULLQ |
244:[49]: 1510539591 | ATM_TX_CRC_GEN_FULLQ | |
245:[50]: | 0 | PACKETQ_SEND_BAD_BDA |
246:[51]: | 0 | PACKETQ_SEND_BAD_INDEX |
247:[52]: | 0 | BDQ_ENQUEUE_BAD_INDEX |
248:[53]: | 0 | QUEUE_BAD_BDA |
249:[54]: | 0 | ATM_RX_CRC_BAD_BD |
250:[55]: | 0 | ATM_TX_CRC_BAD_BD |
251:[56]: 1688087098 | ATM_LOOPBACK forwarded packet with ATM dest to Ethernet | |
252:[57]: | 0 | Counter 57 |
253:[58]: | 0 | Counter 58 |
254:[59]: | 0 | Counter 59 |
192:117726288 Total Packets Discarded
128:[port 8]: 68882072 PORT_FULLQ
138:[port | 8]: | 1 IP_BAD_CHECKSUM |
144:[port | 9]: | 48844381 PORT_FULLQ |
4.9Global $transfer Register Name Manager - xfer.uc
SRAM transfer registers are easily allocated and deallocated by using .local/.endlocal, or by using the xbuf.uc subsystem, which is based on .local. This works well for read transfer registers, because the programmer always knows when the read is done, and thus when the read transfer register can be freed.
However, write transfer registers are a different problem. While it is possible to use the same mechanism as for read transfer registers, this requires waiting for writes to complete before re- using the write transfer registers, and this wait may impact performance.
An alternative is to not wait for the write to complete, but to infer the completion of writes by their order before subsequent reads in the ordered SRAM queue. The .local mechanism and xbuf.uc require strict block structure, and are thus not well suited to write transfer registers becoming available based on seemingly unrelated events. The question becomes then how to manage the name space for write transfer registers.
The answer, at least for some implementations such as the ATM receive microengine, is to allocate transfer registers globally, and to use the new xfer.uc subsystem to help manage the name space.
//Macros to aid in manually allocating transfer registers.
//Essentially wrappers for .xfer_order, .operand_synonym
//that use the
//sanity checking as possible.
//API
//xfer_init(NUM_READ_WRITE)
//xfer_reserve(NAME, POSITION, FLAGS)
//xfer_free(NAME, POSITION, FLAGS)
//Example:
//xfer_init(1) ;; use 1 of 8 $transfers
//xfer_reserve($foo, 0, XFER_RESERVE_READ XFER_RESERVE_WRITE)
//sram[write, $foo], ordered
//sram[read, $foo], ordered, ctx_swap
//xfer_free($foo, 0, XFER_RESERVE_WRITE)
//xfer_reserve($bar, 0, XFER_RESERVE_WRITE)
//sram[write, $bar], ordered
52 | Application Note |
Modified on: 3/20/02,