The Wiznet chips are well supported on Arduino, but I have a PIC. Searching for PIC code without any dependencies on Microchip peripheral libraries or similar, I came across this first:
http://www.ermicro.com/blog/?p=1773Which is for AVR (not Arduino), but it was a good tutorial, with simple example code. Looked easy enough to port, so I had a go at it. With it and the W5100 datasheet, I had basic TCP/IP working in a few hours. Then a couple more days experimenting, optimizing, and tying it into my personal programming environment; which ended up being a total rewrite. Since I do this to learn more than to achieve an end result, for me it was time well spent. None of it was particularly hard, the chip really does hide most of the complexity.
But there were some issues. The W5100 has a linear memory space, containing both the control registers, and the circular (ring) buffers for RX/TX data. Let's say you want to send multiple bytes of payload data over SPI to one of the circular buffers. You must:
1) Lower the chip select (CS) line.
2) Send the "write memory" command.
3) Send the low and high bytes of the memory address, where you want to place the data byte.
4) Send the data byte.
5) You cannot send another byte, because the address doesn't autoincrement. Sending another byte will *replace* the one you just sent, at the same memory address. You have to send a new address, which requires raising CS and going back to #1.
Transferring 4 bytes for every byte of real data is terribly inefficient. The W5100's speed is limited more severely by this, than by its 10Mbps Ethernet. Plus it's extra load on the host MCU, since you're recomputing the address for every byte. And since you're having to toggle CS regularly, you can't even take full advantage of DMA.
The W5100 also doesn't tristate MISO when CS is high. This non-standard behavior really should be mentioned in the main datasheet, but it's not, only in a separate app note regarding SPI. If you intend to have it share a bus with other SPI peripherals, you must add an additional buffer IC.
So I upgraded to the W5200. It has 100Mbps Ethernet, and more memory; neither of which I actually needed. But it autoincrements, and tristates MISO. Presumably newer versions include these enhancements as well. Converting my code was just a matter of putting in new register addresses and buffer ranges, other than the differences I listed it's virtually identical. I'm happy with this one.
There's one other thing worth mentioning. Neither chip seems to have a power-on reset function, or if it does, it doesn't work well. Do NOT skip manually asserting the reset signal after power-on. Do NOT try to be clever like I did, and attempt to conserve an MCU pin by using a RC reset circuit. Do NOT assume any pre-built module with these chips has a pull-up resistor on reset (mine didn't). If you fail to reset it after power-on exactly as described in the datasheet, it may confound you by working many times in a row, then failing when you least expect it. The W5200 can also fail to tristate MISO if not reset, blocking comms with other SPI devices on the same bus.