Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Oliver Hartkopp and committed by
Marc Kleine-Budde
e9dc7c60 21468e6d

+120 -107
+3 -2
include/uapi/linux/can/gw.h
··· 93 93 94 94 /* CAN frame elements that are affected by curr. 3 CAN frame modifications */ 95 95 #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 */ 97 98 #define CGW_MOD_DATA 0x04 98 99 99 - #define CGW_FRAME_MODS 3 /* ID DLC DATA */ 100 + #define CGW_FRAME_MODS 3 /* ID DLC/LEN DATA */ 100 101 101 102 #define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS) 102 103
+117 -105
net/can/gw.c
··· 85 85 /* structure that contains the (on-the-fly) CAN frame modifications */ 86 86 struct cf_mod { 87 87 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; 92 92 } modframe; 93 93 struct { 94 94 u8 and; ··· 96 96 u8 xor; 97 97 u8 set; 98 98 } modtype; 99 - void (*modfunc[MAX_MODFUNCTIONS])(struct can_frame *cf, 99 + void (*modfunc[MAX_MODFUNCTIONS])(struct canfd_frame *cf, 100 100 struct cf_mod *mod); 101 101 102 102 /* CAN frame checksum calculation after CAN frame modifications */ ··· 105 105 struct cgw_csum_crc8 crc8; 106 106 } csum; 107 107 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); 110 112 } csumfunc; 111 113 u32 uid; 112 114 }; ··· 151 149 152 150 /* modification functions that are invoked in the hot path in can_can_gw_rcv */ 153 151 154 - #define MODFUNC(func, op) static void func(struct can_frame *cf, \ 152 + #define MODFUNC(func, op) static void func(struct canfd_frame *cf, \ 155 153 struct cf_mod *mod) { op ; } 156 154 157 155 MODFUNC(mod_and_id, cf->can_id &= mod->modframe.and.can_id) 158 - MODFUNC(mod_and_dlc, cf->can_dlc &= mod->modframe.and.can_dlc) 156 + MODFUNC(mod_and_len, cf->len &= mod->modframe.and.len) 159 157 MODFUNC(mod_and_data, *(u64 *)cf->data &= *(u64 *)mod->modframe.and.data) 160 158 MODFUNC(mod_or_id, cf->can_id |= mod->modframe.or.can_id) 161 - MODFUNC(mod_or_dlc, cf->can_dlc |= mod->modframe.or.can_dlc) 159 + MODFUNC(mod_or_len, cf->len |= mod->modframe.or.len) 162 160 MODFUNC(mod_or_data, *(u64 *)cf->data |= *(u64 *)mod->modframe.or.data) 163 161 MODFUNC(mod_xor_id, cf->can_id ^= mod->modframe.xor.can_id) 164 - MODFUNC(mod_xor_dlc, cf->can_dlc ^= mod->modframe.xor.can_dlc) 162 + MODFUNC(mod_xor_len, cf->len ^= mod->modframe.xor.len) 165 163 MODFUNC(mod_xor_data, *(u64 *)cf->data ^= *(u64 *)mod->modframe.xor.data) 166 164 MODFUNC(mod_set_id, cf->can_id = mod->modframe.set.can_id) 167 - MODFUNC(mod_set_dlc, cf->can_dlc = mod->modframe.set.can_dlc) 165 + MODFUNC(mod_set_len, cf->len = mod->modframe.set.len) 168 166 MODFUNC(mod_set_data, *(u64 *)cf->data = *(u64 *)mod->modframe.set.data) 169 167 170 - static inline void canframecpy(struct can_frame *dst, struct can_frame *src) 168 + static void canframecpy(struct canfd_frame *dst, struct can_frame *src) 171 169 { 172 170 /* Copy the struct members separately to ensure that no uninitialized 173 171 * data are copied in the 3 bytes hole of the struct. This is needed ··· 175 173 */ 176 174 177 175 dst->can_id = src->can_id; 178 - dst->can_dlc = src->can_dlc; 176 + dst->len = src->can_dlc; 179 177 *(u64 *)dst->data = *(u64 *)src->data; 180 178 } 181 179 182 180 static int cgw_chk_csum_parms(s8 fr, s8 to, s8 re) 183 181 { 182 + s8 dlen = CAN_MAX_DLEN; 183 + 184 184 /* absolute dlc values 0 .. 7 => 0 .. 7, e.g. data [0] 185 185 * relative to received dlc -1 .. -8 : 186 186 * e.g. for received dlc = 8 ··· 191 187 * -8 => index = 0 (data[0]) 192 188 */ 193 189 194 - if (fr > -9 && fr < 8 && 195 - to > -9 && to < 8 && 196 - re > -9 && re < 8) 190 + if (fr >= -dlen && fr < dlen && 191 + to >= -dlen && to < dlen && 192 + re >= -dlen && re < dlen) 197 193 return 0; 198 194 else 199 195 return -EINVAL; 200 196 } 201 197 202 - static inline int calc_idx(int idx, int rx_dlc) 198 + static inline int calc_idx(int idx, int rx_len) 203 199 { 204 200 if (idx < 0) 205 - return rx_dlc + idx; 201 + return rx_len + idx; 206 202 else 207 203 return idx; 208 204 } 209 205 210 - static void cgw_csum_xor_rel(struct can_frame *cf, struct cgw_csum_xor *xor) 206 + static void cgw_csum_xor_rel(struct canfd_frame *cf, struct cgw_csum_xor *xor) 211 207 { 212 - int from = calc_idx(xor->from_idx, cf->can_dlc); 213 - int to = calc_idx(xor->to_idx, cf->can_dlc); 214 - int res = calc_idx(xor->result_idx, cf->can_dlc); 208 + int from = calc_idx(xor->from_idx, cf->len); 209 + int to = calc_idx(xor->to_idx, cf->len); 210 + int res = calc_idx(xor->result_idx, cf->len); 215 211 u8 val = xor->init_xor_val; 216 212 int i; 217 213 ··· 229 225 cf->data[res] = val; 230 226 } 231 227 232 - static void cgw_csum_xor_pos(struct can_frame *cf, struct cgw_csum_xor *xor) 228 + static void cgw_csum_xor_pos(struct canfd_frame *cf, struct cgw_csum_xor *xor) 233 229 { 234 230 u8 val = xor->init_xor_val; 235 231 int i; ··· 240 236 cf->data[xor->result_idx] = val; 241 237 } 242 238 243 - static void cgw_csum_xor_neg(struct can_frame *cf, struct cgw_csum_xor *xor) 239 + static void cgw_csum_xor_neg(struct canfd_frame *cf, struct cgw_csum_xor *xor) 244 240 { 245 241 u8 val = xor->init_xor_val; 246 242 int i; ··· 251 247 cf->data[xor->result_idx] = val; 252 248 } 253 249 254 - static void cgw_csum_crc8_rel(struct can_frame *cf, struct cgw_csum_crc8 *crc8) 250 + static void cgw_csum_crc8_rel(struct canfd_frame *cf, 251 + struct cgw_csum_crc8 *crc8) 255 252 { 256 - int from = calc_idx(crc8->from_idx, cf->can_dlc); 257 - int to = calc_idx(crc8->to_idx, cf->can_dlc); 258 - int res = calc_idx(crc8->result_idx, cf->can_dlc); 253 + int from = calc_idx(crc8->from_idx, cf->len); 254 + int to = calc_idx(crc8->to_idx, cf->len); 255 + int res = calc_idx(crc8->result_idx, cf->len); 259 256 u8 crc = crc8->init_crc_val; 260 257 int i; 261 258 ··· 289 284 cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val; 290 285 } 291 286 292 - static void cgw_csum_crc8_pos(struct can_frame *cf, struct cgw_csum_crc8 *crc8) 287 + static void cgw_csum_crc8_pos(struct canfd_frame *cf, 288 + struct cgw_csum_crc8 *crc8) 293 289 { 294 290 u8 crc = crc8->init_crc_val; 295 291 int i; ··· 316 310 cf->data[crc8->result_idx] = crc ^ crc8->final_xor_val; 317 311 } 318 312 319 - static void cgw_csum_crc8_neg(struct can_frame *cf, struct cgw_csum_crc8 *crc8) 313 + static void cgw_csum_crc8_neg(struct canfd_frame *cf, 314 + struct cgw_csum_crc8 *crc8) 320 315 { 321 316 u8 crc = crc8->init_crc_val; 322 317 int i; ··· 347 340 static void can_can_gw_rcv(struct sk_buff *skb, void *data) 348 341 { 349 342 struct cgw_job *gwj = (struct cgw_job *)data; 350 - struct can_frame *cf; 343 + struct canfd_frame *cf; 351 344 struct sk_buff *nskb; 352 345 int modidx = 0; 353 346 ··· 407 400 nskb->dev = gwj->dst.dev; 408 401 409 402 /* pointer to modifiable CAN frame */ 410 - cf = (struct can_frame *)nskb->data; 403 + cf = (struct canfd_frame *)nskb->data; 411 404 412 405 /* perform preprocessed modification functions if there are any */ 413 406 while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx]) ··· 416 409 /* Has the CAN frame been modified? */ 417 410 if (modidx) { 418 411 /* get available space for the processed CAN frame type */ 419 - int max_len = nskb->len - offsetof(struct can_frame, data); 412 + int max_len = nskb->len - offsetof(struct canfd_frame, data); 420 413 421 414 /* dlc may have changed, make sure it fits to the CAN frame */ 422 - if (cf->can_dlc > max_len) 415 + if (cf->len > max_len) 423 416 goto out_delete; 424 417 425 418 /* check for checksum updates in classic CAN length only */ 426 419 if (gwj->mod.csumfunc.crc8) { 427 - if (cf->can_dlc > 8) 420 + if (cf->len > 8) 428 421 goto out_delete; 429 422 430 423 (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8); 431 424 } 432 425 433 426 if (gwj->mod.csumfunc.xor) { 434 - if (cf->can_dlc > 8) 427 + if (cf->len > 8) 435 428 goto out_delete; 436 429 437 430 (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor); ··· 499 492 static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type, 500 493 u32 pid, u32 seq, int flags) 501 494 { 502 - struct cgw_frame_mod mb; 503 495 struct rtcanmsg *rtcan; 504 496 struct nlmsghdr *nlh; 505 497 ··· 535 529 goto cancel; 536 530 } 537 531 538 - if (gwj->mod.modtype.and) { 539 - memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf)); 540 - mb.modtype = gwj->mod.modtype.and; 541 - if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0) 542 - goto cancel; 543 - } 532 + if (1) { 533 + struct cgw_frame_mod mb; 544 534 545 - if (gwj->mod.modtype.or) { 546 - memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf)); 547 - mb.modtype = gwj->mod.modtype.or; 548 - if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0) 549 - goto cancel; 550 - } 535 + if (gwj->mod.modtype.and) { 536 + memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf)); 537 + mb.modtype = gwj->mod.modtype.and; 538 + if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0) 539 + goto cancel; 540 + } 551 541 552 - if (gwj->mod.modtype.xor) { 553 - memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf)); 554 - mb.modtype = gwj->mod.modtype.xor; 555 - if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0) 556 - goto cancel; 557 - } 542 + if (gwj->mod.modtype.or) { 543 + memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf)); 544 + mb.modtype = gwj->mod.modtype.or; 545 + if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0) 546 + goto cancel; 547 + } 558 548 559 - if (gwj->mod.modtype.set) { 560 - memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf)); 561 - mb.modtype = gwj->mod.modtype.set; 562 - if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0) 563 - goto cancel; 549 + if (gwj->mod.modtype.xor) { 550 + memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf)); 551 + mb.modtype = gwj->mod.modtype.xor; 552 + if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0) 553 + goto cancel; 554 + } 555 + 556 + if (gwj->mod.modtype.set) { 557 + memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf)); 558 + mb.modtype = gwj->mod.modtype.set; 559 + if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0) 560 + goto cancel; 561 + } 564 562 } 565 563 566 564 if (gwj->mod.uid) { ··· 652 642 u8 gwtype, void *gwtypeattr, u8 *limhops) 653 643 { 654 644 struct nlattr *tb[CGW_MAX + 1]; 655 - struct cgw_frame_mod mb; 656 645 int modidx = 0; 657 646 int err = 0; 658 647 ··· 671 662 } 672 663 673 664 /* check for AND/OR/XOR/SET modifications */ 665 + if (1) { 666 + struct cgw_frame_mod mb; 674 667 675 - if (tb[CGW_MOD_AND]) { 676 - nla_memcpy(&mb, tb[CGW_MOD_AND], CGW_MODATTR_LEN); 668 + if (tb[CGW_MOD_AND]) { 669 + nla_memcpy(&mb, tb[CGW_MOD_AND], CGW_MODATTR_LEN); 677 670 678 - canframecpy(&mod->modframe.and, &mb.cf); 679 - mod->modtype.and = mb.modtype; 671 + canframecpy(&mod->modframe.and, &mb.cf); 672 + mod->modtype.and = mb.modtype; 680 673 681 - if (mb.modtype & CGW_MOD_ID) 682 - mod->modfunc[modidx++] = mod_and_id; 674 + if (mb.modtype & CGW_MOD_ID) 675 + mod->modfunc[modidx++] = mod_and_id; 683 676 684 - if (mb.modtype & CGW_MOD_DLC) 685 - mod->modfunc[modidx++] = mod_and_dlc; 677 + if (mb.modtype & CGW_MOD_LEN) 678 + mod->modfunc[modidx++] = mod_and_len; 686 679 687 - if (mb.modtype & CGW_MOD_DATA) 688 - mod->modfunc[modidx++] = mod_and_data; 689 - } 680 + if (mb.modtype & CGW_MOD_DATA) 681 + mod->modfunc[modidx++] = mod_and_data; 682 + } 690 683 691 - if (tb[CGW_MOD_OR]) { 692 - nla_memcpy(&mb, tb[CGW_MOD_OR], CGW_MODATTR_LEN); 684 + if (tb[CGW_MOD_OR]) { 685 + nla_memcpy(&mb, tb[CGW_MOD_OR], CGW_MODATTR_LEN); 693 686 694 - canframecpy(&mod->modframe.or, &mb.cf); 695 - mod->modtype.or = mb.modtype; 687 + canframecpy(&mod->modframe.or, &mb.cf); 688 + mod->modtype.or = mb.modtype; 696 689 697 - if (mb.modtype & CGW_MOD_ID) 698 - mod->modfunc[modidx++] = mod_or_id; 690 + if (mb.modtype & CGW_MOD_ID) 691 + mod->modfunc[modidx++] = mod_or_id; 699 692 700 - if (mb.modtype & CGW_MOD_DLC) 701 - mod->modfunc[modidx++] = mod_or_dlc; 693 + if (mb.modtype & CGW_MOD_LEN) 694 + mod->modfunc[modidx++] = mod_or_len; 702 695 703 - if (mb.modtype & CGW_MOD_DATA) 704 - mod->modfunc[modidx++] = mod_or_data; 705 - } 696 + if (mb.modtype & CGW_MOD_DATA) 697 + mod->modfunc[modidx++] = mod_or_data; 698 + } 706 699 707 - if (tb[CGW_MOD_XOR]) { 708 - nla_memcpy(&mb, tb[CGW_MOD_XOR], CGW_MODATTR_LEN); 700 + if (tb[CGW_MOD_XOR]) { 701 + nla_memcpy(&mb, tb[CGW_MOD_XOR], CGW_MODATTR_LEN); 709 702 710 - canframecpy(&mod->modframe.xor, &mb.cf); 711 - mod->modtype.xor = mb.modtype; 703 + canframecpy(&mod->modframe.xor, &mb.cf); 704 + mod->modtype.xor = mb.modtype; 712 705 713 - if (mb.modtype & CGW_MOD_ID) 714 - mod->modfunc[modidx++] = mod_xor_id; 706 + if (mb.modtype & CGW_MOD_ID) 707 + mod->modfunc[modidx++] = mod_xor_id; 715 708 716 - if (mb.modtype & CGW_MOD_DLC) 717 - mod->modfunc[modidx++] = mod_xor_dlc; 709 + if (mb.modtype & CGW_MOD_LEN) 710 + mod->modfunc[modidx++] = mod_xor_len; 718 711 719 - if (mb.modtype & CGW_MOD_DATA) 720 - mod->modfunc[modidx++] = mod_xor_data; 721 - } 712 + if (mb.modtype & CGW_MOD_DATA) 713 + mod->modfunc[modidx++] = mod_xor_data; 714 + } 722 715 723 - if (tb[CGW_MOD_SET]) { 724 - nla_memcpy(&mb, tb[CGW_MOD_SET], CGW_MODATTR_LEN); 716 + if (tb[CGW_MOD_SET]) { 717 + nla_memcpy(&mb, tb[CGW_MOD_SET], CGW_MODATTR_LEN); 725 718 726 - canframecpy(&mod->modframe.set, &mb.cf); 727 - mod->modtype.set = mb.modtype; 719 + canframecpy(&mod->modframe.set, &mb.cf); 720 + mod->modtype.set = mb.modtype; 728 721 729 - if (mb.modtype & CGW_MOD_ID) 730 - mod->modfunc[modidx++] = mod_set_id; 722 + if (mb.modtype & CGW_MOD_ID) 723 + mod->modfunc[modidx++] = mod_set_id; 731 724 732 - if (mb.modtype & CGW_MOD_DLC) 733 - mod->modfunc[modidx++] = mod_set_dlc; 725 + if (mb.modtype & CGW_MOD_LEN) 726 + mod->modfunc[modidx++] = mod_set_len; 734 727 735 - if (mb.modtype & CGW_MOD_DATA) 736 - mod->modfunc[modidx++] = mod_set_data; 728 + if (mb.modtype & CGW_MOD_DATA) 729 + mod->modfunc[modidx++] = mod_set_data; 730 + } 737 731 } 738 732 739 733 /* check for checksum operations after CAN frame modifications */