2021-02-22

jacinto 内核驱动 – 3

3.2.2.8.2 公共平台时间同步(CPTS)模块
a可以通过Kconfig选项CONFIG_TI_AM65_CPTS或menuconfig工具来启用对CPTS模块的支持。只有一个CPSW端口可以开启点到点报文的时间戳功能。
当CPTS模块启用时,它将导出特定时钟驱动程序的内核接口和PTP时钟API用户空间接口,并启用对SIOCSHWTSTAMP and SIOCGHWTSTAMP套接字ioctls的支持。PTP将PHC公开为一个带有标准化ioctls的字符设备,通常可以在path中找到:

/dev/ptpN

支持的PTP硬件时钟功能:
基本时钟操作
-设定时间
-获取时间
-按给定的偏移量自动调整时钟
-调整时钟频率
辅助时钟功能
-时间戳外部事件
-可从用户空间配置的周期性输出信号
-通过PPS子系统同步Linux系统时间
SIOCSHWTSTAMP and SIOCGHWTSTAMP的支持参数:

SIOCSHWTSTAMP
   hwtstamp_config.flags = 0
   hwtstamp_config.tx_type
       HWTSTAMP_TX_ON -使能出方向报文的硬件时间戳
       HWTSTAMP_TX_OFF -没有发送的数据包需要硬件时间戳
   hwtstamp_config.rx_filter
       HWTSTAMP_FILTER_NONE -时间戳根本没有传入数据包
       HWTSTAMP_FILTER_ALL - time stamp any incoming packet
启用时的CPTS PTP数据包时间戳默认配置(SIOCSHWTSTAMP):
CPSW_PN_TS_CTL_REG
   TS_MSG_TYPE_EN = 0xF (Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp.)
   TS_TX_ANNEX_F_EN = 1
   TS_TX_ANNEX_E_EN = 1
   TS_TX_ANNEX_D_EN = 1
   TS_TX_VLAN_LTYPE1_E = 1
CPSW_PN_TS_CTL_LTYPE2_REG
   TS_TTL_NONZERO = 1
   TS_320 = 1
   TS_319 = 1
   TS_132 = 1
   TS_131 = 1
   TS_130 = 1
   TS_129 = 1
   TS_107 = 1
   TS_LTYPE1 = 0x88F7 (ETH_P_1588)
CPSW_PN_TS_SEQ_LTYPE_REG
   TS_SEQ_ID_OFFSET = 0x1e
   TS_LTYPE1 = 0x88F7 (ETH_P_1588)
CPSW_PN_TS_VLAN_LTYPE_REG
   TS_VLAN_LTYPE1 =  0x8100 (ETH_P_8021Q)

有关PTP时钟API和网络时间戳的更多信息,请参阅Linux内核文档Documentation/ptp/ptp.txt
include/uapi/linux/ptp_clock.h
Documentation/ABI/testing/sysfs-ptp
Documentation/networking/timestamping.txt
Documentation/pps/pps.txt

代码示例和工具:

tools/testing/selftests/ptp/testptp.c
tools/testing/selftests/networking/timestamping/timestamping.c

开源项目linuxptp
Linux PPS工具
使用linuxptp项目中的ptp4l工具进行测试
要使用ptp协议检查ptp时钟调整,需要在不同的设备(EVM或PC)上运行ptp从(客户端)和ptp主(服务器)应用程序。开源应用程序包linuxptp既可以用作从应用程序包,也可以用作主应用程序包。因此,可以延迟TX时间戳的生成(特别是对于低速链路),需要设置ptp4l“tx_timestamp_timeout”参数才能使ptp4l工作。
•创建文件ptp.cfg,内容如下:

 [global]
tx_timestamp_timeout     400

•使用“-f”选项将配置文件传递给ptp4l:

ptp4l -E -2 -H -i eth0  -l 6 -m -q -p /dev/ptpN -f ptp.cfg

•从端示例
可以使用以下命令在从属模式的evm上运行ptp-over-L4客户机

./ptp4l -E -4 -H -i eth0 -s -l 7 -m -q -p /dev/ptpN

对于ptp-over-L2客户端,使用此命令

./ptp4l -E -2 -H -i eth0 -s -l 7 -m -q -p /dev/ptpN

•主侧示例
ptp4l也可以在主模式下运行。例如,以下命令使用硬件时间戳在EVM上启动ptp4l-over-L2主机

./ptp4l -E -2 -H -i eth0 -l 7 -m -q -p /dev/ptpN

在不支持硬件时间戳的Linux PC上,下面的命令使用软件时间戳启动ptp4l-over-L2主机.

./ptp4l -E -2 -S -i eth0 -l 7 -m -q

从Linux内核使用testptp工具进行测试
•获取ptp时钟时间

# testptp -d /dev/ptpN -g
clock time: 1493255613.608918429 or Thu Apr 27 01:13:33 2017

•查询ptp时钟的功能

# testptp -d /dev/ptpN -c
capabilities:
  10000000 maximum frequency adjustment (ppb)
  0 programmable alarms
  4 external time stamp channels
  2 programmable periodic signals
  1 pulse per second
  0 programmable pins
  0 cross timestamping

•cpts参考频率的健全性测试
testptp -g调用之间的时间差应该等于睡眠时间

# testptp -g -d /dev/ptpN && sleep 5 && testptp -g -d /dev/ptpN
clock time: 1493255884.565859901 or Thu Apr 27 01:18:04 2017
clock time: 1493255889.611065421 or Thu Apr 27 01:18:09 2017

•将ptp时钟时间移动“val”秒

# testptp -g -d /dev/ptpN && testptp -t 100 && testptp -g -d /dev/ptpN
clock time: 1493256107.640649117 or Thu Apr 27 01:21:47 2017
time shift okay
clock time: 1493256207.678819093 or Thu Apr 27 01:23:27 2017

•将ptp时钟时间设置为“val”秒

