Xilinx zynq zynqmp Macb Gem千兆网使用

参考

zynqMP GEM 如何配置GT lane
Zynq MPsoc的GEM Ethernet DTS问题
2017.1-2018.3 Zynq UltraScale+ MPSoC: Linux MACB MDIO support for single MAC managing multiple PHYs
PetaLinux - Zynq MPSoC PS-GTR SGMII - fixed link support patch
UBOOT下SGMII网络不通问题
【分享】 MPSoC的GEM通过SGMII直接和其它CPU、switch芯片连接
Zynq UltraScale+ MPSoC - SGMII using PS-GTR
Zynq UltraScale+ MPSoC ZCU102 Evaluation Kit - PING test fails if using non-English OS
AR# 66670 Zynq-7000 SoC - Linux - Macb performance is not equal/comparable in both directions when using “iperf -d”
iperf详细使用方法
GMII,RGMII,SGMII,TBI,RTBI接口信号及时序介绍
PHY88E1111配置Verilog程序
TCI6487采用SGMII口与Marvel 88e1111相连,SGMII回环成功,但是就是发不出数据
6678 88E1111 sgmii link不上
uboot网口调试Marvell phy 88E1111
Marvell 88E1145PHY芯片的初始化配置
Marvell交换芯片88E6321/88E6320驱动总结-硬件篇
Zynq 7000 双网卡配置-内核DTS该如何配置
Cadence Macb Linux Driver for Zynq and Zynq Ultrascale+ MPSoC
Xilinx GMII2RGMII convertor
ZYNQ7035 使用petalinux 2018.02 配置Gmii to Rgmii构成双网卡
AR# 67923 2016.2 PetaLinux Zynq UltraScale+ MPSoC GMII2RGMII on MACB driver
phytool
i.MX6D: AR8033 Ethernet PHY register setting

u-boot新驱动

采用设备树net\eth-uclass.c,调用函数uclass_first_device

int eth_initialize(void)
{
	int num_devices = 0;
	struct udevice *dev;

	eth_common_init();

	/*
	 * Devices need to write the hwaddr even if not started so that Linux
	 * will have access to the hwaddr that u-boot stored for the device.
	 * This is accomplished by attempting to probe each device and calling
	 * their write_hwaddr() operation.
	 */
	uclass_first_device(UCLASS_ETH, &dev);
	if (!dev) {
		printf("No ethernet found.\n");
		bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
	} else {
		char *ethprime = env_get("ethprime");
		struct udevice *prime_dev = NULL;

		if (ethprime)
			prime_dev = eth_get_dev_by_name(ethprime);
		if (prime_dev) {
			eth_set_dev(prime_dev);
			eth_current_changed();
		} else {
			eth_set_dev(NULL);
		}

		bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
		do {
			if (num_devices)
				printf(", ");

			printf("eth%d: %s", dev->seq, dev->name);

			if (ethprime && dev == prime_dev)
				printf(" [PRIME]");

			eth_write_hwaddr(dev);

			uclass_next_device(&dev);
			num_devices++;
		} while (dev);

		putc('\n');
	}

	return num_devices;
}

性能

zynq,TCP发送,绑核105MB/s,不绑核只有80MB/s,加窗108MB/s且速度很稳定,TCP接收可稳定在77MB/s。

root@zynq:~# iperf3 -c 192.168.6.85
Connecting to host 192.168.6.85, port 5201
[  4] local 192.168.6.195 port 33536 connected to 192.168.6.85 port 5201
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.01   sec   109 MBytes   906 Mbits/sec    0    185 KBytes       
[  4]   1.01-2.01   sec   108 MBytes   905 Mbits/sec    0    191 KBytes       
[  4]   2.01-3.01   sec   108 MBytes   904 Mbits/sec    0    191 KBytes       
[  4]   3.01-4.01   sec   108 MBytes   903 Mbits/sec    0    191 KBytes       
[  4]   4.01-5.01   sec   108 MBytes   902 Mbits/sec    0    191 KBytes       
[  4]   5.01-6.01   sec   108 MBytes   903 Mbits/sec    0    192 KBytes       
[  4]   6.01-7.00   sec   108 MBytes   904 Mbits/sec    0    192 KBytes       
[  4]   7.00-8.00   sec   107 MBytes   903 Mbits/sec    0    235 KBytes       
[  4]   8.00-9.00   sec   108 MBytes   902 Mbits/sec    0    235 KBytes       
[  4]   9.00-10.00  sec   108 MBytes   902 Mbits/sec    0    235 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec  1.05 GBytes   903 Mbits/sec    0             sender
[  4]   0.00-10.00  sec  1.05 GBytes   903 Mbits/sec                  receiver

