Version 79, changed by hippo5329@yahoo.com.tw. 04/13/2008. Show version history
To enable network driver support, in uClinux-dist kernel config,
Device Drivers -->Network device support ─>
[*] Network device support
[*] Ethernet (10 or 100Mbit)
[*] SMC 91C9x/91C1xxx support # only if you use Altera Nios dev board with SMC91111,
[ ] Opencores (Igor) Emac support
[ ] MoreThanIP 10_100_1000 Emac support
[*] DM9000 support # only if you use DE2 with DM9000A
[ ] DM9000A with checksum offloading # alternative driver for DM9000A , BROKEN!!
If you use Altera's Nios dev board, select "SMC 91C9x/91C1xxx support" . linux-2.6.x/drivers/net/smc91x.c .
If you use DE2 board, you should enable "DM9000 support" . linux-2.6.x/drivers/net/dm9000.c .
If you use Altera Stratix dev board, you must change the irq number of the ether chip to a non-zero value in SOPC builder and rebuild.
Then rebuild the kernel, and boot nios2 uclinux. It should detect the SMC 91111 or DM9000 device as eth0.
If your board has only a PHY, you may use Avalon OpenCores 10/100 Ethernet MAC (you have to register nios forum to download this core) . Name the component as "igor_mac" and select "[*] Opencores (Igor) Emac support" .
Every board should have a unique ethernet hardware address. In file linux-2.6.x/arch/nios2nommu/kernel/setup.c, kernel get the hw addr from the flash on Altera dev board. You may use 'ifconfig' to find out. If you use custom boards, you need to change setup.c or use ifconfig to set hw address.
ifconfig eth0 hw ether 00:07:ed:0a:03:29 # hardware MAC address 00:07:ed:0a:03:<random 00-ff>
Then config the ip address and router.
ifconfig eth0 192.168.1.10 # static ip
route add default gw 192.168.1.254 # gateway
Or, use dhcp client if you have a dhcp server on the local network ( it won't work if you don't have a dhcp server),
ifconfig eth0 up
dhcpcd &
To check the ethernet connection, try "ping" the board to and from your PC or gateway. eg,
/> ping 192.168.1.254
The telnetd and ftpd should be invoked by inetd with the default config. The BOA is standalone.
/> inetd & # start inetd to invoke telnetd and ftpd services
[15]
/> boa & # start httpd with cgi-demo
[16]
/> netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:http *:* LISTEN
tcp 0 0 *:ftp *:* LISTEN
tcp 0 0 *:telnet *:* LISTEN
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
You may try these servers from your PC,
ftp 192.168.1.10 # user ftp, password anything
telnet 192.168.1.10
http://192.168.1.10
from a web brower
You may add these setup for ethernet to the file vendors/Altera/nios2nommu/rc (which will become /etc/rc ) in uClinux-dist dir, follow the setup for "lo" . So that the ethernet will be configed by init.
With dm9ks driver in DE2 the ftpd transfer rate is around 1.5-1.7 MByte/s.
To set name server (DNS) , create the file vendors/Altera/nios2nommu/resolv.conf , with a line of your name server, eg
nameserver 192.168.1.254
Then add a line to romfs: target in file vendors/Altera/nios2nommu/Makefile
$(ROMFSINST) /etc/resolv.conf
Which will be /etc/resolve.conf on your board.
Or if you use DHCP, the dhcpcd will create the file /etc/resolv.conf .
Refer to the end of
NFSFileSytem wiki page for a sample dhcpd.conf.
You may use "ntpdate" to get date & time from internet. Set TZ env to your timezone, eg "TZ=CST-8" for east China. Or edit the file vendors/Altera/nios2nommu/TZ , which will be /etc/TZ as the cache of TZ env.
/> TZ=CST-8
/> ntpdate pool.ntp.org
Looking for host pool.ntp.org and service ntp
host found : 71.237.179.90
13 Dec 11:05:33 ntpdate[20]: step time server 71.237.179.90 offset 222059037.166530 sec
/> date
Wed Dec 13 11:05:39 2006
Reading about performance issues,
Zero Copy I: User-Mode Perspective
Linux Ethernet-Howto: Technical Information
Choosing an Ethernet NIC for Linux 2.4
gigabit ethernet over copper performance comparison at University of Northern Iowa.
Jumbo Frames support can be enabled by changing the MTU to a value larger than the default of 1500. Use the ifconfig command to increase the MTU size.
eg, ifconfig eth<x> mtu 6000 up
SOPC Component for DM9000
For SOPC Builder, create a new component using this verilog file DM9000A_CTRL.v. Click next until the "interface" tab, then make the following changes :
After creating the component, add it to your design. Make sure it is named "DM9000". Thats it. The code includes a clock divider for 25MHz, which means that the input clock to it must be 50MHz.
After compiling the design, the pin assignments must be set. The pin names used in the verilog code matches the pin names used in the DE2 User manual. Make sure the pin assignment is done correctly.
This works in Altera Quartus 7.1sp1.
we try it in Quatus 7.2 I there is somthing different
add a type of signal when creat commpoment interrupt sender
then change the irq signal to this type others is same to front steps
Here is another approach for Quartus v7.1 and later. We use Avalon tristate bridge to connect the DM9000A. This has the advantage that many external peripheral chips can share some signals on the bus, such as CFI flash, SRAM, USB or multiple DM9000A.
Put dm9000a_hw.tcl in your project directory. Open SOPC Builder, and you can find a new "dm9000a" component.

