Commit 7cab44f1 authored by Sergey Temerkhanov's avatar Sergey Temerkhanov Committed by Jakub Kicinski
Browse files

ice: Introduce ETH56G PHY model for E825C products



E825C products feature a new PHY model - ETH56G.

Introduces all necessary PHY definitions, functions etc. for ETH56G PHY,
analogous to E82X and E810 ones with addition of a few HW-specific
functionalities for ETH56G like one-step timestamping.

It ensures correct PTP initialization and operation for E825C products.

Co-developed-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Co-developed-by: default avatarMichal Michalik <michal.michalik@intel.com>
Signed-off-by: default avatarMichal Michalik <michal.michalik@intel.com>
Signed-off-by: default avatarSergey Temerkhanov <sergey.temerkhanov@intel.com>
Reviewed-by: default avatarPrzemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: default avatarArkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Co-developed-by: default avatarKarol Kolacinski <karol.kolacinski@intel.com>
Signed-off-by: default avatarKarol Kolacinski <karol.kolacinski@intel.com>
Tested-by: default avatarPucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Link: https://lore.kernel.org/r/20240528-next-2024-05-28-ptp-refactors-v1-7-c082739bb6f6@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 1f374d57
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -3067,11 +3067,13 @@ bool ice_is_100m_speed_supported(struct ice_hw *hw)
 * Note: In the structure of [phy_type_low, phy_type_high], there should
 * be one bit set, as this function will convert one PHY type to its
 * speed.
 * If no bit gets set, ICE_AQ_LINK_SPEED_UNKNOWN will be returned
 * If more than one bit gets set, ICE_AQ_LINK_SPEED_UNKNOWN will be returned
 *
 * Return:
 * * PHY speed for recognized PHY type
 * * If no bit gets set, ICE_AQ_LINK_SPEED_UNKNOWN will be returned
 * * If more than one bit gets set, ICE_AQ_LINK_SPEED_UNKNOWN will be returned
 */
static u16
ice_get_link_speed_based_on_phy_type(u64 phy_type_low, u64 phy_type_high)
u16 ice_get_link_speed_based_on_phy_type(u64 phy_type_low, u64 phy_type_high)
{
	u16 speed_phy_type_high = ICE_AQ_LINK_SPEED_UNKNOWN;
	u16 speed_phy_type_low = ICE_AQ_LINK_SPEED_UNKNOWN;
+1 −0
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ int
ice_aq_get_gpio(struct ice_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx,
		bool *value, struct ice_sq_cd *cd);
bool ice_is_100m_speed_supported(struct ice_hw *hw);
u16 ice_get_link_speed_based_on_phy_type(u64 phy_type_low, u64 phy_type_high);
int
ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
		    struct ice_sq_cd *cd);
+82 −19
Original line number Diff line number Diff line
@@ -1011,6 +1011,28 @@ ice_ptp_release_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
	tx->len = 0;
}

/**
 * ice_ptp_init_tx_eth56g - Initialize tracking for Tx timestamps
 * @pf: Board private structure
 * @tx: the Tx tracking structure to initialize
 * @port: the port this structure tracks
 *
 * Initialize the Tx timestamp tracker for this port. ETH56G PHYs
 * have independent memory blocks for all ports.
 *
 * Return: 0 for success, -ENOMEM when failed to allocate Tx tracker
 */
static int ice_ptp_init_tx_eth56g(struct ice_pf *pf, struct ice_ptp_tx *tx,
				  u8 port)
{
	tx->block = port;
	tx->offset = 0;
	tx->len = INDEX_PER_PORT_ETH56G;
	tx->has_ready_bitmap = 1;

	return ice_ptp_alloc_tx_tracker(tx);
}

/**
 * ice_ptp_init_tx_e82x - Initialize tracking for Tx timestamps
 * @pf: Board private structure
@@ -1341,10 +1363,19 @@ ice_ptp_port_phy_stop(struct ice_ptp_port *ptp_port)

	mutex_lock(&ptp_port->ps_lock);

	switch (hw->ptp.phy_model) {
	case ICE_PHY_ETH56G:
		err = ice_stop_phy_timer_eth56g(hw, port, true);
		break;
	case ICE_PHY_E82X:
		kthread_cancel_delayed_work_sync(&ptp_port->ov_work);

		err = ice_stop_phy_timer_e82x(hw, port, true);
	if (err)
		break;
	default:
		err = -ENODEV;
	}
	if (err && err != -EBUSY)
		dev_err(ice_pf_to_dev(pf), "PTP failed to set PHY port %d down, err %d\n",
			port, err);

@@ -1378,9 +1409,17 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)

	mutex_lock(&ptp_port->ps_lock);

	switch (hw->ptp.phy_model) {
	case ICE_PHY_ETH56G:
		err = ice_start_phy_timer_eth56g(hw, port);
		break;
	case ICE_PHY_E82X:
		/* Start the PHY timer in Vernier mode */
		kthread_cancel_delayed_work_sync(&ptp_port->ov_work);

	/* temporarily disable Tx timestamps while calibrating PHY offset */
		/* temporarily disable Tx timestamps while calibrating
		 * PHY offset
		 */
		spin_lock_irqsave(&ptp_port->tx.lock, flags);
		ptp_port->tx.calibrating = true;
		spin_unlock_irqrestore(&ptp_port->tx.lock, flags);
