Skip to content

Commit 92a3178

Browse files
passgatmarckleinebudde
authored andcommitted
can: slcan: use the alloc_can_skb() helper
It is used successfully by most (if not all) CAN device drivers. It allows to remove replicated code. Link: https://lore.kernel.org/all/[email protected] Signed-off-by: Dario Binacchi <[email protected]> Tested-by: Jeroen Hofstee <[email protected]> Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent da6788e commit 92a3178

File tree

1 file changed

+33
-37
lines changed

1 file changed

+33
-37
lines changed

drivers/net/can/slcan.c

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include <linux/kernel.h>
5555
#include <linux/workqueue.h>
5656
#include <linux/can.h>
57+
#include <linux/can/dev.h>
5758
#include <linux/can/skb.h>
5859
#include <linux/can/can-ml.h>
5960

@@ -143,85 +144,80 @@ static struct net_device **slcan_devs;
143144
static void slc_bump(struct slcan *sl)
144145
{
145146
struct sk_buff *skb;
146-
struct can_frame cf;
147+
struct can_frame *cf;
147148
int i, tmp;
148149
u32 tmpid;
149150
char *cmd = sl->rbuff;
150151

151-
memset(&cf, 0, sizeof(cf));
152+
skb = alloc_can_skb(sl->dev, &cf);
153+
if (unlikely(!skb)) {
154+
sl->dev->stats.rx_dropped++;
155+
return;
156+
}
152157

153158
switch (*cmd) {
154159
case 'r':
155-
cf.can_id = CAN_RTR_FLAG;
160+
cf->can_id = CAN_RTR_FLAG;
156161
fallthrough;
157162
case 't':
158163
/* store dlc ASCII value and terminate SFF CAN ID string */
159-
cf.len = sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN];
164+
cf->len = sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN];
160165
sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN] = 0;
161166
/* point to payload data behind the dlc */
162167
cmd += SLC_CMD_LEN + SLC_SFF_ID_LEN + 1;
163168
break;
164169
case 'R':
165-
cf.can_id = CAN_RTR_FLAG;
170+
cf->can_id = CAN_RTR_FLAG;
166171
fallthrough;
167172
case 'T':
168-
cf.can_id |= CAN_EFF_FLAG;
173+
cf->can_id |= CAN_EFF_FLAG;
169174
/* store dlc ASCII value and terminate EFF CAN ID string */
170-
cf.len = sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN];
175+
cf->len = sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN];
171176
sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN] = 0;
172177
/* point to payload data behind the dlc */
173178
cmd += SLC_CMD_LEN + SLC_EFF_ID_LEN + 1;
174179
break;
175180
default:
176-
return;
181+
goto decode_failed;
177182
}
178183

179184
if (kstrtou32(sl->rbuff + SLC_CMD_LEN, 16, &tmpid))
180-
return;
185+
goto decode_failed;
181186

182-
cf.can_id |= tmpid;
187+
cf->can_id |= tmpid;
183188

184189
/* get len from sanitized ASCII value */
185-
if (cf.len >= '0' && cf.len < '9')
186-
cf.len -= '0';
190+
if (cf->len >= '0' && cf->len < '9')
191+
cf->len -= '0';
187192
else
188-
return;
193+
goto decode_failed;
189194

190195
/* RTR frames may have a dlc > 0 but they never have any data bytes */
191-
if (!(cf.can_id & CAN_RTR_FLAG)) {
192-
for (i = 0; i < cf.len; i++) {
196+
if (!(cf->can_id & CAN_RTR_FLAG)) {
197+
for (i = 0; i < cf->len; i++) {
193198
tmp = hex_to_bin(*cmd++);
194199
if (tmp < 0)
195-
return;
196-
cf.data[i] = (tmp << 4);
200+
goto decode_failed;
201+
202+
cf->data[i] = (tmp << 4);
197203
tmp = hex_to_bin(*cmd++);
198204
if (tmp < 0)
199-
return;
200-
cf.data[i] |= tmp;
205+
goto decode_failed;
206+
207+
cf->data[i] |= tmp;
201208
}
202209
}
203210

204-
skb = dev_alloc_skb(sizeof(struct can_frame) +
205-
sizeof(struct can_skb_priv));
206-
if (!skb)
207-
return;
208-
209-
skb->dev = sl->dev;
210-
skb->protocol = htons(ETH_P_CAN);
211-
skb->pkt_type = PACKET_BROADCAST;
212-
skb->ip_summed = CHECKSUM_UNNECESSARY;
213-
214-
can_skb_reserve(skb);
215-
can_skb_prv(skb)->ifindex = sl->dev->ifindex;
216-
can_skb_prv(skb)->skbcnt = 0;
217-
218-
skb_put_data(skb, &cf, sizeof(struct can_frame));
219-
220211
sl->dev->stats.rx_packets++;
221-
if (!(cf.can_id & CAN_RTR_FLAG))
222-
sl->dev->stats.rx_bytes += cf.len;
212+
if (!(cf->can_id & CAN_RTR_FLAG))
213+
sl->dev->stats.rx_bytes += cf->len;
223214

224215
netif_rx(skb);
216+
return;
217+
218+
decode_failed:
219+
sl->dev->stats.rx_errors++;
220+
dev_kfree_skb(skb);
225221
}
226222

227223
/* parse tty input stream */

0 commit comments

Comments
 (0)