Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5657f89a authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'qed-PTP-fixes'



Sudarsana Reddy Kalluru says:

====================
qed*: PTP bug fixes.

The series addresses couple of issues in the PTP implementation.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 212c7fd6 8d3f87d8
Loading
Loading
Loading
Loading
+53 −31
Original line number Diff line number Diff line
@@ -188,39 +188,73 @@ static int qed_ptp_hw_read_cc(struct qed_dev *cdev, u64 *phc_cycles)
}

/* Filter PTP protocol packets that need to be timestamped */
static int qed_ptp_hw_cfg_rx_filters(struct qed_dev *cdev,
				     enum qed_ptp_filter_type type)
static int qed_ptp_hw_cfg_filters(struct qed_dev *cdev,
				  enum qed_ptp_filter_type rx_type,
				  enum qed_ptp_hwtstamp_tx_type tx_type)
{
	struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
	struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;
	u32 rule_mask, parm_mask;
	u32 rule_mask, enable_cfg = 0x0;

	switch (type) {
	case QED_PTP_FILTER_L2_IPV4_IPV6:
		parm_mask = 0x6AA;
		rule_mask = 0x3EEE;
	switch (rx_type) {
	case QED_PTP_FILTER_NONE:
		enable_cfg = 0x0;
		rule_mask = 0x3FFF;
		break;
	case QED_PTP_FILTER_L2:
		parm_mask = 0x6BF;
		rule_mask = 0x3EFF;
	case QED_PTP_FILTER_ALL:
		enable_cfg = 0x7;
		rule_mask = 0x3CAA;
		break;
	case QED_PTP_FILTER_IPV4_IPV6:
		parm_mask = 0x7EA;
		rule_mask = 0x3FFE;
	case QED_PTP_FILTER_V1_L4_EVENT:
		enable_cfg = 0x3;
		rule_mask = 0x3FFA;
		break;
	case QED_PTP_FILTER_IPV4:
		parm_mask = 0x7EE;
	case QED_PTP_FILTER_V1_L4_GEN:
		enable_cfg = 0x3;
		rule_mask = 0x3FFE;
		break;
	case QED_PTP_FILTER_V2_L4_EVENT:
		enable_cfg = 0x5;
		rule_mask = 0x3FAA;
		break;
	case QED_PTP_FILTER_V2_L4_GEN:
		enable_cfg = 0x5;
		rule_mask = 0x3FEE;
		break;
	case QED_PTP_FILTER_V2_L2_EVENT:
		enable_cfg = 0x5;
		rule_mask = 0x3CFF;
		break;
	case QED_PTP_FILTER_V2_L2_GEN:
		enable_cfg = 0x5;
		rule_mask = 0x3EFF;
		break;
	case QED_PTP_FILTER_V2_EVENT:
		enable_cfg = 0x5;
		rule_mask = 0x3CAA;
		break;
	case QED_PTP_FILTER_V2_GEN:
		enable_cfg = 0x5;
		rule_mask = 0x3EEE;
		break;
	default:
		DP_INFO(p_hwfn, "Invalid PTP filter type %d\n", type);
		DP_INFO(p_hwfn, "Invalid PTP filter type %d\n", rx_type);
		return -EINVAL;
	}

	qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_PARAM_MASK, parm_mask);
	qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_PARAM_MASK, 0);
	qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_RULE_MASK, rule_mask);
	qed_wr(p_hwfn, p_ptt, NIG_REG_RX_PTP_EN, enable_cfg);

	qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_TO_HOST, 0x1);
	if (tx_type == QED_PTP_HWTSTAMP_TX_OFF) {
		qed_wr(p_hwfn, p_ptt, NIG_REG_TX_PTP_EN, 0x0);
		qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0x7FF);
		qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, 0x3FFF);
	} else {
		qed_wr(p_hwfn, p_ptt, NIG_REG_TX_PTP_EN, enable_cfg);
		qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0);
		qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, rule_mask);
	}

	/* Reset possibly old timestamps */
	qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_PTP_HOST_BUF_SEQID,
@@ -383,17 +417,6 @@ static int qed_ptp_hw_enable(struct qed_dev *cdev)
	return 0;
}

static int qed_ptp_hw_hwtstamp_tx_on(struct qed_dev *cdev)
{
	struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
	struct qed_ptt *p_ptt = p_hwfn->p_ptp_ptt;

	qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_PARAM_MASK, 0x6AA);
	qed_wr(p_hwfn, p_ptt, NIG_REG_TX_LLH_PTP_RULE_MASK, 0x3EEE);

	return 0;
}

static int qed_ptp_hw_disable(struct qed_dev *cdev)
{
	struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
@@ -419,8 +442,7 @@ static int qed_ptp_hw_disable(struct qed_dev *cdev)
}

