Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp3860314pxb; Tue, 17 Nov 2020 05:36:32 -0800 (PST) X-Google-Smtp-Source: ABdhPJyBCzD633fWfJtFbAMg8+y8dlmzkMfvJWzDOiqF+cHuf0F9vKF2ne8OfroAp10l95XDjsXO X-Received: by 2002:a17:906:a444:: with SMTP id cb4mr20132679ejb.416.1605620192561; Tue, 17 Nov 2020 05:36:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605620192; cv=none; d=google.com; s=arc-20160816; b=LmpkQ/1+kws9MI4EQ8GhYy+H5OCjdgz8Lu2HyDOvCDfnzXGWCKZCrVS0j+JIhcf/Wr w9qHMuHYdzBU3E8BqQDoQPjpJsH5l7a7fKBmxzoKO3JrZ97hVD3EaxGXmk+ea6s28Y1b 2GLXsPW0ZCanQV6PUNJCyTpI+gBWSxTu1TKf2dzCl9Q2rGQso9BEktCM+hSasKvqNRrC orwiXGUGS+fho2XsGq3bZUfkkPxENXmxShn8WF5atcar0LRdl8jY2TaF0bWlZe1vVKLu NBvaTbvgs/hiobUiIvZeD/p6yryKzPwDU2Tc/fZaacUijUZkXDa1tDEsOHabDSRQkSxp aIRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=WT2QNnrYqF06mRNVSEvuZ+GAwOM8R9EOz8+uesH4FKM=; b=RljdhT0VVUV8kf0ZpIzqd9X0h7muCsrxuW1/lbK3FVudyBJAZgfqeWTVxNVFGmy18l Qn2ABLJSJ1XJrmr0xxC0V/d+ipyHrvpWN7naLzgDwrzmcF05ZBw3z5SmX2+x6W/GuCI9 d74x7uWRhiDJBZNu4InhW7eJBXxRh5lUllBSj5zQeM/ZsTLnAGHEHG7Siq8FahdAjznR SHwmyUHp/xYwX+/gxiRrJ1LVy+zFwI+quWCFjcBWdNwP2e4NPFqP6TP7uauJCHqENMTd 73DdFe5/o3b7oA7m7S/8JSDnR1UgX+JXmTxz2ofS4BSXZk+xNN/TDOzvlr1j+sWKRghW htvA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=syAdQxKp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w10si13737097ejz.5.2020.11.17.05.36.09; Tue, 17 Nov 2020 05:36:32 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=syAdQxKp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732315AbgKQNcj (ORCPT + 99 others); Tue, 17 Nov 2020 08:32:39 -0500 Received: from mail.kernel.org ([198.145.29.99]:42154 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732266AbgKQNcU (ORCPT ); Tue, 17 Nov 2020 08:32:20 -0500 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 59CCF2078E; Tue, 17 Nov 2020 13:32:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1605619941; bh=+WADrUy5UpjLhJkC1SaS6aQ6KJWeP90Ig6r1nmV5nT0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=syAdQxKpC9xN22nX3lOZ1+4eGguJmqSqZ9HBGoQvLrm4RPUnscq+CfxOfrDh3Gy7+ C85eQV6MOxvUf1Eg8+ggM7ZI/uovDUJjRsylgnLVcd4BILN+gKBNAUTLOZ3dLk5Woz gjaEUmzcrVimv6fVH/htOfqpHML3vwUiB+PV9GZU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Fabian Inostroza , Stephane Grosjean , Marc Kleine-Budde , Sasha Levin Subject: [PATCH 5.9 054/255] can: peak_usb: peak_usb_get_ts_time(): fix timestamp wrapping Date: Tue, 17 Nov 2020 14:03:14 +0100 Message-Id: <20201117122141.582283576@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201117122138.925150709@linuxfoundation.org> References: <20201117122138.925150709@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Stephane Grosjean [ Upstream commit ecc7b4187dd388549544195fb13a11b4ea8e6a84 ] Fabian Inostroza has discovered a potential problem in the hardware timestamp reporting from the PCAN-USB USB CAN interface (only), related to the fact that a timestamp of an event may precede the timestamp used for synchronization when both records are part of the same USB packet. However, this case was used to detect the wrapping of the time counter. This patch details and fixes the two identified cases where this problem can occur. Reported-by: Fabian Inostroza Signed-off-by: Stephane Grosjean Link: https://lore.kernel.org/r/20201014085631.15128-1-s.grosjean@peak-system.com Fixes: bb4785551f64 ("can: usb: PEAK-System Technik USB adapters driver core") Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin --- drivers/net/can/usb/peak_usb/pcan_usb_core.c | 51 ++++++++++++++++++-- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c index d91df34e7fa88..c2764799f9efb 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -130,14 +130,55 @@ void peak_usb_get_ts_time(struct peak_time_ref *time_ref, u32 ts, ktime_t *time) /* protect from getting time before setting now */ if (ktime_to_ns(time_ref->tv_host)) { u64 delta_us; + s64 delta_ts = 0; + + /* General case: dev_ts_1 < dev_ts_2 < ts, with: + * + * - dev_ts_1 = previous sync timestamp + * - dev_ts_2 = last sync timestamp + * - ts = event timestamp + * - ts_period = known sync period (theoretical) + * ~ dev_ts2 - dev_ts1 + * *but*: + * + * - time counters wrap (see adapter->ts_used_bits) + * - sometimes, dev_ts_1 < ts < dev_ts2 + * + * "normal" case (sync time counters increase): + * must take into account case when ts wraps (tsw) + * + * < ts_period > < > + * | | | + * ---+--------+----+-------0-+--+--> + * ts_dev_1 | ts_dev_2 | + * ts tsw + */ + if (time_ref->ts_dev_1 < time_ref->ts_dev_2) { + /* case when event time (tsw) wraps */ + if (ts < time_ref->ts_dev_1) + delta_ts = 1 << time_ref->adapter->ts_used_bits; + + /* Otherwise, sync time counter (ts_dev_2) has wrapped: + * handle case when event time (tsn) hasn't. + * + * < ts_period > < > + * | | | + * ---+--------+--0-+---------+--+--> + * ts_dev_1 | ts_dev_2 | + * tsn ts + */ + } else if (time_ref->ts_dev_1 < ts) { + delta_ts = -(1 << time_ref->adapter->ts_used_bits); + } - delta_us = ts - time_ref->ts_dev_2; - if (ts < time_ref->ts_dev_2) - delta_us &= (1 << time_ref->adapter->ts_used_bits) - 1; + /* add delay between last sync and event timestamps */ + delta_ts += (signed int)(ts - time_ref->ts_dev_2); - delta_us += time_ref->ts_total; + /* add time from beginning to last sync */ + delta_ts += time_ref->ts_total; - delta_us *= time_ref->adapter->us_per_ts_scale; + /* convert ticks number into microseconds */ + delta_us = delta_ts * time_ref->adapter->us_per_ts_scale; delta_us >>= time_ref->adapter->us_per_ts_shift; *time = ktime_add_us(time_ref->tv_host_0, delta_us); -- 2.27.0