1. 概述
-
MAC驱动:
- compatible字符串: "ti,cpsw-switch-controller"
- 组件:DRV_END_FDT_TI_CPSW
- 主要文件:
- net\end-2.0.3.2\drv\src\end\vxbFdtTiCpswEnd.c
- net\end-2.0.3.2\drv\src\end\vxbFdtTiCpswEnd.h
- net\end-2.0.3.2\drv\cdf\40vxbFdtTiCpswEnd.cdf
-
PHY驱动:
- 组件:INCLUDE_MICREL_PHY
- 主要文件:
- net\end-2.0.3.2\drv\src\mii\vxbMicrelPhy.c
- net\end-2.0.3.2\drv\src\mii\vxbMicrelPhy.h
- net\end-2.0.3.2\drv\cdf\10mii.cdf
-
测试方法:
-
VIP中使能
INCLUDE_IPWRAP_IFCONFIG
,编译; -
shell中使用
ifconfig
命令正确设置IP,从PC侧ping单板网口; -
使用VxWorks blaster测试代码进行测试:
- blasteeTCPvx.c/blasterTCPux.c:
- 板子上执行
sp blasteeTCP,5000,16000,16000
:-> sp blasteeTCP,5000,16000,16000 Task spawned: id = 0x204c6cf0, name = t2 value = 541879536 = 0x204c6cf0
- Linux PC上执行:
gcc -O -Wall -DLINUX -o blasterTCP blasterTCPux.c ./blasterTCP 192.168.200.100 5000 16000 16000
- 板子上输出:
-> interrupt: 17218708 bytes/sec interrupt: 34957807 bytes/sec interrupt: 34494040 bytes/sec interrupt: 34287064 bytes/sec interrupt: 34222559 bytes/sec interrupt: 34279281 bytes/sec interrupt: 34666203 bytes/sec interrupt: 34975009 bytes/sec interrupt: 35631638 bytes/sec
- 板子上执行
blasteeTCPQuit
退出 测试:-> blasteeTCPQuit blasteeTCP end. value = -1 = 0xffffffff
- 板子上执行
- blasteeUDPvx.c/blasterUDPux.c:
- 板子上执行
sp blasteeUDP,5000,1000,1000
:-> sp blasteeUDP,5000,1000,1000 Task spawned: id = 0x204c6cf0, name = t3 value = 541879536 = 0x204c6cf0
- Linux PC上执行:
gcc -O -Wall -DLINUX -o blasterUDP blasterUDPux.c ./blasterUDP 192.168.200.100 5000 1000 1000
- 板子上输出:
-> interrupt: 20837600 bytes/sec interrupt: 34809800 bytes/sec interrupt: 58092300 bytes/sec interrupt: 56292000 bytes/sec interrupt: 58101600 bytes/sec interrupt: 57401300 bytes/sec interrupt: 57939400 bytes/sec interrupt: 58106600 bytes/sec interrupt: 54710600 bytes/sec
- 板子上执行
blasteeUDPQuit
退出 测试:-> blasteeUDPQuit blasteeUDP end. value = -1 = 0xffffffff
- 板子上执行
- 第二个网口可以使用如下命令进行初始化,并进行同样的测试:
-> ipcom_drv_eth_init "cpsw",1 value = 0 = 0x0 -> ifconfig "cpsw0 down" value = 0 = 0x0 -> ifconfig "cpsw1 192.168.200.101 up" value = 0 = 0x0 -> sp blasteeTCP,5000,16000,16000 Task spawned: id = 0x2050f7c8, name = t1 value = 542177224 = 0x2050f7c8 -> interrupt: 28898693 bytes/sec interrupt: 41184702 bytes/sec interrupt: 35248939 bytes/sec interrupt: 34481075 bytes/sec interrupt: 34425039 bytes/sec interrupt: 34852720 bytes/sec interrupt: 34491524 bytes/sec interrupt: 38869289 bytes/sec interrupt: 46467280 bytes/sec interrupt: 43134397 bytes/sec -> blasteeTCPQuit blasteeTCP end. value = -1 = 0xffffffff -> sp blasteeUDP,5000,1000,1000 Task spawned: id = 0x2050f7c8, name = t3 value = 542177224 = 0x2050f7c8 -> interrupt: 6305000 bytes/sec interrupt: 56270700 bytes/sec interrupt: 49631900 bytes/sec interrupt: 48110500 bytes/sec interrupt: 46237700 bytes/sec interrupt: 38053500 bytes/sec interrupt: 29870100 bytes/sec interrupt: 31047100 bytes/sec interrupt: 30627800 bytes/sec interrupt: 35647000 bytes/sec -> blasteeUDPQuit blasteeUDP end. value = -1 = 0xffffffff
注意:第二个网口也可以通过CDF参数来配置:
``` Parameter IFCONFIG_2 { NAME Interface configuration. SYNOPSIS Specifies the interface parameters to be configured when the stack is initialized, as a list of attribute-value strings DEFAULT "ifname cpsw1","devname cpsw1","inet 192.168.100.100/24", "gateway 192.168.100.1" } ```
- blasteeTCPvx.c/blasterTCPux.c:
-
-
问题列表:
- 网口灯有时不亮
- 网口收包数为0
- 网口不能runing
2. 网口灯不亮
- 拔掉电源,重新上电若干次后可解决;
- 客户反应不需要关心网口灯,SR0500版本起来后一段时间后会通,而SR0650不行,但是PHY寄存器dump出来内存是一致的;
- SR0500中PHY驱动probe阶段重复5遍,可能是MII接口有问题,需要进一步调查;
- 修改
vxbMicrelPhy.c
驱动micrelPhyProbe()
函数,重复读取设备ID,连续2次结果一致时退出循环匹配设备,最多5次,但是网口灯仍然不能恢复,因此应当属于无效修改; - 修复DTS管脚配置后,网口灯上电一段时间后正常点亮。
3. 收包问题
3.1 问题描述
- 单板侧使用
igconfig
查看网口状态,发现链路状态为UP
即链路已经已经建立,但是只有发包,没收包:-> ifconfig "cpsw0 192.168.200.100 up" value = 0 = 0x0 -> ifconfig lo0 Link type:Local loopback inet 127.0.0.1 mask 255.255.255.255 inet6 unicast fe80::1%lo0 prefixlen 64 automatic inet6 unicast ::1 prefixlen 128 UP RUNNING LOOPBACK MULTICAST NOARP ALLMULTI MTU:1500 metric:1 VR:0 ifindex:1 RX packets:0 mcast:0 errors:0 dropped:0 TX packets:0 mcast:0 errors:0 collisions:0 unsupported proto:0 RX bytes:0 TX bytes:0 cpsw0 Link type:Ethernet HWaddr 74:e1:82:ea:d3:04 capabilities: VLAN_MTU inet 192.168.200.100 mask 255.255.255.0 broadcast 192.168.200.255 inet6 unicast fe80::76e1:82ff:feea:d304%cpsw0 prefixlen 64 automatic UP RUNNING SIMPLEX BROADCAST MULTICAST MTU:1500 metric:1 VR:0 ifindex:2 RX packets:0 mcast:0 errors:0 dropped:0 TX packets:8 mcast:5 errors:0 collisions:0 unsupported proto:0 RX bytes:0 TX bytes:564 value = 0 = 0x0
- 增加
INCLUDE_IPWRAP_PING
组件,从单板侧ping PC,PC侧使用wireshark
抓包,发现可以收到单板发出来的ARP查询报文,PC侧也回复了报文,但是单板侧收包数一直为零。
3.2 调试记录
- 接收中断处理增加打印信息:
-
vxbFdtTiCpswEnd.c
中定义CPSW_DEBUG
,使用DBG_MSG (DBG_ERR,"cpswEndRxInt\n");
在cpswEndRxInt()
开头增加打印信息; - VSB中编译
END_2_0_3_2
; - VIP中使能
INCLUDE_DEBUG_KPRINTF
并重新编译; - 无打印信息
-
- 发送中断(
cpswEndTxInt()
)处理增加打印信息,无打印信息 -
cpswPortAttach()
中断挂接处检查vxbIntConnect
返回值,无错误 -
cpswPortAttach()
中断挂接处打印vxbIntConnect
参数即pSwCtrl
,然后在shell中使用该参数手工调用cpswEndRxInt 0x2008e178
,网口可ping通,因此可以确认是中断问题; - VIP中使能
INCLUDE_ISR_SHOW
并重新编译,shell中查看ISR信息,timer和串口的ISR均有调用,而网口的ISR未调用:-> isrShow ISR ID Name Tag HandlerRtn ---------- --------------------------- ---------- ------------------------------ 0x20083590 isr1 106 tiAm3SiovxbInt 0x200895e8 isr2 70 299de8 ... 0x2008f110 isr9 147 cpswEndRxInt 0x2008f1b8 isr10 148 cpswEndTxInt 0x2008f260 isr11 149 cpswEndMiscInt ... value = 0 = 0x0 -> isrShow 0x2008f1b8 ID : 0x2008f1b8 Name : isr10 Interrupt Tag : 148 Count : 0 Service Count : 0 Options : 0x0 Handler Routine : cpswEndTxInt Argument : 0x2008e178 value = 0 = 0x0 -> isrShow 0x2008f110 ID : 0x2008f110 Name : isr9 Interrupt Tag : 147 Count : 0 Service Count : 0 Options : 0x0 Handler Routine : cpswEndRxInt Argument : 0x2008e178 value = 0 = 0x0 -> isrShow 0x20083590 ID : 0x20083590 Name : isr1 Interrupt Tag : 106 Count : 203 Service Count : 203 Options : 0x0 Handler Routine : tiAm3SiovxbInt Argument : 0x200833f8 value = 0 = 0x0 -> isrShow 0x200895e8 ID : 0x200895e8 Name : isr2 Interrupt Tag : 70 Count : 30209 Service Count : 30209 Options : 0x0 Handler Routine : 299de8 Argument : 0x20089440 value = 0 = 0x0
- 根据
am572x_branson_ca15.dts
文件,中断类型相同,因此应该不是中断控制器的问题:dmtimer2: dmtimer@48032000 /* DM Timer 2 */ { ... interrupts = <70 0 4>; }; cpsw_port1: port@1 /* port device*/ { ... interrupts = <147 0 4>, /* c0_rx_pend */ <148 0 4>, /* c0_tx_pend */ <149 0 4>; /* c0_misc_pend */ ... }; serial3: serial@48020000 { ... interrupts = <106 0 4>; ... };
-
cpswEndStart()
中断使能处检查vxbIntEnable
返回值,无错误; - 中断控制器驱动
vxbFdtArmGenIntCtlr.c
使能调试信息ARM_GIC_DBG
,并在使能函数vxbArmGicIntEnableMethod()
和中断入口vxbArmGicPreempISR()
增加打印信息,中断号没有问题,并且在中断使能后没有打印,因此应该是网口驱动问题 - 对齐到572x参考BSP
ti_sitara_a15-2.0.4.1
,未发现MAC相关问题,无改进; - 对比SR0500版本
vxbFdtTiCpswEnd.c
和vxbFdtTiCpswEnd.h
,无特殊改动; - 查看中断使能和状态寄存器以及中断机制:
- 接收中断使能方法
24.11.4.5.1 Receive Packet Completion Pulse Interrupt (RX_PULSE)
The RX_PULSE interrupt is a pulse interrupt selected from the GMAC_SW RX_PEND[7:0] interrupts. The receive DMA controller has eight channels with each channel having a corresponding (RX_PEND[7:0]).
The following steps will enable the receive packet completion interrupt:
1. Enable the required channel interrupts of the DMA engine by setting 1 to the appropriate bit in the
CPDMA_RX_INTMASK_SET register.
1. The receive completion interrupt(s) to be routed to RX_PULSE is selected by setting one or more bits
in the receive interrupt enable register (WR_C0_RX_EN) . The masked interrupt status can be read in
the address location of RX_STAT bit in the WR_C0_RX_STAT register. - 发送中断使能方法
24.11.4.5.2 Transmit Packet Completion Pulse Interrupt (TX_PULSE)
The TX_PULSE interrupt is a pulse interrupt selected from the GMAC_SW TX_PEND[7:0] interrupts. The transmit DMA controller has eight channels with each channel having a corresponding (TX_PEND[7:0]).
To enable the transmit packet completion interrupt:
1. Enable the required channel interrupts of the DMA engine by setting 1 to the appropriate bit in the
CPDMA_TX_INTMASK_SET register.
1. The transmit completion interrupt(s) to be routed to TX_PULSE is selected by setting one or more bits
in the transmit interrupt enable register WR_C0_TX_EN .The masked interrupt status can be read in
the address location of TX_STAT bit in the WR_C0_TX_STAT register. - 相关寄存器偏移
名称 地址 CPDMA_TX_INTSTAT_RAW 0x4848 4880 CPDMA_TX_INTSTAT_MASKED 0x4848 4884 CPDMA_TX_INTMASK_SET 0x4848 4888 CPDMA_TX_INTMASK_CLEAR 0x4848 488C CPDMA_IN_VECTOR 0x4848 4890 CPDMA_EOI_VECTOR 0x4848 4894 CPDMA_RX_INTSTAT_RAW 0x4848 48A0 CPDMA_RX_INTSTAT_MASKED 0x4848 48A4 CPDMA_RX_INTMASK_SET 0x4848 48A8 CPDMA_RX_INTMASK_CLEAR 0x4848 48AC WR_C0_RX_EN 0x4848 5214 WR_C0_TX_EN 0x4848 5218 WR_C0_RX_STAT 0x4848 5244 WR_C0_TX_STAT 0x4848 5248 -
cpswSwCtrlAttach()
寄存器映射处打印pSwCtrl->regBase
,得到虚拟地址为0x2213e000
,对应于物理地址0x4848 4000
- shell中查看寄存器内容,中断使能且收发中断状态均已置位:
-> d 0x2213e880,16,4 NOTE: memory values are displayed in hexadecimal. 0x2213e880: 00000001 00000001 00000003 00000003 *................* 0x2213e890: 00010001 00000000 00000000 00000000 *................* 0x2213e8a0: 00000001 00000001 00000003 00000003 *................* 0x2213e8b0: 00000000 00000000 00000002 00000002 *................* -> d 0x2213F200 NOTE: memory values are displayed in hexadecimal. 0x2213f200: 4edb1902 00000000 0000000a 00000000 *...N............* 0x2213f210: 00000000 00000003 00000003 0000001f *................* 0x2213f220: 00000000 00000000 00000000 00000000 *................* 0x2213f230: 00000000 00000000 00000000 00000000 *................* value = 0 = 0x0 -> d 0x2213F240 NOTE: memory values are displayed in hexadecimal. 0x2213f240: 00000000 00000001 00000001 00000000 *................* 0x2213f250: 00000000 00000000 00000000 00000000 *................* 0x2213f260: 00000000 00000000 00000000 00000000 *................* 0x2213f270: 00000000 00000000 00000000 00000000 *................* value = 0 = 0x0
- 问题应当出在MAC驱动和中断控制器驱动之间的配合上。
- BSP基于
ti_sitara_a15-2.0.4.1
修改,差别不大,因此基于该BSP创建VSB和VIP,注意VIP中使能INCLUDE_STANDALONE_DTB
,启动后网口中断正常,因此应当是BSP配置问题,尤其是DTS问题;
- MAC和PHY设备中板子相关配置如下所示:
其中,cpsw_switch_controller: ethernet@48484000 /* ethernet system */ { .... clocks = <&gmac_rft_clk_mux>, <&gmac_gmii_ref_clk_div>; clock-names = "gmac_rft_clk_mux","gmac_gmii_ref_clk_div"; pinmux-0 = <&cpsw_pads>; /* pinmux setting */ cpsw_port1: port@4a002514 /* port device*/ { ... cpsw-mac-save-way = <1>; local-mac-address = [ 00 40 47 E0 A8 32 ]; phy-handle = <&phy1>; /* port1 use phy1 */ phy1: ethernet-phy@0 /* phy of port0 */ { compatible = "micrel,phy"; reg = <0>; /* phy address : 0 */ ... }; }; cpsw_port2: port@4a00251c /* port device*/ { ... }; };
- 时钟配置位于
am572x_clock.dtsi
中,对比ti_sitara_a15-2.0.4.1
后发现dpll_mpu_ck: dpll_mpu_ck@4a005160
节点的compatible字符串无效,应当从ti,omap5-mpu-dpll-clock
修改为ti,omap4-dpll-mpu-clock
,但是应当无MAC无关,尝试修改后没有影响; - 管脚配置位于主dts文件中,对比后发现管脚复用节点多了一层
pads0
封装,如下所示:cm@4a002000 /* control module */ { /* this device provide pads config */ compatible = "ti,am5-pads"; reg = <0x4a002000 0x2000>; #address-cells = <1>; #size-cells = <0>; pads@0 { uart3_pads: uart0pads { pin-set = < 0x1648 0x4000e /* rxd */ 0x164c 0x4000e /* txd */ >; }; ... };
- 时钟配置位于
- 进一步检查
os\drv\vxbus\subsystem\src\pinmux\vxbPinMuxLib.c
中的vxbPinMuxEnable()->vxbPinMuxEnable()
调用流程后发现,管脚复用节点的上一级被默认为管脚复用控制器即cm@4a002000
,而不是pads@0
,因此导致管脚复用没有生效;下次遇到类似问题时,可以修改os\drv\vxbus\subsystem\src\pinmux\vxbPinMuxLib.c
文件,将PINMUX_DBG
打开,从而尽快发现错误; - 删除
pads0
封装后,中断可以正常上报,网口可以ping通。
4. 网口不能runing
- 网口起来后
ifconfig
查看网口状态不能runing:-> ifconfig lo0 Link type:Local loopback inet 127.0.0.1 mask 255.255.255.255 inet6 unicast fe80::1%lo0 prefixlen 64 automatic inet6 unicast ::1 prefixlen 128 UP RUNNING LOOPBACK MULTICAST NOARP ALLMULTI MTU:1500 metric:1 VR:0 ifindex:1 RX packets:0 mcast:0 errors:0 dropped:0 TX packets:0 mcast:0 errors:0 collisions:0 unsupported proto:0 RX bytes:0 TX bytes:0 cpsw0 Link type:Ethernet HWaddr 74:e1:82:ea:d3:04 capabilities: VLAN_MTU inet 192.168.200.100 mask 255.255.255.0 broadcast 192.168.200.255 inet6 unicast fe80::76e1:82ff:feea:d304%cpsw0 prefixlen 64 tentative automatic UP SIMPLEX BROADCAST MULTICAST MTU:1500 metric:1 VR:0 ifindex:2 RX packets:0 mcast:0 errors:0 dropped:0 TX packets:0 mcast:0 errors:0 collisions:0 unsupported proto:0 RX bytes:0 TX bytes:0
-
vxbFdtTiCpswEnd.c
中定义CPSW_DEBUG
并在VIP中使能INCLUDE_DEBUG_KPRINTF
,网口正常工作; - SR0650基于
ti_sitara_a15-2.0.4.1
创建VSB和VIP,问题类似; - SR0500客户VIP版本中去除
vxbFdtTiCpswEnd.c
调试打印信息,网口无法runing; - SR0500客户VIP版本中恢复
vxbFdtTiCpswEnd.c
调试打印信息,网口可以runing; - shell中使用
vxbDevShow
查看设备状态,发现PHY设备未正确匹配驱动:-> vxbDevShow mainbus-0 at root nexus level(0) mainbus-0: <TI_AM572X_BRANSON - Cortex-A15 (ARMV7A)> fdtBus-0 (refs: 2) on mainbus0 (refs: 2) fdtBus-0: <FDT bus controller> (0x20237808) level(1) simpleBus-0 (refs: 26) on fdtBus0 (refs: 2) simpleBus-0: <simple bus controller> (0x202378e8) level(2) ... cpsw switch controller-0 (refs: 2) on simpleBus0 (refs: 26) cpsw switch controller-0: <cpsw switch controller> (0x2029fba0) level(3) cpsw port-0 (refs: 1) on cpsw switch controller0 (refs: 2) cpsw port-0: <cpsw port> (0x2029fe08) level(4) ▒4 -0 (refs: 0) on cpsw port0 (refs: 1) ▒4 -0: <(no driver attached)> (0x202a9c90) level(5) cpsw port-1 (refs: 1) on cpsw switch controller0 (refs: 2) cpsw port-1: <cpsw port> (0x202a9ed8) level(4) -0 (refs: 0) on cpsw port1 (refs: 1) -0: <(no driver attached)> (0x2034fc50) level(5) ... cpus-0 (refs: 0) on fdtBus0 (refs: 2) cpus-0: <(no driver attached)> (0x205edb40) level(2) virtBus-0 (refs: 0) on mainbus0 (refs: 2) virtBus-0: <(no driver attached)> (0x205edc30) level(1) value = 543087664 = 0x205edc30
- 修改
vxbMicrelPhy.c
驱动micrelPhyProbe()
函数,probe次数改为SR500的5次,问题依旧; - 修改
vxbMicrelPhy.c
驱动micrelPhyProbe()
函数,probe次数改为无限次,问题消失; - 修改
vxbMicrelPhy.c
驱动micrelPhyProbe()
函数,probe次数改为无限次,并记录最大peobe次数,CPSW0的probe次数为114~117次, CPSW1的probe次数为1次,因此应该是PHY设备的MII接口时序不稳定,只能workaround;SR0500只需要5次是因为使能调试后在网口驱动和PHY驱动之间加入了延时,从而大多数情况只需要1次就可以probe成功,偶尔需要4次才能成功; - 修改
vxbMicrelPhy.c
驱动micrelPhyProbe()
函数,probe次数改为128次,问题解决:LOCAL STATUS micrelPhyProbe ( VXB_DEV_ID pDev ) { ... pPhyDev = vxbDevIvarsGet(pDev); for(i = 0; i < 128; i++) { ... if( miiOui == MICREL_OUI_ID ) { /* match Micrel PHY ID exactly */ return OK; } } return ERROR; }
网友评论