Commit bdf27b54 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'convert-drivers-to-use-ndo_hwtstamp-callbacks-part-3'

Vadim Fedorenko says:

====================
convert drivers to use ndo_hwtstamp callbacks part 3 [part]

This patchset converts the rest of ethernet drivers to use ndo callbacks
instead ioctl to configure and report time stamping. The drivers in part
3 originally implemented only SIOCSHWTSTAMP command, but converted to
also provide configuration back to users.
====================

Link: https://patch.msgid.link/20251103150952.3538205-1-vadim.fedorenko@linux.dev


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents e0c78fca d8fdc706
Loading
Loading
Loading
Loading
+20 −30
Original line number Diff line number Diff line
@@ -2107,20 +2107,16 @@ liquidio_get_stats64(struct net_device *netdev,
		lstats->tx_fifo_errors;
}

/**
 * hwtstamp_ioctl - Handler for SIOCSHWTSTAMP ioctl
 * @netdev: network device
 * @ifr: interface request
 */
static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
static int liquidio_hwtstamp_set(struct net_device *netdev,
				 struct kernel_hwtstamp_config *conf,
				 struct netlink_ext_ack *extack)
{
	struct hwtstamp_config conf;
	struct lio *lio = GET_LIO(netdev);

	if (copy_from_user(&conf, ifr->ifr_data, sizeof(conf)))
		return -EFAULT;
	if (!lio->oct_dev->ptp_enable)
		return -EOPNOTSUPP;

