当前位置:   article > 正文

linux网络开发 rtl8363

rtl8363

记录学习总结,能力有限,仅供参考

rtl8363实现switch

一. 背景知识

A. RTL8363交换芯片的基本信息和功能

1. RTL8363支持:

每个端口都支持全双工
支持IEEE 802.1Q
VLAN支持4096个VLAN和32个额外VLAN
单芯片2+1端口10/100/1000M无阻塞交换机架构嵌入式2端口10/100/1000Base-T
PHY每个端口支持全双工10/100/1000M连接(仅在10/100M模式下支持半双工)

2. RTL8363结构图:
在这里插入图片描述

3. RTL8363框架图:
在这里插入图片描述

B. 相关网络背景知识

1. RTL8363使用的数据接口为rmii (限速100m)
RMII(Reduced Media Independent Interface)是一种常用的以太网物理层接口,用于将以太网 MAC(Media Access Control)层和 PHY(Physical Layer)层连接起来。它通常用于嵌入式系统中,使得系统可以通过以太网进行数据传输。

  • 接口描述:
    RMII接口使用4个信号线进行双向通信,分别是:TXD0、TXD1、RXD0、RXD1。
    此外,还有一些辅助信号线,如:REFCLK(时钟信号)、CRS_DV(冲突检测/数据有效)、MDC(管理数据时钟)和 MDIO(管理数据输入/输出)。
    (rtl8363不同模式接口下TXD0可能为RXD0,注意查看datasheet)

2. SMI管理接口
包括MDC和MDIO两条引脚线。MDIO是一个PHY的管理接口,用来读/写PHY的寄存器,以控制PHY的行为或获取PHY的状态,MDC为MDIO提供时钟。

  • mdio读写协议:
    在这里插入图片描述
    在这里插入图片描述

3. phy和mac
mac媒体访问控制子层协议,处于链路层向下部分
phy即物理层设备,向上对接mac

4. cpu与RTL8363连接模式为:固定模式(mac_to_mac)

  • 固定模式(mac_to_mac)
    mac_to_mac简而言之,需要手动固定一个虚拟phy设备连接。
    在这里插入图片描述

  • phy模式(mac_to_phy)
    在这里插入图片描述

5. RTL8363寄存器
现在datasheet都没有相关寄存器说明,都被提供的api接口封装了。phy id根据mdi高低电位选择。
在这里插入图片描述


二. U-boot下调试rtl8363

  1. 主控芯片arm:sigmastar ssd222d
  2. Linux内核版本:Linux ubuntu 4.4.0-142-generic
  3. 网络文件:mdrv_emac.c
  4. 连接模式:rmii,mac_to_mac

A. U-boot下调试

1.boot下支持

  • 打开RMII支持
    在这里插入图片描述
  • 添加编译rtl8363api库

2. boot下初始化phy设备

  • 实现大体流程:
    board_eth_init()-> MDrv_EMAC_initialize() ->MDrv_EMAC_PhyAddrScan() -> 获取phy_id,初始化phy

3. 虚拟phy设备

  • 由于是mac_to_mac模式,跳过phy相关的操作
    解决思路:虚拟phy设备
    MDrv_EMAC_PhyAddrScan去扫描32个phy_id,在扫描完后将phy_id直接赋值为rtl8363的phy_id ,然后直接return phy_id,初始化rtl8363。后续phy读写所用phy地址都用此phy_id。
  1. //phy扫描
  2. void MDrv_EMAC_PhyAddrScan(void)
  3. {
  4. u32 word_ETH_MAN = 0x00000000;
  5. MHal_EMAC_Write_JULIAN_0100(JULIAN_100_VAL);
  6. ThisUVE.flagISR_INT_DONE = 0x00;
  7. MHal_EMAC_read_phy(phy_id, PHY_REG_STATUS, &word_ETH_MAN);
  8. if((0xffff != word_ETH_MAN)&&(0x0000 != word_ETH_MAN))
  9. {
  10. //printf("phy [%d]=%x\n",phy_id, word_ETH_MAN);
  11. return;
  12. }
  13. for (phy_id = 0; phy_id < 32; phy_id++)
  14. {
  15. MHal_EMAC_read_phy(phy_id, PHY_REG_STATUS, &word_ETH_MAN);
  16. if((0xffff != word_ETH_MAN)&&(0x0000 != word_ETH_MAN))
  17. {
  18. printf("find phy [%d]=%x\n",phy_id, word_ETH_MAN);
  19. return;
  20. }
  21. }
  22. printf("Can't get correct PHY Addr and reset to 0\n");
  23. phy_id = 29;
  24. }
  25. ,,,,,,
  26. //初始化 phy
  27. #ifdef CONFIG_ETHERNET_RTL8363
  28. rtl8363_config_init();
  29. #endif
  30. ,,,,,,
  31. //phy读写 MDC_MDIO_PHY_ID =29
  32. MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP);
  33. MDC_MDIO_READ(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_READ_REG, rData);

