13.1 Ethernet Driver Source Code
The driver of Ethernet is very matured. One thing to note: starting from 2.6.25, the DM9000 driver in “drivers/net/dm9000.c” (version 1.3) is not suitable for chip DM9000E.
But on TQ2440, we use DM9000E. So we need to replace “dm9000.c”. We found that V1.2 works for chip DM9000E.
What we can do is to download linux-2.6.24.tar.bz2 source code and unzip, extract “drivers/net/dm9000.c”, and you can find that this file is of version 1.2. We can use it to replace the driver file in 6.25.8 and begin porting.
Note: The above description is for 2.6.25.8. In .6.30.4, the driver of dm9000 can be used directly.
13.2 Modify the driver source code
We only need to simple changes to be able to drive DM9000 on TQ2440.
Modify Linux-2.6.25.8 source file “arch/arm/plat-s3c24xx/common-smdk.c”:
In line 46, we insert the following content (highlighted as red):
#include
#include
#include
#include
/* LED devices */
static struct s3c24xx_led_platdata smdk_pdata_led4 = {
Then we insert the following content around line 151 (highlighted as red):
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 10,
.twrph0 = 25,
.twrph1 = 10,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
/* DM9000 */
static struct resource s3c_dm9k_resource[] = {
[0] = {
.start = S3C2410_CS4, /* ADDR2=0£¬use this address when send address*/
.end = S3C2410_CS4 + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S3C2410_CS4 + 4, /* ADDR2=1£¬use this address when transfer data*/
.end = S3C2410_CS4 + 4 + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT7, /* IRQ number*/
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ,
}
};
/* for the moment we limit ourselves to 16bit IO until some
* better IO routines can be written and tested
*/
static struct dm9000_plat_data s3c_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
static struct platform_device s3c_device_dm9k = {
.name = “dm9000”,
.id = 0,
.num_resources = ARRAY_SIZE(s3c_dm9k_resource),
.resource = s3c_dm9k_resource,
.dev = {
.platform_data = &s3c_dm9k_platdata,
}
};
/* devices we initialise */
static struct platform_device __initdata *smdk_devs[] = {
Next insert the following content around line 199:
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
&s3c_device_dm9k,
};
Modify Linux-2.6.25.8 kernel source file “drivers/net/dm9000.c”:
Insert the following information in line 73:
#include
#include
#include
#if defined(CONFIG_ARCH_S3C2410)
#include
#endif
#include “dm9000.h”
Change the content starting from line 118:
#ifdef CONFIG_BLACKFIN
#define readsb insb
#define readsw insw
#define readsl insl
#define writesb outsb
#define writesw outsw
#define writesloutsl
#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH)
#elif defined(CONFIG_ARCH_S3C2410)
#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_RISING)
#else
DM9000_IRQ_FLAGS IRQF_SHARED
#endif
In line 414 add the following content:
static int
dm9000_probe(struct platform_device *pdev)
{
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
unsigned long base;
int ret = 0;
int iosize;
int i;
u32 id_val;
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon;
unsigned int oldval_bankcon4;
#endif
/* Init network device */
In line 428, add the following content:
/* Init network device */
ndev = alloc_etherdev(sizeof (struct board_info));
if (!ndev) {
printk(“%s: could not allocate device.n”, CARDNAME);
return -ENOMEM;
}
SET_NETDEV_DEV(ndev, &pdev->dev);
#if defined(CONFIG_ARCH_S3C2410)
oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16))
| S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4);
*((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
#endif
PRINTK2(“dm9000_probe()”);
Starting from line 614, add the following content: (red is the modified content, and it’s used to add mac)
#if defined(CONFIG_ARCH_S3C2410)
printk(“Now use the default MAC address: 10:23:45:67:89:abn”);
mac_src=”EmbedSky” mce_src=”EmbedSky”;
ndev->dev_addr[0] = 0x10;
ndev->dev_addr[1] = 0x23;
ndev->dev_addr[2] = 0x45;
ndev->dev_addr[3] = 0x67;
ndev->dev_addr[4] = 0x89;
ndev->dev_addr[5] = 0xab;
#endif
In line 636 add the following information:
out:
printk(“%s: not found (%d).n”, CARDNAME, ret);
#if defined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
*((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4;
#endif
dm9000_release_board(pdev, db);
free_netdev(ndev);
return ret;
}
Modify Linux-2.6.30.4 source file “arch/arm/mach-s3c2440/mach-smdk2440.c”:
In line 50, add the following information:
#include
In line 154 add the following information:
static struct s3c2410fb_mach_info tq2440_fb_info __initdata = {
.displays = &tq2440_lcd_cfg,
.num_displays = 1,
.default_display = 0,
#if 0
/* currently setup by downloader */
.gpccon = 0xaa940659,
.gpccon_mask = 0xffffffff,
.gpcup = 0x0000ffff,
.gpcup_mask = 0xffffffff,
.gpdcon = 0xaa84aaa0,
.gpdcon_mask = 0xffffffff,
.gpdup = 0x0000faff,
.gpdup_mask = 0xffffffff,
#endif
// .lpcsel = ((0xCE6) & ~7) | 1<<4,
};
/* DM9000 */
static struct resource s3c_dm9k_resource[] = {
[0] = {
.start= S3C2410_CS4,
.end = S3C2410_CS4 + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start= S3C2410_CS4 + 4,
.end = S3C2410_CS4 + 4 + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start= IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
}
};
static struct dm9000_plat_data s3c_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
struct platform_device s3c_device_dm9000 = {
.name = “dm9000”,
.id = 0,
.num_resources = ARRAY_SIZE(s3c_dm9k_resource),
.resource = s3c_dm9k_resource,
.dev = {
.platform_data = &s3c_dm9k_platdata,
}
};
In line 194, add the following content:
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_dm9000,
};
In Linux-2.6.30.4 file “drivers/net/dm9000.c”:
Line 41 add :
#if defined(CONFIG_ARCH_S3C2410)
#include
#endif
Line 1194 add:
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
unsigned int oldval_bankcon4 = *(volatile unsigned int *)S3C2410_BANKCON4;
#endif
Line 1209 add:
#if defined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16)) |
S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
*((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
#endif
Line 1278 add the following content (mainly to add mac):
#if defined(CONFIG_ARCH_S3C2410)
printk(“Now use the default MAC address: 10:23:45:67:89:abn”);
mac_src = “EmbedSky”;
ndev->dev_addr[0] = 0x10;
ndev->dev_addr[1] = 0x23;
ndev->dev_addr[2] = 0x45;
ndev->dev_addr[3] = 0x67;
ndev->dev_addr[4] = 0x89;
ndev->dev_addr[5] = 0xab;
#else
mac_src = “eeprom”;
/* try reading the node address from the attached EEPROM */
for (i = 0; i < 6; i += 2)
dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
mac_src = “platform data”;
memcpy(ndev->dev_addr, pdata->dev_addr, 6);
}
if (!is_valid_ether_addr(ndev->dev_addr)) {
/* try reading from mac */
mac_src = “chip”;
for (i = 0; i < 6; i++)
ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
}
if (!is_valid_ether_addr(ndev->dev_addr))
dev_warn(db->dev, “%s: Invalid ethernet MAC address. Please ”
“set using ifconfign”, ndev->name);
#endif
In line 1423 add:
#if defined(CONFIG_ARCH_S3C2410)
*(volatile unsigned int *)S3C2410_BWSCON = oldval_bwscon;
*(volatile unsigned int *)S3C2410_BANKCON4 = oldval_bankcon4;
#endif
13.3 Config and compile the kernel
After making the above change, type#make menuconfig to enter into config menu, and add the config for DM9000:
[*] Networking support —>
— Networking support
Networking options —>
< > Packet socket
<*> Unix domain sockets
< > PF_KEY sockets
[*] TCP/IP networking
[ ] IP: multicasting
[ ] IP: advanced router
[*] IP: kernel level autoconfiguration
[*] IP: DHCP support
[ ] IP: BOOTP support
[ ] IP: RARP support
Device Drivers —>
[*] Network device support —>
[*] Ethernet (10 or 100Mbit) —>
-*- Generic Media Independent Interface device support
<*> DM9000 support
(4) DM9000 maximum debug level
After the configuration, save the configuration, and build the image and burn into the development board.
13.4 DM9000 configuration
Next step is to edit “/etc/init.d/rcS” of the file system, in the following, we list the changed content:
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mkdir -p /var/lock
ifconfig lo 127.0.0.1 #(set local loop IP address)
net_set & #(call network config file)
/bin/hostname -F /etc/sysconfig/HOSTNAME
Under “/sbin/” directory, we create an executable file “net_set”, the content is as follows:
#!/bin/sh
echo Try to bring eth0 interface up …>/dev/tq2440_serial0
if [ -f /etc/net.conf ] ; then
source /etc/net.conf
ifconfig eth0 down
ifconfig eth0 hw ether $MAC
echo ifconfig eth0 hw ether $MAC >/dev/tq2440_serial0
ifconfig eth0 $IPADDR netmask $NETMASK up
echo ifconfig eth0 $IPADDR netmask $NETMASK up >/dev/tq2440_serial0
route add default gw $GATEWAY
echo add default gw $GATEWAY >/dev/tq2440_serial0
else
ifconfig eth0 hw ether 10:23:45:67:89:ab
ifconfig eth0 192.168.1.6 netmask 255.255.255.0 up
route add default gw 192.168.1.2
echo ifconfig eth0 hw ether 10:23:45:67:89:ab >/dev/tq2440_serial0
echo ifconfig eth0 192.168.1.6 netmask 255.255.255.0 up >/dev/tq2440_serial0
echo route add default gw 192.168.1.2 >/dev/tq2440_serial0
fi
echo Done > /dev/tq2440_serial0
In “net.conf” under “/etc/”, it is saved the network configuration information as:
IPADDR=192.168.1.6
NETMASK=255.255.255.0
GATEWAY=192.168.1.2
MAC=10:23:45:67:89:ab
After changing the file system, we need to rebuild the ysffs iamge and burn into the development board. The IP etc information will be set automatically during reboot.
If you need to change IP, etc, you only need to run “net_set” after editing “/etc/net.conf”.
Next, we will add web server to the file system. In the previous tutorials, we also include web server related files into the file system.
Here we onlyu need to load web server during system reboot. Modify “/etc/init.d/rcS” to add loading web server:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
#
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mkdir -p /var/lock
ifconfig lo 127.0.0.1
net_set &
/etc/rc.d/init.d/httpd start #start web server
/bin/hostname -F /etc/sysconfig/HOSTNAME
After it’s done, rebuild and burn the image into the development board, type $ifconfig:
Leave a Reply
You must be logged in to post a comment.