早年写的笔记,压箱底了,翻出来晒晒
目 录
在redboot中加入以太网支持的通用方法... 1
1. 在redboot中加入以太网支持的步骤... 1
1.1. 加入phy芯片ID支持... 1
1.2.配置网口和phy端口... 2
2.phy芯片ID的确定... 2
3. 网口和phy端口的确定... 3
3.1. 网口的确定... 3
3.2. phy端口的确定... 3
3.3. 正确驱动phy芯片... 3
摸索和实践... 4
新P720的网口问题... 4
P780的phy. 7
移植redboot,除了主要的系统能够运行起来意外,通常需要驱动网卡。而IXP425的网卡通常就是NPE-B和NPE-C。这部分的驱动集成方法在前面已经讲述过了。下面主要是讲述phy的驱动和IXP网口的配合问题。
(07版的redboot两个文件的位置在/packages/devs/eth/intel/npe/ethMii/current/src/)
在IxEthMii.c的ixEthMiiPhyPresent()函数中加入新的phyID支持
找到如下代码,加入红色部分:
if((ixEthMiiPhyId[phyId] == IX_ETH_MII_KS8995_PHY_ID)
|| (ixEthMiiPhyId[phyId] ==IX_ETH_MII_KS8721B_PHY_ID)
|| (ixEthMiiPhyId[phyId] ==IX_ETH_MII_LXT971_PHY_ID)
|| (ixEthMiiPhyId[phyId] ==IX_ETH_MII_LXT972_PHY_ID)
|| (ixEthMiiPhyId[phyId] ==IX_ETH_MII_LXT973_PHY_ID)
|| (ixEthMiiPhyId[phyId] ==IX_ETH_MII_LXT973A3_PHY_ID)
||(ixEthMiiPhyId[phyId] == IX_ETH_MII_LXT9785_PHY_ID))
在IxEthMii_p.h中
找到如下代码加入红色部分
#defineIX_ETH_MII_LXT973_PHY_ID 0x00137A10
#defineIX_ETH_MII_KS8995_PHY_ID 0x00221450
#defineIX_ETH_MII_KS8721B_PHY_ID 0x00221619
其中KS8721B是芯片的名字,这个可以在板子上找到,不同的板子芯片不太一样,但是方法是一样的。0x00221619这phy芯片的ID,可以查找data sheet。如果找不到data sheet,也可以用code读取出来,后面有讲述。
在070302版redboot实验中,如果没有正确加入phy id,会有报错,但是只要网口和phy端口配置正确,一样可以ping通,没有什么大的影响。
网口和phy端口的定义在packages/devs/eth/arm/ixdp425/npe/current/include/ixdp425_npe.inl。
下面两个宏定义是确定phy端口:
#defineCYGNUM_ETH0_PHY_NO 0
#defineCYGNUM_ETH1_PHY_NO 1
含义是ETH0,也就是NPE-B用的phy端口是0号,而ETH1,也就是NPE-C用的phy端口是1号。实际上每个板子不相同。以P720板为例,使用的是NPE-B,PHY_NO为1,所以必须修改如下才能正常启动。
//#defineCYGNUM_ETH0_PHY_NO 0
#defineCYGNUM_ETH0_PHY_NO 1
又以P780为例,使用的是NPE-C,phy端口是0号,那么必须修改如下:
//#defineCYGNUM_ETH1_PHY_NO 1
#defineCYGNUM_ETH1_PHY_NO 0
加入#defineCYGPKG_DEVS_ETH_ARM_IXDP425_NPE_ETH1也可以,不加入也没关系,redboot当中的fconfig有配置。
另外如果板子上没有eeprom存储mac,需要在/ixdp425_npe.inl 里加入下面定义:
#define CYGPKG_DEVS_ETH_INTEL_NPE_REDBOOT_HOLDS_ESA
不然redboot就会试图从eeprom读取信息,就会失败。
找data sheet肯定没错,但是这个其实很简单,可以先什么都不改,然后用redboot启动盒子。如果代码里面没有改动IxEthMii_p.h和IxEthMii.c,那么redboot运行的时候会报错:
[error]ixEthMiiPhyScan : unexpected Mii PHY1 ID 00221619
从打印的语句就知道这个PHY的id是0x00221619了,然后加到代码里就可以了。这个打印语句在IxEthMii.c的ixEthMiiPhyPresent()函数里。读出0x00221619之类的数字,通常就是正确的,而且不放心的话可以google 0x00221619这个数字,肯定就能查找到和KS8721B相关的内容了。如果读出来的是0xffff或者0x0之类的数字,那就是读取失败了。可能硬件上有什么问题了。
网口和phy端口的确定最好是能找到硬件电路图,或者找到电路板的设计师。但是通常不太可能。好在IXP425一共也就3个网口NPE-B, NPE-C, NPE-A。NPE-A一般不使用,所以不用试。在redboot启动时使用的几只能是NPE-B和NPE-C。如果使用NPE-B那么在fconfig里面设置的启动网口就是npe_eth0, 而NPE-C对应的是npe_eth1。可以两个都尝试一下,能通的就行了。另外如果板子以前上面有bootloader或者linux,可以看看配置的是eth0还是eth1也可以帮助确定。
这个比较麻烦,没有电路图或者找到电路板设计师,基本上靠猜。而且phy的data sheet不一定能找到,像bcm5221A,只能找到product brief。这里又分两种情况:单端口phy和多端口phy。这里又分两种情况:单端口phy和多端口phy。不管怎么样,首先去查阅data sheet,找不到data sheet至少能找到product brief,看看到底是单端口phy还是多端口phy。
单端口phy很简单,phy no不是0就是1,最多两下就试出来了,这个因为有的芯片的phy no从0算,有的从1算。比如Kendin芯片,通常是从1开始,而BCM是0。多端口的phy只能看data sheet,到底有多少个phy port,从0还是1开始,然后一个个的试。
不管phy的端口(phy no)是不是被正确设置,phy都能正确读取和设置寄存器,发送数据显示也是正常的,只不过不能真正的将数据包发送出去而已,也不能接收数据。
正确驱动有几个标志:
1. 正确读取phy id。
IxEthMii.c的ixEthMiiPhyPresent()能读出正常的数值就可以了,不管是不是unexpectedMii PHY1。
2. 正确读取状态
在/packages/devs/eth/intel/npe/common/current/src/if_npe.c中加入#define DEBUG,redboot启动的时候会加入以太网状态的信息,显示如下;
Wait for PHY 0to be ready ...
PHY 0configuration:
PHY Status:
Link is Up
Auto Negotiation Completed
PHYConfiguration:
Speed 100Mb/s
Full Duplex
Auto Negotiation Enabled
如果有如上的信息显示,说明phy芯片已经正确的驱动了。在070320的redboot里,打开debug之后,发送数据包会有显示:
npe_tx_callback:m[156240] data[1555c0] len[6a]
npe_rx_callback:m[155440] data[153b40] len[6a]
npe_send: m[1562a0] data[155c00] len[106]
npe_tx_callback:m[1562a0] data[155c00] len[6a]
npe_rx_callback:m[1554a0]data[154180] len[6a]
npe_rx_callback:m[155500] data[1547c0] len[3c]
npe_send:m[156240] data[1555c0]len[106]
npe_tx_callback:m[156240] data[1555c0] len[6a]
npe_rx_callback:m[155560] data[154e00] len[6a]
npe_send: m[1562a0] data[155c00] len[106]
但是即使有发送数据包的正确显示,也不能表明数据包能正确发送出去。因为phy no可能没有正确的设置。
如果按照“在IX425DP上安装redboot”上的方法去做,在新P720上会出现如下错误:
RedBoot> DB:(FeatureScan) NpeDl did not provide the image ID for NPE port 0
DB:(FeatureScan) NpeDl did not provide the image ID for NPE port 1
[warning]ixEthAccQMgrQueuesConfig: no queues configured, bailing out
[warning]ixEthAccInit: queue config failed
Errorinitialising Ethernet access driver!
No networkinterfaces found
NpeDl did notprovide the image ID for NPE在IxEthDBFeatures.c里面。
(packages/devs/eth/intel/npe/ethDB/current/src/IxEthDBFeatures.c)
ixNpeDlLoadedImageGet里面加入判断语句,使用ram redboot的方法调试,打印结果如下:
RedBoot> go-w 1 0x00100040
About to startexecution at 0x00100040 - abort with ^C within 1 seconds
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln60, not validImage
ixNpeDlLoadedImageGet:ln80:Exiting ixNpeDlLoadedImageGet : status = 80
DB:(FeatureScan) NpeDl did not provide the image ID for NPE port 0
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln60, not validImage
ixNpeDlLoadedImageGet:ln80:Exiting ixNpeDlLoadedImageGet : status = 80
DB:(FeatureScan) NpeDl did not provide the image ID for NPE port 1
[warning]ixEthAccQMgrQueuesConfig: no queues configured, bailing out
[warning]ixEthAccInit: queue config failed
Errorinitialising Ethernet access driver!
No networkinterfaces found
RedBoot(tm)bootstrap and debug environment [RAM]
Red Hatcertified release, version 2.02 - built 22:52:13, Sep 1 2009
从ln60, not validImage看来是ixNpeDlNpeState[npeId].validImage的问题了。试试旧的P720, 显示如下:
RedBoot> load-v redboot_ram.srec
Using defaultprotocol (TFTP)
Entry point:0x00100040, address range: 0x00100000-0x0014c284
RedBoot> go-w 1 0x00100040
About to startexecution at 0x00100040 - abort with ^C within 1 seconds
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln50, validImage
ixNpeDlLoadedImageGet:ln80:Exiting ixNpeDlLoadedImageGet : status = 80
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln50, validImage
ixNpeDlLoadedImageGet:ln80:Exiting ixNpeDlLoadedImageGet : status = 80
TryingNPE-B...success. Using NPE-B with PHY 1.
很明显,老的板子认为image是好的。validImage的原始值是0,检查全部代码,在两个赋值的地方检查一下,看看到底是哪个地方将validImage改为true了。
RedBoot> go-w 1 0x00100040
About to startexecution at 0x00100040 - abort with ^C within 1 seconds
ixNpeDlNpeInitAndStartInternal:ln10, ixNpeDlNpeMgrImageLoad ok
ixNpeDlNpeInitAndStartInternal:ln10, ixNpeDlNpeMgrImageLoad ok
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln50, validImage
ixNpeDlLoadedImageGet:ln80:Exiting ixNpeDlLoadedImageGet : status = 80
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln50, validImage
ixNpeDlLoadedImageGet:ln80:Exiting ixNpeDlLoadedImageGet : status = 80
原来使用的是ixNpeDlNpeInitAndStartInternal函数。
使用新板子测试:
RedBoot> go-w 1 0x00100040
About to startexecution at 0x00100040 - abort with ^C within 1 seconds
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln60, not validImage
ixNpeDlLoadedImageGet:ln80:Exiting ixNpeDlLoadedImageGet : status = 80
DB: (FeatureScan)NpeDl did not provide the image ID for NPE port 0
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln60, not validImage
ixNpeDlLoadedImageGet:ln80:Exiting ixNpeDlLoadedImageGet : status = 80
DB:(FeatureScan) NpeDl did not provide the image ID for NPE port 1
[warning]ixEthAccQMgrQueuesConfig: no queues configured, bailing out
[warning]ixEthAccInit: queue config failed
Errorinitialising Ethernet access driver!
No networkinterfaces found
新板子根本就没有进入loadimage的函数。再查看,连上级函数都没有进入。
源代码如下:
if (npe_used[IX_ETH_PORT_1] &&npe_exists[IX_ETH_PORT_1] &&
ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS)!= IX_SUCCESS) {
diag_printf("Errordownloading firmware to NPE-B!\n");
return0;
}
在npe_csr_load里面进行打印。
npe_csr_load:ln10, initialising queue manager ok
npe_csr_load:ln20, initialising NPE Message handler ok
npe_csr_load:ln30, downloading firmware to NPE-B ok
npe_csr_load:ln40, downloading firmware to NPE-c ok
ixNpeDlLoadedImageGet:ln10, Entering
ixNpeDlLoadedImageGet:ln60, not validImage
这个比较奇怪了,实际上在if语句里面前面两个值打印出来如下:
npe_used[IX_ETH_PORT_1] = 1
npe_exists[IX_ETH_PORT_1] = 0
应该是系统优化了,因为发现npe_exists[IX_ETH_PORT_1] = 0,就根本没有执行后面的函数。强行改了算了,因为NPE-B肯定存在的。再次测试,没有问题。
在定义了CYGPKG_DEVS_ETH_INTEL_NPE_REDBOOT_HOLDS_ESA之后,因为没有意识到phy no的问题,显示如下:
npe_csr_load
TryingNPE-C...npe_init: ln15, p_npe->phy_no = 1
phy_present:ln20, phy_scanned[phyno] = 0
ixEthMiiPhyPresent:ln10, enter
ixEthMiiPhyPresent:ln20, go
ixEthMiiPhyPresent:ln80, IX_SUCCESS
npe_init: ln20,NPE_PHY_GROUP, no PHY present
no PHY found
TryingNPE-B...npe_init: ln15, p_npe->phy_no = 0
phy_present:ln20, phy_scanned[phyno] = 0
ixEthMiiPhyPresent:ln10, enter
ixEthMiiPhyPresent:ln20, go
ixEthMiiPhyPresent:ln30, go
ixEthMiiPhyPresent:ln10, ixEthMiiPhyId[phyId] = 4061e4
ixEthMiiPhyPresent:ln80, IX_SUCCESS
Wait for PHY 0to be ready ...success.
PHY 0configuration:
PHY ID[phyAddr]: 004061e4
Status reg: 782d
control reg: 1000
PHY Status:
Link is Up
Auto Negotiation Completed
PHYConfiguration:
Speed 100Mb/s
Full Duplex
Auto Negotiation Enabled
phy for NPE-Bfound!
success. UsingNPE-B with PHY 0.
npe_start: ln11,enter
npe_send:m[156240] data[1555c0]len[42]
npe_tx_callback:m[156240] data[1555c0]len[2a]
这个看起来是已经成功启动了网卡,但是发送的时候打印如下,却没有真正发送出数据包。
npe_start: ln11,enter
npe_send:m[156240] data[1555c0]len[42]
npe_tx_callback:m[156240] data[1555c0]len[2a]
npe_send: m[1562a0] data[155c00] len[42]
npe_tx_callback:m[1562a0] data[155c00] len[2a]
经过试验,发现是因为port no没有设置正确的原因。修改
//#defineCYGNUM_ETH1_PHY_NO 1
#defineCYGNUM_ETH1_PHY_NO 0
再次试验,正确设置好fconfig的启动网卡为npe_eth1,网口完全通了。