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; }