EtherNet

cancel
Showing results for 
Search instead for 
Did you mean: 

EtherNet

EtherNet

 

 

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 <a href="http://www.niosforum.com/pages/project_details.php?p_id=115&t_id=18" >Avalon OpenCores 10/100 Ethernet MAC (you have to register nios forum to download this core) . You can find example ocm design for NEEK from <a href="/OperatingSystems/UClinux/MmcSd">MmcSd .

 

[*] Opencores (Igor) Emac support

exOr,

 

 

The new Kernel mainline driver could be used for OpenCores MAC (nios2-test or unstable-nios2mmu branch)

[*] OpenCores 10/100 Mbps Ethernet MAC support

 

 

Select this only if you are using morethanip 1000/100/10 ethernet mac,

[*] MoreThanIP 10_100_1000 Emac support

 

 

Select this only if you are using Altera 1000/100/10 triple speed ethernet TSE mac, like the one in NEEK.

 

[*] Altera Tripple Speed Ethernet support (EXPERIMENTAL)

exOr,

[*]Altera Triple Speed Ethernet MAC support(SLS)

[*]Drivers for Marvell PHYs

 

 

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.

 

MII-Tool

This utility checks or sets the status of a network interface's Media Independent Interface (MII) unit. Most fast ethernet adapters use an MII to autonegotiate link speed and duplex setting.

1) First you need to enable the MII device support for your used PHY in uClinux-dist kernel config

Device Drivers -->Network device support ─>

 

[*] Network device support

[*] PHY Device support and infrastructure --->

Enable for example for NEEK:

[*] Drivers for National Semiconductor PHYs

2) Now you have to enable mii-tool in "Application/Library Settings" in following section:

Network Applications --->

 

[*] mii-tool (in --- Net-tools section)

After successful compilation you could get following output for example:

/> mii-tool

 

eth0: negotiated 100baseT-FD, link ok

Ethernet hw address

Every ethernet 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 <<a rel="freelink" href="mailto:nico@cam.org" >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

/>

 

Startup and internet servers

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 -d & # 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, eg

nameserver 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 <a href="/OperatingSystems/UClinux/NFSFileSytem">NFSFileSytem wiki page for a sample dhcpd.conf.

You may use "ntpdate" to get date & time from internet. Set <a href="http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap08.html" >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

 

Monitor and debug Ethernet with Wireshark (ethereal)

You can capture and analyze ethernet frame running to and from your ethernet controller, using a great program called "wireshark". It is also a great tool to learn tcp/ip.

On Fedora/RHEL/Centos, via root or sudo yum install wireshark-gnome

Reading about performance issues,

 

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 <a href="/@api/deki/files/109/=DM9000A_CTRL.v">DM9000A_CTRL.v. Click next until the "interface" tab, then make the following changes :

  • Slave Adressing : Registers
  • Units : ns
  • Setup : 0
  • Read Wait : 40
  • Write Wait : 40
  • Hold : 0

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

 

DM9000A Avalon tristate slave, and debug guide

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 [[media:dm9000a_hw.tcl|dm9000a_hw.tcl] in your project directory. Open SOPC Builder, and you can find a new "dm9000a" component.

[[media:dm91.png|dm91.png]

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.

[[media:dm9000.png|dm9000.png]

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 Debug Kernel. 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.

Otherwise, you can debug using printk(). Add printk() before the id check of dm9000_probe() in dm9000.c, to show db->io_addr and db->io_data. And loop forever in the id check.

You can use git to help you restore the source after you made debug changes. In linux-2.6 dir, git checkout drivers/net/dm9000.c

++++++++++++++++++++++ component timing +++++++++++++++++++++++++++++++++++++++

This component is created using Component Editor. Then add a line,

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.

 

Optimized DM9000A SOOPC component with variable wait-state:

Here is an optimized DM9000A component for Quartus/SOPC Builder 7.2. If timing margins have been reached for the DM9000A chip, I believe it operates a read in one wait state, and a write in zero wait-states. If not, it stalls the avalon transaction until it is safely able to perform a read/write.

It only takes 14 logic elements, and is actually very simple. A lot of trial and error went into achieving the lowest delay and logic utilization. I believe the performance can be improved slightly at the expense of more complicated logic by checking which register was read last, or by a slight change to the dm9ks.c file (only one place uses the read instruction from the register that causes the most delay on the next read/write) but I do not consider the minimal benefit worth pursuing any further.

It has been tested with a DE2-70 board, only as far as pinging for both the dm9000 and dm9ks drivers.

Put DM9000A_IF.v and DM9000A_hw.tcl in a subfolder under your quartus project directory. In SOPC Builderr, add the path to your new IP in the menu Tools->Options->IP Search Path. You may have to refresh the component list in the File->Refresh Component List... It gets put into "USER_IP" section.

Add the new component to your SOPC Builder project, name is DM9000A or dm9000, set an interrupt other than 0, and have its clock reference your CPU clock in SOPC Builder (up to 100 Mhz). Beyond 100 Mhz will violate DM9000A timing.

Add to your top level file, the new information like:

// the_DM9000A

.ENET_CLK_from_the_DM9000A(oENET_CLK),

.ENET_CMD_from_the_DM9000A(oENET_CMD),

.ENET_CS_N_from_the_DM9000A(oENET_CS_N),

.ENET_DATA_to_and_from_the_DM9000A(ENET_D),

.ENET_INT_to_the_DM9000A(iENET_INT),

.ENET_RD_N_from_the_DM9000A(oENET_IOR_N),

.ENET_RST_N_from_the_DM9000A(oENET_RESET_N),

.ENET_WR_N_from_the_DM9000A(oENET_IOW_N),

.clk50_to_the_DM9000A(iCLK_50)

and change the name of the signals passed to the component if they are different.

Download

·      DM9000A_CTRL.v - See the Attachments section below

·      dm9000a-hw.tcl

·      dm9000a-hw2.tcl

·      DM9000A_IF.v - See the Attachments section below

·      FtpDropedLastByte.zip - See the Attachments section below

 

 

Attachments
Version history
Last update:
‎12-06-2022 02:35 PM
Updated by:
Contributors