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

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
......@@ -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,
};
......
......@@ -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;
......
......@@ -466,10 +466,17 @@ 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)
......
......@@ -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)
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment