搜档网
当前位置:搜档网 › Rockchip BOX 以太网 指南_v2.2

Rockchip BOX 以太网 指南_v2.2

Rockchip BOX 以太网  指南_v2.2
Rockchip BOX 以太网  指南_v2.2

密级状态:绝密()秘密()内部资料()公开(√)

Rockchip BOX以太网开发指南

(技术研发部,电视事业部)

文件状态:

[]草稿[√]正式发布[]正在修改文件标识:Rockchip BOX以太网开发指南当前版本: 2.2

作者:陈智

完成日期:2014-09-25

审核:

审核日期:

版本历史

版本号作者修改日期修改说明

v0.1陈智2014-03-15创建文件

v2.0陈智2014-09-15增加对RK3288/RK3128/RK3036配置的说明v2.1陈智2014-09-25 1.修改第2章关于PHY芯片驱动的描述

2.修改2.2.3及2.2.5中对RMII时钟的配置V2.2胡卫国2015-0309 1.增加GMAC问题排查部分

目录

1概述 (5)

2以太网PHY芯片 (6)

2.1接口 (6)

2.2K ERNEL配置 (7)

2.2.1RK3066 (7)

2.2.2RK3188 (9)

2.2.3RK3288 (9)

2.2.4RK3036 (14)

2.2.5RK3128 (15)

3USB以太网卡芯片 (16)

3.1K ERNEL配置 (16)

3.2MAC地址烧写 (16)

3.3字节对齐问题 (16)

4ANDROID接口 (19)

4.1A NDROID4.24.4(A NDROID5.0之前版本) (19)

4.2A NDROID5.0 (20)

5以太网常见问题排查 (22)

5.13.10版本K ERNEL部分 (22)

5.1.1phy寄存器读写调试 (22)

5.1.2PHY配置 (22)

5.1.3以太网无法正常工作 (23)

5.1.4USB以太网异常排查 (27)

6附录 (31)

6.1已验证以太网PHY芯片列表 (31)

6.2已验证USB以太网卡芯片列表 (31)

1概述

本文基于Rockchip BOX SDK进行描述。将在第2章和第3章中针对RMII/RGMII 接口芯片和USB以太网两种类型芯片在SDK上的配置做详细的描述,第4章介绍以太网在Android上的相关调用接口。附录将会列出所支持的芯片列表。

2以太网PHY芯片

由于在RK系列的SoC中内置了以太网MAC控制器,所以只需要搭配一颗以太网PHY 芯片,即可实现以太网卡功能。按照规范,即使是不同厂家的PHY,仍然有一部分寄存器的定义是通用的,只要配置了这些通用的寄存器,基本上PHY就可以正常工作。因此,在Linux驱动中有通用的PHY驱动,3288之前的芯片所配套的SDK中使用的都是通用驱动,当然SoC中的MAC驱动是需要实现的。所以理论上,如果不需要使用PHY厂家提供的自定义的寄存器配置实现一些个性化的功能,那么PHY的驱动就不需要修改。从3288之后的SDK开始,打开了各个PHY厂家在Linux上提供驱动的配置,但是基本上,各家的驱动差异很小,基本上也是调用通用驱动的接口。

2.1接口

10/100M以太网PHY与MAC之间的接口主要有MII和RMII。10/100/1000M以太网PHY与MAC之间的接口主要有RGMII。RK系列的各个SoC支持的PHY接口列表如下:

SoC MII RMII RGMII

RK2918√√

RK2908√√

RK3066√

RK3188√

RK3288√√

RK3036√

RK3128√√

(注:2918/2908虽然硬件上有MII接口,但驱动上并不支持)

2.2Kernel配置

SoC控制器Kernel版本

RK2918VMAC 2.6.x

RK2908VMAC 2.6.x

RK3066VMAC 3.0.36

RK3188VMAC 3.0.36

RK3288GMAC 3.10

RK3036VMAC 3.10

RK3128GMAC 3.10

2.2.1RK3066

2.2.1.1基本配置

以太网在kernel中的menuconfig配置如下所示,可以根据产品需求开关此配置,SDK 中下述配置默认打开

Device Drivers--->

Networking support--->

[*]Ethernet(10or100Mbit)--->

<*>RK29VMAC ethernet support

