Atlas 200外设驱动开发和调试指南_RTL8367 网卡
调试基于Atlas 200 参考板驱动包进行重构调试,调试方法请参考
https://support.huawei.com/enterprise/zh/doc/EDOC1100193743/3db58fa7
1.1 芯片型号
网卡芯片使用SWITCH芯片RTL8367。
1.2 固件烧录
是否需要烧录固件:否
1.3 内核配置
是否需要使能内核配置:否
1.4 驱动调试
是否需要驱动支持:否
1.5 测试工具
RTL8367提供了SDK用于支持芯片的初始化和使用,SDK请找厂家获取。
RTL8367 SDK源码包中包括以下资源:
1. SDK源码
2. 《Realtek_Unmanaged_Switch_API_Document.pdf》
3. 《Realtek_Unmanaged_Switch_ProgrammingGuide.pdf》
4. 《Realtek_Unmanaged_Switch_ReleaseNote.pdf》
此处为完成RTL8367芯片的初始化,主要使用SDK源码API和编程指南
《Realtek_Unmanaged_Switch_ProgrammingGuide.pdf》。
确认硬件设计的管理通道和数据通道
通过开发板的硬件原理图或者硬件开发人员确认,RTL8367 Switch使用的通道如下:
管理通道:MDIO
数据通道:RGMII
控制通道的适配
使用MDIO通道进行rtl8367的控制配置,访问rtl8367的寄存器,需要在smi.c中进行配
置,首先在编译时在MÀfiÃ中必须配置DMDC_MDIO_OPERATION宏,
如:CFLAGS += -DMDC_MDIO_OPERATION
通过硬件确认RTL8367的PHY ID,PHY ID为0或者29,由硬件管脚配置决定,找硬件
确认,当前板子的RTL8367的PHY ID为29,在smi.c中修改宏 MDC_MDIO_PHY_ID的
值为29.
/* fin the PHY ID currently used */
ȅfin MDC_MDIO_PHY_ID 29 /* PHY ID 0 or 29 */
适配寄存器访问函数 smi_write和smi_read,访问的四个步骤已经在示例代码中给出,
但MDC_MDIO_WRITE和MDC_MDIO_READ的实现需要依赖于具体的硬件平台,当前
示例代码中为空代码,需要用户适配。
/* MDC/MDIO, àfinȍ²mÝÃmnì the following Macro */
ȅfin MDC_MDIO_WRITE(preamableLength, phyID, regID, data)
ȅfin MDC_MDIO_READ(preamableLength, phyID, regID, pData)
通过MDIO通道访问寄存器需要实现对应的MDIO驱动的读写方法,目前在已有的Atlas
200 SOC开放源码中已经有MDIO的驱动,结合该MDIO驱动实现MDIO的读写方法。
MDIO驱动中对应的ioctl方法只有两个:MDIO_IO_READ和MDIO_IO_WRITE
在用户态通过ioctl实现mdio的读写方法:
int mdio_write(struct hns_mdio_arg *p_mdio_send);
int mdio_read(struct hns_mdio_arg *p_mdio_read);
数据结构如下:
struct hns_mdio_arg {
unsigned short devaddr;
unsigned short regaddr;
unsigned short value_in;
unsigned short value_out;
};
进一步实现读写方法:
int mdio_8367_dev_read(unsigned int mAddrs, unsigned int *rdVal);
int mdio_8367_dev_write(unsigned int mAddrs, const unsigned int wrData);
使用实现的mdio的读写方法适配API中smi.c中的smi_read和smi_write两个方法,这样
到此打通了控制通道,可以进行初始化配置了。
芯片初始化实现
默认配置会被写入外挂EEPROM,没有EEPROM的设备需要调用初始化接口进行初始
化配置。
SDK的API包中提供了初始化接口rtk_switch_init。
int rtk_rtl8367_switch_init()
{
int ret = 0;
int retryCnt = 0;
while (retryCnt < 3) {
retryCnt++;
ret = rtk_switch_init();
printf("rtk_switch_init %s , ret = %d \n", ((ret == RT_ERR_OK)) ? "success" : "fail",
ret);
if (ret == RT_ERR_OK) {
break;
}
usleep(RTL8367_SLEEP_TIME);
}
return ret;
}
调测和配置数据通道
通过SDK中API进行配置,初始化EXT口
int rtl8367_force_ext_interface()
{
int ret;
rtk_mode_ext_t mode = MODE_EXT_RGMII;
rtk_port_mac_ability_t mac_cfg;
mac_cfg.forcemode = MAC_FORCE;
mac_cfg.speed = PORT_SPEED_1000M;
mac_cfg.duplex = PORT_FULL_DUPLEX;
mac_cfg.link = PORT_LINKUP;
mac_cfg.nway = DISABLED;
mac_cfg.txpause = ENABLED;
mac_cfg.rxpause = ENABLED;
ret = rtk_port_macForceLinkExt_set(EXT_PORT0, mode, &mac_cfg);
if (ret != RT_ERR_OK) {
printf("rtk_port_macForceLinkExt_set failed, ret = %d. \n", ret);
return RT_ERR_FAILED;
}
ret = rtk_port_rgmiiDelayExt_set(EXT_PORT0, 1, 4);
if (ret != RT_ERR_OK) {
printf("rtk_port_rgmiiDelayExt_set failed, ret = %d. \n", ret);
return RT_ERR_FAILED;
}
return RT_ERR_OK;
}
初始化PHY
int rtl8367_init_phy_port()
{
int ret;
ret = rtk_port_phyEnableAll_set(ENABLED);
if (ret != RT_ERR_OK) {
printf("rtk_port_phyEnableAll_set failed, ret = %d. \n", ret);
}
rtk_port_phy_ability_t ability;
(void)memset(&ability, 0x00, sizeof(rtk_port_phy_ability_t));
ability.Full_1000 = 1
#if 0
ability.FC = 1;
ability.AsyFC = 1;
#endif
ret = rtk_port_phyAutoNegoAbility_set(UTP_PORT0, &ability);
if (ret != RT_ERR_OK) {
printf("rtk_port_phyEnableAll_set failed,port is %d, ret = %d. \n", UTP_PORT0, ret);
}
ret = rtk_port_phyAutoNegoAbility_set(UTP_PORT1, &ability);
if (ret != RT_ERR_OK) {
printf("rtk_port_phyEnableAll_set failed,port is %d, ret = %d. \n", UTP_PORT1, ret);
return RT_ERR_FAILED;
}
return RT_ERR_OK;
}
完成初始化工具的实现,编译得到初始化工具rtl8367_init,在系统系统启动后执行初始
化工具进行初始化。
初始化完成后可通过RTL8367网口登陆系统和传输文件。
调试基于Atlas 200 参考板驱动包进行重构调试,调试方法请参考
https://support.huawei.com/enterprise/zh/doc/EDOC1100193743/3db58fa7
1.1 芯片型号
网卡芯片使用SWITCH芯片RTL8367。
1.2 固件烧录
是否需要烧录固件:否
1.3 内核配置
是否需要使能内核配置:否
1.4 驱动调试
是否需要驱动支持:否
1.5 测试工具
RTL8367提供了SDK用于支持芯片的初始化和使用,SDK请找厂家获取。
RTL8367 SDK源码包中包括以下资源:
1. SDK源码
2. 《Realtek_Unmanaged_Switch_API_Document.pdf》
3. 《Realtek_Unmanaged_Switch_ProgrammingGuide.pdf》
4. 《Realtek_Unmanaged_Switch_ReleaseNote.pdf》
此处为完成RTL8367芯片的初始化,主要使用SDK源码API和编程指南
《Realtek_Unmanaged_Switch_ProgrammingGuide.pdf》。
确认硬件设计的管理通道和数据通道
通过开发板的硬件原理图或者硬件开发人员确认,RTL8367 Switch使用的通道如下:
管理通道:MDIO
数据通道:RGMII
控制通道的适配
使用MDIO通道进行rtl8367的控制配置,访问rtl8367的寄存器,需要在smi.c中进行配
置,首先在编译时在MÀfiÃ中必须配置DMDC_MDIO_OPERATION宏,
如:CFLAGS += -DMDC_MDIO_OPERATION
通过硬件确认RTL8367的PHY ID,PHY ID为0或者29,由硬件管脚配置决定,找硬件
确认,当前板子的RTL8367的PHY ID为29,在smi.c中修改宏 MDC_MDIO_PHY_ID的
值为29.
/* fin the PHY ID currently used */
ȅfin MDC_MDIO_PHY_ID 29 /* PHY ID 0 or 29 */
适配寄存器访问函数 smi_write和smi_read,访问的四个步骤已经在示例代码中给出,
但MDC_MDIO_WRITE和MDC_MDIO_READ的实现需要依赖于具体的硬件平台,当前
示例代码中为空代码,需要用户适配。
/* MDC/MDIO, àfinȍ²mÝÃmnì the following Macro */
ȅfin MDC_MDIO_WRITE(preamableLength, phyID, regID, data)
ȅfin MDC_MDIO_READ(preamableLength, phyID, regID, pData)
通过MDIO通道访问寄存器需要实现对应的MDIO驱动的读写方法,目前在已有的Atlas
200 SOC开放源码中已经有MDIO的驱动,结合该MDIO驱动实现MDIO的读写方法。
MDIO驱动中对应的ioctl方法只有两个:MDIO_IO_READ和MDIO_IO_WRITE
在用户态通过ioctl实现mdio的读写方法:
int mdio_write(struct hns_mdio_arg *p_mdio_send);
int mdio_read(struct hns_mdio_arg *p_mdio_read);
数据结构如下:
struct hns_mdio_arg {
unsigned short devaddr;
unsigned short regaddr;
unsigned short value_in;
unsigned short value_out;
};
进一步实现读写方法:
int mdio_8367_dev_read(unsigned int mAddrs, unsigned int *rdVal);
int mdio_8367_dev_write(unsigned int mAddrs, const unsigned int wrData);
使用实现的mdio的读写方法适配API中smi.c中的smi_read和smi_write两个方法,这样
到此打通了控制通道,可以进行初始化配置了。
芯片初始化实现
默认配置会被写入外挂EEPROM,没有EEPROM的设备需要调用初始化接口进行初始
化配置。
SDK的API包中提供了初始化接口rtk_switch_init。
int rtk_rtl8367_switch_init()
{
int ret = 0;
int retryCnt = 0;
while (retryCnt < 3) {
retryCnt++;
ret = rtk_switch_init();
printf("rtk_switch_init %s , ret = %d \n", ((ret == RT_ERR_OK)) ? "success" : "fail",
ret);
if (ret == RT_ERR_OK) {
break;
}
usleep(RTL8367_SLEEP_TIME);
}
return ret;
}
调测和配置数据通道
通过SDK中API进行配置,初始化EXT口
int rtl8367_force_ext_interface()
{
int ret;
rtk_mode_ext_t mode = MODE_EXT_RGMII;
rtk_port_mac_ability_t mac_cfg;
mac_cfg.forcemode = MAC_FORCE;
mac_cfg.speed = PORT_SPEED_1000M;
mac_cfg.duplex = PORT_FULL_DUPLEX;
mac_cfg.link = PORT_LINKUP;
mac_cfg.nway = DISABLED;
mac_cfg.txpause = ENABLED;
mac_cfg.rxpause = ENABLED;
ret = rtk_port_macForceLinkExt_set(EXT_PORT0, mode, &mac_cfg);
if (ret != RT_ERR_OK) {
printf("rtk_port_macForceLinkExt_set failed, ret = %d. \n", ret);
return RT_ERR_FAILED;
}
ret = rtk_port_rgmiiDelayExt_set(EXT_PORT0, 1, 4);
if (ret != RT_ERR_OK) {
printf("rtk_port_rgmiiDelayExt_set failed, ret = %d. \n", ret);
return RT_ERR_FAILED;
}
return RT_ERR_OK;
}
初始化PHY
int rtl8367_init_phy_port()
{
int ret;
ret = rtk_port_phyEnableAll_set(ENABLED);
if (ret != RT_ERR_OK) {
printf("rtk_port_phyEnableAll_set failed, ret = %d. \n", ret);
}
rtk_port_phy_ability_t ability;
(void)memset(&ability, 0x00, sizeof(rtk_port_phy_ability_t));
ability.Full_1000 = 1
#if 0
ability.FC = 1;
ability.AsyFC = 1;
#endif
ret = rtk_port_phyAutoNegoAbility_set(UTP_PORT0, &ability);
if (ret != RT_ERR_OK) {
printf("rtk_port_phyEnableAll_set failed,port is %d, ret = %d. \n", UTP_PORT0, ret);
}
ret = rtk_port_phyAutoNegoAbility_set(UTP_PORT1, &ability);
if (ret != RT_ERR_OK) {
printf("rtk_port_phyEnableAll_set failed,port is %d, ret = %d. \n", UTP_PORT1, ret);
return RT_ERR_FAILED;
}
return RT_ERR_OK;
}
完成初始化工具的实现,编译得到初始化工具rtl8367_init,在系统系统启动后执行初始
化工具进行初始化。
初始化完成后可通过RTL8367网口登陆系统和传输文件。