Commit 33b32a29 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'linux-can-next-for-5.13-20210407' of...

Merge tag 'linux-can-next-for-5.13-20210407' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next



Marc Kleine-Budde says:

====================
pull-request: can-next 2021-04-07

this is a pull request of 6 patches for net-next/master.

The first patch targets the CAN driver infrastructure, it improves the
alloc_can{,fd}_skb() function to set the pointer to the CAN frame to
NULL if skb allocation fails.

The next patch adds missing error handling to the m_can driver's RX
path (the code was introduced in -next, no need to backport).

In the next patch an unused constant is removed from an enum in the
c_can driver.

The last 3 patches target the mcp251xfd driver. They add BQL support
and try to work around a sometimes broken CRC when reading the TBC
register.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0854fa82 c7eb923c
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -149,7 +149,6 @@ static const u16 __maybe_unused reg_map_d_can[] = {
};

enum c_can_dev_id {
	BOSCH_C_CAN_PLATFORM,
	BOSCH_C_CAN,
	BOSCH_D_CAN,
};
+8 −2
Original line number Diff line number Diff line
@@ -183,8 +183,11 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)

	skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
			       sizeof(struct can_frame));
	if (unlikely(!skb))
	if (unlikely(!skb)) {
		*cf = NULL;

		return NULL;
	}

	skb->protocol = htons(ETH_P_CAN);
	skb->pkt_type = PACKET_BROADCAST;
@@ -211,8 +214,11 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,

	skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
			       sizeof(struct canfd_frame));
	if (unlikely(!skb))
	if (unlikely(!skb)) {
		*cfd = NULL;

		return NULL;
	}

	skb->protocol = htons(ETH_P_CANFD);
	skb->pkt_type = PACKET_BROADCAST;
+10 −3
Original line number Diff line number Diff line
@@ -466,11 +466,18 @@ static void m_can_receive_skb(struct m_can_classdev *cdev,
			      struct sk_buff *skb,
			      u32 timestamp)
{
	if (cdev->is_peripheral)
		can_rx_offload_queue_sorted(&cdev->offload, skb, timestamp);
	else
	if (cdev->is_peripheral) {
		struct net_device_stats *stats = &cdev->net->stats;
		int err;

		err = can_rx_offload_queue_sorted(&cdev->offload, skb,
						  timestamp);
		if (err)
			stats->rx_fifo_errors++;
	} else {
		netif_receive_skb(skb);
	}
}

static void m_can_read_fifo(struct net_device *dev, u32 rxfs)
{
+18 −5
Original line number Diff line number Diff line
@@ -335,6 +335,8 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
	u8 len;
	int i, j;

	netdev_reset_queue(priv->ndev);

	/* TEF */
	tef_ring = priv->tef;
	tef_ring->head = 0;
@@ -1262,7 +1264,8 @@ mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)

static int
mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
			   const struct mcp251xfd_hw_tef_obj *hw_tef_obj)
			   const struct mcp251xfd_hw_tef_obj *hw_tef_obj,
			   unsigned int *frame_len_ptr)
{
	struct net_device_stats *stats = &priv->ndev->stats;
	struct sk_buff *skb;
@@ -1288,8 +1291,8 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
		mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts);
	stats->tx_bytes +=
		can_rx_offload_get_echo_skb(&priv->offload,
					    tef_tail,
					    hw_tef_obj->ts, NULL);
					    tef_tail, hw_tef_obj->ts,
					    frame_len_ptr);
	stats->tx_packets++;
	priv->tef->tail++;

@@ -1347,6 +1350,7 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv,
static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
{
	struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX];
	unsigned int total_frame_len = 0;
	u8 tef_tail, len, l;
	int err, i;

