ethtool -T显示ptp过滤器信息源码分析

ptp过滤器

新设备使用ethtool -T显示ptp过滤器信息:

linux_cx7110:~# ethtool -T eth0
Time stamping parameters for eth0:
Capabilities:
	hardware-transmit     (SOF_TIMESTAMPING_TX_HARDWARE)
	software-transmit     (SOF_TIMESTAMPING_TX_SOFTWARE)
	hardware-receive      (SOF_TIMESTAMPING_RX_HARDWARE)
	software-receive      (SOF_TIMESTAMPING_RX_SOFTWARE)
	software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
	hardware-raw-clock    (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
	off                   (HWTSTAMP_TX_OFF)
	on                    (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
	none                  (HWTSTAMP_FILTER_NONE)
	all                   (HWTSTAMP_FILTER_ALL)
	ptpv1-l4-event        (HWTSTAMP_FILTER_PTP_V1_L4_EVENT)
	ptpv1-l4-sync         (HWTSTAMP_FILTER_PTP_V1_L4_SYNC)
	ptpv1-l4-delay-req    (HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ)
	ptpv2-l4-event        (HWTSTAMP_FILTER_PTP_V2_L4_EVENT)
	ptpv2-l4-sync         (HWTSTAMP_FILTER_PTP_V2_L4_SYNC)
	ptpv2-l4-delay-req    (HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ)
	ptpv2-event           (HWTSTAMP_FILTER_PTP_V2_EVENT)
	ptpv2-sync            (HWTSTAMP_FILTER_PTP_V2_SYNC)
	ptpv2-delay-req       (HWTSTAMP_FILTER_PTP_V2_DELAY_REQ)

原来设备没有ptp过滤器信息: 

root@imx6qsabresd_genvict:~# ethtool -T eth0
Time stamping parameters for eth0:
Capabilities:
	hardware-transmit     (SOF_TIMESTAMPING_TX_HARDWARE)
	software-transmit     (SOF_TIMESTAMPING_TX_SOFTWARE)
	hardware-receive      (SOF_TIMESTAMPING_RX_HARDWARE)
	software-receive      (SOF_TIMESTAMPING_RX_SOFTWARE)
	software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
	hardware-raw-clock    (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
	off                   (HWTSTAMP_TX_OFF)
	on                    (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
	none                  (HWTSTAMP_FILTER_NONE)
	all                   (HWTSTAMP_FILTER_ALL)
linux_cx7101:~# ethtool -T eth0
Time stamping parameters for eth0:
Capabilities:
	software-receive      (SOF_TIMESTAMPING_RX_SOFTWARE)
	software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
PTP Hardware Clock: none
Hardware Transmit Timestamp Modes: none
Hardware Receive Filter Modes: none

代码流程

ethtool-4.15,最后系统调用:ioctl(ctx->fd, SIOCETHTOOL, &ctx->ifr);

{ "-T|--show-time-stamping", 1, do_tsinfo,
do_tsinfo
	#define ETHTOOL_GET_TS_INFO	0x00000041 /* Get time stamping and PHC info */

	fprintf(stdout, "Time stamping parameters for %s:\n", ctx->devname);
	info.cmd = ETHTOOL_GET_TS_INFO;
	if (send_ioctl(ctx, &info)) {
		perror("Cannot get device time stamping settings");
		return -1;
	}
	dump_tsinfo(&info);

#define SIOCETHTOOL     0x8946
int send_ioctl(struct cmd_context *ctx, void *cmd)
{
	ctx->ifr.ifr_data = cmd;
	return ioctl(ctx->fd, SIOCETHTOOL, &ctx->ifr);
}

static char *rx_filter_labels[N_RX_FILTERS] = {
	"none                  (HWTSTAMP_FILTER_NONE)",
	"all                   (HWTSTAMP_FILTER_ALL)",
	"some                  (HWTSTAMP_FILTER_SOME)",
	"ptpv1-l4-event        (HWTSTAMP_FILTER_PTP_V1_L4_EVENT)",
	"ptpv1-l4-sync         (HWTSTAMP_FILTER_PTP_V1_L4_SYNC)",
	"ptpv1-l4-delay-req    (HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ)",
	"ptpv2-l4-event        (HWTSTAMP_FILTER_PTP_V2_L4_EVENT)",
	"ptpv2-l4-sync         (HWTSTAMP_FILTER_PTP_V2_L4_SYNC)",
	"ptpv2-l4-delay-req    (HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ)",
	"ptpv2-l2-event        (HWTSTAMP_FILTER_PTP_V2_L2_EVENT)",
	"ptpv2-l2-sync         (HWTSTAMP_FILTER_PTP_V2_L2_SYNC)",
	"ptpv2-l2-delay-req    (HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ)",
	"ptpv2-event           (HWTSTAMP_FILTER_PTP_V2_EVENT)",
	"ptpv2-sync            (HWTSTAMP_FILTER_PTP_V2_SYNC)",
	"ptpv2-delay-req       (HWTSTAMP_FILTER_PTP_V2_DELAY_REQ)",
	"ntp-all               (HWTSTAMP_FILTER_NTP_ALL)",
};

dump_tsinfo
	fprintf(stdout, "Hardware Receive Filter Modes:");

	if (!info->rx_filters)
		fprintf(stdout, " none\n");
	else
		fprintf(stdout, "\n");

	for (i = 0; i < N_RX_FILTERS; i++) {
		if (info->rx_filters & (1 << i))
			fprintf(stdout, "\t%s\n", rx_filter_labels[i]);
	}

网络驱动,调用网络通用层代码框架,最后调用设备驱动:get_ts_info

net/core/dev_ioctl.c +420
dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_copyout)
    case SIOCETHTOOL:
        dev_load(net, ifr->ifr_name);
        rtnl_lock();
        ret = dev_ethtool(net, ifr);
        rtnl_unlock();
        if (colon)
            *colon = ':';
        return ret;

dev_ethtool(struct net *net, struct ifreq *ifr)
	struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
	void __user *useraddr = ifr->ifr_data;【ETHTOOL_GET_TS_INFO】
    case ETHTOOL_GET_TS_INFO:
        rc = ethtool_get_ts_info(dev, useraddr);
        break;

static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)
{
    int err = 0;
    struct ethtool_ts_info info;
    const struct ethtool_ops *ops = dev->ethtool_ops;
    struct phy_device *phydev = dev->phydev;

    memset(&info, 0, sizeof(info));
    info.cmd = ETHTOOL_GET_TS_INFO;

    if (phydev && phydev->drv && phydev->drv->ts_info) {
        err = phydev->drv->ts_info(phydev, &info);
    } else if (ops->get_ts_info) {
        err = ops->get_ts_info(dev, &info);
    } else {
        info.so_timestamping =
            SOF_TIMESTAMPING_RX_SOFTWARE |
            SOF_TIMESTAMPING_SOFTWARE;
        info.phc_index = -1;
    }

    if (err)
        return err;

    if (copy_to_user(useraddr, &info, sizeof(info)))
        err = -EFAULT;

    return err;
}

设备驱动,设备驱动如果支持time_stamp,就直接返回全部ptp过滤器信息,没有读取寄存器信息。

drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
static const struct ethtool_ops stmmac_ethtool_ops = {
	.get_ts_info = stmmac_get_ts_info,

static int stmmac_get_ts_info(struct net_device *dev,
                  struct ethtool_ts_info *info)
{   
    struct stmmac_priv *priv = netdev_priv(dev);

    if ((priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) {
        
        info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
                    SOF_TIMESTAMPING_TX_HARDWARE |
                    SOF_TIMESTAMPING_RX_SOFTWARE |
                    SOF_TIMESTAMPING_RX_HARDWARE |
                    SOF_TIMESTAMPING_SOFTWARE |
                    SOF_TIMESTAMPING_RAW_HARDWARE;
        
        if (priv->ptp_clock)
            info->phc_index = ptp_clock_index(priv->ptp_clock);
        
        info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
        
        info->rx_filters = ((1 << HWTSTAMP_FILTER_NONE) |
                    (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |【ethtool -T eth0执行这里获取信息】
                    (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
                    (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
                    (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
                    (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
                    (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
                    (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                    (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                    (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
                    (1 << HWTSTAMP_FILTER_ALL));
        return 0;
    } else
        return ethtool_op_get_ts_info(dev, info);
}

设备驱动支持设置ptp过滤器,但ethtool工具暂不支持:

static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
    if (priv->adv_ts) {
        switch (config.rx_filter) {
        case HWTSTAMP_FILTER_NONE:
            /* time stamp no incoming packet at all */
            config.rx_filter = HWTSTAMP_FILTER_NONE;
            break;

        case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:【没有代码设置属性】
            /* PTP v1, UDP, any kind of event packet */
            config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
            /* take time stamp for all event messages */
            if (xmac)
                snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
            else
                snap_type_sel = PTP_TCR_SNAPTYPSEL_1;

            ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
            ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
            break;

static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
    case SIOCSHWTSTAMP:
        ret = stmmac_hwtstamp_ioctl(dev, rq);

static const struct net_device_ops stmmac_netdev_ops = {
    .ndo_do_ioctl = stmmac_ioctl,

net/core/dev_ioctl.c
int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_copyout)
    case SIOCSIFNAME:
        dev_load(net, ifr->ifr_name);
        if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
            return -EPERM;
        rtnl_lock();
        ret = dev_ifsioc(net, ifr, cmd);

dev_ifsioc
	cmd == SIOCSHWTSTAMP ||
	cmd == SIOCGHWTSTAMP ||
	cmd == SIOCWANDEV) {
	err = -EOPNOTSUPP;
	if (ops->ndo_do_ioctl) {
		if (netif_device_present(dev))
			err = ops->ndo_do_ioctl(dev, ifr, cmd);

总结

目前看ptp过滤器没有实际用到(暂不知如何使用),ptpd2工具发送的udp组播包也是能全部收到的。设备收到192.168.8.202主模式发送的udp包:

linux_genvict:~# tcpdump -i eth0
[10124.286185]  {3}[20512:tcpdump]stmmac_get_ts_info,811,
[10124.288759]  {3}[20512:tcpdump]stmmac_get_ts_info,826,
[10124.295198]  {3}[20512:tcpdump]device eth0 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:21:02.767206 IP 192.168.8.202.319 > 224.0.1.129.319: UDP, length 44
14:21:02.767279 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 44
14:21:03.767224 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 64
14:21:03.767297 IP 192.168.8.202.319 > 224.0.1.129.319: UDP, length 44
14:21:03.767323 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 44
14:21:04.767240 IP 192.168.8.202.319 > 224.0.1.129.319: UDP, length 44
14:21:04.767313 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 44
14:21:05.767137 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 64
14:21:05.767221 IP 192.168.8.202.319 > 224.0.1.129.319: UDP, length 44
14:21:05.767251 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 44
14:21:06.767151 IP 192.168.8.202.319 > 224.0.1.129.319: UDP, length 44
14:21:06.767239 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 44
14:21:07.767173 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 64
14:21:07.767265 IP 192.168.8.202.319 > 224.0.1.129.319: UDP, length 44
14:21:07.767290 IP 192.168.8.202.320 > 224.0.1.129.320: UDP, length 44

设备收到192.168.8.202从模式发送igmp包,

linux_genvict:~# tcpdump -i eth0
[10209.040651]  {2}[22941:tcpdump]stmmac_get_ts_info,811,
[10209.043257]  {2}[22941:tcpdump]stmmac_get_ts_info,826,
[10209.050286]  {2}[22941:tcpdump]device eth0 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:22:27.397521 IP 192.168.8.202 > 224.0.0.22: igmp v3 report, 2 group record(s)
14:22:36.297523 IP 192.168.8.202 > 224.0.0.22: igmp v3 report, 2 group record(s)
14:22:36.397373 IP 192.168.8.202 > 224.0.0.22: igmp v3 report, 2 group record(s)
14:22:44.767547 IP 192.168.8.202 > 224.0.0.22: igmp v3 report, 2 group record(s)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值