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

5
Last change on this file since bc40b4d was bc40b4d, checked in by Martin Aberg <maberg@…>, on Jan 24, 2017 at 10:16:41 AM

leon, grcan: consistent indentation

This commit does not contain any change of functionality.

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