MAC驱动代码位于kernel/drivers/net/rk29_vmac.c

此外,由于各个平台对PHY进行上下电操作使用的控制管脚或PMU会有所不同,同时各款RK芯片的一些和以太网相关的通用寄存器地址也会有所不同,所以和平台相关的操作和驱动代码是分开的,一般存放于arch/arm/mach-rkxx文件夹中,因不同芯片而异,如3066的上述操作位于文件arch/arm/mach-rk30/board-rk30-sdk-vmac.c中。该文件中的接口最终会被驱动代码所调用,需要特别注意的就是对PHY的上下电的操作,有可能不同产品所选用的PMU与SDK不同,或者使用的PMU的LDO口与SDK

不同,所以需要根据实际情况修改这个文件。

2.2.1.2时钟配置

根据规范,RMII接口需要50M参考时钟来保证MAC和PHY之间数据传输的同步。50M时钟,可以由MAC来提供,也可以由PHY来提供。50M时钟必须是精确的,且必须保证尽可能小的jitter,太大的jitter会导致较大的传输的错包率。SDK默认使用MAC,也就是RK芯片内部的MAC控制器来提供时钟。一般情况下,并不需要使用PHY来提供参考时钟,因为这样需要额外增加一颗晶振来实现。除非由于分频的原因,MAC无法给出符合要求的50M参考时钟,RK3188T上即存在这样的问题,所以需要由PHY来提供参考时钟。需要在kernel上增加如下配置,并相应修改电路,即可实现(该配置目前只在3188相关的SDK中有效)。

Device Drivers--->

Networking support--->

[*]Ethernet(10or100Mbit)--->

<*>Select the vmac source clock(RK29_VMAC_EXT_CLK)

2.2.1.3MAC地址

通常,每个以太网设备只有唯一的MAC地址,所以需要有一个地方用来存储这个唯一的地址,同时在打开以太网时读取出这个地址,并写入PHY寄存器。SDK提供了四种获取以太网MAC地址的方法:

1)存储在NAND的IDB中

首先要保证kernel中的配置CONFIG_ETH_MAC_FROM_IDB已打开

其次要使用烧写工具将地址写入,烧写工具在SDK中有提供。

2)存储在EEPROM中

首先要保证kernel中的配置CONFIG_ETH_MAC_FROM_EEPROM已打开

其次EEPROM的驱动见drivers/staging/rk29/eeprom,根据不同型号请自行作相应修改

3)使用WiFi的MAC地址

该种方法的原理是在系统启动时自动加载一次Wi-Fi驱动,同时将Wi-Fi的MAC地址读出并存储在/data分区的一个文件中,以太网打开时,读取该文件中的地址。

首先要保证kernel中的配置CONFIG_ETH_MAC_FROM_WIFI_MAC已打开

其次要保证Android上wlan_mac程序存在,且已在init.rc或init.rkxx.rc中已添加如下脚本

service wlan_mac/system/bin/wlan_mac

class main

oneshot

以太网驱动读取地址的代码存于drivers/net/eth_mac,请根据实际需求修改此代码。

由于不同的网络设备的MAC地址必须是唯一的,所以请考虑使用这种方法的风险性。

4)使用随机地址

若上述三种方法均未采用,驱动中会在每次打开以太网时随机生成MAC地址

由于不同的网络设备的MAC地址必须是唯一的,所以请考虑使用这种方法的风险性。

2.2.2RK3188

同RK3066,见2.2.1

2.2.3RK3288

2.2.

3.1基本配置

以太网在kernel中的menuconfig配置如下所示,可以根据产品需求开关此配置,SDK中下述配置默认打开

Device Drivers--->

Networking support--->

[*]Ethernet(10or100Mbit)--->

RockChip devices--->

RockChip10/100/1000Ethernet driver

由于3.10kernel的驱动架构与3.0.36相比有较大改动,引入了device tree的概念,许多配置改为在dts文件中进行修改。所以,相应地,对以太网相关的一些配置的修改也需要在dts文件中进行。以3288box sdk板为例,相应的dts文件为arch/arm/boot/dts/rk3288-box.dts.G MAC驱动代码位于drivers/net/ethernet/rockchip/gmac/