4. rtl8363提供的mdio读写api,需要将替换成平台mdio读写接口(smi.c)

  1. /* MDC/MDIO, redefine/implement the following Macro */
  2. #define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) MHal_EMAC_write_phy( MDC_MDIO_PHY_ID, regID, data)
  3. #define MDC_MDIO_READ(preamableLength, phyID, regID, pData) MHal_EMAC_read_phy( MDC_MDIO_PHY_ID, regID, pData)

B. U-boot下问题排查

1. 接口验证
如果上述正常,但是在boot下还是网络不通,先验证rmii和MII管理接口是否正常

  • rmii接口验证:
    mdrv_emac下有打印rmii数据包的接口函数MDrv_EMAC_DumpMem,将MDrv_EMAC_tx接口更换MDrv_EMAC_DumpMem。
    PC使用wireshark软件抓包,如果uboot下发的包与PC端抓的包一致,则通讯正常。
  1. //if (ThisBCE.loopback == PHY_LOOPBACK)
  2. // {
  3. printf("Rx Data");
  4. MDrv_EMAC_DumpMem((u32)packet, 0x40);
  5. // }
  6. // else if (ThisBCE.loopback == MAC_LOOPBACK)
  7. // {
  8. // MDrv_EMAC_tx(nic, (void *)packet, pktlen);
  9. // }
  10. // else
  11. NetReceive((uchar *)packet, pktlen);
  • SMI管理接口
    用示波器查看MDC频率,rmii接口所需时钟频率为50Mhz.
    通过MHal_EMAC_read_phy/MHal_EMAC_write_phy 调用mdio读写数据,用示波器查看波形是否正常. 波形和mdio读写协议进行对比。
    不建议用系统指令去读写寄存器的值,因为没有rtl8363寄存器手册,你也不知道读出多少才是正确的。
    避坑:这里只需验证波形是否和你要写的数据匹配,并不要需要关心是否能真正控制rtl8363,真正读写对应的寄存器是rtl8363提供的api实现。

如果上述接口有问题就需要去排除硬件问题,没有就需要验证代码问题。

  • 在初始化rtl8363必要的硬复位是很有必要的,通过拉低再拉高NRESET脚引脚来硬件复位rtl8363.
  • 根据实际情况配置rtk_macability参数,rmii最高支持100m。
  • 根据datasheeet通过的phy_id修改api提供的读写接口。
    将宏==MDC_MDIO_PHY_ID == datasheeet的phy_id=。

2. rtl8363初始化流程
硬件复位 -> rtk_switch_init(); -> 配置rtk_macability参数 ->end
3. uboot调试总结
建议接触先从uboot下理解phy怎么挂载在网卡上,实现网络互通。再在kernel下实现对rtl8363的开发。
由于是mac_to_mac,不用纠结MDrv_EMAC_PhyAddrScan扫描不到phy,只需理解phy是在mac的向下层,mactomac不经过phy,所以手动虚拟一个phy设备即可。


三. kernel下调试rtl8363

在uboot已经成功实现网络互通上,如果是傻瓜型,那在kernel只需配置引脚复用,在kernel下打开对rmii支持,设备树增加phy设备。即可在网络上互通。

由于需要实现软控制,选择dsa框架来实现。

A. dsa框架知识背景

1. dsa介绍
本质上是在链路层和网络层之间抽象出来的一层逻辑交换机。
2. dsa框架组成

DSA Switch:实现DSA框架的交换机设备。
DSA Master:DSA框架的主控节点,负责管理DSA Switch及其之间的通信,一般是网卡驱动。
DSA Slave:连接到DSA Switch的物理端口,负责转发数据包。
DSA Tag:标记数据包的源和目的信息,指示数据包应该从哪个端口发送和转发>到哪个端口。

