mirror of https://gitee.com/openkylin/linux.git
linux-can-next-for-5.13-20210407
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEK3kIWJt9yTYMP3ehqclaivrt76kFAmBtX9oTHG1rbEBwZW5n dXRyb25peC5kZQAKCRCpyVqK+u3vqTNvB/0RHn+yoXjr0C/DjgfIAXtBZy9HMmA+ ZmNFrF3Is3dLaDkEv2FRTVpJlexRtBqlex+Ca6RCDo16/rR++JU9HWXiJaEp0Upx Oc4HPxtnjRne8NJGsbi9tnaQ8o6IazAEr4+vS4r7dOf2flSOfDfo0UMMGNHrG6r9 KrLcSCUf/hM353G68oVWXRtaxDYWW8ueAp6m5Qmo6JeSCkLNYvQjyLtqOV9toer6 9U3zvsF4VGkQdO/JiXXarO7fXjlCq/n8822z+L/YeN1DrSHjCGZ1vn+lnMrpeA7F 7X7vLv7rtfrF+r+OJTBiW+OklsQMvw+cMaCcn2eMON4zNQ7o8jmLALiF =69Yd -----END PGP SIGNATURE----- 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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
33b32a2984
|
@ -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)
|
||||
|
|
|
@ -233,20 +233,11 @@ mcp251xfd_regmap_crc_write(void *context,
|
|||
}
|
||||
|
||||
static int
|
||||
mcp251xfd_regmap_crc_read_one(struct mcp251xfd_priv *priv,
|
||||
struct spi_message *msg, unsigned int data_len)
|
||||
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)
|
||||
{
|
||||
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));
|
||||
BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));
|
||||
|
||||
err = spi_sync(priv->spi, msg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
crc_received = get_unaligned_be16(buf_rx->data + data_len);
|
||||
crc_calculated = mcp251xfd_crc16_compute2(&buf_tx->cmd,
|
||||
|
@ -259,6 +250,25 @@ mcp251xfd_regmap_crc_read_one(struct mcp251xfd_priv *priv,
|
|||
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;
|
||||
int err;
|
||||
|
||||
BUILD_BUG_ON(sizeof(buf_rx->cmd) != sizeof(__be16) + sizeof(u8));
|
||||
BUILD_BUG_ON(sizeof(buf_tx->cmd) != sizeof(__be16) + sizeof(u8));
|
||||
|
||||
err = spi_sync(priv->spi, msg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return mcp251xfd_regmap_crc_read_check_crc(buf_rx, buf_tx, data_len);
|
||||
}
|
||||
|
||||
static int
|
||||
mcp251xfd_regmap_crc_read(void *context,
|
||||
const void *reg_p, size_t reg_len,
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue