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

5
Last change on this file since 9855690 was 9855690, checked in by Daniel Hellstrom <daniel@…>, on 04/11/17 at 08:47:39

leon, grcan: split hw_stop() into hw and sw stop

this is to avoid owning the spin-lock during semaphore operations.

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