History

can: gw: use struct canfd_frame as internal data structure

To prepare the CAN FD support this patch implements the first adaptions in data structures for CAN FD without changing the current functionality. Additionally some code at the end of this patch is moved or indented to simplify the review of the next implementation step.

Oliver Hartkopp committed 7 years ago

Commit e9dc7c61 parent 21468e62 files · +120 −107Browse files

Unified · Split

2 files
  1. include/uapi/linux/can/gw.h +3 −2
  2. net/can/gw.c +117 −105
include/uapi/linux/can/gw.h+3−2
@@ -93,10 +93,11 @@ enum { · 92 unmodified lines
9393
9494 /* CAN frame elements that are affected by curr. 3 CAN frame modifications */
9595 #define CGW_MOD_ID 0x01
96−#define CGW_MOD_DLC 0x02
96+#define CGW_MOD_DLC 0x02 /* contains the data length in bytes */
97+#define CGW_MOD_LEN CGW_MOD_DLC /* CAN FD length representation */
9798 #define CGW_MOD_DATA 0x04
9899
99−#define CGW_FRAME_MODS 3 /* ID DLC DATA */
100+#define CGW_FRAME_MODS 3 /* ID DLC/LEN DATA */
100101
101102 #define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS)
102103
net/can/gw.c+117−105
@@ -85,10 +85,10 @@ static struct kmem_cache *cgw_cache __read_mostly; · 84 unmodified lines
8585 /* structure that contains the (on-the-fly) CAN frame modifications */
8686 struct cf_mod {
8787 struct {
88− struct can_frame and;
89− struct can_frame or;
90− struct can_frame xor;
91− struct can_frame set;
88+ struct canfd_frame and;
89+ struct canfd_frame or;
90+ struct canfd_frame xor;
91+ struct canfd_frame set;
9292 } modframe;
9393 struct {
9494 u8 and;
@@ -96,7 +96,7 @@ struct cf_mod { · 1 unmodified line
9696 u8 xor;
9797 u8 set;
9898 } modtype;
99− void (*modfunc[MAX_MODFUNCTIONS])(struct can_frame *cf,
99+ void (*modfunc[MAX_MODFUNCTIONS])(struct canfd_frame *cf,
100100 struct cf_mod *mod);
101101
102102 /* CAN frame checksum calculation after CAN frame modifications */
@@ -105,8 +105,10 @@ struct cf_mod { · 2 unmodified lines
105105 struct cgw_csum_crc8 crc8;
106106 } csum;
107107 struct {
108− void (*xor)(struct can_frame *cf, struct cgw_csum_xor *xor);
109− void (*crc8)(struct can_frame *cf, struct cgw_csum_crc8 *crc8);
108+ void (*xor)(struct canfd_frame *cf,
109+ struct cgw_csum_xor *xor);
110+ void (*crc8)(struct canfd_frame *cf,
111+ struct cgw_csum_crc8 *crc8);
110112 } csumfunc;
111113 u32 uid;
112114 };
@@ -149,23 +151,23 @@ struct cgw_job { · 36 unmodified lines
149151
150152 /* modification functions that are invoked in the hot path in can_can_gw_rcv */
151153
152−#define MODFUNC(func, op) static void func(struct can_frame *cf, \
154+#define MODFUNC(func, op) static void func(struct canfd_frame *cf, \
153155 struct cf_mod *mod) { op ; }
154156
155157 MODFUNC(mod_and_id, cf->can_id &= mod->modframe.and.can_id)
156−MODFUNC(mod_and_dlc, cf->can_dlc &= mod->modframe.and.can_dlc)
158+MODFUNC(mod_and_len, cf->len &= mod->modframe.and.len)
157159 MODFUNC(mod_and_data, *(u64 *)cf->data &= *(u64 *)mod->modframe.and.data)
158160 MODFUNC(mod_or_id, cf->can_id |= mod->modframe.or.can_id)
159−MODFUNC(mod_or_dlc, cf->can_dlc |= mod->modframe.or.can_dlc)
161+MODFUNC(mod_or_len, cf->len |= mod->modframe.or.len)
160162 MODFUNC(mod_or_data, *(u64 *)cf->data |= *(u64 *)mod->modframe.or.data)
161163 MODFUNC(mod_xor_id, cf->can_id ^= mod->modframe.xor.can_id)
162−MODFUNC(mod_xor_dlc, cf->can_dlc ^= mod->modframe.xor.can_dlc)
164+MODFUNC(mod_xor_len, cf->len ^= mod->modframe.xor.len)
163165 MODFUNC(mod_xor_data, *(u64 *)cf->data ^= *(u64 *)mod->modframe.xor.data)
164166 MODFUNC(mod_set_id, cf->can_id = mod->modframe.set.can_id)
165−MODFUNC(mod_set_dlc, cf->can_dlc = mod->modframe.set.can_dlc)
167+MODFUNC(mod_set_len, cf->len = mod->modframe.set.len)
166168 MODFUNC(mod_set_data, *(u64 *)cf->data = *(u64 *)mod->modframe.set.data)
167169
168−static inline void canframecpy(struct can_frame *dst, struct can_frame *src)
170+static void canframecpy(struct canfd_frame *dst, struct can_frame *src)
169171 {
170172 /* Copy the struct members separately to ensure that no uninitialized
171173 * data are copied in the 3 bytes hole of the struct. This is needed
@@ -173,12 +175,14 @@ static inline void canframecpy(struct can_frame *dst, struct can_frame *src) · 1 unmodified line
173175 */
174176
175177 dst->can_id = src->can_id;
176− dst->can_dlc = src->can_dlc;
178+ dst->len = src->can_dlc;
177179 *(u64 *)dst->data = *(u64 *)src->data;
178180 }
179181
180182 static int cgw_chk_csum_parms(s8 fr, s8 to, s8 re)
181183 {
184+ s8 dlen = CAN_MAX_DLEN;
185+
182186 /* absolute dlc values 0 .. 7 => 0 .. 7, e.g. data [0]
183187 * relative to received dlc -1 .. -8 :
184188 * e.g. for received dlc = 8
@@ -187,27 +191,27 @@ static int cgw_chk_csum_parms(s8 fr, s8 to, s8 re) · 2 unmodified lines
187191 * -8 => index = 0 (data[0])
188192 */
189193
190− if (fr > -9 && fr < 8 &&
191− to > -9 && to < 8 &&
192− re > -9 && re < 8)
194+ if (fr >= -dlen && fr < dlen &&
195+ to >= -dlen && to < dlen &&
196+ re >= -dlen && re < dlen)
193197 return 0;
194198 else
195199 return -EINVAL;
196200 }
197201
198−static inline int calc_idx(int idx, int rx_dlc)
202+static inline int calc_idx(int idx, int rx_len)
199203 {
200204 if (idx < 0)
201− return rx_dlc + idx;
205+ return rx_len + idx;
202206 else
203207 return idx;
204208 }
205209
206−static void cgw_csum_xor_rel(struct can_frame *cf, struct cgw_csum_xor *xor)
210+static void cgw_csum_xor_rel(struct canfd_frame *cf, struct cgw_csum_xor *xor)
207211 {
208− int from = calc_idx(xor->from_idx, cf->can_dlc);
209− int to = calc_idx(xor->to_idx, cf->can_dlc);
210− int res = calc_idx(xor->result_idx, cf->can_dlc);
212+ int from = calc_idx(xor->from_idx, cf->len);
213+ int to = calc_idx(xor->to_idx, cf->len);
214+ int res = calc_idx(xor->result_idx, cf->len);
211215 u8 val = xor->init_xor_val;
212216 int i;
213217
@@ -225,7 +229,7 @@ static void cgw_csum_xor_rel(struct can_frame *cf, struct cgw_csum_xor *xor) · 11 unmodified lines
225229 cf->data[res] = val;
226230 }
227231
228−static void cgw_csum_xor_pos(struct can_frame *cf, struct cgw_csum_xor *xor)
232+static void cgw_csum_xor_pos(struct canfd_frame *cf, struct cgw_csum_xor *xor)
229233 {
230234 u8 val = xor->init_xor_val;
231235 int i;
@@ -236,7 +240,7 @@ static void cgw_csum_xor_pos(struct can_frame *cf, struct cgw_csum_xor *xor) · 4 unmodified lines
236240 cf->data[xor->result_idx] = val;
237241 }
238242
239−static void cgw_csum_xor_neg(struct can_frame *cf, struct cgw_csum_xor *xor)
243+static void cgw_csum_xor_neg(struct canfd_frame *cf, struct cgw_csum_xor *xor)
240244 {
241245 u8 val = xor->init_xor_val;
242246 int i;
@@ -247,11 +251,12 @@ static void cgw_csum_xor_neg(struct can_frame *cf, struct cgw_csum_xor *xor) · 4 unmodified lines
247251 cf->data[xor->result_idx] = val;
248252 }
249253
250−static void cgw_csum_crc8_rel(struct can_frame *cf, struct cgw_csum_crc8 *crc8)
254+static void cgw_csum_crc8_rel(struct canfd_frame *cf,
255+ struct cgw_csum_crc8 *crc8)
251256 {
252− int from = calc_idx(crc8->from_idx, cf->can_dlc);
253− int to = calc_idx(crc8->to_idx, cf->can_dlc);
254− int res = calc_idx(crc8->result_idx, cf->can_dlc);
257+ int from = calc_idx(crc8->from_idx, cf->len);
258+ int to = calc_idx(crc8->to_idx, cf->len);
259+ int res = calc_idx(crc8->result_idx, cf->len);
255260 u8 crc = crc8->init_crc_val;
256261 int i;
257262
@@ -284,7 +289,8 @@ static void cgw_csum_crc8_rel(struct can_frame *cf, struct cgw_csum_crc8 *crc8) · 26 unmodified lines
284289 cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;
285290 }
286291
287−static void cgw_csum_crc8_pos(struct can_frame *cf, struct cgw_csum_crc8 *crc8)
292+static void cgw_csum_crc8_pos(struct canfd_frame *cf,
293+ struct cgw_csum_crc8 *crc8)
288294 {
289295 u8 crc = crc8->init_crc_val;
290296 int i;
@@ -310,7 +316,8 @@ static void cgw_csum_crc8_pos(struct can_frame *cf, struct cgw_csum_crc8 *crc8) · 19 unmodified lines
310316 cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val;
311317 }
312318
313−static void cgw_csum_crc8_neg(struct can_frame *cf, struct cgw_csum_crc8 *crc8)
319+static void cgw_csum_crc8_neg(struct canfd_frame *cf,
320+ struct cgw_csum_crc8 *crc8)
314321 {
315322 u8 crc = crc8->init_crc_val;
316323 int i;
@@ -340,7 +347,7 @@ static void cgw_csum_crc8_neg(struct can_frame *cf, struct cgw_csum_crc8 *crc8) · 23 unmodified lines
340347 static void can_can_gw_rcv(struct sk_buff *skb, void *data)
341348 {
342349 struct cgw_job *gwj = (struct cgw_job *)data;
343− struct can_frame *cf;
350+ struct canfd_frame *cf;
344351 struct sk_buff *nskb;
345352 int modidx = 0;
346353
@@ -400,7 +407,7 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) · 53 unmodified lines
400407 nskb->dev = gwj->dst.dev;
401408
402409 /* pointer to modifiable CAN frame */
403− cf = (struct can_frame *)nskb->data;
410+ cf = (struct canfd_frame *)nskb->data;
404411
405412 /* perform preprocessed modification functions if there are any */
406413 while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx])
@@ -409,22 +416,22 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) · 2 unmodified lines
409416 /* Has the CAN frame been modified? */
410417 if (modidx) {
411418 /* get available space for the processed CAN frame type */
412− int max_len = nskb->len - offsetof(struct can_frame, data);
419+ int max_len = nskb->len - offsetof(struct canfd_frame, data);
413420
414421 /* dlc may have changed, make sure it fits to the CAN frame */
415− if (cf->can_dlc > max_len)
422+ if (cf->len > max_len)
416423 goto out_delete;
417424
418425 /* check for checksum updates in classic CAN length only */
419426 if (gwj->mod.csumfunc.crc8) {
420− if (cf->can_dlc > 8)
427+ if (cf->len > 8)
421428 goto out_delete;
422429
423430 (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8);
424431 }
425432
426433 if (gwj->mod.csumfunc.xor) {
427− if (cf->can_dlc > 8)
434+ if (cf->len > 8)
428435 goto out_delete;
429436
430437 (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor);
@@ -492,7 +499,6 @@ static int cgw_notifier(struct notifier_block *nb, · 61 unmodified lines
492499 static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,
493500 u32 pid, u32 seq, int flags)
494501 {
495− struct cgw_frame_mod mb;
496502 struct rtcanmsg *rtcan;
497503 struct nlmsghdr *nlh;
498504
@@ -529,32 +535,36 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type, · 30 unmodified lines
529535 goto cancel;
530536 }
531537
532− if (gwj->mod.modtype.and) {
533− memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf));
534− mb.modtype = gwj->mod.modtype.and;
535− if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0)
536− goto cancel;
537− }
538+ if (1) {
539+ struct cgw_frame_mod mb;
538540
539− if (gwj->mod.modtype.or) {
540− memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf));
541− mb.modtype = gwj->mod.modtype.or;
542− if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0)
543− goto cancel;
544− }
541+ if (gwj->mod.modtype.and) {
542+ memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf));
543+ mb.modtype = gwj->mod.modtype.and;
544+ if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0)
545+ goto cancel;
546+ }
545547
546− if (gwj->mod.modtype.xor) {
547− memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf));
548− mb.modtype = gwj->mod.modtype.xor;
549− if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0)
550− goto cancel;
551− }
548+ if (gwj->mod.modtype.or) {
549+ memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf));
550+ mb.modtype = gwj->mod.modtype.or;
551+ if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0)
552+ goto cancel;
553+ }
552554
553− if (gwj->mod.modtype.set) {
554− memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf));
555− mb.modtype = gwj->mod.modtype.set;
556− if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0)
557− goto cancel;
555+ if (gwj->mod.modtype.xor) {
556+ memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf));
557+ mb.modtype = gwj->mod.modtype.xor;
558+ if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0)
559+ goto cancel;
560+ }
561+
562+ if (gwj->mod.modtype.set) {
563+ memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf));
564+ mb.modtype = gwj->mod.modtype.set;
565+ if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0)
566+ goto cancel;
567+ }
558568 }
559569
560570 if (gwj->mod.uid) {
@@ -642,7 +652,6 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod, · 81 unmodified lines
642652 u8 gwtype, void *gwtypeattr, u8 *limhops)
643653 {
644654 struct nlattr *tb[CGW_MAX + 1];
645− struct cgw_frame_mod mb;
646655 int modidx = 0;
647656 int err = 0;
648657
@@ -662,69 +671,72 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod, · 13 unmodified lines
662671 }
663672
664673 /* check for AND/OR/XOR/SET modifications */
674+ if (1) {
675+ struct cgw_frame_mod mb;
665676
666− if (tb[CGW_MOD_AND]) {
667− nla_memcpy(&mb, tb[CGW_MOD_AND], CGW_MODATTR_LEN);
677+ if (tb[CGW_MOD_AND]) {
678+ nla_memcpy(&mb, tb[CGW_MOD_AND], CGW_MODATTR_LEN);
668679
669− canframecpy(&mod->modframe.and, &mb.cf);
670− mod->modtype.and = mb.modtype;
680+ canframecpy(&mod->modframe.and, &mb.cf);
681+ mod->modtype.and = mb.modtype;
671682
672− if (mb.modtype & CGW_MOD_ID)
673− mod->modfunc[modidx++] = mod_and_id;
683+ if (mb.modtype & CGW_MOD_ID)
684+ mod->modfunc[modidx++] = mod_and_id;
674685
675− if (mb.modtype & CGW_MOD_DLC)
676− mod->modfunc[modidx++] = mod_and_dlc;
686+ if (mb.modtype & CGW_MOD_LEN)
687+ mod->modfunc[modidx++] = mod_and_len;
677688
678− if (mb.modtype & CGW_MOD_DATA)
679− mod->modfunc[modidx++] = mod_and_data;
680− }
689+ if (mb.modtype & CGW_MOD_DATA)
690+ mod->modfunc[modidx++] = mod_and_data;
691+ }
681692
682− if (tb[CGW_MOD_OR]) {
683− nla_memcpy(&mb, tb[CGW_MOD_OR], CGW_MODATTR_LEN);
693+ if (tb[CGW_MOD_OR]) {
694+ nla_memcpy(&mb, tb[CGW_MOD_OR], CGW_MODATTR_LEN);
684695
685− canframecpy(&mod->modframe.or, &mb.cf);
686− mod->modtype.or = mb.modtype;
696+ canframecpy(&mod->modframe.or, &mb.cf);
697+ mod->modtype.or = mb.modtype;
687698
688− if (mb.modtype & CGW_MOD_ID)
689− mod->modfunc[modidx++] = mod_or_id;
699+ if (mb.modtype & CGW_MOD_ID)
700+ mod->modfunc[modidx++] = mod_or_id;
690701
691− if (mb.modtype & CGW_MOD_DLC)
692− mod->modfunc[modidx++] = mod_or_dlc;
702+ if (mb.modtype & CGW_MOD_LEN)
703+ mod->modfunc[modidx++] = mod_or_len;
693704
694− if (mb.modtype & CGW_MOD_DATA)
695− mod->modfunc[modidx++] = mod_or_data;
696− }
705+ if (mb.modtype & CGW_MOD_DATA)
706+ mod->modfunc[modidx++] = mod_or_data;
707+ }
697708
698− if (tb[CGW_MOD_XOR]) {
699− nla_memcpy(&mb, tb[CGW_MOD_XOR], CGW_MODATTR_LEN);
709+ if (tb[CGW_MOD_XOR]) {
710+ nla_memcpy(&mb, tb[CGW_MOD_XOR], CGW_MODATTR_LEN);
700711
701− canframecpy(&mod->modframe.xor, &mb.cf);
702− mod->modtype.xor = mb.modtype;
712+ canframecpy(&mod->modframe.xor, &mb.cf);
713+ mod->modtype.xor = mb.modtype;
703714
704− if (mb.modtype & CGW_MOD_ID)
705− mod->modfunc[modidx++] = mod_xor_id;
715+ if (mb.modtype & CGW_MOD_ID)
716+ mod->modfunc[modidx++] = mod_xor_id;
706717
707− if (mb.modtype & CGW_MOD_DLC)
708− mod->modfunc[modidx++] = mod_xor_dlc;
718+ if (mb.modtype & CGW_MOD_LEN)
719+ mod->modfunc[modidx++] = mod_xor_len;
709720
710− if (mb.modtype & CGW_MOD_DATA)
711− mod->modfunc[modidx++] = mod_xor_data;
712− }
721+ if (mb.modtype & CGW_MOD_DATA)
722+ mod->modfunc[modidx++] = mod_xor_data;
723+ }
713724
714− if (tb[CGW_MOD_SET]) {
715− nla_memcpy(&mb, tb[CGW_MOD_SET], CGW_MODATTR_LEN);
725+ if (tb[CGW_MOD_SET]) {
726+ nla_memcpy(&mb, tb[CGW_MOD_SET], CGW_MODATTR_LEN);
716727
717− canframecpy(&mod->modframe.set, &mb.cf);
718− mod->modtype.set = mb.modtype;
728+ canframecpy(&mod->modframe.set, &mb.cf);
729+ mod->modtype.set = mb.modtype;
719730
720− if (mb.modtype & CGW_MOD_ID)
721− mod->modfunc[modidx++] = mod_set_id;
731+ if (mb.modtype & CGW_MOD_ID)
732+ mod->modfunc[modidx++] = mod_set_id;
722733
723− if (mb.modtype & CGW_MOD_DLC)
724− mod->modfunc[modidx++] = mod_set_dlc;
734+ if (mb.modtype & CGW_MOD_LEN)
735+ mod->modfunc[modidx++] = mod_set_len;
725736
726− if (mb.modtype & CGW_MOD_DATA)
727− mod->modfunc[modidx++] = mod_set_data;
737+ if (mb.modtype & CGW_MOD_DATA)
738+ mod->modfunc[modidx++] = mod_set_data;
739+ }
728740 }
729741
730742 /* check for checksum operations after CAN frame modifications */