3. phy驱动与switch驱动

  • mac_to_phy模式选择phy驱动:
    phy 驱动的核心功能是提供phy初始化接口,自动协商接口,以及状态读取接口(linkup,协商速率,等),不提供控制接口。
  • mac_to_mac模式选择switch驱动:
    switch 驱动核心功能是实现应用层配置vlan ,port等

4. 网络设备角度看
在这里插入图片描述
1703571336498)

B. rtl8363 switch驱动要实现的功能

1. 根据dsa_switch_ops结构体,根据实际需要实现相应接口
.get_tag_protocol:支持tagging协议
.probe:因为是虚拟phy,建议直接rutuen “驱动名”,表示支持该设备。
.setup: 当dsa驱动probe到设备,会调用该setup去配置和初始化设备。
.phy_read/.phy_write: switch的读写函数,根据平台不同去修改api底层接口。
例如:stmmac用的是stmmac_mdio_read,mdrv是MHal_EMAC_read_phy;
在这里插入图片描述

2. 增加attribute_group接口,方便应用层调试
增加一些接口来获取和设置rtl8363的配置。
例如: 获取rtl8363物理端口的连接状态
rtk_port_phyStatus_get
在这里插入图片描述

c. dsa设备树配置

1.设备树配置主要注意的是mdio和dsa的reg

  • mdio: das的dsa,mii-bus一定要和网卡驱动的mdio是一个节点,因为dsa在probe需要同一mdio总线,发现mdio设备,此外dsa是通过这个mdiobus去find到网卡驱动注册的phy设备,否则dsa直接probe失败。
  • switch:可见rlt8363结构图,phy1和phy3接rj45,其余默认配置即可
    在这里插入图片描述

四. dsa的实现流程

A. DSA加载rtl8363 switch驱动

  • dsa多次probe:当内核探测到新设备插入总线时,会遍历已注册的驱动程序列表,并调用与之匹配的驱动程序的probe函数。

1.网卡驱动注册phy流程:
网卡驱动先注册mdio总线,注册总线时会将设备类型和mdio_bus_class关联,关联之后,创建phy绑定总线为mdio总线

  1. MDev_EMAC_init
  2. MDev_EMAC_mii_init
  3. of_mdiobus_register
  4. mdiobus_register
  5. bus->dev.class = &mdio_bus_class; //网络驱动的midobus归属于MDIO总线类设备,简而言之在mdio_bus_class下可以找到emac的mdiobus
  6. mdiobus_scan
  7. get_phy_device //手动返回phyid
  8. phy_device_create // 创建虚拟phy
  9. mdiodev = &dev->mdio;
  10. mdiodev->dev.bus = &mdio_bus_type; //设备总线类型为mdio总线
  11. phy_device_register

在sys文件系统下bus->dev.class = &mdio_bus_class的效果
在这里插入图片描述

在sys文件系统下mdiodev->dev.bus = &mdio_bus_type的效果
在这里插入图片描述

2.dsa probe phy流程:

  1. dsa_probe
  2. dsa_of_probe
  3. mdio_bus = of_mdio_find_bus(mdio);
  4. class_find_device(&mdio_bus_class, NULL, mdio_bus_np,
  5. of_mdio_bus_match); //寻找mdio类设备 本质上判断dsa的bus是否也归属于mdioclass,所以这里需要设备树设置正确
  6. dsa_setup_dst
  7. dsa_switch_setup
  8. dsa_switch_probe
  9. name = ops->probe(parent, host_dev, sw_addr, priv); //调用rtl8363 probe
  10. dsa_switch_setup_one
  11. tag_protocol = ops->get_tag_protocol(ds); //设置tag协议,根据实际情况设置
  12. dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol);
  13. dst->rcv = dst->tag_ops->rcv; //协议回调处理函数
  14. ret = ops->setup(ds); // 调用rtl8363.setup初始化
  15. dsa_slave_create // 创建switch port
  16. dsa_cpu_dsa_setup //
  17. of_phy_find_device //
  18. bus_find_device(&mdio_bus_type, NULL, phy_np, of_phy_match);//在mdio总线下寻找固定连接phy
  19. ds->ops->adjust_link(ds, port, phydev); //cpu port和emac 固定phy建立连接
  20. genphy_update_link //更新链路

在sys文件系统下class_find_device的效果
在这里插入图片描述

在sys文件系统下bus_find_device的效果
在这里插入图片描述

在sys文件系统下mdio_bus_type下所有驱动
在这里插入图片描述

3.大体流程
在这里插入图片描述

B. DSA数据流

网络数据流:

  1. MDev_EMAC_rx
  2. napi_gro_receive
  3. __netif_receive_skb
  4. __netif_receive_skb_core
  5. skb_vlan_untag
  6. type = skb->protocol;// 获取网络数据协议
  7. deliver_ptype_list_skb
  8. deliver_skb
  9. pt_prev->func(skb, skb->dev, pt_prev, orig_dev);//获取协议处理器的处理函数
  10. // 如果switch驱动.get_tag_protocol不为0,那么网络数据会dsa的协议处理器.func = dsa_switch_rcv 处理。
  11. //dsa处理完后又会调napi_gro_receive继续剥离数据heard
  12. napi_gro_receive
  13. ,,,,
  14. ---> 网络层

dsa协议处理器

  1. dsa_switch_setup_one
  2. tag_protocol = ops->get_tag_protocol(ds); // 获取驱动协议
  3. dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol);
  4. ops = dsa_device_ops[tag_protocol]; /*
  5. const struct dsa_device_ops *dsa_device_ops[DSA_TAG_LAST] = {
  6. #ifdef CONFIG_NET_DSA_TAG_DSA
  7. [DSA_TAG_PROTO_DSA] = &dsa_netdev_ops,
  8. #endif
  9. #ifdef CONFIG_NET_DSA_TAG_EDSA
  10. [DSA_TAG_PROTO_EDSA] = &edsa_netdev_ops,
  11. #endif
  12. #ifdef CONFIG_NET_DSA_TAG_TRAILER
  13. [DSA_TAG_PROTO_TRAILER] = &trailer_netdev_ops,
  14. #endif
  15. #ifdef CONFIG_NET_DSA_TAG_BRCM
  16. [DSA_TAG_PROTO_BRCM] = &brcm_netdev_ops,
  17. #endif
  18. #ifdef CONFIG_NET_DSA_TAG_QCA
  19. [DSA_TAG_PROTO_QCA] = &qca_netdev_ops,
  20. #endif
  21. [DSA_TAG_PROTO_NONE] = &none_ops,
  22. };*/
  23. dst->rcv = dst->tag_ops->rcv;// 获取协议处理函数

DSA数据流和控制流图
在这里插入图片描述

五. dsa的使用

A. 应用层控制实例

B. 内核实现

相关资料链接:
【网络BSP开发经验】交换芯片驱动开发1(RTL8306MB交换芯片驱动开发)
https://blog.csdn.net/yy197696/article/details/129571370
//kernel dsa文档
https://www.kernel.org/doc/html/v5.15/networking/dsa/dsa.html
Linux 5.4内核Distributed Switch Architecture » Architecture翻译
https://blog.csdn.net/u010687717/article/details/124857859
网口扫盲二:Mac与Phy组成原理的简单分析
https://www.cnblogs.com/jason-lu/p/3196096.html
linux phy fixed-link
https://blog.csdn.net/u014044624/article/details/130670398?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-130670398-blog-124857859.235v38pc_relevant_default_base3&spm=1001.2101.3001.4242.1&utm_relevant_index=3
一文搞懂 Linux 网络 Phy 驱动
https://cloud.tencent.com/developer/article/2355036?from=15425
ARM与交换芯片mac_to_mac固定模式总结
https://blog.csdn.net/newbee_sccc/article/details/126266772
设备树 phy节点 使用说明
https://blog.csdn.net/weixin_45647912/article/details/108975862
phy 驱动与 switch 驱动
https://blog.csdn.net/agave7/article/details/106519019
Linux DSA Net Switch驱动开发
https://blog.csdn.net/Zhu_Zhu_2009/article/details/108654578
Linux 内核:设备驱动模型(3)class与device
https://www.cnblogs.com/schips/p/linux_device_model_3.html
以太网驱动的流程浅析(五)-mii_bus初始化以及phy id的获取
https://www.cnblogs.com/sky-heaven/p/11942921.html
STMMAC驱动
https://blog.csdn.net/qq_41076734/article/details/129163748
第十六章PHY -基于Linux3.10
https://blog.csdn.net/shichaog/article/details/44682931
linux驱动_sigmastar_SSD202D网络驱动简析
https://blog.csdn.net/gavinpeng/article/details/127104218
linux内核网络协议栈–netif_receive_skb()函数(八)
https://blog.csdn.net/qq_20817327/article/details/106752029

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/311926?site
推荐阅读
相关标签
  

闽ICP备14008679号