/* QLogic qede NIC Driver
 * Copyright (c) 2015-2017  QLogic Corporation
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and /or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "qede_ptp.h"
#define QEDE_PTP_TX_TIMEOUT (2 * HZ)

struct qede_ptp {
	const struct qed_eth_ptp_ops	*ops;
	struct ptp_clock_info		clock_info;
	struct cyclecounter		cc;
	struct timecounter		tc;
	struct ptp_clock		*clock;
	struct work_struct		work;
	unsigned long			ptp_tx_start;
	struct qede_dev			*edev;
	struct sk_buff			*tx_skb;

	/* ptp spinlock is used for protecting the cycle/time counter fields
	 * and, also for serializing the qed PTP API invocations.
	 */
	spinlock_t			lock;
	bool				hw_ts_ioctl_called;
	u16				tx_type;
	u16				rx_filter;
};

/**
 * qede_ptp_adjfreq
 * @ptp: the ptp clock structure
 * @ppb: parts per billion adjustment from base
 *
 * Adjust the frequency of the ptp cycle counter by the
 * indicated ppb from the base frequency.
 */
static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb)
{
	struct qede_ptp *ptp = container_of(info, struct qede_ptp, clock_info);
	struct qede_dev *edev = ptp->edev;
	int rc;

	__qede_lock(edev);
	if (edev->state == QEDE_STATE_OPEN) {
		spin_lock_bh(&ptp->lock);
		rc = ptp->ops->adjfreq(edev->cdev, ppb);
		spin_unlock_bh(&ptp->lock);
	} else {
		DP_ERR(edev, "PTP adjfreq called while interface is down\n");
		rc = -EFAULT;
	}
	__qede_unlock(edev);

	return rc;
}

static int qede_ptp_adjtime(struct ptp_clock_info *info, s64 delta)
{
	struct qede_dev *edev;
	struct qede_ptp *ptp;

	ptp = container_of(info, struct qede_ptp, clock_info);
	edev = ptp->edev;

	DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP adjtime called, delta = %llx\n",
		   delta);

	spin_lock_bh(&ptp->lock);
	timecounter_adjtime(&ptp->tc, delta);
	spin_unlock_bh(&ptp->lock);

	return 0;
}

static int qede_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
{
	struct qede_dev *edev;
	struct qede_ptp *ptp;
	u64 ns;

	ptp = container_of(info, struct qede_ptp, clock_info);
	edev = ptp->edev;

	spin_lock_bh(&ptp->lock);
	ns = timecounter_read(&ptp->tc);
	spin_unlock_bh(&ptp->lock);

	DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP gettime called, ns = %llu\n", ns);

	*ts = ns_to_timespec64(ns);

	return 0;
}

static int qede_ptp_settime(struct ptp_clock_info *info,
			    const struct timespec64 *ts)
{
	struct qede_dev *edev;
	struct qede_ptp *ptp;
	u64 ns;

	ptp = container_of(info, struct qede_ptp, clock_info);
	edev = ptp->edev;

	ns = timespec64_to_ns(ts);

	DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP settime called, ns = %llu\n", ns);

	/* Re-init the timecounter */
	spin_lock_bh(&ptp->lock);
	timecounter_init(&ptp->tc, &ptp->cc, ns);
	spin_unlock_bh(&ptp->lock);

	return 0;
}

/* Enable (or disable) ancillary features of the phc subsystem */
static int qede_ptp_ancillary_feature_enable(struct ptp_clock_info *info,
					     struct ptp_clock_request *rq,
					     int on)
{
	struct qede_dev *edev;
	struct qede_ptp *ptp;

	ptp = container_of(info, struct qede_ptp, clock_info);
	edev = ptp->edev;

	DP_ERR(edev, "PHC ancillary features are not supported\n");

	return -ENOTSUPP;
}

static void qede_ptp_task(struct work_struct *work)
{
	struct skb_shared_hwtstamps shhwtstamps;
	struct qede_dev *edev;
	struct qede_ptp *ptp;
	u64 timestamp, ns;
	bool timedout;
	int rc;

	ptp = container_of(work, struct qede_ptp, work);
	edev = ptp->edev;
	timedout = time_is_before_jiffies(ptp->ptp_tx_start +
					  QEDE_PTP_TX_TIMEOUT);

	/* Read Tx timestamp registers */
	spin_lock_bh(&ptp->lock);
	rc = ptp->ops->read_tx_ts(edev->cdev, &timestamp);
	spin_unlock_bh(&ptp->lock);
	if (rc) {
		if (unlikely(timedout)) {
			DP_INFO(edev, "Tx timestamp is not recorded\n");
			dev_kfree_skb_any(ptp->tx_skb);
			ptp->tx_skb = NULL;
			clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS,
					 &edev->flags);
			edev->ptp_skip_txts++;
		} else {
			/* Reschedule to keep checking for a valid TS value */
			schedule_work(&ptp->work);
		}
		return;
	}

	ns = timecounter_cyc2time(&ptp->tc, timestamp);
	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
	shhwtstamps.hwtstamp = ns_to_ktime(ns);
	skb_tstamp_tx(ptp->tx_skb, &shhwtstamps);
	dev_kfree_skb_any(ptp->tx_skb);
	ptp->tx_skb = NULL;
	clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);

	DP_VERBOSE(edev, QED_MSG_DEBUG,
		   "Tx timestamp, timestamp cycles = %llu, ns = %llu\n",
		   timestamp, ns);
}

/* Read the PHC. This API is invoked with ptp_lock held. */
static u64 qede_ptp_read_cc(const struct cyclecounter *cc)
{
	struct qede_dev *edev;
	struct qede_ptp *ptp;
	u64 phc_cycles;
	int rc;

	ptp = container_of(cc, struct qede_ptp, cc);
	edev = ptp->edev;
	rc = ptp->ops->read_cc(edev->cdev, &phc_cycles);
	if (rc)
		WARN_ONCE(1, "PHC read err %d\n", rc);

	DP_VERBOSE(edev, QED_MSG_DEBUG, "PHC read cycles = %llu\n", phc_cycles);

	return phc_cycles;
}

static int qede_ptp_cfg_filters(struct qede_dev *edev)
{
	enum qed_ptp_hwtstamp_tx_type tx_type = QED_PTP_HWTSTAMP_TX_ON;
	enum qed_ptp_filter_type rx_filter = QED_PTP_FILTER_NONE;
	struct qede_ptp *ptp = edev->ptp;

	if (!ptp)
		return -EIO;

	if (!ptp->hw_ts_ioctl_called) {
		DP_INFO(edev, "TS IOCTL not called\n");
		return 0;
	}

	switch (ptp->tx_type) {
	case HWTSTAMP_TX_ON:
		set_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags);
		tx_type = QED_PTP_HWTSTAMP_TX_ON;
		break;

	case HWTSTAMP_TX_OFF:
		clear_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags);
		tx_type = QED_PTP_HWTSTAMP_TX_OFF;
		break;

	case HWTSTAMP_TX_ONESTEP_SYNC:
	case HWTSTAMP_TX_ONESTEP_P2P:
		DP_ERR(edev, "One-step timestamping is not supported\n");
		return -ERANGE;
	}

	spin_lock_bh(&ptp->lock);
	switch (ptp->rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		rx_filter = QED_PTP_FILTER_NONE;
		break;
	case HWTSTAMP_FILTER_ALL:
	case HWTSTAMP_FILTER_SOME:
	case HWTSTAMP_FILTER_NTP_ALL:
		ptp->rx_filter = HWTSTAMP_FILTER_NONE;
		rx_filter = QED_PTP_FILTER_ALL;
		break;
	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
		rx_filter = QED_PTP_FILTER_V1_L4_EVENT;
		break;
	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
		/* Initialize PTP detection for UDP/IPv4 events */
		rx_filter = QED_PTP_FILTER_V1_L4_GEN;
		break;
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
		rx_filter = QED_PTP_FILTER_V2_L4_EVENT;
		break;
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
		/* Initialize PTP detection for UDP/IPv4 or UDP/IPv6 events */
		rx_filter = QED_PTP_FILTER_V2_L4_GEN;
		break;
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
		rx_filter = QED_PTP_FILTER_V2_L2_EVENT;
		break;
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
		/* Initialize PTP detection L2 events */
		rx_filter = QED_PTP_FILTER_V2_L2_GEN;
		break;
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
		rx_filter = QED_PTP_FILTER_V2_EVENT;
		break;
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
		ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
		/* Initialize PTP detection L2, UDP/IPv4 or UDP/IPv6 events */
		rx_filter = QED_PTP_FILTER_V2_GEN;
		break;
	}

	ptp->ops->cfg_filters(edev->cdev, rx_filter, tx_type);

	spin_unlock_bh(&ptp->lock);

	return 0;
}

