bcm27xx: update 6.1 patches to latest version
[openwrt/staging/dangole.git] / target / linux / bcm27xx / patches-6.1 / 950-0821-can-isotp-add-module-parameter-for-maximum-pdu-size.patch
1 From 4b729a06b15fc5ee3694dcc62346dcb718ae4290 Mon Sep 17 00:00:00 2001
2 From: Oliver Hartkopp <socketcan@hartkopp.net>
3 Date: Sun, 26 Mar 2023 13:59:11 +0200
4 Subject: [PATCH] can: isotp: add module parameter for maximum pdu size
5
6 commit 96d1c81e6a0478535342dff6c730adb076cd84e8 upstream.
7
8 With ISO 15765-2:2016 the PDU size is not limited to 2^12 - 1 (4095)
9 bytes but can be represented as a 32 bit unsigned integer value which
10 allows 2^32 - 1 bytes (~4GB). The use-cases like automotive unified
11 diagnostic services (UDS) and flashing of ECUs still use the small
12 static buffers which are provided at socket creation time.
13
14 When a use-case requires to transfer PDUs up to 1025 kByte the maximum
15 PDU size can now be extended by setting the module parameter
16 max_pdu_size. The extended size buffers are only allocated on a
17 per-socket/connection base when needed at run-time.
18
19 changes since v2: https://lore.kernel.org/all/20230313172510.3851-1-socketcan@hartkopp.net
20 - use ARRAY_SIZE() to reference DEFAULT_MAX_PDU_SIZE only at one place
21
22 changes since v1: https://lore.kernel.org/all/20230311143446.3183-1-socketcan@hartkopp.net
23 - limit the minimum 'max_pdu_size' to 4095 to maintain the classic
24 behavior before ISO 15765-2:2016
25
26 Link: https://github.com/raspberrypi/linux/issues/5371
27 Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
28 Link: https://lore.kernel.org/all/20230326115911.15094-1-socketcan@hartkopp.net
29 Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
30 ---
31 net/can/isotp.c | 65 ++++++++++++++++++++++++++++++++++++++++++-------
32 1 file changed, 56 insertions(+), 9 deletions(-)
33
34 --- a/net/can/isotp.c
35 +++ b/net/can/isotp.c
36 @@ -85,10 +85,21 @@ MODULE_ALIAS("can-proto-6");
37
38 /* ISO 15765-2:2016 supports more than 4095 byte per ISO PDU as the FF_DL can
39 * take full 32 bit values (4 Gbyte). We would need some good concept to handle
40 - * this between user space and kernel space. For now increase the static buffer
41 - * to something about 64 kbyte to be able to test this new functionality.
42 + * this between user space and kernel space. For now set the static buffer to
43 + * something about 8 kbyte to be able to test this new functionality.
44 */
45 -#define MAX_MSG_LENGTH 66000
46 +#define DEFAULT_MAX_PDU_SIZE 8300
47 +
48 +/* maximum PDU size before ISO 15765-2:2016 extension was 4095 */
49 +#define MAX_12BIT_PDU_SIZE 4095
50 +
51 +/* limit the isotp pdu size from the optional module parameter to 1MByte */
52 +#define MAX_PDU_SIZE (1025 * 1024U)
53 +
54 +static unsigned int max_pdu_size __read_mostly = DEFAULT_MAX_PDU_SIZE;
55 +module_param(max_pdu_size, uint, 0444);
56 +MODULE_PARM_DESC(max_pdu_size, "maximum isotp pdu size (default "
57 + __stringify(DEFAULT_MAX_PDU_SIZE) ")");
58
59 /* N_PCI type values in bits 7-4 of N_PCI bytes */
60 #define N_PCI_SF 0x00 /* single frame */
61 @@ -124,13 +135,15 @@ enum {
62 };
63
64 struct tpcon {
65 - unsigned int idx;
66 + u8 *buf;
67 + unsigned int buflen;
68 unsigned int len;
69 + unsigned int idx;
70 u32 state;
71 u8 bs;
72 u8 sn;
73 u8 ll_dl;
74 - u8 buf[MAX_MSG_LENGTH + 1];
75 + u8 sbuf[DEFAULT_MAX_PDU_SIZE];
76 };
77
78 struct isotp_sock {
79 @@ -498,7 +511,17 @@ static int isotp_rcv_ff(struct sock *sk,
80 if (so->rx.len + ae + off + ff_pci_sz < so->rx.ll_dl)
81 return 1;
82
83 - if (so->rx.len > MAX_MSG_LENGTH) {
84 + /* PDU size > default => try max_pdu_size */
85 + if (so->rx.len > so->rx.buflen && so->rx.buflen < max_pdu_size) {
86 + u8 *newbuf = kmalloc(max_pdu_size, GFP_ATOMIC);
87 +
88 + if (newbuf) {
89 + so->rx.buf = newbuf;
90 + so->rx.buflen = max_pdu_size;
91 + }
92 + }
93 +
94 + if (so->rx.len > so->rx.buflen) {
95 /* send FC frame with overflow status */
96 isotp_send_fc(sk, ae, ISOTP_FC_OVFLW);
97 return 1;
98 @@ -802,7 +825,7 @@ static void isotp_create_fframe(struct c
99 cf->data[0] = so->opt.ext_address;
100
101 /* create N_PCI bytes with 12/32 bit FF_DL data length */
102 - if (so->tx.len > 4095) {
103 + if (so->tx.len > MAX_12BIT_PDU_SIZE) {
104 /* use 32 bit FF_DL notation */
105 cf->data[ae] = N_PCI_FF;
106 cf->data[ae + 1] = 0;
107 @@ -939,7 +962,17 @@ static int isotp_sendmsg(struct socket *
108 goto err_event_drop;
109 }
110
111 - if (!size || size > MAX_MSG_LENGTH) {
112 + /* PDU size > default => try max_pdu_size */
113 + if (size > so->tx.buflen && so->tx.buflen < max_pdu_size) {
114 + u8 *newbuf = kmalloc(max_pdu_size, GFP_KERNEL);
115 +
116 + if (newbuf) {
117 + so->tx.buf = newbuf;
118 + so->tx.buflen = max_pdu_size;
119 + }
120 + }
121 +
122 + if (!size || size > so->tx.buflen) {
123 err = -EINVAL;
124 goto err_out_drop;
125 }
126 @@ -1194,6 +1227,12 @@ static int isotp_release(struct socket *
127 so->ifindex = 0;
128 so->bound = 0;
129
130 + if (so->rx.buf != so->rx.sbuf)
131 + kfree(so->rx.buf);
132 +
133 + if (so->tx.buf != so->tx.sbuf)
134 + kfree(so->tx.buf);
135 +
136 sock_orphan(sk);
137 sock->sk = NULL;
138
139 @@ -1588,6 +1627,11 @@ static int isotp_init(struct sock *sk)
140 so->rx.state = ISOTP_IDLE;
141 so->tx.state = ISOTP_IDLE;
142
143 + so->rx.buf = so->rx.sbuf;
144 + so->tx.buf = so->tx.sbuf;
145 + so->rx.buflen = ARRAY_SIZE(so->rx.sbuf);
146 + so->tx.buflen = ARRAY_SIZE(so->tx.sbuf);
147 +
148 hrtimer_init(&so->rxtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT);
149 so->rxtimer.function = isotp_rx_timer_handler;
150 hrtimer_init(&so->txtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT);
151 @@ -1670,7 +1714,10 @@ static __init int isotp_module_init(void
152 {
153 int err;
154
155 - pr_info("can: isotp protocol\n");
156 + max_pdu_size = max_t(unsigned int, max_pdu_size, MAX_12BIT_PDU_SIZE);
157 + max_pdu_size = min_t(unsigned int, max_pdu_size, MAX_PDU_SIZE);
158 +
159 + pr_info("can: isotp protocol (max_pdu_size %d)\n", max_pdu_size);
160
161 err = can_proto_register(&isotp_can_proto);
162 if (err < 0)