# testptp -g -d /dev/ptpN && testptp -T 1000000 && testptp -g -d /dev/ptpN
clock time: 1493256277.568238925 or Thu Apr 27 01:24:37 2017
set time okay
clock time: 100.018944504 or Thu Jan  1 00:01:40 1970

•通过“val”ppb调整ptp时钟频率

# testptp -g -d /dev/ptpN && testptp -f 1000000 && testptp -g -d /dev/ptpN
clock time: 151.347795184 or Thu Jan  1 00:02:31 1970
frequency adjustment okay
clock time: 151.386187454 or Thu Jan  1 00:02:31 1970

使用时间戳外部事件的示例
外部事件的时间戳可以使用testptp工具进行测试。在测试正确的CPTS信号路由之前,必须使用DT中的timesync路由器。
例如,GENF0的输出可以路由到HW3_TS_PUSH_EN输入。首先需要用以下更改重建内核

#define TS_OFFSET(pa, val)     (0x4+(pa)*4) (0x80000000 | val)

&timesync_router {
   pinctrl-names = "default";
   pinctrl-0 = <&mcu_cpts>;

       /* Example of the timesync routing */
           mcu_cpts: mcu_cpts {
                   pinctrl-single,pins = <
                           /* pps [cpts genf0] in12 -> out24 [cpts hw4_push] */
                           TS_OFFSET(24, 12)
                   >;
           };
};

然后执行:

# testptp -d /dev/ptpN -p 500000000 -i 0
# testptp -d /dev/ptpN -e 100 -i 2
event index 2 at 384.250000025
event index 2 at 384.750000025
event index 2 at 385.250000025
event index 2 at 385.750000025

PPS每秒脉冲支持
默认情况下,通过将GENF1输出连接到HW3_TS_PUSH_EN输入,在TI SDK中实现并启用对J721E的PPS支持:

k3-am654-base-board.dts
#define TS_OFFSET(pa, val)     (0x4+(pa)*4) (0x80000000 | val)

&timesync_router {
       pinctrl-names = "default";
       pinctrl-0 = <&mcu_cpts>;

       /* Example of the timesync routing */
       mcu_cpts: mcu_cpts {
              pinctrl-single,pins = <
                     /* pps [cpts genf1] in13 -> out25 [cpts hw4_push] */
                     TS_OFFSET(25, 13)
              >;
       };
};

&mcu_cpsw {
       ...
       cpts {
              ti,pps = <3 1>;
       };
};

启用后,可以使用testptp和ppstest工具测试PPS:

# ./testptp -d /dev/ptp1 -P 1
pps for system time request okay
# ./ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 198.000000700, sequence: 7 - clear  0.000000000, sequence: 0
source 0 - assert 199.000000700, sequence: 8 - clear  0.000000000, sequence: 0

TI AM65x交换机配置工具
TI处理器SDK包含jacinto7开关配置工具的预编译正确版本。
J721E SoC的TI Jacinto 7交换机配置工具源可在以下位置找到:

git@git.ti.com:switch-config/switch-config.git
branch:
origin/am65x-v1.0
Usage:
# switch-config -h
Switch configuration commands.....
switch-config -I,--ndev <dev> <command>

commands:
switch-config -d,--dump-ale :dump ALE table
switch-config -D,--dump=<0..9> :dump registers (0 - all)
switch-config -v,--version

dump values:
 :1 - cpsw-nuss regs
 :2 - cpsw-nuss-rgmii-status regs
 :3 - cpsw-nuss-mdio regs
 :4 - cpsw-nu regs
 :5 - cpsw-nu-p0 regs
 :6 - cpsw-nu-p1 regs
 :7 - cpsw-nu-cpts regs
 :8 - cpsw-nu-ale regs
 :9 - cpsw-nu-ale-tbl regs
Example, ALE table dump:
# switch-config -d
K3 cpsw dump version (1) len(6328)
ALE table dump ents(64):
0   : type: vlan , vid = 0, untag_force = 0x3, reg_mcast = 0x0, unreg_mcast = 0x0, member_list = 0x3
1   : type: ucast, addr = f4:84:4c:eb:a0:00, ucast_type = persistant, port_num = 0x0, Secure
2   : type: mcast, addr = ff:ff:ff:ff:ff:ff, mcast_state = f, no super, port_mask = 0x3
3   : type: mcast, addr = 01:00:5e:00:00:01, mcast_state = f, no super, port_mask = 0x3
4   : type: mcast, addr = 01:80:c2:00:00:00, mcast_state = f, no super, port_mask = 0x3
5   : type: mcast, addr = 01:80:c2:00:00:03, mcast_state = f, no super, port_mask = 0x3
6   : type: mcast, addr = 01:80:c2:00:00:0e, mcast_state = f, no super, port_mask = 0x3
8   : type: mcast, addr = 01:00:5e:00:00:fc, mcast_state = f, no super, port_mask = 0x3
9   : type: ucast, vid = 0, addr = 9c:b6:d0:89:0d:85, ucast_type = touched   , port_num = 0x1
26  : type: ucast, vid = 0, addr = c4:71:54:a9:6e:b4, ucast_type = touched   , port_num = 0x1
27  : type: ucast, vid = 0, addr = 00:25:22:a9:4c:b3, ucast_type = touched   , port_num = 0x1
Example, CPTS registers dump:
switch-config -D7
K3 cpsw dump version (1) len(6328)
cpsw-nu-cpts regdump: num_regs(38)
0003d000:reg(4E8A2109)
0003d004:reg(00000C21)
0003d008:reg(00000000)
0003d00c:reg(00000000)
0003d010:reg(7EA3BA9B)
0003d014:reg(00000000)
0003d018:reg(00000000)
0003d01c:reg(00000000)
0003d020:reg(00000000)
0003d024:reg(00000000)
0003d028:reg(00000001)
0003d02c:reg(00000000)
0003d030:reg(00000000)
0003d034:reg(C7298A99)
0003d038:reg(03300000)
0003d03c:reg(00000000)
0003d040:reg(0000028E)
0003d044:reg(00000000)
0003d048:reg(00000000)

3.2.2.8.3. 预定流量(EST)卸载的改进
IEEE 802.1Qbv/D2.2调度业务增强(EST),以前称为时间感知整形器(TAS),是对802.1Q标准中定义的传输选择算法的增强。它正式成为802.1Q-2018版标准的一部分。根据标准,网桥或终端站可以支持增强功能,该增强功能允许相对于已知时间尺度来调度来自每个队列的传输。为了实现这一点,传输门与每个队列相关联;传输门的状态决定是否可以选择队列帧进行传输。对于给定队列,传输门可以处于以下两种状态之一:
•开放:根据与队列相关联的传输选择算法的定义,选择排队帧进行传输。
•关闭:未选择排队帧进行传输。
在Linux中,EST/TAS卸载到硬件是使用taprio卸载实现的。时间感知优先级整形器(TAPRIO)TAPRIO是一个qdisc,它实现了IEEE 802.1Q-2018第8.6.9节定义的调度状态机的简化版本,允许配置一系列门状态,其中每个门状态允许出站流量的子集(可能为空)。EST是使用tc命令配置的。有关命令语法和说明的详细信息,请参阅手册页TAPRIO
CPSW2g h/w支持EST配置或卸载。EST通过tc命令进行配置,如上述手册页所述。用户在命令中指示“flag 2”,然后由net core中的taprio scheduler解析,并指示命令将卸载到h/w。taprio然后通过调用ndo_setup_tc() ndo ops将命令卸载到驱动程序。

当前驱动程序只支持SetGateStates操作。EST以CPTS EST函数生成器生成的重复时间间隔运行。每个以太网端口都有一个全局EST fetch RAM,可以配置为2个缓冲区,每个缓冲区有64个位置,或者一个大缓冲区有128个位置。在2缓冲区配置中,乒乓机制用于在一个缓冲区中保存活动计划(oper),在另一个缓冲区中保存新的(admin)命令。每个22位fetch命令由一个14位fetch计数(14 MSB)和一个8位优先级fetch allow(8 LSB)组成,后者将应用于有线时钟中的fetch计数时间。驱动程序处理offload命令中的每个sched条目并更新fetchram。驱动程序将sched条目中的duration配置为fetch count,并将Gate mask配置为RAM的优先级fetch位。然后配置CPTS EST函数生成器以激活计划。由于驱动程序使用2个缓冲区配置来获取ram,因此最大循环时间约为8毫秒(64*128 usec)。
CPSW2g支持可配置的优先队列数量(最多可配置8个),在配置EST之前需要从默认轮询模式切换到该模式。用户通过ethtool命令配置: - -L用于更改队列数,–set-priv-flags用于禁用轮询模式。如果设置了pf_p0_rx_ptype_rrobin privat标志,驱动程序不会启用EST。该标志对所有端口都是通用的,所以不能被taprio配置覆盖,而没有用户参与。如果pf_p0_rx_ptype_rrobin已经在驱动中设置,则命令执行失败。还要注意–set-priv-flags ethtool只能在以太网接口down时执行。因此,执行ethtool命令前,请先执行ifconfig down或类似的命令
调度(命令)配置取决于接口速度,所以驱动程序将持续时间转换为基于链接速度的获取计数。根据时间间隔,每个调度都可以用fetch RAM中的几个命令条目来构造。例如,如果每个调度在1G链路上的计时器间隔小于128us,则每个调度使用一个命令并具有1:1映射。当以太网链路断开时,如果链路断开超过1秒,驱动程序将清除配置。
调度示例
给出了一个包含3个调度条目的配置示例下图:-
•使用3个队列(Q0-Q2)。每个Q都有一个与h/w关联的门。最多支持8个队列/门
•为125usec(Q1和Q2)打开2个高优先级门,每个门大约10个数据包
•Q7是最高优先级队列,Q0是最低优先级队列
•1个较低优先级(Q0)为250 usec打开剩余的门
以下是配置此计划的步骤。
#设置接口和队列配置

ip link set dev eth0 down
ethtool -L eth0 tx 3

#禁用 rrobin

ethtool --set-priv-flags eth0 p0-rx-ptype-rrobin off

打开eth0接口

ip link set dev eth0 up

#设置3个门的EST时间表(Q0-Q2)。有关命令参数的说明,请参阅taprio的手册页。

#TC0<->Q0、TC1<->Q1和TC2<->Q2
tc qdisc replace dev eth0 parent root handle 100 taprio \
   num_tc 3 \
   map 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 \
   queues 1@0 1@1 1@2 \
   base-time 0000 \
   sched-entry S 4 125000 \
   sched-entry S 2 125000 \
   sched-entry S 1 250000 \
   flags 2
#其中num_tc等于number of queues = 3,map,将16个优先级映射到3个TCs中的一个,queues指定
#与每个TC关联的队列,TC0-一个队列@0,TC1-一个队列@1和TC2-一个队列@2
#sched条目S 4 125000
# S - SetGateStates操作
#4位掩码显示位2设置(Q2/TC2)
# 125000 - 125000个nsec (125 usecs)门打开的时间
#循环时间为500毫秒

#启用分类器。分类器用于根据数据包元数据对数据包进行标记。例如UDP端口
#数字
tc qdisc add dev eth0 clsact

#使用tc filter命令编辑基于udp端口号的SKB优先级。即Udp端口5003. i.e Udp port 5003 -> prio 3 (TC2/Q2), port 5002 -> prio 2 (TC1/Q1),  5001 -> prio 1( TC0/Q0)
tc filter add dev eth0 egress protocol ip prio 1 u32 match ip dport 5003 0xffff action skbedit priority 3
tc filter add dev eth0 egress protocol ip prio 1 u32 match ip dport 5002 0xffff action skbedit priority 2
tc filter add dev eth0 egress protocol ip prio 1 u32 match ip dport 5001 0xffff action skbedit priority 1

#网络核心和驱动程序使用skb优先级将帧传送到特定的h/w队列。在上述情况下,
#优先级3 SKB(数据包)转到Q2(tc qdisc命令中map中的第4个条目),优先级2 SKB转到Q1
#(map中的第三个条目)和优先级1 SKB转到Q0(map中的第二个条目)

#运行3个iperf会话,每个会话的udp端口为5001、5002和5003
#远程PC连接到eth0,IP地址为192.168.2.10
iperf3 -s -i30 -p5001&
iperf3 -s -i30 -p5002&
iperf3 -s -i30 -p5003&

#在DUT,使用iperf3开始传输流
ip addr add 192.168.2.20/24 dev eth0
ip link set dev eth0 up
iperf3 -c 192.168.2.10 -u -b100M  -p 5003 -l1472 -t10 -i5&
iperf3 -c 192.168.2.10 -u -b100M  -p 5002 -l1472 -t10 -i5&
iperf3 -c 192.168.2.10 -u -b100M  -p 5001 -l1472 -t10 -i5&

#在PC上使用wireshark捕获帧以查看EST的工作方式。帧只在wire上。
#计划时间和周期性的帧突发将每500毫秒出现一次。

下面显示了上述示例的wireshark捕获示例

高亮显示的数据包是Q2/TC2门打开期间传输的第一个数据包,间隔约500毫秒,这是TAS计划的周期时间。在Gate打开的时间间隔为125 usec内,在窗口内大约有9个数据包被传输,约为12 * 9 = 108 usec。
Guard band
CPSW2g EST H/W将在门打开期间传输帧。如果一个帧恰好在Gate关闭之前到达h/w队列,那么它将溢出到下一个调度窗口。如果这不是期望的,则用户可在调度窗口之间添加保护带,其持续时间应等于MTU帧的传输时间(1518×8=12144纳秒)+2336纳秒(TRM将其描述为292线时钟=292×8=2336)。这样可以确保帧不会散落到下一个sched窗口。例如,对于上面描述的示例时间表,为了确保没有溢出,可以引入保护带作为示例如下所示:-

tc qdisc replace dev eth0 parent root handle 100 taprio \
   num_tc 3 \
   map 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 \
   queues 1@0 1@1 1@2 \
   base-time 0000 \
   sched-entry S 4 110520 \
   sched-entry S 0 14480  \
   sched-entry S 2 110520 \
   sched-entry S 0 14480  \
   sched-entry S 1 235520 \
   sched-entry S 0 14480  \
   flags 2

标志2
上述调度仍然具有500毫秒的周期时间,但是在12144 usec期间在栅极关闭/打开之间插入了保护带并且使用0栅极掩模。
循环时间
在前面描述的示例调度中,有3个由sched entry描述的调度窗口,前2个窗口分别是125 usec和250 usec的三分之一。因此,调度有一个500毫秒的周期时间,它是各个调度间隔的总和。tc命令还允许用户将周期时间指定为命令的一部分,该命令可用于截断或拉伸条目。例如,在典型计划中,如果用户指定周期时间为600000

tc qdisc replace dev eth0 parent root handle 100 taprio \
   num_tc 3 \
   map 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 \
   queues 1@0 1@1 1@2 \
   base-time 0000 \
   sched-entry S 4 110520 \
   sched-entry S 0 14480  \
   sched-entry S 2 110520 \
   sched-entry S 0 14480  \
   sched-entry S 1 235520 \
   sched-entry S 0 14480  \
   cycle-time 600000 \
   flags 2

在上面的示例中,最后一个窗口被拉伸了350 usec而不是250 usec,从而导致循环时间为600 usec。类似地,如果周期时间小于单个sched条目的总和,那么将执行计划.

tc qdisc replace dev eth0 parent root handle 100 taprio \
   num_tc 3 \
   map 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 \
   queues 1@0 1@1 1@2 \
   base-time 0000 \
   sched-entry S 4 110520 \
   sched-entry S 0 14480  \
   sched-entry S 2 110520 \
   sched-entry S 0 14480  \
   sched-entry S 1 235520 \
   sched-entry S 0 14480  \
   cycle-time 400000 \
   flags 2

在上述情况下,最后一个调度条目将被截断为150 usec,从而导致周期时间为400 usec。此外,从内存中获取调度条目需要大约16个wires时钟周期(128 nsec)。这样就确定了调度输入间隔的最小值。如果小于这个值,则数据包溢出到下一个窗口。
管理命令
802.1Q标准将管理描述为操作员在现有(运行)调度运行时切换到新调度的一种方式。在Linux中,这是通过在一个tc运行时发送另一个tc命令来完成的。一个有限的管理命令支持是由以下约束驱动程序:-
•新时间表的周期时间必须与现有时间表相匹配
•开始时间必须为过去
不支持的功能
•周期时间不同于操作计划的管理命令
•未来的管理命令
•管理周期扩展/操作周期扩展
•配置queueMaxSDUTable
•配置ConfigChange
•显示ConfigPending状态(tc命令显示操作和管理计划。因此,如果出现管理计划,用户应用程序可能会将其视为ConfigPending)
•显示ConfigChangeError
•Show SupportedListMax-如果间隔小于128 usec,则支持的最大值为64个sched条目)

3.2.2.8.4. Intersperse Express Traffic (IET) Frame Preemption offload

