Forum Discussion
Data send thru ethernet
Hello,
I am trying to do a simple task: I will form an UDP packet in hardware, then I want to move it to Nios, add IP header and send to ethernet. I will split my problem into two parts: I've created avalon streaming source component, so I am able to move the packet to the Nios memory using SGDMA stream to memory, however I am not sure how can I move the packet to the TSE core? TSE also use SGDMA (st-to-mem and mem-to-st), so I can't connect my component to one of those SGDMA inputs, since it is already in use. What are my options? Add another SGDMA Stream-to-memory core and connect to the same memory that TSE SGDMA use? How can I pick the data from the memory using another SGDMA there? Lets say I already have a packet data in Nios, how can I add IP header to the packet using InterNiche? Maybe there are some examples of packet generation using InterNiche? Also I can't find NicheStack documentation anywhere, maybe someone could point me out? I suppose simple packet sending or receiving tasks can be used without RTOS? I have chosen SGDMA because the data stream can reach 50mbps or more, so the Nios should be really fast to add a header to the whole packet, which is almost 1400 bytes. Thank You.38 Replies
- Altera_Forum
Honored Contributor
Are there a lot of timing errors? hopefully they wouldn't be to difficult to solve.
- Altera_Forum
Honored Contributor
Well, I did not try to solve those errors (5 critical warnings)
Since my packet length is always the same, I am thinking of forming ip and udp headers in hardware and use packet send directly through TSE, like this is done in offload example. I am not sure if I need DMA, seems like it may be not useful now? - Altera_Forum
Honored Contributor
If the only packets that you need to send are those generated by hardware, then you don't need the DMA and can directly connect your IP to the TSE core.
If you also need to send packets from the CPU, then you'll also need a DMA and a multiplexer to connect both the DMA and your IP to the TSE core, like they do in the offload example. - Altera_Forum
Honored Contributor
I will probably form all required headers in hardware, since the required payload is constant size - always 188 bytes.
Edit, probably the idea is not quite OK. Two reasons why: 1) IP header use 16bit identification field which varies every packet, so I will have to recalculate the checksum anyway. 2) I am not sure, but if the implementation is fully hardware, what about ARP, ICMP and other common things? Will TSE do that? - Altera_Forum
Honored Contributor
I've checked packet inserter sources. If I understand verilog and that source correctly, there is no UDP checksum calculated (equals 0).
Indeed, RFC 768 says this: --- Quote Start --- If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic). An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care). --- Quote End --- This means, that if the checksum is sent 0 (actually 0 complement of one's), then the checksum is always accepted as OK. Basically, for good ethernet solution, the checksum should be added. I can't find proper implementation of UDP checksum calculations anywhere on the net. Edit: Yeah, found this line in the description of the udp_payload_inserter: --- Quote Start --- The UDP Checksum field is zero'ed as this component does not compute the UDP Checksum. --- Quote End --- So only IP header is calculated there. - Altera_Forum
Honored Contributor
It shouldn't be too difficult to calculate the IP checksum yourself, but I wonder if you could keep the identification field constant... For UDP it shouldn't be a problem.
You are right that the UDP checksum is optional, so you don't need to do it. As for the other protocols, no they aren't handled. ICMP would only be needed if you want to get error feedback (such as UDP port closed) but it doesn't always work because lots of routers discard it. Now for ARP... if you are just sending, you don't really need ARP if you have a CPU with network access somewhere. Then it can get the destination MAC address for you and give it to your component so that it sends it in the ethernet header. If you also need to receive it's more difficult because you would also need to be able to answer ARP requests. That's why it can be a good idea to share the TSE between your component and a Nios CPU with the SGDMAs. Let the CPU handle the other protocols such as ARP, and just use your hardware to generate the UDP packets. - Altera_Forum
Honored Contributor
Well I am on a crossroad then. I still want to generate UDP checksum in hardware even if it is not necessary, however now I have two possible solutions:
1) Generate payload data + add UDP header (including checksum) in hardware. Then forward this packet to Nios cpu which is running InterNiche, so the stack should add IP header by itself. Then I have another problem: where to find documentation how to calculate and add IP header to incoming packet from the subsystem? I suppose InterNiche has functions for IP header calculation, so I need only pass the data to the stack. 2) Generate payload data + UDP header + IP header in hardware and pass it to Nios+InterNiche. However I still need some documentation how to pass these packets to InterNiche and then to the network. Btw: I am now trying to do packet checksum by hand. I have a real packet sniffed from network with all the parameters available, but no matter how I try to calculate the checksum, I get it different from the correct one. Maybe there are checksum calculators? I think I may do wrong calculations because of wrong byte order or something else. I've taken the shortest packet, which consists only 18 byte data, so in this case I should get no carry bits and do calculations without carry bit mistake. Maybe someone have a good reference how to calculate the UDP checksum correctly in hardware? - Altera_Forum
Honored Contributor
Yes you'll probably have to dig into the interniche stack code to see how it is done. I think that you will need to allocate a mbuf and put your hardware generated data in there, providing enough room before the data so that the stack can add the headers. Then some of the internal functions will probably handle the rest.
But in my opinion it is more complicated go through the nios core just for that. Adding all the header in hardware and sending it directly to the TSE core should be simpler. For the UDP checksum, you need to add some (not all!) words from the header and data, do a one-complement and adjust if the result is zero. The wikipedia page (http://en.wikipedia.org/wiki/user_datagram_protocol#checksum_computation) explains it well. - Altera_Forum
Honored Contributor
It should, but later I will have to do packet receiving. I also need ARP and ICMP, so correct packet transmit engine will be my reference to packet receiving.
- Altera_Forum
Honored Contributor
Hello again,
I've made the IP header and UDP checksum in hardware, so now I can forward 32 bit data to Nios. Since I need full ethernet support (ICMP and ARP), I need to know how to put that streaming data to InterNiche buffer? Are there any documentation? I can also use LwIP, but it seems like it is not well documented how to use it in Nios...