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

Vadim Fedorenko says:

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

This is part 1 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. Part 2 will contain another 6 patches from v1 of the
series.
There are some drivers left with old ioctl interface after this series:
- mlx5 driver be shortly converted by nVidia folks
- TI netcp ethss driver which needs separate series which I'll post
  after this one.
====================

Link: https://patch.msgid.link/20251016152515.3510991-1-vadim.fedorenko@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2025-10-20 17:30:28 -07:00
18 changed files with 233 additions and 321 deletions

View File

@@ -1754,27 +1754,6 @@ static int xgbe_set_mac_address(struct net_device *netdev, void *addr)
return 0;
}
static int xgbe_ioctl(struct net_device *netdev, struct ifreq *ifreq, int cmd)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
int ret;
switch (cmd) {
case SIOCGHWTSTAMP:
ret = xgbe_get_hwtstamp_settings(pdata, ifreq);
break;
case SIOCSHWTSTAMP:
ret = xgbe_set_hwtstamp_settings(pdata, ifreq);
break;
default:
ret = -EOPNOTSUPP;
}
return ret;
}
static int xgbe_change_mtu(struct net_device *netdev, int mtu)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
@@ -2020,7 +1999,6 @@ static const struct net_device_ops xgbe_netdev_ops = {
.ndo_set_rx_mode = xgbe_set_rx_mode,
.ndo_set_mac_address = xgbe_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_eth_ioctl = xgbe_ioctl,
.ndo_change_mtu = xgbe_change_mtu,
.ndo_tx_timeout = xgbe_tx_timeout,
.ndo_get_stats64 = xgbe_get_stats64,
@@ -2033,6 +2011,8 @@ static const struct net_device_ops xgbe_netdev_ops = {
.ndo_fix_features = xgbe_fix_features,
.ndo_set_features = xgbe_set_features,
.ndo_features_check = xgbe_features_check,
.ndo_hwtstamp_get = xgbe_get_hwtstamp_settings,
.ndo_hwtstamp_set = xgbe_set_hwtstamp_settings,
};
const struct net_device_ops *xgbe_get_netdev_ops(void)

View File

@@ -157,26 +157,24 @@ unlock:
spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
}
int xgbe_get_hwtstamp_settings(struct xgbe_prv_data *pdata, struct ifreq *ifreq)
int xgbe_get_hwtstamp_settings(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
if (copy_to_user(ifreq->ifr_data, &pdata->tstamp_config,
sizeof(pdata->tstamp_config)))
return -EFAULT;
struct xgbe_prv_data *pdata = netdev_priv(netdev);
*config = pdata->tstamp_config;
return 0;
}
int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata, struct ifreq *ifreq)
int xgbe_set_hwtstamp_settings(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct hwtstamp_config config;
unsigned int mac_tscr;
struct xgbe_prv_data *pdata = netdev_priv(netdev);
unsigned int mac_tscr = 0;
if (copy_from_user(&config, ifreq->ifr_data, sizeof(config)))
return -EFAULT;
mac_tscr = 0;
switch (config.tx_type) {
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
break;
@@ -188,7 +186,7 @@ int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata, struct ifreq *ifreq)
return -ERANGE;
}
switch (config.rx_filter) {
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
break;
@@ -290,7 +288,7 @@ int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata, struct ifreq *ifreq)
xgbe_config_tstamp(pdata, mac_tscr);
memcpy(&pdata->tstamp_config, &config, sizeof(config));
pdata->tstamp_config = *config;
return 0;
}

View File

