linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marc Kleine-Budde <mkl@pengutronix.de>
To: Marek Vasut <marex@denx.de>, linux-can@vger.kernel.org
Subject: Re: [PATCH 6/6] net: can: ifi: Add more detailed error reporting
Date: Sun, 8 May 2016 20:58:29 +0200	[thread overview]
Message-ID: <572F8C55.5060007@pengutronix.de> (raw)
In-Reply-To: <1462660456-6179-6-git-send-email-marex@denx.de>


[-- Attachment #1.1: Type: text/plain, Size: 8105 bytes --]

On 05/08/2016 12:34 AM, Marek Vasut wrote:
> The updated specification for the IFI CANFD core contains description
> of more detailed error reporting capability of the core. Implement
> support for this detailed error reporting.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> ---
>  drivers/net/can/ifi_canfd/ifi_canfd.c | 109 ++++++++++++++++++++++++++++++++--
>  1 file changed, 105 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
> index ba6cd43..495879f 100644
> --- a/drivers/net/can/ifi_canfd/ifi_canfd.c
> +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
> @@ -52,7 +52,8 @@
>  #define IFI_CANFD_TXSTCMD_OVERFLOW		BIT(13)
>  
>  #define IFI_CANFD_INTERRUPT			0xc
> -#define IFI_CANFD_INTERRUPT_ERROR_WARNING	((u32)BIT(1))
> +#define IFI_CANFD_INTERRUPT_ERROR_WARNING	BIT(1)
> +#define IFI_CANFD_INTERRUPT_ERROR_COUNTER	BIT(10)
>  #define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY	BIT(16)
>  #define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE	BIT(22)
>  #define IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY	BIT(24)
> @@ -103,7 +104,26 @@
>  
>  #define IFI_CANFD_RES1				0x40
>  
> -#define IFI_CANFD_RES2				0x44
> +#define IFI_CANFD_ERROR_CTR			0x44
> +#define IFI_CANFD_ERROR_CTR_UNLOCK_MAGIC	0x21302899
> +#define IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST	BIT(0)
> +#define IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST	BIT(1)
> +#define IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST	BIT(2)
> +#define IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST	BIT(3)
> +#define IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST	BIT(4)
> +#define IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST	BIT(5)
> +#define IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST	BIT(6)
> +#define IFI_CANFD_ERROR_CTR_OVERLOAD_ALL	BIT(8)
> +#define IFI_CANFD_ERROR_CTR_ACK_ERROR_ALL	BIT(9)
> +#define IFI_CANFD_ERROR_CTR_BIT0_ERROR_ALL	BIT(10)
> +#define IFI_CANFD_ERROR_CTR_BIT1_ERROR_ALL	BIT(11)
> +#define IFI_CANFD_ERROR_CTR_STUFF_ERROR_ALL	BIT(12)
> +#define IFI_CANFD_ERROR_CTR_CRC_ERROR_ALL	BIT(13)
> +#define IFI_CANFD_ERROR_CTR_FORM_ERROR_ALL	BIT(14)
> +#define IFI_CANFD_ERROR_CTR_BITPOSITION_OFFSET	16
> +#define IFI_CANFD_ERROR_CTR_BITPOSITION_MASK	0xff
> +#define IFI_CANFD_ERROR_CTR_ER_RESET		BIT(30)
> +#define IFI_CANFD_ERROR_CTR_ER_ENABLE		((u32)BIT(31))
>  
>  #define IFI_CANFD_PAR				0x48
>  
> @@ -197,6 +217,8 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable)
>  	if (enable) {
>  		enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY |
>  			IFI_CANFD_IRQMASK_RXFIFO_NEMPTY;
> +		if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
> +			enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>  	}
>  
>  	writel(IFI_CANFD_IRQMASK_SET_ERR |
> @@ -335,6 +357,68 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev)
>  	return 1;
>  }
>  
> +static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr)
> +{
> +	struct ifi_canfd_priv *priv = netdev_priv(ndev);
> +	struct net_device_stats *stats = &ndev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST |
> +			    IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST;
> +
> +	if (!(errctr & errmask))	/* No error happened. */
> +		return 0;
> +
> +	priv->can.can_stats.bus_error++;
> +	stats->rx_errors++;
> +
> +	/* Propagate the error condition to the CAN stack. */
> +	skb = alloc_can_err_skb(ndev, &cf);
> +	if (unlikely(!skb))
> +		return 0;
> +
> +	/* Read the error counter register and check for new errors. */
> +	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST)
> +		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_BIT0;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_BIT1;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_STUFF;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST)
> +		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_FORM;
> +
> +	/* Reset the error counter, ack the IRQ and re-enable the counter. */
> +	writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
> +	writel(IFI_CANFD_INTERRUPT_ERROR_COUNTER,
> +	       priv->base + IFI_CANFD_INTERRUPT);
> +	writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
> +
> +	stats->rx_packets++;
> +	stats->rx_bytes += cf->can_dlc;
> +	netif_receive_skb(skb);
> +
> +	return 1;
> +}
> +
>  static int ifi_canfd_get_berr_counter(const struct net_device *ndev,
>  				      struct can_berr_counter *bec)
>  {
> @@ -470,6 +554,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
>  
>  	u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
>  	u32 rxstcmd = readl(priv->base + IFI_CANFD_STCMD);
> +	u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
>  
>  	/* Handle bus state changes */
>  	if ((stcmd & stcmd_state_mask) ||
> @@ -480,6 +565,10 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
>  	if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW)
>  		work_done += ifi_canfd_handle_lost_msg(ndev);
>  
> +	/* Handle lec errors on the bus */
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
> +		work_done += ifi_canfd_handle_lec_err(ndev, errctr);
> +
>  	/* Handle normal messages on RX */
>  	if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY))
>  		work_done += ifi_canfd_do_rx_poll(ndev, quota - work_done);
> @@ -499,7 +588,8 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
>  	struct net_device_stats *stats = &ndev->stats;
>  	const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
>  				IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
> -				IFI_CANFD_INTERRUPT_ERROR_WARNING;
> +				IFI_CANFD_INTERRUPT_ERROR_WARNING |
> +				IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>  	const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
>  				IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
>  	const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |

I'll fold this hunk to get rid of another of this warnings :(


>   CC [M]  drivers/net/can/ifi_canfd/ifi_canfd.o
> drivers/net/can/ifi_canfd/ifi_canfd.c: In function ‘ifi_canfd_isr’:
> drivers/net/can/ifi_canfd/ifi_canfd.c:595:27: warning: large integer implicitly truncated to unsigned type [-Woverflow]
>   const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
>                            ^

> diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
> index 495879f30906..2d1d22eec750 100644
> --- a/drivers/net/can/ifi_canfd/ifi_canfd.c
> +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
> @@ -592,8 +592,8 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
>                                 IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>         const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
>                                 IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
> -       const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
> -                                  IFI_CANFD_INTERRUPT_ERROR_WARNING);
> +       const u32 clr_irq_mask = ~((u32)(IFI_CANFD_INTERRUPT_SET_IRQ |
> +                                        IFI_CANFD_INTERRUPT_ERROR_WARNING));
>         u32 isr;
>  
>         isr = readl(priv->base + IFI_CANFD_INTERRUPT);

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

  reply	other threads:[~2016-05-08 18:58 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-07 22:34 [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marek Vasut
2016-05-07 22:34 ` [PATCH 2/6] net: can: ifi: Update timing configuration code Marek Vasut
2016-05-07 22:34 ` [PATCH 3/6] net: can: ifi: Unify timing constants Marek Vasut
2016-05-07 22:34 ` [PATCH 4/6] net: can: ifi: Treat CAN_CTRLMODE_FD_NON_ISO correctly Marek Vasut
2016-05-08 18:26   ` Oliver Hartkopp
2016-05-08 18:55     ` Marc Kleine-Budde
2016-05-07 22:34 ` [PATCH 5/6] net: can: ifi: Increment TX counters only on real transmission Marek Vasut
2016-05-07 22:34 ` [PATCH 6/6] net: can: ifi: Add more detailed error reporting Marek Vasut
2016-05-08 18:58   ` Marc Kleine-Budde [this message]
2016-05-08 19:25     ` Marek Vasut
2016-05-08 18:59 ` [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marc Kleine-Budde

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=572F8C55.5060007@pengutronix.de \
    --to=mkl@pengutronix.de \
    --cc=linux-can@vger.kernel.org \
    --cc=marex@denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).