bnxt_en: Get PTP hardware capability from firmware
authorMichael Chan <michael.chan@broadcom.com>
Sun, 27 Jun 2021 17:19:45 +0000 (13:19 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Jun 2021 20:41:05 +0000 (13:41 -0700)
Store PTP hardware info in a structure if hardware and firmware support PTP.

Reviewed-by: Edwin Peer <edwin.peer@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h [new file with mode: 0644]

index aef3fccc27a97517378f1e2a0eb2c7ee1e335dd8..081cdcb02b48f3b00870d3bbd08550db3a29349b 100644 (file)
@@ -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 @@ hwrm_func_resc_qcaps_exit:
        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 @@ init_err_pci_clean:
        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);
index 30e47ea343f916759e877161639962cc40af6546..696163559b64f0f292cd6b4590bce1d8cbcfb94c 100644 (file)
@@ -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;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
new file mode 100644 (file)
index 0000000..603f0fd
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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