@@ -1146,7 +1146,7 @@ struct xgbe_prv_data {
spinlock_t tstamp_lock;
struct ptp_clock_info ptp_clock_info;
struct ptp_clock *ptp_clock;
struct hwtstamp_config tstamp_config;
struct kernel_hwtstamp_config tstamp_config;
unsigned int tstamp_addend;
struct work_struct tx_tstamp_work;
struct sk_buff *tx_tstamp_skb;
@@ -1307,10 +1307,11 @@ void xgbe_update_tstamp_addend(struct xgbe_prv_data *pdata,
void xgbe_set_tstamp_time(struct xgbe_prv_data *pdata, unsigned int sec,
unsigned int nsec);
void xgbe_tx_tstamp(struct work_struct *work);
int xgbe_get_hwtstamp_settings(struct xgbe_prv_data *pdata,
struct ifreq *ifreq);
int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata,
struct ifreq *ifreq);
int xgbe_get_hwtstamp_settings(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
int xgbe_set_hwtstamp_settings(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
void xgbe_prep_tx_tstamp(struct xgbe_prv_data *pdata,
struct sk_buff *skb,
struct xgbe_packet_data *packet);

View File

@@ -258,10 +258,15 @@ static void aq_ndev_set_multicast_settings(struct net_device *ndev)
(void)aq_nic_set_multicast_list(aq_nic, ndev);
}
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
static int aq_ndev_config_hwtstamp(struct aq_nic_s *aq_nic,
struct hwtstamp_config *config)
static int aq_ndev_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct aq_nic_s *aq_nic = netdev_priv(netdev);
if (!IS_REACHABLE(CONFIG_PTP_1588_CLOCK) || !aq_nic->aq_ptp)
return -EOPNOTSUPP;
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
case HWTSTAMP_TX_ON:
@@ -290,59 +295,17 @@ static int aq_ndev_config_hwtstamp(struct aq_nic_s *aq_nic,
return aq_ptp_hwtstamp_config_set(aq_nic->aq_ptp, config);
}
#endif
static int aq_ndev_hwtstamp_set(struct aq_nic_s *aq_nic, struct ifreq *ifr)
{
struct hwtstamp_config config;
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
int ret_val;
#endif
if (!aq_nic->aq_ptp)
return -EOPNOTSUPP;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
ret_val = aq_ndev_config_hwtstamp(aq_nic, &config);
if (ret_val)
return ret_val;
#endif
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
}
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
static int aq_ndev_hwtstamp_get(struct aq_nic_s *aq_nic, struct ifreq *ifr)
{
struct hwtstamp_config config;
if (!aq_nic->aq_ptp)
return -EOPNOTSUPP;
aq_ptp_hwtstamp_config_get(aq_nic->aq_ptp, &config);
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
}
#endif
static int aq_ndev_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
static int aq_ndev_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct aq_nic_s *aq_nic = netdev_priv(netdev);
switch (cmd) {
case SIOCSHWTSTAMP:
return aq_ndev_hwtstamp_set(aq_nic, ifr);
if (!aq_nic->aq_ptp)
return -EOPNOTSUPP;
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
case SIOCGHWTSTAMP:
return aq_ndev_hwtstamp_get(aq_nic, ifr);
#endif
}
return -EOPNOTSUPP;
aq_ptp_hwtstamp_config_get(aq_nic->aq_ptp, config);
return 0;
}
static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto,
@@ -500,12 +463,13 @@ static const struct net_device_ops aq_ndev_ops = {
.ndo_set_mac_address = aq_ndev_set_mac_address,
.ndo_set_features = aq_ndev_set_features,
.ndo_fix_features = aq_ndev_fix_features,
.ndo_eth_ioctl = aq_ndev_ioctl,
.ndo_vlan_rx_add_vid = aq_ndo_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = aq_ndo_vlan_rx_kill_vid,
.ndo_setup_tc = aq_ndo_setup_tc,
.ndo_bpf = aq_xdp,
.ndo_xdp_xmit = aq_xdp_xmit,
.ndo_hwtstamp_get = aq_ndev_hwtstamp_get,
.ndo_hwtstamp_set = aq_ndev_hwtstamp_set,
};
static int __init aq_ndev_init_module(void)

View File

@@ -51,7 +51,7 @@ struct ptp_tx_timeout {
struct aq_ptp_s {
struct aq_nic_s *aq_nic;
struct hwtstamp_config hwtstamp_config;
struct kernel_hwtstamp_config hwtstamp_config;
spinlock_t ptp_lock;
spinlock_t ptp_ring_lock;
struct ptp_clock *ptp_clock;
@@ -567,7 +567,7 @@ static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct skb_shared_hwtsta
}
void aq_ptp_hwtstamp_config_get(struct aq_ptp_s *aq_ptp,
struct hwtstamp_config *config)
struct kernel_hwtstamp_config *config)
{
*config = aq_ptp->hwtstamp_config;
}
@@ -588,7 +588,7 @@ static void aq_ptp_prepare_filters(struct aq_ptp_s *aq_ptp)
}
int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp,
struct hwtstamp_config *config)
struct kernel_hwtstamp_config *config)
{
struct aq_nic_s *aq_nic = aq_ptp->aq_nic;
const struct aq_hw_ops *hw_ops;

View File

@@ -60,9 +60,9 @@ void aq_ptp_tx_hwtstamp(struct aq_nic_s *aq_nic, u64 timestamp);
/* Must be to check available of PTP before call */
void aq_ptp_hwtstamp_config_get(struct aq_ptp_s *aq_ptp,
struct hwtstamp_config *config);
struct kernel_hwtstamp_config *config);
int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp,
struct hwtstamp_config *config);
struct kernel_hwtstamp_config *config);
/* Return either ring is belong to PTP or not*/
bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring);
@@ -130,9 +130,9 @@ static inline int aq_ptp_xmit(struct aq_nic_s *aq_nic, struct sk_buff *skb)
static inline void aq_ptp_tx_hwtstamp(struct aq_nic_s *aq_nic, u64 timestamp) {}
static inline void aq_ptp_hwtstamp_config_get(struct aq_ptp_s *aq_ptp,
struct hwtstamp_config *config) {}
struct kernel_hwtstamp_config *config) {}
static inline int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp,
struct hwtstamp_config *config)
struct kernel_hwtstamp_config *config)
{
return 0;
}

