Commit 2030eddc authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
100GbE Intel Wired LAN Driver Updates 2021-12-21

This series contains updates to ice driver only.

Karol modifies the reset flow to correct issues with PTP reset.

Jake extends PTP support for E822 based devices. This includes a few
cleanup patches, that fix some minor issues. In addition, there are some
slight refactors to ease the addition of E822 support, followed by adding
the new hardware implementation ice_ptp_hw.c.

There are a few major differences with E822 support compared to E810
support:

*) The E822 device has a Clock Generation Unit which must be initialized in
order to generate proper clock frequencies on the output that drives the PTP
hardware clock registers

*) The E822 PHY is a bit different and requires a more complex
initialization procedure which must be rerun any time the link configuration
changes.

*) The E822 devices support enhanced timestamp calibration by making use of
a process called Vernier offset measurement. This allows the hardware to
measure phase offset related to the PHY clocks for Serdes and FEC, reducing
the inaccuracy of the timestamp relative to the actual packet transmission
and receipt. Making use of this requires data gathered from the first
transmitted and received packets, and waiting for the PHY to complete the
calibration measurements. This is done as part of a new kthread, ov_work.
Note that to avoid delay in enabling timestamps, we start the PHY in
'bypass' mode which allows timestamps to be captured without the Vernier
calibration measurement. Once the first packets have been sent and received,
we then complete the calibration setup and exit bypass mode and begin using
the more precise timestamps. According to the datasheet, timestamps without
calibration data can be incorrect relative to actual receipt or transmission
by up to 1 clock cycle (~1.25 nanoseconds), while calibrated timestamps
should be correct to within 1/8th of a clock cycle (~0.15 nanoseconds).

*) E822 devices support crosstimestamping via PCIe PTM, which we enable when
available on the platform.

There is a fair amount of logic required to perform PHY and CGU
initialization, which is the vast majority of the new code, but it is fairly
self contained within ice_ptp_hw.c, with the exception of monitoring for
offset validity being handled by a kthread.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: support crosstimestamping on E822 devices if supported
  ice: exit bypass mode once hardware finishes timestamp calibration
  ice: ensure the hardware Clock Generation Unit is configured
  ice: implement basic E822 PTP support
  ice: convert clk_freq capability into time_ref
  ice: introduce ice_ptp_init_phc function
  ice: use 'int err' instead of 'int status' in ice_ptp_hw.c
  ice: PTP: move setting of tstamp_config
  ice: introduce ice_base_incval function
  ice: Fix E810 PTP reset flow
====================

Link: https://lore.kernel.org/r/20211221174845.3063640-1-anthony.l.nguyen@intel.com


Acked-by: default avatarRichard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents f4f2970d 13a64f0b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -327,6 +327,16 @@ config ICE_SWITCHDEV

	  If unsure, say N.

config ICE_HWTS
	bool "Support HW cross-timestamp on platforms with PTM support"
	default y
	depends on ICE && X86
	help
	  Say Y to enable hardware supported cross-timestamping on platforms
	  with PCIe PTM support. The cross-timestamp is available through
	  the PTP clock driver precise cross-timestamp ioctl
	  (PTP_SYS_OFFSET_PRECISE).

config FM10K
	tristate "Intel(R) FM10000 Ethernet Switch Host Interface Support"
	default n
+116 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2018-2021, Intel Corporation. */

#ifndef _ICE_CGU_REGS_H_
#define _ICE_CGU_REGS_H_

#define NAC_CGU_DWORD9 0x24
union nac_cgu_dword9 {
	struct {
		u32 time_ref_freq_sel : 3;
		u32 clk_eref1_en : 1;
		u32 clk_eref0_en : 1;
		u32 time_ref_en : 1;
		u32 time_sync_en : 1;
		u32 one_pps_out_en : 1;
		u32 clk_ref_synce_en : 1;
		u32 clk_synce1_en : 1;
		u32 clk_synce0_en : 1;
		u32 net_clk_ref1_en : 1;
		u32 net_clk_ref0_en : 1;
		u32 clk_synce1_amp : 2;
		u32 misc6 : 1;
		u32 clk_synce0_amp : 2;
		u32 one_pps_out_amp : 2;
		u32 misc24 : 12;
	} field;
	u32 val;
};

#define NAC_CGU_DWORD19 0x4c
union nac_cgu_dword19 {
	struct {
		u32 tspll_fbdiv_intgr : 8;
		u32 fdpll_ulck_thr : 5;
		u32 misc15 : 3;
		u32 tspll_ndivratio : 4;
		u32 tspll_iref_ndivratio : 3;
		u32 misc19 : 1;
		u32 japll_ndivratio : 4;
		u32 japll_iref_ndivratio : 3;
		u32 misc27 : 1;
	} field;
	u32 val;
};

