drivers/net/ethernet/intel/ice/ice_ptp_hw.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ice/ice_ptp_hw.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ice/ice_ptp_hw.c
Extension
.c
Size
173820 bytes
Lines
6271
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 (err) {
			ice_debug(hw, ICE_DBG_PTP, "Failed to soft reset port %d, err %d\n",
				  port, err);
			return err;
		}
	}

	return 0;
}

/**
 * ice_ptp_get_dest_dev_e825 - get destination PHY for given port number
 * @hw: pointer to the HW struct
 * @port: destination port
 *
 * Return: destination sideband queue PHY device.
 */
static enum ice_sbq_dev_id ice_ptp_get_dest_dev_e825(struct ice_hw *hw,
						     u8 port)
{
	u8 curr_phy, tgt_phy;

	tgt_phy = port >= hw->ptp.ports_per_phy;
	curr_phy = hw->lane_num >= hw->ptp.ports_per_phy;
	/* In the driver, lanes 4..7 are in fact 0..3 on a second PHY.
	 * On a single complex E825C, PHY 0 is always destination device phy_0
	 * and PHY 1 is phy_0_peer.
	 * On dual complex E825C, device phy_0 points to PHY on a current
	 * complex and phy_0_peer to PHY on a different complex.
	 */
	if ((!ice_is_dual(hw) && tgt_phy == 1) ||
	    (ice_is_dual(hw) && tgt_phy != curr_phy))
		return ice_sbq_dev_phy_0_peer;
	else
		return ice_sbq_dev_phy_0;
}

/**
 * ice_write_phy_eth56g - Write a PHY port register
 * @hw: pointer to the HW struct
 * @port: destination port
 * @addr: PHY register address
 * @val: Value to write
 *
 * Return: 0 on success, other error codes when failed to write to PHY
 */
static int ice_write_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 val)
{
	struct ice_sbq_msg_input msg = {
		.dest_dev = ice_ptp_get_dest_dev_e825(hw, port),
		.opcode = ice_sbq_msg_wr,
		.msg_addr_low = lower_16_bits(addr),
		.msg_addr_high = upper_16_bits(addr),
		.data = val
	};
	int err;

	err = ice_sbq_rw_reg(hw, &msg, LIBIE_AQ_FLAG_RD);
	if (err)
		ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
			  err);

	return err;
}

/**
 * ice_read_phy_eth56g - Read a PHY port register
 * @hw: pointer to the HW struct
 * @port: destination port
 * @addr: PHY register address
 * @val: Value to write
 *
 * Return: 0 on success, other error codes when failed to read from PHY
 */
static int ice_read_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 *val)
{
	struct ice_sbq_msg_input msg = {
		.dest_dev = ice_ptp_get_dest_dev_e825(hw, port),
		.opcode = ice_sbq_msg_rd,
		.msg_addr_low = lower_16_bits(addr),
		.msg_addr_high = upper_16_bits(addr)
	};
	int err;

	err = ice_sbq_rw_reg(hw, &msg, LIBIE_AQ_FLAG_RD);
	if (err)
		ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
			  err);
	else
		*val = msg.data;

Annotation

Implementation Notes