CPSW2g h/w支持Intersperse Express流量(IET,在P802.3br/D2.0规范中定义,稍后包含在IEEE 802.3 2018中)帧抢占(FPE)功能,还允许MAC层验证对等方是否支持IET MAC合并层。MAC合并层负责在优先级较高的Express队列中存在等待传输的帧时,抢占可抢占队列中帧的传输。h/w发送满足最小片段大小要求的帧的初始段,然后从Express队列调度帧以进行传输。最后,当Express队列不再有可用的帧时,它将恢复被抢占的可抢占队列的帧的剩余部分的传输。在对等端,段被重新组装并传送到MAC接口。
通过ethtool –set-priv-flags命令为端口配置IET FPE特性。请注意,这是一个允许在CPSW2g驱动程序中配置IET FPE的临时接口,它没有得到Linux内核邮件列表(LKML)中的netdev子系统维护者的批准,将来可能会更改。当网络设备打开时(ndo_open()),如果用户打开了iet-frame-preemption priv标志,驱动程序为端口配置IET FPE。注意,因为IET是一个适用于所有从端口的通用特性,所以必须在启动CPSW2g的网络端口之前进行此操作。如果连接到CPSW2g端口的对端设备也能够验证MAC merge/FPE能力,用户也可以打开iec-mac-verify标志。为此,驱动程序调度一个工作线程来执行MAC/Verify进程,只要链路启动并设置了iec-mac-verify priv标志。它会重置LINKFAIL位,并检查验证是否成功。在失败时,MAC验证状态机通过切换LINKFAIL位重置,并在退出前重复处理20次。如果没有设置iec-mac-verify priv标志,驱动程序假定peer能够支持FPE,但不能进行MAC验证。所以它将设备配置为强制模式。用户需要验证对端设备是否能够支持IET FPE使用force模式。
驱动假定最高优先级的h/w队列为快速队列,并在MAC验证成功或强制模式启用时通过编程PN_REG_IET_CTRL寄存器将较低的队列(Q0-QN-2,其中N是配置的最大队列数)配置为可抢占队列。在使用IET特性之前,应该关闭p0-rx-ptype-rrobin标志。即CPSW2g h/w应编程为严格优先模式,以使IET工作。
启用IET FPE with MAC Verify, do

ethtool --set-priv-flags eth0 p0-rx-ptype-rrobin off
ethtool --set-priv-flags eth0 iet-frame-preemption on
ethtool --set-priv-flags eth0 iet-mac-verify on

在没有MAC验证的情况下启用IET FPE(强制模式)

ethtool --set-priv-flags eth0 p0-rx-ptype-rrobin off
ethtool --set-priv-flags eth0 iet-frame-preemption on

禁用IET FPE并恢复rrobin模式

ethtool --set-priv-flags eth0 iet-frame-preemption off
ethtool --set-priv-flags eth0 iet-mac-verify off
ethtool --set-priv-flags eth0 p0-rx-ptype-rrobin on

使用MAC验证启用IET FPE的示例会话。
假设2个AM65x IDK通过MCU以太网端口(通常为eth0接口)背靠背连接。示例假定配置了2个h/w队列。在这种配置中,Q1是express队列,Q0是抢占队列。

root@am65xx-evm:~# ifconfig eth0 down
[  169.798571] am65-cpsw-nuss 46000000.ethernet eth0: Link is Down
root@am65xx-evm:~# ethtool -L eth0 tx 2
root@am65xx-evm:~# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX:             1
TX:             8
Other:          0
Combined:       0
Current hardware settings:
RX:             1
TX:             2
Other:          0
Combined:       0
@am65xx-evm:~# ethtool --set-priv-flags eth0 p0-rx-ptype-rrobin off
root@am65xx-evm:~# ethtool --set-priv-flags eth0 iet-frame-preemption on
root@am65xx-evm:~# ethtool --show-priv-flags eth0
Private flags for eth0:
p0-rx-ptype-rrobin  : off
iet-frame-preemption: on
iet-mac-verify      : off
root@am65xx-evm:~# ethtool --set-priv-flags eth0 iet-mac-verify on
root@am65xx-evm:~# ethtool --show-priv-flags eth0
Private flags for eth0:
p0-rx-ptype-rrobin  : off
iet-frame-preemption: on
iet-mac-verify      : on
root@am65xx-evm:~# ifconfig eth0 up
root@am65xx-evm:~#
root@am65xx-evm:~# [  267.393967] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[  267.400353] am65-cpsw-nuss 46000000.ethernet eth0: Starting IET/FPE MAC Verify
[  267.465086] am65-cpsw-nuss 46000000.ethernet eth0: IET/FPE MAC Verify Success
[  267.472276] am65-cpsw-nuss 46000000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off
启用IET FPE的示例会话,无MAC验证(强制模式)
root@am65xx-evm:~# ifconfig eth0 down
[  394.590576] am65-cpsw-nuss 46000000.ethernet eth0: Link is Down
root@am65xx-evm:~# ethtool --set-priv-flags eth0 iet-frame-preemption on
#if iet-mac-verify was enabled before, turn it off
root@am65xx-evm:~# ethtool --set-priv-flags eth0 iet-mac-verify off
root@am65xx-evm:~# ethtool --show-priv-flags eth0
Private flags for eth0:
p0-rx-ptype-rrobin  : off
iet-frame-preemption: on
iet-mac-verify      : off
root@am65xx-evm:~#
root@am65xx-evm:~# ifconfig eth0 192.168.100.20
[  500.502660] TI DP83867 46000f00.mdio:00: attached PHY driver [TI DP83867] (mii_bus:phy_addr=46000f00.mdio:00, irq=POLL)
root@am65xx-evm:~# [  500.516232] am65-cpsw-nuss 46000000.ethernet eth0: Link is Down
root@am65xx-evm:~# [  552.738077] am65-cpsw-nuss 46000000.ethernet eth0: IET Enable Force mode
[  552.744839] am65-cpsw-nuss 46000000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off
[  552.753434] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

IET FPE示例
最高优先级的队列是Express队列。例如:如果通过ethtool -L命令配置了8个队列,那么Q7将是express,Q0-Q6将是抢占的。同样,如果配置了4个队列,那么Q3将是快速队列,Q0-Q2将是可抢占队列。下面是一个如何验证硬件中是否发生了抢占的示例。安装程序需要通过MCU Ethernet/CPSW2g端口连接2个IDK(例如AM65x)。假设两个IDK上都启用了IET,如前几节所述,并且启用了强制模式或MAC验证模式。一旦链接出现,IET FPE就被启用。该测试要求在Talker DUT’e eth0端口配置MQPRIO qdisc,并使分类器能够将具有特定端口的UDP帧映射到给定的流量类。使用流量类作为索引,将流量定向到特定的h/w队列。CPSW2g stats模块提供了一个统计计数器,用于验证IET FPE是否正常:-
•iet_rx_assembly_ok -如果重新组装MAC片段成功,接收端就增加。
•iet_rx_frag -如果因为抢占而接收到MAC分片,则在接收端增加
•iet_tx_frag -如果由于帧抢占而创建了分片,则发送端增加。
因此,为了测试,需要在抢占队列和快速队列上都有流量,并使用上述统计计数器来验证发送端是否发生碎片,接收端是否重新组装。下面的日志提供了一些使用示例。