	switch (conf.tx_type) {
	switch (conf->tx_type) {
	case HWTSTAMP_TX_ON:
	case HWTSTAMP_TX_OFF:
		break;
@@ -2128,7 +2124,7 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
		return -ERANGE;
	}

	switch (conf.rx_filter) {
	switch (conf->rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		break;
	case HWTSTAMP_FILTER_ALL:
@@ -2146,39 +2142,32 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
	case HWTSTAMP_FILTER_NTP_ALL:
		conf.rx_filter = HWTSTAMP_FILTER_ALL;
		conf->rx_filter = HWTSTAMP_FILTER_ALL;
		break;
	default:
		return -ERANGE;
	}

	if (conf.rx_filter == HWTSTAMP_FILTER_ALL)
	if (conf->rx_filter == HWTSTAMP_FILTER_ALL)
		ifstate_set(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED);

	else
		ifstate_reset(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED);

	return copy_to_user(ifr->ifr_data, &conf, sizeof(conf)) ? -EFAULT : 0;
	return 0;
}

/**
 * liquidio_ioctl - ioctl handler
 * @netdev: network device
 * @ifr: interface request
 * @cmd: command
 */
static int liquidio_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
static int liquidio_hwtstamp_get(struct net_device *netdev,
				 struct kernel_hwtstamp_config *conf)
{
	struct lio *lio = GET_LIO(netdev);

	switch (cmd) {
	case SIOCSHWTSTAMP:
		if (lio->oct_dev->ptp_enable)
			return hwtstamp_ioctl(netdev, ifr);
		fallthrough;
	default:
		return -EOPNOTSUPP;
	}
	/* TX timestamping is technically always on */
	conf->tx_type = HWTSTAMP_TX_ON;
	conf->rx_filter = ifstate_check(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED) ?
			  HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE;

	return 0;
}

/**
@@ -3227,7 +3216,6 @@ static const struct net_device_ops lionetdevops = {
	.ndo_vlan_rx_add_vid    = liquidio_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid   = liquidio_vlan_rx_kill_vid,
	.ndo_change_mtu		= liquidio_change_mtu,
	.ndo_eth_ioctl		= liquidio_ioctl,
	.ndo_fix_features	= liquidio_fix_features,
	.ndo_set_features	= liquidio_set_features,
	.ndo_set_vf_mac		= liquidio_set_vf_mac,
@@ -3238,6 +3226,8 @@ static const struct net_device_ops lionetdevops = {
	.ndo_set_vf_link_state  = liquidio_set_vf_link_state,
	.ndo_get_vf_stats	= liquidio_get_vf_stats,
	.ndo_get_port_parent_id	= liquidio_get_port_parent_id,
	.ndo_hwtstamp_get	= liquidio_hwtstamp_get,
	.ndo_hwtstamp_set	= liquidio_hwtstamp_set,
};

/**
+19 −29
Original line number Diff line number Diff line
@@ -1236,20 +1236,13 @@ liquidio_get_stats64(struct net_device *netdev,
		lstats->tx_carrier_errors;
}

/**
 * hwtstamp_ioctl - Handler for SIOCSHWTSTAMP ioctl
 * @netdev: network device
 * @ifr: interface request
 */
static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
static int liquidio_hwtstamp_set(struct net_device *netdev,
				 struct kernel_hwtstamp_config *conf,
				 struct netlink_ext_ack *extack)
{
	struct lio *lio = GET_LIO(netdev);
	struct hwtstamp_config conf;

	if (copy_from_user(&conf, ifr->ifr_data, sizeof(conf)))
		return -EFAULT;

	switch (conf.tx_type) {
	switch (conf->tx_type) {
	case HWTSTAMP_TX_ON:
	case HWTSTAMP_TX_OFF:
		break;
@@ -1257,7 +1250,7 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
		return -ERANGE;
	}

	switch (conf.rx_filter) {
	switch (conf->rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		break;
	case HWTSTAMP_FILTER_ALL:
@@ -1275,35 +1268,31 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
	case HWTSTAMP_FILTER_NTP_ALL:
		conf.rx_filter = HWTSTAMP_FILTER_ALL;
		conf->rx_filter = HWTSTAMP_FILTER_ALL;
		break;
	default:
		return -ERANGE;
	}

	if (conf.rx_filter == HWTSTAMP_FILTER_ALL)
	if (conf->rx_filter == HWTSTAMP_FILTER_ALL)
		ifstate_set(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED);

	else
		ifstate_reset(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED);

	return copy_to_user(ifr->ifr_data, &conf, sizeof(conf)) ? -EFAULT : 0;
	return 0;
}

/**
 * liquidio_ioctl - ioctl handler
 * @netdev: network device
 * @ifr: interface request
 * @cmd: command
 */
static int liquidio_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
static int liquidio_hwtstamp_get(struct net_device *netdev,
				 struct kernel_hwtstamp_config *conf)
{
	switch (cmd) {
	case SIOCSHWTSTAMP:
		return hwtstamp_ioctl(netdev, ifr);
	default:
		return -EOPNOTSUPP;
	}
	struct lio *lio = GET_LIO(netdev);

	/* TX timestamping is techically always on */
	conf->tx_type = HWTSTAMP_TX_ON;
	conf->rx_filter = ifstate_check(lio, LIO_IFSTATE_RX_TIMESTAMP_ENABLED) ?
			  HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE;
	return 0;
}

static void handle_timestamp(struct octeon_device *oct, u32 status, void *buf)
@@ -1881,9 +1870,10 @@ static const struct net_device_ops lionetdevops = {
	.ndo_vlan_rx_add_vid    = liquidio_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid   = liquidio_vlan_rx_kill_vid,
	.ndo_change_mtu		= liquidio_change_mtu,
	.ndo_eth_ioctl		= liquidio_ioctl,
	.ndo_fix_features	= liquidio_fix_features,
	.ndo_set_features	= liquidio_set_features,
	.ndo_hwtstamp_get	= liquidio_hwtstamp_get,
	.ndo_hwtstamp_set	= liquidio_hwtstamp_set,
};

static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf)
+32 −30
Original line number Diff line number Diff line
@@ -690,19 +690,16 @@ static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id)
	return IRQ_HANDLED;
}

static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev,
				      struct ifreq *rq, int cmd)
static int octeon_mgmt_hwtstamp_set(struct net_device *netdev,
				    struct kernel_hwtstamp_config *config,
				    struct netlink_ext_ack *extack)
{
	struct octeon_mgmt *p = netdev_priv(netdev);
	struct hwtstamp_config config;
	union cvmx_mio_ptp_clock_cfg ptp;
	union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl;
	union cvmx_mio_ptp_clock_cfg ptp;
	bool have_hw_timestamps = false;

	if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
		return -EFAULT;

	/* Check the status of hardware for tiemstamps */
	/* Check the status of hardware for timestamps */
	if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
		/* Get the current state of the PTP clock */
		ptp.u64 = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_CFG);