const struct qed_eth_ptp_ops qed_ptp_ops_pass = {
	.hwtstamp_tx_on = qed_ptp_hw_hwtstamp_tx_on,
	.cfg_rx_filters = qed_ptp_hw_cfg_rx_filters,
	.cfg_filters = qed_ptp_hw_cfg_filters,
	.read_rx_ts = qed_ptp_hw_read_rx_ts,
	.read_tx_ts = qed_ptp_hw_read_tx_ts,
	.read_cc = qed_ptp_hw_read_cc,
+3 −2
Original line number Diff line number Diff line
@@ -167,10 +167,11 @@ struct qede_dev {
	u32				dp_module;
	u8				dp_level;

	u32 flags;
	unsigned long flags;
#define QEDE_FLAG_IS_VF			BIT(0)
#define IS_VF(edev)	(!!((edev)->flags & QEDE_FLAG_IS_VF))
#define QEDE_TX_TIMESTAMPING_EN		BIT(1)
#define QEDE_FLAGS_PTP_TX_IN_PRORGESS	BIT(2)

	const struct qed_eth_ops	*ops;
	struct qede_ptp			*ptp;
+32 −6
Original line number Diff line number Diff line
@@ -181,6 +181,7 @@ static void qede_ptp_task(struct work_struct *work)
	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",
@@ -208,6 +209,8 @@ static u64 qede_ptp_read_cc(const struct cyclecounter *cc)

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)
@@ -221,7 +224,12 @@ static int qede_ptp_cfg_filters(struct qede_dev *edev)
	switch (ptp->tx_type) {
	case HWTSTAMP_TX_ON:
		edev->flags |= QEDE_TX_TIMESTAMPING_EN;
		ptp->ops->hwtstamp_tx_on(edev->cdev);
		tx_type = QED_PTP_HWTSTAMP_TX_ON;
		break;

	case HWTSTAMP_TX_OFF:
		edev->flags &= ~QEDE_TX_TIMESTAMPING_EN;
		tx_type = QED_PTP_HWTSTAMP_TX_OFF;
		break;

	case HWTSTAMP_TX_ONESTEP_SYNC:
@@ -232,42 +240,57 @@ static int qede_ptp_cfg_filters(struct qede_dev *edev)
	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:
		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 */
		ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_IPV4);
		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 */
		ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_IPV4_IPV6);
		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 */
		ptp->ops->cfg_rx_filters(edev->cdev, QED_PTP_FILTER_L2);
		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 */
		ptp->ops->cfg_rx_filters(edev->cdev,
					 QED_PTP_FILTER_L2_IPV4_IPV6);
		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;
@@ -485,6 +508,9 @@ void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb)
	if (!ptp)
		return;

	if (test_and_set_bit_lock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags))
		return;

	if (unlikely(!(edev->flags & QEDE_TX_TIMESTAMPING_EN))) {
		DP_NOTICE(edev,
			  "Tx timestamping was not enabled, this packet will not be timestamped\n");
+17 −6
Original line number Diff line number Diff line
@@ -164,10 +164,21 @@ struct qed_eth_cb_ops {
#define QED_MAX_PHC_DRIFT_PPB   291666666

enum qed_ptp_filter_type {
	QED_PTP_FILTER_L2,
	QED_PTP_FILTER_IPV4,
	QED_PTP_FILTER_IPV4_IPV6,
	QED_PTP_FILTER_L2_IPV4_IPV6
	QED_PTP_FILTER_NONE,
	QED_PTP_FILTER_ALL,
	QED_PTP_FILTER_V1_L4_EVENT,
	QED_PTP_FILTER_V1_L4_GEN,
	QED_PTP_FILTER_V2_L4_EVENT,
	QED_PTP_FILTER_V2_L4_GEN,
	QED_PTP_FILTER_V2_L2_EVENT,
	QED_PTP_FILTER_V2_L2_GEN,
	QED_PTP_FILTER_V2_EVENT,
	QED_PTP_FILTER_V2_GEN
};

enum qed_ptp_hwtstamp_tx_type {
	QED_PTP_HWTSTAMP_TX_OFF,
	QED_PTP_HWTSTAMP_TX_ON,
};

#ifdef CONFIG_DCB
@@ -230,8 +241,8 @@ struct qed_eth_dcbnl_ops {
#endif

struct qed_eth_ptp_ops {
	int (*hwtstamp_tx_on)(struct qed_dev *);
	int (*cfg_rx_filters)(struct qed_dev *, enum qed_ptp_filter_type);
	int (*cfg_filters)(struct qed_dev *, enum qed_ptp_filter_type,
			   enum qed_ptp_hwtstamp_tx_type);
	int (*read_rx_ts)(struct qed_dev *, u64 *);
	int (*read_tx_ts)(struct qed_dev *, u64 *);
	int (*read_cc)(struct qed_dev *, u64 *);