If CAN bus is broken we won't be able to get loop back abort signal from the bus. So, use rxtimer to force abort directly. Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> --- net/can/j1939/j1939-priv.h | 3 +++ net/can/j1939/transport.c | 27 +++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/net/can/j1939/j1939-priv.h b/net/can/j1939/j1939-priv.h index 9ebb2c74f4f6..6f7abd12bc54 100644 --- a/net/can/j1939/j1939-priv.h +++ b/net/can/j1939/j1939-priv.h @@ -208,6 +208,9 @@ void j1939_sock_pending_del(struct sock *sk); enum j1939_session_state { J1939_SESSION_NEW, J1939_SESSION_ACTIVE, + /* waiting for abort signal on the bus */ + J1939_SESSION_WAITING_ABORT, + J1939_SESSION_ACTIVE_MAX, J1939_SESSION_DONE, }; diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c index 06b77de6aa85..cd68b98fee92 100644 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -833,7 +833,8 @@ bool j1939_session_deactivate(struct j1939_session *session) bool active = false; j1939_session_list_lock(session->priv); - if (session->state == J1939_SESSION_ACTIVE) { + if (session->state >= J1939_SESSION_ACTIVE && + session->state < J1939_SESSION_ACTIVE_MAX) { active = true; list_del_init(&session->active_session_list_entry); @@ -934,9 +935,27 @@ static enum hrtimer_restart j1939_tp_rxtimer(struct hrtimer *hrtimer) rxtimer); struct j1939_priv *priv = session->priv; - netdev_alert(priv->ndev, "%s: timeout\n", __func__); - j1939_session_txtimer_cancel(session); - j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT); + if (session->state == J1939_SESSION_WAITING_ABORT) { + netdev_alert(priv->ndev, "%s: abort rx timeout. Force session deactivation\n", + __func__); + + j1939_session_deactivate_activate_next(session); + } else { + netdev_alert(priv->ndev, "%s: rx timeout, send abort\n", + __func__); + + j1939_session_list_lock(session->priv); + if (session->state >= J1939_SESSION_ACTIVE && + session->state < J1939_SESSION_ACTIVE_MAX) { + session->state = J1939_SESSION_WAITING_ABORT; + j1939_session_get(session); + hrtimer_start(&session->rxtimer, ms_to_ktime(1250), + HRTIMER_MODE_REL_SOFT); + j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT); + } + j1939_session_list_unlock(session->priv); + } + j1939_session_put(session); return HRTIMER_NORESTART; -- 2.20.1