From patchwork Wed Nov 6 18:47:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hall, Christopher S" X-Patchwork-Id: 13865280 X-Patchwork-Delegate: kuba@kernel.org Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4F895208236 for ; Wed, 6 Nov 2024 18:58:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730919533; cv=none; b=H9yDPwsKExZn7AaUvVzuw8chLxoi5ag5E2DRtTJK+VMWu5vWrLDJw+oiz6TJI7UICIXpK22RxNj23Mqi9fPFdX6SjwxKptd1PmZ3PssdtweKPImtiZyNp0DgJJb4zU89CUtUKnvM6L7OZd0LSsNk7d+PyHXQK22cOclKVcSRnYc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730919533; c=relaxed/simple; bh=INK4rzX+ifNzPtwqxjtgntQ3Qurtmz7AEunuf4qJjOk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=A0f6qCE3JqUXrJZkdhjh9Ljz263eF2/K003l/gwJY8Ilp25SkAlBZxIgK3fuYEL0DqFkKvJu2TcjBmod9EaTlZqpqx6SNFh2oZ1++LpZqKr0nFNYdebV6ToWxPQdceczrTCNWxHJJKkw2OUkt3XNFPPdtrpFQxR1XVycWrQkLao= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=MvgGWj18; arc=none smtp.client-ip=192.198.163.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="MvgGWj18" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1730919532; x=1762455532; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=INK4rzX+ifNzPtwqxjtgntQ3Qurtmz7AEunuf4qJjOk=; b=MvgGWj18SERubq3k8El8ZnW7+p1yLcq98v+fql9V617SLj4DCKka/Sd3 rahlEjvwTzB4mjFhvgiEmhgzciDgbPC3WTDrqvo6zWzI0Gd1kmujzVvDa lh6Z0KMT5KTEghPRohcM3Cqk4499mlJlnQkwSsM3hmSUg9DVo5od5YMJA 5Z/oTecU4CsHhcIL0bWMN07W5FZ/aoF+uZzl6Fq4ZrC+4s8oK/jdIx05a vGw2DmHXy1smM5dJ70TbfxYps1+5u85uv3uGpglm4IRkNLwOUo/ZTKyP/ Mh2hl90KL777zyQGSKcbeiDHO+5Y2EyFmg9fYJJB3xHkGoZ0fZNtmMk4R w==; X-CSE-ConnectionGUID: Jl78tZOlTg6yloIC571n1w== X-CSE-MsgGUID: vIkAfIebREycNzq6V8wcPQ== X-IronPort-AV: E=McAfee;i="6700,10204,11248"; a="30959461" X-IronPort-AV: E=Sophos;i="6.11,263,1725346800"; d="scan'208";a="30959461" Received: from orviesa004.jf.intel.com ([10.64.159.144]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Nov 2024 10:58:50 -0800 X-CSE-ConnectionGUID: DpTZbD/STjWSZBTG9XBUTA== X-CSE-MsgGUID: qAptyY6BREqCWIYLP13feA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,263,1725346800"; d="scan'208";a="89813790" Received: from timelab-spr11.ch.intel.com ([143.182.136.151]) by orviesa004.jf.intel.com with ESMTP; 06 Nov 2024 10:56:39 -0800 From: Christopher S M Hall To: intel-wired-lan@lists.osuosl.org Cc: david.zage@intel.com, vinicius.gomes@intel.com, netdev@vger.kernel.org, rodrigo.cadore@l-acoustics.com, vinschen@redhat.com, Michal Swiatkowski , Mor Bar-Gabay , Avigail Dahan Subject: [PATCH iwl-net v3 1/6] igc: Ensure the PTM cycle is reliably triggered Date: Wed, 6 Nov 2024 18:47:17 +0000 Message-Id: <20241106184722.17230-2-christopher.s.hall@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241106184722.17230-1-christopher.s.hall@intel.com> References: <20241106184722.17230-1-christopher.s.hall@intel.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Writing to clear the PTM status 'valid' bit while the PTM cycle is triggered results in unreliable PTM operation. To fix this, clear the PTM 'trigger' and status after each PTM transaction. The issue can be reproduced with the following: $ sudo phc2sys -R 1000 -O 0 -i tsn0 -m Note: 1000 Hz (-R 1000) is unrealistically large, but provides a way to quickly reproduce the issue. PHC2SYS exits with: "ioctl PTP_OFFSET_PRECISE: Connection timed out" when the PTM transaction fails Fixes: a90ec8483732 ("igc: Add support for PTP getcrosststamp()") Reviewed-by: Michal Swiatkowski Tested-by: Mor Bar-Gabay Tested-by: Avigail Dahan Signed-off-by: Christopher S M Hall --- drivers/net/ethernet/intel/igc/igc_defines.h | 1 + drivers/net/ethernet/intel/igc/igc_ptp.c | 70 ++++++++++++-------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h index 8e449904aa7d..2ff292f5f63b 100644 --- a/drivers/net/ethernet/intel/igc/igc_defines.h +++ b/drivers/net/ethernet/intel/igc/igc_defines.h @@ -593,6 +593,7 @@ #define IGC_PTM_STAT_T4M1_OVFL BIT(3) /* T4 minus T1 overflow */ #define IGC_PTM_STAT_ADJUST_1ST BIT(4) /* 1588 timer adjusted during 1st PTM cycle */ #define IGC_PTM_STAT_ADJUST_CYC BIT(5) /* 1588 timer adjusted during non-1st PTM cycle */ +#define IGC_PTM_STAT_ALL GENMASK(5, 0) /* Used to clear all status */ /* PCIe PTM Cycle Control */ #define IGC_PTM_CYCLE_CTRL_CYC_TIME(msec) ((msec) & 0x3ff) /* PTM Cycle Time (msec) */ diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index 946edbad4302..c640e346342b 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -974,13 +974,40 @@ static void igc_ptm_log_error(struct igc_adapter *adapter, u32 ptm_stat) } } +static void igc_ptm_trigger(struct igc_hw *hw) +{ + u32 ctrl; + + /* To "manually" start the PTM cycle we need to set the + * trigger (TRIG) bit + */ + ctrl = rd32(IGC_PTM_CTRL); + ctrl |= IGC_PTM_CTRL_TRIG; + wr32(IGC_PTM_CTRL, ctrl); + /* Perform flush after write to CTRL register otherwise + * transaction may not start + */ + wrfl(); +} + +static void igc_ptm_reset(struct igc_hw *hw) +{ + u32 ctrl; + + ctrl = rd32(IGC_PTM_CTRL); + ctrl &= ~IGC_PTM_CTRL_TRIG; + wr32(IGC_PTM_CTRL, ctrl); + /* Write to clear all status */ + wr32(IGC_PTM_STAT, IGC_PTM_STAT_ALL); +} + static int igc_phc_get_syncdevicetime(ktime_t *device, struct system_counterval_t *system, void *ctx) { - u32 stat, t2_curr_h, t2_curr_l, ctrl; struct igc_adapter *adapter = ctx; struct igc_hw *hw = &adapter->hw; + u32 stat, t2_curr_h, t2_curr_l; int err, count = 100; ktime_t t1, t2_curr; @@ -994,25 +1021,13 @@ static int igc_phc_get_syncdevicetime(ktime_t *device, * are transitory. Repeating the process returns valid * data eventually. */ - - /* To "manually" start the PTM cycle we need to clear and - * then set again the TRIG bit. - */ - ctrl = rd32(IGC_PTM_CTRL); - ctrl &= ~IGC_PTM_CTRL_TRIG; - wr32(IGC_PTM_CTRL, ctrl); - ctrl |= IGC_PTM_CTRL_TRIG; - wr32(IGC_PTM_CTRL, ctrl); - - /* The cycle only starts "for real" when software notifies - * that it has read the registers, this is done by setting - * VALID bit. - */ - wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID); + igc_ptm_trigger(hw); err = readx_poll_timeout(rd32, IGC_PTM_STAT, stat, stat, IGC_PTM_STAT_SLEEP, IGC_PTM_STAT_TIMEOUT); + igc_ptm_reset(hw); + if (err < 0) { netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n"); return err; @@ -1021,15 +1036,7 @@ static int igc_phc_get_syncdevicetime(ktime_t *device, if ((stat & IGC_PTM_STAT_VALID) == IGC_PTM_STAT_VALID) break; - if (stat & ~IGC_PTM_STAT_VALID) { - /* An error occurred, log it. */ - igc_ptm_log_error(adapter, stat); - /* The STAT register is write-1-to-clear (W1C), - * so write the previous error status to clear it. - */ - wr32(IGC_PTM_STAT, stat); - continue; - } + igc_ptm_log_error(adapter, stat); } while (--count); if (!count) { @@ -1255,7 +1262,7 @@ void igc_ptp_stop(struct igc_adapter *adapter) void igc_ptp_reset(struct igc_adapter *adapter) { struct igc_hw *hw = &adapter->hw; - u32 cycle_ctrl, ctrl; + u32 cycle_ctrl, ctrl, stat; unsigned long flags; u32 timadj; @@ -1290,14 +1297,19 @@ void igc_ptp_reset(struct igc_adapter *adapter) ctrl = IGC_PTM_CTRL_EN | IGC_PTM_CTRL_START_NOW | IGC_PTM_CTRL_SHRT_CYC(IGC_PTM_SHORT_CYC_DEFAULT) | - IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT) | - IGC_PTM_CTRL_TRIG; + IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT); wr32(IGC_PTM_CTRL, ctrl); /* Force the first cycle to run. */ - wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID); + igc_ptm_trigger(hw); + + if (readx_poll_timeout_atomic(rd32, IGC_PTM_STAT, stat, + stat, IGC_PTM_STAT_SLEEP, + IGC_PTM_STAT_TIMEOUT)) + netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n"); + igc_ptm_reset(hw); break; default: /* No work to do. */