&gmac_clkin{

clock-frequency=<125000000>;-->PHY供给GMAC的时钟大小

};

&gmac{

//pmu_regulator="act_ldo5";--->给PHY供电的PMU 上的ldo

//pmu_enable_level=<1>;//1->HIGH,0->LOW--->ldo有效电平

//power-gpio=<&gpio0GPIO_A6GPIO_ACTIVE_HIGH>;--->电源控制IO及有效电平

reset-gpio=<&gpio4GPIO_B0GPIO_ACTIVE_LOW>;--->复位IO及有效电平

phy-mode="rgmii";--->PHY接口

clock_in_out="input";--->时钟方向

tx_delay=<0x30>;--->TX线上的延时值

rx_delay=<0x10>;--->RX线上的延时值

};

一般情况下,控制供电方式或者为PMU,或者为IO控制,若使用其中一种,则屏蔽另外一种。还有一种情况,是对PHY长供电,这时候可以考虑把二者都屏蔽。

PHY接口的配置:根据板上所使用的PHY的接口进行配置,一般千兆PHY为RGMII,百兆PHY为RMII。

时钟方向:input表示由PHY提供,output表示由GMAC提供。关于时钟,请参考2.2.3.2的说明。

TX/RX线上的延时值:请参考2.2.3.3

PHY供给GMAC的时钟大小:这个值只有在时钟方向为input时才会使用到,RMII接口时,设为50000000,RGMII接口时设为125000000

100M PHY配置

&gmac_clkin{

clock-frequency=<50000000>;-->修改成50M

};

&gmac{

//power-gpio=<&gpio0GPIO_A6GPIO_ACTIVE_HIGH>;

reset-gpio=<&gpio4GPIO_B0GPIO_ACTIVE_LOW>;

phy-mode="rmii";--->修改成rmii

clock_in_out="output";--->修改成output,也就是由RK主控提供tx_delay=<0x30>;

rx_delay=<0x10>;

};

注意:如果是RK3288芯片,50M主时建议由外部PHY提供,因为RK主控分出的50M clock 可能不精准,会造成GMAC丢包或无法工作。

1000M PHY配置

&gmac_clkin{

clock-frequency=<125000000>;-->修改成125M

};

&gmac{

//power-gpio=<&gpio0GPIO_A6GPIO_ACTIVE_HIGH>;

reset-gpio=<&gpio4GPIO_B0GPIO_ACTIVE_LOW>;

phy-mode="rgmii";--->修改成rgmii

clock_in_out="input";--->修改成input,也就是125M由PHY提供

tx_delay=<0x30>;

rx_delay=<0x10>;

};

注意:125M主时间需要由外部PHY提供,这是因为RK主控分出的125M clock不精准,会造成GMAC丢包或无法工作。

3.10版本kernel的phy驱动代码位于drivers/net/phy/

menuconfig的配置如下:

Device Drivers--->

Networking support--->

PHY Device support and infrastructure

2.2.

3.2时钟配置

(1)RGMII

RGMII上分别有TX_CLK和RX_CLK两个时钟,这两个时钟分别由MAC和PHY产生,这两个时钟频率的大小和网速的大小相关,千兆网速的时候,时钟频率为125MHz,百兆为25MHz,十兆为2.5MHz。

TX_CLK可以由3288内部的PLL分频产生,也可以由外部的时钟输入经过分频后产生。目前我们使用的是由外部输入的时钟,这样的时钟相对于内部PLL产生的时钟更加独立,不受3288内部分频策略的影响,因此更加稳定。而对于PHY来说,本身就需要一个25M的晶振作为时钟源,因此RX_CLK正是由这个时钟源倍频或分频得到的。绝大多数PHY还有这样的一个输出管脚,可以输出一个时钟给MAC,也就是上面描述的相对于MAC来说的外部时钟,这个时钟大小为125MHz,作为MAC端TX_CLK的时钟源。2.2.3.1中描述的时钟方向正是指的是用内部时钟output或是外部时钟input。

(2)RMII

对于RMII接口来说,需要的只是一个50MHz的参考时钟,这个概念可以参考2.2.1.2。

需要注意的是,若时钟方向设为output,也就是从3288的GMAC向PHY提供参考时钟,就需要额外修改arch/arm/boot/dts/rk3288.dtsi,把npll初始值设为1200000000,也就是1.2G,如下:

