Commit 0ae18a82 authored by Zhang Changzhong's avatar Zhang Changzhong Committed by Marc Kleine-Budde

can: j1939: add rxtimer for multipacket broadcast session

According to SAE J1939/21 (Chapter 5.12.3 and APPENDIX C), for transmit side
the required time interval between packets of a multipacket broadcast message
is 50 to 200 ms, the responder shall use a timeout of 250ms (provides margin
allowing for the maximumm spacing of 200ms). For receive side a timeout will
occur when a time of greater than 750 ms elapsed between two message packets
when more packets were expected.

So this patch fix and add rxtimer for multipacket broadcast session.

Fixes: 9d71dd0c ("can: add support of SAE J1939 protocol")
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
Link: https://lore.kernel.org/r/1596599425-5534-5-git-send-email-zhangchangzhong@huawei.comAcked-by: default avatarOleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 2b8b2e31
......@@ -723,10 +723,12 @@ static int j1939_session_tx_rts(struct j1939_session *session)
return ret;
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_set_rxtimeout(session, 250);
} else {
j1939_tp_set_rxtimeout(session, 1250);
}
netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
......@@ -1687,12 +1689,16 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
}
session->last_cmd = cmd;
j1939_tp_set_rxtimeout(session, 1250);
if (cmd != J1939_TP_CMD_BAM && !session->transmission) {
if (cmd == J1939_TP_CMD_BAM) {
if (!session->transmission)
j1939_tp_set_rxtimeout(session, 750);
} else {
if (!session->transmission) {
j1939_session_txtimer_cancel(session);
j1939_tp_schedule_txtimer(session, 0);
}
j1939_tp_set_rxtimeout(session, 1250);
}
j1939_session_put(session);
}
......@@ -1742,6 +1748,7 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
int offset;
int nbytes;
bool final = false;
bool remain = false;
bool do_cts_eoma = false;
int packet;
......@@ -1817,6 +1824,8 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
j1939_cb_is_broadcast(&session->skcb)) {
if (session->pkt.rx >= session->pkt.total)
final = true;
else
remain = true;
} else {
/* never final, an EOMA must follow */
if (session->pkt.rx >= session->pkt.last)
......@@ -1826,6 +1835,9 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
if (final) {
j1939_session_timers_cancel(session);
j1939_session_completed(session);
} else if (remain) {
if (!session->transmission)
j1939_tp_set_rxtimeout(session, 750);
} else if (do_cts_eoma) {
j1939_tp_set_rxtimeout(session, 1250);
if (!session->transmission)
......
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