Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp3879141pxb; Tue, 17 Nov 2020 06:04:33 -0800 (PST) X-Google-Smtp-Source: ABdhPJw5LKy1f3G7KlSZSZKOKMYSTn2MLrVeKKz7Kf4P0oDVNNdn6zCPt1zzq7UUAiftETX57ZEg X-Received: by 2002:aa7:d709:: with SMTP id t9mr21733198edq.305.1605621873565; Tue, 17 Nov 2020 06:04:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605621873; cv=none; d=google.com; s=arc-20160816; b=PIF3ZOldx6Y+GvnJeG7V/8w3ng/1cKmV3cbq5nGM+cBFjNZ80/CFoZnK7syLlnEman LRR4OHB60CzQChC3okBas4uN8AF9/WolBvKdmoUigtLL9R3q6hb2tzNSjlYS0AiAwc2O OXvfbPbVOOcjCifjnP6Umnx27iinWLhs+SSyYSxQh01u9svAiqUK/4L6Fc4pi5B386Rg qwzgL+/1+0hwd9oIzJeuWRyoEFUiJcwN1loxGjetnmY1bvyg1rzRaGrmKB/DTjLuHuwe 61LS14zGcsBlLyoZWPEkH8cZftOD1Dpuvq1uCmuTUHIInOVSYMixZBwtmeRtxVRX3KfD hX3A== 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=QHO+qZ9wg4+aXyF+nM+VmrRW/8BW8tx5/QqqSdKMvg8=; b=mKdNQR51vNO7f60wLUeUP5zsNVrwQXs9HFigEnPZlIGHOh6zgw5A0BDT8FljjmwjSO qNMyKXwfG6EtsV2vBDCC/D+LMNTKprQ0zk35vdhFU/JWGLmGyN2+n2BTZmpisLl1nnB7 SAWo23Ipz5VCIsOjWGdW3BsCIbZljE44WzUjlshVYnGZhnnpjBg6eQBjA5KPFV08lO+E 1IyQJUssHiHrdlSj0gkJav/hsqRpbHI6F6mmWOkk9savQ52dkqtygQXku0eLEcDRFcYw kO8h6DlgdsQEFUnNAmJImtHNE45juBDFco4lPfDVyVPvyDFgrOct8jQI9iB4CNOuMRv9 /5xA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=eMsTnbbT; 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 f8si3915766edc.529.2020.11.17.06.04.06; Tue, 17 Nov 2020 06:04:33 -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=eMsTnbbT; 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 S1729956AbgKQNNr (ORCPT + 99 others); Tue, 17 Nov 2020 08:13:47 -0500 Received: from mail.kernel.org ([198.145.29.99]:44262 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729705AbgKQNNj (ORCPT ); Tue, 17 Nov 2020 08:13:39 -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 6E653221EB; Tue, 17 Nov 2020 13:13:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1605618818; bh=V5ywhdFexZ2lzsszBRk/PjPOjjFqAJiPYgHmtk9czhM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eMsTnbbTq7rSYjBdudgUbpJiHv0dt4PbugpWhdqaQmCQ+z6BqxKil8leGtnZvz9Jh Amlbl7oqW9nYR8QJj9naUccxW4j/8UV6KVJC1IPeNoQUWBaCm87NcoiErR2TOp7SzA 0FlRTHN/7HxxbgB4YEqdB7KGrc/WqJo+mwge2M74= 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 4.14 18/85] can: peak_usb: peak_usb_get_ts_time(): fix timestamp wrapping Date: Tue, 17 Nov 2020 14:04:47 +0100 Message-Id: <20201117122111.932876525@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201117122111.018425544@linuxfoundation.org> References: <20201117122111.018425544@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 85d92f129af2d..9d78ba7776140 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -154,14 +154,55 @@ void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts, /* protect from getting timeval before setting now */ if (time_ref->tv_host.tv_sec > 0) { 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; *tv = time_ref->tv_host_0; -- 2.27.0