File indexing completed on 2025-05-11 08:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <bsp.h>
0032 #include <stdlib.h>
0033 #include <stdio.h>
0034 #include <string.h>
0035 #include <assert.h>
0036 #include <ctype.h>
0037 #include <rtems/bspIo.h>
0038
0039 #include <grlib/grcan.h>
0040 #include <grlib/canbtrs.h>
0041 #include <drvmgr/drvmgr.h>
0042 #include <grlib/ambapp_bus.h>
0043 #include <grlib/ambapp.h>
0044
0045 #include <grlib/grlib_impl.h>
0046 #include "grcan_internal.h"
0047
0048
0049 #define GRCAN_COUNT_MAX 8
0050
0051 #define BLOCK_SIZE (16*4)
0052
0053
0054 #define BUFFER_ALIGNMENT_NEEDS 1024
0055
0056
0057 #ifndef TX_BUF_SIZE
0058 #define TX_BUF_SIZE (BLOCK_SIZE*16)
0059 #endif
0060
0061
0062 #ifndef RX_BUF_SIZE
0063 #define RX_BUF_SIZE ((3*BLOCK_SIZE)*16)
0064 #endif
0065
0066 #ifndef IRQ_CLEAR_PENDING
0067 #define IRQ_CLEAR_PENDING(irqno)
0068 #endif
0069
0070 #ifndef IRQ_UNMASK
0071 #define IRQ_UNMASK(irqno)
0072 #endif
0073
0074 #ifndef IRQ_MASK
0075 #define IRQ_MASK(irqno)
0076 #endif
0077
0078
0079
0080 #define DBG_TX 2
0081 #define DBG_RX 4
0082 #define DBG_STATE 8
0083
0084 #define DEBUG_FLAGS (DBG_STATE | DBG_RX | DBG_TX )
0085
0086
0087
0088
0089 #include <grlib/debug_defs.h>
0090
0091
0092
0093 int state2err[4] = {
0094 GRCAN_RET_NOTSTARTED,
0095 GRCAN_RET_OK,
0096 GRCAN_RET_BUSOFF,
0097 GRCAN_RET_AHBERR
0098 };
0099
0100 static void __inline__ grcan_hw_reset(struct grcan_regs *regs);
0101
0102 static void grcan_hw_config(
0103 struct grcan_priv *pDev,
0104 struct grcan_config *conf);
0105
0106 static void grcan_hw_accept(
0107 struct grcan_regs *regs,
0108 struct grcan_filter *afilter);
0109
0110 static void grcan_hw_sync(
0111 struct grcan_regs *regs,
0112 struct grcan_filter *sfilter);
0113
0114 static void grcan_interrupt(void *arg);
0115
0116 #define NELEM(a) ((int) (sizeof (a) / sizeof (a[0])))
0117
0118
0119 struct grlib_canbtrs_ranges grcan_btrs_ranges = {
0120 .max_scaler = 256*8,
0121 .has_bpr = 1,
0122 .divfactor = 2,
0123 .min_tseg1 = 1,
0124 .max_tseg1 = 15,
0125 .min_tseg2 = 2,
0126 .max_tseg2 = 8,
0127 };
0128
0129
0130 struct grlib_canbtrs_ranges grcanfd_nom_btrs_ranges = {
0131 .max_scaler = 256,
0132 .has_bpr = 0,
0133 .divfactor = 1,
0134 .min_tseg1 = 2,
0135 .max_tseg1 = 63,
0136 .min_tseg2 = 2,
0137 .max_tseg2 = 16,
0138 };
0139
0140
0141 struct grlib_canbtrs_ranges grcanfd_fd_btrs_ranges = {
0142 .max_scaler = 256,
0143 .has_bpr = 0,
0144 .divfactor = 1,
0145 .min_tseg1 = 1,
0146 .max_tseg1 = 15,
0147 .min_tseg2 = 2,
0148 .max_tseg2 = 8,
0149 };
0150
0151 static int grcan_count = 0;
0152 static struct grcan_priv *priv_tab[GRCAN_COUNT_MAX];
0153
0154
0155
0156
0157 int grcan_device_init(struct grcan_priv *pDev);
0158
0159 int grcan_init2(struct drvmgr_dev *dev);
0160 int grcan_init3(struct drvmgr_dev *dev);
0161
0162 struct drvmgr_drv_ops grcan_ops =
0163 {
0164 .init = {NULL, grcan_init2, grcan_init3, NULL},
0165 .remove = NULL,
0166 .info = NULL
0167 };
0168
0169 struct amba_dev_id grcan_ids[] =
0170 {
0171 {VENDOR_GAISLER, GAISLER_GRCAN},
0172 {VENDOR_GAISLER, GAISLER_GRHCAN},
0173 {VENDOR_GAISLER, GAISLER_GRCANFD},
0174 {0, 0}
0175 };
0176
0177 struct amba_drv_info grcan_drv_info =
0178 {
0179 {
0180 DRVMGR_OBJ_DRV,
0181 NULL,
0182 NULL,
0183 DRIVER_AMBAPP_GAISLER_GRCAN_ID,
0184 "GRCAN_DRV",
0185 DRVMGR_BUS_TYPE_AMBAPP,
0186 &grcan_ops,
0187 NULL,
0188 0,
0189 0,
0190 },
0191 &grcan_ids[0]
0192 };
0193
0194 void grcan_register_drv (void)
0195 {
0196 DBG("Registering GRCAN driver\n");
0197 drvmgr_drv_register(&grcan_drv_info.general);
0198 }
0199
0200 int grcan_init2(struct drvmgr_dev *dev)
0201 {
0202 struct grcan_priv *priv;
0203
0204 DBG("GRCAN[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0205 if (GRCAN_COUNT_MAX <= grcan_count)
0206 return DRVMGR_ENORES;
0207 priv = dev->priv = grlib_calloc(1, sizeof(*priv));
0208 if ( !priv )
0209 return DRVMGR_NOMEM;
0210 priv->dev = dev;
0211
0212
0213
0214 return DRVMGR_OK;
0215 }
0216
0217 int grcan_init3(struct drvmgr_dev *dev)
0218 {
0219 struct grcan_priv *priv;
0220 char prefix[32];
0221
0222 priv = dev->priv;
0223
0224
0225
0226
0227
0228 if ( grcan_device_init(priv) ) {
0229 return DRVMGR_FAIL;
0230 }
0231
0232 priv_tab[grcan_count] = priv;
0233 grcan_count++;
0234
0235
0236 prefix[0] = '\0';
0237 if ( drvmgr_get_dev_prefix(dev, prefix) ) {
0238
0239
0240
0241 sprintf(priv->devName, "grcan%d", dev->minor_drv);
0242 } else {
0243
0244
0245
0246 sprintf(priv->devName, "%sgrcan%d", prefix, dev->minor_bus);
0247 }
0248
0249 return DRVMGR_OK;
0250 }
0251
0252 int grcan_device_init(struct grcan_priv *pDev)
0253 {
0254 struct amba_dev_info *ambadev;
0255 struct ambapp_core *pnpinfo;
0256
0257
0258 ambadev = (struct amba_dev_info *)pDev->dev->businfo;
0259 if ( ambadev == NULL ) {
0260 return -1;
0261 }
0262 pnpinfo = &ambadev->info;
0263 pDev->irq = pnpinfo->irq;
0264 pDev->regs = (struct grcan_regs *)pnpinfo->apb_slv->start;
0265 pDev->minor = pDev->dev->minor_drv;
0266 if (ambadev->id.device == GAISLER_GRCANFD)
0267 pDev->fd_capable = 1;
0268
0269
0270 if ( drvmgr_freq_get(pDev->dev, DEV_APB_SLV, &pDev->corefreq_hz) ) {
0271 return -1;
0272 }
0273
0274 DBG("GRCAN frequency: %d Hz\n", pDev->corefreq_hz);
0275
0276
0277 grcan_hw_reset(pDev->regs);
0278
0279
0280 if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'R', '0' + pDev->minor),
0281 0,
0282 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
0283 RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0284 0,
0285 &pDev->rx_sem) != RTEMS_SUCCESSFUL ) {
0286 return RTEMS_INTERNAL_ERROR;
0287 }
0288
0289
0290 if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'T', '0' + pDev->minor),
0291 0,
0292 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
0293 RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0294 0,
0295 &pDev->tx_sem) != RTEMS_SUCCESSFUL ) {
0296 return RTEMS_INTERNAL_ERROR;
0297 }
0298
0299
0300 if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'E', '0' + pDev->minor),
0301 0,
0302 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
0303 RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0304 0,
0305 &pDev->txempty_sem) != RTEMS_SUCCESSFUL ) {
0306 return RTEMS_INTERNAL_ERROR;
0307 }
0308
0309
0310 if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'A', '0' + pDev->minor),
0311 1,
0312 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
0313 RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0314 0,
0315 &pDev->dev_sem) != RTEMS_SUCCESSFUL ) {
0316 return RTEMS_INTERNAL_ERROR;
0317 }
0318
0319 return 0;
0320 }
0321
0322 static void __inline__ grcan_hw_reset(struct grcan_regs *regs)
0323 {
0324 regs->ctrl = GRCAN_CTRL_RESET;
0325 }
0326
0327 static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
0328 {
0329
0330
0331
0332
0333 unsigned int tmp RTEMS_UNUSED;
0334
0335 SPIN_IRQFLAGS(oldLevel);
0336
0337 FUNCDBG();
0338
0339
0340 if (!pDev->tx || !pDev->rx)
0341 return RTEMS_NO_MEMORY;
0342
0343
0344
0345
0346 if (pDev->config_changed) {
0347 grcan_hw_config(pDev, &pDev->config);
0348 pDev->config_changed = 0;
0349 }
0350
0351
0352 pDev->regs->rx0addr = (unsigned int)pDev->_rx_hw;
0353 pDev->regs->rx0size = pDev->rxbuf_size;
0354
0355
0356 pDev->regs->tx0addr = (unsigned int)pDev->_tx_hw;
0357 pDev->regs->tx0size = pDev->txbuf_size;
0358
0359
0360 grcan_hw_accept(pDev->regs, &pDev->afilter);
0361
0362
0363 grcan_hw_sync(pDev->regs, &pDev->sfilter);
0364
0365
0366 tmp = READ_REG(&pDev->regs->stat);
0367 pDev->regs->stat = 0;
0368
0369
0370
0371
0372 tmp = READ_REG(&pDev->regs->pir);
0373 pDev->regs->picr = 0x1ffff;
0374
0375
0376 pDev->regs->imr = 0x1601f;
0377
0378
0379 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
0380 IRQ_UNMASK(pDev->irq + GRCAN_IRQ_TXSYNC);
0381 IRQ_UNMASK(pDev->irq + GRCAN_IRQ_RXSYNC);
0382 IRQ_UNMASK(pDev->irq + GRCAN_IRQ_IRQ);
0383 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
0384
0385
0386 pDev->regs->rx0ctrl = GRCAN_RXCTRL_ENABLE;
0387 pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
0388
0389
0390 pDev->regs->ctrl = GRCAN_CTRL_ENABLE;
0391
0392
0393
0394
0395 return RTEMS_SUCCESSFUL;
0396 }
0397
0398 static void grcan_hw_stop(struct grcan_priv *pDev)
0399 {
0400 FUNCDBG();
0401
0402
0403 pDev->regs->imr = 0;
0404 IRQ_MASK(pDev->irq + GRCAN_IRQ_TXSYNC);
0405 IRQ_MASK(pDev->irq + GRCAN_IRQ_RXSYNC);
0406 IRQ_MASK(pDev->irq + GRCAN_IRQ_IRQ);
0407
0408
0409 pDev->regs->rx0ctrl = 0;
0410 pDev->regs->tx0ctrl = 0;
0411 }
0412
0413 static void grcan_sw_stop(struct grcan_priv *pDev)
0414 {
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425 rtems_semaphore_release(pDev->rx_sem);
0426 rtems_semaphore_release(pDev->tx_sem);
0427 rtems_semaphore_release(pDev->txempty_sem);
0428 }
0429
0430 static void grcan_hw_config(struct grcan_priv *pDev, struct grcan_config *conf)
0431 {
0432 unsigned int config = 0;
0433 struct grcan_regs *regs = pDev->regs;
0434
0435
0436 regs->ctrl = 0;
0437
0438 if (conf->silent)
0439 config |= GRCAN_CFG_SILENT;
0440
0441 if (conf->abort)
0442 config |= GRCAN_CFG_ABORT;
0443
0444 if (conf->selection.selection)
0445 config |= GRCAN_CFG_SELECTION;
0446
0447 if (conf->selection.enable0)
0448 config |= GRCAN_CFG_ENABLE0;
0449
0450 if (conf->selection.enable1)
0451 config |= GRCAN_CFG_ENABLE1;
0452
0453
0454 if (!pDev->fd_capable) {
0455 config |= (conf->timing.bpr << GRCAN_CFG_BPR_BIT) &
0456 GRCAN_CFG_BPR;
0457 config |= (conf->timing.rsj << GRCAN_CFG_RSJ_BIT) &
0458 GRCAN_CFG_RSJ;
0459 config |= (conf->timing.ps1 << GRCAN_CFG_PS1_BIT) &
0460 GRCAN_CFG_PS1;
0461 config |= (conf->timing.ps2 << GRCAN_CFG_PS2_BIT) &
0462 GRCAN_CFG_PS2;
0463 config |= (conf->timing.scaler << GRCAN_CFG_SCALER_BIT) &
0464 GRCAN_CFG_SCALER;
0465 } else {
0466 regs->nbtr =
0467 (conf->timing.scaler << GRCANFD_NBTR_SCALER_BIT) |
0468 (conf->timing.ps1 << GRCANFD_NBTR_PS1_BIT) |
0469 (conf->timing.ps2 << GRCANFD_NBTR_PS2_BIT) |
0470 (conf->timing.rsj << GRCANFD_NBTR_SJW_BIT);
0471 regs->fdbtr =
0472 (conf->timing_fd.scaler << GRCANFD_FDBTR_SCALER_BIT) |
0473 (conf->timing_fd.ps1 << GRCANFD_FDBTR_PS1_BIT) |
0474 (conf->timing_fd.ps2 << GRCANFD_FDBTR_PS2_BIT) |
0475 (conf->timing_fd.sjw << GRCANFD_FDBTR_SJW_BIT);
0476 }
0477
0478 regs->conf = config;
0479
0480
0481 regs->ctrl = GRCAN_CTRL_ENABLE;
0482 }
0483
0484 static void grcan_hw_accept(
0485 struct grcan_regs *regs,
0486 struct grcan_filter *afilter
0487 )
0488 {
0489
0490
0491
0492 regs->rx0mask = 0xffffffff;
0493
0494
0495 regs->rx0code = afilter->code;
0496 regs->rx0mask = afilter->mask;
0497 }
0498
0499 static void grcan_hw_sync(struct grcan_regs *regs, struct grcan_filter *sfilter)
0500 {
0501
0502
0503
0504 regs->smask = 0xffffffff;
0505
0506
0507 regs->scode = sfilter->code;
0508 regs->smask = sfilter->mask;
0509 }
0510
0511 int grcan_wait_rxdata(struct grcan_priv *pDev, int min)
0512 {
0513 unsigned int wp, rp, size, irq;
0514 unsigned int irq_trunk, dataavail;
0515 int wait, state;
0516 SPIN_IRQFLAGS(oldLevel);
0517
0518 FUNCDBG();
0519
0520
0521
0522
0523
0524 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
0525 state = pDev->started;
0526
0527
0528 if (state != STATE_STARTED) {
0529 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
0530 if (state == STATE_BUSOFF) {
0531 DBGC(DBG_STATE, "cancelled due to a BUS OFF error\n");
0532 } else if (state == STATE_AHBERR) {
0533 DBGC(DBG_STATE, "cancelled due to a AHB error\n");
0534 } else {
0535 DBGC(DBG_STATE, "cancelled due to STOP (unexpected) \n");
0536 }
0537 return state2err[state];
0538 }
0539
0540 size = READ_REG(&pDev->regs->rx0size);
0541 rp = READ_REG(&pDev->regs->rx0rd);
0542 wp = READ_REG(&pDev->regs->rx0wr);
0543
0544
0545 irq = wp + min * GRCAN_MSG_SIZE;
0546
0547 if (irq >= size) {
0548 irq_trunk = irq - size;
0549 } else
0550 irq_trunk = irq;
0551
0552
0553 pDev->regs->rx0irq = irq_trunk;
0554
0555
0556 pDev->regs->picr = GRCAN_RXIRQ_IRQ;
0557
0558 wp = READ_REG(&pDev->regs->rx0wr);
0559
0560
0561 dataavail = grcan_hw_rxavail(rp, wp, size);
0562
0563 if (dataavail < min) {
0564
0565 pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_RXIRQ_IRQ;
0566 wait = 1;
0567 } else {
0568
0569 wait = 0;
0570 }
0571 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
0572
0573
0574 if (wait) {
0575 rtems_semaphore_obtain(pDev->rx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0576
0577
0578
0579
0580
0581
0582 return state2err[pDev->started];
0583 }
0584
0585 return 0;
0586 }
0587
0588
0589
0590
0591
0592
0593
0594 int grcan_wait_txspace(struct grcan_priv *pDev, int min)
0595 {
0596 int wait, state;
0597 unsigned int irq, rp, wp, size, space_left;
0598 unsigned int irq_trunk;
0599 SPIN_IRQFLAGS(oldLevel);
0600
0601 DBGC(DBG_TX, "\n");
0602
0603
0604 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
0605 state = pDev->started;
0606
0607 if (state != STATE_STARTED) {
0608 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
0609 if (state == STATE_BUSOFF) {
0610 DBGC(DBG_STATE, "cancelled due to a BUS OFF error\n");
0611 } else if (state == STATE_AHBERR) {
0612 DBGC(DBG_STATE, "cancelled due to a AHB error\n");
0613 } else {
0614 DBGC(DBG_STATE, "cancelled due to STOP (unexpected)\n");
0615 }
0616 return state2err[state];
0617 }
0618
0619 pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
0620
0621 size = READ_REG(&pDev->regs->tx0size);
0622 wp = READ_REG(&pDev->regs->tx0wr);
0623
0624 rp = READ_REG(&pDev->regs->tx0rd);
0625
0626
0627 irq = rp + min * GRCAN_MSG_SIZE;
0628
0629 if (irq >= size) {
0630 irq_trunk = irq - size;
0631 } else
0632 irq_trunk = irq;
0633
0634
0635 pDev->regs->tx0irq = irq_trunk;
0636
0637
0638 pDev->regs->picr = GRCAN_TXIRQ_IRQ;
0639
0640
0641
0642
0643
0644
0645
0646
0647 rp = READ_REG(&pDev->regs->tx0rd);
0648
0649 space_left = grcan_hw_txspace(rp, wp, size);
0650
0651 if (space_left < min) {
0652
0653 pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXIRQ_IRQ;
0654 wait = 1;
0655 } else {
0656
0657 wait = 0;
0658 }
0659 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
0660
0661
0662 if (wait) {
0663 rtems_semaphore_obtain(pDev->tx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0664 return state2err[pDev->started];
0665 }
0666
0667
0668 return 0;
0669 }
0670
0671 static int grcan_tx_flush(struct grcan_priv *pDev)
0672 {
0673 int wait, state;
0674 unsigned int rp, wp;
0675 SPIN_IRQFLAGS(oldLevel);
0676 FUNCDBG();
0677
0678
0679
0680
0681
0682
0683 while (
0684 (wp = READ_REG(&pDev->regs->tx0wr)) !=
0685 (rp = READ_REG(&pDev->regs->tx0rd))
0686 ) {
0687
0688 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
0689 state = pDev->started;
0690
0691
0692 if (state != STATE_STARTED) {
0693 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
0694 if (state == STATE_BUSOFF) {
0695 DBGC(DBG_STATE, "cancelled due to a BUS OFF error\n");
0696 } else if (state == STATE_AHBERR) {
0697 DBGC(DBG_STATE, "cancelled due to a AHB error\n");
0698 } else {
0699 DBGC(DBG_STATE, "cancelled due to STOP (unexpected)\n");
0700 }
0701 return state2err[state];
0702 }
0703
0704
0705 pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
0706
0707 if (wp != READ_REG(&pDev->regs->tx0rd)) {
0708
0709 pDev->regs->imr =
0710 READ_REG(&pDev->regs->imr) | GRCAN_TXEMPTY_IRQ;
0711 wait = 1;
0712 } else {
0713
0714 wait = 0;
0715 }
0716 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
0717 if (!wait)
0718 break;
0719
0720
0721 rtems_semaphore_obtain(pDev->txempty_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0722 state = pDev->started;
0723 if (state != STATE_STARTED) {
0724 return state2err[state];
0725 }
0726 }
0727 return 0;
0728 }
0729
0730 static int grcan_alloc_buffers(struct grcan_priv *pDev, int rx, int tx)
0731 {
0732 unsigned int adr;
0733 FUNCDBG();
0734
0735 if ( tx ) {
0736 adr = (unsigned int)pDev->txbuf_adr;
0737 if (adr & 0x1) {
0738
0739
0740
0741 pDev->_tx_hw = (void *)(adr & ~0x1);
0742 drvmgr_translate_check(
0743 pDev->dev,
0744 DMAMEM_TO_CPU,
0745 (void *)pDev->_tx_hw,
0746 (void **)&pDev->_tx,
0747 pDev->txbuf_size);
0748 pDev->tx = (struct grcan_msg *)pDev->_tx;
0749 } else {
0750 if (adr == 0) {
0751 pDev->_tx = grlib_malloc(pDev->txbuf_size +
0752 BUFFER_ALIGNMENT_NEEDS);
0753 if (!pDev->_tx)
0754 return -1;
0755 } else {
0756
0757
0758
0759 pDev->_tx = (void *)adr;
0760 }
0761
0762 pDev->tx = (struct grcan_msg *)
0763 (((unsigned int)pDev->_tx +
0764 (BUFFER_ALIGNMENT_NEEDS-1)) &
0765 ~(BUFFER_ALIGNMENT_NEEDS-1));
0766
0767
0768
0769
0770 drvmgr_translate_check(
0771 pDev->dev,
0772 CPUMEM_TO_DMA,
0773 (void *)pDev->tx,
0774 (void **)&pDev->_tx_hw,
0775 pDev->txbuf_size);
0776 }
0777 }
0778
0779 if ( rx ) {
0780 adr = (unsigned int)pDev->rxbuf_adr;
0781 if (adr & 0x1) {
0782
0783
0784
0785 pDev->_rx_hw = (void *)(adr & ~0x1);
0786 drvmgr_translate_check(
0787 pDev->dev,
0788 DMAMEM_TO_CPU,
0789 (void *)pDev->_rx_hw,
0790 (void **)&pDev->_rx,
0791 pDev->rxbuf_size);
0792 pDev->rx = (struct grcan_msg *)pDev->_rx;
0793 } else {
0794 if (adr == 0) {
0795 pDev->_rx = grlib_malloc(pDev->rxbuf_size +
0796 BUFFER_ALIGNMENT_NEEDS);
0797 if (!pDev->_rx)
0798 return -1;
0799 } else {
0800
0801
0802
0803 pDev->_rx = (void *)adr;
0804 }
0805
0806 pDev->rx = (struct grcan_msg *)
0807 (((unsigned int)pDev->_rx +
0808 (BUFFER_ALIGNMENT_NEEDS-1)) &
0809 ~(BUFFER_ALIGNMENT_NEEDS-1));
0810
0811
0812
0813
0814 drvmgr_translate_check(
0815 pDev->dev,
0816 CPUMEM_TO_DMA,
0817 (void *)pDev->rx,
0818 (void **)&pDev->_rx_hw,
0819 pDev->rxbuf_size);
0820 }
0821 }
0822 return 0;
0823 }
0824
0825 static void grcan_free_buffers(struct grcan_priv *pDev, int rx, int tx)
0826 {
0827 FUNCDBG();
0828
0829 if (tx && pDev->_tx) {
0830 free(pDev->_tx);
0831 pDev->_tx = NULL;
0832 pDev->tx = NULL;
0833 }
0834
0835 if (rx && pDev->_rx) {
0836 free(pDev->_rx);
0837 pDev->_rx = NULL;
0838 pDev->rx = NULL;
0839 }
0840 }
0841
0842 int grcan_dev_count(void)
0843 {
0844 return grcan_count;
0845 }
0846
0847 void *grcan_open_by_name(char *name, int *dev_no)
0848 {
0849 int i;
0850 for (i = 0; i < grcan_count; i++){
0851 struct grcan_priv *pDev;
0852
0853 pDev = priv_tab[i];
0854 if (NULL == pDev) {
0855 continue;
0856 }
0857 if (strncmp(pDev->devName, name, NELEM(pDev->devName)) == 0) {
0858 if (dev_no)
0859 *dev_no = i;
0860 return grcan_open(i);
0861 }
0862 }
0863 return NULL;
0864 }
0865
0866 void *grcan_open(int dev_no)
0867 {
0868 struct grcan_priv *pDev;
0869 void *ret;
0870 union drvmgr_key_value *value;
0871 struct grlib_canbtrs_ranges *br;
0872
0873 FUNCDBG();
0874
0875 if (grcan_count == 0 || (grcan_count <= dev_no)) {
0876 return NULL;
0877 }
0878
0879 pDev = priv_tab[dev_no];
0880
0881
0882 if (rtems_semaphore_obtain(pDev->dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0883 != RTEMS_SUCCESSFUL) {
0884 return NULL;
0885 }
0886
0887
0888 if ( pDev->open ) {
0889 ret = NULL;
0890 goto out;
0891 }
0892
0893 SPIN_INIT(&pDev->devlock, pDev->devName);
0894
0895
0896 pDev->open = 1;
0897
0898 pDev->txblock = pDev->rxblock = 1;
0899 pDev->txcomplete = pDev->rxcomplete = 0;
0900 pDev->started = STATE_STOPPED;
0901 pDev->config_changed = 1;
0902 pDev->config.silent = 0;
0903 pDev->config.abort = 0;
0904 pDev->config.selection.selection = 0;
0905 pDev->config.selection.enable0 = 0;
0906 pDev->config.selection.enable1 = 1;
0907 pDev->flushing = 0;
0908 pDev->rx = pDev->_rx = NULL;
0909 pDev->tx = pDev->_tx = NULL;
0910 pDev->txbuf_adr = 0;
0911 pDev->rxbuf_adr = 0;
0912 pDev->txbuf_size = TX_BUF_SIZE;
0913 pDev->rxbuf_size = RX_BUF_SIZE;
0914
0915
0916 value = drvmgr_dev_key_get(pDev->dev, "txBufSize", DRVMGR_KT_INT);
0917 if ( value )
0918 pDev->txbuf_size = value->i;
0919
0920 value = drvmgr_dev_key_get(pDev->dev, "rxBufSize", DRVMGR_KT_INT);
0921 if ( value )
0922 pDev->rxbuf_size = value->i;
0923
0924 value = drvmgr_dev_key_get(pDev->dev, "txBufAdr", DRVMGR_KT_POINTER);
0925 if ( value )
0926 pDev->txbuf_adr = value->ptr;
0927
0928 value = drvmgr_dev_key_get(pDev->dev, "rxBufAdr", DRVMGR_KT_POINTER);
0929 if ( value )
0930 pDev->rxbuf_adr = value->ptr;
0931
0932 DBG("Defaulting to rxbufsize: %d, txbufsize: %d\n",RX_BUF_SIZE,TX_BUF_SIZE);
0933
0934
0935 pDev->afilter.mask = 0x00000000;
0936 pDev->afilter.code = 0x00000000;
0937
0938
0939 pDev->sfilter.mask = 0xffffffff;
0940 pDev->sfilter.code = 0x00000000;
0941
0942
0943 if (pDev->fd_capable)
0944 br = &grcanfd_nom_btrs_ranges;
0945 else
0946 br = &grcan_btrs_ranges;
0947 grlib_canbtrs_calc_timing(
0948 GRCAN_DEFAULT_BAUD, pDev->corefreq_hz, GRCAN_SAMPLING_POINT,
0949 br, (struct grlib_canbtrs_timing *)&pDev->config.timing);
0950
0951 if ( grcan_alloc_buffers(pDev,1,1) ) {
0952 ret = NULL;
0953 goto out;
0954 }
0955
0956
0957 memset(&pDev->stats,0,sizeof(struct grcan_stats));
0958
0959 ret = pDev;
0960 out:
0961 rtems_semaphore_release(pDev->dev_sem);
0962 return ret;
0963 }
0964
0965 int grcan_close(void *d)
0966 {
0967 struct grcan_priv *pDev = d;
0968
0969 FUNCDBG();
0970
0971 grcan_stop(d);
0972
0973 grcan_hw_reset(pDev->regs);
0974
0975 grcan_free_buffers(pDev,1,1);
0976
0977
0978 pDev->open = 0;
0979
0980 return 0;
0981 }
0982
0983 int grcan_canfd_capable(void *d)
0984 {
0985 struct grcan_priv *pDev = d;
0986
0987 return pDev->fd_capable;
0988 }
0989
0990 int grcan_start(void *d)
0991 {
0992 struct grcan_priv *pDev = d;
0993
0994 FUNCDBG();
0995
0996 if (grcan_get_state(d) == STATE_STARTED) {
0997 return -1;
0998 }
0999
1000 if ( (grcan_hw_start(pDev)) != RTEMS_SUCCESSFUL ){
1001 return -2;
1002 }
1003
1004
1005
1006
1007 rtems_semaphore_obtain(pDev->rx_sem, RTEMS_NO_WAIT, 0);
1008 rtems_semaphore_obtain(pDev->tx_sem, RTEMS_NO_WAIT, 0);
1009 rtems_semaphore_obtain(pDev->txempty_sem, RTEMS_NO_WAIT, 0);
1010
1011
1012 pDev->started = STATE_STARTED;
1013 DBGC(DBG_STATE, "STOPPED|BUSOFF|AHBERR->STARTED\n");
1014
1015
1016 drvmgr_interrupt_register(pDev->dev, 0, pDev->devName,
1017 grcan_interrupt, pDev);
1018
1019 return 0;
1020 }
1021
1022 int grcan_stop(void *d)
1023 {
1024 struct grcan_priv *pDev = d;
1025 SPIN_IRQFLAGS(oldLevel);
1026 int do_sw_stop;
1027
1028 FUNCDBG();
1029
1030 if (pDev->started == STATE_STOPPED)
1031 return -1;
1032
1033 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1034 if (pDev->started == STATE_STARTED) {
1035 grcan_hw_stop(pDev);
1036 do_sw_stop = 1;
1037 DBGC(DBG_STATE, "STARTED->STOPPED\n");
1038 } else {
1039
1040
1041
1042
1043 DBGC(DBG_STATE, "[STOPPED|BUSOFF|AHBERR]->STOPPED\n");
1044 do_sw_stop = 0;
1045 }
1046 pDev->started = STATE_STOPPED;
1047 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1048
1049 if (do_sw_stop)
1050 grcan_sw_stop(pDev);
1051
1052
1053 drvmgr_interrupt_unregister(pDev->dev, 0, grcan_interrupt, pDev);
1054
1055 return 0;
1056 }
1057
1058 int grcan_get_state(void *d)
1059 {
1060 struct grcan_priv *pDev = d;
1061
1062 FUNCDBG();
1063
1064 return pDev->started;
1065 }
1066
1067 int grcan_flush(void *d)
1068 {
1069 struct grcan_priv *pDev = d;
1070 int tmp;
1071
1072 FUNCDBG();
1073
1074 if ((pDev->started != STATE_STARTED) || pDev->flushing || pDev->config.silent)
1075 return -1;
1076
1077 pDev->flushing = 1;
1078 tmp = grcan_tx_flush(pDev);
1079 pDev->flushing = 0;
1080 if ( tmp ) {
1081
1082
1083
1084
1085 return -1;
1086 }
1087
1088 return 0;
1089 }
1090
1091 int grcan_set_silent(void* d, int silent)
1092 {
1093 struct grcan_priv *pDev = d;
1094
1095 FUNCDBG();
1096
1097 if (pDev->started == STATE_STARTED)
1098 return -1;
1099
1100 pDev->config.silent = silent;
1101 pDev->config_changed = 1;
1102
1103 return 0;
1104 }
1105
1106 int grcan_set_abort(void* d, int abort)
1107 {
1108 struct grcan_priv *pDev = d;
1109
1110 FUNCDBG();
1111
1112 if (pDev->started == STATE_STARTED)
1113 return -1;
1114
1115 pDev->config.abort = abort;
1116
1117
1118
1119
1120 return 0;
1121 }
1122
1123 int grcan_set_selection(void *d, const struct grcan_selection *selection)
1124 {
1125 struct grcan_priv *pDev = d;
1126
1127 FUNCDBG();
1128
1129 if (pDev->started == STATE_STARTED)
1130 return -1;
1131
1132 if ( !selection )
1133 return -2;
1134
1135 pDev->config.selection = *selection;
1136 pDev->config_changed = 1;
1137
1138 return 0;
1139 }
1140
1141 int grcan_set_rxblock(void *d, int block)
1142 {
1143 struct grcan_priv *pDev = d;
1144
1145 FUNCDBG();
1146
1147 pDev->rxblock = block;
1148
1149 return 0;
1150 }
1151
1152 int grcan_set_txblock(void *d, int block)
1153 {
1154 struct grcan_priv *pDev = d;
1155
1156 FUNCDBG();
1157
1158 pDev->txblock = block;
1159
1160 return 0;
1161 }
1162
1163 int grcan_set_txcomplete(void *d, int complete)
1164 {
1165 struct grcan_priv *pDev = d;
1166
1167 FUNCDBG();
1168
1169 pDev->txcomplete = complete;
1170
1171 return 0;
1172 }
1173
1174 int grcan_set_rxcomplete(void *d, int complete)
1175 {
1176 struct grcan_priv *pDev = d;
1177
1178 FUNCDBG();
1179
1180 pDev->rxcomplete = complete;
1181
1182 return 0;
1183 }
1184
1185 int grcan_get_stats(void *d, struct grcan_stats *stats)
1186 {
1187 struct grcan_priv *pDev = d;
1188 SPIN_IRQFLAGS(oldLevel);
1189
1190 FUNCDBG();
1191
1192 if ( !stats )
1193 return -1;
1194
1195 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1196 *stats = pDev->stats;
1197 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1198
1199 return 0;
1200 }
1201
1202 int grcan_clr_stats(void *d)
1203 {
1204 struct grcan_priv *pDev = d;
1205 SPIN_IRQFLAGS(oldLevel);
1206
1207 FUNCDBG();
1208
1209 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1210 memset(&pDev->stats,0,sizeof(struct grcan_stats));
1211 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1212
1213 return 0;
1214 }
1215
1216 int grcan_set_afilter(void *d, const struct grcan_filter *filter)
1217 {
1218 struct grcan_priv *pDev = d;
1219
1220 FUNCDBG();
1221
1222 if ( !filter ){
1223
1224 pDev->afilter.mask = 0x0;
1225 pDev->afilter.code = 0x0;
1226 }else{
1227
1228 pDev->afilter = *filter;
1229 }
1230
1231 grcan_hw_accept(pDev->regs,&pDev->afilter);
1232
1233 return 0;
1234 }
1235
1236 int grcan_set_sfilter(void *d, const struct grcan_filter *filter)
1237 {
1238 struct grcan_priv *pDev = d;
1239 SPIN_IRQFLAGS(oldLevel);
1240
1241 FUNCDBG();
1242
1243 if ( !filter ){
1244
1245 pDev->sfilter.mask = 0xffffffff;
1246 pDev->sfilter.code = 0;
1247
1248
1249 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1250 pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
1251 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1252 }else{
1253
1254 pDev->sfilter = *filter;
1255
1256
1257 SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
1258 pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
1259 SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
1260 }
1261
1262 grcan_hw_sync(pDev->regs,&pDev->sfilter);
1263
1264 return 0;
1265 }
1266
1267 int grcan_get_status(void* d, unsigned int *data)
1268 {
1269 struct grcan_priv *pDev = d;
1270
1271 FUNCDBG();
1272
1273 if ( !data )
1274 return -1;
1275
1276
1277 data[0] = READ_REG(&pDev->regs->stat);
1278
1279 return 0;
1280 }
1281
1282
1283 #define GRCAN_IRQ_ERRORS \
1284 (GRCAN_RXAHBERR_IRQ | GRCAN_TXAHBERR_IRQ | GRCAN_OFF_IRQ)
1285 #define GRCAN_STAT_ERRORS (GRCAN_STAT_AHBERR | GRCAN_STAT_OFF)
1286
1287 #define GRCAN_IRQ_WARNS \
1288 (GRCAN_ERR_IRQ | GRCAN_OR_IRQ | GRCAN_TXLOSS_IRQ | \
1289 GRCAN_RXSYNC_IRQ | GRCAN_TXSYNC_IRQ)
1290 #define GRCAN_STAT_WARNS (GRCAN_STAT_OR | GRCAN_STAT_PASS)
1291
1292
1293 static void grcan_interrupt(void *arg)
1294 {
1295 struct grcan_priv *pDev = arg;
1296 unsigned int status = READ_REG(&pDev->regs->pimsr);
1297 unsigned int canstat = READ_REG(&pDev->regs->stat);
1298 unsigned int imr_clear;
1299 SPIN_ISR_IRQFLAGS(irqflags);
1300
1301
1302 if ( !status && !canstat )
1303 return;
1304
1305 if (pDev->started != STATE_STARTED) {
1306 DBGC(DBG_STATE, "not STARTED (unexpected interrupt)\n");
1307 pDev->regs->picr = status;
1308 return;
1309 }
1310
1311 FUNCDBG();
1312
1313 if ( (status & GRCAN_IRQ_ERRORS) || (canstat & GRCAN_STAT_ERRORS) ) {
1314
1315
1316
1317
1318
1319 SPIN_LOCK(&pDev->devlock, irqflags);
1320 DBGC(DBG_STATE, "STARTED->BUSOFF|AHBERR\n");
1321 pDev->stats.ints++;
1322 if ((status & GRCAN_OFF_IRQ) || (canstat & GRCAN_STAT_OFF)) {
1323
1324 DBGC(DBG_STATE, "BUSOFF: status: 0x%x, canstat: 0x%x\n",
1325 status, canstat);
1326 pDev->started = STATE_BUSOFF;
1327 pDev->stats.busoff_cnt++;
1328 } else {
1329
1330 printk("AHBERROR: status: 0x%x, canstat: 0x%x\n",
1331 status, canstat);
1332 pDev->started = STATE_AHBERR;
1333 pDev->stats.ahberr_cnt++;
1334 }
1335 grcan_hw_stop(pDev);
1336 pDev->regs->picr = 0x1ffff;
1337
1338
1339
1340
1341 SPIN_UNLOCK(&pDev->devlock, irqflags);
1342
1343
1344 grcan_sw_stop(pDev);
1345
1346
1347
1348
1349
1350 return;
1351 }
1352
1353
1354 imr_clear = status & (GRCAN_RXIRQ_IRQ | GRCAN_TXIRQ_IRQ | GRCAN_TXEMPTY_IRQ);
1355
1356 SPIN_LOCK(&pDev->devlock, irqflags);
1357
1358
1359 pDev->stats.ints++;
1360 if ((status & GRCAN_IRQ_WARNS) || (canstat & GRCAN_STAT_WARNS)) {
1361
1362 if ( (status & GRCAN_ERR_IRQ) || (canstat & GRCAN_STAT_PASS) ) {
1363
1364 pDev->stats.passive_cnt++;
1365 }
1366
1367 if ( (status & GRCAN_OR_IRQ) || (canstat & GRCAN_STAT_OR) ) {
1368
1369 pDev->stats.overrun_cnt++;
1370 }
1371
1372 if ( status & GRCAN_TXLOSS_IRQ ) {
1373 pDev->stats.txloss_cnt++;
1374 }
1375
1376 if ( status & GRCAN_TXSYNC_IRQ ) {
1377
1378 pDev->stats.txsync_cnt++;
1379 }
1380
1381 if ( status & GRCAN_RXSYNC_IRQ ) {
1382
1383 pDev->stats.rxsync_cnt++;
1384 }
1385 }
1386
1387 if (imr_clear) {
1388 pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~imr_clear;
1389
1390 SPIN_UNLOCK(&pDev->devlock, irqflags);
1391
1392 if ( status & GRCAN_RXIRQ_IRQ ) {
1393
1394 rtems_semaphore_release(pDev->rx_sem);
1395 }
1396
1397 if ( status & GRCAN_TXIRQ_IRQ ) {
1398
1399 rtems_semaphore_release(pDev->tx_sem);
1400 }
1401
1402 if (status & GRCAN_TXEMPTY_IRQ ) {
1403 rtems_semaphore_release(pDev->txempty_sem);
1404 }
1405 } else {
1406 SPIN_UNLOCK(&pDev->devlock, irqflags);
1407 }
1408
1409
1410 pDev->regs->picr = status;
1411 }