Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Core driver for the CC770 and AN82527 CAN controllers
0004  *
0005  * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
0006  */
0007 
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 
0010 #include <linux/module.h>
0011 #include <linux/init.h>
0012 #include <linux/kernel.h>
0013 #include <linux/sched.h>
0014 #include <linux/types.h>
0015 #include <linux/fcntl.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/ptrace.h>
0018 #include <linux/string.h>
0019 #include <linux/errno.h>
0020 #include <linux/ethtool.h>
0021 #include <linux/netdevice.h>
0022 #include <linux/if_arp.h>
0023 #include <linux/if_ether.h>
0024 #include <linux/skbuff.h>
0025 #include <linux/delay.h>
0026 
0027 #include <linux/can.h>
0028 #include <linux/can/dev.h>
0029 #include <linux/can/error.h>
0030 #include <linux/can/platform/cc770.h>
0031 
0032 #include "cc770.h"
0033 
0034 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
0035 MODULE_LICENSE("GPL v2");
0036 MODULE_DESCRIPTION(KBUILD_MODNAME "CAN netdevice driver");
0037 
0038 /*
0039  * The CC770 is a CAN controller from Bosch, which is 100% compatible
0040  * with the AN82527 from Intel, but with "bugs" being fixed and some
0041  * additional functionality, mainly:
0042  *
0043  * 1. RX and TX error counters are readable.
0044  * 2. Support of silent (listen-only) mode.
0045  * 3. Message object 15 can receive all types of frames, also RTR and EFF.
0046  *
0047  * Details are available from Bosch's "CC770_Product_Info_2007-01.pdf",
0048  * which explains in detail the compatibility between the CC770 and the
0049  * 82527. This driver use the additional functionality 3. on real CC770
0050  * devices. Unfortunately, the CC770 does still not store the message
0051  * identifier of received remote transmission request frames and
0052  * therefore it's set to 0.
0053  *
0054  * The message objects 1..14 can be used for TX and RX while the message
0055  * objects 15 is optimized for RX. It has a shadow register for reliable
0056  * data reception under heavy bus load. Therefore it makes sense to use
0057  * this message object for the needed use case. The frame type (EFF/SFF)
0058  * for the message object 15 can be defined via kernel module parameter
0059  * "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames,
0060  * otherwise 11 bit SFF messages.
0061  */
0062 static int msgobj15_eff;
0063 module_param(msgobj15_eff, int, 0444);
0064 MODULE_PARM_DESC(msgobj15_eff, "Extended 29-bit frames for message object 15 "
0065          "(default: 11-bit standard frames)");
0066 
0067 static int i82527_compat;
0068 module_param(i82527_compat, int, 0444);
0069 MODULE_PARM_DESC(i82527_compat, "Strict Intel 82527 compatibility mode "
0070          "without using additional functions");
0071 
0072 /*
0073  * This driver uses the last 5 message objects 11..15. The definitions
0074  * and structure below allows to configure and assign them to the real
0075  * message object.
0076  */
0077 static unsigned char cc770_obj_flags[CC770_OBJ_MAX] = {
0078     [CC770_OBJ_RX0] = CC770_OBJ_FLAG_RX,
0079     [CC770_OBJ_RX1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_EFF,
0080     [CC770_OBJ_RX_RTR0] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR,
0081     [CC770_OBJ_RX_RTR1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR |
0082                   CC770_OBJ_FLAG_EFF,
0083     [CC770_OBJ_TX] = 0,
0084 };
0085 
0086 static const struct can_bittiming_const cc770_bittiming_const = {
0087     .name = KBUILD_MODNAME,
0088     .tseg1_min = 1,
0089     .tseg1_max = 16,
0090     .tseg2_min = 1,
0091     .tseg2_max = 8,
0092     .sjw_max = 4,
0093     .brp_min = 1,
0094     .brp_max = 64,
0095     .brp_inc = 1,
0096 };
0097 
0098 static inline int intid2obj(unsigned int intid)
0099 {
0100     if (intid == 2)
0101         return 0;
0102     else
0103         return MSGOBJ_LAST + 2 - intid;
0104 }
0105 
0106 static void enable_all_objs(const struct net_device *dev)
0107 {
0108     struct cc770_priv *priv = netdev_priv(dev);
0109     u8 msgcfg;
0110     unsigned char obj_flags;
0111     unsigned int o, mo;
0112 
0113     for (o = 0; o < ARRAY_SIZE(priv->obj_flags); o++) {
0114         obj_flags = priv->obj_flags[o];
0115         mo = obj2msgobj(o);
0116 
0117         if (obj_flags & CC770_OBJ_FLAG_RX) {
0118             /*
0119              * We don't need extra objects for RTR and EFF if
0120              * the additional CC770 functions are enabled.
0121              */
0122             if (priv->control_normal_mode & CTRL_EAF) {
0123                 if (o > 0)
0124                     continue;
0125                 netdev_dbg(dev, "Message object %d for "
0126                        "RX data, RTR, SFF and EFF\n", mo);
0127             } else {
0128                 netdev_dbg(dev,
0129                        "Message object %d for RX %s %s\n",
0130                        mo, obj_flags & CC770_OBJ_FLAG_RTR ?
0131                        "RTR" : "data",
0132                        obj_flags & CC770_OBJ_FLAG_EFF ?
0133                        "EFF" : "SFF");
0134             }
0135 
0136             if (obj_flags & CC770_OBJ_FLAG_EFF)
0137                 msgcfg = MSGCFG_XTD;
0138             else
0139                 msgcfg = 0;
0140             if (obj_flags & CC770_OBJ_FLAG_RTR)
0141                 msgcfg |= MSGCFG_DIR;
0142 
0143             cc770_write_reg(priv, msgobj[mo].config, msgcfg);
0144             cc770_write_reg(priv, msgobj[mo].ctrl0,
0145                     MSGVAL_SET | TXIE_RES |
0146                     RXIE_SET | INTPND_RES);
0147 
0148             if (obj_flags & CC770_OBJ_FLAG_RTR)
0149                 cc770_write_reg(priv, msgobj[mo].ctrl1,
0150                         NEWDAT_RES | CPUUPD_SET |
0151                         TXRQST_RES | RMTPND_RES);
0152             else
0153                 cc770_write_reg(priv, msgobj[mo].ctrl1,
0154                         NEWDAT_RES | MSGLST_RES |
0155                         TXRQST_RES | RMTPND_RES);
0156         } else {
0157             netdev_dbg(dev, "Message object %d for "
0158                    "TX data, RTR, SFF and EFF\n", mo);
0159 
0160             cc770_write_reg(priv, msgobj[mo].ctrl1,
0161                     RMTPND_RES | TXRQST_RES |
0162                     CPUUPD_RES | NEWDAT_RES);
0163             cc770_write_reg(priv, msgobj[mo].ctrl0,
0164                     MSGVAL_RES | TXIE_RES |
0165                     RXIE_RES | INTPND_RES);
0166         }
0167     }
0168 }
0169 
0170 static void disable_all_objs(const struct cc770_priv *priv)
0171 {
0172     int o, mo;
0173 
0174     for (o = 0; o <  ARRAY_SIZE(priv->obj_flags); o++) {
0175         mo = obj2msgobj(o);
0176 
0177         if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX) {
0178             if (o > 0 && priv->control_normal_mode & CTRL_EAF)
0179                 continue;
0180 
0181             cc770_write_reg(priv, msgobj[mo].ctrl1,
0182                     NEWDAT_RES | MSGLST_RES |
0183                     TXRQST_RES | RMTPND_RES);
0184             cc770_write_reg(priv, msgobj[mo].ctrl0,
0185                     MSGVAL_RES | TXIE_RES |
0186                     RXIE_RES | INTPND_RES);
0187         } else {
0188             /* Clear message object for send */
0189             cc770_write_reg(priv, msgobj[mo].ctrl1,
0190                     RMTPND_RES | TXRQST_RES |
0191                     CPUUPD_RES | NEWDAT_RES);
0192             cc770_write_reg(priv, msgobj[mo].ctrl0,
0193                     MSGVAL_RES | TXIE_RES |
0194                     RXIE_RES | INTPND_RES);
0195         }
0196     }
0197 }
0198 
0199 static void set_reset_mode(struct net_device *dev)
0200 {
0201     struct cc770_priv *priv = netdev_priv(dev);
0202 
0203     /* Enable configuration and puts chip in bus-off, disable interrupts */
0204     cc770_write_reg(priv, control, CTRL_CCE | CTRL_INI);
0205 
0206     priv->can.state = CAN_STATE_STOPPED;
0207 
0208     /* Clear interrupts */
0209     cc770_read_reg(priv, interrupt);
0210 
0211     /* Clear status register */
0212     cc770_write_reg(priv, status, 0);
0213 
0214     /* Disable all used message objects */
0215     disable_all_objs(priv);
0216 }
0217 
0218 static void set_normal_mode(struct net_device *dev)
0219 {
0220     struct cc770_priv *priv = netdev_priv(dev);
0221 
0222     /* Clear interrupts */
0223     cc770_read_reg(priv, interrupt);
0224 
0225     /* Clear status register and pre-set last error code */
0226     cc770_write_reg(priv, status, STAT_LEC_MASK);
0227 
0228     /* Enable all used message objects*/
0229     enable_all_objs(dev);
0230 
0231     /*
0232      * Clear bus-off, interrupts only for errors,
0233      * not for status change
0234      */
0235     cc770_write_reg(priv, control, priv->control_normal_mode);
0236 
0237     priv->can.state = CAN_STATE_ERROR_ACTIVE;
0238 }
0239 
0240 static void chipset_init(struct cc770_priv *priv)
0241 {
0242     int mo, id, data;
0243 
0244     /* Enable configuration and put chip in bus-off, disable interrupts */
0245     cc770_write_reg(priv, control, (CTRL_CCE | CTRL_INI));
0246 
0247     /* Set CLKOUT divider and slew rates */
0248     cc770_write_reg(priv, clkout, priv->clkout);
0249 
0250     /* Configure CPU interface / CLKOUT enable */
0251     cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
0252 
0253     /* Set bus configuration  */
0254     cc770_write_reg(priv, bus_config, priv->bus_config);
0255 
0256     /* Clear interrupts */
0257     cc770_read_reg(priv, interrupt);
0258 
0259     /* Clear status register */
0260     cc770_write_reg(priv, status, 0);
0261 
0262     /* Clear and invalidate message objects */
0263     for (mo = MSGOBJ_FIRST; mo <= MSGOBJ_LAST; mo++) {
0264         cc770_write_reg(priv, msgobj[mo].ctrl0,
0265                 INTPND_UNC | RXIE_RES |
0266                 TXIE_RES | MSGVAL_RES);
0267         cc770_write_reg(priv, msgobj[mo].ctrl0,
0268                 INTPND_RES | RXIE_RES |
0269                 TXIE_RES | MSGVAL_RES);
0270         cc770_write_reg(priv, msgobj[mo].ctrl1,
0271                 NEWDAT_RES | MSGLST_RES |
0272                 TXRQST_RES | RMTPND_RES);
0273         for (data = 0; data < 8; data++)
0274             cc770_write_reg(priv, msgobj[mo].data[data], 0);
0275         for (id = 0; id < 4; id++)
0276             cc770_write_reg(priv, msgobj[mo].id[id], 0);
0277         cc770_write_reg(priv, msgobj[mo].config, 0);
0278     }
0279 
0280     /* Set all global ID masks to "don't care" */
0281     cc770_write_reg(priv, global_mask_std[0], 0);
0282     cc770_write_reg(priv, global_mask_std[1], 0);
0283     cc770_write_reg(priv, global_mask_ext[0], 0);
0284     cc770_write_reg(priv, global_mask_ext[1], 0);
0285     cc770_write_reg(priv, global_mask_ext[2], 0);
0286     cc770_write_reg(priv, global_mask_ext[3], 0);
0287 
0288 }
0289 
0290 static int cc770_probe_chip(struct net_device *dev)
0291 {
0292     struct cc770_priv *priv = netdev_priv(dev);
0293 
0294     /* Enable configuration, put chip in bus-off, disable ints */
0295     cc770_write_reg(priv, control, CTRL_CCE | CTRL_EAF | CTRL_INI);
0296     /* Configure cpu interface / CLKOUT disable */
0297     cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
0298 
0299     /*
0300      * Check if hardware reset is still inactive or maybe there
0301      * is no chip in this address space
0302      */
0303     if (cc770_read_reg(priv, cpu_interface) & CPUIF_RST) {
0304         netdev_info(dev, "probing @0x%p failed (reset)\n",
0305                 priv->reg_base);
0306         return -ENODEV;
0307     }
0308 
0309     /* Write and read back test pattern (some arbitrary values) */
0310     cc770_write_reg(priv, msgobj[1].data[1], 0x25);
0311     cc770_write_reg(priv, msgobj[2].data[3], 0x52);
0312     cc770_write_reg(priv, msgobj[10].data[6], 0xc3);
0313     if ((cc770_read_reg(priv, msgobj[1].data[1]) != 0x25) ||
0314         (cc770_read_reg(priv, msgobj[2].data[3]) != 0x52) ||
0315         (cc770_read_reg(priv, msgobj[10].data[6]) != 0xc3)) {
0316         netdev_info(dev, "probing @0x%p failed (pattern)\n",
0317                 priv->reg_base);
0318         return -ENODEV;
0319     }
0320 
0321     /* Check if this chip is a CC770 supporting additional functions */
0322     if (cc770_read_reg(priv, control) & CTRL_EAF)
0323         priv->control_normal_mode |= CTRL_EAF;
0324 
0325     return 0;
0326 }
0327 
0328 static void cc770_start(struct net_device *dev)
0329 {
0330     struct cc770_priv *priv = netdev_priv(dev);
0331 
0332     /* leave reset mode */
0333     if (priv->can.state != CAN_STATE_STOPPED)
0334         set_reset_mode(dev);
0335 
0336     /* leave reset mode */
0337     set_normal_mode(dev);
0338 }
0339 
0340 static int cc770_set_mode(struct net_device *dev, enum can_mode mode)
0341 {
0342     switch (mode) {
0343     case CAN_MODE_START:
0344         cc770_start(dev);
0345         netif_wake_queue(dev);
0346         break;
0347 
0348     default:
0349         return -EOPNOTSUPP;
0350     }
0351 
0352     return 0;
0353 }
0354 
0355 static int cc770_set_bittiming(struct net_device *dev)
0356 {
0357     struct cc770_priv *priv = netdev_priv(dev);
0358     struct can_bittiming *bt = &priv->can.bittiming;
0359     u8 btr0, btr1;
0360 
0361     btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
0362     btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
0363         (((bt->phase_seg2 - 1) & 0x7) << 4);
0364     if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
0365         btr1 |= 0x80;
0366 
0367     netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
0368 
0369     cc770_write_reg(priv, bit_timing_0, btr0);
0370     cc770_write_reg(priv, bit_timing_1, btr1);
0371 
0372     return 0;
0373 }
0374 
0375 static int cc770_get_berr_counter(const struct net_device *dev,
0376                   struct can_berr_counter *bec)
0377 {
0378     struct cc770_priv *priv = netdev_priv(dev);
0379 
0380     bec->txerr = cc770_read_reg(priv, tx_error_counter);
0381     bec->rxerr = cc770_read_reg(priv, rx_error_counter);
0382 
0383     return 0;
0384 }
0385 
0386 static void cc770_tx(struct net_device *dev, int mo)
0387 {
0388     struct cc770_priv *priv = netdev_priv(dev);
0389     struct can_frame *cf = (struct can_frame *)priv->tx_skb->data;
0390     u8 dlc, rtr;
0391     u32 id;
0392     int i;
0393 
0394     dlc = cf->len;
0395     id = cf->can_id;
0396     rtr = cf->can_id & CAN_RTR_FLAG ? 0 : MSGCFG_DIR;
0397 
0398     cc770_write_reg(priv, msgobj[mo].ctrl0,
0399             MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
0400     cc770_write_reg(priv, msgobj[mo].ctrl1,
0401             RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES);
0402 
0403     if (id & CAN_EFF_FLAG) {
0404         id &= CAN_EFF_MASK;
0405         cc770_write_reg(priv, msgobj[mo].config,
0406                 (dlc << 4) | rtr | MSGCFG_XTD);
0407         cc770_write_reg(priv, msgobj[mo].id[3], id << 3);
0408         cc770_write_reg(priv, msgobj[mo].id[2], id >> 5);
0409         cc770_write_reg(priv, msgobj[mo].id[1], id >> 13);
0410         cc770_write_reg(priv, msgobj[mo].id[0], id >> 21);
0411     } else {
0412         id &= CAN_SFF_MASK;
0413         cc770_write_reg(priv, msgobj[mo].config, (dlc << 4) | rtr);
0414         cc770_write_reg(priv, msgobj[mo].id[0], id >> 3);
0415         cc770_write_reg(priv, msgobj[mo].id[1], id << 5);
0416     }
0417 
0418     for (i = 0; i < dlc; i++)
0419         cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
0420 
0421     cc770_write_reg(priv, msgobj[mo].ctrl1,
0422             RMTPND_UNC | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
0423     cc770_write_reg(priv, msgobj[mo].ctrl0,
0424             MSGVAL_SET | TXIE_SET | RXIE_SET | INTPND_UNC);
0425 }
0426 
0427 static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
0428 {
0429     struct cc770_priv *priv = netdev_priv(dev);
0430     unsigned int mo = obj2msgobj(CC770_OBJ_TX);
0431 
0432     if (can_dropped_invalid_skb(dev, skb))
0433         return NETDEV_TX_OK;
0434 
0435     netif_stop_queue(dev);
0436 
0437     if ((cc770_read_reg(priv,
0438                 msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
0439         netdev_err(dev, "TX register is still occupied!\n");
0440         return NETDEV_TX_BUSY;
0441     }
0442 
0443     priv->tx_skb = skb;
0444     cc770_tx(dev, mo);
0445 
0446     return NETDEV_TX_OK;
0447 }
0448 
0449 static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
0450 {
0451     struct cc770_priv *priv = netdev_priv(dev);
0452     struct net_device_stats *stats = &dev->stats;
0453     struct can_frame *cf;
0454     struct sk_buff *skb;
0455     u8 config;
0456     u32 id;
0457     int i;
0458 
0459     skb = alloc_can_skb(dev, &cf);
0460     if (!skb)
0461         return;
0462 
0463     config = cc770_read_reg(priv, msgobj[mo].config);
0464 
0465     if (ctrl1 & RMTPND_SET) {
0466         /*
0467          * Unfortunately, the chip does not store the real message
0468          * identifier of the received remote transmission request
0469          * frame. Therefore we set it to 0.
0470          */
0471         cf->can_id = CAN_RTR_FLAG;
0472         if (config & MSGCFG_XTD)
0473             cf->can_id |= CAN_EFF_FLAG;
0474         cf->len = 0;
0475     } else {
0476         if (config & MSGCFG_XTD) {
0477             id = cc770_read_reg(priv, msgobj[mo].id[3]);
0478             id |= cc770_read_reg(priv, msgobj[mo].id[2]) << 8;
0479             id |= cc770_read_reg(priv, msgobj[mo].id[1]) << 16;
0480             id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 24;
0481             id >>= 3;
0482             id |= CAN_EFF_FLAG;
0483         } else {
0484             id = cc770_read_reg(priv, msgobj[mo].id[1]);
0485             id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 8;
0486             id >>= 5;
0487         }
0488 
0489         cf->can_id = id;
0490         cf->len = can_cc_dlc2len((config & 0xf0) >> 4);
0491         for (i = 0; i < cf->len; i++)
0492             cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]);
0493 
0494         stats->rx_bytes += cf->len;
0495     }
0496     stats->rx_packets++;
0497 
0498     netif_rx(skb);
0499 }
0500 
0501 static int cc770_err(struct net_device *dev, u8 status)
0502 {
0503     struct cc770_priv *priv = netdev_priv(dev);
0504     struct can_frame *cf;
0505     struct sk_buff *skb;
0506     u8 lec;
0507 
0508     netdev_dbg(dev, "status interrupt (%#x)\n", status);
0509 
0510     skb = alloc_can_err_skb(dev, &cf);
0511     if (!skb)
0512         return -ENOMEM;
0513 
0514     /* Use extended functions of the CC770 */
0515     if (priv->control_normal_mode & CTRL_EAF) {
0516         cf->can_id |= CAN_ERR_CNT;
0517         cf->data[6] = cc770_read_reg(priv, tx_error_counter);
0518         cf->data[7] = cc770_read_reg(priv, rx_error_counter);
0519     }
0520 
0521     if (status & STAT_BOFF) {
0522         /* Disable interrupts */
0523         cc770_write_reg(priv, control, CTRL_INI);
0524         cf->can_id |= CAN_ERR_BUSOFF;
0525         priv->can.state = CAN_STATE_BUS_OFF;
0526         priv->can.can_stats.bus_off++;
0527         can_bus_off(dev);
0528     } else if (status & STAT_WARN) {
0529         cf->can_id |= CAN_ERR_CRTL;
0530         /* Only the CC770 does show error passive */
0531         if (cf->data[7] > 127) {
0532             cf->data[1] = CAN_ERR_CRTL_RX_PASSIVE |
0533                 CAN_ERR_CRTL_TX_PASSIVE;
0534             priv->can.state = CAN_STATE_ERROR_PASSIVE;
0535             priv->can.can_stats.error_passive++;
0536         } else {
0537             cf->data[1] = CAN_ERR_CRTL_RX_WARNING |
0538                 CAN_ERR_CRTL_TX_WARNING;
0539             priv->can.state = CAN_STATE_ERROR_WARNING;
0540             priv->can.can_stats.error_warning++;
0541         }
0542     } else {
0543         /* Back to error active */
0544         cf->can_id |= CAN_ERR_PROT;
0545         cf->data[2] = CAN_ERR_PROT_ACTIVE;
0546         priv->can.state = CAN_STATE_ERROR_ACTIVE;
0547     }
0548 
0549     lec = status & STAT_LEC_MASK;
0550     if (lec < 7 && lec > 0) {
0551         if (lec == STAT_LEC_ACK) {
0552             cf->can_id |= CAN_ERR_ACK;
0553         } else {
0554             cf->can_id |= CAN_ERR_PROT;
0555             switch (lec) {
0556             case STAT_LEC_STUFF:
0557                 cf->data[2] |= CAN_ERR_PROT_STUFF;
0558                 break;
0559             case STAT_LEC_FORM:
0560                 cf->data[2] |= CAN_ERR_PROT_FORM;
0561                 break;
0562             case STAT_LEC_BIT1:
0563                 cf->data[2] |= CAN_ERR_PROT_BIT1;
0564                 break;
0565             case STAT_LEC_BIT0:
0566                 cf->data[2] |= CAN_ERR_PROT_BIT0;
0567                 break;
0568             case STAT_LEC_CRC:
0569                 cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
0570                 break;
0571             }
0572         }
0573     }
0574 
0575 
0576     netif_rx(skb);
0577 
0578     return 0;
0579 }
0580 
0581 static int cc770_status_interrupt(struct net_device *dev)
0582 {
0583     struct cc770_priv *priv = netdev_priv(dev);
0584     u8 status;
0585 
0586     status = cc770_read_reg(priv, status);
0587     /* Reset the status register including RXOK and TXOK */
0588     cc770_write_reg(priv, status, STAT_LEC_MASK);
0589 
0590     if (status & (STAT_WARN | STAT_BOFF) ||
0591         (status & STAT_LEC_MASK) != STAT_LEC_MASK) {
0592         cc770_err(dev, status);
0593         return status & STAT_BOFF;
0594     }
0595 
0596     return 0;
0597 }
0598 
0599 static void cc770_rx_interrupt(struct net_device *dev, unsigned int o)
0600 {
0601     struct cc770_priv *priv = netdev_priv(dev);
0602     struct net_device_stats *stats = &dev->stats;
0603     unsigned int mo = obj2msgobj(o);
0604     u8 ctrl1;
0605     int n = CC770_MAX_MSG;
0606 
0607     while (n--) {
0608         ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
0609 
0610         if (!(ctrl1 & NEWDAT_SET))  {
0611             /* Check for RTR if additional functions are enabled */
0612             if (priv->control_normal_mode & CTRL_EAF) {
0613                 if (!(cc770_read_reg(priv, msgobj[mo].ctrl0) &
0614                       INTPND_SET))
0615                     break;
0616             } else {
0617                 break;
0618             }
0619         }
0620 
0621         if (ctrl1 & MSGLST_SET) {
0622             stats->rx_over_errors++;
0623             stats->rx_errors++;
0624         }
0625         if (mo < MSGOBJ_LAST)
0626             cc770_write_reg(priv, msgobj[mo].ctrl1,
0627                     NEWDAT_RES | MSGLST_RES |
0628                     TXRQST_UNC | RMTPND_UNC);
0629         cc770_rx(dev, mo, ctrl1);
0630 
0631         cc770_write_reg(priv, msgobj[mo].ctrl0,
0632                 MSGVAL_SET | TXIE_RES |
0633                 RXIE_SET | INTPND_RES);
0634         cc770_write_reg(priv, msgobj[mo].ctrl1,
0635                 NEWDAT_RES | MSGLST_RES |
0636                 TXRQST_RES | RMTPND_RES);
0637     }
0638 }
0639 
0640 static void cc770_rtr_interrupt(struct net_device *dev, unsigned int o)
0641 {
0642     struct cc770_priv *priv = netdev_priv(dev);
0643     unsigned int mo = obj2msgobj(o);
0644     u8 ctrl0, ctrl1;
0645     int n = CC770_MAX_MSG;
0646 
0647     while (n--) {
0648         ctrl0 = cc770_read_reg(priv, msgobj[mo].ctrl0);
0649         if (!(ctrl0 & INTPND_SET))
0650             break;
0651 
0652         ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
0653         cc770_rx(dev, mo, ctrl1);
0654 
0655         cc770_write_reg(priv, msgobj[mo].ctrl0,
0656                 MSGVAL_SET | TXIE_RES |
0657                 RXIE_SET | INTPND_RES);
0658         cc770_write_reg(priv, msgobj[mo].ctrl1,
0659                 NEWDAT_RES | CPUUPD_SET |
0660                 TXRQST_RES | RMTPND_RES);
0661     }
0662 }
0663 
0664 static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
0665 {
0666     struct cc770_priv *priv = netdev_priv(dev);
0667     struct net_device_stats *stats = &dev->stats;
0668     unsigned int mo = obj2msgobj(o);
0669     u8 ctrl1;
0670 
0671     ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
0672 
0673     cc770_write_reg(priv, msgobj[mo].ctrl0,
0674             MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
0675     cc770_write_reg(priv, msgobj[mo].ctrl1,
0676             RMTPND_RES | TXRQST_RES | MSGLST_RES | NEWDAT_RES);
0677 
0678     if (unlikely(!priv->tx_skb)) {
0679         netdev_err(dev, "missing tx skb in tx interrupt\n");
0680         return;
0681     }
0682 
0683     if (unlikely(ctrl1 & MSGLST_SET)) {
0684         stats->rx_over_errors++;
0685         stats->rx_errors++;
0686     }
0687 
0688     /* When the CC770 is sending an RTR message and it receives a regular
0689      * message that matches the id of the RTR message, it will overwrite the
0690      * outgoing message in the TX register. When this happens we must
0691      * process the received message and try to transmit the outgoing skb
0692      * again.
0693      */
0694     if (unlikely(ctrl1 & NEWDAT_SET)) {
0695         cc770_rx(dev, mo, ctrl1);
0696         cc770_tx(dev, mo);
0697         return;
0698     }
0699 
0700     can_put_echo_skb(priv->tx_skb, dev, 0, 0);
0701     stats->tx_bytes += can_get_echo_skb(dev, 0, NULL);
0702     stats->tx_packets++;
0703     priv->tx_skb = NULL;
0704 
0705     netif_wake_queue(dev);
0706 }
0707 
0708 static irqreturn_t cc770_interrupt(int irq, void *dev_id)
0709 {
0710     struct net_device *dev = (struct net_device *)dev_id;
0711     struct cc770_priv *priv = netdev_priv(dev);
0712     u8 intid;
0713     int o, n = 0;
0714 
0715     /* Shared interrupts and IRQ off? */
0716     if (priv->can.state == CAN_STATE_STOPPED)
0717         return IRQ_NONE;
0718 
0719     if (priv->pre_irq)
0720         priv->pre_irq(priv);
0721 
0722     while (n < CC770_MAX_IRQ) {
0723         /* Read the highest pending interrupt request */
0724         intid = cc770_read_reg(priv, interrupt);
0725         if (!intid)
0726             break;
0727         n++;
0728 
0729         if (intid == 1) {
0730             /* Exit in case of bus-off */
0731             if (cc770_status_interrupt(dev))
0732                 break;
0733         } else {
0734             o = intid2obj(intid);
0735 
0736             if (o >= CC770_OBJ_MAX) {
0737                 netdev_err(dev, "Unexpected interrupt id %d\n",
0738                        intid);
0739                 continue;
0740             }
0741 
0742             if (priv->obj_flags[o] & CC770_OBJ_FLAG_RTR)
0743                 cc770_rtr_interrupt(dev, o);
0744             else if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX)
0745                 cc770_rx_interrupt(dev, o);
0746             else
0747                 cc770_tx_interrupt(dev, o);
0748         }
0749     }
0750 
0751     if (priv->post_irq)
0752         priv->post_irq(priv);
0753 
0754     if (n >= CC770_MAX_IRQ)
0755         netdev_dbg(dev, "%d messages handled in ISR", n);
0756 
0757     return (n) ? IRQ_HANDLED : IRQ_NONE;
0758 }
0759 
0760 static int cc770_open(struct net_device *dev)
0761 {
0762     struct cc770_priv *priv = netdev_priv(dev);
0763     int err;
0764 
0765     /* set chip into reset mode */
0766     set_reset_mode(dev);
0767 
0768     /* common open */
0769     err = open_candev(dev);
0770     if (err)
0771         return err;
0772 
0773     err = request_irq(dev->irq, &cc770_interrupt, priv->irq_flags,
0774               dev->name, dev);
0775     if (err) {
0776         close_candev(dev);
0777         return -EAGAIN;
0778     }
0779 
0780     /* init and start chip */
0781     cc770_start(dev);
0782 
0783     netif_start_queue(dev);
0784 
0785     return 0;
0786 }
0787 
0788 static int cc770_close(struct net_device *dev)
0789 {
0790     netif_stop_queue(dev);
0791     set_reset_mode(dev);
0792 
0793     free_irq(dev->irq, dev);
0794     close_candev(dev);
0795 
0796     return 0;
0797 }
0798 
0799 struct net_device *alloc_cc770dev(int sizeof_priv)
0800 {
0801     struct net_device *dev;
0802     struct cc770_priv *priv;
0803 
0804     dev = alloc_candev(sizeof(struct cc770_priv) + sizeof_priv,
0805                CC770_ECHO_SKB_MAX);
0806     if (!dev)
0807         return NULL;
0808 
0809     priv = netdev_priv(dev);
0810 
0811     priv->dev = dev;
0812     priv->can.bittiming_const = &cc770_bittiming_const;
0813     priv->can.do_set_bittiming = cc770_set_bittiming;
0814     priv->can.do_set_mode = cc770_set_mode;
0815     priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
0816     priv->tx_skb = NULL;
0817 
0818     memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags));
0819 
0820     if (sizeof_priv)
0821         priv->priv = (void *)priv + sizeof(struct cc770_priv);
0822 
0823     return dev;
0824 }
0825 EXPORT_SYMBOL_GPL(alloc_cc770dev);
0826 
0827 void free_cc770dev(struct net_device *dev)
0828 {
0829     free_candev(dev);
0830 }
0831 EXPORT_SYMBOL_GPL(free_cc770dev);
0832 
0833 static const struct net_device_ops cc770_netdev_ops = {
0834     .ndo_open = cc770_open,
0835     .ndo_stop = cc770_close,
0836     .ndo_start_xmit = cc770_start_xmit,
0837     .ndo_change_mtu = can_change_mtu,
0838 };
0839 
0840 static const struct ethtool_ops cc770_ethtool_ops = {
0841     .get_ts_info = ethtool_op_get_ts_info,
0842 };
0843 
0844 int register_cc770dev(struct net_device *dev)
0845 {
0846     struct cc770_priv *priv = netdev_priv(dev);
0847     int err;
0848 
0849     err = cc770_probe_chip(dev);
0850     if (err)
0851         return err;
0852 
0853     dev->netdev_ops = &cc770_netdev_ops;
0854     dev->ethtool_ops = &cc770_ethtool_ops;
0855 
0856     dev->flags |= IFF_ECHO; /* we support local echo */
0857 
0858     /* Should we use additional functions? */
0859     if (!i82527_compat && priv->control_normal_mode & CTRL_EAF) {
0860         priv->can.do_get_berr_counter = cc770_get_berr_counter;
0861         priv->control_normal_mode = CTRL_IE | CTRL_EAF | CTRL_EIE;
0862         netdev_dbg(dev, "i82527 mode with additional functions\n");
0863     } else {
0864         priv->control_normal_mode = CTRL_IE | CTRL_EIE;
0865         netdev_dbg(dev, "strict i82527 compatibility mode\n");
0866     }
0867 
0868     chipset_init(priv);
0869     set_reset_mode(dev);
0870 
0871     return register_candev(dev);
0872 }
0873 EXPORT_SYMBOL_GPL(register_cc770dev);
0874 
0875 void unregister_cc770dev(struct net_device *dev)
0876 {
0877     set_reset_mode(dev);
0878     unregister_candev(dev);
0879 }
0880 EXPORT_SYMBOL_GPL(unregister_cc770dev);
0881 
0882 static __init int cc770_init(void)
0883 {
0884     if (msgobj15_eff) {
0885         cc770_obj_flags[CC770_OBJ_RX0] |= CC770_OBJ_FLAG_EFF;
0886         cc770_obj_flags[CC770_OBJ_RX1] &= ~CC770_OBJ_FLAG_EFF;
0887     }
0888 
0889     pr_info("CAN netdevice driver\n");
0890 
0891     return 0;
0892 }
0893 module_init(cc770_init);
0894 
0895 static __exit void cc770_exit(void)
0896 {
0897     pr_info("driver removed\n");
0898 }
0899 module_exit(cc770_exit);