Version 84, changed by hippo5329@yahoo.com.tw. 06/30/2008. Show version history
To enable network driver support, in uClinux-dist kernel config. Select the ethernet device on your board, and unselect what you don't have.
Device Drivers -->Network device support ─>
[*] Network device support
[*] Ethernet (10 or 100Mbit)
Select this if you are using Altera nios dev board with SMC91c111 on board,
[*] SMC 91C9x/91C1xxx support
Select this only if you are using opencore 100/10 ethernet mac.
The opencore mac component should be named as "igor_mac" , otherwise you have to modify linux-2.6/arch/nios2/kernel/setup.c .
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) .
[*] Opencores (Igor) Emac support
Select this only if you are using morethanip 1000/100/10 ethernet mac,
[*] MoreThanIP 10_100_1000 Emac support
Select this if you are using DE2, DE2-70 with DM9000A chip, and the component must be named as "dm9000"
[*] DM9000 support
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.
Every ehternet port should have a unique ethernet hardware mac address, usually assigned by vendor. You should use "ifconfig" to set hw address in user space before you use the ethernet interface.
ifconfig eth0 hw ether 00:07:ed:0a:03:29 # hardware MAC address 00:07:ed:0a:03:<random 00-ff>
Or,
if you are using Altera dev board, and you enabled MTD support. There is a hw address in the last 64KB block offset 4 in the cfi flash. Then you can read the hw address from flash with the "setmac" apps, which will read the mtd and call ifconfig to set the hw address. Here is an example on Altera Nios dev board 2C35 edition,
smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@cam.org>
eth0: SMC91C11xFD (rev 1) at 82210300 IRQ 6 [nowait]
eth0: Invalid ethernet MAC address. Please set using ifconfig
physmap platform flash device: 01000000 at 00000000
physmap-flash.0: Found 1 x16 devices at 0x0 in 8-bit bank
Amd/Fujitsu Extended Query Table at 0x0040
physmap-flash.0: CFI does not contain boot bank location. Assuming top.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
cmdlinepart partition parsing not available
RedBoot partition parsing not available
Using physmap partition information
Creating 4 MTD partitions on "physmap-flash.0":
0x00200000-0x00800000 : "romfs/jffs2"
0x00000000-0x00200000 : "loader/kernel"
0x00800000-0x00c00000 : "User configuration"
0x00c00000-0x01000000 : "safe configuration"
Sash command shell (version 1.1.1)
/> hexdump -s 0x3f0000 /dev/mtd3
3F0000: FE 5A 00 00 00 07 ED 0A-03 29 FF FF FF FF FF FF .Z.......)......
3F0010: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
3F0020: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
3F0030: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
3F0040: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
3F0050: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
3F0060: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
3F0070: FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
--more--q
/> setmac -m "safe configuration" -n 1 -o 0x3f0004
Set eth0 to MAC address 00:07:ed:0a:03:29
/>
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/nios2/rc (which will become /etc/rc ) in uClinux-dist dir, follow the setup for "lo" . So that the ethernet will be configed by init.
To set name server (DNS) , create the file vendors/Altera/nios2/resolv.conf , with a line of your name server, egnameserver 192.168.1.254
Then add a line to romfs: target in file vendors/Altera/nios2/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/nios2/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/arch/nios2/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/arch/nios2/kernel/setup.c , using platform_device data structure.