Re: [PATCH v5 4/7] can: Add Nuvoton NCT6694 CAN support

Vincent Mailhol
2025-01-15T16:45:27Z

On 14/01/2025 at 12:30, Ming Yu wrote:

(...)

> +static void nct6694_can_clean(struct net_device *ndev)
> +{
> + struct nct6694_can_priv *priv = netdev_priv(ndev);
> +
> + if (priv->tx_skb || netif_queue_stopped(ndev))
> + ndev->stats.tx_errors++;
> + dev_kfree_skb(priv->tx_skb);

Use:

can_flush_echo_skb(ndev);

(related to the following comments).

> + priv->tx_skb = NULL;
> +}

(...)

> +static void nct6694_can_tx_work(struct work_struct *work)
> +{
> + struct nct6694_can_priv *priv = container_of(work,
> + struct nct6694_can_priv,
> + tx_work);
> + struct net_device *ndev = priv->ndev;
> +
> + guard(mutex)(&priv->lock);
> +
> + if (priv->tx_skb) {
> + if (priv->can.state == CAN_STATE_BUS_OFF) {

Just stop the queue when the can bus is off so that you do not have do
check the bus status each time a frame is sent.

> + nct6694_can_clean(ndev);
> + } else {
> + nct6694_can_tx(ndev);
> + can_put_echo_skb(priv->tx_skb, ndev, 0, 0);
> + priv->tx_skb = NULL;
> + }
> + }
> +}
> +
> +static netdev_tx_t nct6694_can_start_xmit(struct sk_buff *skb,
> + struct net_device *ndev)
> +{
> + struct nct6694_can_priv *priv = netdev_priv(ndev);
> +
> + if (can_dev_dropped_skb(ndev, skb))
> + return NETDEV_TX_OK;
> +
> + if (priv->tx_skb) {
> + netdev_err(ndev, "hard_xmit called while tx busy\n");
> + return NETDEV_TX_BUSY;
> + }
> +
> + netif_stop_queue(ndev);
> + priv->tx_skb = skb;

Here, you can directly do:

can_put_echo_skb(skb, ndev, 0, 0);

The skb remains accessible under priv->can.echo_skb[0]. With this, you
can remove the priv->tx_skb field.

> + queue_work(priv->wq, &priv->tx_work);
> +
> + return NETDEV_TX_OK;
> +}

Yours sincerely,
Vincent Mailhol