cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qede_ptp.c (13702B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
      2/* QLogic qede NIC Driver
      3 * Copyright (c) 2015-2017  QLogic Corporation
      4 * Copyright (c) 2019-2020 Marvell International Ltd.
      5 */
      6
      7#include "qede_ptp.h"
      8#define QEDE_PTP_TX_TIMEOUT (2 * HZ)
      9
     10struct qede_ptp {
     11	const struct qed_eth_ptp_ops	*ops;
     12	struct ptp_clock_info		clock_info;
     13	struct cyclecounter		cc;
     14	struct timecounter		tc;
     15	struct ptp_clock		*clock;
     16	struct work_struct		work;
     17	unsigned long			ptp_tx_start;
     18	struct qede_dev			*edev;
     19	struct sk_buff			*tx_skb;
     20
     21	/* ptp spinlock is used for protecting the cycle/time counter fields
     22	 * and, also for serializing the qed PTP API invocations.
     23	 */
     24	spinlock_t			lock;
     25	bool				hw_ts_ioctl_called;
     26	u16				tx_type;
     27	u16				rx_filter;
     28};
     29
     30/**
     31 * qede_ptp_adjfreq() - Adjust the frequency of the PTP cycle counter.
     32 *
     33 * @info: The PTP clock info structure.
     34 * @ppb: Parts per billion adjustment from base.
     35 *
     36 * Return: Zero on success, negative errno otherwise.
     37 */
     38static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb)
     39{
     40	struct qede_ptp *ptp = container_of(info, struct qede_ptp, clock_info);
     41	struct qede_dev *edev = ptp->edev;
     42	int rc;
     43
     44	__qede_lock(edev);
     45	if (edev->state == QEDE_STATE_OPEN) {
     46		spin_lock_bh(&ptp->lock);
     47		rc = ptp->ops->adjfreq(edev->cdev, ppb);
     48		spin_unlock_bh(&ptp->lock);
     49	} else {
     50		DP_ERR(edev, "PTP adjfreq called while interface is down\n");
     51		rc = -EFAULT;
     52	}
     53	__qede_unlock(edev);
     54
     55	return rc;
     56}
     57
     58static int qede_ptp_adjtime(struct ptp_clock_info *info, s64 delta)
     59{
     60	struct qede_dev *edev;
     61	struct qede_ptp *ptp;
     62
     63	ptp = container_of(info, struct qede_ptp, clock_info);
     64	edev = ptp->edev;
     65
     66	DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP adjtime called, delta = %llx\n",
     67		   delta);
     68
     69	spin_lock_bh(&ptp->lock);
     70	timecounter_adjtime(&ptp->tc, delta);
     71	spin_unlock_bh(&ptp->lock);
     72
     73	return 0;
     74}
     75
     76static int qede_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
     77{
     78	struct qede_dev *edev;
     79	struct qede_ptp *ptp;
     80	u64 ns;
     81
     82	ptp = container_of(info, struct qede_ptp, clock_info);
     83	edev = ptp->edev;
     84
     85	spin_lock_bh(&ptp->lock);
     86	ns = timecounter_read(&ptp->tc);
     87	spin_unlock_bh(&ptp->lock);
     88
     89	DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP gettime called, ns = %llu\n", ns);
     90
     91	*ts = ns_to_timespec64(ns);
     92
     93	return 0;
     94}
     95
     96static int qede_ptp_settime(struct ptp_clock_info *info,
     97			    const struct timespec64 *ts)
     98{
     99	struct qede_dev *edev;
    100	struct qede_ptp *ptp;
    101	u64 ns;
    102
    103	ptp = container_of(info, struct qede_ptp, clock_info);
    104	edev = ptp->edev;
    105
    106	ns = timespec64_to_ns(ts);
    107
    108	DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP settime called, ns = %llu\n", ns);
    109
    110	/* Re-init the timecounter */
    111	spin_lock_bh(&ptp->lock);
    112	timecounter_init(&ptp->tc, &ptp->cc, ns);
    113	spin_unlock_bh(&ptp->lock);
    114
    115	return 0;
    116}
    117
    118/* Enable (or disable) ancillary features of the phc subsystem */
    119static int qede_ptp_ancillary_feature_enable(struct ptp_clock_info *info,
    120					     struct ptp_clock_request *rq,
    121					     int on)
    122{
    123	struct qede_dev *edev;
    124	struct qede_ptp *ptp;
    125
    126	ptp = container_of(info, struct qede_ptp, clock_info);
    127	edev = ptp->edev;
    128
    129	DP_ERR(edev, "PHC ancillary features are not supported\n");
    130
    131	return -ENOTSUPP;
    132}
    133
    134static void qede_ptp_task(struct work_struct *work)
    135{
    136	struct skb_shared_hwtstamps shhwtstamps;
    137	struct qede_dev *edev;
    138	struct qede_ptp *ptp;
    139	u64 timestamp, ns;
    140	bool timedout;
    141	int rc;
    142
    143	ptp = container_of(work, struct qede_ptp, work);
    144	edev = ptp->edev;
    145	timedout = time_is_before_jiffies(ptp->ptp_tx_start +
    146					  QEDE_PTP_TX_TIMEOUT);
    147
    148	/* Read Tx timestamp registers */
    149	spin_lock_bh(&ptp->lock);
    150	rc = ptp->ops->read_tx_ts(edev->cdev, &timestamp);
    151	spin_unlock_bh(&ptp->lock);
    152	if (rc) {
    153		if (unlikely(timedout)) {
    154			DP_INFO(edev, "Tx timestamp is not recorded\n");
    155			dev_kfree_skb_any(ptp->tx_skb);
    156			ptp->tx_skb = NULL;
    157			clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS,
    158					 &edev->flags);
    159			edev->ptp_skip_txts++;
    160		} else {
    161			/* Reschedule to keep checking for a valid TS value */
    162			schedule_work(&ptp->work);
    163		}
    164		return;
    165	}
    166
    167	ns = timecounter_cyc2time(&ptp->tc, timestamp);
    168	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
    169	shhwtstamps.hwtstamp = ns_to_ktime(ns);
    170	skb_tstamp_tx(ptp->tx_skb, &shhwtstamps);
    171	dev_kfree_skb_any(ptp->tx_skb);
    172	ptp->tx_skb = NULL;
    173	clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
    174
    175	DP_VERBOSE(edev, QED_MSG_DEBUG,
    176		   "Tx timestamp, timestamp cycles = %llu, ns = %llu\n",
    177		   timestamp, ns);
    178}
    179
    180/* Read the PHC. This API is invoked with ptp_lock held. */
    181static u64 qede_ptp_read_cc(const struct cyclecounter *cc)
    182{
    183	struct qede_dev *edev;
    184	struct qede_ptp *ptp;
    185	u64 phc_cycles;
    186	int rc;
    187
    188	ptp = container_of(cc, struct qede_ptp, cc);
    189	edev = ptp->edev;
    190	rc = ptp->ops->read_cc(edev->cdev, &phc_cycles);
    191	if (rc)
    192		WARN_ONCE(1, "PHC read err %d\n", rc);
    193
    194	DP_VERBOSE(edev, QED_MSG_DEBUG, "PHC read cycles = %llu\n", phc_cycles);
    195
    196	return phc_cycles;
    197}
    198
    199static int qede_ptp_cfg_filters(struct qede_dev *edev)
    200{
    201	enum qed_ptp_hwtstamp_tx_type tx_type = QED_PTP_HWTSTAMP_TX_ON;
    202	enum qed_ptp_filter_type rx_filter = QED_PTP_FILTER_NONE;
    203	struct qede_ptp *ptp = edev->ptp;
    204
    205	if (!ptp)
    206		return -EIO;
    207
    208	if (!ptp->hw_ts_ioctl_called) {
    209		DP_INFO(edev, "TS IOCTL not called\n");
    210		return 0;
    211	}
    212
    213	switch (ptp->tx_type) {
    214	case HWTSTAMP_TX_ON:
    215		set_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags);
    216		tx_type = QED_PTP_HWTSTAMP_TX_ON;
    217		break;
    218
    219	case HWTSTAMP_TX_OFF:
    220		clear_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags);
    221		tx_type = QED_PTP_HWTSTAMP_TX_OFF;
    222		break;
    223
    224	case HWTSTAMP_TX_ONESTEP_SYNC:
    225	case HWTSTAMP_TX_ONESTEP_P2P:
    226		DP_ERR(edev, "One-step timestamping is not supported\n");
    227		return -ERANGE;
    228	}
    229
    230	spin_lock_bh(&ptp->lock);
    231	switch (ptp->rx_filter) {
    232	case HWTSTAMP_FILTER_NONE:
    233		rx_filter = QED_PTP_FILTER_NONE;
    234		break;
    235	case HWTSTAMP_FILTER_ALL:
    236	case HWTSTAMP_FILTER_SOME:
    237	case HWTSTAMP_FILTER_NTP_ALL:
    238		ptp->rx_filter = HWTSTAMP_FILTER_NONE;
    239		rx_filter = QED_PTP_FILTER_ALL;
    240		break;
    241	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
    242		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
    243		rx_filter = QED_PTP_FILTER_V1_L4_EVENT;
    244		break;
    245	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
    246	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
    247		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
    248		/* Initialize PTP detection for UDP/IPv4 events */
    249		rx_filter = QED_PTP_FILTER_V1_L4_GEN;
    250		break;
    251	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
    252		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
    253		rx_filter = QED_PTP_FILTER_V2_L4_EVENT;
    254		break;
    255	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
    256	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
    257		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
    258		/* Initialize PTP detection for UDP/IPv4 or UDP/IPv6 events */
    259		rx_filter = QED_PTP_FILTER_V2_L4_GEN;
    260		break;
    261	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
    262		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
    263		rx_filter = QED_PTP_FILTER_V2_L2_EVENT;
    264		break;
    265	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
    266	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
    267		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
    268		/* Initialize PTP detection L2 events */
    269		rx_filter = QED_PTP_FILTER_V2_L2_GEN;
    270		break;
    271	case HWTSTAMP_FILTER_PTP_V2_EVENT:
    272		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
    273		rx_filter = QED_PTP_FILTER_V2_EVENT;
    274		break;
    275	case HWTSTAMP_FILTER_PTP_V2_SYNC:
    276	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
    277		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
    278		/* Initialize PTP detection L2, UDP/IPv4 or UDP/IPv6 events */
    279		rx_filter = QED_PTP_FILTER_V2_GEN;
    280		break;
    281	}
    282
    283	ptp->ops->cfg_filters(edev->cdev, rx_filter, tx_type);
    284
    285	spin_unlock_bh(&ptp->lock);
    286
    287	return 0;
    288}
    289
    290int qede_ptp_hw_ts(struct qede_dev *edev, struct ifreq *ifr)
    291{
    292	struct hwtstamp_config config;
    293	struct qede_ptp *ptp;
    294	int rc;
    295
    296	ptp = edev->ptp;
    297	if (!ptp)
    298		return -EIO;
    299
    300	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
    301		return -EFAULT;
    302
    303	DP_VERBOSE(edev, QED_MSG_DEBUG,
    304		   "HWTSTAMP IOCTL: Requested tx_type = %d, requested rx_filters = %d\n",
    305		   config.tx_type, config.rx_filter);
    306
    307	ptp->hw_ts_ioctl_called = 1;
    308	ptp->tx_type = config.tx_type;
    309	ptp->rx_filter = config.rx_filter;
    310
    311	rc = qede_ptp_cfg_filters(edev);
    312	if (rc)
    313		return rc;
    314
    315	config.rx_filter = ptp->rx_filter;
    316
    317	return copy_to_user(ifr->ifr_data, &config,
    318			    sizeof(config)) ? -EFAULT : 0;
    319}
    320
    321int qede_ptp_get_ts_info(struct qede_dev *edev, struct ethtool_ts_info *info)
    322{
    323	struct qede_ptp *ptp = edev->ptp;
    324
    325	if (!ptp) {
    326		info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
    327					SOF_TIMESTAMPING_RX_SOFTWARE |
    328					SOF_TIMESTAMPING_SOFTWARE;
    329		info->phc_index = -1;
    330
    331		return 0;
    332	}
    333
    334	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
    335				SOF_TIMESTAMPING_RX_SOFTWARE |
    336				SOF_TIMESTAMPING_SOFTWARE |
    337				SOF_TIMESTAMPING_TX_HARDWARE |
    338				SOF_TIMESTAMPING_RX_HARDWARE |
    339				SOF_TIMESTAMPING_RAW_HARDWARE;
    340
    341	if (ptp->clock)
    342		info->phc_index = ptp_clock_index(ptp->clock);
    343	else
    344		info->phc_index = -1;
    345
    346	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
    347			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
    348			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
    349			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
    350			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
    351			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
    352			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
    353			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
    354			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
    355			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
    356			   BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
    357			   BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) |
    358			   BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ);
    359
    360	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
    361
    362	return 0;
    363}
    364
    365void qede_ptp_disable(struct qede_dev *edev)
    366{
    367	struct qede_ptp *ptp;
    368
    369	ptp = edev->ptp;
    370	if (!ptp)
    371		return;
    372
    373	if (ptp->clock) {
    374		ptp_clock_unregister(ptp->clock);
    375		ptp->clock = NULL;
    376	}
    377
    378	/* Cancel PTP work queue. Should be done after the Tx queues are
    379	 * drained to prevent additional scheduling.
    380	 */
    381	cancel_work_sync(&ptp->work);
    382	if (ptp->tx_skb) {
    383		dev_kfree_skb_any(ptp->tx_skb);
    384		ptp->tx_skb = NULL;
    385		clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
    386	}
    387
    388	/* Disable PTP in HW */
    389	spin_lock_bh(&ptp->lock);
    390	ptp->ops->disable(edev->cdev);
    391	spin_unlock_bh(&ptp->lock);
    392
    393	kfree(ptp);
    394	edev->ptp = NULL;
    395}
    396
    397static int qede_ptp_init(struct qede_dev *edev)
    398{
    399	struct qede_ptp *ptp;
    400	int rc;
    401
    402	ptp = edev->ptp;
    403	if (!ptp)
    404		return -EINVAL;
    405
    406	spin_lock_init(&ptp->lock);
    407
    408	/* Configure PTP in HW */
    409	rc = ptp->ops->enable(edev->cdev);
    410	if (rc) {
    411		DP_INFO(edev, "PTP HW enable failed\n");
    412		return rc;
    413	}
    414
    415	/* Init work queue for Tx timestamping */
    416	INIT_WORK(&ptp->work, qede_ptp_task);
    417
    418	/* Init cyclecounter and timecounter */
    419	memset(&ptp->cc, 0, sizeof(ptp->cc));
    420	ptp->cc.read = qede_ptp_read_cc;
    421	ptp->cc.mask = CYCLECOUNTER_MASK(64);
    422	ptp->cc.shift = 0;
    423	ptp->cc.mult = 1;
    424
    425	timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real()));
    426
    427	return 0;
    428}
    429
    430int qede_ptp_enable(struct qede_dev *edev)
    431{
    432	struct qede_ptp *ptp;
    433	int rc;
    434
    435	ptp = kzalloc(sizeof(*ptp), GFP_KERNEL);
    436	if (!ptp) {
    437		DP_INFO(edev, "Failed to allocate struct for PTP\n");
    438		return -ENOMEM;
    439	}
    440
    441	ptp->edev = edev;
    442	ptp->ops = edev->ops->ptp;
    443	if (!ptp->ops) {
    444		DP_INFO(edev, "PTP enable failed\n");
    445		rc = -EIO;
    446		goto err1;
    447	}
    448
    449	edev->ptp = ptp;
    450
    451	rc = qede_ptp_init(edev);
    452	if (rc)
    453		goto err1;
    454
    455	qede_ptp_cfg_filters(edev);
    456
    457	/* Fill the ptp_clock_info struct and register PTP clock */
    458	ptp->clock_info.owner = THIS_MODULE;
    459	snprintf(ptp->clock_info.name, 16, "%s", edev->ndev->name);
    460	ptp->clock_info.max_adj = QED_MAX_PHC_DRIFT_PPB;
    461	ptp->clock_info.n_alarm = 0;
    462	ptp->clock_info.n_ext_ts = 0;
    463	ptp->clock_info.n_per_out = 0;
    464	ptp->clock_info.pps = 0;
    465	ptp->clock_info.adjfreq = qede_ptp_adjfreq;
    466	ptp->clock_info.adjtime = qede_ptp_adjtime;
    467	ptp->clock_info.gettime64 = qede_ptp_gettime;
    468	ptp->clock_info.settime64 = qede_ptp_settime;
    469	ptp->clock_info.enable = qede_ptp_ancillary_feature_enable;
    470
    471	ptp->clock = ptp_clock_register(&ptp->clock_info, &edev->pdev->dev);
    472	if (IS_ERR(ptp->clock)) {
    473		DP_ERR(edev, "PTP clock registration failed\n");
    474		qede_ptp_disable(edev);
    475		rc = -EINVAL;
    476		goto err2;
    477	}
    478
    479	return 0;
    480
    481err1:
    482	kfree(ptp);
    483err2:
    484	edev->ptp = NULL;
    485
    486	return rc;
    487}
    488
    489void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb)
    490{
    491	struct qede_ptp *ptp;
    492
    493	ptp = edev->ptp;
    494	if (!ptp)
    495		return;
    496
    497	if (test_and_set_bit_lock(QEDE_FLAGS_PTP_TX_IN_PRORGESS,
    498				  &edev->flags)) {
    499		DP_VERBOSE(edev, QED_MSG_DEBUG, "Timestamping in progress\n");
    500		edev->ptp_skip_txts++;
    501		return;
    502	}
    503
    504	if (unlikely(!test_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags))) {
    505		DP_VERBOSE(edev, QED_MSG_DEBUG,
    506			   "Tx timestamping was not enabled, this pkt will not be timestamped\n");
    507		clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
    508		edev->ptp_skip_txts++;
    509	} else if (unlikely(ptp->tx_skb)) {
    510		DP_VERBOSE(edev, QED_MSG_DEBUG,
    511			   "Device supports a single outstanding pkt to ts, It will not be ts\n");
    512		clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
    513		edev->ptp_skip_txts++;
    514	} else {
    515		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
    516		/* schedule check for Tx timestamp */
    517		ptp->tx_skb = skb_get(skb);
    518		ptp->ptp_tx_start = jiffies;
    519		schedule_work(&ptp->work);
    520	}
    521}
    522
    523void qede_ptp_rx_ts(struct qede_dev *edev, struct sk_buff *skb)
    524{
    525	struct qede_ptp *ptp;
    526	u64 timestamp, ns;
    527	int rc;
    528
    529	ptp = edev->ptp;
    530	if (!ptp)
    531		return;
    532
    533	spin_lock_bh(&ptp->lock);
    534	rc = ptp->ops->read_rx_ts(edev->cdev, &timestamp);
    535	if (rc) {
    536		spin_unlock_bh(&ptp->lock);
    537		DP_INFO(edev, "Invalid Rx timestamp\n");
    538		return;
    539	}
    540
    541	ns = timecounter_cyc2time(&ptp->tc, timestamp);
    542	spin_unlock_bh(&ptp->lock);
    543	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);
    544	DP_VERBOSE(edev, QED_MSG_DEBUG,
    545		   "Rx timestamp, timestamp cycles = %llu, ns = %llu\n",
    546		   timestamp, ns);
    547}