View File

@@ -674,7 +674,7 @@ struct port_info {
struct cxgb_fcoe fcoe;
#endif /* CONFIG_CHELSIO_T4_FCOE */
bool rxtstamp; /* Enable TS */
struct hwtstamp_config tstamp_config;
struct kernel_hwtstamp_config tstamp_config;
bool ptp_enable;
struct sched_table *sched_tbl;
u32 eth_flags;

View File

@@ -3042,12 +3042,87 @@ static void cxgb_get_stats(struct net_device *dev,
ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors;
}
static int cxgb_hwtstamp_get(struct net_device *dev,
struct kernel_hwtstamp_config *config)
{
struct port_info *pi = netdev_priv(dev);
*config = pi->tstamp_config;
return 0;
}
static int cxgb_hwtstamp_set(struct net_device *dev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
if (is_t4(adapter->params.chip)) {
/* For T4 Adapters */
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
pi->rxtstamp = false;
break;
case HWTSTAMP_FILTER_ALL:
pi->rxtstamp = true;
break;
default:
return -ERANGE;
}
pi->tstamp_config = *config;
return 0;
}
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
case HWTSTAMP_TX_ON:
break;
default:
return -ERANGE;
}
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
pi->rxtstamp = false;
break;
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
cxgb4_ptprx_timestamping(pi, pi->port_id, PTP_TS_L4);
break;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
cxgb4_ptprx_timestamping(pi, pi->port_id, PTP_TS_L2_L4);
break;
case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
pi->rxtstamp = true;
break;
default:
return -ERANGE;
}
if (config->tx_type == HWTSTAMP_TX_OFF &&
config->rx_filter == HWTSTAMP_FILTER_NONE) {
if (cxgb4_ptp_txtype(adapter, pi->port_id) >= 0)
pi->ptp_enable = false;
}
if (config->rx_filter != HWTSTAMP_FILTER_NONE) {
if (cxgb4_ptp_redirect_rx_packet(adapter, pi) >= 0)
pi->ptp_enable = true;
}
pi->tstamp_config = *config;
return 0;
}
static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
unsigned int mbox;
int ret = 0, prtad, devad;
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data;
switch (cmd) {
@@ -3076,81 +3151,6 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ret = t4_mdio_wr(pi->adapter, mbox, prtad, devad,
data->reg_num, data->val_in);
break;
case SIOCGHWTSTAMP:
return copy_to_user(req->ifr_data, &pi->tstamp_config,
sizeof(pi->tstamp_config)) ?
-EFAULT : 0;
case SIOCSHWTSTAMP:
if (copy_from_user(&pi->tstamp_config, req->ifr_data,
sizeof(pi->tstamp_config)))
return -EFAULT;
if (!is_t4(adapter->params.chip)) {
switch (pi->tstamp_config.tx_type) {
case HWTSTAMP_TX_OFF:
case HWTSTAMP_TX_ON:
break;
default:
return -ERANGE;
}
switch (pi->tstamp_config.rx_filter) {
case HWTSTAMP_FILTER_NONE:
pi->rxtstamp = false;
break;
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
cxgb4_ptprx_timestamping(pi, pi->port_id,
PTP_TS_L4);
break;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
cxgb4_ptprx_timestamping(pi, pi->port_id,
PTP_TS_L2_L4);
break;
case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
pi->rxtstamp = true;
break;
default:
pi->tstamp_config.rx_filter =
HWTSTAMP_FILTER_NONE;
return -ERANGE;
}
if ((pi->tstamp_config.tx_type == HWTSTAMP_TX_OFF) &&
(pi->tstamp_config.rx_filter ==
HWTSTAMP_FILTER_NONE)) {
if (cxgb4_ptp_txtype(adapter, pi->port_id) >= 0)
pi->ptp_enable = false;
}
if (pi->tstamp_config.rx_filter !=
HWTSTAMP_FILTER_NONE) {
if (cxgb4_ptp_redirect_rx_packet(adapter,
pi) >= 0)
pi->ptp_enable = true;
}
} else {
/* For T4 Adapters */
switch (pi->tstamp_config.rx_filter) {
case HWTSTAMP_FILTER_NONE:
pi->rxtstamp = false;
break;
case HWTSTAMP_FILTER_ALL:
pi->rxtstamp = true;
break;
default:
pi->tstamp_config.rx_filter =
HWTSTAMP_FILTER_NONE;
return -ERANGE;
}
}
return copy_to_user(req->ifr_data, &pi->tstamp_config,
sizeof(pi->tstamp_config)) ?
-EFAULT : 0;
default:
return -EOPNOTSUPP;
}
@@ -3875,6 +3875,8 @@ static const struct net_device_ops cxgb4_netdev_ops = {
.ndo_setup_tc = cxgb_setup_tc,
.ndo_features_check = cxgb_features_check,
.ndo_fix_features = cxgb_fix_features,
.ndo_hwtstamp_get = cxgb_hwtstamp_get,
.ndo_hwtstamp_set = cxgb_hwtstamp_set,
};
#ifdef CONFIG_PCI_IOV