Add a new Avalon-MM
tristate bridge. Add a "dm9000a" component, name it as "dm9000", and connect
it to the Avalon tristate bridge master. You don't need other VHDL or
Verilog for this component, because the SOPC builder will generate a
wrapper inside. Note, don't assign irq 0 to dm9000.

There is no clock output in this component. The DM9000A needs a 25MHz clock. You can add a crystal to the DM9000A on-chip OSC. Or you can generate the clock in your top level design using counter, eg 50MHz div 2. for DE2, (PLL has larger jitter, and not so good)
reg ENET_CLK;
always @(posedge CLOCK_50) ENET_CLK<= ~ENET_CLK;
wire [1:0] cmd_dm9000;
assign ENET_CMD = cmd_dm9000[1];
// in the sopc system (cpu) module instance
// the_DM9000A
.cmd_to_the_dm9000(cmd_dm9000),
.cs_n_to_the_dm9000(ENET_CS_N),
.data_to_and_from_the_dm9000(ENET_DATA),
.irq_from_the_dm9000(ENET_INT),
.ior_n_to_the_dm9000(ENET_RD_N),
.rst_n_to_the_dm9000(ENET_RST_N),
.iow_n_to_the_dm9000(ENET_WR_N),
++++++++++++++++++++++++++++++ debug ++++++++++++++++++++++++++++
To debug this componet,
In Quartus memu Tools --> Signal Tap II Logic Analizer,
Signal Configuration window , Clock: ... select your processor clock.
Setup tab, add signals ior,iow,cs,cmd and data. Add DM9000 clock if it is generated from FPGA.
Save the stp file, as dm9000.stp . Recompile in Quartus. Then download the new
sof. In Signal Tap window, setup Trigger with rising edge of ior, and Run Analysis.
Then you can check the waveform.
Follow DebugKernel . Open a nios2-terminal and start insight GDB. In the "source" window of Insight, open dm9000.c and set breakpoint at the line of id_val check in dm9000_probe(),
/* try two times, DM9000 sometimes gets the first read wrong */
for (i = 0; i < 2; i++) {
id_val = ior(db, DM9000_VIDL);
id_val |= (u32)ior(db, DM9000_VIDH) << 8;
id_val |= (u32)ior(db, DM9000_PIDL) << 16;
id_val |= (u32)ior(db, DM9000_PIDH) << 24;
if (id_val == DM9000_ID) <== set breakpoint here
break;
printk("%s: read wrong id 0x%08x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", CARDNAME, id_val);
}
if (id_val != DM9000_ID) {
printk("%s: wrong id: 0x%08x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n", CARDNAME, id_val);
goto release;
}
When it hits breakpoint, check the "local" window, db->io_addr and db->io_data should have your port address.
Then open "memory" window and display or modify these address.
set_module_property "instantiateInSystemModule" "false"
You should read the data sheet of DM9000. The chip needs an inactive time between
read and write, timing t6, which can be 4-2 DM9000 internal clock, ie
80-20ns. So it won't help to use longer "wait states", if the data
sheet is true. You should use longer "setup" time. The DM9000 HAL
driver, they added a lot of usleep() for the inactive time. But the
Linux driver does not.
The slave interface timing of this component is,
setup time 1 cycle, read wait 1 cycle, write wait 1cycle, hold time 1 cycle.
At 100MHz clock, this provides 20ns command active time, and 20ns inactive time. With two additional instructions cycles, it gives 40ns inactive time, and the timing requirement is met.
You may change the interface timing using Component Editor if your clock is different.
++++++++++++++++++++++ only for 8 bits interface +++++++++++++++++++++++++++++++++++++++If you need 8 bits interface, add a resistor to pull
high the EECS pin of DM9000A, edit the component in SOPC builder,
change the "width" of signal "data" to "8". The bit shift cmd_dm9000 is not needed for 8 bits interface, and should be removed.
Just use,
.cmd_to_the_dm9000(ENET_CMD),
There is no need to change the dm9000 driver. But you need to tell the driver that you want to use 8 bits mode.
Edit the file, linux-2.6.x/arch/nios2nommu/kernel/setup.c , locate the flags,
static struct dm9000_plat_data dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY, ===> change 16 to 8
};
The DM9000 port address binding is in the same file, linux-2.6.x/arch/nios2nommu/kernel/setup.c , using platform_device data structure.