#define NAC_CGU_DWORD22 0x58
union nac_cgu_dword22 {
	struct {
		u32 fdpll_frac_div_out_nc : 2;
		u32 fdpll_lock_int_for : 1;
		u32 synce_hdov_int_for : 1;
		u32 synce_lock_int_for : 1;
		u32 fdpll_phlead_slip_nc : 1;
		u32 fdpll_acc1_ovfl_nc : 1;
		u32 fdpll_acc2_ovfl_nc : 1;
		u32 synce_status_nc : 6;
		u32 fdpll_acc1f_ovfl : 1;
		u32 misc18 : 1;
		u32 fdpllclk_div : 4;
		u32 time1588clk_div : 4;
		u32 synceclk_div : 4;
		u32 synceclk_sel_div2 : 1;
		u32 fdpllclk_sel_div2 : 1;
		u32 time1588clk_sel_div2 : 1;
		u32 misc3 : 1;
	} field;
	u32 val;
};

#define NAC_CGU_DWORD24 0x60
union nac_cgu_dword24 {
	struct {
		u32 tspll_fbdiv_frac : 22;
		u32 misc20 : 2;
		u32 ts_pll_enable : 1;
		u32 time_sync_tspll_align_sel : 1;
		u32 ext_synce_sel : 1;
		u32 ref1588_ck_div : 4;
		u32 time_ref_sel : 1;
	} field;
	u32 val;
};

#define TSPLL_CNTR_BIST_SETTINGS 0x344
union tspll_cntr_bist_settings {
	struct {
		u32 i_irefgen_settling_time_cntr_7_0 : 8;
		u32 i_irefgen_settling_time_ro_standby_1_0 : 2;
		u32 reserved195 : 5;
		u32 i_plllock_sel_0 : 1;
		u32 i_plllock_sel_1 : 1;
		u32 i_plllock_cnt_6_0 : 7;
		u32 i_plllock_cnt_10_7 : 4;
		u32 reserved200 : 4;
	} field;
	u32 val;
};

#define TSPLL_RO_BWM_LF 0x370
union tspll_ro_bwm_lf {
	struct {
		u32 bw_freqov_high_cri_7_0 : 8;
		u32 bw_freqov_high_cri_9_8 : 2;
		u32 biascaldone_cri : 1;
		u32 plllock_gain_tran_cri : 1;
		u32 plllock_true_lock_cri : 1;
		u32 pllunlock_flag_cri : 1;
		u32 afcerr_cri : 1;
		u32 afcdone_cri : 1;
		u32 feedfwrdgain_cal_cri_7_0 : 8;
		u32 m2fbdivmod_cri_7_0 : 8;
	} field;
	u32 val;
};