View File

@@ -176,7 +176,7 @@ struct tsnep_adapter {
struct tsnep_gcl gcl[2];
int next_gcl;
struct hwtstamp_config hwtstamp_config;
struct kernel_hwtstamp_config hwtstamp_config;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_clock_info;
/* ptp clock lock */
@@ -203,7 +203,11 @@ extern const struct ethtool_ops tsnep_ethtool_ops;
int tsnep_ptp_init(struct tsnep_adapter *adapter);
void tsnep_ptp_cleanup(struct tsnep_adapter *adapter);
int tsnep_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
int tsnep_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config);
int tsnep_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
int tsnep_tc_init(struct tsnep_adapter *adapter);
void tsnep_tc_cleanup(struct tsnep_adapter *adapter);

View File

@@ -2168,16 +2168,6 @@ static netdev_tx_t tsnep_netdev_xmit_frame(struct sk_buff *skb,
return tsnep_xmit_frame_ring(skb, &adapter->tx[queue_mapping]);
}
static int tsnep_netdev_ioctl(struct net_device *netdev, struct ifreq *ifr,
int cmd)
{
if (!netif_running(netdev))
return -EINVAL;
if (cmd == SIOCSHWTSTAMP || cmd == SIOCGHWTSTAMP)
return tsnep_ptp_ioctl(netdev, ifr, cmd);
return phy_mii_ioctl(netdev->phydev, ifr, cmd);
}
static void tsnep_netdev_set_multicast(struct net_device *netdev)
{
struct tsnep_adapter *adapter = netdev_priv(netdev);
@@ -2384,7 +2374,7 @@ static const struct net_device_ops tsnep_netdev_ops = {
.ndo_open = tsnep_netdev_open,
.ndo_stop = tsnep_netdev_close,
.ndo_start_xmit = tsnep_netdev_xmit_frame,
.ndo_eth_ioctl = tsnep_netdev_ioctl,
.ndo_eth_ioctl = phy_do_ioctl_running,
.ndo_set_rx_mode = tsnep_netdev_set_multicast,
.ndo_get_stats64 = tsnep_netdev_get_stats64,
.ndo_set_mac_address = tsnep_netdev_set_mac_address,
@@ -2394,6 +2384,8 @@ static const struct net_device_ops tsnep_netdev_ops = {
.ndo_bpf = tsnep_netdev_bpf,
.ndo_xdp_xmit = tsnep_netdev_xdp_xmit,
.ndo_xsk_wakeup = tsnep_netdev_xsk_wakeup,
.ndo_hwtstamp_get = tsnep_ptp_hwtstamp_get,
.ndo_hwtstamp_set = tsnep_ptp_hwtstamp_set,
};
static int tsnep_mac_init(struct tsnep_adapter *adapter)

View File

@@ -19,57 +19,53 @@ void tsnep_get_system_time(struct tsnep_adapter *adapter, u64 *time)
*time = (((u64)high) << 32) | ((u64)low);
}
int tsnep_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
int tsnep_ptp_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *config)
{
struct tsnep_adapter *adapter = netdev_priv(netdev);
struct hwtstamp_config config;
if (!ifr)
return -EINVAL;
*config = adapter->hwtstamp_config;
return 0;
}
if (cmd == SIOCSHWTSTAMP) {
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
int tsnep_ptp_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct tsnep_adapter *adapter = netdev_priv(netdev);
switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
case HWTSTAMP_TX_ON:
break;
default:
return -ERANGE;
}
switch (config.rx_filter) {
case HWTSTAMP_FILTER_NONE:
break;
case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
case HWTSTAMP_FILTER_NTP_ALL:
config.rx_filter = HWTSTAMP_FILTER_ALL;
break;
default:
return -ERANGE;
}
memcpy(&adapter->hwtstamp_config, &config,
sizeof(adapter->hwtstamp_config));
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
case HWTSTAMP_TX_ON:
break;
default:
return -ERANGE;
}
if (copy_to_user(ifr->ifr_data, &adapter->hwtstamp_config,
sizeof(adapter->hwtstamp_config)))
return -EFAULT;
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
break;
case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
case HWTSTAMP_FILTER_NTP_ALL:
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
default:
return -ERANGE;
}
adapter->hwtstamp_config = *config;
return 0;
}

