marvell pxa2128 uboot/linux kernel fast ethernet development

1. uboot hang

Open debug information as follows:

U-Boot code: 00F00000 -> 00F3AA68 BSS: -> 00F80088SoC: ARMADA620 88AP2128-B1Boot Core: MP1Available Cores: MP1 MP2DRAM interleave size: 0x00040000I2C: readymonitor len: 00080088ramsize: 18000000TLB table at: 17ff0000Top of RAM usable for U-Boot at: 17ff0000Reserving 512k for U-Boot at: 17f6f000Reserving 1152k for malloc() at: 17e4f000Reserving 80 Bytes for Board Info at: 17e4efb0Reserving 120 Bytes for Global Data at: 17e4ef38New Stack Pointer is: 17e4ef28DRAM_BANKS[0]: 0x00000000, 0x40000000RAM Configuration:Bank #0: 00000000 1 GiBBank #1: 00000000 0 BytesBank #2: 00000000 0 BytesBank #3: 00000000 0 BytesBank #4: 00000000 0 BytesBank #5: 00000000 0 BytesBank #6: 00000000 0 BytesBank #7: 00000000 0 Bytesrelocation Offset is: 1706f000

Hang here. Seems that the text segment exceeds theboundary.

The related code is in the "board.c" file. The issue is caused by ntim not updated, and it can be solved by using the

marvell burning tool to generate ntim***.bin which would be burned to emmc.

There are two following things needed to remember:

1). make ****_config: where are these configuration files and soc informations?

$ ls uboot/arch/arm/include/asm/arch-armada620/armada620.h config.h cpu.h gpio.h mfp.h usb.h

After completing compilation, the above files would copy into the"include"directory in uboot’s root dir.

$ ll uboot/include/asm/total 1456lrwxrwxrwx 1 yanghaibing yanghaibing 14 12月 20 09:31 arch -> arch-armada620/

$ ls include/asm/arch-armada620/armada620.h config.h cpu.h gpio.h mfp.h usb.h

$ ls uboot/arch/arm/cpu/armv7/armada620/asm-offsets.s cpu.c dram.c Makefile smp_init.S timer.c

$ ls uboot/arch/arm/cpu/armv7

start.S u-boot.lds cache_v7.c …

2). where is board related configuration and soc informations?

$ ls uboot/include/configs/qseven.h

$ ls uboot/board/Marvell/qseven/

libqseven.o Makefile qseven.c qseven.o

2. using container_of macro needs to pay attention to some pointers which is in the structure or not, for example:

priv->dev = malloc(sizeof(struct eth_device));if (!priv->dev)goto error7;PRINT(ETH_INIT_LOG, "Allocate memory successfully.");priv->mac_base = base_addr[0];priv->pmu_base = base_addr[1];priv->regs = &fe_mac_regs;dev = priv->dev;

compare:

dev = malloc(sizeof(struct eth_device)); // "dev" is a local variable, "priv->dev" is a member variable in pxa2128_eth_priv.if (!dev)goto error7;PRINT(ETH_INIT_LOG, "Allocate memory successfully.");priv->mac_base = base_addr[0];priv->pmu_base = base_addr[1];priv->regs = &fe_mac_regs;priv->dev = dev;  // &dev is a local address, but &priv->dev is an address of the structure pxa2128_eth_priv.

Actually, there are no difference. Tommorrow the issue would be continued.

container_ofopen up

