Commit ae5c42f0 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

bnxt_en: Get PTP hardware capability from firmware



Store PTP hardware info in a structure if hardware and firmware support PTP.

Reviewed-by: default avatarEdwin Peer <edwin.peer@broadcom.com>
Reviewed-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 78eeadb8
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@
#include <linux/log2.h>
#include <linux/aer.h>
#include <linux/bitmap.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/timecounter.h>
#include <linux/cpu_rmap.h>
#include <linux/cpumask.h>
#include <net/pkt_cls.h>
@@ -63,6 +65,7 @@
#include "bnxt_ethtool.h"
#include "bnxt_dcb.h"
#include "bnxt_xdp.h"
#include "bnxt_ptp.h"
#include "bnxt_vfr.h"
#include "bnxt_tc.h"
#include "bnxt_devlink.h"
@@ -7391,6 +7394,56 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp, bool all)
	return rc;
}

/* bp->hwrm_cmd_lock already held. */
static int __bnxt_hwrm_ptp_qcfg(struct bnxt *bp)
{
	struct hwrm_port_mac_ptp_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
	struct hwrm_port_mac_ptp_qcfg_input req = {0};
	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
	u8 flags;
	int rc;

	if (bp->hwrm_spec_code < 0x10801) {
		rc = -ENODEV;
		goto no_ptp;
	}

	req.port_id = cpu_to_le16(bp->pf.port_id);
	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_MAC_PTP_QCFG, -1, -1);
	rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
	if (rc)
		goto no_ptp;

	flags = resp->flags;
	if (!(flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_HWRM_ACCESS)) {
		rc = -ENODEV;
		goto no_ptp;
	}
	if (!ptp) {
		ptp = kzalloc(sizeof(*ptp), GFP_KERNEL);
		if (!ptp)
			return -ENOMEM;
		ptp->bp = bp;
		bp->ptp_cfg = ptp;
	}
	if (flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_PARTIAL_DIRECT_ACCESS_REF_CLOCK) {
		ptp->refclk_regs[0] = le32_to_cpu(resp->ts_ref_clock_reg_lower);
		ptp->refclk_regs[1] = le32_to_cpu(resp->ts_ref_clock_reg_upper);
	} else if (bp->flags & BNXT_FLAG_CHIP_P5) {
		ptp->refclk_regs[0] = BNXT_TS_REG_TIMESYNC_TS0_LOWER;
		ptp->refclk_regs[1] = BNXT_TS_REG_TIMESYNC_TS0_UPPER;
	} else {
		rc = -ENODEV;
		goto no_ptp;
	}
	return 0;

no_ptp:
	kfree(ptp);
	bp->ptp_cfg = NULL;
	return rc;
}

static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
{
	int rc = 0;
@@ -7462,6 +7515,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
		bp->flags &= ~BNXT_FLAG_WOL_CAP;
		if (flags & FUNC_QCAPS_RESP_FLAGS_WOL_MAGICPKT_SUPPORTED)
			bp->flags |= BNXT_FLAG_WOL_CAP;
		if (flags & FUNC_QCAPS_RESP_FLAGS_PTP_SUPPORTED)
			__bnxt_hwrm_ptp_qcfg(bp);
	} else {
#ifdef CONFIG_BNXT_SRIOV
		struct bnxt_vf_info *vf = &bp->vf;
@@ -12571,6 +12626,8 @@ static void bnxt_remove_one(struct pci_dev *pdev)
	bnxt_dcb_free(bp);
	kfree(bp->edev);
	bp->edev = NULL;
	kfree(bp->ptp_cfg);
	bp->ptp_cfg = NULL;
	kfree(bp->fw_health);
	bp->fw_health = NULL;
	bnxt_cleanup_pci(bp);
@@ -13161,6 +13218,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	bnxt_free_hwrm_short_cmd_req(bp);
	bnxt_free_hwrm_resources(bp);
	bnxt_ethtool_free(bp);
	kfree(bp->ptp_cfg);
	bp->ptp_cfg = NULL;
	kfree(bp->fw_health);
	bp->fw_health = NULL;
	bnxt_cleanup_pci(bp);
+5 −0
Original line number Diff line number Diff line
@@ -1362,6 +1362,9 @@ struct bnxt_test_info {
#define BNXT_GRC_REG_CHIP_NUM			0x48
#define BNXT_GRC_REG_BASE			0x260000

#define BNXT_TS_REG_TIMESYNC_TS0_LOWER		0x640180c
#define BNXT_TS_REG_TIMESYNC_TS0_UPPER		0x6401810

#define BNXT_GRC_BASE_MASK			0xfffff000
#define BNXT_GRC_OFFSET_MASK			0x00000ffc

@@ -2042,6 +2045,8 @@ struct bnxt {

	struct bpf_prog		*xdp_prog;

	struct bnxt_ptp_cfg	*ptp_cfg;

	/* devlink interface and vf-rep structs */
	struct devlink		*dl;
	struct devlink_port	dl_port;
+49 −0
Original line number Diff line number Diff line
/* Broadcom NetXtreme-C/E network driver.
 *
 * Copyright (c) 2021 Broadcom Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 */

#ifndef BNXT_PTP_H
#define BNXT_PTP_H

struct bnxt_ptp_cfg {
	struct ptp_clock_info	ptp_info;
	struct ptp_clock	*ptp_clock;
	struct cyclecounter	cc;
	struct timecounter	tc;
	/* serialize timecounter access */
	spinlock_t		ptp_lock;
	struct sk_buff		*tx_skb;
	u64			current_time;
	u64			old_time;
	unsigned long		next_period;
	u16			tx_seqid;
	struct bnxt		*bp;
	atomic_t		tx_avail;
#define BNXT_MAX_TX_TS	1
	u16			rxctl;
#define BNXT_PTP_MSG_SYNC			(1 << 0)
#define BNXT_PTP_MSG_DELAY_REQ			(1 << 1)
#define BNXT_PTP_MSG_PDELAY_REQ			(1 << 2)
#define BNXT_PTP_MSG_PDELAY_RESP		(1 << 3)
#define BNXT_PTP_MSG_FOLLOW_UP			(1 << 8)
#define BNXT_PTP_MSG_DELAY_RESP			(1 << 9)
#define BNXT_PTP_MSG_PDELAY_RESP_FOLLOW_UP	(1 << 10)
#define BNXT_PTP_MSG_ANNOUNCE			(1 << 11)
#define BNXT_PTP_MSG_SIGNALING			(1 << 12)
#define BNXT_PTP_MSG_MANAGEMENT			(1 << 13)
#define BNXT_PTP_MSG_EVENTS		(BNXT_PTP_MSG_SYNC |		\
					 BNXT_PTP_MSG_DELAY_REQ |	\
					 BNXT_PTP_MSG_PDELAY_REQ |	\
					 BNXT_PTP_MSG_PDELAY_RESP)
	u8			tx_tstamp_en:1;
	int			rx_filter;

	u32			refclk_regs[2];
	u32			refclk_mapped_regs[2];
};
#endif