@@ -733,10 +730,12 @@ static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev,
		have_hw_timestamps = true;
	}

	if (!have_hw_timestamps)
	if (!have_hw_timestamps) {
		NL_SET_ERR_MSG_MOD(extack, "HW doesn't support timestamping");
		return -EINVAL;
	}

	switch (config.tx_type) {
	switch (config->tx_type) {
	case HWTSTAMP_TX_OFF:
	case HWTSTAMP_TX_ON:
		break;
@@ -744,7 +743,7 @@ static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev,
		return -ERANGE;
	}

	switch (config.rx_filter) {
	switch (config->rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		p->has_rx_tstamp = false;
		rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL);
@@ -766,33 +765,34 @@ static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev,
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
	case HWTSTAMP_FILTER_NTP_ALL:
		p->has_rx_tstamp = have_hw_timestamps;
		config.rx_filter = HWTSTAMP_FILTER_ALL;
		if (p->has_rx_tstamp) {
		p->has_rx_tstamp = true;
		config->rx_filter = HWTSTAMP_FILTER_ALL;
		rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL);
		rxx_frm_ctl.s.ptp_mode = 1;
		cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
		}
		break;
	default:
		return -ERANGE;
	}

	if (copy_to_user(rq->ifr_data, &config, sizeof(config)))
		return -EFAULT;

	return 0;
}

static int octeon_mgmt_ioctl(struct net_device *netdev,
			     struct ifreq *rq, int cmd)
static int octeon_mgmt_hwtstamp_get(struct net_device *netdev,
				    struct kernel_hwtstamp_config *config)
{
	switch (cmd) {
	case SIOCSHWTSTAMP:
		return octeon_mgmt_ioctl_hwtstamp(netdev, rq, cmd);
	default:
		return phy_do_ioctl(netdev, rq, cmd);
	}
	struct octeon_mgmt *p = netdev_priv(netdev);

	/* Check the status of hardware for timestamps */
	if (!OCTEON_IS_MODEL(OCTEON_CN6XXX))
		return -EINVAL;

	config->tx_type = HWTSTAMP_TX_ON;
	config->rx_filter = p->has_rx_tstamp ?
			    HWTSTAMP_FILTER_ALL :
			    HWTSTAMP_FILTER_NONE;

	return 0;
}

static void octeon_mgmt_disable_link(struct octeon_mgmt *p)
@@ -1370,11 +1370,13 @@ static const struct net_device_ops octeon_mgmt_ops = {
	.ndo_start_xmit =		octeon_mgmt_xmit,
	.ndo_set_rx_mode =		octeon_mgmt_set_rx_filtering,
	.ndo_set_mac_address =		octeon_mgmt_set_mac_address,
	.ndo_eth_ioctl =			octeon_mgmt_ioctl,
	.ndo_eth_ioctl =		phy_do_ioctl,
	.ndo_change_mtu =		octeon_mgmt_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller =		octeon_mgmt_poll_controller,
#endif
	.ndo_hwtstamp_get =		octeon_mgmt_hwtstamp_get,
	.ndo_hwtstamp_set =		octeon_mgmt_hwtstamp_set,
};

static int octeon_mgmt_probe(struct platform_device *pdev)
+25 −20
Original line number Diff line number Diff line
@@ -1899,18 +1899,18 @@ static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp)
	}
}

static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
static int nicvf_hwtstamp_set(struct net_device *netdev,
			      struct kernel_hwtstamp_config *config,
			      struct netlink_ext_ack *extack)
{
	struct hwtstamp_config config;
	struct nicvf *nic = netdev_priv(netdev);

	if (!nic->ptp_clock)
	if (!nic->ptp_clock) {
		NL_SET_ERR_MSG_MOD(extack, "HW timestamping is not supported");
		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:
	case HWTSTAMP_TX_ON:
		break;
@@ -1918,7 +1918,7 @@ static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
		return -ERANGE;
	}

	switch (config.rx_filter) {
	switch (config->rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		nic->hw_rx_tstamp = false;
		break;
@@ -1937,7 +1937,7 @@ static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
		nic->hw_rx_tstamp = true;
		config.rx_filter = HWTSTAMP_FILTER_ALL;
		config->rx_filter = HWTSTAMP_FILTER_ALL;
		break;
	default:
		return -ERANGE;
@@ -1946,20 +1946,24 @@ static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
	if (netif_running(netdev))
		nicvf_config_hw_rx_tstamp(nic, nic->hw_rx_tstamp);

	if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
		return -EFAULT;

	return 0;
}

static int nicvf_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
static int nicvf_hwtstamp_get(struct net_device *netdev,
			      struct kernel_hwtstamp_config *config)
{
	switch (cmd) {
	case SIOCSHWTSTAMP:
		return nicvf_config_hwtstamp(netdev, req);
	default:
		return -EOPNOTSUPP;
	}
	struct nicvf *nic = netdev_priv(netdev);

	if (!nic->ptp_clock)
		return -ENODEV;

	/* TX timestamping is technically always on */
	config->tx_type = HWTSTAMP_TX_ON;
	config->rx_filter = nic->hw_rx_tstamp ?
			    HWTSTAMP_FILTER_ALL :
			    HWTSTAMP_FILTER_NONE;

	return 0;
}

static void __nicvf_set_rx_mode_task(u8 mode, struct xcast_addr_list *mc_addrs,
@@ -2081,8 +2085,9 @@ static const struct net_device_ops nicvf_netdev_ops = {
	.ndo_fix_features       = nicvf_fix_features,
	.ndo_set_features       = nicvf_set_features,
	.ndo_bpf		= nicvf_xdp,
	.ndo_eth_ioctl           = nicvf_ioctl,
	.ndo_set_rx_mode        = nicvf_set_rx_mode,
	.ndo_hwtstamp_get	= nicvf_hwtstamp_get,
	.ndo_hwtstamp_set	= nicvf_hwtstamp_set,
};

static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+23 −15
Original line number Diff line number Diff line
@@ -198,23 +198,21 @@ pch_tx_timestamp(struct pch_gbe_adapter *adapter, struct sk_buff *skb)
	pch_ch_event_write(pdev, TX_SNAPSHOT_LOCKED);
}

static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
static int pch_gbe_hwtstamp_set(struct net_device *netdev,
				struct kernel_hwtstamp_config *cfg,
				struct netlink_ext_ack *extack)
{
	struct hwtstamp_config cfg;
	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
	struct pci_dev *pdev;
	u8 station[20];

	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
		return -EFAULT;

	/* Get ieee1588's dev information */
	pdev = adapter->ptp_pdev;

	if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
	if (cfg->tx_type != HWTSTAMP_TX_OFF && cfg->tx_type != HWTSTAMP_TX_ON)
		return -ERANGE;

	switch (cfg.rx_filter) {
	switch (cfg->rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		adapter->hwts_rx_en = 0;
		break;
@@ -223,17 +221,17 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
		pch_ch_control_write(pdev, SLAVE_MODE | CAP_MODE0);
		break;
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
		adapter->hwts_rx_en = 1;
		adapter->hwts_rx_en = cfg->rx_filter;
		pch_ch_control_write(pdev, MASTER_MODE | CAP_MODE0);
		break;
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
		adapter->hwts_rx_en = 1;
		adapter->hwts_rx_en = cfg->rx_filter;
		pch_ch_control_write(pdev, V2_MODE | CAP_MODE2);
		strcpy(station, PTP_L4_MULTICAST_SA);
		pch_set_station_address(station, pdev);
		break;
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
		adapter->hwts_rx_en = 1;
		adapter->hwts_rx_en = cfg->rx_filter;
		pch_ch_control_write(pdev, V2_MODE | CAP_MODE2);
		strcpy(station, PTP_L2_MULTICAST_SA);
		pch_set_station_address(station, pdev);
@@ -242,12 +240,23 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
		return -ERANGE;
	}

	adapter->hwts_tx_en = cfg.tx_type == HWTSTAMP_TX_ON;
	adapter->hwts_tx_en = cfg->tx_type == HWTSTAMP_TX_ON;

	/* Clear out any old time stamps. */
	pch_ch_event_write(pdev, TX_SNAPSHOT_LOCKED | RX_SNAPSHOT_LOCKED);

	return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
	return 0;
}

static int pch_gbe_hwtstamp_get(struct net_device *netdev,
				struct kernel_hwtstamp_config *cfg)
{
	struct pch_gbe_adapter *adapter = netdev_priv(netdev);

	cfg->tx_type = adapter->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
	cfg->rx_filter = adapter->hwts_rx_en;

	return 0;
}

static inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw)
@@ -2234,9 +2243,6 @@ static int pch_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)

	netdev_dbg(netdev, "cmd : 0x%04x\n", cmd);

	if (cmd == SIOCSHWTSTAMP)
		return hwtstamp_ioctl(netdev, ifr, cmd);

	return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL);
}

@@ -2328,6 +2334,8 @@ static const struct net_device_ops pch_gbe_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller = pch_gbe_netpoll,
#endif
	.ndo_hwtstamp_get = pch_gbe_hwtstamp_get,
	.ndo_hwtstamp_set = pch_gbe_hwtstamp_set,
};

static pci_ers_result_t pch_gbe_io_error_detected(struct pci_dev *pdev,