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

5
Last change on this file since c297060 was c297060, checked in by Martin Aberg <maberg@…>, on 03/13/17 at 11:44:58

leon, grcan: protect statistics on copy to user

Locking the stats structure when copying to user buffer ensures a consistent
view to the user.

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