linux-can-fixes-for-5.12-20210301

-----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEEK3kIWJt9yTYMP3ehqclaivrt76kFAmA8xfATHG1rbEBwZW5n
 dXRyb25peC5kZQAKCRCpyVqK+u3vqZzcB/9LC7BTXmD2S5YMUvbH8Dy1XQ1J/Ss5
 VPiT+6eNCxFhl9YzsWXPhhvNg7WYLa5SbWid/yht7UAxgiibtB7COaePeuzTSmtQ
 OaTp1J0QcTnaXVWv2GdUnYu0S3xpIyHmvkUQND7AlIfdQg3evKiN+J3JhrO30mVx
 zLhf+gtZUU48fY/DSD7YgwsRv6+L8FFRgxcPlz5QXS3VJOo3Tic4VEjGBWaGrn0U
 xxuRsjBIPXGBYAhru3TOWuDarLWmEFDL2m6s+hPZG1YLAuuAqLiDKdXKzLjwI8mh
 yfgcnaSS8Mdrd4vjPyhSmr3pULi1Ac8BFhQkGPysJIad0/25eiuMBUZI
 =iiwZ
 -----END PGP SIGNATURE-----

Merge tag 'linux-can-fixes-for-5.12-20210301' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2021-03-01

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

The first 3 patches are by Joakim Zhang for the flexcan driver and fix
the probing and starting of the chip.

The next patch is by me, for the mcp251xfd driver and reverts the BQL
support. BQL support got mainline with rc1 and assumes that CAN frames
are always echoed, which is not the case. A proper fix requires
changes more changes and will be rolled out via linux-can-next later.

Oleksij Rempel's patch fixes the socket ref counting if socket was
closed before setting skb ownership.

Torin Cooper-Bennun's patch for the tcan4x5x driver fixes a race
condition, where the chip is first attached the bus and then the MRAM
is initialized, which may result in lost data.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2021-03-01 13:37:08 -08:00
commit 2eb4898255
4 changed files with 28 additions and 31 deletions

View File

@ -701,7 +701,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
u32 reg;
reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_HALT;
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT;
priv->write(reg, &regs->mcr);
while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
@ -1480,10 +1480,13 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_set_bittiming(dev);
/* set freeze, halt */
err = flexcan_chip_freeze(priv);
if (err)
goto out_chip_disable;
/* MCR
*
* enable freeze
* halt now
* only supervisor access
* enable warning int
* enable individual RX masking
@ -1492,9 +1495,8 @@ static int flexcan_chip_start(struct net_device *dev)
*/
reg_mcr = priv->read(&regs->mcr);
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C |
FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
reg_mcr |= FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ |
FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
/* MCR
*
@ -1865,10 +1867,14 @@ static int register_flexcandev(struct net_device *dev)
if (err)
goto out_chip_disable;
/* set freeze, halt and activate FIFO, restrict register access */
/* set freeze, halt */
err = flexcan_chip_freeze(priv);
if (err)
goto out_chip_disable;
/* activate FIFO, restrict register access */
reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
reg |= FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
priv->write(reg, &regs->mcr);
/* Currently we only support newer versions of this core

View File

@ -237,14 +237,14 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
if (ret)
return ret;
/* Zero out the MCAN buffers */
m_can_init_ram(cdev);
ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL);
if (ret)
return ret;
/* Zero out the MCAN buffers */
m_can_init_ram(cdev);
return ret;
}

View File

@ -335,8 +335,6 @@ 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;
@ -1249,8 +1247,7 @@ 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,
unsigned int *frame_len_ptr)
const struct mcp251xfd_hw_tef_obj *hw_tef_obj)
{
struct net_device_stats *stats = &priv->ndev->stats;
u32 seq, seq_masked, tef_tail_masked;
@ -1272,8 +1269,7 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
stats->tx_bytes +=
can_rx_offload_get_echo_skb(&priv->offload,
mcp251xfd_get_tef_tail(priv),
hw_tef_obj->ts,
frame_len_ptr);
hw_tef_obj->ts, NULL);
stats->tx_packets++;
priv->tef->tail++;
@ -1331,7 +1327,6 @@ 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;
@ -1353,9 +1348,7 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
}
for (i = 0; i < len; i++) {
unsigned int frame_len;
err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i]);
/* -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
@ -1365,8 +1358,6 @@ 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:
@ -1397,7 +1388,6 @@ 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)
@ -2443,7 +2433,6 @@ 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;
@ -2462,9 +2451,7 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
if (mcp251xfd_get_tx_free(tx_ring) == 0)
netif_stop_queue(ndev);
frame_len = can_skb_get_frame_len(skb);
can_put_echo_skb(skb, ndev, tx_head, frame_len);
netdev_sent_queue(priv->ndev, frame_len);
can_put_echo_skb(skb, ndev, tx_head, 0);
err = mcp251xfd_tx_obj_write(priv, tx_obj);
if (err)

View File

@ -65,8 +65,12 @@ static inline void can_skb_reserve(struct sk_buff *skb)
static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk)
{
if (sk) {
sock_hold(sk);
/* If the socket has already been closed by user space, the
* refcount may already be 0 (and the socket will be freed
* after the last TX skb has been freed). So only increase
* socket refcount if the refcount is > 0.
*/
if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) {
skb->destructor = sock_efree;
skb->sk = sk;
}