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.
Use sendto() function. For instance,l = sendto(conn->fd, data, pkgLth, 0,(struct sockaddr *)&cliaddr,nLen); By the by can you tell me how you move the data from hardware to Nios processor? Jacky
Maybe there is documentation for all the stack?I am using my custom hardware->Avalon-ST and Avalon-ST-> hardware component. They're very simple to do, since SOPC builder gives templates, when creating a new component.
Since you started generating the udp packet in hardware, why don't you go all the way and generate the IP and Ethernet headers the same way? Then you can use a multiplexer and send your packet directly to the TSE without going through memory.Did you have a look at the UDP offload example? http://www.alterawiki.com/wiki/nios_ii_udp_offload_example
Hm, I am not sure, but I suppose IP header is a bit harder to add in hardware, because of header checksum. Maybe there are full (IP(UDP(RTP))) implementations in hardware?I am checking UDP offload example now, too bad I am bad at verilog :)
The payload checksum in UDP is optionnal, so indeed you are only left with the IP header cheksum. If all your packets have the same length, the checksum will always be the same and can be pre-calculated in software. If your packets have various length, the software can pre-calculate the checksum with a length of 0 and the hardware just needs to add the length to that value before putting it in the header. I don't remember how this is done in the example.The Ethernet CRC is automatically calculated by the TSE so you don't need to worry about this one.
What about packet receive then? In this phase, I do only transmit, but in the second I will have to do packet receive. My idea was to make header easy to add/check/remove.Altera provides Video-Over-IP reference design, which is exactly what I need, however I did not manage to make it running on Q10.1sp1, so I am doing my own.
The old design made with Q9.0 fails timing @ 10.1sp1, so the design doesn't run - Nios is not found in the system (yes, sysid component is in the system). I've checked the source, however such simple project it should be, but use RTOS - which makes it complicate...
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?
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.
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?
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.
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.
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?
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.
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...