Commit d8fdc706 authored by Vadim Fedorenko's avatar Vadim Fedorenko Committed by Jakub Kicinski
Browse files

net: pch_gbe: convert to use ndo_hwtstamp callbacks



The driver implemented SIOCSHWTSTAMP ioctl command only, but it stores
configuration in the private data, so it is possible to report it back
to users. Implement both ndo_hwtstamp_set and ndo_hwtstamp_get
callbacks. To properly report RX filter type, store it in hwts_rx_en
instead of using this field as a simple flag. The logic didn't change
because receive path used this field as boolean flag.

Signed-off-by: default avatarVadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: default avatarKory Maincent <kory.maincent@bootlin.com>
Link: https://patch.msgid.link/20251103150952.3538205-7-vadim.fedorenko@linux.dev


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a23d0486
Loading
Loading
Loading
Loading
+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,