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

Merge branch 'for-davem' of git://gitorious.org/linux-can/linux-can-next

+320 -23
+3
Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
··· 11 11 12 12 - reg : Offset and length of the register set for this device 13 13 - interrupts : Interrupt tuple for this device 14 + 15 + Optional properties: 16 + 14 17 - clock-frequency : The oscillator frequency driving the flexcan device 15 18 16 19 Example:
+1 -1
drivers/net/can/cc770/cc770.c
··· 695 695 netif_wake_queue(dev); 696 696 } 697 697 698 - irqreturn_t cc770_interrupt(int irq, void *dev_id) 698 + static irqreturn_t cc770_interrupt(int irq, void *dev_id) 699 699 { 700 700 struct net_device *dev = (struct net_device *)dev_id; 701 701 struct cc770_priv *priv = netdev_priv(dev);
+1 -1
drivers/net/can/dev.c
··· 401 401 /* 402 402 * CAN device restart for bus-off recovery 403 403 */ 404 - void can_restart(unsigned long data) 404 + static void can_restart(unsigned long data) 405 405 { 406 406 struct net_device *dev = (struct net_device *)data; 407 407 struct can_priv *priv = netdev_priv(dev);
+55 -16
drivers/net/can/flexcan.c
··· 34 34 #include <linux/list.h> 35 35 #include <linux/module.h> 36 36 #include <linux/of.h> 37 + #include <linux/of_device.h> 37 38 #include <linux/platform_device.h> 38 39 #include <linux/pinctrl/consumer.h> 39 40 ··· 166 165 u32 imask1; /* 0x28 */ 167 166 u32 iflag2; /* 0x2c */ 168 167 u32 iflag1; /* 0x30 */ 169 - u32 _reserved2[19]; 168 + u32 crl2; /* 0x34 */ 169 + u32 esr2; /* 0x38 */ 170 + u32 imeur; /* 0x3c */ 171 + u32 lrfr; /* 0x40 */ 172 + u32 crcr; /* 0x44 */ 173 + u32 rxfgmask; /* 0x48 */ 174 + u32 rxfir; /* 0x4c */ 175 + u32 _reserved3[12]; 170 176 struct flexcan_mb cantxfg[64]; 177 + }; 178 + 179 + struct flexcan_devtype_data { 180 + u32 hw_ver; /* hardware controller version */ 171 181 }; 172 182 173 183 struct flexcan_priv { ··· 192 180 193 181 struct clk *clk; 194 182 struct flexcan_platform_data *pdata; 183 + struct flexcan_devtype_data *devtype_data; 184 + }; 185 + 186 + static struct flexcan_devtype_data fsl_p1010_devtype_data = { 187 + .hw_ver = 3, 188 + }; 189 + 190 + static struct flexcan_devtype_data fsl_imx6q_devtype_data = { 191 + .hw_ver = 10, 195 192 }; 196 193 197 194 static struct can_bittiming_const flexcan_bittiming_const = { ··· 771 750 flexcan_write(0x0, &regs->rx14mask); 772 751 flexcan_write(0x0, &regs->rx15mask); 773 752 753 + if (priv->devtype_data->hw_ver >= 10) 754 + flexcan_write(0x0, &regs->rxfgmask); 755 + 774 756 flexcan_transceiver_switch(priv, 1); 775 757 776 758 /* synchronize with the can bus */ ··· 946 922 unregister_candev(dev); 947 923 } 948 924 925 + static const struct of_device_id flexcan_of_match[] = { 926 + { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, 927 + { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, 928 + { /* sentinel */ }, 929 + }; 930 + 931 + static const struct platform_device_id flexcan_id_table[] = { 932 + { .name = "flexcan", .driver_data = (kernel_ulong_t)&fsl_p1010_devtype_data, }, 933 + { /* sentinel */ }, 934 + }; 935 + 949 936 static int __devinit flexcan_probe(struct platform_device *pdev) 950 937 { 938 + const struct of_device_id *of_id; 939 + struct flexcan_devtype_data *devtype_data; 951 940 struct net_device *dev; 952 941 struct flexcan_priv *priv; 953 942 struct resource *mem; ··· 975 938 if (IS_ERR(pinctrl)) 976 939 return PTR_ERR(pinctrl); 977 940 978 - if (pdev->dev.of_node) { 979 - const __be32 *clock_freq_p; 980 - 981 - clock_freq_p = of_get_property(pdev->dev.of_node, 982 - "clock-frequency", NULL); 983 - if (clock_freq_p) 984 - clock_freq = be32_to_cpup(clock_freq_p); 985 - } 941 + if (pdev->dev.of_node) 942 + of_property_read_u32(pdev->dev.of_node, 943 + "clock-frequency", &clock_freq); 986 944 987 945 if (!clock_freq) { 988 946 clk = clk_get(&pdev->dev, NULL); ··· 1014 982 goto failed_alloc; 1015 983 } 1016 984 985 + of_id = of_match_device(flexcan_of_match, &pdev->dev); 986 + if (of_id) { 987 + devtype_data = of_id->data; 988 + } else if (pdev->id_entry->driver_data) { 989 + devtype_data = (struct flexcan_devtype_data *) 990 + pdev->id_entry->driver_data; 991 + } else { 992 + err = -ENODEV; 993 + goto failed_devtype; 994 + } 995 + 1017 996 dev->netdev_ops = &flexcan_netdev_ops; 1018 997 dev->irq = irq; 1019 998 dev->flags |= IFF_ECHO; ··· 1041 998 priv->dev = dev; 1042 999 priv->clk = clk; 1043 1000 priv->pdata = pdev->dev.platform_data; 1001 + priv->devtype_data = devtype_data; 1044 1002 1045 1003 netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); 1046 1004 ··· 1060 1016 return 0; 1061 1017 1062 1018 failed_register: 1019 + failed_devtype: 1063 1020 free_candev(dev); 1064 1021 failed_alloc: 1065 1022 iounmap(base); ··· 1093 1048 1094 1049 return 0; 1095 1050 } 1096 - 1097 - static struct of_device_id flexcan_of_match[] = { 1098 - { 1099 - .compatible = "fsl,p1010-flexcan", 1100 - }, 1101 - {}, 1102 - }; 1103 1051 1104 1052 #ifdef CONFIG_PM 1105 1053 static int flexcan_suspend(struct platform_device *pdev, pm_message_t state) ··· 1140 1102 .remove = __devexit_p(flexcan_remove), 1141 1103 .suspend = flexcan_suspend, 1142 1104 .resume = flexcan_resume, 1105 + .id_table = flexcan_id_table, 1143 1106 }; 1144 1107 1145 1108 module_platform_driver(flexcan_driver);
+3
include/linux/can.h
··· 38 38 */ 39 39 typedef __u32 canid_t; 40 40 41 + #define CAN_SFF_ID_BITS 11 42 + #define CAN_EFF_ID_BITS 29 43 + 41 44 /* 42 45 * Controller Area Network Error Message Frame Mask structure 43 46 *
+3 -2
include/linux/pkt_cls.h
··· 451 451 #define TCF_EM_U32 3 452 452 #define TCF_EM_META 4 453 453 #define TCF_EM_TEXT 5 454 - #define TCF_EM_VLAN 6 455 - #define TCF_EM_MAX 6 454 + #define TCF_EM_VLAN 6 455 + #define TCF_EM_CANID 7 456 + #define TCF_EM_MAX 7 456 457 457 458 enum { 458 459 TCF_EM_PROG_TC
+3
net/can/af_can.h
··· 104 104 unsigned long rcv_entries_max; 105 105 }; 106 106 107 + /* receive filters subscribed for 'all' CAN devices */ 108 + extern struct dev_rcv_lists can_rx_alldev_list; 109 + 107 110 /* function prototypes for the CAN networklayer procfs (proc.c) */ 108 111 extern void can_init_proc(void); 109 112 extern void can_remove_proc(void);
-3
net/can/proc.c
··· 83 83 [RX_EFF] = "rx_eff", 84 84 }; 85 85 86 - /* receive filters subscribed for 'all' CAN devices */ 87 - extern struct dev_rcv_lists can_rx_alldev_list; 88 - 89 86 /* 90 87 * af_can statistics stuff 91 88 */
+10
net/sched/Kconfig
··· 507 507 To compile this code as a module, choose M here: the 508 508 module will be called em_text. 509 509 510 + config NET_EMATCH_CANID 511 + tristate "CAN Identifier" 512 + depends on NET_EMATCH && CAN 513 + ---help--- 514 + Say Y here if you want to be able to classify CAN frames based 515 + on CAN Identifier. 516 + 517 + To compile this code as a module, choose M here: the 518 + module will be called em_canid. 519 + 510 520 config NET_CLS_ACT 511 521 bool "Actions" 512 522 ---help---
+1
net/sched/Makefile
··· 55 55 obj-$(CONFIG_NET_EMATCH_U32) += em_u32.o 56 56 obj-$(CONFIG_NET_EMATCH_META) += em_meta.o 57 57 obj-$(CONFIG_NET_EMATCH_TEXT) += em_text.o 58 + obj-$(CONFIG_NET_EMATCH_CANID) += em_canid.o
+240
net/sched/em_canid.c
··· 1 + /* 2 + * em_canid.c Ematch rule to match CAN frames according to their CAN IDs 3 + * 4 + * This program is free software; you can distribute it and/or 5 + * modify it under the terms of the GNU General Public License 6 + * as published by the Free Software Foundation; either version 7 + * 2 of the License, or (at your option) any later version. 8 + * 9 + * Idea: Oliver Hartkopp <oliver.hartkopp@volkswagen.de> 10 + * Copyright: (c) 2011 Czech Technical University in Prague 11 + * (c) 2011 Volkswagen Group Research 12 + * Authors: Michal Sojka <sojkam1@fel.cvut.cz> 13 + * Pavel Pisa <pisa@cmp.felk.cvut.cz> 14 + * Rostislav Lisovy <lisovy@gmail.cz> 15 + * Funded by: Volkswagen Group Research 16 + */ 17 + 18 + #include <linux/slab.h> 19 + #include <linux/module.h> 20 + #include <linux/types.h> 21 + #include <linux/kernel.h> 22 + #include <linux/string.h> 23 + #include <linux/skbuff.h> 24 + #include <net/pkt_cls.h> 25 + #include <linux/can.h> 26 + 27 + #define EM_CAN_RULES_MAX 500 28 + 29 + struct canid_match { 30 + /* For each SFF CAN ID (11 bit) there is one record in this bitfield */ 31 + DECLARE_BITMAP(match_sff, (1 << CAN_SFF_ID_BITS)); 32 + 33 + int rules_count; 34 + int sff_rules_count; 35 + int eff_rules_count; 36 + 37 + /* 38 + * Raw rules copied from netlink message; Used for sending 39 + * information to userspace (when 'tc filter show' is invoked) 40 + * AND when matching EFF frames 41 + */ 42 + struct can_filter rules_raw[]; 43 + }; 44 + 45 + /** 46 + * em_canid_get_id() - Extracts Can ID out of the sk_buff structure. 47 + */ 48 + static canid_t em_canid_get_id(struct sk_buff *skb) 49 + { 50 + /* CAN ID is stored within the data field */ 51 + struct can_frame *cf = (struct can_frame *)skb->data; 52 + 53 + return cf->can_id; 54 + } 55 + 56 + static void em_canid_sff_match_add(struct canid_match *cm, u32 can_id, 57 + u32 can_mask) 58 + { 59 + int i; 60 + 61 + /* 62 + * Limit can_mask and can_id to SFF range to 63 + * protect against write after end of array 64 + */ 65 + can_mask &= CAN_SFF_MASK; 66 + can_id &= can_mask; 67 + 68 + /* Single frame */ 69 + if (can_mask == CAN_SFF_MASK) { 70 + set_bit(can_id, cm->match_sff); 71 + return; 72 + } 73 + 74 + /* All frames */ 75 + if (can_mask == 0) { 76 + bitmap_fill(cm->match_sff, (1 << CAN_SFF_ID_BITS)); 77 + return; 78 + } 79 + 80 + /* 81 + * Individual frame filter. 82 + * Add record (set bit to 1) for each ID that 83 + * conforms particular rule 84 + */ 85 + for (i = 0; i < (1 << CAN_SFF_ID_BITS); i++) { 86 + if ((i & can_mask) == can_id) 87 + set_bit(i, cm->match_sff); 88 + } 89 + } 90 + 91 + static inline struct canid_match *em_canid_priv(struct tcf_ematch *m) 92 + { 93 + return (struct canid_match *)m->data; 94 + } 95 + 96 + static int em_canid_match(struct sk_buff *skb, struct tcf_ematch *m, 97 + struct tcf_pkt_info *info) 98 + { 99 + struct canid_match *cm = em_canid_priv(m); 100 + canid_t can_id; 101 + int match = 0; 102 + int i; 103 + const struct can_filter *lp; 104 + 105 + can_id = em_canid_get_id(skb); 106 + 107 + if (can_id & CAN_EFF_FLAG) { 108 + for (i = 0, lp = cm->rules_raw; 109 + i < cm->eff_rules_count; i++, lp++) { 110 + if (!(((lp->can_id ^ can_id) & lp->can_mask))) { 111 + match = 1; 112 + break; 113 + } 114 + } 115 + } else { /* SFF */ 116 + can_id &= CAN_SFF_MASK; 117 + match = (test_bit(can_id, cm->match_sff) ? 1 : 0); 118 + } 119 + 120 + return match; 121 + } 122 + 123 + static int em_canid_change(struct tcf_proto *tp, void *data, int len, 124 + struct tcf_ematch *m) 125 + { 126 + struct can_filter *conf = data; /* Array with rules */ 127 + struct canid_match *cm; 128 + struct canid_match *cm_old = (struct canid_match *)m->data; 129 + int i; 130 + 131 + if (!len) 132 + return -EINVAL; 133 + 134 + if (len % sizeof(struct can_filter)) 135 + return -EINVAL; 136 + 137 + if (len > sizeof(struct can_filter) * EM_CAN_RULES_MAX) 138 + return -EINVAL; 139 + 140 + cm = kzalloc(sizeof(struct canid_match) + len, GFP_KERNEL); 141 + if (!cm) 142 + return -ENOMEM; 143 + 144 + cm->rules_count = len / sizeof(struct can_filter); 145 + 146 + /* 147 + * We need two for() loops for copying rules into two contiguous 148 + * areas in rules_raw to process all eff rules with a simple loop. 149 + * NB: The configuration interface supports sff and eff rules. 150 + * We do not support filters here that match for the same can_id 151 + * provided in a SFF and EFF frame (e.g. 0x123 / 0x80000123). 152 + * For this (unusual case) two filters have to be specified. The 153 + * SFF/EFF separation is done with the CAN_EFF_FLAG in the can_id. 154 + */ 155 + 156 + /* Fill rules_raw with EFF rules first */ 157 + for (i = 0; i < cm->rules_count; i++) { 158 + if (conf[i].can_id & CAN_EFF_FLAG) { 159 + memcpy(cm->rules_raw + cm->eff_rules_count, 160 + &conf[i], 161 + sizeof(struct can_filter)); 162 + 163 + cm->eff_rules_count++; 164 + } 165 + } 166 + 167 + /* append SFF frame rules */ 168 + for (i = 0; i < cm->rules_count; i++) { 169 + if (!(conf[i].can_id & CAN_EFF_FLAG)) { 170 + memcpy(cm->rules_raw 171 + + cm->eff_rules_count 172 + + cm->sff_rules_count, 173 + &conf[i], sizeof(struct can_filter)); 174 + 175 + cm->sff_rules_count++; 176 + 177 + em_canid_sff_match_add(cm, 178 + conf[i].can_id, conf[i].can_mask); 179 + } 180 + } 181 + 182 + m->datalen = sizeof(struct canid_match) + len; 183 + m->data = (unsigned long)cm; 184 + 185 + if (cm_old != NULL) { 186 + pr_err("canid: Configuring an existing ematch!\n"); 187 + kfree(cm_old); 188 + } 189 + 190 + return 0; 191 + } 192 + 193 + static void em_canid_destroy(struct tcf_proto *tp, struct tcf_ematch *m) 194 + { 195 + struct canid_match *cm = em_canid_priv(m); 196 + 197 + kfree(cm); 198 + } 199 + 200 + static int em_canid_dump(struct sk_buff *skb, struct tcf_ematch *m) 201 + { 202 + struct canid_match *cm = em_canid_priv(m); 203 + 204 + /* 205 + * When configuring this ematch 'rules_count' is set not to exceed 206 + * 'rules_raw' array size 207 + */ 208 + if (nla_put_nohdr(skb, sizeof(struct can_filter) * cm->rules_count, 209 + &cm->rules_raw) < 0) 210 + return -EMSGSIZE; 211 + 212 + return 0; 213 + } 214 + 215 + static struct tcf_ematch_ops em_canid_ops = { 216 + .kind = TCF_EM_CANID, 217 + .change = em_canid_change, 218 + .match = em_canid_match, 219 + .destroy = em_canid_destroy, 220 + .dump = em_canid_dump, 221 + .owner = THIS_MODULE, 222 + .link = LIST_HEAD_INIT(em_canid_ops.link) 223 + }; 224 + 225 + static int __init init_em_canid(void) 226 + { 227 + return tcf_em_register(&em_canid_ops); 228 + } 229 + 230 + static void __exit exit_em_canid(void) 231 + { 232 + tcf_em_unregister(&em_canid_ops); 233 + } 234 + 235 + MODULE_LICENSE("GPL"); 236 + 237 + module_init(init_em_canid); 238 + module_exit(exit_em_canid); 239 + 240 + MODULE_ALIAS_TCF_EMATCH(TCF_EM_CANID);