Merge branch 'convert-net-drivers-to-ndo_hwtstamp-api-part-2'

Vadim Fedorenko says:

====================
convert net drivers to ndo_hwtstamp API part 2

This is part 2 of patchset to convert drivers which support HW
timestamping to use .ndo_hwtstamp_get()/.ndo_hwtstamp_set() callbacks.
The new API uses netlink to communicate with user-space and have some
test coverage.
====================

Link: https://patch.msgid.link/20251023220457.3201122-1-vadim.fedorenko@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2025-10-27 18:04:38 -07:00
15 changed files with 216 additions and 220 deletions

View File

@@ -804,6 +804,11 @@ struct hnae3_ae_ops {
int (*dbg_get_read_func)(struct hnae3_handle *handle,
enum hnae3_dbg_cmd cmd,
read_func *func);
int (*hwtstamp_get)(struct hnae3_handle *handle,
struct kernel_hwtstamp_config *config);
int (*hwtstamp_set)(struct hnae3_handle *handle,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
};
struct hnae3_dcb_ops {

View File

@@ -2419,6 +2419,35 @@ static int hns3_nic_do_ioctl(struct net_device *netdev,
return h->ae_algo->ops->do_ioctl(h, ifr, cmd);
}
static int hns3_nic_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct hnae3_handle *h = hns3_get_handle(netdev);
if (!netif_running(netdev))
return -EINVAL;
if (!h->ae_algo->ops->hwtstamp_get)
return -EOPNOTSUPP;
return h->ae_algo->ops->hwtstamp_get(h, config);
}
static int hns3_nic_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct hnae3_handle *h = hns3_get_handle(netdev);
if (!netif_running(netdev))
return -EINVAL;
if (!h->ae_algo->ops->hwtstamp_set)
return -EOPNOTSUPP;
return h->ae_algo->ops->hwtstamp_set(h, config, extack);
}
static int hns3_nic_set_features(struct net_device *netdev,
netdev_features_t features)
{
@@ -3048,6 +3077,8 @@ static const struct net_device_ops hns3_nic_netdev_ops = {
.ndo_set_vf_rate = hns3_nic_set_vf_rate,
.ndo_set_vf_mac = hns3_nic_set_vf_mac,
.ndo_select_queue = hns3_nic_select_queue,
.ndo_hwtstamp_get = hns3_nic_hwtstamp_get,
.ndo_hwtstamp_set = hns3_nic_hwtstamp_set,
};
bool hns3_is_phys_func(struct pci_dev *pdev)

View File

@@ -9445,15 +9445,8 @@ static int hclge_do_ioctl(struct hnae3_handle *handle, struct ifreq *ifr,
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
switch (cmd) {
case SIOCGHWTSTAMP:
return hclge_ptp_get_cfg(hdev, ifr);
case SIOCSHWTSTAMP:
return hclge_ptp_set_cfg(hdev, ifr);
default:
if (!hdev->hw.mac.phydev)
return hclge_mii_ioctl(hdev, ifr, cmd);
}
if (!hdev->hw.mac.phydev)
return hclge_mii_ioctl(hdev, ifr, cmd);
return phy_mii_ioctl(hdev->hw.mac.phydev, ifr, cmd);
}
@@ -12901,6 +12894,8 @@ static const struct hnae3_ae_ops hclge_ops = {
.get_dscp_prio = hclge_get_dscp_prio,
.get_wol = hclge_get_wol,
.set_wol = hclge_set_wol,
.hwtstamp_get = hclge_ptp_get_cfg,
.hwtstamp_set = hclge_ptp_set_cfg,
};
static struct hnae3_ae_algo ae_algo = {

View File

@@ -204,13 +204,17 @@ static int hclge_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
return 0;
}
int hclge_ptp_get_cfg(struct hclge_dev *hdev, struct ifreq *ifr)
int hclge_ptp_get_cfg(struct hnae3_handle *handle,
struct kernel_hwtstamp_config *config)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state))
return -EOPNOTSUPP;
return copy_to_user(ifr->ifr_data, &hdev->ptp->ts_cfg,
sizeof(struct hwtstamp_config)) ? -EFAULT : 0;
*config = hdev->ptp->ts_cfg;
return 0;
}
static int hclge_ptp_int_en(struct hclge_dev *hdev, bool en)
@@ -269,7 +273,7 @@ static int hclge_ptp_cfg(struct hclge_dev *hdev, u32 cfg)
return ret;
}
static int hclge_ptp_set_tx_mode(struct hwtstamp_config *cfg,
static int hclge_ptp_set_tx_mode(struct kernel_hwtstamp_config *cfg,
unsigned long *flags, u32 *ptp_cfg)
{
switch (cfg->tx_type) {
@@ -287,7 +291,7 @@ static int hclge_ptp_set_tx_mode(struct hwtstamp_config *cfg,
return 0;
}
static int hclge_ptp_set_rx_mode(struct hwtstamp_config *cfg,
static int hclge_ptp_set_rx_mode(struct kernel_hwtstamp_config *cfg,
unsigned long *flags, u32 *ptp_cfg)
{
int rx_filter = cfg->rx_filter;
@@ -332,7 +336,7 @@ static int hclge_ptp_set_rx_mode(struct hwtstamp_config *cfg,
}
static int hclge_ptp_set_ts_mode(struct hclge_dev *hdev,
struct hwtstamp_config *cfg)
struct kernel_hwtstamp_config *cfg)
{
unsigned long flags = hdev->ptp->flags;
u32 ptp_cfg = 0;
@@ -359,9 +363,12 @@ static int hclge_ptp_set_ts_mode(struct hclge_dev *hdev,
return 0;
}
int hclge_ptp_set_cfg(struct hclge_dev *hdev, struct ifreq *ifr)
int hclge_ptp_set_cfg(struct hnae3_handle *handle,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct hwtstamp_config cfg;
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
int ret;
if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state)) {
@@ -369,16 +376,13 @@ int hclge_ptp_set_cfg(struct hclge_dev *hdev, struct ifreq *ifr)
return -EOPNOTSUPP;
}
if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
return -EFAULT;
ret = hclge_ptp_set_ts_mode(hdev, &cfg);
ret = hclge_ptp_set_ts_mode(hdev, config);
if (ret)
return ret;
hdev->ptp->ts_cfg = cfg;
hdev->ptp->ts_cfg = *config;
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
return 0;
}
int hclge_ptp_get_ts_info(struct hnae3_handle *handle,

View File

@@ -62,7 +62,7 @@ struct hclge_ptp {
unsigned long flags;
void __iomem *io_base;
struct ptp_clock_info info;
struct hwtstamp_config ts_cfg;
struct kernel_hwtstamp_config ts_cfg;
spinlock_t lock; /* protects ptp registers */
u32 ptp_cfg;
u32 last_tx_seqid;
@@ -133,8 +133,11 @@ bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb);
void hclge_ptp_clean_tx_hwts(struct hclge_dev *hdev);
void hclge_ptp_get_rx_hwts(struct hnae3_handle *handle, struct sk_buff *skb,
u32 nsec, u32 sec);
int hclge_ptp_get_cfg(struct hclge_dev *hdev, struct ifreq *ifr);
int hclge_ptp_set_cfg(struct hclge_dev *hdev, struct ifreq *ifr);
int hclge_ptp_get_cfg(struct hnae3_handle *handle,
struct kernel_hwtstamp_config *config);
int hclge_ptp_set_cfg(struct hnae3_handle *handle,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
int hclge_ptp_init(struct hclge_dev *hdev);
void hclge_ptp_uninit(struct hclge_dev *hdev);
int hclge_ptp_get_ts_info(struct hnae3_handle *handle,

View File

@@ -527,7 +527,7 @@ struct otx2_nic {
u32 nix_lmt_size;
struct otx2_ptp *ptp;
struct hwtstamp_config tstamp;
struct kernel_hwtstamp_config tstamp;
unsigned long rq_bmap;
@@ -1098,8 +1098,11 @@ int otx2_open(struct net_device *netdev);
int otx2_stop(struct net_device *netdev);
int otx2_set_real_num_queues(struct net_device *netdev,
int tx_queues, int rx_queues);
int otx2_ioctl(struct net_device *netdev, struct ifreq *req, int cmd);
int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr);
int otx2_config_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
int otx2_config_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
/* MCAM filter related APIs */
int otx2_mcam_flow_init(struct otx2_nic *pf);

View File

@@ -2445,18 +2445,26 @@ static int otx2_config_hw_tx_tstamp(struct otx2_nic *pfvf, bool enable)
return 0;
}
int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
int otx2_config_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
*config = pfvf->tstamp;
return 0;
}
EXPORT_SYMBOL(otx2_config_hwtstamp_get);
int otx2_config_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
struct hwtstamp_config config;
if (!pfvf->ptp)
return -ENODEV;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
switch (config.tx_type) {
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
if (pfvf->flags & OTX2_FLAG_PTP_ONESTEP_SYNC)
pfvf->flags &= ~OTX2_FLAG_PTP_ONESTEP_SYNC;
@@ -2465,8 +2473,11 @@ int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
otx2_config_hw_tx_tstamp(pfvf, false);
break;
case HWTSTAMP_TX_ONESTEP_SYNC:
if (!test_bit(CN10K_PTP_ONESTEP, &pfvf->hw.cap_flag))
if (!test_bit(CN10K_PTP_ONESTEP, &pfvf->hw.cap_flag)) {
NL_SET_ERR_MSG_MOD(extack,
"One-step time stamping is not supported");
return -ERANGE;
}
pfvf->flags |= OTX2_FLAG_PTP_ONESTEP_SYNC;
schedule_delayed_work(&pfvf->ptp->synctstamp_work,
msecs_to_jiffies(500));
@@ -2478,7 +2489,7 @@ int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
return -ERANGE;
}
switch (config.rx_filter) {
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
otx2_config_hw_rx_tstamp(pfvf, false);
break;
@@ -2497,35 +2508,17 @@ int otx2_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
otx2_config_hw_rx_tstamp(pfvf, true);
config.rx_filter = HWTSTAMP_FILTER_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
default:
return -ERANGE;
}
memcpy(&pfvf->tstamp, &config, sizeof(config));
pfvf->tstamp = *config;
return copy_to_user(ifr->ifr_data, &config,
sizeof(config)) ? -EFAULT : 0;
return 0;
}
EXPORT_SYMBOL(otx2_config_hwtstamp);
int otx2_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
struct hwtstamp_config *cfg = &pfvf->tstamp;
switch (cmd) {
case SIOCSHWTSTAMP:
return otx2_config_hwtstamp(netdev, req);
case SIOCGHWTSTAMP:
return copy_to_user(req->ifr_data, cfg,
sizeof(*cfg)) ? -EFAULT : 0;
default:
return -EOPNOTSUPP;
}
}
EXPORT_SYMBOL(otx2_ioctl);
EXPORT_SYMBOL(otx2_config_hwtstamp_set);
static int otx2_do_set_vf_mac(struct otx2_nic *pf, int vf, const u8 *mac)
{
@@ -2942,7 +2935,6 @@ static const struct net_device_ops otx2_netdev_ops = {
.ndo_set_features = otx2_set_features,
.ndo_tx_timeout = otx2_tx_timeout,
.ndo_get_stats64 = otx2_get_stats64,
.ndo_eth_ioctl = otx2_ioctl,
.ndo_set_vf_mac = otx2_set_vf_mac,
.ndo_set_vf_vlan = otx2_set_vf_vlan,
.ndo_get_vf_config = otx2_get_vf_config,
@@ -2951,6 +2943,8 @@ static const struct net_device_ops otx2_netdev_ops = {
.ndo_xdp_xmit = otx2_xdp_xmit,
.ndo_setup_tc = otx2_setup_tc,
.ndo_set_vf_trust = otx2_ndo_set_vf_trust,
.ndo_hwtstamp_get = otx2_config_hwtstamp_get,
.ndo_hwtstamp_set = otx2_config_hwtstamp_set,
};
int otx2_wq_init(struct otx2_nic *pf)

View File

@@ -534,8 +534,9 @@ static const struct net_device_ops otx2vf_netdev_ops = {
.ndo_set_features = otx2vf_set_features,
.ndo_get_stats64 = otx2_get_stats64,
.ndo_tx_timeout = otx2_tx_timeout,
.ndo_eth_ioctl = otx2_ioctl,
.ndo_setup_tc = otx2_setup_tc,
.ndo_hwtstamp_get = otx2_config_hwtstamp_get,
.ndo_hwtstamp_set = otx2_config_hwtstamp_set,
};
static int otx2_vf_wq_init(struct otx2_nic *vf)

View File

@@ -2420,21 +2420,22 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
static int mlx4_en_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
static int mlx4_en_hwtstamp_set(struct net_device *dev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
struct hwtstamp_config config;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
/* device doesn't support time stamping */
if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS))
if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)) {
NL_SET_ERR_MSG_MOD(extack,
"device doesn't support time stamping");
return -EINVAL;
}
/* TX HW timestamp */
switch (config.tx_type) {
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
case HWTSTAMP_TX_ON:
break;
@@ -2443,7 +2444,7 @@ static int mlx4_en_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
}
/* RX HW timestamp */
switch (config.rx_filter) {
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
break;
case HWTSTAMP_FILTER_ALL:
@@ -2461,39 +2462,27 @@ static int mlx4_en_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
case HWTSTAMP_FILTER_NTP_ALL:
config.rx_filter = HWTSTAMP_FILTER_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
default:
return -ERANGE;
}
if (mlx4_en_reset_config(dev, config, dev->features)) {
config.tx_type = HWTSTAMP_TX_OFF;
config.rx_filter = HWTSTAMP_FILTER_NONE;
config->tx_type = HWTSTAMP_TX_OFF;
config->rx_filter = HWTSTAMP_FILTER_NONE;
}
return copy_to_user(ifr->ifr_data, &config,
sizeof(config)) ? -EFAULT : 0;
return 0;
}
static int mlx4_en_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
static int mlx4_en_hwtstamp_get(struct net_device *dev,
struct kernel_hwtstamp_config *config)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
return copy_to_user(ifr->ifr_data, &priv->hwtstamp_config,
sizeof(priv->hwtstamp_config)) ? -EFAULT : 0;
}
static int mlx4_en_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
case SIOCSHWTSTAMP:
return mlx4_en_hwtstamp_set(dev, ifr);
case SIOCGHWTSTAMP:
return mlx4_en_hwtstamp_get(dev, ifr);
default:
return -EOPNOTSUPP;
}
*config = priv->hwtstamp_config;
return 0;
}
static netdev_features_t mlx4_en_fix_features(struct net_device *netdev,
@@ -2560,7 +2549,7 @@ static int mlx4_en_set_features(struct net_device *netdev,
}
if (reset) {
ret = mlx4_en_reset_config(netdev, priv->hwtstamp_config,
ret = mlx4_en_reset_config(netdev, &priv->hwtstamp_config,
features);
if (ret)
return ret;
@@ -2844,7 +2833,6 @@ static const struct net_device_ops mlx4_netdev_ops = {
.ndo_set_mac_address = mlx4_en_set_mac,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = mlx4_en_change_mtu,
.ndo_eth_ioctl = mlx4_en_ioctl,
.ndo_tx_timeout = mlx4_en_tx_timeout,
.ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid,
@@ -2858,6 +2846,8 @@ static const struct net_device_ops mlx4_netdev_ops = {
.ndo_features_check = mlx4_en_features_check,
.ndo_set_tx_maxrate = mlx4_en_set_tx_maxrate,
.ndo_bpf = mlx4_xdp,
.ndo_hwtstamp_get = mlx4_en_hwtstamp_get,
.ndo_hwtstamp_set = mlx4_en_hwtstamp_set,
};
static const struct net_device_ops mlx4_netdev_ops_master = {
@@ -3512,7 +3502,7 @@ out:
}
int mlx4_en_reset_config(struct net_device *dev,
struct hwtstamp_config ts_config,
struct kernel_hwtstamp_config *ts_config,
netdev_features_t features)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
@@ -3522,8 +3512,8 @@ int mlx4_en_reset_config(struct net_device *dev,
int port_up = 0;
int err = 0;
if (priv->hwtstamp_config.tx_type == ts_config.tx_type &&
priv->hwtstamp_config.rx_filter == ts_config.rx_filter &&
if (priv->hwtstamp_config.tx_type == ts_config->tx_type &&
priv->hwtstamp_config.rx_filter == ts_config->rx_filter &&
!DEV_FEATURE_CHANGED(dev, features, NETIF_F_HW_VLAN_CTAG_RX) &&
!DEV_FEATURE_CHANGED(dev, features, NETIF_F_RXFCS))
return 0; /* Nothing to change */
@@ -3542,7 +3532,7 @@ int mlx4_en_reset_config(struct net_device *dev,
mutex_lock(&mdev->state_lock);
memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
memcpy(&new_prof.hwtstamp_config, &ts_config, sizeof(ts_config));
memcpy(&new_prof.hwtstamp_config, ts_config, sizeof(*ts_config));
err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
if (err)
@@ -3560,7 +3550,7 @@ int mlx4_en_reset_config(struct net_device *dev,
dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
else
dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
} else if (ts_config.rx_filter == HWTSTAMP_FILTER_NONE) {
} else if (ts_config->rx_filter == HWTSTAMP_FILTER_NONE) {
/* RX time-stamping is OFF, update the RX vlan offload
* to the latest wanted state
*/
@@ -3581,7 +3571,7 @@ int mlx4_en_reset_config(struct net_device *dev,
* Regardless of the caller's choice,
* Turn Off RX vlan offload in case of time-stamping is ON
*/
if (ts_config.rx_filter != HWTSTAMP_FILTER_NONE) {
if (ts_config->rx_filter != HWTSTAMP_FILTER_NONE) {
if (dev->features & NETIF_F_HW_VLAN_CTAG_RX)
en_warn(priv, "Turning off RX vlan offload since RX time-stamping is ON\n");
dev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;

View File

@@ -388,7 +388,7 @@ struct mlx4_en_port_profile {
u8 num_up;
int rss_rings;
int inline_thold;
struct hwtstamp_config hwtstamp_config;
struct kernel_hwtstamp_config hwtstamp_config;
};
struct mlx4_en_profile {
@@ -612,7 +612,7 @@ struct mlx4_en_priv {
bool wol;
struct device *ddev;
struct hlist_head mac_hash[MLX4_EN_MAC_HASH_SIZE];
struct hwtstamp_config hwtstamp_config;
struct kernel_hwtstamp_config hwtstamp_config;
u32 counter_index;
#ifdef CONFIG_MLX4_EN_DCB
@@ -780,7 +780,7 @@ void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev);
int mlx4_en_moderation_update(struct mlx4_en_priv *priv);
int mlx4_en_reset_config(struct net_device *dev,
struct hwtstamp_config ts_config,
struct kernel_hwtstamp_config *ts_config,
netdev_features_t new_features);
void mlx4_en_update_pfc_stats_bitmap(struct mlx4_dev *dev,
struct mlx4_en_stats_bitmap *stats_bitmap,

View File

@@ -2335,20 +2335,6 @@ static int ionic_stop(struct net_device *netdev)
return 0;
}
static int ionic_eth_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
struct ionic_lif *lif = netdev_priv(netdev);
switch (cmd) {
case SIOCSHWTSTAMP:
return ionic_lif_hwstamp_set(lif, ifr);
case SIOCGHWTSTAMP:
return ionic_lif_hwstamp_get(lif, ifr);
default:
return -EOPNOTSUPP;
}
}
static int ionic_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivf)
{
@@ -2812,7 +2798,6 @@ static int ionic_xdp(struct net_device *netdev, struct netdev_bpf *bpf)
static const struct net_device_ops ionic_netdev_ops = {
.ndo_open = ionic_open,
.ndo_stop = ionic_stop,
.ndo_eth_ioctl = ionic_eth_ioctl,
.ndo_start_xmit = ionic_start_xmit,
.ndo_bpf = ionic_xdp,
.ndo_xdp_xmit = ionic_xdp_xmit,
@@ -2833,6 +2818,8 @@ static const struct net_device_ops ionic_netdev_ops = {
.ndo_get_vf_config = ionic_get_vf_config,
.ndo_set_vf_link_state = ionic_set_vf_link_state,
.ndo_get_vf_stats = ionic_get_vf_stats,
.ndo_hwtstamp_get = ionic_hwstamp_get,
.ndo_hwtstamp_set = ionic_hwstamp_set,
};
static int ionic_cmb_reconfig(struct ionic_lif *lif,

View File

@@ -6,7 +6,7 @@
#include <linux/ptp_clock_kernel.h>
#include <linux/timecounter.h>
#include <uapi/linux/net_tstamp.h>
#include <linux/net_tstamp.h>
#include <linux/dim.h>
#include <linux/pci.h>
#include "ionic_rx_filter.h"
@@ -254,7 +254,7 @@ struct ionic_phc {
struct timecounter tc;
struct mutex config_lock; /* lock for ts_config */
struct hwtstamp_config ts_config;
struct kernel_hwtstamp_config ts_config;
u64 ts_config_rx_filt;
u32 ts_config_tx_mode;
@@ -362,8 +362,11 @@ int ionic_lif_size(struct ionic *ionic);
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
void ionic_lif_hwstamp_replay(struct ionic_lif *lif);
void ionic_lif_hwstamp_recreate_queues(struct ionic_lif *lif);
int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr);
int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr);
int ionic_hwstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
int ionic_hwstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 counter);
void ionic_lif_register_phc(struct ionic_lif *lif);
void ionic_lif_unregister_phc(struct ionic_lif *lif);
@@ -373,12 +376,15 @@ void ionic_lif_free_phc(struct ionic_lif *lif);
static inline void ionic_lif_hwstamp_replay(struct ionic_lif *lif) {}
static inline void ionic_lif_hwstamp_recreate_queues(struct ionic_lif *lif) {}
static inline int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
static inline int ionic_hwstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
return -EOPNOTSUPP;
}
static inline int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr)
static inline int ionic_hwstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
return -EOPNOTSUPP;
}

View File

@@ -65,11 +65,12 @@ static u64 ionic_hwstamp_rx_filt(int config_rx_filter)
}
static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif *lif,
struct hwtstamp_config *new_ts)
struct kernel_hwtstamp_config *new_ts,
struct netlink_ext_ack *extack)
{
struct kernel_hwtstamp_config *config;
struct kernel_hwtstamp_config ts = {};
struct ionic *ionic = lif->ionic;
struct hwtstamp_config *config;
struct hwtstamp_config ts;
int tx_mode = 0;
u64 rx_filt = 0;
int err, err2;
@@ -99,12 +100,16 @@ static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif *lif,
tx_mode = ionic_hwstamp_tx_mode(config->tx_type);
if (tx_mode < 0) {
NL_SET_ERR_MSG_MOD(extack,
"TX time stamping mode isn't supported");
err = tx_mode;
goto err_queues;
}
mask = cpu_to_le64(BIT_ULL(tx_mode));
if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask) {
NL_SET_ERR_MSG_MOD(extack,
"TX time stamping mode isn't supported");
err = -ERANGE;
goto err_queues;
}
@@ -124,32 +129,47 @@ static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif *lif,
if (tx_mode) {
err = ionic_lif_create_hwstamp_txq(lif);
if (err)
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"Error creating TX timestamp queue");
goto err_queues;
}
}
if (rx_filt) {
err = ionic_lif_create_hwstamp_rxq(lif);
if (err)
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"Error creating RX timestamp queue");
goto err_queues;
}
}
if (tx_mode != lif->phc->ts_config_tx_mode) {
err = ionic_lif_set_hwstamp_txmode(lif, tx_mode);
if (err)
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"Error enabling TX timestamp mode");
goto err_txmode;
}
}
if (rx_filt != lif->phc->ts_config_rx_filt) {
err = ionic_lif_set_hwstamp_rxfilt(lif, rx_filt);
if (err)
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"Error enabling RX timestamp mode");
goto err_rxfilt;
}
}
if (rx_all != (lif->phc->ts_config.rx_filter == HWTSTAMP_FILTER_ALL)) {
err = ionic_lif_config_hwstamp_rxq_all(lif, rx_all);
if (err)
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"Error enabling RX timestamp mode");
goto err_rxall;
}
}
memcpy(&lif->phc->ts_config, config, sizeof(*config));
@@ -183,28 +203,24 @@ err_queues:
return err;
}
int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
int ionic_hwstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct hwtstamp_config config;
struct ionic_lif *lif = netdev_priv(netdev);
int err;
if (!lif->phc || !lif->phc->ptp)
return -EOPNOTSUPP;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
mutex_lock(&lif->queue_lock);
err = ionic_lif_hwstamp_set_ts_config(lif, &config);
err = ionic_lif_hwstamp_set_ts_config(lif, config, extack);
mutex_unlock(&lif->queue_lock);
if (err) {
netdev_info(lif->netdev, "hwstamp set failed: %d\n", err);
return err;
}
if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
return -EFAULT;
return 0;
}
@@ -216,7 +232,7 @@ void ionic_lif_hwstamp_replay(struct ionic_lif *lif)
return;
mutex_lock(&lif->queue_lock);
err = ionic_lif_hwstamp_set_ts_config(lif, NULL);
err = ionic_lif_hwstamp_set_ts_config(lif, NULL, NULL);
mutex_unlock(&lif->queue_lock);
if (err)
netdev_info(lif->netdev, "hwstamp replay failed: %d\n", err);
@@ -246,19 +262,18 @@ void ionic_lif_hwstamp_recreate_queues(struct ionic_lif *lif)
mutex_unlock(&lif->phc->config_lock);
}
int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr)
int ionic_hwstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct hwtstamp_config config;
struct ionic_lif *lif = netdev_priv(netdev);
if (!lif->phc || !lif->phc->ptp)
return -EOPNOTSUPP;
mutex_lock(&lif->phc->config_lock);
memcpy(&config, &lif->phc->ts_config, sizeof(config));
memcpy(config, &lif->phc->ts_config, sizeof(*config));
mutex_unlock(&lif->phc->config_lock);
if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
return -EFAULT;
return 0;
}

View File

@@ -2410,41 +2410,38 @@ static int ravb_close(struct net_device *ndev)
return 0;
}
static int ravb_hwtstamp_get(struct net_device *ndev, struct ifreq *req)
static int ravb_hwtstamp_get(struct net_device *ndev,
struct kernel_hwtstamp_config *config)
{
struct ravb_private *priv = netdev_priv(ndev);
struct hwtstamp_config config;
config.flags = 0;
config.tx_type = priv->tstamp_tx_ctrl ? HWTSTAMP_TX_ON :
HWTSTAMP_TX_OFF;
config->flags = 0;
config->tx_type = priv->tstamp_tx_ctrl ? HWTSTAMP_TX_ON :
HWTSTAMP_TX_OFF;
switch (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE) {
case RAVB_RXTSTAMP_TYPE_V2_L2_EVENT:
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
break;
case RAVB_RXTSTAMP_TYPE_ALL:
config.rx_filter = HWTSTAMP_FILTER_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
default:
config.rx_filter = HWTSTAMP_FILTER_NONE;
config->rx_filter = HWTSTAMP_FILTER_NONE;
}
return copy_to_user(req->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
return 0;
}
/* Control hardware time stamping */
static int ravb_hwtstamp_set(struct net_device *ndev, struct ifreq *req)
static int ravb_hwtstamp_set(struct net_device *ndev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct ravb_private *priv = netdev_priv(ndev);
struct hwtstamp_config config;
u32 tstamp_rx_ctrl = RAVB_RXTSTAMP_ENABLED;
u32 tstamp_tx_ctrl;
if (copy_from_user(&config, req->ifr_data, sizeof(config)))
return -EFAULT;
switch (config.tx_type) {
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
tstamp_tx_ctrl = 0;
break;
@@ -2455,7 +2452,7 @@ static int ravb_hwtstamp_set(struct net_device *ndev, struct ifreq *req)
return -ERANGE;
}
switch (config.rx_filter) {
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
tstamp_rx_ctrl = 0;
break;
@@ -2463,36 +2460,14 @@ static int ravb_hwtstamp_set(struct net_device *ndev, struct ifreq *req)
tstamp_rx_ctrl |= RAVB_RXTSTAMP_TYPE_V2_L2_EVENT;
break;
default:
config.rx_filter = HWTSTAMP_FILTER_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL;
tstamp_rx_ctrl |= RAVB_RXTSTAMP_TYPE_ALL;
}
priv->tstamp_tx_ctrl = tstamp_tx_ctrl;
priv->tstamp_rx_ctrl = tstamp_rx_ctrl;
return copy_to_user(req->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
}
/* ioctl to device function */
static int ravb_do_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
{
struct phy_device *phydev = ndev->phydev;
if (!netif_running(ndev))
return -EINVAL;
if (!phydev)
return -ENODEV;
switch (cmd) {
case SIOCGHWTSTAMP:
return ravb_hwtstamp_get(ndev, req);
case SIOCSHWTSTAMP:
return ravb_hwtstamp_set(ndev, req);
}
return phy_mii_ioctl(phydev, req, cmd);
return 0;
}
static int ravb_change_mtu(struct net_device *ndev, int new_mtu)
@@ -2628,11 +2603,13 @@ static const struct net_device_ops ravb_netdev_ops = {
.ndo_get_stats = ravb_get_stats,
.ndo_set_rx_mode = ravb_set_rx_mode,
.ndo_tx_timeout = ravb_tx_timeout,
.ndo_eth_ioctl = ravb_do_ioctl,
.ndo_eth_ioctl = phy_do_ioctl_running,
.ndo_change_mtu = ravb_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
.ndo_set_features = ravb_set_features,
.ndo_hwtstamp_get = ravb_hwtstamp_get,
.ndo_hwtstamp_set = ravb_hwtstamp_set,
};
/* MDIO bus init function */

View File

@@ -1793,46 +1793,44 @@ static struct net_device_stats *rswitch_get_stats(struct net_device *ndev)
return &ndev->stats;
}
static int rswitch_hwstamp_get(struct net_device *ndev, struct ifreq *req)
static int rswitch_hwstamp_get(struct net_device *ndev,
struct kernel_hwtstamp_config *config)
{
struct rswitch_device *rdev = netdev_priv(ndev);
struct rcar_gen4_ptp_private *ptp_priv;
struct hwtstamp_config config;
ptp_priv = rdev->priv->ptp_priv;
config.flags = 0;
config.tx_type = ptp_priv->tstamp_tx_ctrl ? HWTSTAMP_TX_ON :
config->flags = 0;
config->tx_type = ptp_priv->tstamp_tx_ctrl ? HWTSTAMP_TX_ON :
HWTSTAMP_TX_OFF;
switch (ptp_priv->tstamp_rx_ctrl & RCAR_GEN4_RXTSTAMP_TYPE) {
case RCAR_GEN4_RXTSTAMP_TYPE_V2_L2_EVENT:
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
break;
case RCAR_GEN4_RXTSTAMP_TYPE_ALL:
config.rx_filter = HWTSTAMP_FILTER_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
default:
config.rx_filter = HWTSTAMP_FILTER_NONE;
config->rx_filter = HWTSTAMP_FILTER_NONE;
break;
}
return copy_to_user(req->ifr_data, &config, sizeof(config)) ? -EFAULT : 0;
return 0;
}
static int rswitch_hwstamp_set(struct net_device *ndev, struct ifreq *req)
static int rswitch_hwstamp_set(struct net_device *ndev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct rswitch_device *rdev = netdev_priv(ndev);
u32 tstamp_rx_ctrl = RCAR_GEN4_RXTSTAMP_ENABLED;
struct hwtstamp_config config;
u32 tstamp_tx_ctrl;
if (copy_from_user(&config, req->ifr_data, sizeof(config)))
return -EFAULT;
if (config.flags)
if (config->flags)
return -EINVAL;
switch (config.tx_type) {
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
tstamp_tx_ctrl = 0;
break;
@@ -1843,7 +1841,7 @@ static int rswitch_hwstamp_set(struct net_device *ndev, struct ifreq *req)
return -ERANGE;
}
switch (config.rx_filter) {
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
tstamp_rx_ctrl = 0;
break;
@@ -1851,7 +1849,7 @@ static int rswitch_hwstamp_set(struct net_device *ndev, struct ifreq *req)
tstamp_rx_ctrl |= RCAR_GEN4_RXTSTAMP_TYPE_V2_L2_EVENT;
break;
default:
config.rx_filter = HWTSTAMP_FILTER_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL;
tstamp_rx_ctrl |= RCAR_GEN4_RXTSTAMP_TYPE_ALL;
break;
}
@@ -1859,22 +1857,7 @@ static int rswitch_hwstamp_set(struct net_device *ndev, struct ifreq *req)
rdev->priv->ptp_priv->tstamp_tx_ctrl = tstamp_tx_ctrl;
rdev->priv->ptp_priv->tstamp_rx_ctrl = tstamp_rx_ctrl;
return copy_to_user(req->ifr_data, &config, sizeof(config)) ? -EFAULT : 0;
}
static int rswitch_eth_ioctl(struct net_device *ndev, struct ifreq *req, int cmd)
{
if (!netif_running(ndev))
return -EINVAL;
switch (cmd) {
case SIOCGHWTSTAMP:
return rswitch_hwstamp_get(ndev, req);
case SIOCSHWTSTAMP:
return rswitch_hwstamp_set(ndev, req);
default:
return phy_mii_ioctl(ndev->phydev, req, cmd);
}
return 0;
}
static int rswitch_get_port_parent_id(struct net_device *ndev,
@@ -1905,11 +1888,13 @@ static const struct net_device_ops rswitch_netdev_ops = {
.ndo_stop = rswitch_stop,
.ndo_start_xmit = rswitch_start_xmit,
.ndo_get_stats = rswitch_get_stats,
.ndo_eth_ioctl = rswitch_eth_ioctl,
.ndo_eth_ioctl = phy_do_ioctl_running,
.ndo_get_port_parent_id = rswitch_get_port_parent_id,
.ndo_get_phys_port_name = rswitch_get_phys_port_name,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
.ndo_hwtstamp_get = rswitch_hwstamp_get,
.ndo_hwtstamp_set = rswitch_hwstamp_set,
};
bool is_rdev(const struct net_device *ndev)