iperf Done.
root@zynq:~# iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 192.168.6.85, port 38296
[  5] local 192.168.6.195 port 5201 connected to 192.168.6.85 port 38298
[ ID] Interval           Transfer     Bandwidth
[  5]   0.00-1.00   sec  76.4 MBytes   641 Mbits/sec                  
[  5]   1.00-2.00   sec  77.6 MBytes   651 Mbits/sec                  
[  5]   2.00-3.00   sec  77.6 MBytes   651 Mbits/sec                  
[  5]   3.00-4.00   sec  77.7 MBytes   652 Mbits/sec                  
[  5]   4.00-5.00   sec  77.7 MBytes   652 Mbits/sec                  
[  5]   5.00-6.00   sec  77.7 MBytes   652 Mbits/sec                  
[  5]   6.00-7.00   sec  77.8 MBytes   653 Mbits/sec                  
[  5]   7.00-8.00   sec  77.6 MBytes   651 Mbits/sec                  
[  5]   8.00-9.00   sec  77.9 MBytes   653 Mbits/sec                  
[  5]   9.00-10.00  sec  77.8 MBytes   652 Mbits/sec                  
[  5]  10.00-10.02  sec  1.38 MBytes   646 Mbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  5]   0.00-10.02  sec  0.00 Bytes  0.00 bits/sec                  sender
[  5]   0.00-10.02  sec   777 MBytes   651 Mbits/sec                  receiver

zynqmp发送接收都可达108MB/s。

88e1518

米联开发板,百兆网pc直连无法ping通,接交换机就没问题,按道理应该支持网线直连检测啊。

GEM EMIO RGMII

GEM EMIO只能出GMII,这里用到一个Xilinx的IP,GMII-to-RGMII,在米联的开发板上,不连网线,会导致无法搜索到phy,这个应该是硬件问题。米联的硬件上MDIO总线划分有问题和PL的phy共用MDIO总线,导致不能同时使用。

GEM MIO RGMII 1.8v AR8033

PS_MIO_VREF设置RGMII工作电压,配置AR8033的寄存器工作与1.8v,正确配置RX上下拉电阻。

       /* Set RGMII IO voltage to 1.8V */
       phy_write(dev, 0x1d, 0x1f);
       phy_write(dev, 0x1e, 0x8);

macb.probe failed with -16

EMIO出的MDIO总线没有接到phy上,无法获得正确的phy id,导致执行of_mdiobus_register_device而不是of_mdiobus_register_phy,返回-16,

zynqmp GEM SGMII

首先要给88E1111复位信号信号,复位引脚电平 高电平->低电平->高电平保持,低电平要维持10ms以上,可以给15ms,88E1111通过125CLK设置输出检测到了125Mhz时钟,能确定其正常工作。zynqmp的PS自带GTR,可以配置GEM直接从PS-GTR出SGMII,采用88e1111把SGMII转RJ45,但硬件设计时没有把MDIO接到GEM,所以PHY需要配置寄存器,

reg  value
0x1b 0x8084
0x16 0x0
0x00 0x8000

问题解决,只需对芯片执行软复位,发起自协商即可,可以从vivado获取example,内有verilog的配置示例,硬件原理图和封装映射错误,导致1000M无法自协商成功,直接卡死,百兆网可以。

双网口zynq eth1初始化失败

2015.2.1手动生成设备树,默认设置has-mdio=1,所以双网卡共享mdio时,eth1需要覆盖数值为0。

双网口内核 kernel oops

petalinux 2015.2.1,使能了双网口,GEM1的设备树没有配置phy node导致,

macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe000b000 irq 145 (00:0a:02:f2:ab:aa)
macb e000b000.ethernet eth0: attached PHY driver [Atheros 8031 ethernet] (mii_bus:phy_addr=e000b000.etherne:01, irq=-1)
Unable to handle kernel NULL pointer dereference at virtual address 00000028
pgd = 40004000
[00000028] *pgd=00000000
Internal error: Oops - BUG: 17 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.19.0-xilinx #3
Hardware name: Xilinx Zynq Platform
task: 7d82c9c0 ti: 7d84e000 task.ti: 7d84e000
PC is at mutex_lock+0x10/0x4c
LR is at mdiobus_read+0x1c/0x44
pc : [<404893a4>]    lr : [<402d1944>]    psr: 600d0013
sp : 7d84fd80  ip : 7d84fdd0  fp : 7d9a0500
r10: 7d80d300  r9 : 00000000  r8 : 7d84fdac
r7 : 403a34a8  r6 : 00000002  r5 : 00000028  r4 : 00000028
r3 : 00000000  r2 : 00000002  r1 : 403a34a8  r0 : 00000028
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 18c5387d  Table: 3dbb004a  DAC: 00000015
Process swapper/0 (pid: 1, stack limit = 0x7d84e238)
Stack: (0x7d84fd80 to 0x7d850000)
fd80: 00000000 402d1944 00000000 7d9a0500 00000000 403a34a8 00000000 402d1688
fda0: 00000004 7d9a0000 7d8d2a10 00000000 00000000 00000000 00000000 00000000
fdc0: 00000000 00000000 00000000 00000000 7d9a0000 7d9a0500 00000000 7d9a0000
fde0: 7d80dc80 7d80dc80 00000000 7d80d300 7d9a0500 402d6ce4 7d8d2a00 7d80dc80
fe00: 7d80dc80 403a34a8 00000001 7d9a0000 7d8d2a10 7d8d2a00 7d80dc80 40671b88
fe20: 00000080 7d9a0000 7d9a0520 401060a0 00000000 00000001 00000008 7d9a0500
fe40: 7d8d0300 00000001 00000000 7d9a0520 406cd400 ffffffed 7d8d2a10 406bac38
fe60: 406bac38 00000000 406cd400 40683e94 00000000 40274e10 7d8d2a10 406f4ddc
fe80: 406bac38 402739c8 7d8d2a10 7d8d2a44 406bac38 406abb98 406996e0 40273bb4
fea0: 00000000 406bac38 40273b4c 402722ec 7d80fb5c 7d8b4334 406bac38 00000000
fec0: 7d9d6f00 4027328c 405d13e8 405d13e9 00000000 406bac38 4067150c 00000000
fee0: 406996e0 402740b8 00000000 406bac24 4067150c 40274e88 7db92880 4067150c
ff00: 00000000 400088e0 7d875180 40490c58 406d3f38 40683e70 00000000 400fe5e4
ff20: 405a9292 7d875400 4069d2b8 60000013 000000b4 7ffffe16 00000000 40035990
ff40: 000000b5 00000006 00000006 000000b4 4069d2a0 00000006 000000b5 00000006
ff60: 000000b5 4068ac8c 40683e8c 406cd400 406cd400 40657d3c 00000006 00000006
ff80: 406574fc 7d84e000 00000000 40483968 00000000 00000000 00000000 00000000
ffa0: 00000000 40483970 00000000 4000dd40 00000000 00000000 00000000 00000000
ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff
[<404893a4>] (mutex_lock) from [<402d1944>] (mdiobus_read+0x1c/0x44)
[<402d1944>] (mdiobus_read) from [<402d1688>] (get_phy_device+0x130/0x198)
[<402d1688>] (get_phy_device) from [<402d6ce4>] (macb_mii_init+0x1c8/0x308)
[<402d6ce4>] (macb_mii_init) from [<40671b88>] (macb_probe+0x664/0x7d0)
[<40671b88>] (macb_probe) from [<40274e10>] (platform_drv_probe+0x48/0x98)
[<40274e10>] (platform_drv_probe) from [<402739c8>] (driver_probe_device+0x8c/0x1cc)
[<402739c8>] (driver_probe_device) from [<40273bb4>] (__driver_attach+0x68/0x8c)
[<40273bb4>] (__driver_attach) from [<402722ec>] (bus_for_each_dev+0x6c/0x90)
[<402722ec>] (bus_for_each_dev) from [<4027328c>] (bus_add_driver+0xdc/0x1c4)
[<4027328c>] (bus_add_driver) from [<402740b8>] (driver_register+0x8c/0xd0)
[<402740b8>] (driver_register) from [<40274e88>] (__platform_driver_probe+0x20/0x94)
[<40274e88>] (__platform_driver_probe) from [<400088e0>] (do_one_initcall+0x100/0x180)
[<400088e0>] (do_one_initcall) from [<40657d3c>] (kernel_init_freeable+0x110/0x1d4)
[<40657d3c>] (kernel_init_freeable) from [<40483970>] (kernel_init+0x8/0xe4)
[<40483970>] (kernel_init) from [<4000dd40>] (ret_from_fork+0x14/0x34)
Code: e92d4010 e1a04000 f57ff05b f590f000 (e1903f9f) 
---[ end trace b13f75501ad3b839 ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

CPU0: stopping
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G      D        3.19.0-xilinx #3
Hardware name: Xilinx Zynq Platform
[<400147f0>] (unwind_backtrace) from [<40010d54>] (show_stack+0x10/0x14)
[<40010d54>] (show_stack) from [<40486d38>] (dump_stack+0x80/0xcc)
[<40486d38>] (dump_stack) from [<400131c8>] (ipi_cpu_stop+0x3c/0x6c)
[<400131c8>] (ipi_cpu_stop) from [<400137b0>] (handle_IPI+0x64/0x84)
[<400137b0>] (handle_IPI) from [<400085cc>] (gic_handle_irq+0x54/0x5c)
[<400085cc>] (gic_handle_irq) from [<40011700>] (__irq_svc+0x40/0x74)
Exception stack(0x4068ff60 to 0x4068ffa8)
ff60: ffffffed 00000000 00000000 4001c9c0 4068e000 00000000 00000000 4068ffb0
ff80: 4048def0 7ffffdc0 00000000 ffffffed 00000001 4068ffa8 4000e7d4 4000e7d8
ffa0: 600d0013 ffffffff
[<40011700>] (__irq_svc) from [<4000e7d8>] (arch_cpu_idle+0x2c/0x38)
[<4000e7d8>] (arch_cpu_idle) from [<40048c94>] (cpu_startup_entry+0xcc/0x1e8)
[<40048c94>] (cpu_startup_entry) from [<40657bcc>] (start_kernel+0x324/0x384)
[<40657bcc>] (start_kernel) from [<00008074>] (0x8074)
---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

link up但是ping不通

petalinux 2015.2.1,设备树配phy node配置compatible错误,

ethernet@e000b000 {
        compatible = "xlnx,ps7-ethernet-1.00.a";
        reg = <0xe000b000 0x1000>;
        status = "okay";
        interrupts = <0x0 0x16 0x4>;
        clocks = <0x1 0x1e 0x1 0x1e 0x1 0xd>;
        clock-names = "pclk", "hclk", "tx_clk";
        #address-cells = <0x1>;
        #size-cells = <0x0>;
        phy-mode = "rgmii-id";
        xlnx,ptp-enet-clock = <0x69f6bcb>;
        local-mac-address = [00 0a 35 00 1e 53];
        xlnx,has-mdio = <0x1>;
        phy-handle = <0x4>;

        mdio {
                #address-cells = <0x1>;
                #size-cells = <0x0>;

                phy@1 {
                        compatible = "atheros, at803x";
                        device_type = "ethernet-phy";
                        reg = <0x1>;
                        reset-gpio = <0x5 0x2f 0x0>;
                        linux,phandle = <0x4>;
                        phandle = <0x4>;
                };

                phy@3 {
                        compatible = "atheros, at803x";
                        device_type = "ethernet-phy";
                        reg = <0x3>;
                        linux,phandle = <0x6>;
                        phandle = <0x6>;
                };
        };
};

fixed phy

ti-linux-kernel的cpsw驱动不支持fixed-link
I.MX6 PHY fixup 调用流程 hacking

ping不通,内核打印,FPGA时钟设置不对,重新设置设备树的时钟源,为0,是因为fsbl设置的0

xemacps e000c000.ethernet: Set clk to 0 Hz
xemacps e000c000.ethernet: link up (1000/FULL)

设备树,

fixed-link {
	reg = <1>;
	full-duplex = <1>; /*0 1*/
	speed = <1000>; /*10 100 1000*/
	pause = <0>; /*0 1*/
	asym-pause = <0>; /*0 1*/
	autoneg = <0>; /*0 1*/
	duplex = <1>; /*0 1*/
}

zynq uboot下超时

在百兆网时经常出现这个问题,

zynq-uboot> run update_boot
Gem.e000b000 Waiting for PHY auto negotiation to complete......... TIMEOUT !
Gem.e000b000: No link, phyaddr: 1.
Gem.e000b000:1 is connected to Gem.e000b000.  Reconnecting to Gem.e000b000
Gem.e000b000 Waiting for PHY auto negotiation to complete......... TIMEOUT !
Gem.e000b000: No link, phyaddr: 1.
Gem.e000b000 Waiting for PHY auto negotiation to complete.....user interrupt!
Gem.e000b000: No link, phyaddr: 3.

增大uboot自协商超时时间。

#define PHY_ANEG_TIMEOUT	16000

tftp超时,时断时续,编辑uboot tftp.c下相关时间宏定义。

AR8033初始化错误导致linux ping不通

petalinux 2015.2.1,wireshark调试,实际情况是包根本没有发出去,在emmc做rootfs时出现,原因不明,参考uboot在驱动中加上下面的补丁。

static int at803x_config_init(struct phy_device *phydev)
{
	int ret;

	/*printk("%s %d\n", __FUNCTION__, __LINE__);*/
#if 1
	/*mwm193 rd rootfs ok, emmc rootfs net ping failed*/
	{
	int regval;
	phy_write(phydev, 0xd, 0x0007);
	phy_write(phydev, 0xe, 0x8016);
	phy_write(phydev, 0xd, 0x4007);
	regval = phy_read(phydev, 0xe);
	phy_write(phydev, 0xe, (regval|0x0018));
	phy_write(phydev, 0x1d, 0x05);
	regval = phy_read(phydev, 0x1e);
	phy_write(phydev, 0x1e, (regval|0x0100));
	}
#endif
...
}

20190815更新,

	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID || 
		phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
		ret = phy_write(phydev, AT803X_DEBUG_ADDR,
				0x0);
		if (ret)
			return ret;
		ret = phy_write(phydev, AT803X_DEBUG_DATA,
				BIT(15));
		if (ret)
			return ret;
	}
	
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID || 
		phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
		ret = phy_write(phydev, AT803X_DEBUG_ADDR,
				AT803X_DEBUG_SYSTEM_MODE_CTRL);
		if (ret)
			return ret;
		ret = phy_write(phydev, AT803X_DEBUG_DATA,
				AT803X_DEBUG_RGMII_TX_CLK_DLY);
		if (ret)
			return ret;
	}

