source: rtems/bsps/shared/grlib/can/grcan.c @ 7eb606d3

5
Last change on this file since 7eb606d3 was 7eb606d3, checked in by Sebastian Huber <sebastian.huber@…>, on 12/22/18 at 17:31:04

grlib: Move source files

Update #3678.

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