drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
Extension
.c
Size
30040 bytes
Lines
1171
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (pps->pins[pin].state) {
			rc = bnxt_ptp_cfg_pin(bp, pin, pps->pins[pin].usage);
			if (!rc && pps->pins[pin].event)
				rc = bnxt_ptp_cfg_event(bp,
							pps->pins[pin].event);
			if (rc)
				netdev_err(bp->dev, "1PPS: Failed to configure pin%d\n",
					   pin);
		}
	}
}

static int bnxt_ptp_perout_cfg(struct bnxt_ptp_cfg *ptp,
			       struct ptp_clock_request *rq)
{
	struct hwrm_func_ptp_cfg_input *req;
	struct bnxt *bp = ptp->bp;
	struct timespec64 ts;
	u64 target_ns;
	u16 enables;
	int rc;

	ts.tv_sec = rq->perout.start.sec;
	ts.tv_nsec = rq->perout.start.nsec;
	target_ns = timespec64_to_ns(&ts);

	rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_CFG);
	if (rc)
		return rc;

	enables = FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PERIOD |
		  FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_UP |
		  FUNC_PTP_CFG_REQ_ENABLES_PTP_FREQ_ADJ_EXT_PHASE;
	req->enables = cpu_to_le16(enables);
	req->ptp_pps_event = 0;
	req->ptp_freq_adj_dll_source = 0;
	req->ptp_freq_adj_dll_phase = 0;
	req->ptp_freq_adj_ext_period = cpu_to_le32(NSEC_PER_SEC);
	req->ptp_freq_adj_ext_up = 0;
	req->ptp_freq_adj_ext_phase_lower =
		cpu_to_le32(lower_32_bits(target_ns));
	req->ptp_freq_adj_ext_phase_upper =
		cpu_to_le32(upper_32_bits(target_ns));

	return hwrm_req_send(bp, req);
}

static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info,
			   struct ptp_clock_request *rq, int on)
{
	struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
						ptp_info);
	struct bnxt *bp = ptp->bp;
	int pin_id;
	int rc;

	switch (rq->type) {
	case PTP_CLK_REQ_EXTTS:
		/* Configure an External PPS IN */
		pin_id = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS,
				      rq->extts.index);
		if (!TSIO_PIN_VALID(pin_id))
			return -EOPNOTSUPP;
		if (!on)
			break;
		rc = bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_PPS_IN);
		if (rc)
			return rc;
		rc = bnxt_ptp_cfg_event(bp, BNXT_PPS_EVENT_EXTERNAL);
		if (!rc)
			ptp->pps_info.pins[pin_id].event = BNXT_PPS_EVENT_EXTERNAL;
		return rc;
	case PTP_CLK_REQ_PEROUT:
		/* Configure a Periodic PPS OUT */
		pin_id = ptp_find_pin(ptp->ptp_clock, PTP_PF_PEROUT,
				      rq->perout.index);
		if (!TSIO_PIN_VALID(pin_id))
			return -EOPNOTSUPP;
		if (!on)
			break;

		rc = bnxt_ptp_cfg_pin(bp, pin_id, BNXT_PPS_PIN_PPS_OUT);
		if (!rc)
			rc = bnxt_ptp_perout_cfg(ptp, rq);

		return rc;
	case PTP_CLK_REQ_PPS:
		/* Configure PHC PPS IN */
		rc = bnxt_ptp_cfg_pin(bp, 0, BNXT_PPS_PIN_PPS_IN);
		if (rc)

Annotation

Implementation Notes