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 --]
next prev parent 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.