WIZnet’s chip solution includes Hardware TCP/IP stack (we are saying it TCP/IP Offload engine). Can we use WIZnet chip on the platform where software TCP/IP stack already operates such as Linux.? Yes, we can. There are 3 ways
#1 : Use the MACRAW mode. In this mode, WIZnet chip operates as normal MAC/PHY chip.
#2 : Replace the software TCP/IP with Hardware TCP/IP engine of WIZnet chip (Disable the software TCP/IP engine)
#3 : Mixing #1 & #2. We are saying it hybrid mode.
In this posting, we will provide the porting guide of W5500 Linux driver using MACRAW mode. We will use the W5300E01-ARM for Linux board and its kernel version is 2.6.24. (W5300E01-ARM is based on the MCU, S3C2410A(200MHz &266MHz -32-Bit RISC)
1. Driver Development Environment
Preparation materials
- Software
- arm-toolchain-3.4.3.tar.gz
- linux-2.6.24.4-w5300e01
- included .config: copied w5300e01-config-v01
- patched by patch-w5300e01-v01: patch-w5300e01-v01
- Hardware
- Documentations
Install Toolchain
After downloading ‘arm-toolchain-3.4.3.tar.gz’, install it as below.
make directory /usr/local/arm
mkdir /usr/local/arm
Install toochain
# tar zxvf arm-toolchain-3.4.3.tar.gz # cp -rf usr/ /usr/local/arm/arm-gcc-W5300
Setting toochain path:
//Add below path in **.bashrc** x export PATH=/usr/local/arm/arm-gcc-W5300/bin::$PATH //then sourcing the bashrc file # source .bashrc
Verify: type arm and press TAB
~$ arm arm2hpdl arm-linux-gcc arm-linux-objdump arm-linux-addr2line arm-linux-gcc-3.4.3 arm-linux-ranlib arm-linux-ar arm-linux-gccbug arm-linux-readelf arm-linux-as arm-linux-gcov arm-linux-run arm-linux-c++ arm-linux-gdb arm-linux-size arm-linux-c++filt arm-linux-ld arm-linux-strings arm-linux-cpp arm-linux-nm arm-linux-strip arm-linux-g++ arm-linux-objcopy
Compile Linux kernel
# tar zxvf linux-2.6.24.4-w5300e01.tar.gz # cd linux-2.6.24.4 # cp ../w5300e01-config-v01 .config # make wizImage # or make ARCH=arm CROSS_COMPILE=arm-linux- wizImage -j8
2. Hardware Connection
Below is the layout of W5300E01-ARM. We are going to connect it with WIZ550io using J4 connector
J4 Connector
Connect WIZ550io with SPI0 of J4 Connector
The pin connections are as below
Pin Name | Pin No | Dir | WIZ550io |
SPICLK0 | 24 | -> | SPI Clock |
SPIMOSI0 | 26 | -> | SPI MOSI |
SPIMISOO | 28 | <- | SPI MISO |
EINT10 | 30 | RESETn | |
ENT1 | 37 | -> | SPI SELECT |
※ WIZ550io PinMap
3. Porting Guide
Hardware Configuration in mach-W5300e-1.c
Set W5500 hardware related configuration in ‘mach-w5300e01.c’, the configuration file that exists in the path ‘
linux/arch/arm/mach-s3c2410/’
- SPI pin configuration
//static void __init w5300e01_init(void) /* W5500 SPI pin */ s3c2410_gpio_cfgpin(S3C2410_GPF1, S3C2410_GPF1_OUTP); //SCS s3c2410_gpio_setpin(S3C2410_GPF1, 1); //low active s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_SPICLK0); //SCLK s3c2410_gpio_setpin(S3C2410_GPE13, 1); s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_SPIMOSI0); //MOSI s3c2410_gpio_setpin(S3C2410_GPE12, 1); s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_SPIMISO0); //MISO s3c2410_gpio_setpin(S3C2410_GPE11, 1);
- Interrupt Request(IRQ) Pin Connection
//static void __init w5300e01_init(void) /* W5500 interrupt pin */ s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_EINT10); //GPG2 Interrupt s3c2410_gpio_setpin(S3C2410_GPG2, 1); //low active
- Reset Pin Configuration
//static void __init w5300e01_init(void) /* W5500 Reset pin */ s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP); s3c2410_gpio_setpin(S3C2410_GPF6, 1);
- Virtual Base Address Configuration
static struct map_desc w5300e01_iodesc[] __initdata = { { 0xf0000000, __phys_to_pfn(S3C2410_CS2), SZ_1M, MT_DEVICE }, { 0xf8000000, __phys_to_pfn(S3C2410_CS3), SZ_1M, MT_DEVICE }, { 0xe8000000, __phys_to_pfn(S3C2410_PA_SPI), SZ_1M, MT_DEVICE } };
W5500 Linux Driver Porting
- Enable PCLK into SPI block
//dev.c void iinchip_spiclock_init(void) { ... reg = ioremap((unsigned long)rCLKCON, 4); *reg |= 0x40000; ... }
- Control : polling mode / SPI Clock enable / master select / CPOL=0 / etc
//spi.h (*(volatile unsigned char *)(_rSPCON0) = (0x18))
- Baudrate : PCLK / 2 / ((SPPRE0)+1)
//spi.h (*(volatile unsigned char *)(_rSPPRE0) = (0x02));
- IRQ
//module.c wiz_module_init(void) { ... gDrvInfo.irq = IRQ_EINT10; ... }
- Chip Select
//spi.h #define IINCHIP_CSon(Cs) (*_rGPFDAT) |= 0x2 #define IINCHIP_CSoff(Cs) (*_rGPFDAT) &= 0xfffffffd
- Default MAC Address
Write the detault MAC address to W5500. You can change the MAC address using ifconfig in kernel.
//module.c static unsigned char defmac[] = { 0x00, 0x08, 0xDC, 0x91, 0x97, 0x98 }; static int __init wiz_module_init(void) { ... /* mac address */ memcpy(gDrvInfo.macaddr, defmac, 6); ... }
- Socket Buffer Size
W5500 supports 8 hardware sockets. As 5500 operates as MACRAW mode, we will allocate 8Kbytes to the socket#0 for TX/RX buffer. (At eh MACRAW mode, only socket#0 is available)
//dev.cstatic unsigned char txsize[MAX_SOCK_NUM] = { 8, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char rxsize[MAX_SOCK_NUM] = { 8, 0, 0, 0, 0, 0, 0, 0 }; void iinchip_sysinit(void) { ... for (i = 0 ; i < MAX_SOCK_NUM; i++) { /* Set Buffer Size */ iinchip_outb(TX_BUF_SIZE_PTR(i), txsize[i]); iinchip_outb(RX_BUF_SIZE_PTR(i), rxsize[i]); ... }
- SPI READ/WRITE Function
//spi.h #define SPI0_RxData() (*(volatile unsigned char *)(_rSPRDAT0)) //(ioread8(_rSPRDAT0)) #define SPI0_TxData(Data) (*(volatile unsigned char *)(_rSPTDAT0) = (Data)) //(iowrite8(Data, _rSPTDAT0 #define SPI0_WaitForSend() while(!((*(volatile unsigned char *)(_rSPSTA0)) & 0x01)) //while(!(ioread8(_rSPSTA0) & 0x01)) #define SPI0_SendByte(Data) SPI0_TxData(Data);SPI0_WaitForSend() #define SPI0_RecvBute() SPI0_RxData()
- Hardware Reset for W5500
//dev.c oid iinchip_hwreset(void) { s3c2410_gpio_setpin(S3C2410_GPF6, 0); mdelay(1); s3c2410_gpio_setpin(S3C2410_GPF6, 1); mdelay(2); mdelay(3000);// WIZ550IO Need for MCU which is embedded on Board. }
4. Testing W5500 Linux Driver
- Connect the serial port to a PC to check the logs. You can download w5500.ko, the Linux driver module through Zmodem
- You can download the kernel through the Ethernet port of WIZ830MJ at the Bootloader
- After kernel is activated, the packet is transferred through Ethernet port of WIZ550io.
Kernel download on target board
Connect the W5300E01-ARM and PC using serial cable. In order to enter the bootloader, input ‘enter’ in the serial terminal in 3 seconds after turning on the power of the board. You can download the kernel to the target board as below.
#tftp 31000000 wizImage // to download wizImage(kernel image) to the target board #nand erase 40000 3c0000 //remove nand flash kernel area #nand write 31000000 40000 2eb958 // write kernel image to nand flash kernel area #reset //re-start #login ID : root
Driver module download
At the serial terminal, you can download ‘w5500.ko’ through zmodem, and load the module to the kernel.
#rmmod wiznet //remove W5300 linux driver(default) module #lsmod //verify #insmod w5500.ko // insert w5500.ko module #ifconfig wiz0 192.168.0.3 //setting network IP address
Ping Test
- on the Board side
#ping 192.168.0.223 // PC address
- on the PC side
#ping 192.168.0.3 // Target board address
netloop in app
You can use network loopback program included in driver code.
- Compile
#arm-linux-gcc netloop.c -o netloop
- Download netloop by using Zmodem
Download the netloop to the target board using Zmodem.
- netloop options
Option | Description |
-u | UDP loopback mode |
-t | TCP loopback mode |
-p | Port Number (Default 5001) |
-b | Socket Buffer size (Default 2048) |
- Example : TCP loopback: port number 5003, socket buffer size : 4096
$netloop -t -p 5003 -b 4096
COMMENTS