int qede_ptp_hw_ts(struct qede_dev *edev, struct ifreq *ifr)
{
	struct hwtstamp_config config;
	struct qede_ptp *ptp;
	int rc;

	ptp = edev->ptp;
	if (!ptp)
		return -EIO;

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

	DP_VERBOSE(edev, QED_MSG_DEBUG,
		   "HWTSTAMP IOCTL: Requested tx_type = %d, requested rx_filters = %d\n",
		   config.tx_type, config.rx_filter);

	if (config.flags) {
		DP_ERR(edev, "config.flags is reserved for future use\n");
		return -EINVAL;
	}

	ptp->hw_ts_ioctl_called = 1;
	ptp->tx_type = config.tx_type;
	ptp->rx_filter = config.rx_filter;

	rc = qede_ptp_cfg_filters(edev);
	if (rc)
		return rc;

	config.rx_filter = ptp->rx_filter;

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

int qede_ptp_get_ts_info(struct qede_dev *edev, struct ethtool_ts_info *info)
{
	struct qede_ptp *ptp = edev->ptp;

	if (!ptp) {
		info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
					SOF_TIMESTAMPING_RX_SOFTWARE |
					SOF_TIMESTAMPING_SOFTWARE;
		info->phc_index = -1;

		return 0;
	}

	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
				SOF_TIMESTAMPING_RX_SOFTWARE |
				SOF_TIMESTAMPING_SOFTWARE |
				SOF_TIMESTAMPING_TX_HARDWARE |
				SOF_TIMESTAMPING_RX_HARDWARE |
				SOF_TIMESTAMPING_RAW_HARDWARE;

	if (ptp->clock)
		info->phc_index = ptp_clock_index(ptp->clock);
	else
		info->phc_index = -1;

	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) |
			   BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ);

	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);

	return 0;
}

void qede_ptp_disable(struct qede_dev *edev)
{
	struct qede_ptp *ptp;

	ptp = edev->ptp;
	if (!ptp)
		return;

	if (ptp->clock) {
		ptp_clock_unregister(ptp->clock);
		ptp->clock = NULL;
	}

	/* Cancel PTP work queue. Should be done after the Tx queues are
	 * drained to prevent additional scheduling.
	 */
	cancel_work_sync(&ptp->work);
	if (ptp->tx_skb) {
		dev_kfree_skb_any(ptp->tx_skb);
		ptp->tx_skb = NULL;
	}

	/* Disable PTP in HW */
	spin_lock_bh(&ptp->lock);
	ptp->ops->disable(edev->cdev);
	spin_unlock_bh(&ptp->lock);

	kfree(ptp);
	edev->ptp = NULL;
}

static int qede_ptp_init(struct qede_dev *edev, bool init_tc)
{
	struct qede_ptp *ptp;
	int rc;

	ptp = edev->ptp;
	if (!ptp)
		return -EINVAL;

	spin_lock_init(&ptp->lock);

	/* Configure PTP in HW */
	rc = ptp->ops->enable(edev->cdev);
	if (rc) {
		DP_INFO(edev, "PTP HW enable failed\n");
		return rc;
	}

	/* Init work queue for Tx timestamping */
	INIT_WORK(&ptp->work, qede_ptp_task);

	/* Init cyclecounter and timecounter. This is done only in the first
	 * load. If done in every load, PTP application will fail when doing
	 * unload / load (e.g. MTU change) while it is running.
	 */
	if (init_tc) {
		memset(&ptp->cc, 0, sizeof(ptp->cc));
		ptp->cc.read = qede_ptp_read_cc;
		ptp->cc.mask = CYCLECOUNTER_MASK(64);
		ptp->cc.shift = 0;
		ptp->cc.mult = 1;

		timecounter_init(&ptp->tc, &ptp->cc,
				 ktime_to_ns(ktime_get_real()));
	}

	return rc;
}

