]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - patch-series/net-2.6.29/09-mscan-mpc5200-driver.patch
Prelimary quilt patch stack for including the device drivers interface
[socketcan-devel.git] / patch-series / net-2.6.29 / 09-mscan-mpc5200-driver.patch
1 [PATCH 9/9] Socket-CAN: driver for the Freescale MSCAN controller
2
3 This patch adds the generic Socket-CAN driver for the MSCAN controller
4 available on some Freescale processor chips like the PowerPC MPC5200,
5 MPC512x or the m86k MC68HC12. It also includes an OF platform driver
6 for the MPC5200.
7
8 Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
9 ---
10  drivers/net/can/Kconfig             |   20 +
11  drivers/net/can/Makefile            |    1 
12  drivers/net/can/mscan/Makefile      |    9 
13  drivers/net/can/mscan/mpc52xx_can.c |  293 +++++++++++++++
14  drivers/net/can/mscan/mscan.c       |  681 ++++++++++++++++++++++++++++++++++++
15  drivers/net/can/mscan/mscan.h       |  237 ++++++++++++
16  6 files changed, 1241 insertions(+)
17
18 Index: net-next-2.6/drivers/net/can/Kconfig
19 ===================================================================
20 --- net-next-2.6.orig/drivers/net/can/Kconfig
21 +++ net-next-2.6/drivers/net/can/Kconfig
22 @@ -70,4 +70,24 @@ config CAN_KVASER_PCI
23           This driver is for the the PCIcanx and PCIcan cards (1, 2 or
24           4 channel) from Kvaser (http://www.kvaser.com).
25  
26 +config CAN_MSCAN
27 +       depends on CAN_DEV && (PPC || M68K || M68KNOMMU)
28 +       tristate "Freescale MSCAN based chips"
29 +       ---help---
30 +         The Motorola Scalable Controller Area Network (MSCAN) definition
31 +         is based on the MSCAN12 definition which is the specific
32 +         implementation of the Motorola Scalable CAN concept targeted for
33 +         the Motorola MC68HC12 Microcontroller Family.
34 +
35 +config CAN_MPC52XX
36 +       tristate "Freescale MPC5200 onboard CAN controller"
37 +       depends on CAN_MSCAN && PPC_MPC52xx
38 +       default N
39 +       ---help---
40 +         If you say yes here you get support for Freescale MPC5200
41 +         onboard dualCAN controller.
42 +
43 +         This driver can also be built as a module.  If so, the module
44 +         will be called mpc52xx_can.
45 +
46  endmenu
47 Index: net-next-2.6/drivers/net/can/Makefile
48 ===================================================================
49 --- net-next-2.6.orig/drivers/net/can/Makefile
50 +++ net-next-2.6/drivers/net/can/Makefile
51 @@ -8,5 +8,6 @@ obj-$(CONFIG_CAN_DEV)           += can-dev.o
52  can-dev-y                      := dev.o sysfs.o
53  
54  obj-$(CONFIG_CAN_SJA1000)      += sja1000/
55 +obj-$(CONFIG_CAN_MSCAN)                += mscan/
56  
57  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
58 Index: net-next-2.6/drivers/net/can/mscan/mpc52xx_can.c
59 ===================================================================
60 --- /dev/null
61 +++ net-next-2.6/drivers/net/can/mscan/mpc52xx_can.c
62 @@ -0,0 +1,293 @@
63 +/*
64 + * CAN bus driver for the Freescale MPC52xx embedded CPU.
65 + *
66 + * Copyright (C) 2004-2005 Andrey Volkov <avolkov@varma-el.com>,
67 + *                         Varma Electronics Oy
68 + * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
69 + *
70 + * This program is free software; you can redistribute it and/or modify
71 + * it under the terms of the version 2 of the GNU General Public License
72 + * as published by the Free Software Foundation
73 + *
74 + * This program is distributed in the hope that it will be useful, but
75 + * WITHOUT ANY WARRANTY; without even the implied warranty of
76 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
77 + * GNU General Public License for more details.
78 + *
79 + * You should have received a copy of the GNU General Public License
80 + * along with this program; if not, write to the Free Software
81 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
82 + */
83 +
84 +#include <linux/kernel.h>
85 +#include <linux/module.h>
86 +#include <linux/interrupt.h>
87 +#include <linux/platform_device.h>
88 +#include <linux/netdevice.h>
89 +#include <linux/can.h>
90 +#include <linux/can/dev.h>
91 +#include <linux/of_platform.h>
92 +#include <sysdev/fsl_soc.h>
93 +#include <linux/io.h>
94 +#include <asm/mpc52xx.h>
95 +
96 +#include "mscan.h"
97 +
98 +
99 +#define DRV_NAME "mpc52xx_can"
100 +
101 +static struct of_device_id mpc52xx_cdm_ids[] __devinitdata = {
102 +       { .compatible = "fsl,mpc5200-cdm", },
103 +       { .compatible = "fsl,mpc5200b-cdm", },
104 +       {}
105 +};
106 +
107 +/*
108 + * Get the frequency of the external oscillator clock connected
109 + * to the SYS_XTAL_IN pin, or retrun 0 if it cannot be determined.
110 + */
111 +static unsigned int  __devinit mpc52xx_can_xtal_freq(struct device_node *np)
112 +{
113 +       struct mpc52xx_cdm  __iomem *cdm;
114 +       struct device_node *np_cdm;
115 +       unsigned int freq;
116 +       u32 val;
117 +
118 +       freq = mpc52xx_find_ipb_freq(np);
119 +       if (!freq)
120 +               return 0;
121 +
122 +       /*
123 +        * Detemine SYS_XTAL_IN frequency from the clock domain settings
124 +        */
125 +       np_cdm = of_find_matching_node(NULL, mpc52xx_cdm_ids);
126 +       cdm = of_iomap(np_cdm, 0);
127 +       of_node_put(np_cdm);
128 +       if (!np_cdm) {
129 +               printk(KERN_ERR "%s() failed abnormally\n", __func__);
130 +               return 0;
131 +       }
132 +
133 +       if (in_8(&cdm->ipb_clk_sel) & 0x1)
134 +               freq *= 2;
135 +       val  = in_be32(&cdm->rstcfg);
136 +       if (val & (1 << 5))
137 +               freq *= 8;
138 +       else
139 +               freq *= 4;
140 +       if (val & (1 << 6))
141 +               freq /= 12;
142 +       else
143 +               freq /= 16;
144 +
145 +       iounmap(cdm);
146 +
147 +       return freq;
148 +}
149 +
150 +/*
151 + * Get frequency of the MSCAN clock source
152 + *
153 + * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock (IP_CLK)
154 + * can be selected. According to the MPC5200 user's manual, the oscillator
155 + * clock is the better choice as it has less jitter but due to a hardware
156 + * bug, it can not be selected for the old MPC5200 Rev. A chips.
157 + */
158 +
159 +static unsigned int  __devinit mpc52xx_can_clock_freq(struct device_node *np,
160 +                                                     int clock_src)
161 +{
162 +       unsigned int pvr;
163 +
164 +       pvr = mfspr(SPRN_PVR);
165 +
166 +       if (clock_src == MSCAN_CLKSRC_BUS || pvr == 0x80822011)
167 +               return mpc52xx_find_ipb_freq(np);
168 +
169 +       return mpc52xx_can_xtal_freq(np);
170 +}
171 +
172 +static int __devinit mpc52xx_can_probe(struct of_device *ofdev,
173 +                                      const struct of_device_id *id)
174 +{
175 +       struct device_node *np = ofdev->node;
176 +       struct net_device *dev;
177 +       struct can_priv *priv;
178 +       struct resource res;
179 +       void __iomem *base;
180 +       int err, irq, res_size, clock_src;
181 +
182 +       err = of_address_to_resource(np, 0, &res);
183 +       if (err) {
184 +               dev_err(&ofdev->dev, "invalid address\n");
185 +               return err;
186 +       }
187 +
188 +       res_size = res.end - res.start + 1;
189 +
190 +       if (!request_mem_region(res.start, res_size, DRV_NAME)) {
191 +               dev_err(&ofdev->dev, "couldn't request %#x..%#x\n",
192 +                       res.start, res.end);
193 +               return -EBUSY;
194 +       }
195 +
196 +       base = ioremap_nocache(res.start, res_size);
197 +       if (!base) {
198 +               dev_err(&ofdev->dev, "couldn't ioremap %#x..%#x\n",
199 +                       res.start, res.end);
200 +               err = -ENOMEM;
201 +               goto exit_release_mem;
202 +       }
203 +
204 +       irq = irq_of_parse_and_map(np, 0);
205 +       if (irq == NO_IRQ) {
206 +               dev_err(&ofdev->dev, "no irq found\n");
207 +               err = -ENODEV;
208 +               goto exit_unmap_mem;
209 +       }
210 +
211 +       dev = alloc_mscandev();
212 +       if (!dev) {
213 +               err = -ENOMEM;
214 +               goto exit_dispose_irq;
215 +       }
216 +
217 +       dev->base_addr = (unsigned long)base;
218 +       dev->irq = irq;
219 +
220 +       priv = netdev_priv(dev);
221 +
222 +       /*
223 +        * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
224 +        * (IP_CLK) can be selected as MSCAN clock source. According to
225 +        * the MPC5200 user's manual, the oscillator clock is the better
226 +        * choice as it has less jitter. For this reason, it is selected
227 +        * by default.
228 +        */
229 +       if (of_get_property(np, "clock-ipb", NULL))
230 +               clock_src = MSCAN_CLKSRC_BUS;
231 +       else
232 +               clock_src = MSCAN_CLKSRC_XTAL;
233 +       priv->bittiming.clock = mpc52xx_can_clock_freq(np, clock_src);
234 +       if (!priv->bittiming.clock) {
235 +               dev_err(&ofdev->dev, "couldn't get MSCAN clock frequency\n");
236 +               err = -ENODEV;
237 +               goto exit_free_mscan;
238 +       }
239 +
240 +       SET_NETDEV_DEV(dev, &ofdev->dev);
241 +
242 +       err = register_mscandev(dev, clock_src);
243 +       if (err) {
244 +               dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
245 +                       DRV_NAME, err);
246 +               goto exit_free_mscan;
247 +       }
248 +
249 +       dev_set_drvdata(&ofdev->dev, dev);
250 +
251 +       dev_info(&ofdev->dev, "MSCAN at 0x%lx, irq %d, clock %dHZ\n",
252 +                dev->base_addr, dev->irq, priv->bittiming.clock);
253 +
254 +       return 0;
255 +
256 +exit_free_mscan:
257 +       free_candev(dev);
258 +exit_dispose_irq:
259 +       irq_dispose_mapping(irq);
260 +exit_unmap_mem:
261 +       iounmap(base);
262 +exit_release_mem:
263 +       release_mem_region(res.start, res_size);
264 +
265 +       return err;
266 +}
267 +
268 +static int __devexit mpc52xx_can_remove(struct of_device *ofdev)
269 +{
270 +       struct net_device *dev = dev_get_drvdata(&ofdev->dev);
271 +       struct device_node *np = ofdev->node;
272 +       struct resource res;
273 +
274 +       dev_set_drvdata(&ofdev->dev, NULL);
275 +
276 +       unregister_mscandev(dev);
277 +       iounmap((void __iomem *)dev->base_addr);
278 +       irq_dispose_mapping(dev->irq);
279 +       free_candev(dev);
280 +
281 +       of_address_to_resource(np, 0, &res);
282 +       release_mem_region(res.start, res.end - res.start + 1);
283 +
284 +       return 0;
285 +}
286 +
287 +static struct mscan_regs saved_regs;
288 +static int mpc52xx_can_suspend(struct of_device *ofdev, pm_message_t state)
289 +{
290 +       struct net_device *dev = dev_get_drvdata(&ofdev->dev);
291 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
292 +
293 +       _memcpy_fromio(&saved_regs, regs, sizeof(*regs));
294 +
295 +       return 0;
296 +}
297 +
298 +static int mpc52xx_can_resume(struct of_device *ofdev)
299 +{
300 +       struct net_device *dev = dev_get_drvdata(&ofdev->dev);
301 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
302 +
303 +       regs->canctl0 |= MSCAN_INITRQ;
304 +       while ((regs->canctl1 & MSCAN_INITAK) == 0)
305 +               udelay(10);
306 +
307 +       regs->canctl1 = saved_regs.canctl1;
308 +       regs->canbtr0 = saved_regs.canbtr0;
309 +       regs->canbtr1 = saved_regs.canbtr1;
310 +       regs->canidac = saved_regs.canidac;
311 +
312 +       /* restore masks, buffers etc. */
313 +       _memcpy_toio(&regs->canidar1_0, (void *)&saved_regs.canidar1_0,
314 +                    sizeof(*regs) - offsetof(struct mscan_regs, canidar1_0));
315 +
316 +       regs->canctl0 &= ~MSCAN_INITRQ;
317 +       regs->cantbsel = saved_regs.cantbsel;
318 +       regs->canrier = saved_regs.canrier;
319 +       regs->cantier = saved_regs.cantier;
320 +       regs->canctl0 = saved_regs.canctl0;
321 +
322 +       return 0;
323 +}
324 +
325 +static struct of_device_id __devinitdata mpc52xx_can_table[] = {
326 +       {.compatible = "fsl,mpc5200-mscan"},
327 +       {.compatible = "fsl,mpc5200b-mscan"},
328 +       {},
329 +};
330 +
331 +static struct of_platform_driver mpc52xx_can_driver = {
332 +       .owner = THIS_MODULE,
333 +       .name = "mpc52xx_can",
334 +       .probe = mpc52xx_can_probe,
335 +       .remove = __devexit_p(mpc52xx_can_remove),
336 +       .suspend = mpc52xx_can_suspend,
337 +       .resume = mpc52xx_can_resume,
338 +       .match_table = mpc52xx_can_table,
339 +};
340 +
341 +static int __init mpc52xx_can_init(void)
342 +{
343 +       return of_register_platform_driver(&mpc52xx_can_driver);
344 +}
345 +module_init(mpc52xx_can_init);
346 +
347 +static void __exit mpc52xx_can_exit(void)
348 +{
349 +       return of_unregister_platform_driver(&mpc52xx_can_driver);
350 +};
351 +module_exit(mpc52xx_can_exit);
352 +
353 +MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
354 +MODULE_DESCRIPTION("Freescale MPC5200 CAN driver");
355 +MODULE_LICENSE("GPL v2");
356 Index: net-next-2.6/drivers/net/can/mscan/mscan.c
357 ===================================================================
358 --- /dev/null
359 +++ net-next-2.6/drivers/net/can/mscan/mscan.c
360 @@ -0,0 +1,681 @@
361 +/*
362 + * CAN bus driver for the alone generic (as possible as) MSCAN controller.
363 + *
364 + * Copyright (C) 2005-2006 Andrey Volkov <avolkov@varma-el.com>,
365 + *                         Varma Electronics Oy
366 + * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
367 + *
368 + * This program is free software; you can redistribute it and/or modify
369 + * it under the terms of the version 2 of the GNU General Public License
370 + * as published by the Free Software Foundation
371 + *
372 + * This program is distributed in the hope that it will be useful,
373 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
374 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
375 + * GNU General Public License for more details.
376 + *
377 + * You should have received a copy of the GNU General Public License
378 + * along with this program; if not, write to the Free Software
379 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
380 + */
381 +
382 +#include <linux/kernel.h>
383 +#include <linux/module.h>
384 +#include <linux/interrupt.h>
385 +#include <linux/delay.h>
386 +#include <linux/netdevice.h>
387 +#include <linux/if_arp.h>
388 +#include <linux/if_ether.h>
389 +#include <linux/list.h>
390 +#include <linux/can.h>
391 +#include <linux/can/dev.h>
392 +#include <linux/can/error.h>
393 +#include <linux/io.h>
394 +
395 +#include "mscan.h"
396 +
397 +#define MSCAN_NORMAL_MODE      0
398 +#define MSCAN_SLEEP_MODE       MSCAN_SLPRQ
399 +#define MSCAN_INIT_MODE                (MSCAN_INITRQ | MSCAN_SLPRQ)
400 +#define MSCAN_POWEROFF_MODE    (MSCAN_CSWAI | MSCAN_SLPRQ)
401 +#define MSCAN_SET_MODE_RETRIES 255
402 +
403 +#define BTR0_BRP_MASK          0x3f
404 +#define BTR0_SJW_SHIFT         6
405 +#define BTR0_SJW_MASK          (0x3 << BTR0_SJW_SHIFT)
406 +
407 +#define BTR1_TSEG1_MASK        0xf
408 +#define BTR1_TSEG2_SHIFT       4
409 +#define BTR1_TSEG2_MASK        (0x7 << BTR1_TSEG2_SHIFT)
410 +#define BTR1_SAM_SHIFT         7
411 +
412 +#define BTR0_SET_BRP(brp)      (((brp) - 1) & BTR0_BRP_MASK)
413 +#define BTR0_SET_SJW(sjw)      ((((sjw) - 1) << BTR0_SJW_SHIFT) & \
414 +                                BTR0_SJW_MASK)
415 +
416 +#define BTR1_SET_TSEG1(tseg1)  (((tseg1) - 1) &  BTR1_TSEG1_MASK)
417 +#define BTR1_SET_TSEG2(tseg2)  ((((tseg2) - 1) << BTR1_TSEG2_SHIFT) & \
418 +                                BTR1_TSEG2_MASK)
419 +#define BTR1_SET_SAM(sam)      (((sam) & 1) << BTR1_SAM_SHIFT)
420 +
421 +static struct can_bittiming_const mscan_bittiming_const = {
422 +       .tseg1_min = 4,
423 +       .tseg1_max = 16,
424 +       .tseg2_min = 2,
425 +       .tseg2_max = 8,
426 +       .sjw_max = 4,
427 +       .brp_min = 1,
428 +       .brp_max = 64,
429 +       .brp_inc = 1,
430 +};
431 +
432 +struct mscan_state {
433 +       u8 mode;
434 +       u8 canrier;
435 +       u8 cantier;
436 +};
437 +
438 +#define TX_QUEUE_SIZE  3
439 +
440 +struct tx_queue_entry {
441 +       struct list_head list;
442 +       u8 mask;
443 +       u8 id;
444 +};
445 +
446 +struct mscan_priv {
447 +       struct can_priv can;
448 +       long open_time;
449 +       unsigned long flags;
450 +       u8 shadow_statflg;
451 +       u8 shadow_canrier;
452 +       u8 cur_pri;
453 +       u8 tx_active;
454 +
455 +       struct list_head tx_head;
456 +       struct tx_queue_entry tx_queue[TX_QUEUE_SIZE];
457 +       struct napi_struct napi;
458 +};
459 +
460 +#define F_RX_PROGRESS  0
461 +#define F_TX_PROGRESS  1
462 +#define F_TX_WAIT_ALL  2
463 +
464 +static enum can_state state_map[] = {
465 +       CAN_STATE_ACTIVE,
466 +       CAN_STATE_BUS_WARNING,
467 +       CAN_STATE_BUS_PASSIVE,
468 +       CAN_STATE_BUS_OFF
469 +};
470 +
471 +static int mscan_set_mode(struct net_device *dev, u8 mode)
472 +{
473 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
474 +       struct mscan_priv *priv = netdev_priv(dev);
475 +       int ret = 0;
476 +       int i;
477 +       u8 canctl1;
478 +
479 +       if (mode != MSCAN_NORMAL_MODE) {
480 +
481 +               if (priv->tx_active) {
482 +                       /* Abort transfers before going to sleep */
483 +                       out_8(&regs->cantier, 0);
484 +                       out_8(&regs->cantarq, priv->tx_active);
485 +                       out_8(&regs->cantier, priv->tx_active);
486 +               }
487 +
488 +               canctl1 = in_8(&regs->canctl1);
489 +               if ((mode & MSCAN_SLPRQ) && (canctl1 & MSCAN_SLPAK) == 0) {
490 +                       out_8(&regs->canctl0,
491 +                             in_8(&regs->canctl0) | MSCAN_SLPRQ);
492 +                       for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
493 +                               if (in_8(&regs->canctl1) & MSCAN_SLPAK)
494 +                                       break;
495 +                               udelay(100);
496 +                       }
497 +                       if (i >= MSCAN_SET_MODE_RETRIES)
498 +                               ret = -ENODEV;
499 +               }
500 +               if (!ret)
501 +                       priv->can.state = CAN_STATE_SLEEPING;
502 +
503 +               if (!ret && (mode & MSCAN_INITRQ)
504 +                   && (canctl1 & MSCAN_INITAK) == 0) {
505 +                       out_8(&regs->canctl0,
506 +                             in_8(&regs->canctl0) | MSCAN_INITRQ);
507 +                       for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
508 +                               if (in_8(&regs->canctl1) & MSCAN_INITAK)
509 +                                       break;
510 +                       }
511 +                       if (i >= MSCAN_SET_MODE_RETRIES)
512 +                               ret = -ENODEV;
513 +               }
514 +               if (!ret)
515 +                       priv->can.state = CAN_STATE_STOPPED;
516 +
517 +               if (!ret && (mode & MSCAN_CSWAI))
518 +                       out_8(&regs->canctl0,
519 +                             in_8(&regs->canctl0) | MSCAN_CSWAI);
520 +
521 +       } else {
522 +               canctl1 = in_8(&regs->canctl1);
523 +               if (canctl1 & (MSCAN_SLPAK | MSCAN_INITAK)) {
524 +                       out_8(&regs->canctl0, in_8(&regs->canctl0) &
525 +                             ~(MSCAN_SLPRQ | MSCAN_INITRQ));
526 +                       for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
527 +                               canctl1 = in_8(&regs->canctl1);
528 +                               if (!(canctl1 & (MSCAN_INITAK | MSCAN_SLPAK)))
529 +                                       break;
530 +                       }
531 +                       if (i >= MSCAN_SET_MODE_RETRIES)
532 +                               ret = -ENODEV;
533 +                       else
534 +                               priv->can.state = CAN_STATE_ACTIVE;
535 +               }
536 +       }
537 +       return ret;
538 +}
539 +
540 +static int mscan_start(struct net_device *dev)
541 +{
542 +       struct mscan_priv *priv = netdev_priv(dev);
543 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
544 +       u8 canrflg;
545 +       int err;
546 +
547 +       out_8(&regs->canrier, 0);
548 +
549 +       INIT_LIST_HEAD(&priv->tx_head);
550 +       priv->cur_pri = 0;
551 +       priv->tx_active = 0;
552 +       priv->shadow_canrier = 0;
553 +       priv->flags = 0;
554 +
555 +       err = mscan_set_mode(dev, MSCAN_NORMAL_MODE);
556 +       if (err)
557 +               return err;
558 +
559 +       canrflg = in_8(&regs->canrflg);
560 +       priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
561 +       priv->can.state = state_map[max(MSCAN_STATE_RX(canrflg),
562 +                                   MSCAN_STATE_TX(canrflg))];
563 +       out_8(&regs->cantier, 0);
564 +
565 +       /* Enable receive interrupts. */
566 +       out_8(&regs->canrier, MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE |
567 +             MSCAN_RSTATE1 | MSCAN_RSTATE0 | MSCAN_TSTATE1 | MSCAN_TSTATE0);
568 +
569 +       return 0;
570 +}
571 +
572 +static int mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
573 +{
574 +       struct can_frame *frame = (struct can_frame *)skb->data;
575 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
576 +       struct mscan_priv *priv = netdev_priv(dev);
577 +       int i, rtr, buf_id;
578 +       u32 can_id;
579 +
580 +       if (frame->can_dlc > 8)
581 +               return -EINVAL;
582 +
583 +       out_8(&regs->cantier, 0);
584 +
585 +       i = ~priv->tx_active & MSCAN_TXE;
586 +       buf_id = ffs(i) - 1;
587 +       switch (hweight8(i)) {
588 +       case 0:
589 +               netif_stop_queue(dev);
590 +               dev_err(ND2D(dev), "BUG! Tx Ring full when queue awake!\n");
591 +               return NETDEV_TX_BUSY;
592 +       case 1:
593 +               /* if buf_id < 3, then current frame will be send out of order,
594 +                  since  buffer with lower id have higher priority (hell..) */
595 +               if (buf_id < 3)
596 +                       priv->cur_pri++;
597 +               if (priv->cur_pri == 0xff)
598 +                       set_bit(F_TX_WAIT_ALL, &priv->flags);
599 +               netif_stop_queue(dev);
600 +       case 2:
601 +               set_bit(F_TX_PROGRESS, &priv->flags);
602 +       }
603 +       out_8(&regs->cantbsel, i);
604 +
605 +       rtr = frame->can_id & CAN_RTR_FLAG;
606 +
607 +       if (frame->can_id & CAN_EFF_FLAG) {
608 +               can_id = (frame->can_id & CAN_EFF_MASK) << 1;
609 +               if (rtr)
610 +                       can_id |= 1;
611 +               out_be16(&regs->tx.idr3_2, can_id);
612 +
613 +               can_id >>= 16;
614 +               can_id = (can_id & 0x7) | ((can_id << 2) & 0xffe0) | (3 << 3);
615 +       } else {
616 +               can_id = (frame->can_id & CAN_SFF_MASK) << 5;
617 +               if (rtr)
618 +                       can_id |= 1 << 4;
619 +       }
620 +       out_be16(&regs->tx.idr1_0, can_id);
621 +
622 +       if (!rtr) {
623 +               void __iomem *data = &regs->tx.dsr1_0;
624 +               u16 *payload = (u16 *) frame->data;
625 +               /*Its safe to write into dsr[dlc+1] */
626 +               for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
627 +                       out_be16(data, *payload++);
628 +                       data += 2 + _MSCAN_RESERVED_DSR_SIZE;
629 +               }
630 +       }
631 +
632 +       out_8(&regs->tx.dlr, frame->can_dlc);
633 +       out_8(&regs->tx.tbpr, priv->cur_pri);
634 +
635 +       /* Start transmission. */
636 +       out_8(&regs->cantflg, 1 << buf_id);
637 +
638 +       if (!test_bit(F_TX_PROGRESS, &priv->flags))
639 +               dev->trans_start = jiffies;
640 +
641 +       list_add_tail(&priv->tx_queue[buf_id].list, &priv->tx_head);
642 +
643 +       can_put_echo_skb(skb, dev, buf_id);
644 +
645 +       /* Enable interrupt. */
646 +       priv->tx_active |= 1 << buf_id;
647 +       out_8(&regs->cantier, priv->tx_active);
648 +
649 +       return NETDEV_TX_OK;
650 +}
651 +
652 +static inline int check_set_state(struct net_device *dev, u8 canrflg)
653 +{
654 +       struct mscan_priv *priv = netdev_priv(dev);
655 +       enum can_state state;
656 +       int ret = 0;
657 +
658 +       if (!(canrflg & MSCAN_CSCIF) || priv->can.state > CAN_STATE_BUS_OFF)
659 +               return 0;
660 +
661 +       state = state_map[max(MSCAN_STATE_RX(canrflg),
662 +                             MSCAN_STATE_TX(canrflg))];
663 +       if (priv->can.state < state)
664 +               ret = 1;
665 +       if (state == CAN_STATE_BUS_OFF)
666 +               can_bus_off(dev);
667 +       priv->can.state = state;
668 +       return ret;
669 +}
670 +
671 +static int mscan_rx_poll(struct napi_struct *napi, int quota)
672 +{
673 +       struct mscan_priv *priv = container_of(napi, struct mscan_priv, napi);
674 +       struct net_device *dev = napi->dev;
675 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
676 +       struct net_device_stats *stats = &dev->stats;
677 +       int npackets = 0;
678 +       int ret = 1;
679 +       struct sk_buff *skb;
680 +       struct can_frame *frame;
681 +       u32 can_id;
682 +       u8 canrflg;
683 +       int i;
684 +
685 +       while (npackets < quota && ((canrflg = in_8(&regs->canrflg)) &
686 +                                   (MSCAN_RXF | MSCAN_ERR_IF))) {
687 +
688 +               skb = dev_alloc_skb(sizeof(struct can_frame));
689 +               if (!skb) {
690 +                       if (printk_ratelimit())
691 +                               dev_notice(ND2D(dev), "packet dropped\n");
692 +                       stats->rx_dropped++;
693 +                       out_8(&regs->canrflg, canrflg);
694 +                       continue;
695 +               }
696 +
697 +               frame = (struct can_frame *)skb_put(skb, sizeof(*frame));
698 +               memset(frame, 0, sizeof(*frame));
699 +
700 +               if (canrflg & MSCAN_RXF) {
701 +                       can_id = in_be16(&regs->rx.idr1_0);
702 +                       if (can_id & (1 << 3)) {
703 +                               frame->can_id = CAN_EFF_FLAG;
704 +                               can_id = ((can_id << 16) |
705 +                                         in_be16(&regs->rx.idr3_2));
706 +                               can_id = ((can_id & 0xffe00000) |
707 +                                         ((can_id & 0x7ffff) << 2)) >> 2;
708 +                       } else {
709 +                               can_id >>= 4;
710 +                               frame->can_id = 0;
711 +                       }
712 +
713 +                       frame->can_id |= can_id >> 1;
714 +                       if (can_id & 1)
715 +                               frame->can_id |= CAN_RTR_FLAG;
716 +                       frame->can_dlc = in_8(&regs->rx.dlr) & 0xf;
717 +
718 +                       if (!(frame->can_id & CAN_RTR_FLAG)) {
719 +                               void __iomem *data = &regs->rx.dsr1_0;
720 +                               u16 *payload = (u16 *) frame->data;
721 +                               for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
722 +                                       *payload++ = in_be16(data);
723 +                                       data += 2 + _MSCAN_RESERVED_DSR_SIZE;
724 +                               }
725 +                       }
726 +
727 +                       out_8(&regs->canrflg, MSCAN_RXF);
728 +                       dev->last_rx = jiffies;
729 +                       stats->rx_packets++;
730 +                       stats->rx_bytes += frame->can_dlc;
731 +               } else if (canrflg & MSCAN_ERR_IF) {
732 +                       dev_dbg(ND2D(dev), "error interrupt (canrflg=%#x)\n",
733 +                               canrflg);
734 +                       frame->can_id = CAN_ERR_FLAG;
735 +
736 +                       if (canrflg & MSCAN_OVRIF) {
737 +                               frame->can_id |= CAN_ERR_CRTL;
738 +                               frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
739 +                               stats->rx_over_errors++;
740 +                       } else
741 +                               frame->data[1] = 0;
742 +
743 +                       if (check_set_state(dev, canrflg)) {
744 +                               frame->can_id |= CAN_ERR_CRTL;
745 +                               switch (priv->can.state) {
746 +                               case CAN_STATE_BUS_WARNING:
747 +                                       if ((priv->shadow_statflg &
748 +                                            MSCAN_RSTAT_MSK) <
749 +                                           (canrflg & MSCAN_RSTAT_MSK))
750 +                                               frame->data[1] |=
751 +                                                   CAN_ERR_CRTL_RX_WARNING;
752 +
753 +                                       if ((priv->shadow_statflg &
754 +                                            MSCAN_TSTAT_MSK) <
755 +                                           (canrflg & MSCAN_TSTAT_MSK))
756 +                                               frame->data[1] |=
757 +                                                       CAN_ERR_CRTL_TX_WARNING;
758 +                                       break;
759 +                               case CAN_STATE_BUS_PASSIVE:
760 +                                       frame->data[1] |=
761 +                                           CAN_ERR_CRTL_RX_PASSIVE;
762 +                                       break;
763 +                               case CAN_STATE_BUS_OFF:
764 +                                       frame->can_id |= CAN_ERR_BUSOFF;
765 +                                       frame->can_id &= ~CAN_ERR_CRTL;
766 +                                       break;
767 +                               default:
768 +                                       break;
769 +                               }
770 +                       }
771 +                       priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
772 +                       frame->can_dlc = CAN_ERR_DLC;
773 +                       out_8(&regs->canrflg, MSCAN_ERR_IF);
774 +               }
775 +
776 +               npackets++;
777 +               skb->dev = dev;
778 +               skb->protocol = __constant_htons(ETH_P_CAN);
779 +               skb->ip_summed = CHECKSUM_UNNECESSARY;
780 +               netif_receive_skb(skb);
781 +       }
782 +
783 +       if (!(in_8(&regs->canrflg) & (MSCAN_RXF | MSCAN_ERR_IF))) {
784 +               napi_complete(&priv->napi);
785 +               clear_bit(F_RX_PROGRESS, &priv->flags);
786 +               if (priv->can.state < CAN_STATE_BUS_OFF)
787 +                       out_8(&regs->canrier, priv->shadow_canrier);
788 +               ret = 0;
789 +       }
790 +       return ret;
791 +}
792 +
793 +static irqreturn_t mscan_isr(int irq, void *dev_id)
794 +{
795 +       struct net_device *dev = (struct net_device *)dev_id;
796 +       struct mscan_priv *priv = netdev_priv(dev);
797 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
798 +       struct net_device_stats *stats = &dev->stats;
799 +       u8 cantier, cantflg, canrflg;
800 +       irqreturn_t ret = IRQ_NONE;
801 +
802 +       cantier = in_8(&regs->cantier) & MSCAN_TXE;
803 +       cantflg = in_8(&regs->cantflg) & cantier;
804 +
805 +       if (cantier && cantflg) {
806 +
807 +               struct list_head *tmp, *pos;
808 +
809 +               list_for_each_safe(pos, tmp, &priv->tx_head) {
810 +                       struct tx_queue_entry *entry =
811 +                           list_entry(pos, struct tx_queue_entry, list);
812 +                       u8 mask = entry->mask;
813 +
814 +                       if (!(cantflg & mask))
815 +                               continue;
816 +
817 +                       out_8(&regs->cantbsel, mask);
818 +                       stats->tx_bytes += in_8(&regs->tx.dlr);
819 +                       stats->tx_packets++;
820 +                       can_get_echo_skb(dev, entry->id);
821 +                       priv->tx_active &= ~mask;
822 +                       list_del(pos);
823 +               }
824 +
825 +               if (list_empty(&priv->tx_head)) {
826 +                       clear_bit(F_TX_WAIT_ALL, &priv->flags);
827 +                       clear_bit(F_TX_PROGRESS, &priv->flags);
828 +                       priv->cur_pri = 0;
829 +               } else
830 +                       dev->trans_start = jiffies;
831 +
832 +               if (!test_bit(F_TX_WAIT_ALL, &priv->flags))
833 +                       netif_wake_queue(dev);
834 +
835 +               out_8(&regs->cantier, priv->tx_active);
836 +               ret = IRQ_HANDLED;
837 +       }
838 +
839 +       canrflg = in_8(&regs->canrflg);
840 +       if ((canrflg & ~MSCAN_STAT_MSK) &&
841 +           !test_and_set_bit(F_RX_PROGRESS, &priv->flags)) {
842 +               if (canrflg & ~MSCAN_STAT_MSK) {
843 +                       priv->shadow_canrier = in_8(&regs->canrier);
844 +                       out_8(&regs->canrier, 0);
845 +                       napi_schedule(&priv->napi);
846 +                       ret = IRQ_HANDLED;
847 +               } else
848 +                       clear_bit(F_RX_PROGRESS, &priv->flags);
849 +       }
850 +       return ret;
851 +}
852 +
853 +static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode)
854 +{
855 +
856 +       struct mscan_priv *priv = netdev_priv(dev);
857 +       int ret = 0;
858 +
859 +       if (!priv->open_time)
860 +               return -EINVAL;
861 +
862 +       switch (mode) {
863 +       case CAN_MODE_SLEEP:
864 +       case CAN_MODE_STOP:
865 +               netif_stop_queue(dev);
866 +               mscan_set_mode(dev,
867 +                              (mode ==
868 +                               CAN_MODE_STOP) ? MSCAN_INIT_MODE :
869 +                              MSCAN_SLEEP_MODE);
870 +               break;
871 +       case CAN_MODE_START:
872 +               if (priv->can.state <= CAN_STATE_BUS_OFF)
873 +                       mscan_set_mode(dev, MSCAN_INIT_MODE);
874 +               ret = mscan_start(dev);
875 +               if (ret)
876 +                       break;
877 +               if (netif_queue_stopped(dev))
878 +                       netif_wake_queue(dev);
879 +               break;
880 +
881 +       default:
882 +               ret = -EOPNOTSUPP;
883 +               break;
884 +       }
885 +       return ret;
886 +}
887 +
888 +static int mscan_do_set_bittiming(struct net_device *dev)
889 +{
890 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
891 +       struct mscan_priv *priv = netdev_priv(dev);
892 +       struct can_bittiming *bt = &priv->can.bittiming;
893 +       u8 btr0, btr1;
894 +
895 +       btr0 = BTR0_SET_BRP(bt->brp) | BTR0_SET_SJW(bt->sjw);
896 +       btr1 = (BTR1_SET_TSEG1(bt->prop_seg + bt->phase_seg1) |
897 +               BTR1_SET_TSEG2(bt->phase_seg2) |
898 +               BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES));
899 +
900 +       dev_info(ND2D(dev), "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
901 +
902 +       out_8(&regs->canbtr0, btr0);
903 +       out_8(&regs->canbtr1, btr1);
904 +
905 +       return 0;
906 +}
907 +
908 +static int mscan_open(struct net_device *dev)
909 +{
910 +       int ret;
911 +       struct mscan_priv *priv = netdev_priv(dev);
912 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
913 +
914 +       /* determine and set bittime */
915 +       ret = can_set_bittiming(dev);
916 +       if (ret)
917 +               return ret;
918 +
919 +       napi_enable(&priv->napi);
920 +       ret = request_irq(dev->irq, mscan_isr, 0, dev->name, dev);
921 +
922 +       if (ret < 0) {
923 +               napi_disable(&priv->napi);
924 +               printk(KERN_ERR "%s - failed to attach interrupt\n",
925 +                      dev->name);
926 +               return ret;
927 +       }
928 +
929 +       priv->open_time = jiffies;
930 +
931 +       out_8(&regs->canctl1, in_8(&regs->canctl1) & ~MSCAN_LISTEN);
932 +
933 +       ret = mscan_start(dev);
934 +       if (ret)
935 +               return ret;
936 +
937 +       netif_start_queue(dev);
938 +
939 +       return 0;
940 +}
941 +
942 +static int mscan_close(struct net_device *dev)
943 +{
944 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
945 +       struct mscan_priv *priv = netdev_priv(dev);
946 +
947 +       napi_disable(&priv->napi);
948 +
949 +       out_8(&regs->cantier, 0);
950 +       out_8(&regs->canrier, 0);
951 +       free_irq(dev->irq, dev);
952 +       mscan_set_mode(dev, MSCAN_INIT_MODE);
953 +       can_close_cleanup(dev);
954 +       netif_stop_queue(dev);
955 +       priv->open_time = 0;
956 +
957 +       return 0;
958 +}
959 +
960 +static const struct net_device_ops mscan_netdev_ops = {
961 +       .ndo_open               = mscan_open,
962 +       .ndo_stop               = mscan_close,
963 +       .ndo_start_xmit         = mscan_start_xmit,
964 +};
965 +
966 +int register_mscandev(struct net_device *dev, int clock_src)
967 +{
968 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
969 +       u8 ctl1;
970 +
971 +       ctl1 = in_8(&regs->canctl1);
972 +       if (clock_src)
973 +               ctl1 |= MSCAN_CLKSRC;
974 +       else
975 +               ctl1 &= ~MSCAN_CLKSRC;
976 +
977 +       ctl1 |= MSCAN_CANE;
978 +       out_8(&regs->canctl1, ctl1);
979 +       udelay(100);
980 +
981 +       /* acceptance mask/acceptance code (accept everything) */
982 +       out_be16(&regs->canidar1_0, 0);
983 +       out_be16(&regs->canidar3_2, 0);
984 +       out_be16(&regs->canidar5_4, 0);
985 +       out_be16(&regs->canidar7_6, 0);
986 +
987 +       out_be16(&regs->canidmr1_0, 0xffff);
988 +       out_be16(&regs->canidmr3_2, 0xffff);
989 +       out_be16(&regs->canidmr5_4, 0xffff);
990 +       out_be16(&regs->canidmr7_6, 0xffff);
991 +       /* Two 32 bit Acceptance Filters */
992 +       out_8(&regs->canidac, MSCAN_AF_32BIT);
993 +
994 +       mscan_set_mode(dev, MSCAN_INIT_MODE);
995 +
996 +       return register_candev(dev);
997 +}
998 +EXPORT_SYMBOL(register_mscandev);
999 +
1000 +void unregister_mscandev(struct net_device *dev)
1001 +{
1002 +       struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
1003 +       mscan_set_mode(dev, MSCAN_INIT_MODE);
1004 +       out_8(&regs->canctl1, in_8(&regs->canctl1) & ~MSCAN_CANE);
1005 +       unregister_candev(dev);
1006 +}
1007 +EXPORT_SYMBOL(unregister_mscandev);
1008 +
1009 +struct net_device *alloc_mscandev(void)
1010 +{
1011 +       struct net_device *dev;
1012 +       struct mscan_priv *priv;
1013 +       int i;
1014 +
1015 +       dev = alloc_candev(sizeof(struct mscan_priv));
1016 +       if (!dev)
1017 +               return NULL;
1018 +       priv = netdev_priv(dev);
1019 +
1020 +       dev->netdev_ops = &mscan_netdev_ops;
1021 +
1022 +       dev->flags |= IFF_ECHO; /* we support local echo */
1023 +
1024 +       netif_napi_add(dev, &priv->napi, mscan_rx_poll, 8);
1025 +
1026 +       priv->can.bittiming_const = &mscan_bittiming_const;
1027 +       priv->can.do_set_bittiming = mscan_do_set_bittiming;
1028 +       priv->can.do_set_mode = mscan_do_set_mode;
1029 +
1030 +       for (i = 0; i < TX_QUEUE_SIZE; i++) {
1031 +               priv->tx_queue[i].id = i;
1032 +               priv->tx_queue[i].mask = 1 << i;
1033 +       }
1034 +
1035 +       return dev;
1036 +}
1037 +EXPORT_SYMBOL(alloc_mscandev);
1038 +
1039 +MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
1040 +MODULE_LICENSE("GPL v2");
1041 +MODULE_DESCRIPTION("CAN port driver for a MSCAN based chips");
1042 Index: net-next-2.6/drivers/net/can/mscan/mscan.h
1043 ===================================================================
1044 --- /dev/null
1045 +++ net-next-2.6/drivers/net/can/mscan/mscan.h
1046 @@ -0,0 +1,237 @@
1047 +/*
1048 + * Definitions of consts/structs to drive the Freescale MSCAN.
1049 + *
1050 + * Copyright (C) 2005-2006 Andrey Volkov <avolkov@varma-el.com>,
1051 + *                         Varma Electronics Oy
1052 + *
1053 + * This program is free software; you can redistribute it and/or modify
1054 + * it under the terms of the version 2 of the GNU General Public License
1055 + * as published by the Free Software Foundation
1056 + *
1057 + * This program is distributed in the hope that it will be useful,
1058 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1059 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1060 + * GNU General Public License for more details.
1061 + *
1062 + * You should have received a copy of the GNU General Public License
1063 + * along with this program; if not, write to the Free Software
1064 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1065 + */
1066 +
1067 +#ifndef __MSCAN_H__
1068 +#define __MSCAN_H__
1069 +
1070 +#include <linux/types.h>
1071 +
1072 +/* MSCAN control register 0 (CANCTL0) bits */
1073 +#define MSCAN_RXFRM            0x80
1074 +#define MSCAN_RXACT            0x40
1075 +#define MSCAN_CSWAI            0x20
1076 +#define MSCAN_SYNCH            0x10
1077 +#define MSCAN_TIME             0x08
1078 +#define MSCAN_WUPE             0x04
1079 +#define MSCAN_SLPRQ            0x02
1080 +#define MSCAN_INITRQ           0x01
1081 +
1082 +/* MSCAN control register 1 (CANCTL1) bits */
1083 +#define MSCAN_CANE             0x80
1084 +#define MSCAN_CLKSRC           0x40
1085 +#define MSCAN_LOOPB            0x20
1086 +#define MSCAN_LISTEN           0x10
1087 +#define MSCAN_WUPM             0x04
1088 +#define MSCAN_SLPAK            0x02
1089 +#define MSCAN_INITAK           0x01
1090 +
1091 +/* Use the MPC5200 MSCAN variant? */
1092 +#ifdef CONFIG_PPC
1093 +#define MSCAN_FOR_MPC5200
1094 +#endif
1095 +
1096 +#ifdef MSCAN_FOR_MPC5200
1097 +#define MSCAN_CLKSRC_BUS       0
1098 +#define MSCAN_CLKSRC_XTAL      MSCAN_CLKSRC
1099 +#else
1100 +#define MSCAN_CLKSRC_BUS       MSCAN_CLKSRC
1101 +#define MSCAN_CLKSRC_XTAL      0
1102 +#endif
1103 +
1104 +/* MSCAN receiver flag register (CANRFLG) bits */
1105 +#define MSCAN_WUPIF            0x80
1106 +#define MSCAN_CSCIF            0x40
1107 +#define MSCAN_RSTAT1           0x20
1108 +#define MSCAN_RSTAT0           0x10
1109 +#define MSCAN_TSTAT1           0x08
1110 +#define MSCAN_TSTAT0           0x04
1111 +#define MSCAN_OVRIF            0x02
1112 +#define MSCAN_RXF              0x01
1113 +#define MSCAN_ERR_IF           (MSCAN_OVRIF | MSCAN_CSCIF)
1114 +#define MSCAN_RSTAT_MSK                (MSCAN_RSTAT1 | MSCAN_RSTAT0)
1115 +#define MSCAN_TSTAT_MSK                (MSCAN_TSTAT1 | MSCAN_TSTAT0)
1116 +#define MSCAN_STAT_MSK         (MSCAN_RSTAT_MSK | MSCAN_TSTAT_MSK)
1117 +
1118 +#define MSCAN_STATE_BUS_OFF    (MSCAN_RSTAT1 | MSCAN_RSTAT0 | \
1119 +                                MSCAN_TSTAT1 | MSCAN_TSTAT0)
1120 +#define MSCAN_STATE_TX(canrflg)        (((canrflg)&MSCAN_TSTAT_MSK)>>2)
1121 +#define MSCAN_STATE_RX(canrflg)        (((canrflg)&MSCAN_RSTAT_MSK)>>4)
1122 +#define MSCAN_STATE_ACTIVE     0
1123 +#define MSCAN_STATE_WARNING    1
1124 +#define MSCAN_STATE_PASSIVE    2
1125 +#define MSCAN_STATE_BUSOFF     3
1126 +
1127 +/* MSCAN receiver interrupt enable register (CANRIER) bits */
1128 +#define MSCAN_WUPIE            0x80
1129 +#define MSCAN_CSCIE            0x40
1130 +#define MSCAN_RSTATE1          0x20
1131 +#define MSCAN_RSTATE0          0x10
1132 +#define MSCAN_TSTATE1          0x08
1133 +#define MSCAN_TSTATE0          0x04
1134 +#define MSCAN_OVRIE            0x02
1135 +#define MSCAN_RXFIE            0x01
1136 +
1137 +/* MSCAN transmitter flag register (CANTFLG) bits */
1138 +#define MSCAN_TXE2             0x04
1139 +#define MSCAN_TXE1             0x02
1140 +#define MSCAN_TXE0             0x01
1141 +#define MSCAN_TXE              (MSCAN_TXE2 | MSCAN_TXE1 | MSCAN_TXE0)
1142 +
1143 +/* MSCAN transmitter interrupt enable register (CANTIER) bits */
1144 +#define MSCAN_TXIE2            0x04
1145 +#define MSCAN_TXIE1            0x02
1146 +#define MSCAN_TXIE0            0x01
1147 +#define MSCAN_TXIE             (MSCAN_TXIE2 | MSCAN_TXIE1 | MSCAN_TXIE0)
1148 +
1149 +/* MSCAN transmitter message abort request (CANTARQ) bits */
1150 +#define MSCAN_ABTRQ2           0x04
1151 +#define MSCAN_ABTRQ1           0x02
1152 +#define MSCAN_ABTRQ0           0x01
1153 +
1154 +/* MSCAN transmitter message abort ack (CANTAAK) bits */
1155 +#define MSCAN_ABTAK2           0x04
1156 +#define MSCAN_ABTAK1           0x02
1157 +#define MSCAN_ABTAK0           0x01
1158 +
1159 +/* MSCAN transmit buffer selection (CANTBSEL) bits */
1160 +#define MSCAN_TX2              0x04
1161 +#define MSCAN_TX1              0x02
1162 +#define MSCAN_TX0              0x01
1163 +
1164 +/* MSCAN ID acceptance control register (CANIDAC) bits */
1165 +#define MSCAN_IDAM1            0x20
1166 +#define MSCAN_IDAM0            0x10
1167 +#define MSCAN_IDHIT2           0x04
1168 +#define MSCAN_IDHIT1           0x02
1169 +#define MSCAN_IDHIT0           0x01
1170 +
1171 +#define MSCAN_AF_32BIT         0x00
1172 +#define MSCAN_AF_16BIT         MSCAN_IDAM0
1173 +#define MSCAN_AF_8BIT          MSCAN_IDAM1
1174 +#define MSCAN_AF_CLOSED                (MSCAN_IDAM0|MSCAN_IDAM1)
1175 +#define MSCAN_AF_MASK          (~(MSCAN_IDAM0|MSCAN_IDAM1))
1176 +
1177 +/* MSCAN Miscellaneous Register (CANMISC) bits */
1178 +#define MSCAN_BOHOLD           0x01
1179 +
1180 +#ifdef MSCAN_FOR_MPC5200
1181 +#define _MSCAN_RESERVED_(n, num) u8 _res##n[num]
1182 +#define _MSCAN_RESERVED_DSR_SIZE       2
1183 +#else
1184 +#define _MSCAN_RESERVED_(n, num)
1185 +#define _MSCAN_RESERVED_DSR_SIZE       0
1186 +#endif
1187 +
1188 +/* Structure of the hardware registers */
1189 +struct mscan_regs {
1190 +       /* (see doco S12MSCANV3/D)                MPC5200    MSCAN */
1191 +       u8 canctl0;                             /* + 0x00     0x00 */
1192 +       u8 canctl1;                             /* + 0x01     0x01 */
1193 +       _MSCAN_RESERVED_(1, 2);                 /* + 0x02          */
1194 +       u8 canbtr0;                             /* + 0x04     0x02 */
1195 +       u8 canbtr1;                             /* + 0x05     0x03 */
1196 +       _MSCAN_RESERVED_(2, 2);                 /* + 0x06          */
1197 +       u8 canrflg;                             /* + 0x08     0x04 */
1198 +       u8 canrier;                             /* + 0x09     0x05 */
1199 +       _MSCAN_RESERVED_(3, 2);                 /* + 0x0a          */
1200 +       u8 cantflg;                             /* + 0x0c     0x06 */
1201 +       u8 cantier;                             /* + 0x0d     0x07 */
1202 +       _MSCAN_RESERVED_(4, 2);                 /* + 0x0e          */
1203 +       u8 cantarq;                             /* + 0x10     0x08 */
1204 +       u8 cantaak;                             /* + 0x11     0x09 */
1205 +       _MSCAN_RESERVED_(5, 2);                 /* + 0x12          */
1206 +       u8 cantbsel;                            /* + 0x14     0x0a */
1207 +       u8 canidac;                             /* + 0x15     0x0b */
1208 +       u8 reserved;                            /* + 0x16     0x0c */
1209 +       _MSCAN_RESERVED_(6, 5);                 /* + 0x17          */
1210 +#ifndef MSCAN_FOR_MPC5200
1211 +       u8 canmisc;                             /*            0x0d */
1212 +#endif
1213 +       u8 canrxerr;                            /* + 0x1c     0x0e */
1214 +       u8 cantxerr;                            /* + 0x1d     0x0f */
1215 +       _MSCAN_RESERVED_(7, 2);                 /* + 0x1e          */
1216 +       u16 canidar1_0;                         /* + 0x20     0x10 */
1217 +       _MSCAN_RESERVED_(8, 2);                 /* + 0x22          */
1218 +       u16 canidar3_2;                         /* + 0x24     0x12 */
1219 +       _MSCAN_RESERVED_(9, 2);                 /* + 0x26          */
1220 +       u16 canidmr1_0;                         /* + 0x28     0x14 */
1221 +       _MSCAN_RESERVED_(10, 2);                /* + 0x2a          */
1222 +       u16 canidmr3_2;                         /* + 0x2c     0x16 */
1223 +       _MSCAN_RESERVED_(11, 2);                /* + 0x2e          */
1224 +       u16 canidar5_4;                         /* + 0x30     0x18 */
1225 +       _MSCAN_RESERVED_(12, 2);                /* + 0x32          */
1226 +       u16 canidar7_6;                         /* + 0x34     0x1a */
1227 +       _MSCAN_RESERVED_(13, 2);                /* + 0x36          */
1228 +       u16 canidmr5_4;                         /* + 0x38     0x1c */
1229 +       _MSCAN_RESERVED_(14, 2);                /* + 0x3a          */
1230 +       u16 canidmr7_6;                         /* + 0x3c     0x1e */
1231 +       _MSCAN_RESERVED_(15, 2);                /* + 0x3e          */
1232 +       struct {
1233 +               u16 idr1_0;                     /* + 0x40     0x20 */
1234 +                _MSCAN_RESERVED_(16, 2);       /* + 0x42          */
1235 +               u16 idr3_2;                     /* + 0x44     0x22 */
1236 +                _MSCAN_RESERVED_(17, 2);       /* + 0x46          */
1237 +               u16 dsr1_0;                     /* + 0x48     0x24 */
1238 +                _MSCAN_RESERVED_(18, 2);       /* + 0x4a          */
1239 +               u16 dsr3_2;                     /* + 0x4c     0x26 */
1240 +                _MSCAN_RESERVED_(19, 2);       /* + 0x4e          */
1241 +               u16 dsr5_4;                     /* + 0x50     0x28 */
1242 +                _MSCAN_RESERVED_(20, 2);       /* + 0x52          */
1243 +               u16 dsr7_6;                     /* + 0x54     0x2a */
1244 +                _MSCAN_RESERVED_(21, 2);       /* + 0x56          */
1245 +               u8 dlr;                         /* + 0x58     0x2c */
1246 +                u8:8;                          /* + 0x59     0x2d */
1247 +                _MSCAN_RESERVED_(22, 2);       /* + 0x5a          */
1248 +               u16 time;                       /* + 0x5c     0x2e */
1249 +       } rx;
1250 +        _MSCAN_RESERVED_(23, 2);               /* + 0x5e          */
1251 +       struct {
1252 +               u16 idr1_0;                     /* + 0x60     0x30 */
1253 +                _MSCAN_RESERVED_(24, 2);       /* + 0x62          */
1254 +               u16 idr3_2;                     /* + 0x64     0x32 */
1255 +                _MSCAN_RESERVED_(25, 2);       /* + 0x66          */
1256 +               u16 dsr1_0;                     /* + 0x68     0x34 */
1257 +                _MSCAN_RESERVED_(26, 2);       /* + 0x6a          */
1258 +               u16 dsr3_2;                     /* + 0x6c     0x36 */
1259 +                _MSCAN_RESERVED_(27, 2);       /* + 0x6e          */
1260 +               u16 dsr5_4;                     /* + 0x70     0x38 */
1261 +                _MSCAN_RESERVED_(28, 2);       /* + 0x72          */
1262 +               u16 dsr7_6;                     /* + 0x74     0x3a */
1263 +                _MSCAN_RESERVED_(29, 2);       /* + 0x76          */
1264 +               u8 dlr;                         /* + 0x78     0x3c */
1265 +               u8 tbpr;                        /* + 0x79     0x3d */
1266 +                _MSCAN_RESERVED_(30, 2);       /* + 0x7a          */
1267 +               u16 time;                       /* + 0x7c     0x3e */
1268 +       } tx;
1269 +        _MSCAN_RESERVED_(31, 2);               /* + 0x7e          */
1270 +} __attribute__ ((packed));
1271 +
1272 +#undef _MSCAN_RESERVED_
1273 +#define MSCAN_REGION   sizeof(struct mscan)
1274 +
1275 +struct net_device *alloc_mscandev(void);
1276 +/* clock_src:
1277 + *     1 = The MSCAN clock source is the onchip Bus Clock.
1278 + *     0 = The MSCAN clock source is the chip Oscillator Clock.
1279 + */
1280 +extern int register_mscandev(struct net_device *dev, int clock_src);
1281 +extern void unregister_mscandev(struct net_device *dev);
1282 +
1283 +#endif /* __MSCAN_H__ */
1284 Index: net-next-2.6/drivers/net/can/mscan/Makefile
1285 ===================================================================
1286 --- /dev/null
1287 +++ net-next-2.6/drivers/net/can/mscan/Makefile
1288 @@ -0,0 +1,9 @@
1289 +#
1290 +#  Makefile for the MSCAN controller drivers.
1291 +#
1292 +
1293 +obj-$(CONFIG_CAN_MPC52XX)      += mscan-mpc52xx.o
1294 +
1295 +mscan-mpc52xx-objs     := mscan.o mpc52xx_can.o
1296 +
1297 +ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG