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

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.com


Acked-by: default avatarOleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 2b8b2e31
Loading
Loading
Loading
Loading
+20 −8
Original line number Diff line number Diff line
@@ -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)