The ADM5120 has a built in ethernet switch. It has up to 6 external ports (5 on the SQFP package, the BGA package has an extra MII port). Also there is a special 'CPU' port which is used to send the packages to and from the CPU.
Internally the driver works with 6 VLANs. Each of the ports (including the cpu port) can be part of any of these vlans. These VLANS can be seen as the actual switches, if two ports are part of the same VLAN packets will be routed between them.
Switch matrix and the Linux driver
The setup of these vlans can be done using a switch matrix. This is a 6 by 7 matrix encoded into 6 bytes. Each of the bytes is the matrix setup for a single vlan. Each of the bits of such a byte represent one of the 6 ports or the cpu port. (It is possible to configure a switch without the cpu port in it, this will result in a ethernet switch with no cpu load at all.)
The Linux driver will allocate an ethernet device for each of the available vlans. Per default the driver will setup up the matrix such that each port has its own vlan and the cpu port is part off every vlan.
Configure vlan via /proc
/ # cd /proc/sys/net/adm5120sw/ /proc/sys/net/adm5120sw # ls eth0 eth1 eth2 eth3 eth4 eth5 status /proc/sys/net/adm5120sw # cat status WAN up 100M full-duplex enabled vlanid=1 unit=0 Port1 down - - enabled vlanid=2 unit=1 Port2 down - - enabled vlanid=4 unit=2 Port3 down - - enabled vlanid=8 unit=3 Port4 down - - enabled vlanid=16 unit=4 /proc/sys/net/adm5120sw # ifconfig eth0 down /proc/sys/net/adm5120sw # ifconfig eth1 down /proc/sys/net/adm5120sw # ifconfig eth2 down /proc/sys/net/adm5120sw # ifconfig eth3 down /proc/sys/net/adm5120sw # ifconfig eth4 down /proc/sys/net/adm5120sw # echo 0 >eth0 /proc/sys/net/adm5120sw # echo 1234 >eth1 /proc/sys/net/adm5120sw # cat status WAN up 100M full-duplex disabled vlanid=1 unit=0 Port1 down - - disabled vlanid=2 unit=1 Port2 down - - disabled vlanid=4 unit=2 Port3 down - - disabled vlanid=8 unit=3 Port4 down - - disabled vlanid=16 unit=4 /proc/sys/net/adm5120sw # ifconfig eth0 up /proc/sys/net/adm5120sw # ifconfig eth1 up /proc/sys/net/adm5120sw # cat status WAN up 100M full-duplex enabled vlanid=1 unit=0 Port1 down - - enabled vlanid=2 unit=1 Port2 down - - enabled vlanid=2 unit=1 Port3 down - - enabled vlanid=2 unit=1 Port4 down - - enabled vlanid=2 unit=1
The driver has a few ioctls for configuring the matrix. The tool 'admswconfig' uses these to get and set the matrix. This is the output of the tool with the default matrix set:
# admswconfig eth0 ADM5120 switch detected with 5 ports eth0 is vlan0 vlan port0 port1 port2 port3 port4 CPU 0 1 1 1 1 1 2 1 1 3 1 1 4 1 1 #
In the following example ports 1,2,3 and 4 form a single switch and are mapped to eth0 and port 0 is mapped to eth1. This is the default hardwired in the Edimax BR6104 routers.
# admswconfig eth0 "1234c" # admswconfig eth1 "0c" # admswconfig eth2 "" # admswconfig eth3 "" # admswconfig eth4 "" # admswconfig eth0 ADM5120 switch detected with 5 ports eth0 is vlan0 vlan port0 port1 port2 port3 port4 CPU 0 1 1 1 1 1 1 1 1 2 3 4 #
The admswconfig tool can be downloaded from this page.
The admswconfig tool does not work on the Hawking H2WR54G Linux 2.4.18 kernel. It does not recognize any of the ethX devices as VLANs. The ADM5120 network switch driver code that supports the necessary IOCTL calls seems to be missing from the kernel. It is hard to tell exactly what the problem is since Hawking does not supply source code for their devices as required by the GPL. The Hawking firmware seems to be substantially based on the tried-and-true Edimax source but there are significant differences that are impossible to pin down without the source code.
However, AMiLDA Linux's kernel has this driver backported from 2.6, and so the admswconfig tool can be used perfectly.
ADM5120 switch hardware descriptor has 25-bit dma address field. So dma-addressible only 32Mb. But in MIPS Linux kernel dma-addressible all memory. So if you have memory more than 32Mb, driver would not works properly. And sometimes in switch drivers DMA mask is incorrect: 0xffffff instead 0x1ffffff (look in driver header files).