({ \    // if the member variable is a pointer, the first argument musts take its address with "&"!!const typeof( ((struct pxa2128_eth_priv *)0)->dev ) *__mptr = (&ndev);\   (struct pxa2128_eth_priv *)( (char *)__mptr - ((size_t) &((struct pxa2128_eth_priv *)0)->dev) );})

Replace the container_of macro to the following function:

static inline void *netdev_priv(const struct eth_device *ndev){return ndev->priv;}

If the member is a pointer, container_of macro can’t find the header. Because according to the symbol "&" to get the pointer address which is at other place, it can’t get actual address in pxa2128_eth_priv structure.3. MAC controller needs to know phy device address, and this thing can be set by setting the MAC register 0x0. Then typically, the SMI unit continuously queries the PHY device for link status without the need for CPUintervention and the register Port Status(PSR)(offset 0x418) would display link status.

Table 1033:PHY Address (PAR) Offset: 0x000Bits Field Type / Description HW Rst31:15 Reserved RSVD Reserved14:10 Phy_AD2 0x06 PHY Device Address for Port 29:5 Phy_AD1 0x05 PHY Device Address for Port 14:0 Phy_AD0 0x04 PHY Device Address for Port 0

static void pxa2128_set_phyaddr(struct pxa2128_eth_priv *priv, int phy_addr){u32 reg_data;int addr_shift = 5 * priv->port_num;struct pxa2128_regs *reg = priv->regs;reg_data = rdl(priv, reg->PAR.addr);reg_data &= ~(0x1f << addr_shift);reg_data |= (phy_addr & 0x1f) << addr_shift;wrl(priv, reg->PAR.addr, reg_data); // MAC Register 0x0 and set bits 0-4}

4. FE dump mac and phy registers

pxa2128-eth: Dumping Ethernet MAC registers …offset 0x400: pxa2128-eth: 0x00001080 0x00000000 0x10204838 0x00000000offset 0x410: pxa2128-eth: 0x00000000 0x00000000 0x0000000b 0x00000000offset 0x420: pxa2128-eth: 0x00218823 0x00000000 0x17e4fad0 0x00000000offset 0x430: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000offset 0x440: pxa2128-eth: 0x000032fc 0x00000000 0x00800080 0x00000000offset 0x450: pxa2128-eth: 0x00000044 0x00000000 0x10002dcd 0x00000000offset 0x460: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000offset 0x470: pxa2128-eth: 0x0000f0cc 0x00000000 0x00000000 0x00000000offset 0x480: pxa2128-eth: 0x17e53b00 0x00000000 0x00000000 0x00000000offset 0x490: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000offset 0x4a0: pxa2128-eth: 0x17e53b00 0x00000000 0x00000000 0x00000000offset 0x4b0: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000offset 0x4c0: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000offset 0x4d0: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000offset 0x4e0: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000offset 0x500: pxa2128-eth: 0x000002c4 0x000000c0 0x00000005 0x00000003offset 0x510: pxa2128-eth: 0x000002c4 0x00000005 0x00000000 0x00000003offset 0x520: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000offset 0x530: pxa2128-eth: 0x00000000 0x00000000 0x00000005 0x00000000offset 0x540: pxa2128-eth: 0x00000003 0x00000000 0x00000000 0x00000000offset 0x550: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000002offset 0x560: pxa2128-eth: 0x00000000 0x00000000 0x00000000 0x00000000pxa2128-eth: Dumping Ethernet PHY registers …pxa2128-eth: offset 0xd4282a10 : 0x1b, 0x40000, 0x82foffset 0x 0: pxa2128-eth: 0x1100 0x78ed 0x0141 0x0e60 0x05e1offset 0x 5: pxa2128-eth: 0xc1e1 0x000f 0x2801 0x0000 0x0000offset 0x a: pxa2128-eth: 0x0000 0x0000 0x0000 0x0007 0x0000offset 0x f: pxa2128-eth: 0x0000 0x0138 0x7c00 0x0000 0x1c40offset 0x14: pxa2128-eth: 0x0000 0x0000 0x4458 0x4000 0x4245offset 0x19: pxa2128-eth: 0x0000 0x0000 0x0000 0x0c03 0x0009

5. TFTP download uImage

Marvell>>dhcp 0x1100000 10.20.112.32:uImagepxa2128-eth: link up, 100 Mb/s, full duplexBOOTP broadcast 1DHCP client bound to address 10.20.112.11Using pxa2128-eth deviceTFTP from server 10.20.112.32; our IP address is 10.20.112.11Filename ‘uImage’.Load address: 0x1100000Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ######doneBytes transferred = 3358164 (333dd4 hex)Marvel>>

6. Get mac address from eeprom

static int get_mac_from_eeprom(struct pxa2128_eth_priv *priv){#define EEPROM_ADDR 0x50#define EEPROM_MAC_OFFSET 0x64        int err;        char mac_addr[ETH_ALEN * 4] = {0};        char *mac_env = "ethaddr";        err = i2c_read(EEPROM_ADDR, EEPROM_MAC_OFFSET, 1, mac_addr, ETH_ALEN);        if (err < 0)                goto ERROR;        err = str_reverse(mac_addr, ETH_ALEN);        if (err < 0)                goto ERROR;        mac_addr[0] &= 0xfe; /* clear multicast bit */        mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */        memcpy(priv->oldmac, mac_addr, ETH_ALEN);    sprintf(&mac_addr[ETH_ALEN], "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0],                mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);        setenv(mac_env, &mac_addr[ETH_ALEN]);        return 0;ERROR:        PRINT(ETH_ERR, "Fail to get mac address from eeprom");        return -1;}

Write mac address to hash table

static int pxa2128_wirte_hwaddr(struct eth_device *dev){        struct pxa2128_eth_priv *priv = netdev_priv(dev);        if (!memcmp(priv->oldmac, dev->enetaddr, ETH_ALEN))                return 0;        if (!is_valid_ether_addr(dev->enetaddr))                return -EINVAL;        memcpy(priv->oldmac, dev->enetaddr, ETH_ALEN);        update_hash_table_mac_address(priv, priv->oldmac, dev->enetaddr);        return 0;}

7. Changing MAC leads that fe can’t work

Because changing MAC address leads ubuntu modifies eth*. In my environment, the eth0 port number is changed to eth3.

If we need the port number revert to eth0, we could do the following changes:

CHANGE NETWORK DEVICE NAME FROM ETH3 BACK TO ETH0.

The file is the udev rule for network devices which is located here:

/etc/udev/rules.d/70-persistent-net.rules

Copy the new mac address to the line of your eth0 rule and delete eth3.

# net device ()SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:43:01:11:df", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0" // previous name is "eth3"

To be sure everything works fine reboot your machine.

then we can see:

Come into /proc/net

root@localhost:/proc/net# cat dev

Inter-| Receive | Transmitface |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 eth0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0tunl0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0mlan0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 uap0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 wfd0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Come into /sys/devices/platform/pxa168-eth/net

We can see that the directory named eth3 is changed to be eth0

Come into the directory:eth0

root@localhost:/sys/devices/platform/pxa168-eth/net# lseth0

root@localhost:/sys/devices/platform/pxa168-eth/net/eth0# lsaddr_assign_type dev_id flags mtu speed ueventaddr_len device ifalias netdev_group statisticsaddress dormant ifindex operstate subsystembroadcast duplex iflink power tx_queue_lencarrier features link_mode queues type

The card information can be seen. For example: get mac address

root@localhost:/sys/devices/platform/pxa168-eth/net/eth0# cat address00:50:43:01:11:df

8. TFTP Server Setting (ubuntu)—Step 1: Install software of tftp— (My ubuntu’s version is 12.04)Boot up Ubuntu, open the terminal and issue the command:# sudo apt-get install tftpd# sudo apt-get install netkit-inetdIf the second above command’s result is as follow:Reading package lists… DoneBuilding dependency tree Reading state information… DonePackage netkit-inetd is a virtual package provided by: inetutils-inetd 2:1.8-3 openbsd-inetd 0.20080125-6Ubuntu1You should explicitly select one to install.E: Package ‘netkit-inetd’ has no installation candidateIf so, issue the following command# sudo apt-get install openbsd-inetd—Step 2: Config tftp setting—Modify the file of "/etc/inetd.conf" and add the following contents:tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp"/srv/tftp" should be replaced to your own tftp home directory.—Step 3: Restart tftp service—Issue the following command# sudo /etc/init.d/openbsd-inetd restartThe output should be as follow:* Restarting internet superserver inetd [ OK ]The tftp configuration is done.9. Ethernet Port Number is not "eth0" in user space (refer to No.7)

All three numbering systems use the same format and differ only in the length of the identifier. Addresses can either be universally administered addresses or locally administered addresses. A universally administered address is uniquely assigned to a device by its manufacturer. The first three octets (in transmission order) identify the organization that issued the identifier and are known as the Organizationally Unique Identifier (OUI). The following three (MAC-48 and EUI-48) or five (EUI-64) octets are assigned by that organization in nearly any manner they please, subject to the constraint of uniqueness. The IEEE expects the MAC-48 space to be exhausted no sooner than the year 2100; EUI-64s are not expected to run out in the foreseeable future. A locally administered address is assigned to a device by a network administrator, overriding the burned-in address. Locally administered addresses do not contain OUIs. Universally administered and locally administered addresses are distinguished by setting the second-least-significant bit of the most significant byte of the address. This bit is also referred to as the U/L bit, short for Universal/Local, which identifies how the address is administered. If the bit is 0, the address is universally administered. If it is 1, the address is locally administered. In the example address 06-00-00-00-00-00 the most significant byte is 06 (hex), the binary form of which is 00000110, where the second-least-significant bit is 1. Therefore, it is a locally administered address. Consequently, this bit is 0 in all OUIs.

The interface name of a network device increases if the mac address of the physical or virtual network card changes. A common case is if you made a clone of a virtual machine for example via VMware or KVM or replaced a physical network card in a non virtualized server.

Remember if the mac address is set to a locally administered one, the interface name of the network device would not increase!

We have found a workaround that maps the network card to eth0 but first, a little background about how the adaptors are dynamically assigned.

Device mapping on some of our Linux machines are controlled by the file/etc/iftab.

On our Ubuntu test machine this file,/etc/iftab, is not present and the network devices assignment is controlled by files located in the /etc/udev/rules.d directory.

What’s in Rules.d

This directory will contain two files with names the same as (or similar to) the following:

75-persistent-net-generator.rules70-persistent-net.rules

The file,75-persistent-net-generator.rules, contains rules for a script/lib/udev/write_net_rulesthat runs each time the machine boots up.

The second file,70-persistent-net.rules, contains the names of the device files:

## You can modify it, as long as you keep each rule on a single# line, and change only the value of the NAME= key.# USB device 0x0846:0x1040 (usb)SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0f:b5:fb:fc:e0", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"# USB device 0x0b95:0x1780 (usb)SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:b6:4d:c5:a9", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"# USB device 0x0b95:0x1780 (usb)SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:b6:4d:c6:86", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"# net device ()SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:43:01:11:df", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"# net device ()SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="04:50:43:01:11:df", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth4"

It appears to us that each time the networking is reconfigured (for example, if one switches from a wireless adaptor to a wired adaptor) and then rebooted, this rule file gets updated and new network device names are assigned. On this particular machine, the most recent ethernet assignments had incremented to eth4.

root@localhost:/etc/udev/rules.d# ls /lib/udev/rules.d/40-gnupg.rules 70-udev-acl.rules40-ia64.rules 75-cd-aliases-generator.rules40-ppc.rules 75-net-description.rules42-qemu-usb.rules 75-persistent-net-generator.rules50-firmware.rules 75-probe_mtd.rules50-udev-default.rules 75-tty-description.rules60-cdrom_id.rules 78-graphics-card.rules60-persistent-alsa.rules 78-sound-card.rules60-persistent-input.rules 80-drivers.rules60-persistent-serial.rules 85-keyboard-configuration.rules60-persistent-storage-tape.rules 90-alsa-restore.rules60-persistent-storage.rules 90-alsa-ucm.rules60-persistent-v4l.rules 95-keyboard-force-release.rules61-accelerometer.rules 95-keymap.rules64-xorg-xkb.rules 95-udev-late.rules66-xorg-synaptics-quirks.rules 97-bluetooth-hid2hci.rules69-xserver-xorg-input-wacom.rules README























接受我们不能改变的一切,改变我们能改变的一切。

marvell pxa2128 uboot/linux kernel fast ethernet development

相关文章:

你感兴趣的文章:

标签云: