Commit 71a50419 authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-fixes-for-5.9-20200815' of...

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

Marc Kleine-Budde says:

====================
pull-request: can 2020-08-15

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

All patches are by Zhang Changzhong and fix broadcast related problems in the
j1939 CAN networking stack.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 55eff0eb 0ae18a82
...@@ -723,10 +723,12 @@ static int j1939_session_tx_rts(struct j1939_session *session) ...@@ -723,10 +723,12 @@ static int j1939_session_tx_rts(struct j1939_session *session)
return ret; return ret;
session->last_txcmd = dat[0]; session->last_txcmd = dat[0];
if (dat[0] == J1939_TP_CMD_BAM) if (dat[0] == J1939_TP_CMD_BAM) {
j1939_tp_schedule_txtimer(session, 50); j1939_tp_schedule_txtimer(session, 50);
j1939_tp_set_rxtimeout(session, 250);
j1939_tp_set_rxtimeout(session, 1250); } else {
j1939_tp_set_rxtimeout(session, 1250);
}
netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
...@@ -1074,9 +1076,9 @@ static void __j1939_session_cancel(struct j1939_session *session, ...@@ -1074,9 +1076,9 @@ static void __j1939_session_cancel(struct j1939_session *session,
lockdep_assert_held(&session->priv->active_session_list_lock); lockdep_assert_held(&session->priv->active_session_list_lock);
session->err = j1939_xtp_abort_to_errno(priv, err); session->err = j1939_xtp_abort_to_errno(priv, err);
session->state = J1939_SESSION_WAITING_ABORT;
/* do not send aborts on incoming broadcasts */ /* do not send aborts on incoming broadcasts */
if (!j1939_cb_is_broadcast(&session->skcb)) { if (!j1939_cb_is_broadcast(&session->skcb)) {
session->state = J1939_SESSION_WAITING_ABORT;
j1939_xtp_tx_abort(priv, &session->skcb, j1939_xtp_tx_abort(priv, &session->skcb,
!session->transmission, !session->transmission,
err, session->skcb.addr.pgn); err, session->skcb.addr.pgn);
...@@ -1673,8 +1675,12 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb, ...@@ -1673,8 +1675,12 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
return; return;
} }
session = j1939_xtp_rx_rts_session_new(priv, skb); session = j1939_xtp_rx_rts_session_new(priv, skb);
if (!session) if (!session) {
if (cmd == J1939_TP_CMD_BAM && j1939_sk_recv_match(priv, skcb))
netdev_info(priv->ndev, "%s: failed to create TP BAM session\n",
__func__);
return; return;
}
} else { } else {
if (j1939_xtp_rx_rts_session_active(session, skb)) { if (j1939_xtp_rx_rts_session_active(session, skb)) {
j1939_session_put(session); j1939_session_put(session);
...@@ -1683,11 +1689,15 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb, ...@@ -1683,11 +1689,15 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
} }
session->last_cmd = cmd; session->last_cmd = cmd;
j1939_tp_set_rxtimeout(session, 1250); if (cmd == J1939_TP_CMD_BAM) {
if (!session->transmission)
if (cmd != J1939_TP_CMD_BAM && !session->transmission) { j1939_tp_set_rxtimeout(session, 750);
j1939_session_txtimer_cancel(session); } else {
j1939_tp_schedule_txtimer(session, 0); if (!session->transmission) {
j1939_session_txtimer_cancel(session);
j1939_tp_schedule_txtimer(session, 0);
}
j1939_tp_set_rxtimeout(session, 1250);
} }
j1939_session_put(session); j1939_session_put(session);
...@@ -1738,6 +1748,7 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session, ...@@ -1738,6 +1748,7 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
int offset; int offset;
int nbytes; int nbytes;
bool final = false; bool final = false;
bool remain = false;
bool do_cts_eoma = false; bool do_cts_eoma = false;
int packet; int packet;
...@@ -1813,6 +1824,8 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session, ...@@ -1813,6 +1824,8 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
j1939_cb_is_broadcast(&session->skcb)) { j1939_cb_is_broadcast(&session->skcb)) {
if (session->pkt.rx >= session->pkt.total) if (session->pkt.rx >= session->pkt.total)
final = true; final = true;
else
remain = true;
} else { } else {
/* never final, an EOMA must follow */ /* never final, an EOMA must follow */
if (session->pkt.rx >= session->pkt.last) if (session->pkt.rx >= session->pkt.last)
...@@ -1820,7 +1833,11 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session, ...@@ -1820,7 +1833,11 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
} }
if (final) { if (final) {
j1939_session_timers_cancel(session);
j1939_session_completed(session); j1939_session_completed(session);
} else if (remain) {
if (!session->transmission)
j1939_tp_set_rxtimeout(session, 750);
} else if (do_cts_eoma) { } else if (do_cts_eoma) {
j1939_tp_set_rxtimeout(session, 1250); j1939_tp_set_rxtimeout(session, 1250);
if (!session->transmission) if (!session->transmission)
...@@ -1865,6 +1882,13 @@ static void j1939_xtp_rx_dat(struct j1939_priv *priv, struct sk_buff *skb) ...@@ -1865,6 +1882,13 @@ static void j1939_xtp_rx_dat(struct j1939_priv *priv, struct sk_buff *skb)
else else
j1939_xtp_rx_dat_one(session, skb); j1939_xtp_rx_dat_one(session, skb);
} }
if (j1939_cb_is_broadcast(skcb)) {
session = j1939_session_get_by_addr(priv, &skcb->addr, false,
false);
if (session)
j1939_xtp_rx_dat_one(session, skb);
}
} }
/* j1939 main intf */ /* j1939 main intf */
...@@ -1956,7 +1980,7 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb) ...@@ -1956,7 +1980,7 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb)
if (j1939_tp_im_transmitter(skcb)) if (j1939_tp_im_transmitter(skcb))
j1939_xtp_rx_rts(priv, skb, true); j1939_xtp_rx_rts(priv, skb, true);
if (j1939_tp_im_receiver(skcb)) if (j1939_tp_im_receiver(skcb) || j1939_cb_is_broadcast(skcb))
j1939_xtp_rx_rts(priv, skb, false); j1939_xtp_rx_rts(priv, skb, false);
break; break;
...@@ -2020,7 +2044,7 @@ int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb) ...@@ -2020,7 +2044,7 @@ int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb)
{ {
struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb); struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
if (!j1939_tp_im_involved_anydir(skcb)) if (!j1939_tp_im_involved_anydir(skcb) && !j1939_cb_is_broadcast(skcb))
return 0; return 0;
switch (skcb->addr.pgn) { switch (skcb->addr.pgn) {
......
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