View File

@@ -4,7 +4,7 @@
#define _FUNETH_H
#include <uapi/linux/if_ether.h>
#include <uapi/linux/net_tstamp.h>
#include <linux/net_tstamp.h>
#include <linux/mutex.h>
#include <linux/seqlock.h>
#include <linux/xarray.h>
@@ -121,7 +121,7 @@ struct funeth_priv {
u8 rx_coal_usec;
u8 rx_coal_count;
struct hwtstamp_config hwtstamp_cfg;
struct kernel_hwtstamp_config hwtstamp_cfg;
/* cumulative queue stats from earlier queue instances */
u64 tx_packets;

View File

@@ -1014,26 +1014,25 @@ static int fun_get_port_attributes(struct net_device *netdev)
return 0;
}
static int fun_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
static int fun_hwtstamp_get(struct net_device *dev,
struct kernel_hwtstamp_config *config)
{
const struct funeth_priv *fp = netdev_priv(dev);
return copy_to_user(ifr->ifr_data, &fp->hwtstamp_cfg,
sizeof(fp->hwtstamp_cfg)) ? -EFAULT : 0;
*config = fp->hwtstamp_cfg;
return 0;
}
static int fun_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
static int fun_hwtstamp_set(struct net_device *dev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct funeth_priv *fp = netdev_priv(dev);
struct hwtstamp_config cfg;
if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
return -EFAULT;
/* no TX HW timestamps */
cfg.tx_type = HWTSTAMP_TX_OFF;
config->tx_type = HWTSTAMP_TX_OFF;
switch (cfg.rx_filter) {
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
break;
case HWTSTAMP_FILTER_ALL:
@@ -1051,26 +1050,14 @@ static int fun_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:
cfg.rx_filter = HWTSTAMP_FILTER_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
default:
return -ERANGE;
}
fp->hwtstamp_cfg = cfg;
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
}
static int fun_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
case SIOCSHWTSTAMP:
return fun_hwtstamp_set(dev, ifr);
case SIOCGHWTSTAMP:
return fun_hwtstamp_get(dev, ifr);
default:
return -EOPNOTSUPP;
}
fp->hwtstamp_cfg = *config;
return 0;
}
/* Prepare the queues for XDP. */
@@ -1340,7 +1327,6 @@ static const struct net_device_ops fun_netdev_ops = {
.ndo_change_mtu = fun_change_mtu,
.ndo_set_mac_address = fun_set_macaddr,
.ndo_validate_addr = eth_validate_addr,
.ndo_eth_ioctl = fun_ioctl,
.ndo_uninit = fun_uninit,
.ndo_bpf = fun_xdp,
.ndo_xdp_xmit = fun_xdp_xmit_frames,
@@ -1348,6 +1334,8 @@ static const struct net_device_ops fun_netdev_ops = {
.ndo_set_vf_vlan = fun_set_vf_vlan,
.ndo_set_vf_rate = fun_set_vf_rate,
.ndo_get_vf_config = fun_get_vf_config,
.ndo_hwtstamp_get = fun_hwtstamp_get,
.ndo_hwtstamp_set = fun_hwtstamp_set,
};
#define GSO_ENCAP_FLAGS (NETIF_F_GSO_GRE | NETIF_F_GSO_IPXIP4 | \

View File

@@ -1788,28 +1788,28 @@ static int am65_cpsw_nuss_ndo_slave_set_mac_address(struct net_device *ndev,
}
static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev,
struct ifreq *ifr)
struct kernel_hwtstamp_config *cfg,
struct netlink_ext_ack *extack)
{
struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
u32 ts_ctrl, seq_id, ts_ctrl_ltype2, ts_vlan_ltype;
struct hwtstamp_config cfg;
if (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS))
if (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS)) {
NL_SET_ERR_MSG(extack, "Time stamping is not supported");
return -EOPNOTSUPP;
if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
return -EFAULT;
}
/* TX HW timestamp */
switch (cfg.tx_type) {
switch (cfg->tx_type) {
case HWTSTAMP_TX_OFF:
case HWTSTAMP_TX_ON:
break;
default:
NL_SET_ERR_MSG(extack, "TX mode is not supported");
return -ERANGE;
}
switch (cfg.rx_filter) {
switch (cfg->rx_filter) {
case HWTSTAMP_FILTER_NONE:
port->rx_ts_enabled = false;
break;
@@ -1826,17 +1826,19 @@ static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev,
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
port->rx_ts_enabled = true;
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT | HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT | HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
break;
case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_SOME:
case HWTSTAMP_FILTER_NTP_ALL:
NL_SET_ERR_MSG(extack, "RX filter is not supported");
return -EOPNOTSUPP;
default:
NL_SET_ERR_MSG(extack, "RX filter is not supported");
return -ERANGE;
}
port->tx_ts_enabled = (cfg.tx_type == HWTSTAMP_TX_ON);
port->tx_ts_enabled = (cfg->tx_type == HWTSTAMP_TX_ON);
/* cfg TX timestamp */
seq_id = (AM65_CPSW_TS_SEQ_ID_OFFSET <<
@@ -1872,25 +1874,24 @@ static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev,
AM65_CPSW_PORTN_REG_TS_CTL_LTYPE2);
writel(ts_ctrl, port->port_base + AM65_CPSW_PORTN_REG_TS_CTL);
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
return 0;
}
static int am65_cpsw_nuss_hwtstamp_get(struct net_device *ndev,
struct ifreq *ifr)
struct kernel_hwtstamp_config *cfg)
{
struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
struct hwtstamp_config cfg;
if (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS))
return -EOPNOTSUPP;
cfg.flags = 0;
cfg.tx_type = port->tx_ts_enabled ?
cfg->flags = 0;
cfg->tx_type = port->tx_ts_enabled ?
HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
cfg.rx_filter = port->rx_ts_enabled ? HWTSTAMP_FILTER_PTP_V2_EVENT |
cfg->rx_filter = port->rx_ts_enabled ? HWTSTAMP_FILTER_PTP_V2_EVENT |
HWTSTAMP_FILTER_PTP_V1_L4_EVENT : HWTSTAMP_FILTER_NONE;
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
return 0;
}
static int am65_cpsw_nuss_ndo_slave_ioctl(struct net_device *ndev,
@@ -1901,13 +1902,6 @@ static int am65_cpsw_nuss_ndo_slave_ioctl(struct net_device *ndev,
if (!netif_running(ndev))
return -EINVAL;
switch (cmd) {
case SIOCSHWTSTAMP:
return am65_cpsw_nuss_hwtstamp_set(ndev, req);
case SIOCGHWTSTAMP:
return am65_cpsw_nuss_hwtstamp_get(ndev, req);
}
return phylink_mii_ioctl(port->slave.phylink, req, cmd);
}
@@ -1991,6 +1985,8 @@ static const struct net_device_ops am65_cpsw_nuss_netdev_ops = {
.ndo_set_tx_maxrate = am65_cpsw_qos_ndo_tx_p0_set_maxrate,
.ndo_bpf = am65_cpsw_ndo_bpf,
.ndo_xdp_xmit = am65_cpsw_ndo_xdp_xmit,
.ndo_hwtstamp_get = am65_cpsw_nuss_hwtstamp_get,
.ndo_hwtstamp_set = am65_cpsw_nuss_hwtstamp_set,
};
static void am65_cpsw_disable_phy(struct phy *phy)

View File

@@ -1223,15 +1223,13 @@ void icssg_ndo_tx_timeout(struct net_device *ndev, unsigned int txqueue)
}
EXPORT_SYMBOL_GPL(icssg_ndo_tx_timeout);
static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr)
int icssg_ndo_set_ts_config(struct net_device *ndev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack)
{
struct prueth_emac *emac = netdev_priv(ndev);
struct hwtstamp_config config;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
return -EFAULT;
switch (config.tx_type) {
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
emac->tx_ts_enabled = 0;
break;
@@ -1242,7 +1240,7 @@ static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr)
return -ERANGE;
}
switch (config.rx_filter) {
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
emac->rx_ts_enabled = 0;
break;
@@ -1262,43 +1260,28 @@ static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr)
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
case HWTSTAMP_FILTER_NTP_ALL:
emac->rx_ts_enabled = 1;
config.rx_filter = HWTSTAMP_FILTER_ALL;
config->rx_filter = HWTSTAMP_FILTER_ALL;
break;
default:
return -ERANGE;
}
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
return 0;
}
EXPORT_SYMBOL_GPL(icssg_ndo_set_ts_config);
static int emac_get_ts_config(struct net_device *ndev, struct ifreq *ifr)
int icssg_ndo_get_ts_config(struct net_device *ndev,
struct kernel_hwtstamp_config *config)
{
struct prueth_emac *emac = netdev_priv(ndev);
struct hwtstamp_config config;
config.flags = 0;
config.tx_type = emac->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
config.rx_filter = emac->rx_ts_enabled ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE;
config->flags = 0;
config->tx_type = emac->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
config->rx_filter = emac->rx_ts_enabled ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE;
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
return 0;
}
int icssg_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
case SIOCGHWTSTAMP:
return emac_get_ts_config(ndev, ifr);
case SIOCSHWTSTAMP:
return emac_set_ts_config(ndev, ifr);
default:
break;
}
return phy_do_ioctl(ndev, ifr, cmd);
}
EXPORT_SYMBOL_GPL(icssg_ndo_ioctl);
EXPORT_SYMBOL_GPL(icssg_ndo_get_ts_config);
void icssg_ndo_get_stats64(struct net_device *ndev,
struct rtnl_link_stats64 *stats)

View File

@@ -1168,7 +1168,7 @@ static const struct net_device_ops emac_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_tx_timeout = icssg_ndo_tx_timeout,
.ndo_set_rx_mode = emac_ndo_set_rx_mode,
.ndo_eth_ioctl = icssg_ndo_ioctl,
.ndo_eth_ioctl = phy_do_ioctl,
.ndo_get_stats64 = icssg_ndo_get_stats64,
.ndo_get_phys_port_name = icssg_ndo_get_phys_port_name,
.ndo_fix_features = emac_ndo_fix_features,
@@ -1176,6 +1176,8 @@ static const struct net_device_ops emac_netdev_ops = {
.ndo_vlan_rx_kill_vid = emac_ndo_vlan_rx_del_vid,
.ndo_bpf = emac_ndo_bpf,
.ndo_xdp_xmit = emac_xdp_xmit,
.ndo_hwtstamp_get = icssg_ndo_get_ts_config,
.ndo_hwtstamp_set = icssg_ndo_set_ts_config,
};
static int prueth_netdev_init(struct prueth *prueth,

View File

@@ -479,7 +479,11 @@ void prueth_reset_tx_chan(struct prueth_emac *emac, int ch_num,
void prueth_reset_rx_chan(struct prueth_rx_chn *chn,
int num_flows, bool disable);
void icssg_ndo_tx_timeout(struct net_device *ndev, unsigned int txqueue);
int icssg_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd);
int icssg_ndo_get_ts_config(struct net_device *ndev,
struct kernel_hwtstamp_config *config);
int icssg_ndo_set_ts_config(struct net_device *ndev,
struct kernel_hwtstamp_config *config,
struct netlink_ext_ack *extack);
void icssg_ndo_get_stats64(struct net_device *ndev,
struct rtnl_link_stats64 *stats);
int icssg_ndo_get_phys_port_name(struct net_device *ndev, char *name,

View File

@@ -747,9 +747,11 @@ static const struct net_device_ops emac_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_tx_timeout = icssg_ndo_tx_timeout,
.ndo_set_rx_mode = emac_ndo_set_rx_mode_sr1,
.ndo_eth_ioctl = icssg_ndo_ioctl,
.ndo_eth_ioctl = phy_do_ioctl,
.ndo_get_stats64 = icssg_ndo_get_stats64,
.ndo_get_phys_port_name = icssg_ndo_get_phys_port_name,
.ndo_hwtstamp_get = icssg_ndo_get_ts_config,
.ndo_hwtstamp_set = icssg_ndo_set_ts_config,
};
static int prueth_netdev_init(struct prueth *prueth,