|
49 | 49 | #include <linux/log2.h> |
50 | 50 | #include <linux/aer.h> |
51 | 51 | #include <linux/bitmap.h> |
| 52 | +#include <linux/ptp_clock_kernel.h> |
| 53 | +#include <linux/timecounter.h> |
52 | 54 | #include <linux/cpu_rmap.h> |
53 | 55 | #include <linux/cpumask.h> |
54 | 56 | #include <net/pkt_cls.h> |
|
63 | 65 | #include "bnxt_ethtool.h" |
64 | 66 | #include "bnxt_dcb.h" |
65 | 67 | #include "bnxt_xdp.h" |
| 68 | +#include "bnxt_ptp.h" |
66 | 69 | #include "bnxt_vfr.h" |
67 | 70 | #include "bnxt_tc.h" |
68 | 71 | #include "bnxt_devlink.h" |
@@ -7391,6 +7394,56 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp, bool all) |
7391 | 7394 | return rc; |
7392 | 7395 | } |
7393 | 7396 |
|
| 7397 | +/* bp->hwrm_cmd_lock already held. */ |
| 7398 | +static int __bnxt_hwrm_ptp_qcfg(struct bnxt *bp) |
| 7399 | +{ |
| 7400 | + struct hwrm_port_mac_ptp_qcfg_output *resp = bp->hwrm_cmd_resp_addr; |
| 7401 | + struct hwrm_port_mac_ptp_qcfg_input req = {0}; |
| 7402 | + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 7403 | + u8 flags; |
| 7404 | + int rc; |
| 7405 | + |
| 7406 | + if (bp->hwrm_spec_code < 0x10801) { |
| 7407 | + rc = -ENODEV; |
| 7408 | + goto no_ptp; |
| 7409 | + } |
| 7410 | + |
| 7411 | + req.port_id = cpu_to_le16(bp->pf.port_id); |
| 7412 | + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_MAC_PTP_QCFG, -1, -1); |
| 7413 | + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 7414 | + if (rc) |
| 7415 | + goto no_ptp; |
| 7416 | + |
| 7417 | + flags = resp->flags; |
| 7418 | + if (!(flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_HWRM_ACCESS)) { |
| 7419 | + rc = -ENODEV; |
| 7420 | + goto no_ptp; |
| 7421 | + } |
| 7422 | + if (!ptp) { |
| 7423 | + ptp = kzalloc(sizeof(*ptp), GFP_KERNEL); |
| 7424 | + if (!ptp) |
| 7425 | + return -ENOMEM; |
| 7426 | + ptp->bp = bp; |
| 7427 | + bp->ptp_cfg = ptp; |
| 7428 | + } |
| 7429 | + if (flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_PARTIAL_DIRECT_ACCESS_REF_CLOCK) { |
| 7430 | + ptp->refclk_regs[0] = le32_to_cpu(resp->ts_ref_clock_reg_lower); |
| 7431 | + ptp->refclk_regs[1] = le32_to_cpu(resp->ts_ref_clock_reg_upper); |
| 7432 | + } else if (bp->flags & BNXT_FLAG_CHIP_P5) { |
| 7433 | + ptp->refclk_regs[0] = BNXT_TS_REG_TIMESYNC_TS0_LOWER; |
| 7434 | + ptp->refclk_regs[1] = BNXT_TS_REG_TIMESYNC_TS0_UPPER; |
| 7435 | + } else { |
| 7436 | + rc = -ENODEV; |
| 7437 | + goto no_ptp; |
| 7438 | + } |
| 7439 | + return 0; |
| 7440 | + |
| 7441 | +no_ptp: |
| 7442 | + kfree(ptp); |
| 7443 | + bp->ptp_cfg = NULL; |
| 7444 | + return rc; |
| 7445 | +} |
| 7446 | + |
7394 | 7447 | static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) |
7395 | 7448 | { |
7396 | 7449 | int rc = 0; |
@@ -7462,6 +7515,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) |
7462 | 7515 | bp->flags &= ~BNXT_FLAG_WOL_CAP; |
7463 | 7516 | if (flags & FUNC_QCAPS_RESP_FLAGS_WOL_MAGICPKT_SUPPORTED) |
7464 | 7517 | bp->flags |= BNXT_FLAG_WOL_CAP; |
| 7518 | + if (flags & FUNC_QCAPS_RESP_FLAGS_PTP_SUPPORTED) |
| 7519 | + __bnxt_hwrm_ptp_qcfg(bp); |
7465 | 7520 | } else { |
7466 | 7521 | #ifdef CONFIG_BNXT_SRIOV |
7467 | 7522 | struct bnxt_vf_info *vf = &bp->vf; |
@@ -12571,6 +12626,8 @@ static void bnxt_remove_one(struct pci_dev *pdev) |
12571 | 12626 | bnxt_dcb_free(bp); |
12572 | 12627 | kfree(bp->edev); |
12573 | 12628 | bp->edev = NULL; |
| 12629 | + kfree(bp->ptp_cfg); |
| 12630 | + bp->ptp_cfg = NULL; |
12574 | 12631 | kfree(bp->fw_health); |
12575 | 12632 | bp->fw_health = NULL; |
12576 | 12633 | bnxt_cleanup_pci(bp); |
@@ -13161,6 +13218,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
13161 | 13218 | bnxt_free_hwrm_short_cmd_req(bp); |
13162 | 13219 | bnxt_free_hwrm_resources(bp); |
13163 | 13220 | bnxt_ethtool_free(bp); |
| 13221 | + kfree(bp->ptp_cfg); |
| 13222 | + bp->ptp_cfg = NULL; |
13164 | 13223 | kfree(bp->fw_health); |
13165 | 13224 | bp->fw_health = NULL; |
13166 | 13225 | bnxt_cleanup_pci(bp); |
|
0 commit comments