Commit 92595a0c authored by Pavan Chebbi's avatar Pavan Chebbi Committed by David S. Miller
Browse files

bnxt_en: Refactor all PTP TX timestamp fields into a struct



On the older 5750X (P5) chips, we currently support only 1 TX PTP
packet in-flight waiting for the timestamp.  Refactor the
datastructures to prepare to support up to 4 TX PTP packets.

Combine all fields required for PTP TX timestamp query into one
structure.  An array of this structure will be added in follow-on
patches to support multiple outstanding TX timestamps.

Signed-off-by: default avatarPavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4d588d32
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -517,14 +517,18 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
			tx_buf->is_ts_pkt = 1;
			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
		} else if (!skb_is_gso(skb)) {
			u16 seq_id, hdr_off;

			if (atomic_dec_if_positive(&ptp->tx_avail) < 0) {
				atomic64_inc(&ptp->stats.ts_err);
				goto tx_no_ts;
			}
			if (!bnxt_ptp_parse(skb, &ptp->tx_seqid,
					    &ptp->tx_hdr_off)) {

			if (!bnxt_ptp_parse(skb, &seq_id, &hdr_off)) {
				if (vlan_tag_flags)
					ptp->tx_hdr_off += VLAN_HLEN;
					hdr_off += VLAN_HLEN;
				ptp->txts_req.tx_seqid = seq_id;
				ptp->txts_req.tx_hdr_off = hdr_off;
				lflags |= cpu_to_le32(TX_BD_FLAGS_STAMP);
				tx_buf->is_ts_pkt = 1;
				skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+23 −20
Original line number Diff line number Diff line
@@ -123,11 +123,12 @@ static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts,
	req->flags = cpu_to_le32(flags);
	if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH) ==
	    PORT_TS_QUERY_REQ_FLAGS_PATH_TX) {
		struct bnxt_ptp_tx_req *txts_req = &bp->ptp_cfg->txts_req;
		u32 tmo_us = txts_tmo * 1000;

		req->enables = cpu_to_le16(BNXT_PTP_QTS_TX_ENABLES);
		req->ptp_seq_id = cpu_to_le32(bp->ptp_cfg->tx_seqid);
		req->ptp_hdr_offset = cpu_to_le16(bp->ptp_cfg->tx_hdr_off);
		req->ptp_seq_id = cpu_to_le32(txts_req->tx_seqid);
		req->ptp_hdr_offset = cpu_to_le16(txts_req->tx_hdr_off);
		if (!tmo_us)
			tmo_us = BNXT_PTP_QTS_TIMEOUT;
		tmo_us = min(tmo_us, BNXT_PTP_QTS_MAX_TMO_US);
@@ -686,15 +687,17 @@ static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
{
	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
	struct skb_shared_hwtstamps timestamp;
	struct bnxt_ptp_tx_req *txts_req;
	unsigned long now = jiffies;
	u64 ts = 0, ns = 0;
	u32 tmo = 0;
	int rc;

	if (!ptp->txts_pending)
		ptp->abs_txts_tmo = now + msecs_to_jiffies(ptp->txts_tmo);
	if (!time_after_eq(now, ptp->abs_txts_tmo))
		tmo = jiffies_to_msecs(ptp->abs_txts_tmo - now);
	txts_req = &ptp->txts_req;
	if (!txts_req->txts_pending)
		txts_req->abs_txts_tmo = now + msecs_to_jiffies(ptp->txts_tmo);
	if (!time_after_eq(now, txts_req->abs_txts_tmo))
		tmo = jiffies_to_msecs(txts_req->abs_txts_tmo - now);
	rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts,
				     tmo);
	if (!rc) {
@@ -703,11 +706,11 @@ static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
		ns = timecounter_cyc2time(&ptp->tc, ts);
		spin_unlock_bh(&ptp->ptp_lock);
		timestamp.hwtstamp = ns_to_ktime(ns);
		skb_tstamp_tx(ptp->tx_skb, &timestamp);
		skb_tstamp_tx(txts_req->tx_skb, &timestamp);
		ptp->stats.ts_pkts++;
	} else {
		if (!time_after_eq(jiffies, ptp->abs_txts_tmo)) {
			ptp->txts_pending = true;
		if (!time_after_eq(jiffies, txts_req->abs_txts_tmo)) {
			txts_req->txts_pending = true;
			return;
		}
		ptp->stats.ts_lost++;
@@ -715,10 +718,10 @@ static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
				 "TS query for TX timer failed rc = %x\n", rc);
	}

	dev_kfree_skb_any(ptp->tx_skb);
	ptp->tx_skb = NULL;
	dev_kfree_skb_any(txts_req->tx_skb);
	txts_req->tx_skb = NULL;
	atomic_inc(&ptp->tx_avail);
	ptp->txts_pending = false;
	txts_req->txts_pending = false;
}

static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
@@ -728,8 +731,8 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
	unsigned long now = jiffies;
	struct bnxt *bp = ptp->bp;

	if (ptp->tx_skb)
		bnxt_stamp_tx_skb(bp, ptp->tx_skb);
	if (ptp->txts_req.tx_skb)
		bnxt_stamp_tx_skb(bp, ptp->txts_req.tx_skb);

	if (!time_after_eq(now, ptp->next_period))
		return ptp->next_period - now;
@@ -742,7 +745,7 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
		spin_unlock_bh(&ptp->ptp_lock);
		ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD;
	}
	if (ptp->txts_pending)
	if (ptp->txts_req.txts_pending)
		return 0;
	return HZ;
}
@@ -751,11 +754,11 @@ int bnxt_get_tx_ts_p5(struct bnxt *bp, struct sk_buff *skb)
{
	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;

	if (ptp->tx_skb) {
	if (ptp->txts_req.tx_skb) {
		netdev_err(bp->dev, "deferring skb:one SKB is still outstanding\n");
		return -EBUSY;
	}
	ptp->tx_skb = skb;
	ptp->txts_req.tx_skb = skb;
	ptp_schedule_worker(ptp->ptp_clock, 0);
	return 0;
}
@@ -1056,9 +1059,9 @@ void bnxt_ptp_clear(struct bnxt *bp)
	kfree(ptp->ptp_info.pin_config);
	ptp->ptp_info.pin_config = NULL;

	if (ptp->tx_skb) {
		dev_kfree_skb_any(ptp->tx_skb);
		ptp->tx_skb = NULL;
	if (ptp->txts_req.tx_skb) {
		dev_kfree_skb_any(ptp->txts_req.tx_skb);
		ptp->txts_req.tx_skb = NULL;
	}

	bnxt_unmap_ptp_regs(bp);
+10 −5
Original line number Diff line number Diff line
@@ -85,6 +85,14 @@ struct bnxt_ptp_stats {
	atomic64_t	ts_err;
};

struct bnxt_ptp_tx_req {
	struct sk_buff		*tx_skb;
	u16			tx_seqid;
	u16			tx_hdr_off;
	u8			txts_pending:1;
	unsigned long		abs_txts_tmo;
};

struct bnxt_ptp_cfg {
	struct ptp_clock_info	ptp_info;
	struct ptp_clock	*ptp_clock;
@@ -93,7 +101,6 @@ struct bnxt_ptp_cfg {
	struct bnxt_pps		pps_info;
	/* serialize timecounter access */
	spinlock_t		ptp_lock;
	struct sk_buff		*tx_skb;
	u64			current_time;
	u64			old_time;
	unsigned long		next_period;
@@ -102,8 +109,8 @@ struct bnxt_ptp_cfg {
	/* a 23b shift cyclecounter will overflow in ~36 mins.  Check overflow every 18 mins. */
	#define BNXT_PHC_OVERFLOW_PERIOD	(18 * 60 * HZ)

	u16			tx_seqid;
	u16			tx_hdr_off;
	struct bnxt_ptp_tx_req	txts_req;

	struct bnxt		*bp;
	atomic_t		tx_avail;
#define BNXT_MAX_TX_TS	1
@@ -123,14 +130,12 @@ struct bnxt_ptp_cfg {
					 BNXT_PTP_MSG_PDELAY_REQ |	\
					 BNXT_PTP_MSG_PDELAY_RESP)
	u8			tx_tstamp_en:1;
	u8			txts_pending:1;
	int			rx_filter;
	u32			tstamp_filters;

	u32			refclk_regs[2];
	u32			refclk_mapped_regs[2];
	u32			txts_tmo;
	unsigned long		abs_txts_tmo;

	struct bnxt_ptp_stats	stats;
};