diff--git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi

index75392fd..503f6b6100755

---a/arch/arm/boot/dts/rk3288.dtsi

+++b/arch/arm/boot/dts/rk3288.dtsi

@@-496,7+496,7@@

<&usbphy_480m&otgphy2_480m>;

rockchip,clocks-init-rate=

<&clk_core792000000>,<&clk_gpll600000000>,//box changed

-<&clk_cpll29700000>,<&clk_npll1250000000>,

+<&clk_cpll29700000>,<&clk_npll1200000000>,

<&aclk_bus_src300000000>,<&aclk_bus300000000>,

<&hclk_bus150000000>,<&pclk_bus75000000>,

<&clk_crypto150000000>,<&aclk_peri300000000>,

2.2.

3.3时序配置

时序配置是千兆网卡上才开始有的概念,具体到3288上,也就是RGMII接口才需要去特别配置时序。这是因为时钟频率更高了以后更容易受到PCB layout走线,电磁干扰等因素的影响,因此需要更加精确的调整。比如TX或RX出现走线太长的情况,就有可能需要配置不同的延时值来调整时序。2.2.3.1中列出的两个值是SDK板上用的,目前在多数客户板上也是使用这两个值,如果有出现测试吞吐率不足的情况,可以适当调整这两个值,范围是0x0—0x7F.在实际的调整过程中,可以在上述这两个值的基础上适当加减,正常不应该会有太大的偏差。

2.2.

3.4IO驱动强度配置

如果发现gmac信号质量不佳,幅度偏大或偏小,可通过调整相应的IO驱动强度来改善。驱动强度有4档,分别是2mA,4mA,8mA和12mA,以RK3288为例,将txpins 的驱动强度调整为4mA,调整方法如下:

b/arch/arm/boot/dts/rk3288-pinctrl.dtsi

mac_txpins:mac-txpins{

rockchip,pins=,,,, ,;

rockchip,pull=;

-rockchip,drive=;

+rockchip,drive=;

//rockchip,tristate=;

};

2.2.

3.5MAC地址

目前32上对MAC地址的读取策略是,优先使用烧写在IDB中的MAC地址,若该地址符合规范,则使用,若不符合,则使用随机生成的地址。烧写工具在SDK中会附带。

2.2.4RK3036

RK3036使用3.10kernel,配置如下

Device Drivers--->

Networking support--->

[*]Ethernet(10or100Mbit)--->

RockChip devices--->

RockChip10/100Ethernet driver

由于3.10kernel的驱动架构与3.0.36相比有较大改动,引入了device tree的概念,许多配置改为在dts文件中进行修改。所以,相应地,对以太网相关的一些配置的修改

也需要在dts文件中进行。SDK上的相应3036的dts文件为arch/arm/boot/dts/rk3036-sdk.dts

&vmac{

//pmu_regulator="act_ldo5";

//pmu_enable_level=<1>;//1->HIGH,0->LOW

//power-gpio=<&gpio0GPIO_A6GPIO_ACTIVE_HIGH>;

reset-gpio=<&gpio2GPIO_C6GPIO_ACTIVE_LOW>;

};

上述dts文件中各个字段的含义可参考2.2.3.1

MAC驱动代码位于drivers/net/ethernet/rockchip/vmac/rk29_vmac.c

2.2.5RK3128

同RK3288,见2.2.3

注:2.2.3.2时钟配置(2)RMII这个章节中描述的对npll的配置在3128上不需要进行

3USB以太网卡芯片

USB以太网芯片内部集成了以太网MAC和PHY,因此并不需要RK芯片内部的MAC,驱动和第2章所述的也完全不同。所以如果产品中使用的是内置的USB以太网芯片,可以考虑把2.2中提到的配置关闭。

3.1Kernel配置

和PHY情况类似,Linux kernel中有USB以太网卡的通用驱动,只需要打开如下配置即可

Device Drivers--->

Networking support--->

USB Network Adapters--->

Multi-purpose USB Networking Framework

通常各款USB以太网卡还会有自己的驱动,可以根据实际情况打开上述配置下一级相应的配置即可。另外有些厂家还会额外提供驱动的更新,按厂家指导进行即可。3.2MAC地址烧写

