ret = ethtool_net_get_ts_info_by_phc(dev, &ts_info, hwprov_desc); if (!ret) { /* Found */
source = HWTSTAMP_SOURCE_NETDEV;
} else {
phy = ethtool_phy_get_ts_info_by_phc(dev, &ts_info, hwprov_desc); if (IS_ERR(phy)) { if (PTR_ERR(phy) == -ENODEV)
NL_SET_ERR_MSG_ATTR(info->extack,
tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER], "phc not in this net device topology"); return ERR_CAST(phy);
}
source = HWTSTAMP_SOURCE_PHYLIB;
}
hwprov = kzalloc(sizeof(*hwprov), GFP_KERNEL); if (!hwprov) return ERR_PTR(-ENOMEM);
ret = ts_parse_hwtst_provider(tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER],
&__hwprov_desc, info->extack,
&hwprov_mod); if (ret < 0) return ret;
if (hwprov_mod) {
hwprov = tsconfig_set_hwprov_from_desc(dev, info,
&__hwprov_desc); if (IS_ERR(hwprov)) return PTR_ERR(hwprov);
}
}
/* Get current hwtstamp config if we are not changing the * hwtstamp source. It will be zeroed in the other case.
*/ if (!hwprov_mod) {
ret = dev_get_hwtstamp_phylib(dev, &hwtst_config); if (ret < 0 && ret != -EOPNOTSUPP) goto err_free_hwprov;
}
/* Get the hwtstamp config from netlink */ if (tb[ETHTOOL_A_TSCONFIG_TX_TYPES]) {
u32 req_tx_type;
req_tx_type = BIT(hwtst_config.tx_type);
ret = ethnl_update_bitset32(&req_tx_type,
__HWTSTAMP_TX_CNT,
tb[ETHTOOL_A_TSCONFIG_TX_TYPES],
ts_tx_type_names, info->extack,
&config_mod); if (ret < 0) goto err_free_hwprov;
/* Select only one tx type at a time */ if (ffs(req_tx_type) != fls(req_tx_type)) {
ret = -EINVAL; goto err_free_hwprov;
}
hwtst_config.tx_type = ffs(req_tx_type) - 1;
}
if (tb[ETHTOOL_A_TSCONFIG_RX_FILTERS]) {
u32 req_rx_filter;
req_rx_filter = BIT(hwtst_config.rx_filter);
ret = ethnl_update_bitset32(&req_rx_filter,
__HWTSTAMP_FILTER_CNT,
tb[ETHTOOL_A_TSCONFIG_RX_FILTERS],
ts_rx_filter_names, info->extack,
&config_mod); if (ret < 0) goto err_free_hwprov;
/* Select only one rx filter at a time */ if (ffs(req_rx_filter) != fls(req_rx_filter)) {
ret = -EINVAL; goto err_free_hwprov;
}
/* Disable current time stamping if we try to enable * another one
*/
ret = dev_set_hwtstamp_phylib(dev, &zero_config, info->extack); if (ret < 0) goto err_free_hwprov;
/* Change the selected hwtstamp source */
__hwprov = rcu_replace_pointer_rtnl(dev->hwprov, hwprov); if (__hwprov)
kfree_rcu(__hwprov, rcu_head);
}
if (config_mod) {
ret = dev_set_hwtstamp_phylib(dev, &hwtst_config,
info->extack); if (ret < 0) return ret;
}
ret = tsconfig_send_reply(dev, info); if (ret && ret != -EOPNOTSUPP) {
NL_SET_ERR_MSG(info->extack, "error while reading the new configuration set"); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.