@@ -1368,7 +1372,9 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
	}

	for (i = 0; i < len; i++) {
		err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i]);
		unsigned int frame_len = 0;

		err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
		/* -EAGAIN means the Sequence Number in the TEF
		 * doesn't match our tef_tail. This can happen if we
		 * read the TEF objects too early. Leave loop let the
@@ -1378,6 +1384,8 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
			goto out_netif_wake_queue;
		if (err)
			return err;

		total_frame_len += frame_len;
	}

 out_netif_wake_queue:
@@ -1403,6 +1411,7 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
			return err;

		tx_ring->tail += len;
		netdev_completed_queue(priv->ndev, len, total_frame_len);

		err = mcp251xfd_check_tef_tail(priv);
		if (err)
@@ -2446,6 +2455,7 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
	struct mcp251xfd_priv *priv = netdev_priv(ndev);
	struct mcp251xfd_tx_ring *tx_ring = priv->tx;
	struct mcp251xfd_tx_obj *tx_obj;
	unsigned int frame_len;
	u8 tx_head;
	int err;

@@ -2464,7 +2474,10 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
	if (mcp251xfd_get_tx_free(tx_ring) == 0)
		netif_stop_queue(ndev);

	can_put_echo_skb(skb, ndev, tx_head, 0);
	frame_len = can_skb_get_frame_len(skb);
	err = can_put_echo_skb(skb, ndev, tx_head, frame_len);
	if (!err)
		netdev_sent_queue(priv->ndev, frame_len);

	err = mcp251xfd_tx_obj_write(priv, tx_obj);
	if (err)
+54 −10
Original line number Diff line number Diff line
@@ -232,13 +232,31 @@ mcp251xfd_regmap_crc_write(void *context,
						 count - data_offset);
}

static int
mcp251xfd_regmap_crc_read_check_crc(const struct mcp251xfd_map_buf_crc * const buf_rx,
				    const struct mcp251xfd_map_buf_crc * const buf_tx,
				    unsigned int data_len)
{
	u16 crc_received, crc_calculated;

	crc_received = get_unaligned_be16(buf_rx->data + data_len);
	crc_calculated = mcp251xfd_crc16_compute2(&buf_tx->cmd,
						  sizeof(buf_tx->cmd),
						  buf_rx->data,
						  data_len);
	if (crc_received != crc_calculated)
		return -EBADMSG;

	return 0;
}


static int
mcp251xfd_regmap_crc_read_one(struct mcp251xfd_priv *priv,
			      struct spi_message *msg, unsigned int data_len)
{
	const struct mcp251xfd_map_buf_crc *buf_rx = priv->map_buf_crc_rx;
	const struct mcp251xfd_map_buf_crc *buf_tx = priv->map_buf_crc_tx;
	u16 crc_received, crc_calculated;
	int err;

	BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8));
@@ -248,15 +266,7 @@ mcp251xfd_regmap_crc_read_one(struct mcp251xfd_priv *priv,
	if (err)
		return err;

	crc_received = get_unaligned_be16(buf_rx->data + data_len);
	crc_calculated = mcp251xfd_crc16_compute2(&buf_tx->cmd,
						  sizeof(buf_tx->cmd),
						  buf_rx->data,
						  data_len);
	if (crc_received != crc_calculated)
		return -EBADMSG;

	return 0;
	return mcp251xfd_regmap_crc_read_check_crc(buf_rx, buf_tx, data_len);
}

static int
@@ -311,6 +321,40 @@ mcp251xfd_regmap_crc_read(void *context,
		if (err != -EBADMSG)
			return err;

		/* MCP251XFD_REG_TBC is the time base counter
		 * register. It increments once per SYS clock tick,
		 * which is 20 or 40 MHz.
		 *
		 * Observation shows that if the lowest byte (which is
		 * transferred first on the SPI bus) of that register
		 * is 0x00 or 0x80 the calculated CRC doesn't always
		 * match the transferred one.
		 *
		 * If the highest bit in the lowest byte is flipped
		 * the transferred CRC matches the calculated one. We
		 * assume for now the CRC calculation in the chip
		 * works on wrong data and the transferred data is
		 * correct.
		 */
		if (reg == MCP251XFD_REG_TBC &&
		    (buf_rx->data[0] == 0x0 || buf_rx->data[0] == 0x80)) {
			/* Flip highest bit in lowest byte of le32 */
			buf_rx->data[0] ^= 0x80;

			/* re-check CRC */
			err = mcp251xfd_regmap_crc_read_check_crc(buf_rx,
								  buf_tx,
								  val_len);
			if (!err) {
				/* If CRC is now correct, assume
				 * transferred data was OK, flip bit
				 * back to original value.
				 */
				buf_rx->data[0] ^= 0x80;
				goto out;
			}
		}

		/* MCP251XFD_REG_OSC is the first ever reg we read from.
		 *
		 * The chip may be in deep sleep and this SPI transfer