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:
Коммит
2eb4898255
|
@ -701,7 +701,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv)
|
|||
u32 reg;
|
||||
|
||||
reg = priv->read(®s->mcr);
|
||||
reg |= FLEXCAN_MCR_HALT;
|
||||
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT;
|
||||
priv->write(reg, ®s->mcr);
|
||||
|
||||
while (timeout-- && !(priv->read(®s->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(®s->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(®s->mcr);
|
||||
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
|
||||
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
|
||||
reg |= FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
|
||||
priv->write(reg, ®s->mcr);
|
||||
|
||||
/* Currently we only support newer versions of this core
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче