随着嵌入式系统设备的广泛应用, 当设备需要与多个网络设备交互数据时, 需要设备具有多网口、多连接的功能, 同时能够解析应用规约[1]. 目前大部分对TMS320C6678处理器的应用场景下, 都要求网卡工作在switch模式, 这样两个slave 端口始终接收到相同的数据. 所以不论是TI提供的keystone架构下的网卡参考驱动, 还是互联网上能搜索到的关于此网卡的驱动开发, 都是关于switch模式的. 随着TMS320C6678处理器的广泛应用, 越来越多的场景需要使用双网卡模式, 即port1和port2作为两个独立的网卡使用, 分别与不同的设备连接完成不同的功能, 这就需要研究基于TMS320C6678的双网卡驱动实现.
本文从网卡模块简介、驱动原理分析、驱动设计实现以及驱动测试等多个方面介绍了基于TMS320C6678的双网卡的原理和实现, 对TI keystone架构下的多种DSP处理器的双网卡模式的实现都具有参考和借鉴意义, 能极大的扩展该系列处理器的应用范围.
2 TMS320C6678处理器的网卡介绍TMS320C6678处理器基于KeyStone I架构, 片上集成了一个网络协处理器NETCP, NETCP由千兆以太网交换子系统、包加速器PA (Packet Accelerator)和安全加速器SA (Security Accelerator Engine)组成[2]. PA负责数据包的分类操作和修改操作, SA负责数据包的加密和解密, 交换子系统由三端口网络交换机、MDIO模块和SGMII模块组成, 其组成框图如下[3]:
系统中三端口网络交换机的host port(即port0)负责交换机与网络协处理器NETCP之间的通信, 两个slave port(即port1和port2)分别与两个SGMII模块相连, 负责交换机与SGMII之间的数据传输. NETCP与主机之间的数据传输由PKTDMA完成.
交换机主要由以下模块组成: 流媒体数据接口、MAC控制器、MAC接收FIFO、信息统计模块、时间同步模块和ALE模块.
流媒体数据接口包括发送流媒体数据接口和接收流媒体数据接口. 发送流媒体数据接口负责将数据包从port 0传输到NETCP, 交换机有两个相同的发送流媒体数据接口(TXA和TXB), 其中TXA输出从port1传给port0的数据包, TXB输出从port2传给port0的数据包. 接收流媒体数据接口负责接收来自于NETCP内的数据[3].
MAC控制器不仅负责完成交换机与SGMII模块之间的信号转换, 还负责与IEEE802.3以太网帧相关的操作; MAC接收FIFO供数据传输时使用; 信息统计模块用来记录三个端口数据收发的情况, 便于网络调试; 时间同步模块的主要用途是检测时间同步事件并生成时间戳, 然后将此信息提供给主机软件进行处理.
ALE模块处理所有接收的包, 确定每个包被发往哪个端口. 当ALE非能时, 所有数据包都被丢弃. 当ALE工作在bypass模式时, MAC模块接收的所有数据包都只给port0, port0可以发送定向包给port1或者(和)port2.
3 双网卡模式下的驱动实现 3.1 驱动原理多核导航器是Keystone架构的核心组成部分. 多核导航器使用队列管理子系统(Queue Manager SubSystem, QMSS)和打包DMA(PKTDMA)来控制和完成高速数据包在设备内的传输. NETCP与主机之间的数据传输由PKTDMA完成, PKTDMA处理的数据是以描述符的形式存在的, 描述符存在于队列中, 由QMSS的PDSP固件完成队列中描述符的操作. 当网卡硬件初始化完成后, 主机发送数据时, 从发送空闲队列分配一个描述符, 填写描述符域和负载数据后, 将描述符PUSH到发送队列, 队列管理器为队列提供一个层敏感(level sensitive)状态信号量, 负责DMA的调度操作, DMA控制器最终引入相应通道的上下文, 并且开始处理包. DMA控制器通过将数据块中的内容传输出去的方式, 来清空缓冲区. 根据包大小域中指定的大小, 包中的数据全部传输完之后, DMA会将包描述符的指针写到队列中, 这个队列在返回队列管理(包描述符的返回队列数目域)中被指定, 通常指定为发送空闲队列便于以后发送数据时使用. 当Rx DMA给定的通道上开始一个包接收操作时, 这个端口会从接收空闲队列中取出一个描述符, 将数据写入描述符对应的缓存中. 当整个包被接收之后, PKTDMA 将包描述符指针写入相应的接收完成队列, 用户处理完接收数据包后, 将描述符重新PUSH到接收空闲队列供PKTDMA下次接收使用.
主机发送数据时, 接收流媒体数据接口能够从接收的将要发送给以太网交换机的描述符的PS_FLAGS字段中提炼出额外的控制信息. 该字段的说明如表1所示.
从表1可看出, 可以在发送描述符的PS_FLAGS字段中设置端口号从而将数据包定向发送给交换机的某个端口, 前提是ALE必须工作在bypass模式.
数据接收时, 不论port1还是port2接收到数据都会传输到port0, 通过发送流媒体数据接口传输到NETCP, 其中来自port1的数据通过TXA传输, 来自port2的数据通过TXB传输. TXA和TXB不仅传输数据包, 还提供了一些额外信息, 这些信息由PKTDMA的接收flow控制. 接收flow的配置寄存器C的部分字段描述如表2所示.
Host packet描述符的字段描述见表3.
从表2和表3可以看出, 如果将网卡接收flow的配置寄存器C的bit26-24(RX_SRC_TAG_LO_SEL)设置成4, 则当端口接收到数据时, PKTDMA控制器会将接收描述符的word1的source tag-lo字段设置成该端口的SRC_ID值, 两个slave端口的SRC_ID值是不同的. 网卡接收到数据时, 根据接收描述符的word1的source tag-lo字段的值就可判断出该数据包来自哪个端口.
3.2 驱动实现
为了实现TMS320C6678的双网卡驱动, 需要完成硬件初始化、数据包的发送和接收等功能. 尤其是要解决好下面两个问题: 数据包发送时, 交换机内部的接收流媒体数据接口需要知道它从NETCP接收的数据将要发给哪个端口; 接收到数据包后, 驱动需要根据接收的数据包判断其来自哪个端口.
(1) 网卡硬件初始化
这里需要完成跟网卡工作相关的所有硬件的初始化, 包括:
a) 多核导航器的初始化
多核导航器由队列管理器、PKTDMA、导航云、打包数据结构协处理器(Packed-Data Structure Processors, PDSP)固件等模块组成[4]. 初始化时, 主要完成PDSP固件的下载和执行.
b) memory region的初始化
完成网卡工作时使用的描述符区间的初始化工作, 包括描述符的起始地址、大小、数量、使用的内存区域的序号等的初始化.
c) 描述符的初始化
由于数据在NETCP与主机之间的传输由PKTDMA完成, 数据包需要封装成PKTDMA能够识别的描述符格式. 驱动中使用了host packet描述符的格式.
从已经初始化的memory region中分配一定数量的发送空闲描述符和接收空闲描述符, 并为每个描述符分配buffer地址空间, 所有的发送空闲描述符被PUSH到发送空闲队列, 所有的接收空闲描述符被PUSH到接收空闲队列. 两个网卡具有不同的描述符地址和不同的发送接收空闲队列号.
d) SGMII_SERDES初始化
依次配置PLL寄存器, 两个端口的发送配置和接收配置寄存器.
e) SGMII模块初始化
配置两个端口的连接模式(master或者slave)、工作模式(全双工或半双工)、连接速度、是否自动协商等.
f) MAC初始化
设置MAC地址, 虽然器件的MAC地址只有一个, 但是可以虚拟一个出来, 确保两个端口分别配置了不同的MAC地址, 除此之外, 还配置了VLAN和接收帧的最大长度.
g) 三端口交换机switch初始化
完成端口0的使能启动、网卡统计功能的配置(便于调试)以及ALE (Address Lookup Engine)的配置等, 这里需要注意的是, 双网卡模式时, ALE必须工作在bypass模式.
由于需要通过接收描述符中的SRC_ID判断接收数据的来源, 所以分别为port1和port2设置SRC_ID值. port1和port2的SRC_ID值即TXA_SRC_ID和TXB_SRC_ID, 可通过设置寄存器P0_CPPI_SRC_ID来设置.
h) cppi初始化
完成网卡的发送通道和接收通道的使能, 接收Flow ID、接收空闲队列和接收完成队列的配置等.
i) PA子系统初始化
完成PA固件下载、广播和组播路由配置、添加MAC地址到PA PDSP查找表等工作.
j) 接收flow初始化
完成Rx DMA的接收完成队列、接收空闲队列、描述符类型等的配置, 需要注意配置寄存器C的RX_SRC_TAG_LO_SEL字段要设置成4.
(2) 数据包发送
从发送空闲队列分配一个描述符, 填写描述符域和负载数据, 注意在描述符word2的Protocol Specific Flags字段中指定数据包发给哪个端口, 然后将描述符PUSH到发送队列, PKTDMA将将数据包直接发送给指定的端口.
(3) 数据包接收
当PKTDMA的接收完成队列接收到数据后会产生接收完成中断, 在中断服务程序中, 根据接收描述符word1的source tag-lo字段的值即可判断出数据的来源, 从而做出正确处理.
3.3 驱动测试如果TMS320C6678开发板上的两个网络端口都通过RJ45接口引出来了, 那么就把它们当作两个独立的普通网卡, 分别进行测试验证即可. 但是实际上有很多DSP6678开发板的网口只引出来了一个, 在使用中另一个端口通过特定的背板与其他以太网设备进行通信. 这里以TIC6678公板为例重点介绍只引出一个网络端口的情况下的双网卡测试方法.
TIC6678公板的网卡0没有通过RJ45接口引出来, 只引出了网卡1, 通过配套的背板可以将两块公板的网卡0对连起来. 当两条链路都能正常通信时, 表明双网卡能正常工作了. 具体有以下两种测试方法:
(1) 两块公板的网卡1分别与两台PC机相连
分别为两块公板的两个网卡设置不同网段的IP地址, 并分别与两台PC机相连, IP的具体要求以及整个测试系统的连接如图2所示.
当同时满足以下测试结果时, 表明两块公板的双网卡均工作正常.
a) PC机1可以ping通公板1的网卡1, PC机1不能ping通公板2的两个网卡;
b) PC机2可以ping通公板2的网卡1, PC机2不能ping通公板1的两个网卡;
c)公板1 ping不通公板2的网卡1, 公板2 ping不通公板1的网卡1;
d) 两块公板的网卡0互相可以ping通.
(2) 两块公板的网卡1互连
当两块公板的网卡1互相可以ping通, 网卡0互相可以ping通, 但是一块板子的网卡1和另一块板子的网卡0 ping不通时, 则双网卡工作正常.
3.4 测试结果按照图2的IP要求配置了通过背板连接的两块TIC6678开发板的网卡, 并将它们的网卡1通过网线互连, 网卡1互相可以ping通, 网卡0互相可以ping通, 测试结果如图3和图4所示.
断开两块公板的网卡1之间的网线, 双网卡模式下网卡1的网络连接就断了, 测试结果如图5和图6所示.
测试结果表明本文实现的基于TMS320C6678的双网卡驱动工作正常. 双网卡工作模式目前已在多个项目中投入使用.
4 结论
测试结果以及实际应用情况表明, 本文设计的基于TMS320C6678的双网卡驱动是成功的, 该功能的实现使得TI KEYSTONE 1架构下的DSP芯片的应用范围更加广泛而不仅仅局限于switch模式下的应用场景.
[1] |
徐业荣, 包明磊, 李明. 一种基于LwIP协议栈的双网口通信方案设计. 计算机应用与软件, 2016, 33(9): 127-129, 198. DOI:10.3969/j.issn.1000-386x.2016.09.030 |
[2] |
邓豹. TI6678多核DSP以太网接口的设计与实现. 航空计算技术, 2017, 47(4): 130-134. DOI:10.3969/j.issn.1671-654X.2017.04.032 |
[3] |
KeyStone architecture gigabit ethernet (GbE) switch subsystem user guide. SPRUGV9C. 2013.
|
[4] |
KeyStone architecture multicore navigator user’s guide. SPRUGR9G. 2013.
|