@@ -1389,16 +1428,20 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
		/* Start the PHY timer in Vernier mode */
		err = ice_start_phy_timer_e82x(hw, port);
		if (err)
		goto out_unlock;
			break;

		/* Enable Tx timestamps right away */
		spin_lock_irqsave(&ptp_port->tx.lock, flags);
		ptp_port->tx.calibrating = false;
		spin_unlock_irqrestore(&ptp_port->tx.lock, flags);

	kthread_queue_delayed_work(pf->ptp.kworker, &ptp_port->ov_work, 0);
		kthread_queue_delayed_work(pf->ptp.kworker, &ptp_port->ov_work,
					   0);
		break;
	default:
		err = -ENODEV;
	}

out_unlock:
	if (err)
		dev_err(ice_pf_to_dev(pf), "PTP failed to set PHY port %d up, err %d\n",
			port, err);
@@ -1436,6 +1479,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
	case ICE_PHY_E810:
		/* Do not reconfigure E810 PHY */
		return;
	case ICE_PHY_ETH56G:
	case ICE_PHY_E82X:
		ice_ptp_port_phy_restart(ptp_port);
		return;
@@ -1465,6 +1509,22 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold)
	ice_ptp_reset_ts_memory(hw);

	switch (hw->ptp.phy_model) {
	case ICE_PHY_ETH56G: {
		int port;

		for (port = 0; port < hw->ptp.num_lports; port++) {
			int err;

			err = ice_phy_cfg_intr_eth56g(hw, port, ena, threshold);
			if (err) {
				dev_err(dev, "Failed to configure PHY interrupt for port %d, err %d\n",
					port, err);
				return err;
			}
		}

		return 0;
	}
	case ICE_PHY_E82X: {
		int quad;

@@ -3075,6 +3135,9 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
	mutex_init(&ptp_port->ps_lock);

	switch (hw->ptp.phy_model) {
	case ICE_PHY_ETH56G:
		return ice_ptp_init_tx_eth56g(pf, &ptp_port->tx,
					      ptp_port->port_num);
	case ICE_PHY_E810:
		return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
	case ICE_PHY_E82X:
+1 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ struct ice_ptp_tx {
#define INDEX_PER_QUAD			64
#define INDEX_PER_PORT_E82X		16
#define INDEX_PER_PORT_E810		64
#define INDEX_PER_PORT_ETH56G		64

/**
 * struct ice_ptp_port - data used to initialize an external port for PTP
+315 −0
Original line number Diff line number Diff line
@@ -9,6 +9,321 @@
 */
/* Constants defined for the PTP 1588 clock hardware. */

const struct ice_phy_reg_info_eth56g eth56g_phy_res[NUM_ETH56G_PHY_RES] = {
	/* ETH56G_PHY_REG_PTP */
	{
		/* base_addr */
		{
			0x092000,
			0x126000,
			0x1BA000,
			0x24E000,
			0x2E2000,
		},
		/* step */
		0x98,
	},
	/* ETH56G_PHY_MEM_PTP */
	{
		/* base_addr */
		{
			0x093000,
			0x127000,
			0x1BB000,
			0x24F000,
			0x2E3000,
		},
		/* step */
		0x200,
	},
	/* ETH56G_PHY_REG_XPCS */
	{
		/* base_addr */
		{
			0x000000,
			0x009400,
			0x128000,
			0x1BC000,
			0x250000,
		},
		/* step */
		0x21000,
	},
	/* ETH56G_PHY_REG_MAC */
	{
		/* base_addr */
		{
			0x085000,
			0x119000,
			0x1AD000,
			0x241000,
			0x2D5000,
		},
		/* step */
		0x1000,
	},
	/* ETH56G_PHY_REG_GPCS */
	{
		/* base_addr */
		{
			0x084000,
			0x118000,
			0x1AC000,
			0x240000,
			0x2D4000,
		},
		/* step */
		0x400,
	},
};

const
struct ice_eth56g_mac_reg_cfg eth56g_mac_cfg[NUM_ICE_ETH56G_LNK_SPD] = {
	[ICE_ETH56G_LNK_SPD_1G] = {
		.tx_mode = { .def = 6, },
		.rx_mode = { .def = 6, },
		.blks_per_clk = 1,
		.blktime = 0x4000, /* 32 */
		.tx_offset = {
			.serdes = 0x6666, /* 51.2 */
			.no_fec = 0xd066, /* 104.2 */
			.sfd = 0x3000, /* 24 */
			.onestep = 0x30000 /* 384 */
		},
		.rx_offset = {
			.serdes = 0xffffc59a, /* -29.2 */
			.no_fec = 0xffff0a80, /* -122.75 */
			.sfd = 0x2c00, /* 22 */
			.bs_ds = 0x19a /* 0.8 */
			/* Dynamic bitslip 0 equals to 10 */
		}
	},
	[ICE_ETH56G_LNK_SPD_2_5G] = {
		.tx_mode = { .def = 6, },
		.rx_mode = { .def = 6, },
		.blks_per_clk = 1,
		.blktime = 0x199a, /* 12.8 */
		.tx_offset = {
			.serdes = 0x28f6, /* 20.48 */
			.no_fec = 0x53b8, /* 41.86 */
			.sfd = 0x1333, /* 9.6 */
			.onestep = 0x13333 /* 153.6 */
		},
		.rx_offset = {
			.serdes = 0xffffe8a4, /* -11.68 */
			.no_fec = 0xffff9a76, /* -50.77 */
			.sfd = 0xf33, /* 7.6 */
			.bs_ds = 0xa4 /* 0.32 */
		}
	},
	[ICE_ETH56G_LNK_SPD_10G] = {
		.tx_mode = { .def = 1, },
		.rx_mode = { .def = 1, },
		.blks_per_clk = 1,
		.blktime = 0x666, /* 3.2 */
		.tx_offset = {
			.serdes = 0x234c, /* 17.6484848 */
			.no_fec = 0x8e80, /* 71.25 */
			.fc = 0xb4a4, /* 90.32 */
			.sfd = 0x4a4, /* 2.32 */
			.onestep = 0x4ccd /* 38.4 */
		},
		.rx_offset = {
			.serdes = 0xffffeb27, /* -10.42424 */
			.no_fec = 0xffffcccd, /* -25.6 */
			.fc = 0xfffe0014, /* -255.96 */
			.sfd = 0x4a4, /* 2.32 */
			.bs_ds = 0x32 /* 0.0969697 */
		}
	},
	[ICE_ETH56G_LNK_SPD_25G] = {
		.tx_mode = {
			.def = 1,
			.rs = 4
		},
		.tx_mk_dly = 4,
		.tx_cw_dly = {
			.def = 1,
			.onestep = 6
		},
		.rx_mode = {
			.def = 1,
			.rs = 4
		},
		.rx_mk_dly = {
			.def = 1,
			.rs = 1
		},
		.rx_cw_dly = {
			.def = 1,
			.rs = 1
		},
		.blks_per_clk = 1,
		.blktime = 0x28f, /* 1.28 */
		.mktime = 0x147b, /* 10.24, only if RS-FEC enabled */
		.tx_offset = {
			.serdes = 0xe1e, /* 7.0593939 */
			.no_fec = 0x3857, /* 28.17 */
			.fc = 0x48c3, /* 36.38 */
			.rs = 0x8100, /* 64.5 */
			.sfd = 0x1dc, /* 0.93 */
			.onestep = 0x1eb8 /* 15.36 */
		},
		.rx_offset = {
			.serdes = 0xfffff7a9, /* -4.1697 */
			.no_fec = 0xffffe71a, /* -12.45 */
			.fc = 0xfffe894d, /* -187.35 */
			.rs = 0xfffff8cd, /* -3.6 */
			.sfd = 0x1dc, /* 0.93 */
			.bs_ds = 0x14 /* 0.0387879, RS-FEC 0 */
		}
	},
	[ICE_ETH56G_LNK_SPD_40G] = {
		.tx_mode = { .def = 3 },
		.tx_mk_dly = 4,
		.tx_cw_dly = {
			.def = 1,
			.onestep = 6
		},
		.rx_mode = { .def = 4 },
		.rx_mk_dly = { .def = 1 },
		.rx_cw_dly = { .def = 1 },
		.blktime = 0x333, /* 1.6 */
		.mktime = 0xccd, /* 6.4 */
		.tx_offset = {
			.serdes = 0x234c, /* 17.6484848 */
			.no_fec = 0x5a8a, /* 45.27 */
			.fc = 0x81b8, /* 64.86 */
			.sfd = 0x4a4, /* 2.32 */
			.onestep = 0x1333 /* 9.6 */
		},
		.rx_offset = {
			.serdes = 0xffffeb27, /* -10.42424 */
			.no_fec = 0xfffff594, /* -5.21 */
			.fc = 0xfffe3080, /* -231.75 */
			.sfd = 0x4a4, /* 2.32 */
			.bs_ds = 0xccd /* 6.4 */
		}
	},
	[ICE_ETH56G_LNK_SPD_50G] = {
		.tx_mode = { .def = 5 },
		.tx_mk_dly = 4,
		.tx_cw_dly = {
			.def = 1,
			.onestep = 6
		},
		.rx_mode = { .def = 5 },
		.rx_mk_dly = { .def = 1 },
		.rx_cw_dly = { .def = 1 },
		.blktime = 0x28f, /* 1.28 */
		.mktime = 0xa3d, /* 5.12 */
		.tx_offset = {
			.serdes = 0x13ba, /* 9.86353 */
			.rs = 0x5400, /* 42 */
			.sfd = 0xe6, /* 0.45 */
			.onestep = 0xf5c /* 7.68 */
		},
		.rx_offset = {
			.serdes = 0xfffff7e8, /* -4.04706 */
			.rs = 0xfffff994, /* -3.21 */
			.sfd = 0xe6 /* 0.45 */
		}
	},
	[ICE_ETH56G_LNK_SPD_50G2] = {
		.tx_mode = {
			.def = 3,
			.rs = 2
		},
		.tx_mk_dly = 4,
		.tx_cw_dly = {
			.def = 1,
			.onestep = 6
		},
		.rx_mode = {
			.def = 4,
			.rs = 1
		},
		.rx_mk_dly = { .def = 1 },
		.rx_cw_dly = { .def = 1 },
		.blktime = 0x28f, /* 1.28 */
		.mktime = 0xa3d, /* 5.12 */
		.tx_offset = {
			.serdes = 0xe1e, /* 7.0593939 */
			.no_fec = 0x3d33, /* 30.6 */
			.rs = 0x5057, /* 40.17 */
			.sfd = 0x1dc, /* 0.93 */
			.onestep = 0xf5c /* 7.68 */
		},
		.rx_offset = {
			.serdes = 0xfffff7a9, /* -4.1697 */
			.no_fec = 0xfffff8cd, /* -3.6 */
			.rs = 0xfffff21a, /* -6.95 */
			.sfd = 0x1dc, /* 0.93 */
			.bs_ds = 0xa3d /* 5.12, RS-FEC 0x633 (3.1) */
		}
	},
	[ICE_ETH56G_LNK_SPD_100G] = {
		.tx_mode = {
			.def = 3,
			.rs = 2
		},
		.tx_mk_dly = 10,
		.tx_cw_dly = {
			.def = 3,
			.onestep = 6
		},
		.rx_mode = {
			.def = 4,
			.rs = 1
		},
		.rx_mk_dly = { .def = 5 },
		.rx_cw_dly = { .def = 5 },
		.blks_per_clk = 1,
		.blktime = 0x148, /* 0.64 */
		.mktime = 0x199a, /* 12.8 */
		.tx_offset = {
			.serdes = 0xe1e, /* 7.0593939 */
			.no_fec = 0x67ec, /* 51.96 */
			.rs = 0x44fb, /* 34.49 */
			.sfd = 0x1dc, /* 0.93 */
			.onestep = 0xf5c /* 7.68 */
		},
		.rx_offset = {
			.serdes = 0xfffff7a9, /* -4.1697 */
			.no_fec = 0xfffff5a9, /* -5.17 */
			.rs = 0xfffff6e6, /* -4.55 */
			.sfd = 0x1dc, /* 0.93 */
			.bs_ds = 0x199a /* 12.8, RS-FEC 0x31b (1.552) */
		}
	},
	[ICE_ETH56G_LNK_SPD_100G2] = {
		.tx_mode = { .def = 5 },
		.tx_mk_dly = 10,
		.tx_cw_dly = {
			.def = 3,
			.onestep = 6
		},
		.rx_mode = { .def = 5 },
		.rx_mk_dly = { .def = 5 },
		.rx_cw_dly = { .def = 5 },
		.blks_per_clk = 1,
		.blktime = 0x148, /* 0.64 */
		.mktime = 0x199a, /* 12.8 */
		.tx_offset = {
			.serdes = 0x13ba, /* 9.86353 */
			.rs = 0x460a, /* 35.02 */
			.sfd = 0xe6, /* 0.45 */
			.onestep = 0xf5c /* 7.68 */
		},
		.rx_offset = {
			.serdes = 0xfffff7e8, /* -4.04706 */
			.rs = 0xfffff548, /* -5.36 */
			.sfd = 0xe6, /* 0.45 */
			.bs_ds = 0x303 /* 1.506 */
		}
	}
};

/* struct ice_time_ref_info_e82x
 *
 * E822 hardware can use different sources as the reference for the PTP
Loading