ae7aefd649e4f29fdb4c30dbcde7d42fd38d00f6
[lede.git] / target / linux / coldfire / patches / 077-mcfv4e_flexcan.patch
1 From c44de58d0972d05851512ba8cbd928b7adef5187 Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Tue, 8 Jul 2008 17:11:33 -0600
4 Subject: [PATCH] Add FlexCAN support.
5
6 LTIBName: mcfv4e-flexcan
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
8 Signed-off-by: Huan Wang <b18965@freescale.com>
9 ---
10  drivers/net/can/Kconfig               |   13 ++
11  drivers/net/can/Makefile              |    1 +
12  drivers/net/can/flexcan/Makefile      |    5 +
13  drivers/net/can/flexcan/flexcan.c     |  378 +++++++++++++++++++++++++++++++++
14  drivers/net/can/flexcan/flexcan.h     |  148 +++++++++++++
15  drivers/net/can/flexcan/mcf548x_can.c |  213 ++++++++++++++++++
16  include/asm-m68k/m5485sim.h           |    2 +
17  include/linux/can/dev.h               |   62 ++++++
18  include/linux/can/ioctl.h             |  152 +++++++++++++
19  include/linux/can/version.h           |   22 ++
20  net/can/Makefile                      |    3 +
21  net/can/dev.c                         |  292 +++++++++++++++++++++++++
22  12 files changed, 1291 insertions(+), 0 deletions(-)
23  create mode 100644 drivers/net/can/flexcan/Makefile
24  create mode 100644 drivers/net/can/flexcan/flexcan.c
25  create mode 100644 drivers/net/can/flexcan/flexcan.h
26  create mode 100644 drivers/net/can/flexcan/mcf548x_can.c
27  create mode 100644 include/linux/can/dev.h
28  create mode 100644 include/linux/can/ioctl.h
29  create mode 100644 include/linux/can/version.h
30  create mode 100644 net/can/dev.c
31
32 --- a/drivers/net/can/Kconfig
33 +++ b/drivers/net/can/Kconfig
34 @@ -12,6 +12,19 @@ config CAN_VCAN
35           This driver can also be built as a module.  If so, the module
36           will be called vcan.
37  
38 +config CAN_FLEXCAN
39 +       tristate "Support for Freescale FLEXCAN based chips"
40 +       depends on CAN && (PPC || M68K || M68KNOMMU)
41 +       ---help---
42 +         Say Y here if you want to support for Freescale FlexCAN.
43 +
44 +config CAN_MCF547X_8X
45 +       tristate "Freescale MCF547X/MCF548X onboard CAN controller"
46 +       depends on CAN_FLEXCAN && (M547X || M548X)
47 +       ---help---
48 +         Say Y here if you want to support for Freescale MCF547x/MCF548x
49 +         onboard dualCAN controller.
50 +
51  config CAN_DEBUG_DEVICES
52         bool "CAN devices debugging messages"
53         depends on CAN
54 --- a/drivers/net/can/Makefile
55 +++ b/drivers/net/can/Makefile
56 @@ -3,3 +3,4 @@
57  #
58  
59  obj-$(CONFIG_CAN_VCAN)         += vcan.o
60 +obj-$(CONFIG_CAN_FLEXCAN)      += flexcan/
61 --- /dev/null
62 +++ b/drivers/net/can/flexcan/Makefile
63 @@ -0,0 +1,5 @@
64 +
65 +obj-$(CONFIG_CAN_MCF547X_8X)   += flexcan-mcf548x.o
66 +
67 +flexcan-mcf548x-objs   := flexcan.o mcf548x_can.o
68 +
69 --- /dev/null
70 +++ b/drivers/net/can/flexcan/flexcan.c
71 @@ -0,0 +1,378 @@
72 +/*
73 + * flexcan.c
74 + *
75 + * DESCRIPTION:
76 + *  CAN bus driver for the alone generic (as possible as) FLEXCAN controller.
77 + *
78 + * AUTHOR:
79 + *  Andrey Volkov <avolkov@varma-el.com>
80 + *
81 + * COPYRIGHT:
82 + *  2005-2006, Varma Electronics Oy
83 + *
84 + * LICENCE:
85 + *  This program is free software; you can redistribute it and/or modify
86 + *  it under the terms of the GNU General Public License as published by
87 + *  the Free Software Foundation; either version 2 of the License, or
88 + *  (at your option) any later version.
89 + *
90 + *  This program is distributed in the hope that it will be useful,
91 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
92 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
93 + *  GNU General Public License for more details.
94 + *
95 + *  You should have received a copy of the GNU General Public License
96 + *  along with this program; if not, write to the Free Software
97 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
98 + *
99 + *  HISTORY:
100 + *     2008-06-23 Support for MCF548x's FlexCAN
101 + *                     Huan, Wang <b18965@freescale.com>
102 + */
103 +
104 +
105 +
106 +#include <linux/kernel.h>
107 +#include <linux/module.h>
108 +#include <linux/interrupt.h>
109 +#include <linux/delay.h>
110 +#include <linux/netdevice.h>
111 +#include <linux/if_arp.h>
112 +#include <linux/if_ether.h>
113 +#include <linux/can.h>
114 +#include <linux/list.h>
115 +#include <linux/io.h>
116 +
117 +#include <linux/can/dev.h>
118 +#include <linux/can/error.h>
119 +#include "flexcan.h"
120 +#include <asm/coldfire.h>
121 +#include <asm/m5485sim.h>
122 +#include <linux/can/version.h> /* for RCSID. Removed by mkpatch script */
123 +RCSID("$Id$");
124 +
125 +struct flexcan_priv {
126 +       struct can_priv can;
127 +       volatile unsigned long flags;
128 +       u8 shadow_statflg;
129 +       u8 shadow_canrier;
130 +       u8 cur_pri;
131 +       u8 tx_active;
132 +
133 +       struct list_head tx_head;
134 +       struct napi_struct napi;
135 +       struct net_device *dev;
136 +};
137 +
138 +
139 +static int flexcan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
140 +{
141 +       struct can_frame *frame = (struct can_frame *)skb->data;
142 +       struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
143 +       int i, len;
144 +       int txbuf = 0;
145 +       u32 can_id, can_ext, tmp, tmp1;
146 +
147 +       /* Transmission inactive */
148 +       regs->cantxfg[txbuf].can_dlc = MB_CNT_CODE(0x08);
149 +
150 +       can_ext = frame->can_id;
151 +       if (can_ext & CAN_EFF_FLAG) {
152 +               /* Frame format is extended */
153 +               regs->cantxfg[txbuf].can_dlc |= (1 << 21);
154 +               regs->cantxfg[txbuf].can_dlc |= (1 << 22);
155 +               can_id = frame->can_id & MB_ID_EXT;
156 +               if (frame->can_id & CAN_RTR_FLAG)
157 +                       regs->cantxfg[txbuf].can_dlc |= (1 << 20);
158 +
159 +               tmp = (can_id & CAN_SFF_MASK) << 18;
160 +               tmp1 = can_id >> 11;
161 +               can_id = tmp | tmp1;
162 +               regs->cantxfg[txbuf].can_id = can_id;
163 +       } else {
164 +               /* Frame format is standard */
165 +               can_id = frame->can_id & MB_ID_EXT;
166 +               if (frame->can_id & CAN_RTR_FLAG)
167 +                       regs->cantxfg[txbuf].can_dlc |= (1 << 20);
168 +
169 +               regs->cantxfg[txbuf].can_id = can_id << 18;
170 +       }
171 +
172 +       len = 8;
173 +       for (i = 0; i < len; i++)
174 +               regs->cantxfg[txbuf].data[i] = frame->data[i];
175 +
176 +       regs->cantxfg[txbuf].can_dlc |= len << 16;
177 +       /* Transmission active */
178 +       regs->cantxfg[txbuf].can_dlc |= MB_CNT_CODE(0x0c);
179 +       kfree_skb(skb);
180 +       return NETDEV_TX_OK;
181 +}
182 +
183 +static void flexcan_tx_timeout(struct net_device *dev)
184 +{
185 +       struct sk_buff *skb;
186 +       struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
187 +       struct can_frame *frame;
188 +       int length = 8;
189 +
190 +       /* Diable the interrupts */
191 +       regs->imask = IMASK_BUFF_DISABLE_ALL;
192 +
193 +       skb = dev_alloc_skb(sizeof(struct can_frame));
194 +       if (!skb) {
195 +               if (printk_ratelimit())
196 +                       dev_notice(ND2D(dev), "TIMEOUT packet dropped.\n");
197 +               return;
198 +       }
199 +       frame = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
200 +
201 +       frame->can_dlc = length;
202 +
203 +       skb->dev = dev;
204 +       skb->protocol = __constant_htons(ETH_P_CAN);
205 +       skb->pkt_type = PACKET_BROADCAST;
206 +       skb->ip_summed = CHECKSUM_UNNECESSARY;
207 +
208 +       netif_rx(skb);
209 +}
210 +
211 +static irqreturn_t flexcan_isr(int irq, void *dev_id)
212 +{
213 +       struct net_device *dev = (struct net_device *)dev_id;
214 +       struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
215 +       struct net_device_stats *stats = dev->get_stats(dev);
216 +       struct sk_buff *skb;
217 +       struct can_frame *frame;
218 +       u32 iflags, oflags;
219 +       int i, k;
220 +       int retval = 1;
221 +
222 +       iflags = regs->iflag;
223 +       oflags = iflags;
224 +       for (i = 0; i < 16; i++) {
225 +               if (iflags & (0x01 << i)) {
226 +                       struct flexcan_mb *mb = &regs->cantxfg[i];
227 +                       int ctrl = mb->can_dlc;
228 +                       int code = (ctrl >> 24) & 0x0f;
229 +                       int length = (ctrl >> 16) & 0x0f;
230 +                       u32 tmp, tmp1;
231 +
232 +                       if (code < 8 && (length > 0)) {
233 +                               /* receive frame */
234 +                               skb = dev_alloc_skb(sizeof(struct can_frame));
235 +                               if (!skb)
236 +                                       dev_notice(ND2D(dev),
237 +                                                       "Packets dropped.\n");
238 +                               skb->dev = dev;
239 +                               frame = (struct can_frame *)skb_put(skb,
240 +                                               sizeof(struct can_frame));
241 +
242 +                               frame->can_id &= 0x0;
243 +                               frame->can_dlc = length;
244 +                               tmp1 = mb->can_id & MB_ID_EXT;
245 +                               if (ctrl & MB_CNT_IDE) {
246 +                                       tmp = tmp1;
247 +                                       tmp = (tmp >> 18) & CAN_SFF_MASK;
248 +                                       frame->can_id = (tmp1 << 11) | tmp;
249 +                                       frame->can_id &= CAN_EFF_MASK;
250 +                                       frame->can_id |= CAN_EFF_FLAG;
251 +                                       if (ctrl & MB_CNT_RTR)
252 +                                               frame->can_id |= CAN_RTR_FLAG;
253 +                               } else {
254 +                                       frame->can_id  = tmp1 >> 18;
255 +                                       if (ctrl & MB_CNT_RTR)
256 +                                               frame->can_id |= CAN_RTR_FLAG;
257 +                               }
258 +
259 +                               for (k = 0; k < 8; k++)
260 +                                       frame->data[k] = mb->data[k];
261 +
262 +                               mb->can_dlc &= MB_CODE_MASK;
263 +                               mb->can_dlc |= MB_CNT_CODE(0x04);
264 +
265 +                               stats->rx_packets++;
266 +                               stats->rx_bytes += frame->can_dlc;
267 +                               skb->dev = dev;
268 +                               skb->protocol = __constant_htons(ETH_P_CAN);
269 +                               skb->ip_summed = CHECKSUM_UNNECESSARY;
270 +
271 +                               retval = netif_rx(skb);
272 +                               if (retval == NET_RX_DROP)
273 +                                       dev_notice(ND2D(dev),
274 +                                                       "Packets dropped.\n");
275 +                       } else {
276 +                               /* transmit frame */
277 +                               mb->can_dlc = MB_CNT_CODE(0x04);
278 +                       }
279 +               }
280 +       }
281 +       regs->iflag = oflags;
282 +
283 +       return IRQ_HANDLED;
284 +}
285 +
286 +static int flexcan_do_set_bit_time(struct net_device *dev,
287 +                                struct can_bittime *bt)
288 +{
289 +       struct flexcan_priv *priv = netdev_priv(dev);
290 +       struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
291 +       int ret = 0;
292 +       u32 reg;
293 +
294 +       if (bt->type != CAN_BITTIME_STD)
295 +               return -EINVAL;
296 +
297 +       spin_lock_irq(&priv->can.irq_lock);
298 +
299 +       reg = CANCTRL_PRESDIV(bt->std.brp) | CANCTRL_PSEG1(bt->std.phase_seg1
300 +                       - 1) | CANCTRL_PSEG2(bt->std.phase_seg2 - 1);
301 +       regs->canctrl &= CANCTRL_BITTIME;
302 +       regs->canctrl |= (reg | CANCTRL_SAMP(bt->std.sam) |
303 +               CANCTRL_PROPSEG(bt->std.prop_seg - 1));
304 +
305 +       spin_unlock_irq(&priv->can.irq_lock);
306 +       return ret;
307 +}
308 +
309 +
310 +static int flexcan_open(struct net_device *dev)
311 +{
312 +       int ret, i, j;
313 +       struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
314 +
315 +#if defined(CONFIG_M547X_8X)
316 +       MCF_PAR_TIMER = MCF_PAR_TIMER | 0x28;
317 +       MCF_PAR_TIMER = MCF_PAR_TIMER & 0xf8;
318 +       MCF_PAR_DSPI = MCF_PAR_DSPI | 0x0a00;
319 +       MCF_PAR_FECI2CIRQ = MCF_PAR_FECI2CIRQ | 0x0283;
320 +       MCF_PAR_PSCn(2) = MCF_PAR_PSCn(2) & 0x0f;
321 +       MCF_PAR_PSCn(2) = MCF_PAR_PSCn(2) | 0x50;
322 +#endif
323 +
324 +       regs->canmcr |= CANMCR_SOFTRST;
325 +       regs->canmcr |= CANMCR_MDIS;
326 +       udelay(10);
327 +
328 +       if ((regs->canmcr & CANMCR_SOFTRST) != 0x0) {
329 +               dev_err(ND2D(dev), "Failed to softreset can module.\n");
330 +               return -1;
331 +       }
332 +
333 +       /* Enable error and bus off interrupt */
334 +       regs->canctrl |= (CANCTRL_RJW(3) | CANCTRL_ERRMSK |
335 +                       CANCTRL_BOFFMSK);
336 +
337 +       /* Set lowest buffer transmitted first */
338 +       regs->canctrl |= CANCTRL_LBUF;
339 +
340 +       for (i = 0; i < 16; i++) {
341 +               regs->cantxfg[i].can_dlc = 0;
342 +               regs->cantxfg[i].can_id = 0;
343 +               for (j = 0; j < 8; j++)
344 +                       regs->cantxfg[i].data[j] = 0;
345 +
346 +               /* Put MB into rx queue */
347 +               regs->cantxfg[i].can_dlc = MB_CNT_CODE(0x04);
348 +       }
349 +
350 +       /* acceptance mask/acceptance code (accept everything) */
351 +       regs->rxgmask = 0x00000000;
352 +       regs->rx14mask = 0x00000000;
353 +       regs->rx15mask = 0x00000000;
354 +       /* extended frame */
355 +       regs->cantxfg[14].can_dlc |= 0x600000;
356 +       /* Enable flexcan module */
357 +       regs->canmcr &= ~CANMCR_MDIS;
358 +       /* Synchronize with the can bus */
359 +       regs->canmcr &= ~CANMCR_HALT;
360 +
361 +#if defined(CONFIG_M547X_8X)
362 +       for (i = 0; i < 2; i++) {
363 +               MCF_ICR(ISC_CANn_MBOR(i)) = 0x33;
364 +               MCF_ICR(ISC_CANn_ERR(i)) = 0x33;
365 +               MCF_ICR(ISC_CANn_BUSOFF(i)) = 0x33;
366 +       }
367 +
368 +       ret = request_irq(dev->irq + 64, flexcan_isr, IRQF_DISABLED,
369 +                       dev->name, dev);
370 +       ret = request_irq(dev->irq + 1 + 64, flexcan_isr, IRQF_DISABLED,
371 +                       dev->name, dev);
372 +       ret = request_irq(dev->irq + 2 + 64, flexcan_isr, IRQF_DISABLED,
373 +                       dev->name, dev);
374 +       if (ret < 0) {
375 +               printk(KERN_ERR "%s - failed to attach interrupt.\n",
376 +                      dev->name);
377 +               return ret;
378 +       }
379 +#endif
380 +
381 +       /* Enable all interrupts */
382 +       regs->imask = IMASK_BUFF_ENABLE_ALL;
383 +       netif_start_queue(dev);
384 +       return 0;
385 +}
386 +
387 +static int flexcan_close(struct net_device *dev)
388 +{
389 +       struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
390 +
391 +       netif_stop_queue(dev);
392 +
393 +       /* Disable all interrupts */
394 +       regs->imask = IMASK_BUFF_DISABLE_ALL;
395 +       free_irq(dev->irq + 64, dev);
396 +       free_irq(dev->irq + 1 + 64, dev);
397 +       free_irq(dev->irq + 2 + 64, dev);
398 +
399 +       /* Disable module */
400 +       regs->canmcr |= CANMCR_MDIS;
401 +       return 0;
402 +}
403 +
404 +int register_flexcandev(struct net_device *dev, int clock_src)
405 +{
406 +       struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
407 +
408 +       regs->canmcr &= ~CANMCR_MDIS;
409 +       udelay(100);
410 +       regs->canmcr |= (CANMCR_FRZ | CANMCR_HALT);
411 +       return register_netdev(dev);
412 +}
413 +EXPORT_SYMBOL(register_flexcandev);
414 +
415 +void unregister_flexcandev(struct net_device *dev)
416 +{
417 +       struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
418 +
419 +       regs->canmcr |= (CANMCR_FRZ | CANMCR_HALT);
420 +       regs->canmcr |= CANMCR_MDIS;
421 +
422 +       unregister_netdev(dev);
423 +}
424 +EXPORT_SYMBOL(unregister_flexcandev);
425 +
426 +struct net_device *alloc_flexcandev(void)
427 +{
428 +       struct net_device *dev;
429 +       struct flexcan_priv *priv;
430 +
431 +       dev = alloc_candev(sizeof(struct flexcan_priv));
432 +       if (!dev)
433 +               return NULL;
434 +
435 +       priv = netdev_priv(dev);
436 +       priv->dev = dev;
437 +       dev->open = flexcan_open;
438 +       dev->stop = flexcan_close;
439 +       dev->hard_start_xmit = flexcan_hard_start_xmit;
440 +       dev->tx_timeout = flexcan_tx_timeout;
441 +       dev->flags |= IFF_NOARP;
442 +       priv->can.do_set_bit_time = flexcan_do_set_bit_time;
443 +       return dev;
444 +}
445 +EXPORT_SYMBOL(alloc_flexcandev);
446 +
447 +MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
448 +MODULE_LICENSE("GPL v2");
449 +MODULE_DESCRIPTION("CAN port driver for flexcan based chip");
450 --- /dev/null
451 +++ b/drivers/net/can/flexcan/flexcan.h
452 @@ -0,0 +1,148 @@
453 +/*
454 + * flexcan.h
455 + *
456 + * DESCRIPTION:
457 + *  Definitions of consts/structs to drive the Freescale FLEXCAN.
458 + *
459 + */
460 +
461 +#ifndef __FLEXCAN_H__
462 +#define __FLEXCAN_H__
463 +
464 +#include <linux/autoconf.h>
465 +#include <linux/types.h>
466 +
467 +/* FLEXCAN module configuration register (CANMCR) bits */
468 +#define CANMCR_MDIS                            0x80000000
469 +#define CANMCR_FRZ                             0x40000000
470 +#define CANMCR_HALT                            0x10000000
471 +#define CANMCR_SOFTRST                         0x02000000
472 +#define CANMCR_FRZACK                          0x01000000
473 +#define CANMCR_SUPV                            0x00800000
474 +#define CANMCR_MAXMB(x)                                ((x)&0x0f)
475 +
476 +/* FLEXCAN control register (CANCTRL) bits */
477 +#define CANCTRL_PRESDIV(x)                     (((x)&0xff)<<24)
478 +#define CANCTRL_RJW(x)                         (((x)&0x03)<<22)
479 +#define CANCTRL_PSEG1(x)                       (((x)&0x07)<<19)
480 +#define CANCTRL_PSEG2(x)                       (((x)&0x07)<<16)
481 +#define CANCTRL_BOFFMSK                                0x00008000
482 +#define CANCTRL_ERRMSK                         0x00004000
483 +#define CANCTRL_LPB                            0x00001000
484 +#define CANCTRL_SAMP(x)                                (((x)&0x1)<<7)
485 +#define CANCTRL_BOFFREC                                0x00000040
486 +#define CANCTRL_TSYNC                          0x00000020
487 +#define CANCTRL_LBUF                           0x00000010
488 +#define CANCTRL_LOM                            0x00000008
489 +#define CANCTRL_PROPSEG(x)                     ((x)&0x07)
490 +#define CANCTRL_BITTIME                                0x00c0d078
491 +
492 +/* FLEXCAN error counter register (ERRCNT) bits */
493 +#define ERRCNT_REXECTR(x)                      (((x)&0xff)<<8)
494 +#define ERRCNT_TXECTR(x)                       ((x)&0xff)
495 +
496 +/* FLEXCAN error and status register (ERRSTAT) bits */
497 +#define ERRSTAT_BITERR(x)                      (((x)&0x03)<<14)
498 +#define ERRSTAT_ACKERR                         0x00002000
499 +#define ERRSTAT_CRCERR                         0x00001000
500 +#define ERRSTAT_FRMERR                         0x00000800
501 +#define ERRSTAT_STFERR                         0x00000400
502 +#define ERRSTAT_TXWRN                          0x00000200
503 +#define ERRSTAT_RXWRN                          0x00000100
504 +#define ERRSTAT_IDLE                           0x00000080
505 +#define ERRSTAT_TXRX                           0x00000040
506 +#define ERRSTAT_FLTCONF(x)                     (((x)&0x03)<<4)
507 +#define ERRSTAT_BOFFINT                                0x00000004
508 +#define ERRSTAT_ERRINT                         0x00000002
509 +
510 +/* FLEXCAN interrupt mask register (IMASK) bits */
511 +#define IMASK_BUF15M                           0x8000
512 +#define IMASK_BUF14M                           0x4000
513 +#define IMASK_BUF13M                           0x2000
514 +#define IMASK_BUF12M                           0x1000
515 +#define IMASK_BUF11M                           0x0800
516 +#define IMASK_BUF10M                           0x0400
517 +#define IMASK_BUF9M                            0x0200
518 +#define IMASK_BUF8M                            0x0100
519 +#define IMASK_BUF7M                            0x0080
520 +#define IMASK_BUF6M                            0x0040
521 +#define IMASK_BUF5M                            0x0020
522 +#define IMASK_BUF4M                            0x0010
523 +#define IMASK_BUF3M                            0x0008
524 +#define IMASK_BUF2M                            0x0004
525 +#define IMASK_BUF1M                            0x0002
526 +#define IMASK_BUF0M                            0x0001
527 +#define IMASK_BUFnM(x)                         (0x1<<(x))
528 +#define IMASK_BUFF_ENABLE_ALL                  0xffff
529 +#define IMASK_BUFF_DISABLE_ALL                         0x0000
530 +
531 +/* FLEXCAN interrupt flag register (IFLAG) bits */
532 +#define IFLAG_BUF15M                           0x8000
533 +#define IFLAG_BUF14M                           0x4000
534 +#define IFLAG_BUF13M                           0x2000
535 +#define IFLAG_BUF12M                           0x1000
536 +#define IFLAG_BUF11M                           0x0800
537 +#define IFLAG_BUF10M                           0x0400
538 +#define IFLAG_BUF9M                            0x0200
539 +#define IFLAG_BUF8M                            0x0100
540 +#define IFLAG_BUF7M                            0x0080
541 +#define IFLAG_BUF6M                            0x0040
542 +#define IFLAG_BUF5M                            0x0020
543 +#define IFLAG_BUF4M                            0x0010
544 +#define IFLAG_BUF3M                            0x0008
545 +#define IFLAG_BUF2M                            0x0004
546 +#define IFLAG_BUF1M                            0x0002
547 +#define IFLAG_BUF0M                            0x0001
548 +#define IFLAG_BUFnM(x)                         (0x1<<(x))
549 +#define IFLAG_BUFF_SET_ALL                     0xffff
550 +#define IFLAG_BUFF_DISABLE_ALL                         0x0000
551 +
552 +/* FLEXCAN message buffers */
553 +#define MB_CNT_CODE(x)                         (((x)&0x0f)<<24)
554 +#define MB_CNT_SRR                             0x00400000
555 +#define MB_CNT_IDE                             0x00200000
556 +#define MB_CNT_RTR                             0x00100000
557 +#define MB_CNT_LENGTH(x)                       (((x)&0x0f)<<16)
558 +#define MB_CNT_TIMESTAMP(x)                    ((x)&0xffff)
559 +
560 +#define MB_ID_STD                              ((0x7ff)<<18)
561 +#define MB_ID_EXT                              0x1fffffff
562 +#define MB_CODE_MASK                           0xf0ffffff
563 +
564 +/* Structure of the message buffer */
565 +struct flexcan_mb {
566 +       u32     can_dlc;
567 +       u32     can_id;
568 +       u8      data[8];
569 +};
570 +
571 +/* Structure of the hardware registers */
572 +struct flexcan_regs {
573 +       u32     canmcr;
574 +       u32     canctrl;
575 +       u32     timer;
576 +       u32     reserved1;
577 +       u32     rxgmask;
578 +       u32     rx14mask;
579 +       u32     rx15mask;
580 +       u32     errcnt;
581 +       u32     errstat;
582 +       u32     reserved2;
583 +       u32     imask;
584 +       u32     reserved3;
585 +       u32     iflag;
586 +       u32     reserved4[19];
587 +       struct  flexcan_mb cantxfg[16];
588 +};
589 +
590 +struct flexcan_platform_data {
591 +       u8 clock_src;           /* FLEXCAN clock source CRIN or SYSCLK */
592 +       u32 clock_frq;          /* can ref. clock, in Hz */
593 +};
594 +
595 +struct net_device *alloc_flexcandev(void);
596 +
597 +extern int register_flexcandev(struct net_device *dev, int clock_src);
598 +extern void unregister_flexcandev(struct net_device *dev);
599 +
600 +#endif                         /* __FLEXCAN_H__ */
601 --- /dev/null
602 +++ b/drivers/net/can/flexcan/mcf548x_can.c
603 @@ -0,0 +1,213 @@
604 +/*
605 + * DESCRIPTION:
606 + *  CAN bus driver for the Freescale MCF548x embedded CPU.
607 + *
608 + * AUTHOR:
609 + *  Andrey Volkov <avolkov@varma-el.com>
610 + *
611 + * COPYRIGHT:
612 + *  2004-2005, Varma Electronics Oy
613 + *
614 + * LICENCE:
615 + *  This program is free software; you can redistribute it and/or modify
616 + *  it under the terms of the GNU General Public License as published by
617 + *  the Free Software Foundation; either version 2 of the License, or
618 + *  (at your option) any later version.
619 + *
620 + *  This program is distributed in the hope that it will be useful,
621 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
622 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
623 + *  GNU General Public License for more details.
624 + *
625 + *  You should have received a copy of the GNU General Public License
626 + *  along with this program; if not, write to the Free Software
627 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
628 + *
629 + * HISTORY:
630 + *     2008-06-23 support for MCF548x's FlexCAN
631 + *             Huan, Wang  <b18965@freescale.com>
632 + *     2005-02-03 created
633 + *
634 + */
635 +
636 +#include <linux/kernel.h>
637 +#include <linux/module.h>
638 +#include <linux/interrupt.h>
639 +#include <linux/platform_device.h>
640 +#include <linux/netdevice.h>
641 +#include <linux/can.h>
642 +#include <linux/can/dev.h>
643 +#include <linux/io.h>
644 +
645 +#include "flexcan.h"
646 +#include <asm/coldfire.h>
647 +#include <asm/m5485sim.h>
648 +#include <linux/can/version.h> /* for RCSID. Removed by mkpatch script */
649 +
650 +RCSID("$Id$");
651 +
652 +#define PDEV_MAX 2
653 +
654 +struct platform_device *pdev[PDEV_MAX];
655 +
656 +static int __devinit mcf548x_can_probe(struct platform_device *pdev)
657 +{
658 +       struct resource *mem;
659 +       struct net_device *dev;
660 +       struct flexcan_platform_data *pdata = pdev->dev.platform_data;
661 +       struct can_priv *can;
662 +       u32 mem_size;
663 +       int ret = -ENODEV;
664 +
665 +       if (!pdata)
666 +               return ret;
667 +
668 +       dev = alloc_flexcandev();
669 +       if (!dev)
670 +               return -ENOMEM;
671 +       can = netdev_priv(dev);
672 +
673 +       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
674 +
675 +       dev->irq = platform_get_irq(pdev, 0);
676 +       if (!mem || !dev->irq)
677 +               goto req_error;
678 +
679 +       mem_size = mem->end - mem->start + 1;
680 +       if (!request_mem_region(mem->start, mem_size, pdev->dev.driver->name)) {
681 +               dev_err(&pdev->dev, "resource unavailable\n");
682 +               goto req_error;
683 +       }
684 +       SET_NETDEV_DEV(dev, &pdev->dev);
685 +
686 +       dev->base_addr = (unsigned long)ioremap_nocache(mem->start, mem_size);
687 +       if (!dev->base_addr) {
688 +               dev_err(&pdev->dev, "failed to map can port\n");
689 +               ret = -ENOMEM;
690 +               goto fail_map;
691 +       }
692 +       can->can_sys_clock = pdata->clock_frq;
693 +       platform_set_drvdata(pdev, dev);
694 +       ret = register_flexcandev(dev, pdata->clock_src);
695 +       if (ret >= 0) {
696 +               dev_info(&pdev->dev, "probe for port 0x%lX done\n",
697 +                        dev->base_addr);
698 +               return ret;
699 +       }
700 +
701 +       iounmap((unsigned long *)dev->base_addr);
702 +fail_map:
703 +       release_mem_region(mem->start, mem_size);
704 +req_error:
705 +       free_candev(dev);
706 +       dev_err(&pdev->dev, "probe failed\n");
707 +       return ret;
708 +}
709 +
710 +static int __devexit mcf548x_can_remove(struct platform_device *pdev)
711 +{
712 +       struct net_device *dev = platform_get_drvdata(pdev);
713 +       struct resource *mem;
714 +
715 +       platform_set_drvdata(pdev, NULL);
716 +       unregister_flexcandev(dev);
717 +       iounmap((unsigned long *)dev->base_addr);
718 +
719 +       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
720 +       release_mem_region(mem->start, mem->end - mem->start + 1);
721 +       free_candev(dev);
722 +       return 0;
723 +}
724 +
725 +static struct platform_driver mcf548x_can_driver = {
726 +       .driver = {
727 +                  .name = "mcf548x-flexcan",
728 +                  },
729 +       .probe = mcf548x_can_probe,
730 +       .remove = __devexit_p(mcf548x_can_remove),
731 +};
732 +
733 +static struct resource mcf548x_can0_resources[] = {
734 +       [0] = {
735 +               .start          = MCF_MBAR + 0x0000A000,
736 +               .end            = MCF_MBAR + 0x0000A7FF,
737 +               .flags          = IORESOURCE_MEM,
738 +       },
739 +       [1] = {
740 +               .start          = 49,
741 +               .end            = 49,
742 +               .flags          = IORESOURCE_IRQ,
743 +       },
744 +};
745 +
746 +static struct resource mcf548x_can1_resources[] = {
747 +       [0] = {
748 +               .start          = MCF_MBAR + 0x0000A800,
749 +               .end            = MCF_MBAR + 0x0000AFFF,
750 +               .flags          = IORESOURCE_MEM,
751 +       },
752 +       [1] = {
753 +               .start          = 55,
754 +               .end            = 55,
755 +               .flags          = IORESOURCE_IRQ,
756 +       },
757 +};
758 +
759 +
760 +static int __init mcf548x_of_to_pdev(void)
761 +{
762 +       unsigned int i;
763 +       int err = -ENODEV;
764 +       struct flexcan_platform_data pdata;
765 +
766 +       pdev[0] = platform_device_register_simple("mcf548x-flexcan", 0,
767 +                       mcf548x_can0_resources, 2);
768 +       if (IS_ERR(pdev[0])) {
769 +               err = PTR_ERR(pdev[0]);
770 +               return err;
771 +       }
772 +       pdev[1] = platform_device_register_simple("mcf548x-flexcan", 1,
773 +                       mcf548x_can1_resources, 2);
774 +       if (IS_ERR(pdev[1])) {
775 +               err = PTR_ERR(pdev[1]);
776 +               return err;
777 +       }
778 +
779 +       /* FlexCAN clock */
780 +       pdata.clock_frq = 100000000;
781 +
782 +       for (i = 0; i < PDEV_MAX; i++) {
783 +               err = platform_device_add_data(pdev[i], &pdata, sizeof(pdata));
784 +               if (err)
785 +                       return err;
786 +       }
787 +       return err;
788 +}
789 +
790 +int __init mcf548x_can_init(void)
791 +{
792 +       int err = mcf548x_of_to_pdev();
793 +
794 +       if (err) {
795 +               printk(KERN_ERR "%s init failed with err=%d\n",
796 +                       mcf548x_can_driver.driver.name, err);
797 +               return err;
798 +       }
799 +
800 +       return platform_driver_register(&mcf548x_can_driver);
801 +}
802 +
803 +void __exit mcf548x_can_exit(void)
804 +{
805 +       int i;
806 +       platform_driver_unregister(&mcf548x_can_driver);
807 +       for (i = 0; i < PDEV_MAX; i++)
808 +               platform_device_unregister(pdev[i]);
809 +}
810 +
811 +module_init(mcf548x_can_init);
812 +module_exit(mcf548x_can_exit);
813 +
814 +MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
815 +MODULE_DESCRIPTION("Freescale MCF548x CAN driver");
816 +MODULE_LICENSE("GPL v2");
817 --- a/include/asm-m68k/m5485sim.h
818 +++ b/include/asm-m68k/m5485sim.h
819 @@ -186,6 +186,8 @@
820  #define MCF_PAR_PCIBR             MCF_REG16(0x000A4A)
821  #define MCF_PAR_PSCn(x)            MCF_REG08(0x000A4F-((x)&0x3))
822  #define MCF_PAR_FECI2CIRQ         MCF_REG16(0x000A44)
823 +#define MCF_PAR_DSPI               MCF_REG16(0x000A50)
824 +#define MCF_PAR_TIMER              MCF_REG08(0X000A52)
825  #define MCF_EPPAR                 MCF_REG16(0x000F00)
826  #define MCF_EPIER                 MCF_REG08(0x000F05)
827  #define MCF_EPFR                          MCF_REG08(0x000F0C)
828 --- /dev/null
829 +++ b/include/linux/can/dev.h
830 @@ -0,0 +1,62 @@
831 +/*
832 + * linux/can/dev.h
833 + *
834 + * Definitions for CAN controller network devices lib (work in progress)
835 + *
836 + * * * $Id$
837 + *
838 + * Author: Andrey Volkov <avolkov@varma-el.com>
839 + * Copyright (c) 2006 Varma Electronics Oy
840 + *
841 + */
842 +
843 +#ifndef CAN_DEVICE_H
844 +#define CAN_DEVICE_H
845 +
846 +#include <linux/version.h>
847 +#include <linux/can/error.h>
848 +#include <linux/can/ioctl.h>
849 +
850 +struct can_priv {
851 +       struct can_device_stats can_stats;
852 +
853 +       /* can-bus oscillator frequency, in Hz,
854 +          BE CAREFUL! SOME CONTROLLERS (LIKE SJA1000)
855 +          FOOLISH ABOUT THIS FRQ (for sja1000 as ex. this
856 +          clock must be xtal clock divided by 2). */
857 +       u32     can_sys_clock;
858 +
859 +       /* by default max_brp is equal 64,
860 +          but for a Freescale TouCAN, as ex., it can be 255*/
861 +       u32     max_brp;
862 +       /* For the mostly all controllers, max_sjw is equal 4, but
863 +          some, hmm, CAN implementations hardwared it to 1 */
864 +       u8      max_sjw;
865 +
866 +       u32     baudrate;       /* in bauds */
867 +       struct can_bittime      bit_time;
868 +
869 +       spinlock_t irq_lock;
870 +       /* Please hold this lock when touching net_stats/can_stats*/
871 +       spinlock_t stats_lock;
872 +
873 +       can_state_t state;
874 +       can_mode_t  mode;
875 +       can_ctrlmode_t ctrlmode;
876 +
877 +       int (*do_set_bit_time)(struct net_device *dev, struct can_bittime *br);
878 +       int (*do_get_state)   (struct net_device *dev, can_state_t *state);
879 +       int (*do_set_mode)    (struct net_device *dev, can_mode_t mode);
880 +       int (*do_set_ctrlmode)(struct net_device *dev, can_ctrlmode_t ctrlmode);
881 +       int (*do_get_ctrlmode)(struct net_device *dev, can_ctrlmode_t *ctrlmode);
882 +};
883 +
884 +#define ND2D(_ndev)            (_ndev->dev.parent)
885 +
886 +struct net_device *alloc_candev(int sizeof_priv);
887 +void free_candev(struct net_device *dev);
888 +
889 +int can_calc_bit_time(struct can_priv *can, u32 baudrate,
890 +                     struct can_bittime_std *bit_time);
891 +
892 +#endif /* CAN_DEVICE_H */
893 --- /dev/null
894 +++ b/include/linux/can/ioctl.h
895 @@ -0,0 +1,152 @@
896 +/*
897 + * linux/can/ioctl.h
898 + *
899 + * Definitions for CAN controller setup (work in progress)
900 + *
901 + * $Id$
902 + *
903 + * Send feedback to <socketcan-users@lists.berlios.de>
904 + *
905 + */
906 +
907 +#ifndef CAN_IOCTL_H
908 +#define CAN_IOCTL_H
909 +
910 +#include <linux/sockios.h>
911 +
912 +
913 +/* max. 16 private ioctls */
914 +
915 +#define SIOCSCANBAUDRATE       (SIOCDEVPRIVATE+0)
916 +#define SIOCGCANBAUDRATE       (SIOCDEVPRIVATE+1)
917 +
918 +#define SIOCSCANCUSTOMBITTIME   (SIOCDEVPRIVATE+2)
919 +#define SIOCGCANCUSTOMBITTIME   (SIOCDEVPRIVATE+3)
920 +
921 +#define SIOCSCANMODE           (SIOCDEVPRIVATE+4)
922 +#define SIOCGCANMODE           (SIOCDEVPRIVATE+5)
923 +
924 +#define SIOCSCANCTRLMODE       (SIOCDEVPRIVATE+6)
925 +#define SIOCGCANCTRLMODE       (SIOCDEVPRIVATE+7)
926 +
927 +#define SIOCSCANFILTER         (SIOCDEVPRIVATE+8)
928 +#define SIOCGCANFILTER         (SIOCDEVPRIVATE+9)
929 +
930 +#define SIOCGCANSTATE          (SIOCDEVPRIVATE+10)
931 +#define SIOCGCANSTATS          (SIOCDEVPRIVATE+11)
932 +
933 +#define SIOCSCANERRORCONFIG    (SIOCDEVPRIVATE+12)
934 +#define SIOCGCANERRORCONFIG    (SIOCDEVPRIVATE+13)
935 +
936 +/* parameters for ioctls */
937 +
938 +/* SIOC[SG]CANBAUDRATE */
939 +/* baudrate for CAN-controller in bits per second. */
940 +/* 0 = Scan for baudrate (Autobaud) */
941 +
942 +typedef __u32 can_baudrate_t;
943 +
944 +
945 +/* SIOC[SG]CANCUSTOMBITTIME */
946 +
947 +typedef enum CAN_BITTIME_TYPE {
948 +       CAN_BITTIME_STD,
949 +       CAN_BITTIME_BTR
950 +} can_bittime_type_t;
951 +
952 +/* TSEG1 of controllers usually is a sum of synch_seg (always 1),
953 + * prop_seg and phase_seg1, TSEG2 = phase_seg2 */
954 +
955 +struct can_bittime_std {
956 +       __u32 brp;        /* baud rate prescaler */
957 +       __u8  prop_seg;   /* from 1 to 8 */
958 +       __u8  phase_seg1; /* from 1 to 8 */
959 +       __u8  phase_seg2; /* from 1 to 8 */
960 +       __u8  sjw:7;      /* from 1 to 4 */
961 +       __u8  sam:1;      /* 1 - enable triple sampling */
962 +};
963 +
964 +struct can_bittime_btr {
965 +       __u8  btr0;
966 +       __u8  btr1;
967 +};
968 +
969 +struct can_bittime {
970 +       can_bittime_type_t type;
971 +       union {
972 +               struct can_bittime_std std;
973 +               struct can_bittime_btr btr;
974 +       };
975 +};
976 +
977 +#define CAN_BAUDRATE_UNCONFIGURED      ((__u32) 0xFFFFFFFFU)
978 +#define CAN_BAUDRATE_UNKNOWN           0
979 +
980 +/* SIOC[SG]CANMODE */
981 +
982 +typedef __u32 can_mode_t;
983 +
984 +#define CAN_MODE_STOP  0
985 +#define CAN_MODE_START 1
986 +#define CAN_MODE_SLEEP 2
987 +
988 +
989 +/* SIOC[SG]CANCTRLMODE */
990 +
991 +typedef __u32 can_ctrlmode_t;
992 +
993 +#define CAN_CTRLMODE_LOOPBACK   0x1
994 +#define CAN_CTRLMODE_LISTENONLY 0x2
995 +
996 +
997 +/* SIOCGCANFILTER */
998 +
999 +typedef __u32 can_filter_t;
1000 +
1001 +/* filter modes (may vary due to controller specific capabilities) */
1002 +#define CAN_FILTER_CAPAB       0  /* get filter type capabilities
1003 +                                    (32 Bit value) */
1004 +#define CAN_FILTER_MASK_VALUE  1  /* easy bit filter (see struct can_filter) */
1005 +#define CAN_FILTER_SFF_BITMASK 2  /* bitfield with 2048 bit SFF filter */
1006 +                                 /* filters 3 - 31 currently undefined */
1007 +
1008 +#define CAN_FILTER_MAX         31 /* max. filter type value */
1009 +
1010 +
1011 +/* SIOCGCANSTATE */
1012 +
1013 +typedef __u32 can_state_t;
1014 +
1015 +#define CAN_STATE_ACTIVE               0
1016 +#define CAN_STATE_BUS_WARNING          1
1017 +#define CAN_STATE_BUS_PASSIVE          2
1018 +#define CAN_STATE_BUS_OFF              3
1019 +#define CAN_STATE_SCANNING_BAUDRATE    4
1020 +#define CAN_STATE_STOPPED              5
1021 +#define CAN_STATE_SLEEPING             6
1022 +
1023 +
1024 +/* SIOCGCANSTATS */
1025 +
1026 +struct can_device_stats {
1027 +       int error_warning;
1028 +       int data_overrun;
1029 +       int wakeup;
1030 +       int bus_error;
1031 +       int error_passive;
1032 +       int arbitration_lost;
1033 +       int restarts;
1034 +       int bus_error_at_init;
1035 +};
1036 +
1037 +/* SIOC[SG]CANERRORCONFIG */
1038 +
1039 +typedef enum CAN_ERRCFG_TYPE {
1040 +       CAN_ERRCFG_MASK,
1041 +       CAN_ERRCFG_BUSERR,
1042 +       CAN_ERRCFG_BUSOFF
1043 +} can_errcfg_type_t;
1044 +
1045 +/* tbd */
1046 +
1047 +#endif /* CAN_IOCTL_H */
1048 --- /dev/null
1049 +++ b/include/linux/can/version.h
1050 @@ -0,0 +1,22 @@
1051 +/*
1052 + * linux/can/version.h
1053 + *
1054 + * Version information for the CAN network layer implementation
1055 +
1056 + * Author: Urs Thuermann   <urs.thuermann@volkswagen.de>
1057 + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
1058 + * All rights reserved.
1059 + *
1060 + * Send feedback to <socketcan-users@lists.berlios.de>
1061 + *
1062 + */
1063 +
1064 +#ifndef CAN_VERSION_H
1065 +#define CAN_VERSION_H
1066 +
1067 +#define RCSID(s) asm(".section .rodata.str1.1,\"aMS\",@progbits,1\n\t" \
1068 +                    ".string \"" s "\"\n\t.previous\n")
1069 +
1070 +RCSID("$Id$");
1071 +
1072 +#endif /* CAN_VERSION_H */
1073 --- a/net/can/Makefile
1074 +++ b/net/can/Makefile
1075 @@ -10,3 +10,6 @@ can-raw-objs          := raw.o
1076  
1077  obj-$(CONFIG_CAN_BCM)  += can-bcm.o
1078  can-bcm-objs           := bcm.o
1079 +
1080 +obj-$(CONFIG_CAN)       += candev.o
1081 +candev-objs             := dev.o
1082 --- /dev/null
1083 +++ b/net/can/dev.c
1084 @@ -0,0 +1,292 @@
1085 +/*
1086 + * $Id$
1087 + *
1088 + * Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
1089 + * Copyright (C) 2006 Andrey Volkov, Varma Electronics
1090 + *
1091 + * This program is free software; you can redistribute it and/or modify
1092 + * it under the terms of the version 2 of the GNU General Public License
1093 + * as published by the Free Software Foundation
1094 + *
1095 + * This program is distributed in the hope that it will be useful,
1096 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1097 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1098 + * GNU General Public License for more details.
1099 + *
1100 + * You should have received a copy of the GNU General Public License
1101 + * along with this program; if not, write to the Free Software
1102 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1103 + */
1104 +
1105 +#include <linux/module.h>
1106 +#include <linux/netdevice.h>
1107 +#include <linux/if_arp.h>
1108 +#include <linux/can.h>
1109 +#include <linux/can/dev.h>
1110 +
1111 +MODULE_DESCRIPTION("CAN netdevice library");
1112 +MODULE_LICENSE("GPL v2");
1113 +MODULE_AUTHOR("Marc Kleine-Budde <mkl@pengutronix.de>, "
1114 +             "Andrey Volkov <avolkov@varma-el.com>");
1115 +
1116 +/*
1117 + Abstract:
1118 +       Baud rate calculated with next formula:
1119 +       baud = frq/(brp*(1 + prop_seg+ phase_seg1 + phase_seg2))
1120 +
1121 +       This calc function based on work of Florian Hartwich and Armin Bassemi
1122 +       "The Configuration of the CAN Bit Timing"
1123 +       (http://www.semiconductors.bosch.de/pdf/CiA99Paper.pdf)
1124 +
1125 + Parameters:
1126 +  [in]
1127 +    bit_time_nsec - expected bit time in nanosecs
1128 +
1129 +  [out]
1130 +       bit_time        - calculated time segments, for meaning of
1131 +                         each field read CAN standard.
1132 +*/
1133 +
1134 +#define DEFAULT_MAX_BRP                        64U
1135 +#define DEFAULT_MAX_SJW                        4U
1136 +
1137 +/* All below values in tq units */
1138 +#define MAX_BIT_TIME   25U
1139 +#define MIN_BIT_TIME   8U
1140 +#define MAX_PROP_SEG   8U
1141 +#define MAX_PHASE_SEG1 8U
1142 +#define MAX_PHASE_SEG2 8U
1143 +
1144 +int can_calc_bit_time(struct can_priv *can, u32 baudrate,
1145 +                     struct can_bittime_std *bit_time)
1146 +{
1147 +       int best_error  = -1; /* Ariphmetic error */
1148 +       int df, best_df = -1; /* oscillator's tolerance range */
1149 +       u32 quanta;           /*in tq units*/
1150 +       u32 brp, phase_seg1, phase_seg2, sjw, prop_seg;
1151 +       u32 brp_min, brp_max, brp_expected;
1152 +       u64 tmp;
1153 +
1154 +       /* baudrate range [1baud,1Mbaud] */
1155 +       if (baudrate == 0 || baudrate > 1000000UL)
1156 +               return -EINVAL;
1157 +
1158 +       tmp = (u64)can->can_sys_clock*1000;
1159 +       do_div(tmp, baudrate);
1160 +       brp_expected = (u32)tmp;
1161 +
1162 +       brp_min = brp_expected / (1000 * MAX_BIT_TIME);
1163 +       if (brp_min == 0)
1164 +               brp_min = 1;
1165 +       if (brp_min > can->max_brp)
1166 +               return -ERANGE;
1167 +
1168 +       brp_max = (brp_expected + 500 * MIN_BIT_TIME) / (1000 * MIN_BIT_TIME);
1169 +       if (brp_max == 0)
1170 +               brp_max = 1;
1171 +       if (brp_max > can->max_brp)
1172 +               brp_max = can->max_brp;
1173 +
1174 +       for (brp = brp_min; brp <= brp_max; brp++) {
1175 +               quanta = brp_expected / (brp * 1000);
1176 +               if (quanta < MAX_BIT_TIME && quanta * brp * 1000 !=
1177 +                               brp_expected)
1178 +                       quanta++;
1179 +               if (quanta < MIN_BIT_TIME || quanta > MAX_BIT_TIME)
1180 +                       continue;
1181 +
1182 +               phase_seg2 = min((quanta - 3) / 2, MAX_PHASE_SEG2);
1183 +               for (sjw = can->max_sjw; sjw > 0; sjw--) {
1184 +                       for (; phase_seg2 > sjw; phase_seg2--) {
1185 +                               u32 err1, err2;
1186 +                               phase_seg1 = phase_seg2 % 2 ?
1187 +                                       phase_seg2-1 : phase_seg2;
1188 +                               prop_seg = quanta-1 - phase_seg2 - phase_seg1;
1189 +                               /*
1190 +                                * FIXME: support of longer lines
1191 +                                * (i.e. bigger prop_seg) is more prefered
1192 +                                * than support of cheap oscillators
1193 +                                * (i.e. bigger df/phase_seg1/phase_seg2)
1194 +                                * */
1195 +
1196 +                               if (prop_seg < phase_seg1)
1197 +                                               continue;
1198 +                               if (prop_seg > MAX_PROP_SEG)
1199 +                                               goto next_brp;
1200 +
1201 +                               err1 = phase_seg1 * brp * 500 * 1000 /
1202 +                                       (13 * brp_expected - phase_seg2 *
1203 +                                        brp * 1000);
1204 +                               err2 = sjw * brp * 50 * 1000 / brp_expected;
1205 +
1206 +                               df = min(err1, err2);
1207 +                               if (df >= best_df) {
1208 +                                       unsigned error = abs(brp_expected * 10 /
1209 +                                                       (brp * (1 + prop_seg +
1210 +                                                               phase_seg1 +
1211 +                                                               phase_seg2)) - 10000);
1212 +
1213 +                                       if (error > 10 || error > best_error)
1214 +                                               continue;
1215 +
1216 +                                       if (error == best_error && prop_seg <
1217 +                                                       bit_time->prop_seg)
1218 +                                               continue;
1219 +
1220 +                                       best_error = error;
1221 +                                       best_df = df;
1222 +                                       bit_time->brp = brp;
1223 +                                       bit_time->prop_seg = prop_seg;
1224 +                                       bit_time->phase_seg1 = phase_seg1;
1225 +                                       bit_time->phase_seg2 = phase_seg2;
1226 +                                       bit_time->sjw = sjw;
1227 +                                       bit_time->sam =
1228 +                                               (bit_time->phase_seg1 > 3);
1229 +                               }
1230 +                       }
1231 +               }
1232 +next_brp:      ;
1233 +       }
1234 +
1235 +       if (best_error < 0)
1236 +               return -EDOM;
1237 +       return 0;
1238 +}
1239 +EXPORT_SYMBOL(can_calc_bit_time);
1240 +
1241 +static int can_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1242 +{
1243 +       struct can_priv *can = netdev_priv(dev);
1244 +       struct can_bittime *bt = (struct can_bittime *)&ifr->ifr_ifru;
1245 +       ulong *baudrate = (ulong *)&ifr->ifr_ifru;
1246 +       int ret = -EOPNOTSUPP;
1247 +
1248 +       dev_dbg(ND2D(dev), "(%s) 0x%08x %p\n", __func__, cmd, &ifr->ifr_ifru);
1249 +
1250 +       switch (cmd) {
1251 +       case SIOCSCANBAUDRATE:
1252 +               if (can->do_set_bit_time) {
1253 +                       struct can_bittime bit_time;
1254 +                       ret = can_calc_bit_time(can, *baudrate, &bit_time.std);
1255 +                       if (ret != 0)
1256 +                               break;
1257 +                       bit_time.type = CAN_BITTIME_STD;
1258 +                       ret = can->do_set_bit_time(dev, &bit_time);
1259 +                       if (!ret) {
1260 +                               can->baudrate = *baudrate;
1261 +                               can->bit_time = bit_time;
1262 +                       }
1263 +               }
1264 +               break;
1265 +       case SIOCGCANBAUDRATE:
1266 +               *baudrate = can->baudrate;
1267 +               ret = 0;
1268 +               break;
1269 +       case SIOCSCANCUSTOMBITTIME:
1270 +               if (can->do_set_bit_time) {
1271 +                       ret = can->do_set_bit_time(dev, bt);
1272 +                       if (!ret) {
1273 +                               can->bit_time = *bt;
1274 +                               if (bt->type == CAN_BITTIME_STD && bt->std.brp) {
1275 +                                       can->baudrate = can->can_sys_clock /
1276 +                                               (bt->std.brp * (1 + bt->std.prop_seg +
1277 +                                                               bt->std.phase_seg1 +
1278 +                                                               bt->std.phase_seg2));
1279 +                               } else
1280 +                                       can->baudrate = CAN_BAUDRATE_UNKNOWN;
1281 +                       }
1282 +               }
1283 +               break;
1284 +       case SIOCGCANCUSTOMBITTIME:
1285 +               *bt = can->bit_time;
1286 +               ret = 0;
1287 +               break;
1288 +       case SIOCSCANMODE:
1289 +               if (can->do_set_mode) {
1290 +                       can_mode_t mode =
1291 +                               *((can_mode_t *)(&ifr->ifr_ifru));
1292 +                       if (mode == CAN_MODE_START &&
1293 +                           can->baudrate == CAN_BAUDRATE_UNCONFIGURED) {
1294 +                               dev_info(ND2D(dev), "Impossible to start \
1295 +                                               on UNKNOWN speed\n");
1296 +                               ret = EINVAL;
1297 +                       } else
1298 +                               return can->do_set_mode(dev, mode);
1299 +               }
1300 +               break;
1301 +       case SIOCGCANMODE:
1302 +               *((can_mode_t *)(&ifr->ifr_ifru)) = can->mode;
1303 +               ret = 0;
1304 +               break;
1305 +       case SIOCSCANCTRLMODE:
1306 +               if (can->do_set_ctrlmode) {
1307 +                       can_ctrlmode_t ctrlmode =
1308 +                               *((can_ctrlmode_t *)(&ifr->ifr_ifru));
1309 +                       return can->do_set_ctrlmode(dev, ctrlmode);
1310 +               }
1311 +               break;
1312 +       case SIOCGCANCTRLMODE:
1313 +               *((can_ctrlmode_t *)(&ifr->ifr_ifru)) = can->ctrlmode;
1314 +               ret = 0;
1315 +               break;
1316 +       case SIOCSCANFILTER:
1317 +               break;
1318 +       case SIOCGCANFILTER:
1319 +               break;
1320 +       case SIOCGCANSTATE:
1321 +               if (can->do_get_state)
1322 +                       return can->do_get_state(dev,
1323 +                                       (can_state_t *)(&ifr->ifr_ifru));
1324 +               break;
1325 +       case SIOCGCANSTATS:
1326 +               *((struct can_device_stats *)(&ifr->ifr_ifru)) = can->can_stats;
1327 +               ret = 0;
1328 +               break;
1329 +       }
1330 +
1331 +       return ret;
1332 +}
1333 +
1334 +static void can_setup(struct net_device *dev)
1335 +{
1336 +       dev->type            = ARPHRD_CAN;
1337 +       dev->mtu             = sizeof(struct can_frame);
1338 +       dev->do_ioctl        = can_ioctl;
1339 +       dev->hard_header_len = 0;
1340 +       dev->addr_len        = 0;
1341 +       dev->tx_queue_len    = 10;
1342 +
1343 +       /* New-style flags. */
1344 +       dev->flags           = IFF_NOARP;
1345 +       dev->features        = NETIF_F_NO_CSUM;
1346 +}
1347 +
1348 +/*
1349 + * Function  alloc_candev
1350 + *     Allocates and sets up an CAN device
1351 + */
1352 +struct net_device *alloc_candev(int sizeof_priv)
1353 +{
1354 +       struct net_device *dev;
1355 +       struct can_priv *priv;
1356 +
1357 +       dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
1358 +       if (!dev)
1359 +               return NULL;
1360 +
1361 +       priv = netdev_priv(dev);
1362 +
1363 +       priv->baudrate = CAN_BAUDRATE_UNCONFIGURED;
1364 +       priv->max_brp  = DEFAULT_MAX_BRP;
1365 +       priv->max_sjw  = DEFAULT_MAX_SJW;
1366 +       spin_lock_init(&priv->irq_lock);
1367 +
1368 +       return dev;
1369 +}
1370 +EXPORT_SYMBOL(alloc_candev);
1371 +
1372 +void free_candev(struct net_device *dev)
1373 +{
1374 +       free_netdev(dev);
1375 +}
1376 +EXPORT_SYMBOL(free_candev);