At the Talker一方

#在eth0 - 2队列配置上设置mqprio qdisc。Q0 — 抢占队列和Q1快速队列

root@am65xx-evm:~# tc qdisc replace dev eth0 handle 100: parent root mqprio num_tc 2  map 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 queues 1@0
1@1 hw 0
root@am65xx-evm:~# tc -g class show dev eth0
+---(100:ffe1) mqprio
|    +---(100:2) mqprio
|
+---(100:ffe0) mqprio
    +---(100:1) mqprio

#在网络核心启用分类器

root@am65xx-evm:~# tc qdisc add dev eth0 clsact

#添加tc筛选器规则,以基于目标UDP端口号(端口5002映射到prio 2)标记数据包优先级
#从以上mqprio设置来看,索引2处的TC为0。所以这个TC数据包去Q0

root@am65xx-evm:~# tc filter add dev eth0 egress protocol ip prio 1 u32 match ip dport 5002 0xffff action skbedit priority 2
[  285.576105] u32 classifier
[  285.578910]     input device check on
[  285.582640]     Actions configured

#添加tc筛选器规则以将UDP端口号为-端口5003的数据包映射到prio 3
#从以上mqprio设置中,索引3处的TC为1。所以这个TC数据包会转到Q1

root@am65xx-evm:~# tc filter add dev eth0 egress protocol ip prio 1 u32 match ip dport 5003 0xffff action skbedit priority 3
root@am65xx-evm:~#
root@am65xx-evm:~# ifconfig eth0 192.168.100.20

#在侦听器DUT上,设置ip地址并运行iperf3服务器会话,侦听端口5002和5003。

# ifconfig eth0 192.168.100.30
root@am65xx-evm:~# iperf3 -s -i30 -p5002&
[1] 1224
root@am65xx-evm:~# iperf3 -s -i30 -p5003&
-----------------------------------------------------------
Server listening on 5002
-----------------------------------------------------------
[2] 1225
-----------------------------------------------------------
Server listening on 5003
-----------------------------------------------------------
root@am65xx-evm:~#

#在侦听器DUT上,启动到端口5002和5003的iperf3客户端会话

root@am65xx-evm:~# iperf3 -c 192.168.100.30 -u -b200M -l1472 -u -t30 -i30 -p5002&
[1] 1050
root@am65xx-evm:~# iperf3 -c 192.168.100.30 -u -b50M -l1472 -u -t30 -i30 -p5003&
[2] 1051
root@am65xx-evm:~#
root@am65xx-evm:~# warning: UDP block size 1472 exceeds TCP MSS 1448, may result in fragmentation / drops
warning: UDP block size 1472 exceeds TCP MSS 1448, may result in fragmentation / drops
Connecting to host 192.168.100.30, port 5003
Connecting to host 192.168.100.30, port 5002
[  5] local 192.168.100.20 port 60646 connected to 192.168.100.30 port 5003
[  5] local 192.168.100.20 port 39515 connected to 192.168.100.30 port 5002

#现在在Talker DUT中,dump Q0和Q1的统计信息计数器以及IET统计信息

root@am65xx-evm:~# ethtool -S eth0 | grep 'tx_pri1'
    p0_tx_pri1: 0
    p0_tx_pri1_bcnt: 0
    p0_tx_pri1_drop: 0
    p0_tx_pri1_drop_bcnt: 0
    tx_pri1: 24869
    tx_pri1_bcnt: 37722660
    tx_pri1_drop: 0
    tx_pri1_drop_bcnt: 0
root@am65xx-evm:~# ethtool -S eth0 | grep 'tx_pri0'
    p0_tx_pri0: 0
    p0_tx_pri0_bcnt: 0
    p0_tx_pri0_drop: 0
    p0_tx_pri0_drop_bcnt: 0
    tx_pri0: 100271
    tx_pri0_bcnt: 152067960
    tx_pri0_drop: 0
    tx_pri0_drop_bcnt: 0
root@am65xx-evm:~# ethtool -S eth0 | grep iet
    iet_rx_assembly_err: 0
    iet_rx_assembly_ok: 0
    iet_rx_smd_err: 0
    iet_rx_frag: 0
    iet_tx_hold: 0
    iet_tx_frag: 159
root@am65xx-evm:~# ethtool -S eth0 | grep 'tx_pri1'
    p0_tx_pri1: 0
    p0_tx_pri1_bcnt: 0
    p0_tx_pri1_drop: 0
    p0_tx_pri1_drop_bcnt: 0
    tx_pri1: 27718
    tx_pri1_bcnt: 42047442
    tx_pri1_drop: 0
    tx_pri1_drop_bcnt: 0
root@am65xx-evm:~# ethtool -S eth0 | grep 'tx_pri0'
    p0_tx_pri0: 0
    p0_tx_pri0_bcnt: 0
    p0_tx_pri0_drop: 0
    p0_tx_pri0_drop_bcnt: 0
    tx_pri0: 111637
    tx_pri0_bcnt: 169320030
    tx_pri0_drop: 0
    tx_pri0_drop_bcnt: 0
root@am65xx-evm:~# ethtool -S eth0 | grep iet
    iet_rx_assembly_err: 0
    iet_rx_assembly_ok: 0
    iet_rx_smd_err: 0
    iet_rx_frag: 0
    iet_tx_hold: 0
    iet_tx_frag: 175

#如图所示,iet_tx_frag统计计数器在Talker处递增,显示Talker处的碎片
#同时在listener DUT上dump统计信息

ethtool -S eth0 | grep iet
    iet_rx_assembly_err: 0
    iet_rx_assembly_ok: 248
    iet_rx_smd_err: 0
    iet_rx_frag: 248
    iet_tx_hold: 0
    iet_tx_frag: 0
root@am65xx-evm:~# ethtool -S eth0 | grep iet
    iet_rx_assembly_err: 0
    iet_rx_assembly_ok: 252
    iet_rx_smd_err: 0
    iet_rx_frag: 252
    iet_tx_hold: 0
    iet_tx_frag: 0
root@am65xx-evm:~# ethtool -S eth0 | grep iet
    iet_rx_assembly_err: 0
    iet_rx_assembly_ok: 252
    iet_rx_smd_err: 0
    iet_rx_frag: 252
    iet_tx_hold: 0
    iet_tx_frag: 0

#如图所示,iet_rx_frag and iet_rx_assembly_ok统计计数器在侦听器处递增,显示侦听器处的重新组装
将IET与EST结合使用
Express和preemption queues/Gates可以用作EST调度的一部分。如果只有抢占队列在一个调度条目中,在一个带有Express queue的条目之前,保护带需求减少到2048nsec(0x100=256*8),这样数据包就不会溢出到下一个sched条目。否则,所需的保护带如EST部分所述。
3.2.2.9. CPSW9g虚拟MAC(remoteproc)
3.2.2.9.1. 介绍
TI Jacinto 7 SoC将九端口千兆以太网交换子系统集成到设备主域CPSW0中,具有8个外部以太网端口。
在Jacinto 7系列SoC上的处理器SDK Linux J721e不允许从Linux直接访问CPSW0, CPSW0被置于运行在一个R5F内核上的EthSwitch固件的独占控制下(默认为main_r5fss0_core0)。
只有EthSwitch固件对Jacinto 7 CPSW0有完全的控制,并允许通过使用可编程的ALE分类器和专用的UDMA TX通道和RX流隔离每个附加的远程CPU的以太网流量。EthSwitch firmware支持rpmsg-kdrv协议,并将自己呈现为rpmsg-kdrv设备,它为每个连接的远程CPU提供CPSW0资源管理和调试服务。
jacinto7系列SoC上的处理器SDK Linux J721e包含一个解决方案,允许使用标准Linux网络设备发送/接收指向运行Linux的CPU核心的以太网通信。提供的解决方案由两个驱动程序实现:- drivers/rpmsg-kdrv/rpmsg_kdrv_switch.c - drivers/net/ethernet/ti/j721e-cpsw-virt-mac.c
此解决方案如下所示。
注意
TI remoteproc/virtio/rpmsg/rpmsg-kdrv的总体描述超出了本节的范围。

User space           +------+
+--------------------+ethX  +----------------------------------------+
                     +--^---+
                       |
                       |
               +-------v-----+
               |Net core     |
               +-----^-------+
                     |
      +--------------v--------------------+ rpmsg_remotedev/
      | main_r5fss_cpsw9g_virt_mac0       | rpmsg_remotedev_eth_switch_ops API
      | ethernet/ti/j721e-cpsw-virt-mac.c <--------+
      +-----------------------------------+        |
                                                   |
                          +------------------------v------+
                          | mpu_1_0_ethswitch-device-0    |
                          | rpmsg-kdrv/rpmsg_kdrv_switch.c|
                          +-------------^-----------------+
       rpmsg_kdr Bus                    |
     +---------------------^--------+--------------------------+
                           |
                      +----+--------+
                      | rpmsg-kdrv  |
                      |             |
                      +----^--------+
       RPMSG Bus           |
     +---------------------+-----------------^-----------------+
                                             |
                                    +--------+--------------+
                                    |   virtio_rpmsg_bus    |
                                    |                       |
                                    +--------^--------------+
                                             |
                                             |
                                    +--------v--------------+
                                    | remoteproc            |
                                    | ti_k3_r5_remoteproc   |
                                    +--------+--------------+
Kernel                                       |
+--------------------------------------------|------------------------+                                              |
           +---------------------------------v------------+
           |SoC                                           |
           |  +------------+        +------------------+  |
           |  |            |        |main_r5fss0_core0 |  |
           |  |  CPSW9G    <--------+                  |  |
           |  +------------+        +------------------+  |
           |                                              |
           +----------------------------------------------+

驱动程序初始化
Linux TI remoteproc核心确保正确的R5F核心初始化,加载并启动EthSwitch固件,并创建默认的virtio设备来与该固件交互。virtio_rpmsg_bus驱动程序执行RPMSG设备的发现,并创建一个rpmsg-kdrv设备,该设备将触发rpmsg-kdrv核心发现“mpu_1_0_ethswitch-device-0”并探测rpmsg_kdrv_switch驱动程序
一旦Linux DT解析代码创建了相应的main_r5fss_cpsw9g_virt_macX设备,Linux内核就会单独启动j721e-cpsw-virt-mac驱动程序。一旦启动,j721e-cpsw-virt-mac驱动程序将等待探测rpmsg_kdrv_switch驱动程序。
请注意
EthSwitch FW也可能被bootloader加载,在这种情况下,remoteproc组件将以“IPC-only”模式启动。
rpmsg_kdrv_switch驱动
rpmsg_kdrv_switch驱动(drivers/rpmsg-kdrv/rpmsg_kdrv_switch.c)本身除了检查支持的EthSwitch FW版本外,没有其他功能。它旨在提供j721e-cpsw-virt-mac驱动程序所使用的RPMSG-KDRV rpmsg_remotedev API接口。功能控制的RPMSG-KDRV rpmsgi_remotedev API包括:- DMA资源配置:TX UDMA通道和RX流- MAC地址分配ARP助手ARP请求处理从远程网络主机- dbg: IPC ping - dbg: CPSW0寄存器访问- dbg:统计打印请求在R5F控制台(ioctl)
j721e-cpsw-virt-mac 驱动
j721e-cpsw-virt-mac 驱动 (drivers/net/ethernet/ti/j721e-cpsw-virt-mac.c) 遵循标准的Linux网络接口架构,支持以下特性:
•网络设备up/down
•自动(或手动)MAC地址分配
•ip地址分配
•Ethertool基本功能
•rx /TX csum offload(如果EthSwitch FW启用)
不支持:
•HW不支持中断间隔。NAPI由驱动程序使用。
网络数据流
EthSwitch FW负责连接的远端核之间的UDMA资源管理和分配。j721e-cpsw-virt-mac驱动程序在初始化过程中执行附加操作:TX通道和RX流通过控制路径(rpmsg_remotedev API),请求EthSwitch FW提供可用的UDMA资源。在当前的设计中,EthSwitch FW为每个附加核分配TX UDMA专用(非共享)通道,而EthSwitch FW控制RX UDMA通道,仅为附加核提供专用UDMA RX流。
因此,在分配之后,j721e-cpsw-virt-mac 驱动程序负责完整的TX UDMA通道初始化(包括TX和TX完成环初始化)。j721e-cpsw-virt-mac驱动程序还启动/停止TX UDMA通道。对于RX端,j721e-cpsw-virt-mac驱动程序只执行UDMA RX流初始化(包括RX自由描述符和RX环初始化)。

