]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/drivers/net/can/mscan/mscan.c
fixed includes and defines.
[socketcan-devel.git] / kernel / 2.6 / drivers / net / can / mscan / mscan.c
1 /*
2  * $Id$
3  *
4  * mscan.c
5  *
6  * DESCRIPTION:
7  *  CAN bus driver for the alone generic (as possible as) MSCAN controller.
8  *
9  * AUTHOR:
10  *  Andrey Volkov <avolkov@varma-el.com>
11  *
12  * COPYRIGHT:
13  *  2005-2006, Varma Electronics Oy
14  *
15  * LICENCE:
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 2 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, write to the Free Software
28  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29  *
30  */
31
32 #include <linux/autoconf.h>
33 #include <linux/kernel.h>
34 #include <linux/module.h>
35 #include <linux/interrupt.h>
36 #include <linux/delay.h>
37 #include <linux/netdevice.h>
38 #include <linux/can.h>
39 #include <linux/list.h>
40 #include <asm/io.h>
41
42 #include <linux/can/dev.h>
43 #include <linux/can/error.h>
44 #include "mscan.h"
45
46 #define MSCAN_NORMAL_MODE       0
47 #define MSCAN_SLEEP_MODE         MSCAN_SLPRQ
48 #define MSCAN_INIT_MODE         (MSCAN_INITRQ | MSCAN_SLPRQ)
49 #define MSCAN_POWEROFF_MODE     (MSCAN_CSWAI | MSCAN_SLPRQ)
50
51 #define BTR0_BRP_MASK   0x3f
52 #define BTR0_SJW_SHIFT  6
53 #define BTR0_SJW_MASK   (0x3 << BTR0_SJW_SHIFT)
54
55 #define BTR1_TSEG1_MASK  0xf
56 #define BTR1_TSEG2_SHIFT 4
57 #define BTR1_TSEG2_MASK  (0x7 << BTR1_TSEG2_SHIFT)
58 #define BTR1_SAM_SHIFT   7
59
60 #define BTR0_SET_BRP(brp)       (((brp)-1)&BTR0_BRP_MASK)
61 #define BTR0_SET_SJW(sjw)       ((((sjw)-1)<<BTR0_SJW_SHIFT)&BTR0_SJW_MASK)
62
63 #define BTR1_SET_TSEG1(tseg1) (((tseg1)-1)&BTR1_TSEG1_MASK)
64 #define BTR1_SET_TSEG2(tseg2) ((((tseg2)-1)<<BTR1_TSEG2_SHIFT)&BTR1_TSEG2_MASK)
65 #define BTR1_SET_SAM(sam)         (((sam)&1)<<BTR1_SAM_SHIFT)
66
67 struct mscan_state {
68         u8 mode;
69         u8 canrier;
70         u8 cantier;
71 };
72
73 #define TX_QUEUE_SIZE   3
74
75 typedef struct {
76         struct list_head list;
77         u8 mask;
78 } tx_queue_entry_t;
79
80 struct mscan_priv {
81         volatile unsigned long flags;
82         u8 shadow_statflg;
83         u8 shadow_canrier;
84         u8 cur_pri;
85         u8 tx_active;
86
87         struct list_head tx_head;
88         tx_queue_entry_t tx_queue[TX_QUEUE_SIZE];
89 };
90
91 #define F_RX_PROGRESS   0
92 #define F_TX_PROGRESS   1
93 #define F_TX_WAIT_ALL   2
94
95 static int mscan_set_mode(struct can_device *can, u8 mode)
96 {
97         struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
98         int ret = 0;
99         int i;
100         u8 canctl1;
101
102         if( mode != MSCAN_NORMAL_MODE ) {
103                 canctl1 = in_8(&regs->canctl1);
104                 if ((mode & MSCAN_SLPRQ) && (canctl1 & MSCAN_SLPAK) == 0) {
105                         out_8( &regs->canctl0, in_8(&regs->canctl0) | MSCAN_SLPRQ );
106                         for (i = 0; i < 255; i++ ) {
107                                 if ( in_8(&regs->canctl1) & MSCAN_SLPAK )
108                                         break;
109                                 udelay(100);
110                         }
111                         if(i>255)
112                            ret=-ENODEV;
113                 }
114
115                 if ( !ret && (mode & MSCAN_INITRQ) && (canctl1 & MSCAN_INITAK) == 0) {
116                         out_8( &regs->canctl0, in_8( &regs->canctl0 ) | MSCAN_INITRQ);
117                         for (i = 0; i < 255; i++ ) {
118                                 if ( in_8(&regs->canctl1) & MSCAN_INITAK )
119                                         break;
120                         }
121                         if(i>255)
122                                 ret=-ENODEV;
123                 }
124
125                 if ( !ret && (mode & MSCAN_CSWAI) )
126                         out_8( &regs->canctl0, in_8(&regs->canctl0) | MSCAN_CSWAI);
127
128         } else  {
129                 canctl1 = in_8(&regs->canctl1);
130                 if ( canctl1 & (MSCAN_SLPAK | MSCAN_INITAK) ) {
131                         out_8(&regs->canctl0, in_8(&regs->canctl0) &
132                               ~(MSCAN_SLPRQ | MSCAN_INITRQ));
133                         for (i = 0; i < 255; i++ ) {
134                                 canctl1 = in_8(&regs->canctl1);
135                                 if ( (canctl1 & (MSCAN_INITAK | MSCAN_SLPAK)) ==0 )
136                                         break;
137                         }
138                         if(i>255)
139                                 ret=-ENODEV;
140                 }
141         }
142         return ret;
143 }
144
145 static void mscan_push_state(struct can_device *can, struct mscan_state *state)
146 {
147         struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
148
149         state->mode = in_8(&regs->canctl0) &
150                                         (MSCAN_SLPRQ | MSCAN_INITRQ | MSCAN_CSWAI);
151         state->canrier = in_8(&regs->canrier);
152         state->cantier = in_8(&regs->cantier);
153 }
154
155 static int mscan_pop_state(struct can_device *can, struct mscan_state *state)
156 {
157         struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
158         int ret;
159         ret = mscan_set_mode(can, state->mode);
160         if (!ret) {
161                 out_8( &regs->canrier, state->canrier);
162                 out_8( &regs->cantier, state->cantier);
163         }
164         return ret;
165 }
166
167 static int mscan_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
168 {
169         struct can_frame *frame = (struct can_frame *)skb->data;
170         struct can_device *can = ND2CAN(ndev);
171         struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
172         struct mscan_priv *priv = can->priv;
173         int i, rtr, buf_id;
174         u32 can_id;
175
176         if ( frame->can_dlc > 8 )
177                 return -EINVAL;
178
179         dev_dbg( ND2D(ndev), "%s\n", __FUNCTION__);
180         out_8(&regs->cantier, 0);
181
182         i = ~priv->tx_active & MSCAN_TXE;
183         buf_id = ffs(i) - 1;
184         switch ( hweight8(i) ) {
185                 case 0:
186                         netif_stop_queue(ndev);
187                         dev_err( ND2D(ndev), "BUG! Tx Ring full when queue awake!\n" );
188                         return NETDEV_TX_BUSY;
189                 case 1:
190                         /* if buf_id < 3, then current frame will be send out of order,
191                            since  buffer with lower id have higher priority (hell..) */
192                         if(buf_id < 3 )
193                                 priv->cur_pri++;
194                         if(priv->cur_pri==0xff)
195                                 set_bit(F_TX_WAIT_ALL, &priv->flags);
196                         netif_stop_queue(ndev);
197                 case 2:
198                         set_bit(F_TX_PROGRESS, &priv->flags);
199         }
200         out_8(&regs->cantbsel, i);
201
202         rtr = frame->can_id & CAN_RTR_FLAG;
203
204         if (frame->can_id & CAN_EFF_FLAG) {
205                 dev_dbg(ND2D(ndev), "sending extended frame\n");
206
207                 can_id = (frame->can_id & CAN_EFF_MASK) << 1;
208                 if( rtr )
209                         can_id |= 1;
210                 out_be16(&regs->tx.idr3_2, can_id);
211
212                 can_id>>=16;
213                 can_id = (can_id & 0x7) | ((can_id<<2) & 0xffe0) | (3<<3);
214         } else {
215                 dev_dbg(ND2D(ndev), "sending standard frame\n");
216                 can_id = (frame->can_id & CAN_SFF_MASK) << 5;
217                 if( rtr )
218                         can_id |= 1<<4;
219         }
220         out_be16(&regs->tx.idr1_0, can_id);
221
222         if ( !rtr ) {
223                 volatile void __iomem *data = &regs->tx.dsr1_0;
224                 u16 *payload = (u16 *)frame->data;
225                 /*Its safe to write into dsr[dlc+1]*/
226                 for (i=0; i<(frame->can_dlc+1)/2; i++) {
227                         out_be16(data, *payload++);
228                     data += 2+_MSCAN_RESERVED_DSR_SIZE;
229                 }
230         }
231
232         out_8(&regs->tx.dlr, frame->can_dlc);
233         out_8(&regs->tx.tbpr, priv->cur_pri);
234
235         /* Start transmission. */
236         out_8(&regs->cantflg, 1<<buf_id);
237
238         if ( ! test_bit(F_TX_PROGRESS, &priv->flags) )
239                 ndev->trans_start = jiffies;
240
241         list_add_tail( &priv->tx_queue[buf_id].list, &priv->tx_head);
242
243         dev_kfree_skb (skb);
244
245         /* Enable interrupt. */
246         priv->tx_active |= 1<<buf_id;
247         out_8( &regs->cantier, priv->tx_active);
248
249         return NETDEV_TX_OK;
250 }
251
252
253 static void mscan_tx_timeout(struct net_device *ndev)
254 {
255         struct sk_buff *skb;
256         struct can_device *can = ND2CAN(ndev);
257         struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
258         struct mscan_priv *priv = can->priv;
259         struct can_frame *frame;
260         u8 mask;
261
262         printk ("%s\n", __FUNCTION__);
263
264         out_8(&regs->cantier, 0);
265
266         mask = list_entry( priv->tx_head.next, tx_queue_entry_t, list)->mask;
267         ndev->trans_start = jiffies;
268         out_8(&regs->cantarq, mask);
269         out_8(&regs->cantier, priv->tx_active);
270
271         skb = dev_alloc_skb(sizeof(struct can_frame));
272         if (!skb) {
273                 if(printk_ratelimit())
274                         dev_notice(ND2D(ndev), "TIMEOUT packet dropped\n");
275                 return;
276         }
277         frame = (struct can_frame *)skb_put(skb,sizeof(struct can_frame));
278
279         frame->can_id = CAN_ERR_FLAG | CAN_ERR_TX_TIMEOUT;
280         frame->can_dlc = CAN_ERR_DLC;
281
282         skb->dev = ndev;
283         skb->protocol = __constant_htons(ETH_P_CAN);
284         skb->ip_summed = CHECKSUM_UNNECESSARY;
285         netif_rx(skb);
286
287 }
288
289 static can_state_t state_map[] = {
290         CAN_STATE_ACTIVE,
291         CAN_STATE_BUS_WARNING,
292         CAN_STATE_BUS_PASSIVE,
293         CAN_STATE_BUS_OFF
294 };
295
296 static inline int check_set_state(struct can_device *can, u8 canrflg)
297 {
298  can_state_t state;
299  int ret = 0;
300
301  if ( !(canrflg & MSCAN_CSCIF) || can->state > CAN_STATE_BUS_OFF)
302         return 0;
303
304  state = state_map[max( MSCAN_STATE_RX(canrflg), MSCAN_STATE_TX(canrflg))];
305  if(can->state < state)
306         ret = 1;
307  if(state == CAN_STATE_BUS_OFF)
308         netif_carrier_off(CAN2ND(can));
309  else if(can->state == CAN_STATE_BUS_OFF && state != CAN_STATE_BUS_OFF)
310         netif_carrier_on(CAN2ND(can));
311  can->state = state;
312  return ret;
313 }
314
315 static int mscan_rx_poll(struct net_device *ndev, int *budget)
316 {
317         struct can_device *can = ND2CAN(ndev);
318         struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
319         struct mscan_priv *priv = can->priv;
320         int npackets = 0, quota = min(ndev->quota, *budget);
321         int ret = 1;
322         struct sk_buff *skb;
323         struct can_frame *frame;
324         u32 can_id;
325         u8  canrflg;
326         int i;
327
328         while ( npackets < quota &&
329         ( (canrflg = in_8(&regs->canrflg)) & (MSCAN_RXF | MSCAN_ERR_IF) )) {
330
331                 skb = dev_alloc_skb(sizeof(struct can_frame));
332                 if (!skb) {
333                         if(printk_ratelimit())
334                                 dev_notice(ND2D(ndev), "packet dropped\n");
335                         can->net_stats.rx_dropped++;
336                         out_8(&regs->canrflg, canrflg);
337                         continue;
338                 }
339
340                 frame = (struct can_frame *)skb_put(skb,sizeof(struct can_frame));
341
342                 if (canrflg & MSCAN_RXF) {
343                         can_id = in_be16( &regs->rx.idr1_0 );
344                         if (can_id & (1<<3) ) {
345                            frame->can_id = CAN_EFF_FLAG;
346                            can_id = (can_id << 16) | in_be16(&regs->rx.idr3_2);
347                            can_id = ((can_id & 0xffe00000) | ((can_id & 0x7ffff) << 2 ))>>2;
348                         }
349                         else  {
350                                 can_id >>= 4;
351                                 frame->can_id = 0;
352                         }
353
354                         frame->can_id |= can_id>>1;
355                         if(can_id & 1)
356                                 frame->can_id |= CAN_RTR_FLAG;
357                         frame->can_dlc = in_8(&regs->rx.dlr) & 0xf;
358
359                         if( !(frame->can_id & CAN_RTR_FLAG ) ) {
360                                 volatile void __iomem * data = &regs->rx.dsr1_0;
361                                 u16 *payload = (u16 *)frame->data;
362                                 for (i=0; i<(frame->can_dlc+1)/2; i++) {
363                                         *payload++ = in_be16(data);
364                                     data += 2+_MSCAN_RESERVED_DSR_SIZE;
365                                 }
366                         }
367
368                         dev_dbg(ND2D(ndev), "received pkt: id: %u dlc: %u data: ",
369                                 frame->can_id,frame->can_dlc);
370 #ifdef DEBUG
371                         for(i=0; i<frame->can_dlc && !(frame->can_id & CAN_FLAG_RTR ); i++)
372                                 printk( "%2x ",frame->data[i]);
373                         printk("\n");
374 #endif
375
376                         out_8(&regs->canrflg, MSCAN_RXF);
377                         ndev->last_rx = jiffies;
378                         can->net_stats.rx_packets++;
379                         can->net_stats.rx_bytes += frame->can_dlc;
380                 }
381                 else if (canrflg & MSCAN_ERR_IF ) {
382                         frame->can_id = CAN_ERR_FLAG;
383
384                         if (canrflg & MSCAN_OVRIF) {
385                                 frame->can_id |= CAN_ERR_CRTL;
386                                 frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
387                                 can->net_stats.rx_over_errors++;
388                         }
389                         else
390                                 frame->data[1] = 0;
391
392                         if ( check_set_state(can, canrflg)) {
393                           frame->can_id |= CAN_ERR_CRTL;
394                           switch( can->state )  {
395                                   case CAN_STATE_BUS_WARNING:
396                                         if( (priv->shadow_statflg & MSCAN_RSTAT_MSK) <
397                                             (canrflg & MSCAN_RSTAT_MSK))
398                                                 frame->data[1] |= CAN_ERR_CRTL_RX_WARNING;
399
400                                         if( (priv->shadow_statflg & MSCAN_TSTAT_MSK) <
401                                             (canrflg & MSCAN_TSTAT_MSK))
402                                                 frame->data[1] |= CAN_ERR_CRTL_TX_WARNING;
403                                         break;
404                                   case CAN_STATE_BUS_PASSIVE:
405                                         frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
406                                         break;
407                                   case CAN_STATE_BUS_OFF:
408                                         frame->can_id |= CAN_ERR_BUSOFF;
409                                         frame->can_id &= ~CAN_ERR_CRTL;
410                                         break;
411                           }
412                         }
413                         priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
414                         frame->can_dlc = CAN_ERR_DLC;
415                         out_8(&regs->canrflg, MSCAN_ERR_IF);
416                 }
417
418                 npackets++;
419                 skb->dev = ndev;
420                 skb->protocol = __constant_htons(ETH_P_CAN);
421                 skb->ip_summed = CHECKSUM_UNNECESSARY;
422                 netif_receive_skb(skb);
423         }
424
425   *budget -= npackets;
426   ndev->quota -= npackets;
427
428   if ( !(in_8(&regs->canrflg) & (MSCAN_RXF | MSCAN_ERR_IF))) {
429         netif_rx_complete(ndev);
430         clear_bit(F_RX_PROGRESS, &priv->flags);
431         out_8(&regs->canrier, in_8(&regs->canrier) | MSCAN_ERR_IF | MSCAN_RXFIE);
432         ret = 0;
433   }
434   return ret;
435 }
436
437 static irqreturn_t
438 mscan_isr(int irq, void *dev_id, struct pt_regs *r)
439 {
440         struct net_device *ndev = (struct net_device *) dev_id;
441         struct can_device *can = ND2CAN(ndev);
442         struct mscan_regs *regs = (struct mscan_regs *)(ndev->base_addr);
443         struct mscan_priv *priv = can->priv;
444         u8 cantflg, canrflg;
445         irqreturn_t ret = IRQ_NONE;
446
447         if ( in_8(&regs->cantier) & MSCAN_TXE )
448         {
449                 struct list_head *tmp, *pos;
450
451                 cantflg = in_8(&regs->cantflg) & MSCAN_TXE;
452
453                 list_for_each_safe(pos, tmp, &priv->tx_head)  {
454                         tx_queue_entry_t *entry = list_entry(pos, tx_queue_entry_t, list);
455                         u8 mask = entry->mask;
456
457                         if( !(cantflg & mask) )
458                                 continue;
459
460                         if ( in_8(&regs->cantaak) & mask ) {
461                                 can->net_stats.tx_dropped++;
462                                 can->net_stats.tx_aborted_errors++;
463                         }
464                         else {
465                                 out_8(&regs->cantbsel, mask);
466                                 can->net_stats.tx_bytes += in_8(&regs->tx.dlr);
467                                 can->net_stats.tx_packets++;
468                         }
469                         priv->tx_active &= ~mask;
470                         list_del(pos);
471                 }
472
473                 if ( list_empty(&priv->tx_head) ) {
474                         clear_bit(F_TX_WAIT_ALL, &priv->flags);
475                         clear_bit(F_TX_PROGRESS, &priv->flags);
476                         priv->cur_pri = 0;
477                 }
478                 else
479                         ndev->trans_start = jiffies;
480
481                 if( !test_bit(F_TX_WAIT_ALL, &priv->flags) )
482                         netif_wake_queue(ndev);
483
484                 out_8( &regs->cantier, priv->tx_active );
485                 ret = IRQ_HANDLED;
486         }
487
488         if ( !test_and_set_bit(F_RX_PROGRESS, &priv->flags) &&
489                 (((canrflg = in_8(&regs->canrflg)) & ~MSCAN_STAT_MSK))) {
490                 if ( check_set_state(can, canrflg) ) {
491                         out_8(&regs->canrflg, MSCAN_CSCIF);
492                         ret = IRQ_HANDLED;
493                 }
494                 if (canrflg & ~MSCAN_STAT_MSK) {
495                         priv->shadow_canrier = in_8(&regs->canrier);
496                         out_8(&regs->canrier, 0);
497                         netif_rx_schedule(ndev);
498                         ret = IRQ_HANDLED;
499                 }
500                 else
501                         clear_bit(F_RX_PROGRESS, &priv->flags);
502         }
503         return ret;
504 }
505
506 static int mscan_do_set_mode(struct can_device *can, can_mode_t mode)
507 {
508         switch (mode) {
509         case CAN_MODE_SLEEP:
510         case CAN_MODE_STOP:
511                 netif_stop_queue(CAN2ND(can));
512                 mscan_set_mode(can,
513                                         (mode==CAN_MODE_STOP)? MSCAN_INIT_MODE: MSCAN_SLEEP_MODE);
514                 break;
515         case CAN_MODE_START:
516                 printk("%s: CAN_MODE_START requested\n",__FUNCTION__);
517                 mscan_set_mode(can, MSCAN_NORMAL_MODE);
518                 netif_wake_queue(CAN2ND(can));
519                 break;
520
521         default:
522                 return -EOPNOTSUPP;
523         }
524         return 0;
525 }
526
527 static
528 int mscan_do_set_bit_time(struct can_device *can, struct can_bittime *bt)
529 {
530         int ret = 0;
531         u8 reg;
532         struct mscan_state state;
533         struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
534
535         if(bt->type != CAN_BITTIME_STD)
536                 return -EINVAL;
537
538         spin_lock_irq(&can->irq_lock);
539
540         mscan_push_state(can, &state);
541     ret = mscan_set_mode(can, MSCAN_INIT_MODE);
542     if (! ret) {
543                 reg = BTR0_SET_BRP(bt->std.brp) | BTR0_SET_SJW(bt->std.sjw);
544                 out_8(&regs->canbtr0, reg);
545
546                 reg = BTR1_SET_TSEG1(bt->std.prop_seg + bt->std.phase_seg1) |
547                           BTR1_SET_TSEG2(bt->std.phase_seg2) | BTR1_SET_SAM(bt->std.sam);
548                 out_8(&regs->canbtr1, reg);
549
550             ret = mscan_pop_state(can, &state);
551     }
552
553         spin_unlock_irq(&can->irq_lock);
554         return ret;
555 }
556
557 static int mscan_open(struct net_device *ndev)
558 {
559         int ret = 0;
560         struct can_device *can = ND2CAN(ndev);
561         struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
562         struct mscan_priv *priv = can->priv;
563
564         if((ret = request_irq(ndev->irq, mscan_isr, SA_SHIRQ, ndev->name, ndev)) < 0) {
565                 printk(KERN_ERR "%s - failed to attach interrupt\n", ndev->name);
566                 return ret;
567         }
568
569         INIT_LIST_HEAD(&priv->tx_head);
570         /* acceptance mask/acceptance code (accept everything) */
571         out_be16(&regs->canidar1_0, 0);
572         out_be16(&regs->canidar3_2, 0);
573         out_be16(&regs->canidar5_4, 0);
574         out_be16(&regs->canidar7_6, 0);
575
576         out_be16(&regs->canidmr1_0, 0xffff);
577         out_be16(&regs->canidmr3_2, 0xffff);
578         out_be16(&regs->canidmr5_4, 0xffff);
579         out_be16(&regs->canidmr7_6, 0xffff);
580         /* Two 32 bit Acceptance Filters */
581         out_8(&regs->canidac, MSCAN_AF_32BIT);
582
583         out_8(&regs->canctl1, in_8(&regs->canctl1) & ~MSCAN_LISTEN);
584         mscan_set_mode( can, MSCAN_NORMAL_MODE);
585
586         priv->shadow_statflg = in_8(&regs->canrflg) & MSCAN_STAT_MSK;
587         priv->cur_pri = 0;
588         priv->tx_active = 0;
589
590         out_8(&regs->cantier, 0);
591         /* Enable receive interrupts. */
592         out_8(&regs->canrier, MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE |
593               MSCAN_RSTATE1 | MSCAN_RSTATE0 |
594               MSCAN_TSTATE1 | MSCAN_TSTATE0);
595
596         netif_start_queue(ndev);
597
598         return 0;
599 }
600
601 static int mscan_close(struct net_device *ndev)
602 {
603   struct can_device *can = ND2CAN(ndev);
604   struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
605
606   netif_stop_queue(ndev);
607
608   /* disable interrupts */
609   out_8(&regs->cantier, 0);
610   out_8(&regs->canrier, 0);
611   free_irq(ndev->irq, ndev);
612
613   mscan_set_mode( can, MSCAN_INIT_MODE);
614   return 0;
615 }
616
617 int mscan_register(struct can_device *can, int clock_src)
618 {
619   struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
620   u8 ctl1;
621
622   ctl1 = in_8(&regs->canctl1);
623   if(clock_src)
624         ctl1 |= MSCAN_CLKSRC;
625   else
626         ctl1 &= ~MSCAN_CLKSRC;
627
628   ctl1 |= MSCAN_CANE;
629   out_8(&regs->canctl1, ctl1);
630   udelay(100);
631
632   mscan_set_mode( can, MSCAN_INIT_MODE );
633
634   return register_netdev(CAN2ND(can));
635 }
636 EXPORT_SYMBOL(mscan_register);
637
638 void mscan_unregister(struct can_device *can)
639 {
640   struct mscan_regs *regs = (struct mscan_regs *)(CAN2ND(can)->base_addr);
641   mscan_set_mode( can, MSCAN_INIT_MODE );
642   out_8(&regs->canctl1, in_8(&regs->canctl1) & ~MSCAN_CANE);
643   unregister_netdev(CAN2ND(can));
644 }
645
646 EXPORT_SYMBOL(mscan_unregister);
647
648 struct can_device *alloc_mscandev()
649 {
650   struct can_device *can;
651   struct net_device *ndev;
652   struct mscan_priv *priv;
653   int i;
654
655   can = alloc_candev(sizeof(struct mscan_priv));
656   if(!can)
657                 return NULL;
658   ndev = CAN2ND(can);
659   priv = can->priv;
660
661   ndev->watchdog_timeo  = MSCAN_WATCHDOG_TIMEOUT;
662   ndev->open                    = mscan_open;
663   ndev->stop                    = mscan_close;
664   ndev->hard_start_xmit = mscan_hard_start_xmit;
665   ndev->tx_timeout      = mscan_tx_timeout;
666
667   ndev->poll                    = mscan_rx_poll;
668   ndev->weight                  = 8;
669
670   can->do_set_bit_time  = mscan_do_set_bit_time;
671   can->do_set_mode              = mscan_do_set_mode;
672
673   for(i=0; i< TX_QUEUE_SIZE; i++)
674         priv->tx_queue[i].mask = 1<<i;
675
676   return can;
677 }
678
679 EXPORT_SYMBOL(alloc_mscandev);
680
681 MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
682 MODULE_LICENSE("GPL v2");
683 MODULE_DESCRIPTION("CAN port driver for a mscan based chips");