source: rtems/c/src/lib/libbsp/sparc/shared/can/grcan.c @ 039edd2a

5
Last change on this file since 039edd2a was 039edd2a, checked in by Martin Aberg <maberg@…>, on 04/13/17 at 12:12:31

leon, grcan: removed unused txerror, rxerror

  • Property mode set to 100644
File size: 46.1 KB
Line 
1/*
2 *  GRCAN driver
3 *
4 *  COPYRIGHT (c) 2007.
5 *  Cobham Gaisler AB.
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.org/license/LICENSE.
10 */
11
12#include <bsp.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <assert.h>
17#include <ctype.h>
18#include <rtems/bspIo.h>
19
20#include <bsp/grcan.h>
21#include <drvmgr/drvmgr.h>
22#include <drvmgr/ambapp_bus.h>
23#include <ambapp.h>
24
25#if (((__RTEMS_MAJOR__ << 16) | (__RTEMS_MINOR__ << 8) | __RTEMS_REVISION__) >= 0x040b63)
26
27/* Spin locks mapped via rtems_interrupt_lock_* API: */
28#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
29#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
30#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
31#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
32#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
33#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
34#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
35#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
36
37#else
38
39/* maintain compatibility with older versions of RTEMS: */
40#define SPIN_DECLARE(name)
41#define SPIN_INIT(lock, name)
42#define SPIN_LOCK(lock, level)
43#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_disable(level)
44#define SPIN_UNLOCK(lock, level)
45#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_enable(level)
46#define SPIN_IRQFLAGS(k) rtems_interrupt_level k
47#define SPIN_ISR_IRQFLAGS(k)
48
49#endif
50
51/* Maximum number of GRCAN devices supported by driver */
52#define GRCAN_COUNT_MAX 8
53
54#define WRAP_AROUND_TX_MSGS 1
55#define WRAP_AROUND_RX_MSGS 2
56#define GRCAN_MSG_SIZE sizeof(struct grcan_msg)
57#define BLOCK_SIZE (16*4)
58
59/* grcan needs to have it buffers aligned to 1k boundaries */
60#define BUFFER_ALIGNMENT_NEEDS 1024
61
62/* Default Maximium buffer size for statically allocated buffers */
63#ifndef TX_BUF_SIZE
64 #define TX_BUF_SIZE (BLOCK_SIZE*16)
65#endif
66
67/* Make receiver buffers bigger than transmitt */
68#ifndef RX_BUF_SIZE
69 #define RX_BUF_SIZE ((3*BLOCK_SIZE)*16)
70#endif
71
72#ifndef IRQ_CLEAR_PENDING
73 #define IRQ_CLEAR_PENDING(irqno)
74#endif
75
76#ifndef IRQ_UNMASK
77 #define IRQ_UNMASK(irqno)
78#endif
79
80#ifndef IRQ_MASK
81 #define IRQ_MASK(irqno)
82#endif
83
84#ifndef GRCAN_DEFAULT_BAUD
85 /* default to 500kbits/s */
86 #define GRCAN_DEFAULT_BAUD 500000
87#endif
88
89#ifndef GRCAN_SAMPLING_POINT
90 #define GRCAN_SAMPLING_POINT 80
91#endif
92
93/* Uncomment for debug output */
94/****************** DEBUG Definitions ********************/
95#define DBG_TX 2
96#define DBG_RX 4
97#define DBG_STATE 8
98
99#define DEBUG_FLAGS (DBG_STATE | DBG_RX | DBG_TX )
100/*
101#define DEBUG
102#define DEBUGFUNCS
103*/
104#include <bsp/debug_defs.h>
105
106/*********************************************************/
107
108int state2err[4] = {
109        /* STATE_STOPPED */ GRCAN_RET_NOTSTARTED,
110        /* STATE_STARTED */ GRCAN_RET_OK,
111        /* STATE_BUSOFF  */ GRCAN_RET_BUSOFF,
112        /* STATE_AHBERR  */ GRCAN_RET_AHBERR
113};
114
115struct grcan_msg {
116        unsigned int head[2];
117        unsigned char data[8];
118};
119
120struct grcan_config {
121        struct grcan_timing timing;
122        struct grcan_selection selection;
123        int abort;
124        int silent;
125};
126
127struct grcan_priv {
128        struct drvmgr_dev *dev; /* Driver manager device */
129        char devName[32];       /* Device Name */
130        unsigned int baseaddr, ram_base;
131        struct grcan_regs *regs;
132        int irq;
133        int minor;
134        int open;
135        int started;
136        unsigned int channel;
137        int flushing;
138        unsigned int corefreq_hz;
139
140        /* Circular DMA buffers */
141        void *_rx, *_rx_hw;
142        void *_tx, *_tx_hw;
143        void *txbuf_adr;
144        void *rxbuf_adr;
145        struct grcan_msg *rx;
146        struct grcan_msg *tx;
147        unsigned int rxbuf_size;    /* requested RX buf size in bytes */
148        unsigned int txbuf_size;    /* requested TX buf size in bytes */
149
150        int txblock, rxblock;
151        int txcomplete, rxcomplete;
152
153        struct grcan_filter sfilter;
154        struct grcan_filter afilter;
155        int config_changed; /* 0=no changes, 1=changes ==> a Core reset is needed */
156        struct grcan_config config;
157        struct grcan_stats stats;
158
159        rtems_id rx_sem, tx_sem, txempty_sem, dev_sem;
160        SPIN_DECLARE(devlock);
161};
162
163static void __inline__ grcan_hw_reset(struct grcan_regs *regs);
164
165static int grcan_hw_read_try(
166        struct grcan_priv *pDev,
167        struct grcan_regs *regs,
168        CANMsg *buffer,
169        int max);
170
171static int grcan_hw_write_try(
172        struct grcan_priv *pDev,
173        struct grcan_regs *regs,
174        CANMsg *buffer,
175        int count);
176
177static void grcan_hw_config(
178        struct grcan_regs *regs,
179        struct grcan_config *conf);
180
181static void grcan_hw_accept(
182        struct grcan_regs *regs,
183        struct grcan_filter *afilter);
184
185static void grcan_hw_sync(
186        struct grcan_regs *regs,
187        struct grcan_filter *sfilter);
188
189static void grcan_interrupt(void *arg);
190
191#ifdef GRCAN_REG_BYPASS_CACHE
192#define READ_REG(address) _grcan_read_nocache((unsigned int)(address))
193#else
194#define READ_REG(address) (*(volatile unsigned int *)(address))
195#endif
196
197#ifdef GRCAN_DMA_BYPASS_CACHE
198#define READ_DMA_WORD(address) _grcan_read_nocache((unsigned int)(address))
199#define READ_DMA_BYTE(address) _grcan_read_nocache_byte((unsigned int)(address))
200static unsigned char __inline__ _grcan_read_nocache_byte(unsigned int address)
201{
202        unsigned char tmp;
203        __asm__ (" lduba [%1]1, %0 "
204            : "=r"(tmp)
205            : "r"(address)
206        );
207        return tmp;
208}
209#else
210#define READ_DMA_WORD(address) (*(volatile unsigned int *)(address))
211#define READ_DMA_BYTE(address) (*(volatile unsigned char *)(address))
212#endif
213
214#if defined(GRCAN_REG_BYPASS_CACHE) || defined(GRCAN_DMA_BYPASS_CACHE)
215static unsigned int __inline__ _grcan_read_nocache(unsigned int address)
216{
217        unsigned int tmp;
218        __asm__ (" lda [%1]1, %0 "
219                : "=r"(tmp)
220                : "r"(address)
221        );
222        return tmp;
223}
224#endif
225
226#define NELEM(a) ((int) (sizeof (a) / sizeof (a[0])))
227
228static int grcan_count = 0;
229static struct grcan_priv *priv_tab[GRCAN_COUNT_MAX];
230
231/******************* Driver manager interface ***********************/
232
233/* Driver prototypes */
234int grcan_device_init(struct grcan_priv *pDev);
235
236int grcan_init2(struct drvmgr_dev *dev);
237int grcan_init3(struct drvmgr_dev *dev);
238
239struct drvmgr_drv_ops grcan_ops =
240{
241        .init = {NULL, grcan_init2, grcan_init3, NULL},
242        .remove = NULL,
243        .info = NULL
244};
245
246struct amba_dev_id grcan_ids[] =
247{
248        {VENDOR_GAISLER, GAISLER_GRCAN},
249        {VENDOR_GAISLER, GAISLER_GRHCAN},
250        {0, 0}          /* Mark end of table */
251};
252
253struct amba_drv_info grcan_drv_info =
254{
255        {
256                DRVMGR_OBJ_DRV,                 /* Driver */
257                NULL,                           /* Next driver */
258                NULL,                           /* Device list */
259                DRIVER_AMBAPP_GAISLER_GRCAN_ID, /* Driver ID */
260                "GRCAN_DRV",                    /* Driver Name */
261                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
262                &grcan_ops,
263                NULL,                           /* Funcs */
264                0,                              /* No devices yet */
265                0,
266        },
267        &grcan_ids[0]
268};
269
270void grcan_register_drv (void)
271{
272        DBG("Registering GRCAN driver\n");
273        drvmgr_drv_register(&grcan_drv_info.general);
274}
275
276int grcan_init2(struct drvmgr_dev *dev)
277{
278        struct grcan_priv *priv;
279
280        DBG("GRCAN[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
281        if (GRCAN_COUNT_MAX <= grcan_count)
282                return DRVMGR_ENORES;
283        priv = dev->priv = malloc(sizeof(struct grcan_priv));
284        if ( !priv )
285                return DRVMGR_NOMEM;
286        memset(priv, 0, sizeof(*priv));
287        priv->dev = dev;
288
289        /* This core will not find other cores, so we wait for init2() */
290
291        return DRVMGR_OK;
292}
293
294int grcan_init3(struct drvmgr_dev *dev)
295{
296        struct grcan_priv *priv;
297        char prefix[32];
298
299        priv = dev->priv;
300
301        /*
302         * Now we take care of device initialization.
303         */
304
305        if ( grcan_device_init(priv) ) {
306                return DRVMGR_FAIL;
307        }
308
309        priv_tab[grcan_count] = priv;
310        grcan_count++;
311
312        /* Get Filesystem name prefix */
313        prefix[0] = '\0';
314        if ( drvmgr_get_dev_prefix(dev, prefix) ) {
315                /* Failed to get prefix, make sure of a unique FS name
316                 * by using the driver minor.
317                 */
318                sprintf(priv->devName, "grcan%d", dev->minor_drv);
319        } else {
320                /* Got special prefix, this means we have a bus prefix
321                 * And we should use our "bus minor"
322                 */
323                sprintf(priv->devName, "%sgrcan%d", prefix, dev->minor_bus);
324        }
325
326        return DRVMGR_OK;
327}
328
329int grcan_device_init(struct grcan_priv *pDev)
330{
331        struct amba_dev_info *ambadev;
332        struct ambapp_core *pnpinfo;
333
334        /* Get device information from AMBA PnP information */
335        ambadev = (struct amba_dev_info *)pDev->dev->businfo;
336        if ( ambadev == NULL ) {
337                return -1;
338        }
339        pnpinfo = &ambadev->info;
340        pDev->irq = pnpinfo->irq;
341        pDev->regs = (struct grcan_regs *)pnpinfo->apb_slv->start;
342        pDev->minor = pDev->dev->minor_drv;
343
344        /* Get frequency in Hz */
345        if ( drvmgr_freq_get(pDev->dev, DEV_APB_SLV, &pDev->corefreq_hz) ) {
346                return -1;
347        }
348
349        DBG("GRCAN frequency: %d Hz\n", pDev->corefreq_hz);
350
351        /* Reset Hardware before attaching IRQ handler */
352        grcan_hw_reset(pDev->regs);
353
354        /* RX Semaphore created with count = 0 */
355        if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'R', '0' + pDev->minor),
356                0,
357                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
358                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
359                0,
360                &pDev->rx_sem) != RTEMS_SUCCESSFUL ) {
361                return RTEMS_INTERNAL_ERROR;
362        }
363
364        /* TX Semaphore created with count = 0 */
365        if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'T', '0' + pDev->minor),
366                0,
367                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
368                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
369                0,
370                &pDev->tx_sem) != RTEMS_SUCCESSFUL ) {
371                return RTEMS_INTERNAL_ERROR;
372        }
373
374        /* TX Empty Semaphore created with count = 0 */
375        if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'E', '0' + pDev->minor),
376                0,
377                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
378                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
379                0,
380                &pDev->txempty_sem) != RTEMS_SUCCESSFUL ) {
381                return RTEMS_INTERNAL_ERROR;
382        }
383
384        /* Device Semaphore created with count = 1 */
385        if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'A', '0' + pDev->minor),
386                1,
387                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
388                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
389                0,
390                &pDev->dev_sem) != RTEMS_SUCCESSFUL ) {
391                return RTEMS_INTERNAL_ERROR;
392        }
393
394        return 0;
395}
396
397static void __inline__ grcan_hw_reset(struct grcan_regs *regs)
398{
399        regs->ctrl = GRCAN_CTRL_RESET;
400}
401
402static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
403{
404        /*
405         * tmp is set but never used. GCC gives a warning for this
406         * and we need to tell GCC not to complain.
407         */
408        unsigned int tmp RTEMS_UNUSED;
409
410        SPIN_IRQFLAGS(oldLevel);
411
412        FUNCDBG();
413
414        /* Check that memory has been allocated successfully */
415        if (!pDev->tx || !pDev->rx)
416                return RTEMS_NO_MEMORY;
417
418        /* Configure FIFO configuration register
419         * and Setup timing
420         */
421        if (pDev->config_changed) {
422                grcan_hw_config(pDev->regs, &pDev->config);
423                pDev->config_changed = 0;
424        }
425
426        /* Setup receiver */
427        pDev->regs->rx0addr = (unsigned int)pDev->_rx_hw;
428        pDev->regs->rx0size = pDev->rxbuf_size;
429
430        /* Setup Transmitter */
431        pDev->regs->tx0addr = (unsigned int)pDev->_tx_hw;
432        pDev->regs->tx0size = pDev->txbuf_size;
433
434        /* Setup acceptance filters */
435        grcan_hw_accept(pDev->regs, &pDev->afilter);
436
437        /* Sync filters */
438        grcan_hw_sync(pDev->regs, &pDev->sfilter);
439
440        /* Clear status bits */
441        tmp = READ_REG(&pDev->regs->stat);
442        pDev->regs->stat = 0;
443
444        /* Setup IRQ handling */
445
446        /* Clear all IRQs */
447        tmp = READ_REG(&pDev->regs->pir);
448        pDev->regs->picr = 0x1ffff;
449
450        /* unmask TxLoss|TxErrCntr|RxErrCntr|TxAHBErr|RxAHBErr|OR|OFF|PASS */
451        pDev->regs->imr = 0x1601f;
452
453        /* Enable routing of the IRQs */
454        SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
455        IRQ_UNMASK(pDev->irq + GRCAN_IRQ_TXSYNC);
456        IRQ_UNMASK(pDev->irq + GRCAN_IRQ_RXSYNC);
457        IRQ_UNMASK(pDev->irq + GRCAN_IRQ_IRQ);
458        SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
459
460        /* Enable receiver/transmitter */
461        pDev->regs->rx0ctrl = GRCAN_RXCTRL_ENABLE;
462        pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
463
464        /* Enable HurriCANe core */
465        pDev->regs->ctrl = GRCAN_CTRL_ENABLE;
466
467        /* Leave transmitter disabled, it is enabled when
468         * trying to send something.
469         */
470        return RTEMS_SUCCESSFUL;
471}
472
473static void grcan_hw_stop(struct grcan_priv *pDev)
474{
475        FUNCDBG();
476
477        /* Mask all IRQs */
478        pDev->regs->imr = 0;
479        IRQ_MASK(pDev->irq + GRCAN_IRQ_TXSYNC);
480        IRQ_MASK(pDev->irq + GRCAN_IRQ_RXSYNC);
481        IRQ_MASK(pDev->irq + GRCAN_IRQ_IRQ);
482
483        /* Disable receiver & transmitter */
484        pDev->regs->rx0ctrl = 0;
485        pDev->regs->tx0ctrl = 0;
486}
487
488static void grcan_sw_stop(struct grcan_priv *pDev)
489{
490        /*
491         * Release semaphores to wake all threads waiting for an IRQ.
492         * The threads that
493         * get woken up must check started state in
494         * order to determine that they should return to
495         * user space with error status.
496         *
497         * Entering into started mode again will reset the
498         * semaphore count.
499         */
500        rtems_semaphore_release(pDev->rx_sem);
501        rtems_semaphore_release(pDev->tx_sem);
502        rtems_semaphore_release(pDev->txempty_sem);
503}
504
505static void grcan_hw_config(struct grcan_regs *regs, struct grcan_config *conf)
506{
507        unsigned int config = 0;
508
509        /* Reset HurriCANe Core */
510        regs->ctrl = 0;
511
512        if (conf->silent)
513                config |= GRCAN_CFG_SILENT;
514
515        if (conf->abort)
516                config |= GRCAN_CFG_ABORT;
517
518        if (conf->selection.selection)
519                config |= GRCAN_CFG_SELECTION;
520
521        if (conf->selection.enable0)
522                config |= GRCAN_CFG_ENABLE0;
523
524        if (conf->selection.enable1)
525                config |= GRCAN_CFG_ENABLE1;
526
527        /* Timing */
528        config |= (conf->timing.bpr << GRCAN_CFG_BPR_BIT) & GRCAN_CFG_BPR;
529        config |= (conf->timing.rsj << GRCAN_CFG_RSJ_BIT) & GRCAN_CFG_RSJ;
530        config |= (conf->timing.ps1 << GRCAN_CFG_PS1_BIT) & GRCAN_CFG_PS1;
531        config |= (conf->timing.ps2 << GRCAN_CFG_PS2_BIT) & GRCAN_CFG_PS2;
532        config |=
533            (conf->timing.scaler << GRCAN_CFG_SCALER_BIT) & GRCAN_CFG_SCALER;
534
535        /* Write configuration */
536        regs->conf = config;
537
538        /* Enable HurriCANe Core */
539        regs->ctrl = GRCAN_CTRL_ENABLE;
540}
541
542static void grcan_hw_accept(
543        struct grcan_regs *regs,
544        struct grcan_filter *afilter
545)
546{
547        /* Disable Sync mask totaly (if we change scode or smask
548         * in an unfortunate way we may trigger a sync match)
549         */
550        regs->rx0mask = 0xffffffff;
551
552        /* Set Sync Filter in a controlled way */
553        regs->rx0code = afilter->code;
554        regs->rx0mask = afilter->mask;
555}
556
557static void grcan_hw_sync(struct grcan_regs *regs, struct grcan_filter *sfilter)
558{
559        /* Disable Sync mask totaly (if we change scode or smask
560         * in an unfortunate way we may trigger a sync match)
561         */
562        regs->smask = 0xffffffff;
563
564        /* Set Sync Filter in a controlled way */
565        regs->scode = sfilter->code;
566        regs->smask = sfilter->mask;
567}
568
569static unsigned int grcan_hw_rxavail(
570        unsigned int rp,
571        unsigned int wp, unsigned int size
572)
573{
574        if (rp == wp) {
575                /* read pointer and write pointer is equal only
576                 * when RX buffer is empty.
577                 */
578                return 0;
579        }
580
581        if (wp > rp) {
582                return (wp - rp) / GRCAN_MSG_SIZE;
583        } else {
584                return (size - (rp - wp)) / GRCAN_MSG_SIZE;
585        }
586}
587
588static unsigned int grcan_hw_txspace(
589        unsigned int rp,
590        unsigned int wp,
591        unsigned int size
592)
593{
594        unsigned int left;
595
596        if (rp == wp) {
597                /* read pointer and write pointer is equal only
598                 * when TX buffer is empty.
599                 */
600                return size / GRCAN_MSG_SIZE - WRAP_AROUND_TX_MSGS;
601        }
602
603        /* size - 4 - abs(read-write) */
604        if (wp > rp) {
605                left = size - (wp - rp);
606        } else {
607                left = rp - wp;
608        }
609
610        return left / GRCAN_MSG_SIZE - WRAP_AROUND_TX_MSGS;
611}
612
613#define MIN_TSEG1 1
614#define MIN_TSEG2 2
615#define MAX_TSEG1 14
616#define MAX_TSEG2 8
617
618static int grcan_calc_timing(
619        unsigned int baud,      /* The requested BAUD to calculate timing for */
620        unsigned int core_hz,   /* Frequency in Hz of GRCAN Core */
621        unsigned int sampl_pt,
622        struct grcan_timing *timing     /* result is placed here */
623)
624{
625        int best_error = 1000000000;
626        int error;
627        int best_tseg = 0, best_brp = 0, brp = 0;
628        int tseg = 0, tseg1 = 0, tseg2 = 0;
629        int sjw = 1;
630
631        /* Default to 90% */
632        if ((sampl_pt < 50) || (sampl_pt > 99)) {
633                sampl_pt = GRCAN_SAMPLING_POINT;
634        }
635
636        if ((baud < 5000) || (baud > 1000000)) {
637                /* invalid speed mode */
638                return -1;
639        }
640
641        /* find best match, return -2 if no good reg
642         * combination is available for this frequency
643         */
644
645        /* some heuristic specials */
646        if (baud > ((1000000 + 500000) / 2))
647                sampl_pt = 75;
648
649        if (baud < ((12500 + 10000) / 2))
650                sampl_pt = 75;
651
652        /* tseg even = round down, odd = round up */
653        for (
654                tseg = (MIN_TSEG1 + MIN_TSEG2 + 2) * 2;
655                tseg <= (MAX_TSEG2 + MAX_TSEG1 + 2) * 2 + 1;
656                tseg++
657        ) {
658                brp = core_hz / ((1 + tseg / 2) * baud) + tseg % 2;
659                if (
660                        (brp <= 0) ||
661                        ((brp > 256 * 1) && (brp <= 256 * 2) && (brp & 0x1)) ||
662                        ((brp > 256 * 2) && (brp <= 256 * 4) && (brp & 0x3)) ||
663                        ((brp > 256 * 4) && (brp <= 256 * 8) && (brp & 0x7)) ||
664                        (brp > 256 * 8)
665                )
666                        continue;
667
668                error = baud - core_hz / (brp * (1 + tseg / 2));
669                if (error < 0) {
670                        error = -error;
671                }
672
673                if (error <= best_error) {
674                        best_error = error;
675                        best_tseg = tseg / 2;
676                        best_brp = brp - 1;
677                }
678        }
679
680        if (best_error && (baud / best_error < 10)) {
681                return -2;
682        } else if (!timing)
683                return 0;       /* nothing to store result in, but a valid bitrate can be calculated */
684
685        tseg2 = best_tseg - (sampl_pt * (best_tseg + 1)) / 100;
686
687        if (tseg2 < MIN_TSEG2) {
688                tseg2 = MIN_TSEG2;
689        }
690
691        if (tseg2 > MAX_TSEG2) {
692                tseg2 = MAX_TSEG2;
693        }
694
695        tseg1 = best_tseg - tseg2 - 2;
696
697        if (tseg1 > MAX_TSEG1) {
698                tseg1 = MAX_TSEG1;
699                tseg2 = best_tseg - tseg1 - 2;
700        }
701
702        /* Get scaler and BRP from pseudo BRP */
703        if (best_brp <= 256) {
704                timing->scaler = best_brp;
705                timing->bpr = 0;
706        } else if (best_brp <= 256 * 2) {
707                timing->scaler = ((best_brp + 1) >> 1) - 1;
708                timing->bpr = 1;
709        } else if (best_brp <= 256 * 4) {
710                timing->scaler = ((best_brp + 1) >> 2) - 1;
711                timing->bpr = 2;
712        } else {
713                timing->scaler = ((best_brp + 1) >> 3) - 1;
714                timing->bpr = 3;
715        }
716
717        timing->ps1 = tseg1 + 1;
718        timing->ps2 = tseg2;
719        timing->rsj = sjw;
720
721        return 0;
722}
723
724static int grcan_hw_read_try(
725        struct grcan_priv *pDev,
726        struct grcan_regs *regs,
727        CANMsg * buffer,
728        int max
729)
730{
731        int i, j;
732        CANMsg *dest;
733        struct grcan_msg *source, tmp;
734        unsigned int wp, rp, size, rxmax, addr;
735        int trunk_msg_cnt;
736
737        FUNCDBG();
738
739        wp = READ_REG(&regs->rx0wr);
740        rp = READ_REG(&regs->rx0rd);
741
742        /*
743         * Due to hardware wrap around simplification write pointer will
744         * never reach the read pointer, at least a gap of 8 bytes.
745         * The only time they are equal is when the read pointer has
746         * reached the write pointer (empty buffer)
747         *
748         */
749        if (wp != rp) {
750                /* Not empty, we have received chars...
751                 * Read as much as possible from DMA buffer
752                 */
753                size = READ_REG(&regs->rx0size);
754
755                /* Get number of bytes available in RX buffer */
756                trunk_msg_cnt = grcan_hw_rxavail(rp, wp, size);
757
758                /* truncate size if user space buffer hasn't room for
759                 * all received chars.
760                 */
761                if (trunk_msg_cnt > max)
762                        trunk_msg_cnt = max;
763
764                /* Read until i is 0 */
765                i = trunk_msg_cnt;
766
767                addr = (unsigned int)pDev->rx;
768                source = (struct grcan_msg *)(addr + rp);
769                dest = buffer;
770                rxmax = addr + (size - GRCAN_MSG_SIZE);
771
772                /* Read as many can messages as possible */
773                while (i > 0) {
774                        /* Read CAN message from DMA buffer */
775                        tmp.head[0] = READ_DMA_WORD(&source->head[0]);
776                        tmp.head[1] = READ_DMA_WORD(&source->head[1]);
777                        if (tmp.head[1] & 0x4) {
778                                DBGC(DBG_RX, "overrun\n");
779                        }
780                        if (tmp.head[1] & 0x2) {
781                                DBGC(DBG_RX, "bus-off mode\n");
782                        }
783                        if (tmp.head[1] & 0x1) {
784                                DBGC(DBG_RX, "error-passive mode\n");
785                        }
786                        /* Convert one grcan CAN message to one "software" CAN message */
787                        dest->extended = tmp.head[0] >> 31;
788                        dest->rtr = (tmp.head[0] >> 30) & 0x1;
789                        if (dest->extended) {
790                                dest->id = tmp.head[0] & 0x3fffffff;
791                        } else {
792                                dest->id = (tmp.head[0] >> 18) & 0xfff;
793                        }
794                        dest->len = tmp.head[1] >> 28;
795                        for (j = 0; j < dest->len; j++)
796                                dest->data[j] = READ_DMA_BYTE(&source->data[j]);
797
798                        /* wrap around if neccessary */
799                        source =
800                            ((unsigned int)source >= rxmax) ?
801                            (struct grcan_msg *)addr : source + 1;
802                        dest++; /* straight user buffer */
803                        i--;
804                }
805                {
806                        /* A bus off interrupt may have occured after checking pDev->started */
807                        SPIN_IRQFLAGS(oldLevel);
808
809                        SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
810                        if (pDev->started == STATE_STARTED) {
811                                regs->rx0rd = (unsigned int) source - addr;
812                                regs->rx0ctrl = GRCAN_RXCTRL_ENABLE;
813                        } else {
814                                DBGC(DBG_STATE, "cancelled due to a BUS OFF error\n");
815                                trunk_msg_cnt = state2err[pDev->started];
816                        }
817                        SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
818                }
819                return trunk_msg_cnt;
820        }
821        return 0;
822}
823
824static int grcan_hw_write_try(
825        struct grcan_priv *pDev,
826        struct grcan_regs *regs,
827        CANMsg * buffer,
828        int count
829)
830{
831        unsigned int rp, wp, size, txmax, addr;
832        int ret;
833        struct grcan_msg *dest;
834        CANMsg *source;
835        int space_left;
836        unsigned int tmp;
837        int i;
838
839        DBGC(DBG_TX, "\n");
840        /*FUNCDBG(); */
841
842        rp = READ_REG(&regs->tx0rd);
843        wp = READ_REG(&regs->tx0wr);
844        size = READ_REG(&regs->tx0size);
845
846        space_left = grcan_hw_txspace(rp, wp, size);
847
848        /* is circular fifo full? */
849        if (space_left < 1)
850                return 0;
851
852        /* Truncate size */
853        if (space_left > count)
854                space_left = count;
855        ret = space_left;
856
857        addr = (unsigned int)pDev->tx;
858
859        dest = (struct grcan_msg *)(addr + wp);
860        source = (CANMsg *) buffer;
861        txmax = addr + (size - GRCAN_MSG_SIZE);
862
863        while (space_left > 0) {
864                /* Convert and write CAN message to DMA buffer */
865                if (source->extended) {
866                        tmp = (1 << 31) | (source->id & 0x3fffffff);
867                } else {
868                        tmp = (source->id & 0xfff) << 18;
869                }
870                if (source->rtr)
871                        tmp |= (1 << 30);
872                dest->head[0] = tmp;
873                dest->head[1] = source->len << 28;
874                for (i = 0; i < source->len; i++)
875                        dest->data[i] = source->data[i];
876                source++;       /* straight user buffer */
877                dest =
878                    ((unsigned int)dest >= txmax) ?
879                    (struct grcan_msg *)addr : dest + 1;
880                space_left--;
881        }
882
883        {
884                /* A bus off interrupt may have occured after checking pDev->started */
885                SPIN_IRQFLAGS(oldLevel);
886
887                SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
888                if (pDev->started == STATE_STARTED) {
889                        regs->tx0wr = (unsigned int) dest - addr;
890                        regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
891                } else {
892                        DBGC(DBG_STATE, "cancelled due to a BUS OFF error\n");
893                        ret = state2err[pDev->started];
894                }
895                SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
896        }
897        return ret;
898}
899
900static int grcan_wait_rxdata(struct grcan_priv *pDev, int min)
901{
902        unsigned int wp, rp, size, irq;
903        unsigned int irq_trunk, dataavail;
904        int wait, state;
905        SPIN_IRQFLAGS(oldLevel);
906
907        FUNCDBG();
908
909        /*** block until receive IRQ received
910         * Set up a valid IRQ point so that an IRQ is received
911         * when one or more messages are received
912         */
913        SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
914        state = pDev->started;
915
916        /* A bus off interrupt may have occured after checking pDev->started */
917        if (state != STATE_STARTED) {
918                SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
919                if (state == STATE_BUSOFF) {
920                        DBGC(DBG_STATE, "cancelled due to a BUS OFF error\n");
921                } else if (state == STATE_AHBERR) {
922                        DBGC(DBG_STATE, "cancelled due to a AHB error\n");
923                } else {
924                        DBGC(DBG_STATE, "cancelled due to STOP (unexpected) \n");
925                }
926                return state2err[state];
927        }
928
929        size = READ_REG(&pDev->regs->rx0size);
930        rp = READ_REG(&pDev->regs->rx0rd);
931        wp = READ_REG(&pDev->regs->rx0wr);
932
933        /**** Calculate IRQ Pointer ****/
934        irq = wp + min * GRCAN_MSG_SIZE;
935        /* wrap irq around */
936        if (irq >= size) {
937                irq_trunk = irq - size;
938        } else
939                irq_trunk = irq;
940
941        /* init IRQ HW */
942        pDev->regs->rx0irq = irq_trunk;
943
944        /* Clear pending Rx IRQ */
945        pDev->regs->picr = GRCAN_RXIRQ_IRQ;
946
947        wp = READ_REG(&pDev->regs->rx0wr);
948
949        /* Calculate messages available */
950        dataavail = grcan_hw_rxavail(rp, wp, size);
951
952        if (dataavail < min) {
953                /* Still empty, proceed with sleep - Turn on IRQ (unmask irq) */
954                pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_RXIRQ_IRQ;
955                wait = 1;
956        } else {
957                /* enough message has been received, abort sleep - don't unmask interrupt */
958                wait = 0;
959        }
960        SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
961
962        /* Wait for IRQ to fire only if has been triggered */
963        if (wait) {
964                rtems_semaphore_obtain(pDev->rx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
965                /*
966                 * The semaphore is released either due to the expected IRQ
967                 * condition or by BUSOFF, AHBERROR or another thread calling
968                 * grcan_stop(). In either case, state2err[] has the correnct
969                 * return value.
970                 */
971                return state2err[pDev->started];
972        }
973
974        return 0;
975}
976
977/* Wait for TX circular buffer to have room for min CAN messagges. TXIRQ is used to pin
978 * point the location of the CAN message corresponding to min.
979 *
980 * min must be at least WRAP_AROUND_TX_MSGS less than max buffer capacity
981 * (pDev->txbuf_size/GRCAN_MSG_SIZE) for this algo to work.
982 */
983static int grcan_wait_txspace(struct grcan_priv *pDev, int min)
984{
985        int wait, state;
986        unsigned int irq, rp, wp, size, space_left;
987        unsigned int irq_trunk;
988        SPIN_IRQFLAGS(oldLevel);
989
990        DBGC(DBG_TX, "\n");
991        /*FUNCDBG(); */
992
993        SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
994        state = pDev->started;
995        /* A bus off interrupt may have occured after checking pDev->started */
996        if (state != STATE_STARTED) {
997                SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
998                if (state == STATE_BUSOFF) {
999                        DBGC(DBG_STATE, "cancelled due to a BUS OFF error\n");
1000                } else if (state == STATE_AHBERR) {
1001                        DBGC(DBG_STATE, "cancelled due to a AHB error\n");
1002                } else {
1003                        DBGC(DBG_STATE, "cancelled due to STOP (unexpected)\n");
1004                }
1005                return state2err[state];
1006        }
1007
1008        pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
1009
1010        size = READ_REG(&pDev->regs->tx0size);
1011        wp = READ_REG(&pDev->regs->tx0wr);
1012
1013        rp = READ_REG(&pDev->regs->tx0rd);
1014
1015        /**** Calculate IRQ Pointer ****/
1016        irq = rp + min * GRCAN_MSG_SIZE;
1017        /* wrap irq around */
1018        if (irq >= size) {
1019                irq_trunk = irq - size;
1020        } else
1021                irq_trunk = irq;
1022
1023        /* trigger HW to do a IRQ when enough room in buffer */
1024        pDev->regs->tx0irq = irq_trunk;
1025
1026        /* Clear pending Tx IRQ */
1027        pDev->regs->picr = GRCAN_TXIRQ_IRQ;
1028
1029        /* One problem, if HW already gone past IRQ place the IRQ will
1030         * never be received resulting in a thread hang. We check if so
1031         * before proceeding.
1032         *
1033         * has the HW already gone past the IRQ generation place?
1034         *  == does min fit info tx buffer?
1035         */
1036        rp = READ_REG(&pDev->regs->tx0rd);
1037
1038        space_left = grcan_hw_txspace(rp, wp, size);
1039
1040        if (space_left < min) {
1041                /* Still too full, proceed with sleep - Turn on IRQ (unmask irq) */
1042                pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXIRQ_IRQ;
1043                wait = 1;
1044        } else {
1045                /* There are enough room in buffer, abort wait - don't unmask interrupt */
1046                wait = 0;
1047        }
1048        SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1049
1050        /* Wait for IRQ to fire only if it has been triggered */
1051        if (wait) {
1052                rtems_semaphore_obtain(pDev->tx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1053                return state2err[pDev->started];
1054        }
1055
1056        /* At this point the TxIRQ has been masked, we ned not to mask it */
1057        return 0;
1058}
1059
1060static int grcan_tx_flush(struct grcan_priv *pDev)
1061{
1062        int wait, state;
1063        unsigned int rp, wp;
1064        SPIN_IRQFLAGS(oldLevel);
1065        FUNCDBG();
1066
1067        /* loop until all data in circular buffer has been read by hw.
1068         * (write pointer != read pointer )
1069         *
1070         * Hardware doesn't update write pointer - we do
1071         */
1072        while (
1073                (wp = READ_REG(&pDev->regs->tx0wr)) !=
1074                (rp = READ_REG(&pDev->regs->tx0rd))
1075        ) {
1076                /* Wait for TX empty IRQ */
1077                SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1078                state = pDev->started;
1079
1080                /* A bus off interrupt may have occured after checking pDev->started */
1081                if (state != STATE_STARTED) {
1082                        SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1083                        if (state == STATE_BUSOFF) {
1084                                DBGC(DBG_STATE, "cancelled due to a BUS OFF error\n");
1085                        } else if (state == STATE_AHBERR) {
1086                                DBGC(DBG_STATE, "cancelled due to a AHB error\n");
1087                        } else {
1088                                DBGC(DBG_STATE, "cancelled due to STOP (unexpected)\n");
1089                        }
1090                        return state2err[state];
1091                }
1092
1093                /* Clear pending TXEmpty IRQ */
1094                pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
1095
1096                if (wp != READ_REG(&pDev->regs->tx0rd)) {
1097                        /* Still not empty, proceed with sleep - Turn on IRQ (unmask irq) */
1098                        pDev->regs->imr =
1099                            READ_REG(&pDev->regs->imr) | GRCAN_TXEMPTY_IRQ;
1100                        wait = 1;
1101                } else {
1102                        /* TX fifo is empty */
1103                        wait = 0;
1104                }
1105                SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1106                if (!wait)
1107                        break;
1108
1109                /* Wait for IRQ to wake us */
1110                rtems_semaphore_obtain(pDev->txempty_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1111                state = pDev->started;
1112                if (state != STATE_STARTED) {
1113                        return state2err[state];
1114                }
1115        }
1116        return 0;
1117}
1118
1119static int grcan_alloc_buffers(struct grcan_priv *pDev, int rx, int tx)
1120{
1121        unsigned int adr;
1122        FUNCDBG();
1123
1124        if ( tx ) {
1125                adr = (unsigned int)pDev->txbuf_adr;
1126                if (adr & 0x1) {
1127                        /* User defined "remote" address. Translate it into
1128                         * a CPU accessible address
1129                         */
1130                        pDev->_tx_hw = (void *)(adr & ~0x1);
1131                        drvmgr_translate_check(
1132                                pDev->dev,
1133                                DMAMEM_TO_CPU,
1134                                (void *)pDev->_tx_hw,
1135                                (void **)&pDev->_tx,
1136                                pDev->txbuf_size);
1137                        pDev->tx = (struct grcan_msg *)pDev->_tx;
1138                } else {
1139                        if (adr == 0) {
1140                                pDev->_tx = malloc(pDev->txbuf_size +
1141                                                   BUFFER_ALIGNMENT_NEEDS);
1142                                if (!pDev->_tx)
1143                                        return -1;
1144                        } else {
1145                                /* User defined "cou-local" address. Translate
1146                                 * it into a CPU accessible address
1147                                 */
1148                                pDev->_tx = (void *)adr;
1149                        }
1150                        /* Align TX buffer */
1151                        pDev->tx = (struct grcan_msg *)
1152                                   (((unsigned int)pDev->_tx +
1153                                   (BUFFER_ALIGNMENT_NEEDS-1)) &
1154                                   ~(BUFFER_ALIGNMENT_NEEDS-1));
1155
1156                        /* Translate address into an hardware accessible
1157                         * address
1158                         */
1159                        drvmgr_translate_check(
1160                                pDev->dev,
1161                                CPUMEM_TO_DMA,
1162                                (void *)pDev->tx,
1163                                (void **)&pDev->_tx_hw,
1164                                pDev->txbuf_size);
1165                }
1166        }
1167
1168        if ( rx ) {
1169                adr = (unsigned int)pDev->rxbuf_adr;
1170                if (adr & 0x1) {
1171                        /* User defined "remote" address. Translate it into
1172                         * a CPU accessible address
1173                         */
1174                        pDev->_rx_hw = (void *)(adr & ~0x1);
1175                        drvmgr_translate_check(
1176                                pDev->dev,
1177                                DMAMEM_TO_CPU,
1178                                (void *)pDev->_rx_hw,
1179                                (void **)&pDev->_rx,
1180                                pDev->rxbuf_size);
1181                        pDev->rx = (struct grcan_msg *)pDev->_rx;
1182                } else {
1183                        if (adr == 0) {
1184                                pDev->_rx = malloc(pDev->rxbuf_size +
1185                                                   BUFFER_ALIGNMENT_NEEDS);
1186                                if (!pDev->_rx)
1187                                        return -1;
1188                        } else {
1189                                /* User defined "cou-local" address. Translate
1190                                 * it into a CPU accessible address
1191                                 */
1192                                pDev->_rx = (void *)adr;
1193                        }
1194                        /* Align RX buffer */
1195                        pDev->rx = (struct grcan_msg *)
1196                                   (((unsigned int)pDev->_rx +
1197                                   (BUFFER_ALIGNMENT_NEEDS-1)) &
1198                                   ~(BUFFER_ALIGNMENT_NEEDS-1));
1199
1200                        /* Translate address into an hardware accessible
1201                         * address
1202                         */
1203                        drvmgr_translate_check(
1204                                pDev->dev,
1205                                CPUMEM_TO_DMA,
1206                                (void *)pDev->rx,
1207                                (void **)&pDev->_rx_hw,
1208                                pDev->rxbuf_size);
1209                }
1210        }
1211        return 0;
1212}
1213
1214static void grcan_free_buffers(struct grcan_priv *pDev, int rx, int tx)
1215{
1216        FUNCDBG();
1217
1218        if (tx && pDev->_tx) {
1219                free(pDev->_tx);
1220                pDev->_tx = NULL;
1221                pDev->tx = NULL;
1222        }
1223
1224        if (rx && pDev->_rx) {
1225                free(pDev->_rx);
1226                pDev->_rx = NULL;
1227                pDev->rx = NULL;
1228        }
1229}
1230
1231int grcan_dev_count(void)
1232{
1233        return grcan_count;
1234}
1235
1236void *grcan_open_by_name(char *name, int *dev_no)
1237{
1238        int i;
1239        for (i = 0; i < grcan_count; i++){
1240                struct grcan_priv *pDev;
1241
1242                pDev = priv_tab[i];
1243                if (NULL == pDev) {
1244                        continue;
1245                }
1246                if (strncmp(pDev->devName, name, NELEM(pDev->devName)) == 0) {
1247                        if (dev_no)
1248                                *dev_no = i;
1249                        return grcan_open(i);
1250                }
1251        }
1252        return NULL;
1253}
1254
1255void *grcan_open(int dev_no)
1256{
1257        struct grcan_priv *pDev;
1258        void *ret;
1259        union drvmgr_key_value *value;
1260
1261        FUNCDBG();
1262
1263        if (grcan_count == 0 || (grcan_count <= dev_no)) {
1264                return NULL;
1265        }
1266
1267        pDev = priv_tab[dev_no];
1268
1269        /* Wait until we get semaphore */
1270        if (rtems_semaphore_obtain(pDev->dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1271            != RTEMS_SUCCESSFUL) {
1272                return NULL;
1273        }
1274
1275        /* is device busy/taken? */
1276        if ( pDev->open ) {
1277                ret = NULL;
1278                goto out;
1279        }
1280
1281        SPIN_INIT(&pDev->devlock, pDev->devName);
1282
1283        /* Mark device taken */
1284        pDev->open = 1;
1285
1286        pDev->txblock = pDev->rxblock = 1;
1287        pDev->txcomplete = pDev->rxcomplete = 0;
1288        pDev->started = STATE_STOPPED;
1289        pDev->config_changed = 1;
1290        pDev->config.silent = 0;
1291        pDev->config.abort = 0;
1292        pDev->config.selection.selection = 0;
1293        pDev->config.selection.enable0 = 0;
1294        pDev->config.selection.enable1 = 1;
1295        pDev->flushing = 0;
1296        pDev->rx = pDev->_rx = NULL;
1297        pDev->tx = pDev->_tx = NULL;
1298        pDev->txbuf_adr = 0;
1299        pDev->rxbuf_adr = 0;
1300        pDev->txbuf_size = TX_BUF_SIZE;
1301        pDev->rxbuf_size = RX_BUF_SIZE;
1302
1303        /* Override default buffer sizes if available from bus resource */
1304        value = drvmgr_dev_key_get(pDev->dev, "txBufSize", DRVMGR_KT_INT);
1305        if ( value )
1306                pDev->txbuf_size = value->i;
1307
1308        value = drvmgr_dev_key_get(pDev->dev, "rxBufSize", DRVMGR_KT_INT);
1309        if ( value )
1310                pDev->rxbuf_size = value->i;
1311
1312        value = drvmgr_dev_key_get(pDev->dev, "txBufAdr", DRVMGR_KT_POINTER);
1313        if ( value )
1314                pDev->txbuf_adr = value->ptr;
1315
1316        value = drvmgr_dev_key_get(pDev->dev, "rxBufAdr", DRVMGR_KT_POINTER);
1317        if ( value )
1318                pDev->rxbuf_adr = value->ptr;
1319
1320        DBG("Defaulting to rxbufsize: %d, txbufsize: %d\n",RX_BUF_SIZE,TX_BUF_SIZE);
1321
1322        /* Default to accept all messages */
1323        pDev->afilter.mask = 0x00000000;
1324        pDev->afilter.code = 0x00000000;
1325
1326        /* Default to disable sync messages (only trigger when id is set to all ones) */
1327        pDev->sfilter.mask = 0xffffffff;
1328        pDev->sfilter.code = 0x00000000;
1329
1330        /* Calculate default timing register values */
1331        grcan_calc_timing(GRCAN_DEFAULT_BAUD,pDev->corefreq_hz,GRCAN_SAMPLING_POINT,&pDev->config.timing);
1332
1333        if ( grcan_alloc_buffers(pDev,1,1) ) {
1334                ret = NULL;
1335                goto out;
1336        }
1337
1338        /* Clear statistics */
1339        memset(&pDev->stats,0,sizeof(struct grcan_stats));
1340
1341        ret = pDev;
1342out:
1343        rtems_semaphore_release(pDev->dev_sem);
1344        return ret;
1345}
1346
1347int grcan_close(void *d)
1348{
1349        struct grcan_priv *pDev = d;
1350
1351        FUNCDBG();
1352
1353        grcan_stop(d);
1354
1355        grcan_hw_reset(pDev->regs);
1356
1357        grcan_free_buffers(pDev,1,1);
1358
1359        /* Mark Device as closed */
1360        pDev->open = 0;
1361
1362        return 0;
1363}
1364
1365int grcan_read(void *d, CANMsg *msg, size_t ucount)
1366{
1367        struct grcan_priv *pDev = d;
1368        CANMsg *dest;
1369        unsigned int count, left;
1370        int nread;
1371        int req_cnt;
1372
1373        FUNCDBG();
1374
1375        dest = msg;
1376        req_cnt = ucount;
1377
1378        if ( (!dest) || (req_cnt<1) )
1379                return GRCAN_RET_INVARG;
1380
1381        if (pDev->started != STATE_STARTED) {
1382                return GRCAN_RET_NOTSTARTED;
1383        }
1384
1385        DBGC(DBG_RX, "grcan_read [%p]: buf: %p len: %u\n", d, msg, (unsigned int) ucount);
1386
1387        nread = grcan_hw_read_try(pDev,pDev->regs,dest,req_cnt);
1388        if (nread < 0) {
1389                return nread;
1390        }
1391        count = nread;
1392        if ( !( pDev->rxblock && pDev->rxcomplete && (count!=req_cnt) ) ){
1393                if ( count > 0 ) {
1394                        /* Successfully received messages (at least one) */
1395                        return count;
1396                }
1397
1398                /* nothing read, shall we block? */
1399                if ( !pDev->rxblock ) {
1400                        /* non-blocking mode */
1401                        return GRCAN_RET_TIMEOUT;
1402                }
1403        }
1404
1405        while (count == 0 || (pDev->rxcomplete && (count!=req_cnt))) {
1406                if (!pDev->rxcomplete) {
1407                        left = 1; /* return as soon as there is one message available */
1408                } else {
1409                        left = req_cnt - count;     /* return as soon as all data are available */
1410
1411                        /* never wait for more than the half the maximum size of the receive buffer
1412                         * Why? We need some time to copy buffer before to catch up with hw,
1413                         * otherwise we would have to copy everything when the data has been
1414                         * received.
1415                         */
1416                        if (left > ((pDev->rxbuf_size/GRCAN_MSG_SIZE) / 2)){
1417                                left = (pDev->rxbuf_size/GRCAN_MSG_SIZE) / 2;
1418                        }
1419                }
1420
1421                nread = grcan_wait_rxdata(pDev, left);
1422                if (nread) {
1423                        /* The wait has been aborted, probably due to
1424                         * the device driver has been closed by another
1425                         * thread or a bus-off. Return error code.
1426                         */
1427                        return nread;
1428                }
1429
1430                /* Try read bytes from circular buffer */
1431                nread = grcan_hw_read_try(
1432                                pDev,
1433                                pDev->regs,
1434                                dest+count,
1435                                req_cnt-count);
1436
1437                if (nread < 0) {
1438                        /* The read was aborted by bus-off. */
1439                        return nread;
1440                }
1441                count += nread;
1442        }
1443        /* no need to unmask IRQ as IRQ Handler do that for us. */
1444        return count;
1445}
1446
1447int grcan_write(void *d, CANMsg *msg, size_t ucount)
1448{
1449        struct grcan_priv *pDev = d;
1450        CANMsg *source;
1451        unsigned int count, left;
1452        int nwritten;
1453        int req_cnt;
1454
1455        DBGC(DBG_TX,"\n");
1456
1457        if ((pDev->started != STATE_STARTED) || pDev->config.silent || pDev->flushing)
1458                return GRCAN_RET_NOTSTARTED;
1459
1460        req_cnt = ucount;
1461        source = (CANMsg *) msg;
1462
1463        /* check proper length and buffer pointer */
1464        if (( req_cnt < 1) || (source == NULL) ){
1465                return GRCAN_RET_INVARG;
1466        }
1467
1468        nwritten = grcan_hw_write_try(pDev,pDev->regs,source,req_cnt);
1469        if (nwritten < 0) {
1470                return nwritten;
1471        }
1472        count = nwritten;
1473        if ( !(pDev->txblock && pDev->txcomplete && (count!=req_cnt)) ) {
1474                if ( count > 0 ) {
1475                        /* Successfully transmitted chars (at least one char) */
1476                        return count;
1477                }
1478
1479                /* nothing written, shall we block? */
1480                if ( !pDev->txblock ) {
1481                        /* non-blocking mode */
1482                        return GRCAN_RET_TIMEOUT;
1483                }
1484        }
1485
1486        /* if in txcomplete mode we need to transmit all chars */
1487        while((count == 0) || (pDev->txcomplete && (count!=req_cnt)) ){
1488                /*** block until room to fit all or as much of transmit buffer as possible
1489                 * IRQ comes. Set up a valid IRQ point so that an IRQ is received
1490                 * when we can put a chunk of data into transmit fifo
1491                 */
1492                if ( !pDev->txcomplete ){
1493                        left = 1; /* wait for anything to fit buffer */
1494                }else{
1495                        left = req_cnt - count; /* wait for all data to fit in buffer */
1496
1497                        /* never wait for more than the half the maximum size of the transmit
1498                         * buffer
1499                         * Why? We need some time to fill buffer before hw catches up.
1500                         */
1501                        if ( left > ((pDev->txbuf_size/GRCAN_MSG_SIZE)/2) ){
1502                                left = (pDev->txbuf_size/GRCAN_MSG_SIZE)/2;
1503                        }
1504                }
1505
1506                nwritten = grcan_wait_txspace(pDev,left);
1507                /* Wait until more room in transmit buffer */
1508                if ( nwritten ) {
1509                        /* The wait has been aborted, probably due to
1510                         * the device driver has been closed by another
1511                         * thread. To avoid deadlock we return directly
1512                         * with error status.
1513                         */
1514                        return nwritten;
1515                }
1516
1517                /* Try read bytes from circular buffer */
1518                nwritten = grcan_hw_write_try(
1519                        pDev,
1520                        pDev->regs,
1521                        source+count,
1522                        req_cnt-count);
1523
1524                if (nwritten < 0) {
1525                        /* Write was aborted by bus-off. */
1526                        return nwritten;
1527                }
1528                count += nwritten;
1529        }
1530        /* no need to unmask IRQ as IRQ Handler do that for us. */
1531
1532        return count;
1533}
1534
1535int grcan_start(void *d)
1536{
1537        struct grcan_priv *pDev = d;
1538
1539        FUNCDBG();
1540
1541        if (grcan_get_state(d) == STATE_STARTED) {
1542                return -1;
1543        }
1544
1545        if ( (grcan_hw_start(pDev)) != RTEMS_SUCCESSFUL ){
1546                return -2;
1547        }
1548
1549        /* Clear semaphore state. This is to avoid effects from previous
1550         * bus-off/stop where semahpores where flushed() but the count remained.
1551         */
1552        rtems_semaphore_obtain(pDev->rx_sem, RTEMS_NO_WAIT, 0);
1553        rtems_semaphore_obtain(pDev->tx_sem, RTEMS_NO_WAIT, 0);
1554        rtems_semaphore_obtain(pDev->txempty_sem, RTEMS_NO_WAIT, 0);
1555
1556        /* Read and write are now open... */
1557        pDev->started = STATE_STARTED;
1558        DBGC(DBG_STATE, "STOPPED|BUSOFF|AHBERR->STARTED\n");
1559
1560        /* Register interrupt routine and enable IRQ at IRQ ctrl */
1561        drvmgr_interrupt_register(pDev->dev, 0, pDev->devName,
1562                                        grcan_interrupt, pDev);
1563
1564        return 0;
1565}
1566
1567int grcan_stop(void *d)
1568{
1569        struct grcan_priv *pDev = d;
1570        SPIN_IRQFLAGS(oldLevel);
1571        int do_sw_stop;
1572
1573        FUNCDBG();
1574
1575        if (pDev->started == STATE_STOPPED)
1576                return -1;
1577
1578        SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1579        if (pDev->started == STATE_STARTED) {
1580                grcan_hw_stop(pDev);
1581                do_sw_stop = 1;
1582                DBGC(DBG_STATE, "STARTED->STOPPED\n");
1583        } else {
1584                /*
1585                 * started == STATE_[STOPPED|BUSOFF|AHBERR] so grcan_hw_stop()
1586                 * might already been called from ISR.
1587                 */
1588                DBGC(DBG_STATE, "[STOPPED|BUSOFF|AHBERR]->STOPPED\n");
1589                do_sw_stop = 0;
1590        }
1591        pDev->started = STATE_STOPPED;
1592        SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1593
1594        if (do_sw_stop)
1595                grcan_sw_stop(pDev);
1596
1597        /* Disable interrupts */
1598        drvmgr_interrupt_unregister(pDev->dev, 0, grcan_interrupt, pDev);
1599
1600        return 0;
1601}
1602
1603int grcan_get_state(void *d)
1604{
1605        struct grcan_priv *pDev = d;
1606
1607        FUNCDBG();
1608
1609        return pDev->started;
1610}
1611
1612int grcan_flush(void *d)
1613{
1614        struct grcan_priv *pDev = d;
1615        int tmp;
1616
1617        FUNCDBG();
1618
1619        if ((pDev->started != STATE_STARTED) || pDev->flushing || pDev->config.silent)
1620                return -1;
1621
1622        pDev->flushing = 1;
1623        tmp = grcan_tx_flush(pDev);
1624        pDev->flushing = 0;
1625        if ( tmp ) {
1626                /* The wait has been aborted, probably due to
1627                 * the device driver has been closed by another
1628                 * thread.
1629                 */
1630                return -1;
1631        }
1632
1633        return 0;
1634}
1635
1636int grcan_set_silent(void* d, int silent)
1637{
1638        struct grcan_priv *pDev = d;
1639
1640        FUNCDBG();
1641
1642        if (pDev->started == STATE_STARTED)
1643                return -1;
1644
1645        pDev->config.silent = silent;
1646        pDev->config_changed = 1;
1647
1648        return 0;
1649}
1650
1651int grcan_set_abort(void* d, int abort)
1652{
1653        struct grcan_priv *pDev = d;
1654
1655        FUNCDBG();
1656
1657        if (pDev->started == STATE_STARTED)
1658                return -1;
1659
1660        pDev->config.abort = abort;
1661        /* This Configuration parameter doesn't need HurriCANe reset
1662         * ==> no pDev->config_changed = 1;
1663         */
1664
1665        return 0;
1666}
1667
1668int grcan_set_selection(void *d, const struct grcan_selection *selection)
1669{
1670        struct grcan_priv *pDev = d;
1671
1672        FUNCDBG();
1673
1674        if (pDev->started == STATE_STARTED)
1675                return -1;
1676
1677        if ( !selection )
1678                return -2;
1679
1680        pDev->config.selection = *selection;
1681        pDev->config_changed = 1;
1682
1683        return 0;
1684}
1685
1686int grcan_set_rxblock(void *d, int block)
1687{
1688        struct grcan_priv *pDev = d;
1689
1690        FUNCDBG();
1691
1692        pDev->rxblock = block;
1693
1694        return 0;
1695}
1696
1697int grcan_set_txblock(void *d, int block)
1698{
1699        struct grcan_priv *pDev = d;
1700
1701        FUNCDBG();
1702
1703        pDev->txblock = block;
1704
1705        return 0;
1706}
1707
1708int grcan_set_txcomplete(void *d, int complete)
1709{
1710        struct grcan_priv *pDev = d;
1711
1712        FUNCDBG();
1713
1714        pDev->txcomplete = complete;
1715
1716        return 0;
1717}
1718
1719int grcan_set_rxcomplete(void *d, int complete)
1720{
1721        struct grcan_priv *pDev = d;
1722
1723        FUNCDBG();
1724
1725        pDev->rxcomplete = complete;
1726
1727        return 0;
1728}
1729
1730int grcan_get_stats(void *d, struct grcan_stats *stats)
1731{
1732        struct grcan_priv *pDev = d;
1733        SPIN_IRQFLAGS(oldLevel);
1734
1735        FUNCDBG();
1736
1737        if ( !stats )
1738                return -1;
1739
1740        SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1741        *stats = pDev->stats;
1742        SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1743
1744        return 0;
1745}
1746
1747int grcan_clr_stats(void *d)
1748{
1749        struct grcan_priv *pDev = d;
1750        SPIN_IRQFLAGS(oldLevel);
1751
1752        FUNCDBG();
1753
1754        SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1755        memset(&pDev->stats,0,sizeof(struct grcan_stats));
1756        SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1757
1758        return 0;
1759}
1760
1761int grcan_set_speed(void *d, unsigned int speed)
1762{
1763        struct grcan_priv *pDev = d;
1764        struct grcan_timing timing;
1765        int ret;
1766
1767        FUNCDBG();
1768
1769        /* cannot change speed during run mode */
1770        if (pDev->started == STATE_STARTED)
1771                return -1;
1772
1773        /* get speed rate from argument */
1774        ret = grcan_calc_timing(speed, pDev->corefreq_hz, GRCAN_SAMPLING_POINT, &timing);
1775        if ( ret )
1776                return -2;
1777
1778        /* save timing/speed */
1779        pDev->config.timing = timing;
1780        pDev->config_changed = 1;
1781
1782        return 0;
1783}
1784
1785int grcan_set_btrs(void *d, const struct grcan_timing *timing)
1786{
1787        struct grcan_priv *pDev = d;
1788
1789        FUNCDBG();
1790
1791        /* Set BTR registers manually
1792         * Read GRCAN/HurriCANe Manual.
1793         */
1794        if (pDev->started == STATE_STARTED)
1795                return -1;
1796
1797        if ( !timing )
1798                return -2;
1799
1800        pDev->config.timing = *timing;
1801        pDev->config_changed = 1;
1802
1803        return 0;
1804}
1805
1806int grcan_set_afilter(void *d, const struct grcan_filter *filter)
1807{
1808        struct grcan_priv *pDev = d;
1809
1810        FUNCDBG();
1811
1812        if ( !filter ){
1813                /* Disable filtering - let all messages pass */
1814                pDev->afilter.mask = 0x0;
1815                pDev->afilter.code = 0x0;
1816        }else{
1817                /* Save filter */
1818                pDev->afilter = *filter;
1819        }
1820        /* Set hardware acceptance filter */
1821        grcan_hw_accept(pDev->regs,&pDev->afilter);
1822
1823        return 0;
1824}
1825
1826int grcan_set_sfilter(void *d, const struct grcan_filter *filter)
1827{
1828        struct grcan_priv *pDev = d;
1829        SPIN_IRQFLAGS(oldLevel);
1830
1831        FUNCDBG();
1832
1833        if ( !filter ){
1834                /* disable TX/RX SYNC filtering */
1835                pDev->sfilter.mask = 0xffffffff;
1836                pDev->sfilter.mask = 0;
1837
1838                 /* disable Sync interrupt */
1839                SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1840                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
1841                SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1842        }else{
1843                /* Save filter */
1844                pDev->sfilter = *filter;
1845
1846                /* Enable Sync interrupt */
1847                SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1848                pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
1849                SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1850        }
1851        /* Set Sync RX/TX filter */
1852        grcan_hw_sync(pDev->regs,&pDev->sfilter);
1853
1854        return 0;
1855}
1856
1857int grcan_get_status(void* d, unsigned int *data)
1858{
1859        struct grcan_priv *pDev = d;
1860
1861        FUNCDBG();
1862
1863        if ( !data )
1864                return -1;
1865
1866        /* Read out the statsu register from the GRCAN core */
1867        data[0] = READ_REG(&pDev->regs->stat);
1868
1869        return 0;
1870}
1871
1872/* Error indicators */
1873#define GRCAN_IRQ_ERRORS \
1874                (GRCAN_RXAHBERR_IRQ | GRCAN_TXAHBERR_IRQ | GRCAN_OFF_IRQ)
1875#define GRCAN_STAT_ERRORS (GRCAN_STAT_AHBERR | GRCAN_STAT_OFF)
1876/* Warning & RX/TX sync indicators */
1877#define GRCAN_IRQ_WARNS \
1878                (GRCAN_ERR_IRQ | GRCAN_OR_IRQ | GRCAN_TXLOSS_IRQ | \
1879                 GRCAN_RXSYNC_IRQ | GRCAN_TXSYNC_IRQ)
1880#define GRCAN_STAT_WARNS (GRCAN_STAT_OR | GRCAN_STAT_PASS)
1881
1882/* Handle the IRQ */
1883static void grcan_interrupt(void *arg)
1884{
1885        struct grcan_priv *pDev = arg;
1886        unsigned int status = READ_REG(&pDev->regs->pimsr);
1887        unsigned int canstat = READ_REG(&pDev->regs->stat);
1888        unsigned int imr_clear;
1889        SPIN_ISR_IRQFLAGS(irqflags);
1890
1891        /* Spurious IRQ call? */
1892        if ( !status && !canstat )
1893                return;
1894
1895        if (pDev->started != STATE_STARTED) {
1896                DBGC(DBG_STATE, "not STARTED (unexpected interrupt)\n");
1897                pDev->regs->picr = status;
1898                return;
1899        }
1900
1901        FUNCDBG();
1902
1903        if ( (status & GRCAN_IRQ_ERRORS) || (canstat & GRCAN_STAT_ERRORS) ) {
1904                /* Bus-off condition interrupt
1905                 * The link is brought down by hardware, we wake all threads
1906                 * that is blocked in read/write calls and stop futher calls
1907                 * to read/write until user has called ioctl(fd,START,0).
1908                 */
1909                SPIN_LOCK(&pDev->devlock, irqflags);
1910                DBGC(DBG_STATE, "STARTED->BUSOFF|AHBERR\n");
1911                pDev->stats.ints++;
1912                if ((status & GRCAN_OFF_IRQ) || (canstat & GRCAN_STAT_OFF)) {
1913                        /* CAN Bus-off interrupt */
1914                        DBGC(DBG_STATE, "BUSOFF: status: 0x%x, canstat: 0x%x\n",
1915                                status, canstat);
1916                        pDev->started = STATE_BUSOFF;
1917                        pDev->stats.busoff_cnt++;
1918                } else {
1919                        /* RX or Tx AHB Error interrupt */
1920                        printk("AHBERROR: status: 0x%x, canstat: 0x%x\n",
1921                                status, canstat);
1922                        pDev->started = STATE_AHBERR;
1923                        pDev->stats.ahberr_cnt++;
1924                }
1925                grcan_hw_stop(pDev); /* this mask all IRQ sources */
1926                pDev->regs->picr = 0x1ffff; /* clear all interrupts */
1927                /*
1928                 * Prevent driver from affecting bus. Driver can be started
1929                 * again with grcan_start().
1930                 */
1931                SPIN_UNLOCK(&pDev->devlock, irqflags);
1932
1933                /* Release semaphores to wake blocked threads. */
1934                grcan_sw_stop(pDev);
1935
1936                /*
1937                 * NOTE: Another interrupt may be pending now so ISR could be
1938                 * executed one more time aftert this (first) return.
1939                 */
1940                return;
1941        }
1942
1943        /* Mask interrupts in one place under spin-lock. */
1944        imr_clear = status & (GRCAN_RXIRQ_IRQ | GRCAN_TXIRQ_IRQ | GRCAN_TXEMPTY_IRQ);
1945
1946        SPIN_LOCK(&pDev->devlock, irqflags);
1947
1948        /* Increment number of interrupts counter */
1949        pDev->stats.ints++;
1950        if ((status & GRCAN_IRQ_WARNS) || (canstat & GRCAN_STAT_WARNS)) {
1951
1952                if ( (status & GRCAN_ERR_IRQ) || (canstat & GRCAN_STAT_PASS) ) {
1953                        /* Error-Passive interrupt */
1954                        pDev->stats.passive_cnt++;
1955                }
1956
1957                if ( (status & GRCAN_OR_IRQ) || (canstat & GRCAN_STAT_OR) ) {
1958                        /* Over-run during reception interrupt */
1959                        pDev->stats.overrun_cnt++;
1960                }
1961
1962                if ( status & GRCAN_TXLOSS_IRQ ) {
1963                        pDev->stats.txloss_cnt++;
1964                }
1965
1966                if ( status & GRCAN_TXSYNC_IRQ ) {
1967                        /* TxSync message transmitted interrupt */
1968                        pDev->stats.txsync_cnt++;
1969                }
1970
1971                if ( status & GRCAN_RXSYNC_IRQ ) {
1972                        /* RxSync message received interrupt */
1973                        pDev->stats.rxsync_cnt++;
1974                }
1975        }
1976
1977        if (imr_clear) {
1978                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~imr_clear;
1979
1980                SPIN_UNLOCK(&pDev->devlock, irqflags);
1981
1982                if ( status & GRCAN_RXIRQ_IRQ ) {
1983                        /* RX IRQ pointer interrupt */
1984                        rtems_semaphore_release(pDev->rx_sem);
1985                }
1986
1987                if ( status & GRCAN_TXIRQ_IRQ ) {
1988                        /* TX IRQ pointer interrupt */
1989                        rtems_semaphore_release(pDev->tx_sem);
1990                }
1991
1992                if (status & GRCAN_TXEMPTY_IRQ ) {
1993                        rtems_semaphore_release(pDev->txempty_sem);
1994                }
1995        } else {
1996                SPIN_UNLOCK(&pDev->devlock, irqflags);
1997        }
1998
1999        /* Clear IRQs */
2000        pDev->regs->picr = status;
2001}
Note: See TracBrowser for help on using the repository browser.