User space          +------+
+--------------------+ethX  +----------------------------------------+
                     +--^---+
                        |
                        |
                +-------v-----+
                |Net core     |
                +-----^-------+
                      |
       +--------------v-------+
       | j721e-cpsw-virt-mac  |   Control Path
       |                      <----------+
       +----+---^-------------+          |
            |   |                        |
            |   |                        |
            |   |              +---------v---------+
TX channel  |   |RX flow       | rpmsg_kdrv_switch |
            |   |              |                   |
            |   |              +---------^---------+
            |   |                        |
         Data Path                       |
       +----+---+-------------------------------------+
       |    |   |                        |      SoC   |
       |  +-v---+------+                 |            |
       |  |            |                 |            |
       |  |  UDMA      |                 |            |
       |  +---+--------+                 |            |
       |      |                          |            |
       |  +---v--------+        +--------v---------+  |
       |  |            |        |main_r5fss0_core0 |  |
       |  |  CPSW9G    <--------+                  |  |
       |  +------------+        +------------------+  |
       |                                              |
       +----------------------------------------------+

EthSwitch FW需要知道哪些流量隔离到Linux主机;因此,j721e-cpsw-virt-mac驱动通过控制路径注册分配给EthSwitch FW内virt_mac网络设备的MAC地址。
配置完成后,Linux virt_mac网络设备与CPSW0之间的网络数据即可通过,无需与EthSwitch FW交互。
3.2.2.9.2. 启用j721e-cpsw-virt-mac驱动程序
处理器SDK Linux J721e包有一个jacinto7 rpmsg_kdrv_switch交换机和j721e-cpsw-virt-mac驱动程序,默认情况下,这些驱动程序可以构建为模块。

要手动启用/禁用j721e-cpsw-virt-mac驱动程序支持,请启动Linux内核配置工具:

# make ARCH=arm64 menuconfig
Select Device Drivers from the main menu ->
Select Rpmsg virtual device drivers ->
Select ** as shown here:
-*- RPMSG virtual device interface
<M> RPMSG virtual eth switch device support
 ...
Select Device Drivers from the main menu ->
Select Network device support ->
Select Ethernet driver support ->
Select ** as shown here:
[*]   Texas Instruments (TI) devices
<M>     TI Virtual Eth MAC driver
...
内核Kconfig选项:
CONFIG_RPMSG_KDRV
CONFIG_RPMSG_KDRV_ETH_SWITCH
CONFIG_TI_RDEV_ETH_SWITCH_VIRT_EMAC

设备树绑定
DT绑定说明可在以下位置找到:
Documentation/devicetree/bindings/net/ti,cpsw-virt-mac.txt

3.2.2.9.3 用户空间接口
启动接口
Eth0支持默认启动和手动配置:
DHCP

udhcpc -i ethX
ifup eth0

手动配置IP地址

ifconfig eth0 <ip> netmask <mask> up
ifconfig - Set MAC address

j721e-cpsw-virt-mac支持修改HW MAC地址,但只有在网络设备处于非活动状态(down)时才能执行。

# ifconfig <dev> down
# ifconfig <dev> hw ether <MAC-addr>

ethtool - 获取驱动信息
CPSW0接口可以通过使用ethtool -i|–driver命令来识别。它还提供了一些有关支持的功能的信息。

# ethtool -i <dev>
...

ethtool - 显示设备/链路的标准信息

# ethtool eth0

请注意
支持这个命令,但不是很有用,因为链接总是up而没有PHY.
ethtool - 显示永久硬件地址地址

# ethtool -P eth0
Permanent address: a0:f6:fd:a6:46:6e"

ethtool - RX/TX校验和卸载
驱动程序默认启用RX校验和卸载。当前状态可以通过命令“ethtool -k”获取:

# ethtool -k <dev>
....
rx-checksumming: on
tx-checksumming: off
    tx-checksum-ipv4: off [fixed]
    tx-checksum-ip-generic: off

可以通过命令“ethtool -K”禁用/启用:

ethtool -K <dev> rx-checksum on|off
ethtool -K <dev> tx-checksum-ip-generic on|off

请注意
TX校验和卸载使能由EthSwitch FW控制,当前状态提供给j721e-cpsw-virt-mac驱动程序。
ethtool - 驱动程序测试

# ethtool -t|--test <dev>
...
RPMSG Ping test
RPMSG Read reg
RPMSG Dump stat

j721e-cpsw-virt-mac可以运行几种类型的测试(如果EthSwitch FW启用):
•rpmsg Ping测试:向EthSwitch FW发送Ping命令,检查返回的数据是否相同
•rpmsg Read reg:发送CPSW0 CPSW_SS_CPSW_NUSS_IDVER_REG (0x0C000000) Read register命令到EthSwitch FW
•rpmsg Dump stat:发送命令给EthSwitch FW dump当前状态和统计信息

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值