budget exhausted after napi reschedule

【Linux4.1.12源码分析】收包软中断和NAPI
Linux内核NAPI机制分析

打印来自napi_poll函数,目前不影响使用,

	/* Some drivers may have called napi_schedule
	 * prior to exhausting their budget.
	 */
	if (unlikely(!list_empty(&n->poll_list))) {
		pr_warn_once("%s: Budget exhausted after napi rescheduled\n",
			     n->dev ? n->dev->name : "backlog");
		goto out_unlock;
	}

phytool

直接敲phytool输出帮助,phytool -h会报错error: bad location format

root@zynq:~# phytool print eth0/0
ieee-phy: id:0x02430c54

   ieee-phy: reg:BMCR(0x00) val:0x3100
      flags:          -reset -loopback +aneg-enable -power-down -isolate -aneg-restart -collision-test
      speed:          100-full

   ieee-phy: reg:BMSR(0x01) val:0x786d
      capabilities:   -100-b4 +100-f +100-h +10-f +10-h -100-t2-f -100-t2-h
      flags:          -ext-status +aneg-complete -remote-fault +aneg-capable +link -jabber +ext-register
root@zynq:~# phytool
Usage: phytool read  IFACE/ADDR/REG
       phytool write IFACE/ADDR/REG <0-0xffff>
       phytool print IFACE/ADDR[/REG]
where

ADDR := C22 | C45
C22  := <0-0x1f>
C45  := <0-0x1f>:<0-0x1f>
REG  := <0-0x1f>

Examples:
       phytool read  eth0/0:3/1
       phytool write eth0/0xa/0 0x1140
       phytool print eth0/0x1c

你可能感兴趣的:(linux内核与驱动开发)