^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (c) 2010-2011 EIA Electronics,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Kurt Van Dijck <kurt.van.dijck@eia.be>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Copyright (c) 2018 Protonic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Robin van der Gracht <robin@protonic.nl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Copyright (c) 2017-2019 Pengutronix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Marc Kleine-Budde <kernel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // Copyright (c) 2017-2019 Pengutronix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) // Oleksij Rempel <kernel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/can/skb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "j1939-priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define J1939_XTP_TX_RETRY_LIMIT 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define J1939_ETP_PGN_CTL 0xc800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define J1939_ETP_PGN_DAT 0xc700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define J1939_TP_PGN_CTL 0xec00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define J1939_TP_PGN_DAT 0xeb00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define J1939_TP_CMD_RTS 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define J1939_TP_CMD_CTS 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define J1939_TP_CMD_EOMA 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define J1939_TP_CMD_BAM 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define J1939_TP_CMD_ABORT 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define J1939_ETP_CMD_RTS 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define J1939_ETP_CMD_CTS 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define J1939_ETP_CMD_DPO 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define J1939_ETP_CMD_EOMA 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define J1939_ETP_CMD_ABORT 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) enum j1939_xtp_abort {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) J1939_XTP_NO_ABORT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) J1939_XTP_ABORT_BUSY = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Already in one or more connection managed sessions and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * cannot support another.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * EALREADY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Operation already in progress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) J1939_XTP_ABORT_RESOURCE = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* System resources were needed for another task so this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * connection managed session was terminated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * EMSGSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * The socket type requires that message be sent atomically,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * and the size of the message to be sent made this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * impossible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) J1939_XTP_ABORT_TIMEOUT = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* A timeout occurred and this is the connection abort to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * close the session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * EHOSTUNREACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * The destination host cannot be reached (probably because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * the host is down or a remote router cannot reach it).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) J1939_XTP_ABORT_GENERIC = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* CTS messages received when data transfer is in progress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * EBADMSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Not a data message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) J1939_XTP_ABORT_FAULT = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Maximal retransmit request limit reached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * ENOTRECOVERABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * State not recoverable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) J1939_XTP_ABORT_UNEXPECTED_DATA = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Unexpected data transfer packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * ENOTCONN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Transport endpoint is not connected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) J1939_XTP_ABORT_BAD_SEQ = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* Bad sequence number (and software is not able to recover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * EILSEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Illegal byte sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) J1939_XTP_ABORT_DUP_SEQ = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Duplicate sequence number (and software is not able to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * recover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) J1939_XTP_ABORT_EDPO_UNEXPECTED = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* Unexpected EDPO packet (ETP) or Message size > 1785 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * (TP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) J1939_XTP_ABORT_BAD_EDPO_PGN = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Unexpected EDPO PGN (PGN in EDPO is bad) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) J1939_XTP_ABORT_EDPO_OUTOF_CTS = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* EDPO number of packets is greater than CTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) J1939_XTP_ABORT_BAD_EDPO_OFFSET = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Bad EDPO offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) J1939_XTP_ABORT_OTHER_DEPRECATED = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Deprecated. Use 250 instead (Any other reason) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) J1939_XTP_ABORT_ECTS_UNXPECTED_PGN = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Unexpected ECTS PGN (PGN in ECTS is bad) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) J1939_XTP_ABORT_ECTS_TOO_BIG = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* ECTS requested packets exceeds message size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) J1939_XTP_ABORT_OTHER = 250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Any other reason (if a Connection Abort reason is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * identified that is not listed in the table use code 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static unsigned int j1939_tp_block = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static unsigned int j1939_tp_packet_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static unsigned int j1939_tp_padding = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static const char *j1939_xtp_abort_to_str(enum j1939_xtp_abort abort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) switch (abort) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case J1939_XTP_ABORT_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return "Already in one or more connection managed sessions and cannot support another.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) case J1939_XTP_ABORT_RESOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return "System resources were needed for another task so this connection managed session was terminated.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case J1939_XTP_ABORT_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return "A timeout occurred and this is the connection abort to close the session.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case J1939_XTP_ABORT_GENERIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return "CTS messages received when data transfer is in progress";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case J1939_XTP_ABORT_FAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return "Maximal retransmit request limit reached";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case J1939_XTP_ABORT_UNEXPECTED_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return "Unexpected data transfer packet";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case J1939_XTP_ABORT_BAD_SEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return "Bad sequence number (and software is not able to recover)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case J1939_XTP_ABORT_DUP_SEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return "Duplicate sequence number (and software is not able to recover)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case J1939_XTP_ABORT_EDPO_UNEXPECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return "Unexpected EDPO packet (ETP) or Message size > 1785 bytes (TP)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) case J1939_XTP_ABORT_BAD_EDPO_PGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return "Unexpected EDPO PGN (PGN in EDPO is bad)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case J1939_XTP_ABORT_EDPO_OUTOF_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return "EDPO number of packets is greater than CTS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case J1939_XTP_ABORT_BAD_EDPO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return "Bad EDPO offset";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case J1939_XTP_ABORT_OTHER_DEPRECATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return "Deprecated. Use 250 instead (Any other reason)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case J1939_XTP_ABORT_ECTS_UNXPECTED_PGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return "Unexpected ECTS PGN (PGN in ECTS is bad)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case J1939_XTP_ABORT_ECTS_TOO_BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return "ECTS requested packets exceeds message size";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) case J1939_XTP_ABORT_OTHER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return "Any other reason (if a Connection Abort reason is identified that is not listed in the table use code 250)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return "<unknown>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int j1939_xtp_abort_to_errno(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) enum j1939_xtp_abort abort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) switch (abort) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case J1939_XTP_NO_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) WARN_ON_ONCE(abort == J1939_XTP_NO_ABORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) case J1939_XTP_ABORT_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) err = EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case J1939_XTP_ABORT_RESOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) err = EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case J1939_XTP_ABORT_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) err = EHOSTUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case J1939_XTP_ABORT_GENERIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) err = EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case J1939_XTP_ABORT_FAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) err = ENOTRECOVERABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case J1939_XTP_ABORT_UNEXPECTED_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) err = ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case J1939_XTP_ABORT_BAD_SEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) err = EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case J1939_XTP_ABORT_DUP_SEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case J1939_XTP_ABORT_EDPO_UNEXPECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) case J1939_XTP_ABORT_BAD_EDPO_PGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case J1939_XTP_ABORT_EDPO_OUTOF_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case J1939_XTP_ABORT_BAD_EDPO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case J1939_XTP_ABORT_OTHER_DEPRECATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case J1939_XTP_ABORT_ECTS_UNXPECTED_PGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case J1939_XTP_ABORT_ECTS_TOO_BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case J1939_XTP_ABORT_OTHER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) netdev_warn(priv->ndev, "Unknown abort code %i", abort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) err = EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static inline void j1939_session_list_lock(struct j1939_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) spin_lock_bh(&priv->active_session_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static inline void j1939_session_list_unlock(struct j1939_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) spin_unlock_bh(&priv->active_session_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void j1939_session_get(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) kref_get(&session->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* session completion functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static void __j1939_session_drop(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!session->transmission)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) j1939_sock_pending_del(session->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) sock_put(session->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static void j1939_session_destroy(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (session->err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) j1939_sk_errqueue(session, J1939_ERRQUEUE_ABORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) j1939_sk_errqueue(session, J1939_ERRQUEUE_ACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) WARN_ON_ONCE(!list_empty(&session->sk_session_queue_entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) WARN_ON_ONCE(!list_empty(&session->active_session_list_entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) skb_queue_purge(&session->skb_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) __j1939_session_drop(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) j1939_priv_put(session->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) kfree(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void __j1939_session_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct j1939_session *session = container_of(kref, struct j1939_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) j1939_session_destroy(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) void j1939_session_put(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) kref_put(&session->kref, __j1939_session_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static void j1939_session_txtimer_cancel(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (hrtimer_cancel(&session->txtimer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static void j1939_session_rxtimer_cancel(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (hrtimer_cancel(&session->rxtimer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void j1939_session_timers_cancel(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) j1939_session_txtimer_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) j1939_session_rxtimer_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static inline bool j1939_cb_is_broadcast(const struct j1939_sk_buff_cb *skcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return (!skcb->addr.dst_name && (skcb->addr.da == 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static void j1939_session_skb_drop_old(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct sk_buff *do_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct j1939_sk_buff_cb *do_skcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) unsigned int offset_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (skb_queue_len(&session->skb_queue) < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) offset_start = session->pkt.tx_acked * 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) spin_lock_irqsave(&session->skb_queue.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) do_skb = skb_peek(&session->skb_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) do_skcb = j1939_skb_to_cb(do_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if ((do_skcb->offset + do_skb->len) < offset_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) __skb_unlink(do_skb, &session->skb_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* drop ref taken in j1939_session_skb_queue() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) skb_unref(do_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) kfree_skb(do_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) spin_unlock_irqrestore(&session->skb_queue.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) void j1939_session_skb_queue(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) j1939_ac_fixup(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (j1939_address_is_unicast(skcb->addr.da) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) priv->ents[skcb->addr.da].nusers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) skcb->flags |= J1939_ECU_LOCAL_DST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) skcb->flags |= J1939_ECU_LOCAL_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) skb_get(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) skb_queue_tail(&session->skb_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) sk_buff *j1939_session_skb_get_by_offset(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) unsigned int offset_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct j1939_sk_buff_cb *do_skcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct sk_buff *do_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) spin_lock_irqsave(&session->skb_queue.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) skb_queue_walk(&session->skb_queue, do_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) do_skcb = j1939_skb_to_cb(do_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (offset_start >= do_skcb->offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) offset_start < (do_skcb->offset + do_skb->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) skb = do_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) skb_get(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) spin_unlock_irqrestore(&session->skb_queue.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) netdev_dbg(priv->ndev, "%s: 0x%p: no skb found for start: %i, queue size: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) __func__, session, offset_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) skb_queue_len(&session->skb_queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static struct sk_buff *j1939_session_skb_get(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) unsigned int offset_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) offset_start = session->pkt.dpo * 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return j1939_session_skb_get_by_offset(session, offset_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* see if we are receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * returns 0 for broadcasts, although we will receive them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static inline int j1939_tp_im_receiver(const struct j1939_sk_buff_cb *skcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return skcb->flags & J1939_ECU_LOCAL_DST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* see if we are sender */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static inline int j1939_tp_im_transmitter(const struct j1939_sk_buff_cb *skcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return skcb->flags & J1939_ECU_LOCAL_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* see if we are involved as either receiver or transmitter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int j1939_tp_im_involved(const struct j1939_sk_buff_cb *skcb, bool swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return j1939_tp_im_receiver(skcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return j1939_tp_im_transmitter(skcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int j1939_tp_im_involved_anydir(struct j1939_sk_buff_cb *skcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return skcb->flags & (J1939_ECU_LOCAL_SRC | J1939_ECU_LOCAL_DST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* extract pgn from flow-ctl message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static inline pgn_t j1939_xtp_ctl_to_pgn(const u8 *dat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) pgn_t pgn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) pgn = (dat[7] << 16) | (dat[6] << 8) | (dat[5] << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (j1939_pgn_is_pdu1(pgn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) pgn &= 0xffff00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return pgn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static inline unsigned int j1939_tp_ctl_to_size(const u8 *dat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return (dat[2] << 8) + (dat[1] << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static inline unsigned int j1939_etp_ctl_to_packet(const u8 *dat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return (dat[4] << 16) | (dat[3] << 8) | (dat[2] << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static inline unsigned int j1939_etp_ctl_to_size(const u8 *dat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return (dat[4] << 24) | (dat[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) (dat[2] << 8) | (dat[1] << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* find existing session:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * reverse: swap cb's src & dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * there is no problem with matching broadcasts, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * broadcasts (no dst, no da) would never call this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * with reverse == true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static bool j1939_session_match(struct j1939_addr *se_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct j1939_addr *sk_addr, bool reverse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (se_addr->type != sk_addr->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (reverse) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (se_addr->src_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (se_addr->src_name != sk_addr->dst_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) } else if (se_addr->sa != sk_addr->da) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (se_addr->dst_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (se_addr->dst_name != sk_addr->src_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) } else if (se_addr->da != sk_addr->sa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (se_addr->src_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (se_addr->src_name != sk_addr->src_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) } else if (se_addr->sa != sk_addr->sa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (se_addr->dst_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (se_addr->dst_name != sk_addr->dst_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) } else if (se_addr->da != sk_addr->da) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) j1939_session *j1939_session_get_by_addr_locked(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct list_head *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct j1939_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) bool reverse, bool transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) lockdep_assert_held(&priv->active_session_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) list_for_each_entry(session, root, active_session_list_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) j1939_session_get(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (j1939_session_match(&session->skcb.addr, addr, reverse) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) session->transmission == transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) j1939_session *j1939_session_get_simple(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) lockdep_assert_held(&priv->active_session_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) list_for_each_entry(session, &priv->active_session_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) active_session_list_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) j1939_session_get(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (session->skcb.addr.type == J1939_SIMPLE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) session->tskey == skcb->tskey && session->sk == skb->sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) j1939_session *j1939_session_get_by_addr(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct j1939_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) bool reverse, bool transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) j1939_session_list_lock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) session = j1939_session_get_by_addr_locked(priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) &priv->active_session_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) addr, reverse, transmitter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) j1939_session_list_unlock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static void j1939_skbcb_swap(struct j1939_sk_buff_cb *skcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) u8 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) swap(skcb->addr.dst_name, skcb->addr.src_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) swap(skcb->addr.da, skcb->addr.sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* swap SRC and DST flags, leave other untouched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (skcb->flags & J1939_ECU_LOCAL_SRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) tmp |= J1939_ECU_LOCAL_DST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (skcb->flags & J1939_ECU_LOCAL_DST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) tmp |= J1939_ECU_LOCAL_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) skcb->flags &= ~(J1939_ECU_LOCAL_SRC | J1939_ECU_LOCAL_DST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) skcb->flags |= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) sk_buff *j1939_tp_tx_dat_new(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) const struct j1939_sk_buff_cb *re_skcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) bool ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) bool swap_src_dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct j1939_sk_buff_cb *skcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) skb = alloc_skb(sizeof(struct can_frame) + sizeof(struct can_skb_priv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (unlikely(!skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) skb->dev = priv->ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) can_skb_reserve(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) can_skb_prv(skb)->skbcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* reserve CAN header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) skb_reserve(skb, offsetof(struct can_frame, data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) memcpy(skb->cb, re_skcb, sizeof(skb->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (swap_src_dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) j1939_skbcb_swap(skcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (ctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (skcb->addr.type == J1939_ETP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) skcb->addr.pgn = J1939_ETP_PGN_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) skcb->addr.pgn = J1939_TP_PGN_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (skcb->addr.type == J1939_ETP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) skcb->addr.pgn = J1939_ETP_PGN_DAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) skcb->addr.pgn = J1939_TP_PGN_DAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /* TP transmit packet functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static int j1939_tp_tx_dat(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) const u8 *dat, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) skb = j1939_tp_tx_dat_new(priv, &session->skcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (IS_ERR(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) skb_put_data(skb, dat, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (j1939_tp_padding && len < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) memset(skb_put(skb, 8 - len), 0xff, 8 - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return j1939_send_one(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static int j1939_xtp_do_tx_ctl(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) const struct j1939_sk_buff_cb *re_skcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) bool swap_src_dst, pgn_t pgn, const u8 *dat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) u8 *skdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!j1939_tp_im_involved(re_skcb, swap_src_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) skb = j1939_tp_tx_dat_new(priv, re_skcb, true, swap_src_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (IS_ERR(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) skdat = skb_put(skb, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) memcpy(skdat, dat, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) skdat[5] = (pgn >> 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) skdat[6] = (pgn >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) skdat[7] = (pgn >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return j1939_send_one(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static inline int j1939_tp_tx_ctl(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) bool swap_src_dst, const u8 *dat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return j1939_xtp_do_tx_ctl(priv, &session->skcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) swap_src_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) session->skcb.addr.pgn, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int j1939_xtp_tx_abort(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) const struct j1939_sk_buff_cb *re_skcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) bool swap_src_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) enum j1939_xtp_abort err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) pgn_t pgn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) u8 dat[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (!j1939_tp_im_involved(re_skcb, swap_src_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) memset(dat, 0xff, sizeof(dat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) dat[0] = J1939_TP_CMD_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dat[1] = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return j1939_xtp_do_tx_ctl(priv, re_skcb, swap_src_dst, pgn, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) void j1939_tp_schedule_txtimer(struct j1939_session *session, int msec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) j1939_session_get(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) hrtimer_start(&session->txtimer, ms_to_ktime(msec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static inline void j1939_tp_set_rxtimeout(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int msec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) j1939_session_rxtimer_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) j1939_session_get(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) hrtimer_start(&session->rxtimer, ms_to_ktime(msec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static int j1939_session_tx_rts(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) u8 dat[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) memset(dat, 0xff, sizeof(dat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) dat[1] = (session->total_message_size >> 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dat[2] = (session->total_message_size >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) dat[3] = session->pkt.total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (session->skcb.addr.type == J1939_ETP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) dat[0] = J1939_ETP_CMD_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dat[1] = (session->total_message_size >> 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) dat[2] = (session->total_message_size >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) dat[3] = (session->total_message_size >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) dat[4] = (session->total_message_size >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) } else if (j1939_cb_is_broadcast(&session->skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dat[0] = J1939_TP_CMD_BAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* fake cts for broadcast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) session->pkt.tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) dat[0] = J1939_TP_CMD_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) dat[4] = dat[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (dat[0] == session->last_txcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /* done already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ret = j1939_tp_tx_ctl(session, false, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) session->last_txcmd = dat[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (dat[0] == J1939_TP_CMD_BAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) j1939_tp_schedule_txtimer(session, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) j1939_tp_set_rxtimeout(session, 250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) j1939_tp_set_rxtimeout(session, 1250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) static int j1939_session_tx_dpo(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) unsigned int pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) u8 dat[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) memset(dat, 0xff, sizeof(dat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) dat[0] = J1939_ETP_CMD_DPO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) session->pkt.dpo = session->pkt.tx_acked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) pkt = session->pkt.dpo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) dat[1] = session->pkt.last - session->pkt.tx_acked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) dat[2] = (pkt >> 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) dat[3] = (pkt >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) dat[4] = (pkt >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ret = j1939_tp_tx_ctl(session, false, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) session->last_txcmd = dat[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) j1939_tp_set_rxtimeout(session, 1250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) session->pkt.tx = session->pkt.tx_acked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static int j1939_session_tx_dat(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct j1939_sk_buff_cb *skcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) int offset, pkt_done, pkt_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) unsigned int len, pdelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct sk_buff *se_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) const u8 *tpdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) u8 dat[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) se_skb = j1939_session_skb_get_by_offset(session, session->pkt.tx * 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!se_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) skcb = j1939_skb_to_cb(se_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) tpdat = se_skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) pkt_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (session->skcb.addr.type != J1939_ETP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) j1939_cb_is_broadcast(&session->skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) pkt_end = session->pkt.total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pkt_end = session->pkt.last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) while (session->pkt.tx < pkt_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) dat[0] = session->pkt.tx - session->pkt.dpo + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) offset = (session->pkt.tx * 7) - skcb->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) len = se_skb->len - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (len > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) len = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (offset + len > se_skb->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) netdev_err_once(priv->ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) "%s: 0x%p: requested data outside of queued buffer: offset %i, len %i, pkt.tx: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) __func__, session, skcb->offset, se_skb->len , session->pkt.tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ret = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (!len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) memcpy(&dat[1], &tpdat[offset], len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) ret = j1939_tp_tx_dat(session, dat, len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* ENOBUS == CAN interface TX queue is full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (ret != -ENOBUFS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) netdev_alert(priv->ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) "%s: 0x%p: queue data error: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) __func__, session, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) session->last_txcmd = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) pkt_done++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) session->pkt.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) pdelay = j1939_cb_is_broadcast(&session->skcb) ? 50 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) j1939_tp_packet_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (session->pkt.tx < session->pkt.total && pdelay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) j1939_tp_schedule_txtimer(session, pdelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (pkt_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) j1939_tp_set_rxtimeout(session, 250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) kfree_skb(se_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) consume_skb(se_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static int j1939_xtp_txnext_transmiter(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (!j1939_tp_im_transmitter(&session->skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) netdev_alert(priv->ndev, "%s: 0x%p: called by not transmitter!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) switch (session->last_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) ret = j1939_session_tx_rts(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) case J1939_ETP_CMD_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (session->last_txcmd != J1939_ETP_CMD_DPO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ret = j1939_session_tx_dpo(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) case J1939_TP_CMD_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) case 0xff: /* did some data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) case J1939_ETP_CMD_DPO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) case J1939_TP_CMD_BAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ret = j1939_session_tx_dat(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) netdev_alert(priv->ndev, "%s: 0x%p: unexpected last_cmd: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) __func__, session, session->last_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) static int j1939_session_tx_cts(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) unsigned int pkt, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) u8 dat[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (!j1939_sk_recv_match(priv, &session->skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) len = session->pkt.total - session->pkt.rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) len = min3(len, session->pkt.block, j1939_tp_block ?: 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) memset(dat, 0xff, sizeof(dat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (session->skcb.addr.type == J1939_ETP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) pkt = session->pkt.rx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) dat[0] = J1939_ETP_CMD_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) dat[1] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) dat[2] = (pkt >> 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) dat[3] = (pkt >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) dat[4] = (pkt >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) dat[0] = J1939_TP_CMD_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) dat[1] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) dat[2] = session->pkt.rx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (dat[0] == session->last_txcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* done already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ret = j1939_tp_tx_ctl(session, true, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /* only mark cts done when len is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) session->last_txcmd = dat[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) j1939_tp_set_rxtimeout(session, 1250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static int j1939_session_tx_eoma(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) u8 dat[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (!j1939_sk_recv_match(priv, &session->skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) memset(dat, 0xff, sizeof(dat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (session->skcb.addr.type == J1939_ETP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) dat[0] = J1939_ETP_CMD_EOMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dat[1] = session->total_message_size >> 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) dat[2] = session->total_message_size >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) dat[3] = session->total_message_size >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) dat[4] = session->total_message_size >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) dat[0] = J1939_TP_CMD_EOMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) dat[1] = session->total_message_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dat[2] = session->total_message_size >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) dat[3] = session->pkt.total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (dat[0] == session->last_txcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* done already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ret = j1939_tp_tx_ctl(session, true, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) session->last_txcmd = dat[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /* wait for the EOMA packet to come in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) j1939_tp_set_rxtimeout(session, 1250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) netdev_dbg(session->priv->ndev, "%p: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) static int j1939_xtp_txnext_receiver(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (!j1939_tp_im_receiver(&session->skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) netdev_alert(priv->ndev, "%s: 0x%p: called by not receiver!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) switch (session->last_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) case J1939_TP_CMD_RTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) case J1939_ETP_CMD_RTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ret = j1939_session_tx_cts(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) case J1939_ETP_CMD_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) case J1939_TP_CMD_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) case 0xff: /* did some data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) case J1939_ETP_CMD_DPO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if ((session->skcb.addr.type == J1939_TP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) j1939_cb_is_broadcast(&session->skcb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (session->pkt.rx >= session->pkt.total) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ret = j1939_session_tx_eoma(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) } else if (session->pkt.rx >= session->pkt.last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) session->last_txcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ret = j1939_session_tx_cts(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) netdev_alert(priv->ndev, "%s: 0x%p: unexpected last_cmd: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) __func__, session, session->last_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static int j1939_simple_txnext(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct sk_buff *se_skb = j1939_session_skb_get(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (!se_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) skb = skb_clone(se_skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) can_skb_set_owner(skb, se_skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) j1939_tp_set_rxtimeout(session, J1939_SIMPLE_ECHO_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) ret = j1939_send_one(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) j1939_sk_errqueue(session, J1939_ERRQUEUE_SCHED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) j1939_sk_queue_activate_next(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) kfree_skb(se_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) consume_skb(se_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static bool j1939_session_deactivate_locked(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) bool active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) lockdep_assert_held(&session->priv->active_session_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (session->state >= J1939_SESSION_ACTIVE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) session->state < J1939_SESSION_ACTIVE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) list_del_init(&session->active_session_list_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) session->state = J1939_SESSION_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static bool j1939_session_deactivate(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) bool active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) j1939_session_list_lock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* This function should be called with a session ref-count of at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) * least 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) WARN_ON_ONCE(kref_read(&session->kref) < 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) active = j1939_session_deactivate_locked(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) j1939_session_list_unlock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) j1939_session_deactivate_activate_next(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (j1939_session_deactivate(session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) j1939_sk_queue_activate_next(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static void __j1939_session_cancel(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) enum j1939_xtp_abort err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) WARN_ON_ONCE(!err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) lockdep_assert_held(&session->priv->active_session_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) session->err = j1939_xtp_abort_to_errno(priv, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) session->state = J1939_SESSION_WAITING_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) /* do not send aborts on incoming broadcasts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (!j1939_cb_is_broadcast(&session->skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) j1939_xtp_tx_abort(priv, &session->skcb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) !session->transmission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) err, session->skcb.addr.pgn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (session->sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) j1939_sk_send_loop_abort(session->sk, session->err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static void j1939_session_cancel(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) enum j1939_xtp_abort err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) j1939_session_list_lock(session->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (session->state >= J1939_SESSION_ACTIVE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) session->state < J1939_SESSION_WAITING_ABORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) j1939_tp_set_rxtimeout(session, J1939_XTP_ABORT_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) __j1939_session_cancel(session, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) j1939_session_list_unlock(session->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct j1939_session *session =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) container_of(hrtimer, struct j1939_session, txtimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (session->skcb.addr.type == J1939_SIMPLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) ret = j1939_simple_txnext(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (session->transmission)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) ret = j1939_xtp_txnext_transmiter(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) ret = j1939_xtp_txnext_receiver(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) case -ENOBUFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) /* Retry limit is currently arbitrary chosen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (session->tx_retry < J1939_XTP_TX_RETRY_LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) session->tx_retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) j1939_tp_schedule_txtimer(session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 10 + prandom_u32_max(16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) netdev_alert(priv->ndev, "%s: 0x%p: tx retry count reached\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) session->err = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) j1939_session_rxtimer_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) j1939_session_deactivate_activate_next(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) case -ENETDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /* In this case we should get a netdev_event(), all active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * sessions will be cleared by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) * j1939_cancel_all_active_sessions(). So handle this as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * error, but let j1939_cancel_all_active_sessions() do the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * cleanup including propagation of the error to user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) case -EOVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) j1939_session_cancel(session, J1939_XTP_ABORT_ECTS_TOO_BIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) session->tx_retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) netdev_alert(priv->ndev, "%s: 0x%p: tx aborted with unknown reason: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) __func__, session, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (session->skcb.addr.type != J1939_SIMPLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) j1939_session_cancel(session, J1939_XTP_ABORT_OTHER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) session->err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) j1939_session_rxtimer_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) j1939_session_deactivate_activate_next(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return HRTIMER_NORESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) static void j1939_session_completed(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (!session->transmission) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) skb = j1939_session_skb_get(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* distribute among j1939 receivers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) j1939_sk_recv(session->priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) j1939_session_deactivate_activate_next(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) static enum hrtimer_restart j1939_tp_rxtimer(struct hrtimer *hrtimer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) struct j1939_session *session = container_of(hrtimer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct j1939_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) rxtimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (session->state == J1939_SESSION_WAITING_ABORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) netdev_alert(priv->ndev, "%s: 0x%p: abort rx timeout. Force session deactivation\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) j1939_session_deactivate_activate_next(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) } else if (session->skcb.addr.type == J1939_SIMPLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) netdev_alert(priv->ndev, "%s: 0x%p: Timeout. Failed to send simple message.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) /* The message is probably stuck in the CAN controller and can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * be send as soon as CAN bus is in working state again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) session->err = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) j1939_session_deactivate(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) j1939_session_list_lock(session->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (session->state >= J1939_SESSION_ACTIVE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) session->state < J1939_SESSION_ACTIVE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) netdev_alert(priv->ndev, "%s: 0x%p: rx timeout, send abort\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) j1939_session_get(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) hrtimer_start(&session->rxtimer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ms_to_ktime(J1939_XTP_ABORT_TIMEOUT_MS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) __j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) j1939_session_list_unlock(session->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return HRTIMER_NORESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) static bool j1939_xtp_rx_cmd_bad_pgn(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) const struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) const struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) pgn_t pgn = j1939_xtp_ctl_to_pgn(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) enum j1939_xtp_abort abort = J1939_XTP_NO_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) u8 cmd = skb->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (session->skcb.addr.pgn == pgn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) case J1939_TP_CMD_BAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) abort = J1939_XTP_NO_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) case J1939_ETP_CMD_RTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) case J1939_TP_CMD_RTS: /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) abort = J1939_XTP_ABORT_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) case J1939_ETP_CMD_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) case J1939_TP_CMD_CTS: /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) abort = J1939_XTP_ABORT_ECTS_UNXPECTED_PGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) case J1939_ETP_CMD_DPO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) abort = J1939_XTP_ABORT_BAD_EDPO_PGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) case J1939_ETP_CMD_EOMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) case J1939_TP_CMD_EOMA: /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) abort = J1939_XTP_ABORT_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) case J1939_ETP_CMD_ABORT: /* && J1939_TP_CMD_ABORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) abort = J1939_XTP_NO_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) netdev_warn(priv->ndev, "%s: 0x%p: CMD 0x%02x with PGN 0x%05x for running session with different PGN 0x%05x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) __func__, session, cmd, pgn, session->skcb.addr.pgn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (abort != J1939_XTP_NO_ABORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) j1939_xtp_tx_abort(priv, skcb, true, abort, pgn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) static void j1939_xtp_rx_abort_one(struct j1939_priv *priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) bool reverse, bool transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) u8 abort = skb->data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) session = j1939_session_get_by_addr(priv, &skcb->addr, reverse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) transmitter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (j1939_xtp_rx_cmd_bad_pgn(session, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) goto abort_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) netdev_info(priv->ndev, "%s: 0x%p: 0x%05x: (%u) %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) session, j1939_xtp_ctl_to_pgn(skb->data), abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) j1939_xtp_abort_to_str(abort));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) j1939_session_timers_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) session->err = j1939_xtp_abort_to_errno(priv, abort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (session->sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) j1939_sk_send_loop_abort(session->sk, session->err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) j1939_session_deactivate_activate_next(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) abort_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) /* abort packets may come in 2 directions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) j1939_xtp_rx_abort(struct j1939_priv *priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) bool transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) j1939_xtp_rx_abort_one(priv, skb, false, transmitter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) j1939_xtp_rx_abort_one(priv, skb, true, transmitter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) j1939_xtp_rx_eoma_one(struct j1939_session *session, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) const u8 *dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (j1939_xtp_rx_cmd_bad_pgn(session, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) dat = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) if (skcb->addr.type == J1939_ETP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) len = j1939_etp_ctl_to_size(dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) len = j1939_tp_ctl_to_size(dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (session->total_message_size != len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) netdev_warn_once(session->priv->ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) "%s: 0x%p: Incorrect size. Expected: %i; got: %i.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) __func__, session, session->total_message_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) session->pkt.tx_acked = session->pkt.total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) j1939_session_timers_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /* transmitted without problems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) j1939_session_completed(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) j1939_xtp_rx_eoma(struct j1939_priv *priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) bool transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) session = j1939_session_get_by_addr(priv, &skcb->addr, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) transmitter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) j1939_xtp_rx_eoma_one(session, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) j1939_xtp_rx_cts_one(struct j1939_session *session, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) enum j1939_xtp_abort err = J1939_XTP_ABORT_FAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) unsigned int pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) const u8 *dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) dat = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (j1939_xtp_rx_cmd_bad_pgn(session, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (session->last_cmd == dat[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) err = J1939_XTP_ABORT_DUP_SEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) goto out_session_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (session->skcb.addr.type == J1939_ETP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) pkt = j1939_etp_ctl_to_packet(dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) pkt = dat[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) if (!pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) goto out_session_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) else if (dat[1] > session->pkt.block /* 0xff for etp */)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) goto out_session_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) /* set packet counters only when not CTS(0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) session->pkt.tx_acked = pkt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) j1939_session_skb_drop_old(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) session->pkt.last = session->pkt.tx_acked + dat[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (session->pkt.last > session->pkt.total)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /* safety measure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) session->pkt.last = session->pkt.total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) /* TODO: do not set tx here, do it in txtimer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) session->pkt.tx = session->pkt.tx_acked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) session->last_cmd = dat[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (dat[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) j1939_tp_set_rxtimeout(session, 1250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (session->transmission) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (session->pkt.tx_acked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) j1939_sk_errqueue(session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) J1939_ERRQUEUE_SCHED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) j1939_session_txtimer_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) j1939_tp_schedule_txtimer(session, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /* CTS(0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) j1939_tp_set_rxtimeout(session, 550);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) out_session_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) j1939_session_timers_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) j1939_session_cancel(session, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) j1939_xtp_rx_cts(struct j1939_priv *priv, struct sk_buff *skb, bool transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) session = j1939_session_get_by_addr(priv, &skcb->addr, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) transmitter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) j1939_xtp_rx_cts_one(session, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) static struct j1939_session *j1939_session_new(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) struct sk_buff *skb, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct j1939_sk_buff_cb *skcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) session = kzalloc(sizeof(*session), gfp_any());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) INIT_LIST_HEAD(&session->active_session_list_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) INIT_LIST_HEAD(&session->sk_session_queue_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) kref_init(&session->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) j1939_priv_get(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) session->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) session->total_message_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) session->state = J1939_SESSION_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) skb_queue_head_init(&session->skb_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) skb_queue_tail(&session->skb_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) memcpy(&session->skcb, skcb, sizeof(session->skcb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) hrtimer_init(&session->txtimer, CLOCK_MONOTONIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) session->txtimer.function = j1939_tp_txtimer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) hrtimer_init(&session->rxtimer, CLOCK_MONOTONIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) session->rxtimer.function = j1939_tp_rxtimer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) netdev_dbg(priv->ndev, "%s: 0x%p: sa: %02x, da: %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) __func__, session, skcb->addr.sa, skcb->addr.da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) return session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) static struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) j1939_session *j1939_session_fresh_new(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) const struct j1939_sk_buff_cb *rel_skcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) struct j1939_sk_buff_cb *skcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) skb = alloc_skb(size + sizeof(struct can_skb_priv), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (unlikely(!skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) skb->dev = priv->ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) can_skb_reserve(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) can_skb_prv(skb)->skbcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) memcpy(skcb, rel_skcb, sizeof(*skcb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) session = j1939_session_new(priv, skb, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (!session) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) /* alloc data area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) skb_put(skb, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /* skb is recounted in j1939_session_new() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) return session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) int j1939_session_activate(struct j1939_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) struct j1939_session *active = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) j1939_session_list_lock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (session->skcb.addr.type != J1939_SIMPLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) active = j1939_session_get_by_addr_locked(priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) &priv->active_session_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) &session->skcb.addr, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) session->transmission);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) if (active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) j1939_session_put(active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) WARN_ON_ONCE(session->state != J1939_SESSION_NEW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) list_add_tail(&session->active_session_list_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) &priv->active_session_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) j1939_session_get(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) session->state = J1939_SESSION_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) netdev_dbg(session->priv->ndev, "%s: 0x%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) j1939_session_list_unlock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) static struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) j1939_session *j1939_xtp_rx_rts_session_new(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) enum j1939_xtp_abort abort = J1939_XTP_NO_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) struct j1939_sk_buff_cb skcb = *j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) const u8 *dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) pgn_t pgn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) netdev_dbg(priv->ndev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) dat = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) pgn = j1939_xtp_ctl_to_pgn(dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) skcb.addr.pgn = pgn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) if (!j1939_sk_recv_match(priv, &skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) if (skcb.addr.type == J1939_ETP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) len = j1939_etp_ctl_to_size(dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (len > J1939_MAX_ETP_PACKET_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) abort = J1939_XTP_ABORT_FAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) else if (len > priv->tp_max_packet_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) abort = J1939_XTP_ABORT_RESOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) else if (len <= J1939_MAX_TP_PACKET_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) abort = J1939_XTP_ABORT_FAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) len = j1939_tp_ctl_to_size(dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) if (len > J1939_MAX_TP_PACKET_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) abort = J1939_XTP_ABORT_FAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) else if (len > priv->tp_max_packet_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) abort = J1939_XTP_ABORT_RESOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) else if (len < J1939_MIN_TP_PACKET_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) abort = J1939_XTP_ABORT_FAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (abort != J1939_XTP_NO_ABORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) j1939_xtp_tx_abort(priv, &skcb, true, abort, pgn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) session = j1939_session_fresh_new(priv, len, &skcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (!session) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) j1939_xtp_tx_abort(priv, &skcb, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) J1939_XTP_ABORT_RESOURCE, pgn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) /* initialize the control buffer: plain copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) session->pkt.total = (len + 6) / 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) session->pkt.block = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) if (skcb.addr.type != J1939_ETP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (dat[3] != session->pkt.total)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) netdev_alert(priv->ndev, "%s: 0x%p: strange total, %u != %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) __func__, session, session->pkt.total,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) dat[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) session->pkt.total = dat[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) session->pkt.block = min(dat[3], dat[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) session->pkt.rx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) session->pkt.tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) WARN_ON_ONCE(j1939_session_activate(session));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) return session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) static int j1939_xtp_rx_rts_session_active(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (!session->transmission) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (j1939_xtp_rx_cmd_bad_pgn(session, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) /* RTS on active session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) j1939_session_timers_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) j1939_session_cancel(session, J1939_XTP_ABORT_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) if (session->last_cmd != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) /* we received a second rts on the same connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) netdev_alert(priv->ndev, "%s: 0x%p: connection exists (%02x %02x). last cmd: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) __func__, session, skcb->addr.sa, skcb->addr.da,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) session->last_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) j1939_session_timers_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) j1939_session_cancel(session, J1939_XTP_ABORT_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (session->skcb.addr.sa != skcb->addr.sa ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) session->skcb.addr.da != skcb->addr.da)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) netdev_warn(priv->ndev, "%s: 0x%p: session->skcb.addr.sa=0x%02x skcb->addr.sa=0x%02x session->skcb.addr.da=0x%02x skcb->addr.da=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) __func__, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) session->skcb.addr.sa, skcb->addr.sa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) session->skcb.addr.da, skcb->addr.da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) /* make sure 'sa' & 'da' are correct !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) * They may be 'not filled in yet' for sending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) * skb's, since they did not pass the Address Claim ever.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) session->skcb.addr.sa = skcb->addr.sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) session->skcb.addr.da = skcb->addr.da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) bool transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) u8 cmd = skb->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) session = j1939_session_get_by_addr(priv, &skcb->addr, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) transmitter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) if (!session) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) if (transmitter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) /* If we're the transmitter and this function is called,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) * we received our own RTS. A session has already been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) * created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) * For some reasons however it might have been destroyed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) * already. So don't create a new one here (using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) * "j1939_xtp_rx_rts_session_new()") as this will be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * receiver session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) * The reasons the session is already destroyed might
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) * be:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) * - user space closed socket was and the session was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * aborted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) * - session was aborted due to external abort message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) session = j1939_xtp_rx_rts_session_new(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) if (!session) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) if (cmd == J1939_TP_CMD_BAM && j1939_sk_recv_match(priv, skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) netdev_info(priv->ndev, "%s: failed to create TP BAM session\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) if (j1939_xtp_rx_rts_session_active(session, skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) session->last_cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (cmd == J1939_TP_CMD_BAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (!session->transmission)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) j1939_tp_set_rxtimeout(session, 750);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) if (!session->transmission) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) j1939_session_txtimer_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) j1939_tp_schedule_txtimer(session, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) j1939_tp_set_rxtimeout(session, 1250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) static void j1939_xtp_rx_dpo_one(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) const u8 *dat = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) if (j1939_xtp_rx_cmd_bad_pgn(session, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) /* transmitted without problems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) session->pkt.dpo = j1939_etp_ctl_to_packet(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) session->last_cmd = dat[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) j1939_tp_set_rxtimeout(session, 750);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) static void j1939_xtp_rx_dpo(struct j1939_priv *priv, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) bool transmitter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) session = j1939_session_get_by_addr(priv, &skcb->addr, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) transmitter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) if (!session) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) netdev_info(priv->ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) "%s: no connection found\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) j1939_xtp_rx_dpo_one(session, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) static void j1939_xtp_rx_dat_one(struct j1939_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) enum j1939_xtp_abort abort = J1939_XTP_ABORT_FAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) struct j1939_priv *priv = session->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) struct j1939_sk_buff_cb *skcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) struct sk_buff *se_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) const u8 *dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) u8 *tpdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) int nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) bool final = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) bool remain = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) bool do_cts_eoma = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) int packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) dat = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (skb->len != 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) /* makes no sense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) abort = J1939_XTP_ABORT_UNEXPECTED_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) goto out_session_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) switch (session->last_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) case 0xff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) case J1939_ETP_CMD_DPO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) if (skcb->addr.type == J1939_ETP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) case J1939_TP_CMD_BAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) case J1939_TP_CMD_CTS: /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (skcb->addr.type != J1939_ETP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) netdev_info(priv->ndev, "%s: 0x%p: last %02x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) session, session->last_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) goto out_session_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) packet = (dat[0] - 1 + session->pkt.dpo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (packet > session->pkt.total ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) (session->pkt.rx + 1) > session->pkt.total) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) netdev_info(priv->ndev, "%s: 0x%p: should have been completed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) __func__, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) goto out_session_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) se_skb = j1939_session_skb_get_by_offset(session, packet * 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if (!se_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) netdev_warn(priv->ndev, "%s: 0x%p: no skb found\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) goto out_session_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) skcb = j1939_skb_to_cb(se_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) offset = packet * 7 - skcb->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) nbytes = se_skb->len - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) if (nbytes > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) nbytes = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (nbytes <= 0 || (nbytes + 1) > skb->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) netdev_info(priv->ndev, "%s: 0x%p: nbytes %i, len %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) __func__, session, nbytes, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) goto out_session_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) tpdat = se_skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) if (!session->transmission) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) memcpy(&tpdat[offset], &dat[1], nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) err = memcmp(&tpdat[offset], &dat[1], nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) netdev_err_once(priv->ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) "%s: 0x%p: Data of RX-looped back packet (%*ph) doesn't match TX data (%*ph)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) __func__, session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) nbytes, &dat[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) nbytes, &tpdat[offset]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (packet == session->pkt.rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) session->pkt.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (skcb->addr.type != J1939_ETP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) j1939_cb_is_broadcast(&session->skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (session->pkt.rx >= session->pkt.total)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) final = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) remain = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) /* never final, an EOMA must follow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) if (session->pkt.rx >= session->pkt.last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) do_cts_eoma = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) if (final) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) j1939_session_timers_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) j1939_session_completed(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) } else if (remain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (!session->transmission)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) j1939_tp_set_rxtimeout(session, 750);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) } else if (do_cts_eoma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) j1939_tp_set_rxtimeout(session, 1250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (!session->transmission)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) j1939_tp_schedule_txtimer(session, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) j1939_tp_set_rxtimeout(session, 750);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) session->last_cmd = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) consume_skb(se_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) out_session_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) kfree_skb(se_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) j1939_session_timers_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) j1939_session_cancel(session, abort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) static void j1939_xtp_rx_dat(struct j1939_priv *priv, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) struct j1939_sk_buff_cb *skcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (j1939_tp_im_transmitter(skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) session = j1939_session_get_by_addr(priv, &skcb->addr, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) netdev_info(priv->ndev, "%s: no tx connection found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) j1939_xtp_rx_dat_one(session, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (j1939_tp_im_receiver(skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) session = j1939_session_get_by_addr(priv, &skcb->addr, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) netdev_info(priv->ndev, "%s: no rx connection found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) j1939_xtp_rx_dat_one(session, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (j1939_cb_is_broadcast(skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) session = j1939_session_get_by_addr(priv, &skcb->addr, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) j1939_xtp_rx_dat_one(session, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) /* j1939 main intf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) struct sk_buff *skb, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if (skcb->addr.pgn == J1939_TP_PGN_DAT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) skcb->addr.pgn == J1939_TP_PGN_CTL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) skcb->addr.pgn == J1939_ETP_PGN_DAT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) skcb->addr.pgn == J1939_ETP_PGN_CTL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) /* avoid conflict */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) return ERR_PTR(-EDOM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if (size > priv->tp_max_packet_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) return ERR_PTR(-EMSGSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (size <= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) skcb->addr.type = J1939_SIMPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) else if (size > J1939_MAX_TP_PACKET_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) skcb->addr.type = J1939_ETP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) skcb->addr.type = J1939_TP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (skcb->addr.type == J1939_ETP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) j1939_cb_is_broadcast(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) return ERR_PTR(-EDESTADDRREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) /* fill in addresses from names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) ret = j1939_ac_fixup(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) /* fix DST flags, it may be used there soon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (j1939_address_is_unicast(skcb->addr.da) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) priv->ents[skcb->addr.da].nusers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) skcb->flags |= J1939_ECU_LOCAL_DST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) /* src is always local, I'm sending ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) skcb->flags |= J1939_ECU_LOCAL_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /* prepare new session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) session = j1939_session_new(priv, skb, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) /* skb is recounted in j1939_session_new() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) sock_hold(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) session->sk = skb->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) session->transmission = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) session->pkt.total = (size + 6) / 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) session->pkt.block = skcb->addr.type == J1939_ETP ? 255 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) min(j1939_tp_block ?: 255, session->pkt.total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (j1939_cb_is_broadcast(&session->skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) /* set the end-packet for broadcast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) session->pkt.last = session->pkt.total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) skcb->tskey = session->sk->sk_tskey++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) session->tskey = skcb->tskey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) return session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) int extd = J1939_TP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) u8 cmd = skb->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) case J1939_ETP_CMD_RTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) extd = J1939_ETP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) case J1939_TP_CMD_BAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (cmd == J1939_TP_CMD_BAM && !j1939_cb_is_broadcast(skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) netdev_err_once(priv->ndev, "%s: BAM to unicast (%02x), ignoring!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) __func__, skcb->addr.sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) case J1939_TP_CMD_RTS: /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (skcb->addr.type != extd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (cmd == J1939_TP_CMD_RTS && j1939_cb_is_broadcast(skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) netdev_alert(priv->ndev, "%s: rts without destination (%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) __func__, skcb->addr.sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) if (j1939_tp_im_transmitter(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) j1939_xtp_rx_rts(priv, skb, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (j1939_tp_im_receiver(skcb) || j1939_cb_is_broadcast(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) j1939_xtp_rx_rts(priv, skb, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) case J1939_ETP_CMD_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) extd = J1939_ETP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) case J1939_TP_CMD_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) if (skcb->addr.type != extd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) if (j1939_tp_im_transmitter(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) j1939_xtp_rx_cts(priv, skb, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) if (j1939_tp_im_receiver(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) j1939_xtp_rx_cts(priv, skb, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) case J1939_ETP_CMD_DPO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) if (skcb->addr.type != J1939_ETP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if (j1939_tp_im_transmitter(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) j1939_xtp_rx_dpo(priv, skb, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (j1939_tp_im_receiver(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) j1939_xtp_rx_dpo(priv, skb, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) case J1939_ETP_CMD_EOMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) extd = J1939_ETP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) case J1939_TP_CMD_EOMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if (skcb->addr.type != extd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) if (j1939_tp_im_transmitter(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) j1939_xtp_rx_eoma(priv, skb, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) if (j1939_tp_im_receiver(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) j1939_xtp_rx_eoma(priv, skb, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) case J1939_ETP_CMD_ABORT: /* && J1939_TP_CMD_ABORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (j1939_cb_is_broadcast(skcb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) netdev_err_once(priv->ndev, "%s: abort to broadcast (%02x), ignoring!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) __func__, skcb->addr.sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (j1939_tp_im_transmitter(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) j1939_xtp_rx_abort(priv, skb, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) if (j1939_tp_im_receiver(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) j1939_xtp_rx_abort(priv, skb, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if (!j1939_tp_im_involved_anydir(skcb) && !j1939_cb_is_broadcast(skcb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) switch (skcb->addr.pgn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) case J1939_ETP_PGN_DAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) skcb->addr.type = J1939_ETP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) case J1939_TP_PGN_DAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) j1939_xtp_rx_dat(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) case J1939_ETP_PGN_CTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) skcb->addr.type = J1939_ETP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) case J1939_TP_PGN_CTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) if (skb->len < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) return 0; /* Don't care. Nothing to extract here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) j1939_tp_cmd_recv(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) return 0; /* no problem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) return 1; /* "I processed the message" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) void j1939_simple_recv(struct j1939_priv *priv, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) struct j1939_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) if (!skb->sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) if (skb->sk->sk_family != AF_CAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) skb->sk->sk_protocol != CAN_J1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) j1939_session_list_lock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) session = j1939_session_get_simple(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) j1939_session_list_unlock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) if (!session) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) netdev_warn(priv->ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) "%s: Received already invalidated message\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) j1939_session_timers_cancel(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) j1939_session_deactivate(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) int j1939_cancel_active_session(struct j1939_priv *priv, struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) struct j1939_session *session, *saved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) netdev_dbg(priv->ndev, "%s, sk: %p\n", __func__, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) j1939_session_list_lock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) list_for_each_entry_safe(session, saved,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) &priv->active_session_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) active_session_list_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (!sk || sk == session->sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) if (hrtimer_try_to_cancel(&session->txtimer) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if (hrtimer_try_to_cancel(&session->rxtimer) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) j1939_session_put(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) session->err = ESHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) j1939_session_deactivate_locked(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) j1939_session_list_unlock(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) void j1939_tp_init(struct j1939_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) spin_lock_init(&priv->active_session_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) INIT_LIST_HEAD(&priv->active_session_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) priv->tp_max_packet_size = J1939_MAX_ETP_PACKET_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) }