int qede_ptp_enable(struct qede_dev *edev, bool init_tc)
{
	struct qede_ptp *ptp;
	int rc;

	ptp = kzalloc(sizeof(*ptp), GFP_KERNEL);
	if (!ptp) {
		DP_INFO(edev, "Failed to allocate struct for PTP\n");
		return -ENOMEM;
	}

	ptp->edev = edev;
	ptp->ops = edev->ops->ptp;
	if (!ptp->ops) {
		DP_INFO(edev, "PTP enable failed\n");
		rc = -EIO;
		goto err1;
	}

	edev->ptp = ptp;

	rc = qede_ptp_init(edev, init_tc);
	if (rc)
		goto err1;

	qede_ptp_cfg_filters(edev);

	/* Fill the ptp_clock_info struct and register PTP clock */
	ptp->clock_info.owner = THIS_MODULE;
	snprintf(ptp->clock_info.name, 16, "%s", edev->ndev->name);
	ptp->clock_info.max_adj = QED_MAX_PHC_DRIFT_PPB;
	ptp->clock_info.n_alarm = 0;
	ptp->clock_info.n_ext_ts = 0;
	ptp->clock_info.n_per_out = 0;
	ptp->clock_info.pps = 0;
	ptp->clock_info.adjfreq = qede_ptp_adjfreq;
	ptp->clock_info.adjtime = qede_ptp_adjtime;
	ptp->clock_info.gettime64 = qede_ptp_gettime;
	ptp->clock_info.settime64 = qede_ptp_settime;
	ptp->clock_info.enable = qede_ptp_ancillary_feature_enable;

	ptp->clock = ptp_clock_register(&ptp->clock_info, &edev->pdev->dev);
	if (IS_ERR(ptp->clock)) {
		DP_ERR(edev, "PTP clock registration failed\n");
		qede_ptp_disable(edev);
		rc = -EINVAL;
		goto err2;
	}

	return 0;

err1:
	kfree(ptp);
err2:
	edev->ptp = NULL;

	return rc;
}

void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb)
{
	struct qede_ptp *ptp;

	ptp = edev->ptp;
	if (!ptp)
		return;

	if (test_and_set_bit_lock(QEDE_FLAGS_PTP_TX_IN_PRORGESS,
				  &edev->flags)) {
		DP_ERR(edev, "Timestamping in progress\n");
		edev->ptp_skip_txts++;
		return;
	}

	if (unlikely(!test_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags))) {
		DP_ERR(edev,
		       "Tx timestamping was not enabled, this packet will not be timestamped\n");
		clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
		edev->ptp_skip_txts++;
	} else if (unlikely(ptp->tx_skb)) {
		DP_ERR(edev,
		       "The device supports only a single outstanding packet to timestamp, this packet will not be timestamped\n");
		clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags);
		edev->ptp_skip_txts++;
	} else {
		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
		/* schedule check for Tx timestamp */
		ptp->tx_skb = skb_get(skb);
		ptp->ptp_tx_start = jiffies;
		schedule_work(&ptp->work);
	}
}

void qede_ptp_rx_ts(struct qede_dev *edev, struct sk_buff *skb)
{
	struct qede_ptp *ptp;
	u64 timestamp, ns;
	int rc;

	ptp = edev->ptp;
	if (!ptp)
		return;

	spin_lock_bh(&ptp->lock);
	rc = ptp->ops->read_rx_ts(edev->cdev, &timestamp);
	if (rc) {
		spin_unlock_bh(&ptp->lock);
		DP_INFO(edev, "Invalid Rx timestamp\n");
		return;
	}

	ns = timecounter_cyc2time(&ptp->tc, timestamp);
	spin_unlock_bh(&ptp->lock);
	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);
	DP_VERBOSE(edev, QED_MSG_DEBUG,
		   "Rx timestamp, timestamp cycles = %llu, ns = %llu\n",
		   timestamp, ns);
}
