Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3325991imu; Sun, 11 Nov 2018 12:25:42 -0800 (PST) X-Google-Smtp-Source: AJdET5cO77OHsVupUAkkxDT5xCNNzlKmQ/64Gs5Ikzfo7Ia2grifqFfN+CNCbaXWVT4w0Qbx07i0 X-Received: by 2002:a63:170c:: with SMTP id x12mr14647933pgl.364.1541967942918; Sun, 11 Nov 2018 12:25:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541967942; cv=none; d=google.com; s=arc-20160816; b=kGmVDFX0cItBbzwz0+DInaBxKTOCpdT1nUsuSRci0ICB11F1wybnujrM/x3XDcGeAm ATxiDTG2LHUktLQctcD61vSXhdAKRHMFaBY+L0SSo2upmi957+HfY+EpbhD7GFCcs2qz Jc2x0T6XxGVwOFeQhcgLatAaTnmvHjallPN5au2QMpcyqw1l+K/X8yZE26na9HlJkxgs wkFVfnLuvF63NOgVWlVsr1S68/XCkFhlo+1VbC8HiKcj47MF65CPA4cX5gm/IiAwJiPq WLoPNdV55NGCngp6448KD48bZSmAFTSSBpUiQ53m0pVRBKfHwrWzKDnM7iFG3OhYbuUP ZL4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=tHE2/1dFSBudmNN/QS1CIVQemlblEUifW35fD1oMX44=; b=zlxgpAaIXebxNHBbIgSKXgWrBl4KrVgDRO0D8ZXWd33LpwLxFzC8sOtRTj5oofScxg 2ICpEgVCMuoHqQpCoTgD9POXvRTXQuJX/vmScCEuo8wqs2qsJD01vdG7rPKppgBC3Bl8 tJXdhYCAbXTRei3uNQ96XIHjQW9rZhyodpBsUxrL+Me0i7Ydps+WMq5Mk9KQUuIrxX1r dKBT5fU4bipSlxc8g5lL+EHukCl1K1PpOZXpP34Etga+0iWAacqaaRNYKJ5U6K8j8EGT Zmokuy+Lz6AESgeZ57DbvfTwV7RxIOskYqSMbOWCspHT+wOZlWAHwsr5acqrRCwalP8F 5fOw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s22-v6si14928452pfs.13.2018.11.11.12.25.28; Sun, 11 Nov 2018 12:25:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731239AbeKLGOd (ORCPT + 99 others); Mon, 12 Nov 2018 01:14:33 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:50994 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730672AbeKLFs3 (ORCPT ); Mon, 12 Nov 2018 00:48:29 -0500 Received: from [192.168.4.242] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gLvsn-0000oF-MH; Sun, 11 Nov 2018 19:58:57 +0000 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1gLvsX-0001lO-PV; Sun, 11 Nov 2018 19:58:41 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Wolfgang Grandegger" , "Marc Kleine-Budde" , "Andri Yngvason" Date: Sun, 11 Nov 2018 19:49:05 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 280/366] can: dev: Consolidate and unify state change handling In-Reply-To: X-SA-Exim-Connect-IP: 192.168.4.242 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.61-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Andri Yngvason commit bac78aabcfece0c493b2ad824c68fbdc20448cbc upstream. The handling of can error states is different between platforms. This is an attempt to correct that problem. I've moved this handling into a generic function for changing the error state. This ensures that error state changes are handled the same way everywhere (where this function is used). This new mechanism also adds reverse state transitioning in error frames, i.e. the user will be notified through the socket interface when the state goes down. Signed-off-by: Andri Yngvason Acked-by: Wolfgang Grandegger Signed-off-by: Marc Kleine-Budde Signed-off-by: Ben Hutchings --- drivers/net/can/dev.c | 78 ++++++++++++++++++++++++++++++++++ include/linux/can/dev.h | 3 ++ include/uapi/linux/can/error.h | 1 + 3 files changed, 82 insertions(+) --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -275,6 +275,84 @@ static int can_get_bittiming(struct net_ return err; } +static void can_update_state_error_stats(struct net_device *dev, + enum can_state new_state) +{ + struct can_priv *priv = netdev_priv(dev); + + if (new_state <= priv->state) + return; + + switch (new_state) { + case CAN_STATE_ERROR_WARNING: + priv->can_stats.error_warning++; + break; + case CAN_STATE_ERROR_PASSIVE: + priv->can_stats.error_passive++; + break; + case CAN_STATE_BUS_OFF: + default: + break; + }; +} + +static int can_tx_state_to_frame(struct net_device *dev, enum can_state state) +{ + switch (state) { + case CAN_STATE_ERROR_ACTIVE: + return CAN_ERR_CRTL_ACTIVE; + case CAN_STATE_ERROR_WARNING: + return CAN_ERR_CRTL_TX_WARNING; + case CAN_STATE_ERROR_PASSIVE: + return CAN_ERR_CRTL_TX_PASSIVE; + default: + return 0; + } +} + +static int can_rx_state_to_frame(struct net_device *dev, enum can_state state) +{ + switch (state) { + case CAN_STATE_ERROR_ACTIVE: + return CAN_ERR_CRTL_ACTIVE; + case CAN_STATE_ERROR_WARNING: + return CAN_ERR_CRTL_RX_WARNING; + case CAN_STATE_ERROR_PASSIVE: + return CAN_ERR_CRTL_RX_PASSIVE; + default: + return 0; + } +} + +void can_change_state(struct net_device *dev, struct can_frame *cf, + enum can_state tx_state, enum can_state rx_state) +{ + struct can_priv *priv = netdev_priv(dev); + enum can_state new_state = max(tx_state, rx_state); + + if (unlikely(new_state == priv->state)) { + netdev_warn(dev, "%s: oops, state did not change", __func__); + return; + } + + netdev_dbg(dev, "New error state: %d\n", new_state); + + can_update_state_error_stats(dev, new_state); + priv->state = new_state; + + if (unlikely(new_state == CAN_STATE_BUS_OFF)) { + cf->can_id |= CAN_ERR_BUSOFF; + return; + } + + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] |= tx_state >= rx_state ? + can_tx_state_to_frame(dev, tx_state) : 0; + cf->data[1] |= tx_state <= rx_state ? + can_rx_state_to_frame(dev, rx_state) : 0; +} +EXPORT_SYMBOL_GPL(can_change_state); + /* * Local echo of CAN messages * --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -122,6 +122,9 @@ void unregister_candev(struct net_device int can_restart_now(struct net_device *dev); void can_bus_off(struct net_device *dev); +void can_change_state(struct net_device *dev, struct can_frame *cf, + enum can_state tx_state, enum can_state rx_state); + void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, unsigned int idx); unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); --- a/include/uapi/linux/can/error.h +++ b/include/uapi/linux/can/error.h @@ -71,6 +71,7 @@ #define CAN_ERR_CRTL_TX_PASSIVE 0x20 /* reached error passive status TX */ /* (at least one error counter exceeds */ /* the protocol-defined level of 127) */ +#define CAN_ERR_CRTL_ACTIVE 0x40 /* recovered to error active state */ /* error in CAN protocol (type) / data[2] */ #define CAN_ERR_PROT_UNSPEC 0x00 /* unspecified */