此处MAC地址烧写的概念和2.4所述不同,由于USB以太网芯片是一个独立的网卡,所以必须事先固化MAC地址到芯片的OTP中。不同厂家会有不同的实现方式,有些是事先内置好的,有些则需要使用相应的工具进行烧写,可以联系供应商提供相应支持。

注意:没有烧写MAC地址的USB以太网芯片无法正常工作!

3.3字节对齐问题

注意:此部分只针对kernel3.0的平台

由于RK芯片的USB驱动内部没有处理字节对齐问题,所以所有调用USB传输接口的驱动必须自行处理好字节对齐。若发现kernel的log中打出USB相关报错,请确认如下补丁是否已经打上。SDK默认已经打上下述补丁。此外,若使用供应商提供的驱动代码,也需要参照下述补丁在驱动中调用USB传输接口的地方做相应处理。

diff--git a/kernel/drivers/net/usb/usbnet.c b/kernel/drivers/net/usb/usbnet.c

old mode100644

new mode100755

index d1ab169..809f416

---a/kernel/drivers/net/usb/usbnet.c

+++b/kernel/drivers/net/usb/usbnet.c

@@-1103,6+1103,28@@netdev_tx_t usbnet_start_xmit(struct sk_buff*skb,

}

}

}

+

+

+length=((unsigned long)skb->data)&0x3;

+if(length){

+if(skb_cloned(skb)||

+((skb_headroom(skb)

+(skb_tailroom(skb)<(4-length)))){

+struct sk_buff*skb2;

+/*copy skb with proper alignment*/

+skb2=skb_copy_expand(skb,0,4,GFP_ATOMIC);

+dev_kfree_skb_any(skb);

+skb=skb2;

+if(!skb)

+goto drop;

+}else{

+/*move data inside buffer*/

+length=((skb_headroom(skb)>=length)?0:4)-length;

+memmove(skb->data+length,skb->data,skb->len);

+skb_reserve(skb,length);

+}

+}

+

length=skb->len;

if(!(urb=usb_alloc_urb(0,GFP_ATOMIC))){

4Android接口

4.1Android4.24.4(Android

5.0之前版本)

下述接口代码存放于frameworks/base/ethernet

public int getEthernetConnectState()

获取连接状态

0::未连接;1:连接中;2:已连接

public int getEthernetIfaceState()

获取以太网接口状态(是否使能以太网)

0:未使能;1:已使能

public int getEthernetCarrierState()

获取是否有载波信号(可用来判断网线是否已插入)

0:无载波信号;1:有载波信号

public boolean setEthernetEnabled(boolean enabled)

打开/关闭以太网

public String getEthernetIfaceName()

获取以太网接口名,一般为“eth0”

public String getEthernetHwaddr(String iface)

获取MAC地址

此外还可以在应用程序中监听如下Intent消息以获取接口和连接状态

public static final String ETHERNET_STATE_CHANGED_ACTION= "https://www.sodocs.net/doc/921470008.html,.ethernet.ETHERNET_STATE_CHANGED";

public static final String EXTRA_ETHERNET_STATE="ethernet_state";

public static final String ETHERNET_IFACE_STATE_CHANGED_ACTION= "https://www.sodocs.net/doc/921470008.html,.ethernet.ETHERNET_IFACE_STATE_CHANGED";

public static final String EXTRA_ETHERNET_IFACE_STATE="ethernet_iface_state"; public static final int ETHER_STATE_DISCONNECTED=0;

public static final int ETHER_STATE_CONNECTING=1;

public static final int ETHER_STATE_CONNECTED=2;

public static final int ETHER_IFACE_STATE_DOWN=0;

public static final int ETHER_IFACE_STATE_UP=1;

此外,以太网相关接口的具体调用,包括静态IP的设置方法等,可参考如下目录中的代码

packages/apps/Settings/src/com/android/settings/ethernet

4.2Android

5.0

Android5.0中google集成了以太网框架代码,具体在:

frameworks/opt/net/ethernet/

客户如果想自己开发以太网设置部分代码,可参考:

src/com/android/settings/EthernetSettings.java

src/com/android/settings/SettingsPreferenceFragment.java

相关主题