#endif /* _ICE_CGU_REGS_H_ */
+12 −0
Original line number Diff line number Diff line
@@ -2189,6 +2189,18 @@ ice_parse_1588_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
	info->clk_freq = (number & ICE_TS_CLK_FREQ_M) >> ICE_TS_CLK_FREQ_S;
	info->clk_src = ((number & ICE_TS_CLK_SRC_M) != 0);

	if (info->clk_freq < NUM_ICE_TIME_REF_FREQ) {
		info->time_ref = (enum ice_time_ref_freq)info->clk_freq;
	} else {
		/* Unknown clock frequency, so assume a (probably incorrect)
		 * default to avoid out-of-bounds look ups of frequency
		 * related information.
		 */
		ice_debug(hw, ICE_DBG_INIT, "1588 func caps: unknown clock frequency %u\n",
			  info->clk_freq);
		info->time_ref = ICE_TIME_REF_FREQ_25_000;
	}

	ice_debug(hw, ICE_DBG_INIT, "func caps: ieee_1588 = %u\n",
		  func_p->common_cap.ieee_1588);
	ice_debug(hw, ICE_DBG_INIT, "func caps: src_tmr_owned = %u\n",
+9 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@
#define PF_SB_ATQT				0x0022FE00
#define PF_SB_ATQT_ATQT_S			0
#define PF_SB_ATQT_ATQT_M			ICE_M(0x3FF, 0)
#define PF_SB_REM_DEV_CTL			0x002300F0
#define PRTDCB_GENC				0x00083000
#define PRTDCB_GENC_PFCLDA_S			16
#define PRTDCB_GENC_PFCLDA_M			ICE_M(0xFFFF, 16)
@@ -440,6 +441,10 @@
#define GLV_UPRCL(_i)				(0x003B2000 + ((_i) * 8))
#define GLV_UPTCL(_i)				(0x0030A000 + ((_i) * 8))
#define PRTRPB_RDPC				0x000AC260
#define GLHH_ART_CTL				0x000A41D4
#define GLHH_ART_CTL_ACTIVE_M			BIT(0)
#define GLHH_ART_TIME_H				0x000A41D8
#define GLHH_ART_TIME_L				0x000A41DC
#define GLTSYN_AUX_IN_0(_i)			(0x000889D8 + ((_i) * 4))
#define GLTSYN_AUX_IN_0_INT_ENA_M		BIT(4)
#define GLTSYN_AUX_OUT_0(_i)			(0x00088998 + ((_i) * 4))
@@ -452,6 +457,8 @@
#define GLTSYN_ENA_TSYN_ENA_M			BIT(0)
#define GLTSYN_EVNT_H_0(_i)			(0x00088970 + ((_i) * 4))
#define GLTSYN_EVNT_L_0(_i)			(0x00088968 + ((_i) * 4))
#define GLTSYN_HHTIME_H(_i)			(0x00088900 + ((_i) * 4))
#define GLTSYN_HHTIME_L(_i)			(0x000888F8 + ((_i) * 4))
#define GLTSYN_INCVAL_H(_i)			(0x00088920 + ((_i) * 4))
#define GLTSYN_INCVAL_L(_i)			(0x00088918 + ((_i) * 4))
#define GLTSYN_SHADJ_H(_i)			(0x00088910 + ((_i) * 4))
@@ -468,6 +475,8 @@
#define GLTSYN_TGT_L_0(_i)			(0x00088928 + ((_i) * 4))
#define GLTSYN_TIME_H(_i)			(0x000888D8 + ((_i) * 4))
#define GLTSYN_TIME_L(_i)			(0x000888D0 + ((_i) * 4))
#define PFHH_SEM				0x000A4200 /* Reset Source: PFR */
#define PFHH_SEM_BUSY_M				BIT(0)
#define PFTSYN_SEM				0x00088880
#define PFTSYN_SEM_BUSY_M			BIT(0)
#define VSIQF_FD_CNT(_VSI)			(0x00464000 + ((_VSI) * 4))
+13 −2
Original line number Diff line number Diff line
@@ -539,7 +539,7 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
	ice_pf_dis_all_vsi(pf, false);

	if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
		ice_ptp_release(pf);
		ice_ptp_prepare_for_reset(pf);

	if (hw->port_info)
		ice_sched_clear_port(hw->port_info);
@@ -1063,6 +1063,9 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi, bool link_up,
	if (link_up == old_link && link_speed == old_link_speed)
		return 0;

	if (!ice_is_e810(&pf->hw))
		ice_ptp_link_change(pf, pf->hw.pf_id, link_up);

	if (ice_is_dcb_active(pf)) {
		if (test_bit(ICE_FLAG_DCB_ENA, pf->flags))
			ice_dcb_rebuild(pf);
@@ -5839,6 +5842,8 @@ static int ice_up_complete(struct ice_vsi *vsi)
		ice_print_link_msg(vsi, true);
		netif_tx_start_all_queues(vsi->netdev);
		netif_carrier_on(vsi->netdev);
		if (!ice_is_e810(&pf->hw))
			ice_ptp_link_change(pf, pf->hw.pf_id, true);
	}

	/* clear this now, and the first stats read will be used as baseline */
@@ -6239,6 +6244,8 @@ int ice_down(struct ice_vsi *vsi)
	WARN_ON(!test_bit(ICE_VSI_DOWN, vsi->state));

	if (vsi->netdev && vsi->type == ICE_VSI_PF) {
		if (!ice_is_e810(&vsi->back->hw))
			ice_ptp_link_change(vsi->back, vsi->back->hw.pf_id, false);
		netif_carrier_off(vsi->netdev);
		netif_tx_disable(vsi->netdev);
	} else if (vsi->type == ICE_VSI_SWITCHDEV_CTRL) {
@@ -6685,7 +6692,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
	 * fail.
	 */
	if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
		ice_ptp_init(pf);
		ice_ptp_reset(pf);

	/* rebuild PF VSI */
	err = ice_vsi_rebuild_by_type(pf, ICE_VSI_PF);
@@ -6694,6 +6701,10 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
		goto err_vsi_rebuild;
	}

	/* configure PTP timestamping after VSI rebuild */
	if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
		ice_ptp_cfg_timestamp(pf, false);

	err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
	if (err) {
		dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);
Loading