Commit 2eb48982 authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-fixes-for-5.12-20210301' of...

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 8a00946e 27126252
...@@ -701,7 +701,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv) ...@@ -701,7 +701,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
u32 reg; u32 reg;
reg = priv->read(&regs->mcr); reg = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_HALT; reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT;
priv->write(reg, &regs->mcr); priv->write(reg, &regs->mcr);
while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)) while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
...@@ -1480,10 +1480,13 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -1480,10 +1480,13 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_set_bittiming(dev); flexcan_set_bittiming(dev);
/* set freeze, halt */
err = flexcan_chip_freeze(priv);
if (err)
goto out_chip_disable;
/* MCR /* MCR
* *
* enable freeze
* halt now
* only supervisor access * only supervisor access
* enable warning int * enable warning int
* enable individual RX masking * enable individual RX masking
...@@ -1492,9 +1495,8 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -1492,9 +1495,8 @@ static int flexcan_chip_start(struct net_device *dev)
*/ */
reg_mcr = priv->read(&regs->mcr); reg_mcr = priv->read(&regs->mcr);
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | reg_mcr |= FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ |
FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
/* MCR /* MCR
* *
...@@ -1865,10 +1867,14 @@ static int register_flexcandev(struct net_device *dev) ...@@ -1865,10 +1867,14 @@ static int register_flexcandev(struct net_device *dev)
if (err) if (err)
goto out_chip_disable; 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 = priv->read(&regs->mcr);
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | reg |= FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
priv->write(reg, &regs->mcr); priv->write(reg, &regs->mcr);
/* Currently we only support newer versions of this core /* Currently we only support newer versions of this core
......
...@@ -237,14 +237,14 @@ static int tcan4x5x_init(struct m_can_classdev *cdev) ...@@ -237,14 +237,14 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
if (ret) if (ret)
return ret; return ret;
/* Zero out the MCAN buffers */
m_can_init_ram(cdev);
ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL); TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL);
if (ret) if (ret)
return ret; return ret;
/* Zero out the MCAN buffers */
m_can_init_ram(cdev);
return ret; return ret;
} }
......
...@@ -335,8 +335,6 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv) ...@@ -335,8 +335,6 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
u8 len; u8 len;
int i, j; int i, j;
netdev_reset_queue(priv->ndev);
/* TEF */ /* TEF */
tef_ring = priv->tef; tef_ring = priv->tef;
tef_ring->head = 0; tef_ring->head = 0;
...@@ -1249,8 +1247,7 @@ mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq) ...@@ -1249,8 +1247,7 @@ mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)
static int static int
mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, 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 net_device_stats *stats = &priv->ndev->stats;
u32 seq, seq_masked, tef_tail_masked; u32 seq, seq_masked, tef_tail_masked;
...@@ -1272,8 +1269,7 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, ...@@ -1272,8 +1269,7 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
stats->tx_bytes += stats->tx_bytes +=
can_rx_offload_get_echo_skb(&priv->offload, can_rx_offload_get_echo_skb(&priv->offload,
mcp251xfd_get_tef_tail(priv), mcp251xfd_get_tef_tail(priv),
hw_tef_obj->ts, hw_tef_obj->ts, NULL);
frame_len_ptr);
stats->tx_packets++; stats->tx_packets++;
priv->tef->tail++; priv->tef->tail++;
...@@ -1331,7 +1327,6 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv, ...@@ -1331,7 +1327,6 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv,
static int mcp251xfd_handle_tefif(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]; struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX];
unsigned int total_frame_len = 0;
u8 tef_tail, len, l; u8 tef_tail, len, l;
int err, i; int err, i;
...@@ -1353,9 +1348,7 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) ...@@ -1353,9 +1348,7 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
} }
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
unsigned int frame_len; err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i]);
err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
/* -EAGAIN means the Sequence Number in the TEF /* -EAGAIN means the Sequence Number in the TEF
* doesn't match our tef_tail. This can happen if we * doesn't match our tef_tail. This can happen if we
* read the TEF objects too early. Leave loop let the * read the TEF objects too early. Leave loop let the
...@@ -1365,8 +1358,6 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) ...@@ -1365,8 +1358,6 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
goto out_netif_wake_queue; goto out_netif_wake_queue;
if (err) if (err)
return err; return err;
total_frame_len += frame_len;
} }
out_netif_wake_queue: out_netif_wake_queue:
...@@ -1397,7 +1388,6 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) ...@@ -1397,7 +1388,6 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
return err; return err;
tx_ring->tail += len; tx_ring->tail += len;
netdev_completed_queue(priv->ndev, len, total_frame_len);
err = mcp251xfd_check_tef_tail(priv); err = mcp251xfd_check_tef_tail(priv);
if (err) if (err)
...@@ -2443,7 +2433,6 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, ...@@ -2443,7 +2433,6 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
struct mcp251xfd_priv *priv = netdev_priv(ndev); struct mcp251xfd_priv *priv = netdev_priv(ndev);
struct mcp251xfd_tx_ring *tx_ring = priv->tx; struct mcp251xfd_tx_ring *tx_ring = priv->tx;
struct mcp251xfd_tx_obj *tx_obj; struct mcp251xfd_tx_obj *tx_obj;
unsigned int frame_len;
u8 tx_head; u8 tx_head;
int err; int err;
...@@ -2462,9 +2451,7 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, ...@@ -2462,9 +2451,7 @@ static netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
if (mcp251xfd_get_tx_free(tx_ring) == 0) if (mcp251xfd_get_tx_free(tx_ring) == 0)
netif_stop_queue(ndev); netif_stop_queue(ndev);
frame_len = can_skb_get_frame_len(skb); can_put_echo_skb(skb, ndev, tx_head, 0);
can_put_echo_skb(skb, ndev, tx_head, frame_len);
netdev_sent_queue(priv->ndev, frame_len);
err = mcp251xfd_tx_obj_write(priv, tx_obj); err = mcp251xfd_tx_obj_write(priv, tx_obj);
if (err) if (err)
......
...@@ -65,8 +65,12 @@ static inline void can_skb_reserve(struct sk_buff *skb) ...@@ -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) static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk)
{ {
if (sk) { /* If the socket has already been closed by user space, the
sock_hold(sk); * 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->destructor = sock_efree;
skb->sk = sk; skb->sk = sk;
} }
......
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