linux/drivers/net/can/cc770/cc770.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Core driver for the CC770 and AN82527 CAN controllers
   4 *
   5 * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
   6 */
   7
   8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9
  10#include <linux/module.h>
  11#include <linux/init.h>
  12#include <linux/kernel.h>
  13#include <linux/sched.h>
  14#include <linux/types.h>
  15#include <linux/fcntl.h>
  16#include <linux/interrupt.h>
  17#include <linux/ptrace.h>
  18#include <linux/string.h>
  19#include <linux/errno.h>
  20#include <linux/netdevice.h>
  21#include <linux/if_arp.h>
  22#include <linux/if_ether.h>
  23#include <linux/skbuff.h>
  24#include <linux/delay.h>
  25
  26#include <linux/can.h>
  27#include <linux/can/dev.h>
  28#include <linux/can/error.h>
  29#include <linux/can/platform/cc770.h>
  30
  31#include "cc770.h"
  32
  33MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
  34MODULE_LICENSE("GPL v2");
  35MODULE_DESCRIPTION(KBUILD_MODNAME "CAN netdevice driver");
  36
  37/*
  38 * The CC770 is a CAN controller from Bosch, which is 100% compatible
  39 * with the AN82527 from Intel, but with "bugs" being fixed and some
  40 * additional functionality, mainly:
  41 *
  42 * 1. RX and TX error counters are readable.
  43 * 2. Support of silent (listen-only) mode.
  44 * 3. Message object 15 can receive all types of frames, also RTR and EFF.
  45 *
  46 * Details are available from Bosch's "CC770_Product_Info_2007-01.pdf",
  47 * which explains in detail the compatibility between the CC770 and the
  48 * 82527. This driver use the additional functionality 3. on real CC770
  49 * devices. Unfortunately, the CC770 does still not store the message
  50 * identifier of received remote transmission request frames and
  51 * therefore it's set to 0.
  52 *
  53 * The message objects 1..14 can be used for TX and RX while the message
  54 * objects 15 is optimized for RX. It has a shadow register for reliable
  55 * data reception under heavy bus load. Therefore it makes sense to use
  56 * this message object for the needed use case. The frame type (EFF/SFF)
  57 * for the message object 15 can be defined via kernel module parameter
  58 * "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames,
  59 * otherwise 11 bit SFF messages.
  60 */
  61static int msgobj15_eff;
  62module_param(msgobj15_eff, int, 0444);
  63MODULE_PARM_DESC(msgobj15_eff, "Extended 29-bit frames for message object 15 "
  64                 "(default: 11-bit standard frames)");
  65
  66static int i82527_compat;
  67module_param(i82527_compat, int, 0444);
  68MODULE_PARM_DESC(i82527_compat, "Strict Intel 82527 compatibility mode "
  69                 "without using additional functions");
  70
  71/*
  72 * This driver uses the last 5 message objects 11..15. The definitions
  73 * and structure below allows to configure and assign them to the real
  74 * message object.
  75 */
  76static unsigned char cc770_obj_flags[CC770_OBJ_MAX] = {
  77        [CC770_OBJ_RX0] = CC770_OBJ_FLAG_RX,
  78        [CC770_OBJ_RX1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_EFF,
  79        [CC770_OBJ_RX_RTR0] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR,
  80        [CC770_OBJ_RX_RTR1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR |
  81                              CC770_OBJ_FLAG_EFF,
  82        [CC770_OBJ_TX] = 0,
  83};
  84
  85static const struct can_bittiming_const cc770_bittiming_const = {
  86        .name = KBUILD_MODNAME,
  87        .tseg1_min = 1,
  88        .tseg1_max = 16,
  89        .tseg2_min = 1,
  90        .tseg2_max = 8,
  91        .sjw_max = 4,
  92        .brp_min = 1,
  93        .brp_max = 64,
  94        .brp_inc = 1,
  95};
  96
  97static inline int intid2obj(unsigned int intid)
  98{
  99        if (intid == 2)
 100                return 0;
 101        else
 102                return MSGOBJ_LAST + 2 - intid;
 103}
 104
 105static void enable_all_objs(const struct net_device *dev)
 106{
 107        struct cc770_priv *priv = netdev_priv(dev);
 108        u8 msgcfg;
 109        unsigned char obj_flags;
 110        unsigned int o, mo;
 111
 112        for (o = 0; o < ARRAY_SIZE(priv->obj_flags); o++) {
 113                obj_flags = priv->obj_flags[o];
 114                mo = obj2msgobj(o);
 115
 116                if (obj_flags & CC770_OBJ_FLAG_RX) {
 117                        /*
 118                         * We don't need extra objects for RTR and EFF if
 119                         * the additional CC770 functions are enabled.
 120                         */
 121                        if (priv->control_normal_mode & CTRL_EAF) {
 122                                if (o > 0)
 123                                        continue;
 124                                netdev_dbg(dev, "Message object %d for "
 125                                           "RX data, RTR, SFF and EFF\n", mo);
 126                        } else {
 127                                netdev_dbg(dev,
 128                                           "Message object %d for RX %s %s\n",
 129                                           mo, obj_flags & CC770_OBJ_FLAG_RTR ?
 130                                           "RTR" : "data",
 131                                           obj_flags & CC770_OBJ_FLAG_EFF ?
 132                                           "EFF" : "SFF");
 133                        }
 134
 135                        if (obj_flags & CC770_OBJ_FLAG_EFF)
 136                                msgcfg = MSGCFG_XTD;
 137                        else
 138                                msgcfg = 0;
 139                        if (obj_flags & CC770_OBJ_FLAG_RTR)
 140                                msgcfg |= MSGCFG_DIR;
 141
 142                        cc770_write_reg(priv, msgobj[mo].config, msgcfg);
 143                        cc770_write_reg(priv, msgobj[mo].ctrl0,
 144                                        MSGVAL_SET | TXIE_RES |
 145                                        RXIE_SET | INTPND_RES);
 146
 147                        if (obj_flags & CC770_OBJ_FLAG_RTR)
 148                                cc770_write_reg(priv, msgobj[mo].ctrl1,
 149                                                NEWDAT_RES | CPUUPD_SET |
 150                                                TXRQST_RES | RMTPND_RES);
 151                        else
 152                                cc770_write_reg(priv, msgobj[mo].ctrl1,
 153                                                NEWDAT_RES | MSGLST_RES |
 154                                                TXRQST_RES | RMTPND_RES);
 155                } else {
 156                        netdev_dbg(dev, "Message object %d for "
 157                                   "TX data, RTR, SFF and EFF\n", mo);
 158
 159                        cc770_write_reg(priv, msgobj[mo].ctrl1,
 160                                        RMTPND_RES | TXRQST_RES |
 161                                        CPUUPD_RES | NEWDAT_RES);
 162                        cc770_write_reg(priv, msgobj[mo].ctrl0,
 163                                        MSGVAL_RES | TXIE_RES |
 164                                        RXIE_RES | INTPND_RES);
 165                }
 166        }
 167}
 168
 169static void disable_all_objs(const struct cc770_priv *priv)
 170{
 171        int o, mo;
 172
 173        for (o = 0; o <  ARRAY_SIZE(priv->obj_flags); o++) {
 174                mo = obj2msgobj(o);
 175
 176                if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX) {
 177                        if (o > 0 && priv->control_normal_mode & CTRL_EAF)
 178                                continue;
 179
 180                        cc770_write_reg(priv, msgobj[mo].ctrl1,
 181                                        NEWDAT_RES | MSGLST_RES |
 182                                        TXRQST_RES | RMTPND_RES);
 183                        cc770_write_reg(priv, msgobj[mo].ctrl0,
 184                                        MSGVAL_RES | TXIE_RES |
 185                                        RXIE_RES | INTPND_RES);
 186                } else {
 187                        /* Clear message object for send */
 188                        cc770_write_reg(priv, msgobj[mo].ctrl1,
 189                                        RMTPND_RES | TXRQST_RES |
 190                                        CPUUPD_RES | NEWDAT_RES);
 191                        cc770_write_reg(priv, msgobj[mo].ctrl0,
 192                                        MSGVAL_RES | TXIE_RES |
 193                                        RXIE_RES | INTPND_RES);
 194                }
 195        }
 196}
 197
 198static void set_reset_mode(struct net_device *dev)
 199{
 200        struct cc770_priv *priv = netdev_priv(dev);
 201
 202        /* Enable configuration and puts chip in bus-off, disable interrupts */
 203        cc770_write_reg(priv, control, CTRL_CCE | CTRL_INI);
 204
 205        priv->can.state = CAN_STATE_STOPPED;
 206
 207        /* Clear interrupts */
 208        cc770_read_reg(priv, interrupt);
 209
 210        /* Clear status register */
 211        cc770_write_reg(priv, status, 0);
 212
 213        /* Disable all used message objects */
 214        disable_all_objs(priv);
 215}
 216
 217static void set_normal_mode(struct net_device *dev)
 218{
 219        struct cc770_priv *priv = netdev_priv(dev);
 220
 221        /* Clear interrupts */
 222        cc770_read_reg(priv, interrupt);
 223
 224        /* Clear status register and pre-set last error code */
 225        cc770_write_reg(priv, status, STAT_LEC_MASK);
 226
 227        /* Enable all used message objects*/
 228        enable_all_objs(dev);
 229
 230        /*
 231         * Clear bus-off, interrupts only for errors,
 232         * not for status change
 233         */
 234        cc770_write_reg(priv, control, priv->control_normal_mode);
 235
 236        priv->can.state = CAN_STATE_ERROR_ACTIVE;
 237}
 238
 239static void chipset_init(struct cc770_priv *priv)
 240{
 241        int mo, id, data;
 242
 243        /* Enable configuration and put chip in bus-off, disable interrupts */
 244        cc770_write_reg(priv, control, (CTRL_CCE | CTRL_INI));
 245
 246        /* Set CLKOUT divider and slew rates */
 247        cc770_write_reg(priv, clkout, priv->clkout);
 248
 249        /* Configure CPU interface / CLKOUT enable */
 250        cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
 251
 252        /* Set bus configuration  */
 253        cc770_write_reg(priv, bus_config, priv->bus_config);
 254
 255        /* Clear interrupts */
 256        cc770_read_reg(priv, interrupt);
 257
 258        /* Clear status register */
 259        cc770_write_reg(priv, status, 0);
 260
 261        /* Clear and invalidate message objects */
 262        for (mo = MSGOBJ_FIRST; mo <= MSGOBJ_LAST; mo++) {
 263                cc770_write_reg(priv, msgobj[mo].ctrl0,
 264                                INTPND_UNC | RXIE_RES |
 265                                TXIE_RES | MSGVAL_RES);
 266                cc770_write_reg(priv, msgobj[mo].ctrl0,
 267                                INTPND_RES | RXIE_RES |
 268                                TXIE_RES | MSGVAL_RES);
 269                cc770_write_reg(priv, msgobj[mo].ctrl1,
 270                                NEWDAT_RES | MSGLST_RES |
 271                                TXRQST_RES | RMTPND_RES);
 272                for (data = 0; data < 8; data++)
 273                        cc770_write_reg(priv, msgobj[mo].data[data], 0);
 274                for (id = 0; id < 4; id++)
 275                        cc770_write_reg(priv, msgobj[mo].id[id], 0);
 276                cc770_write_reg(priv, msgobj[mo].config, 0);
 277        }
 278
 279        /* Set all global ID masks to "don't care" */
 280        cc770_write_reg(priv, global_mask_std[0], 0);
 281        cc770_write_reg(priv, global_mask_std[1], 0);
 282        cc770_write_reg(priv, global_mask_ext[0], 0);
 283        cc770_write_reg(priv, global_mask_ext[1], 0);
 284        cc770_write_reg(priv, global_mask_ext[2], 0);
 285        cc770_write_reg(priv, global_mask_ext[3], 0);
 286
 287}
 288
 289static int cc770_probe_chip(struct net_device *dev)
 290{
 291        struct cc770_priv *priv = netdev_priv(dev);
 292
 293        /* Enable configuration, put chip in bus-off, disable ints */
 294        cc770_write_reg(priv, control, CTRL_CCE | CTRL_EAF | CTRL_INI);
 295        /* Configure cpu interface / CLKOUT disable */
 296        cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
 297
 298        /*
 299         * Check if hardware reset is still inactive or maybe there
 300         * is no chip in this address space
 301         */
 302        if (cc770_read_reg(priv, cpu_interface) & CPUIF_RST) {
 303                netdev_info(dev, "probing @0x%p failed (reset)\n",
 304                            priv->reg_base);
 305                return -ENODEV;
 306        }
 307
 308        /* Write and read back test pattern (some arbitrary values) */
 309        cc770_write_reg(priv, msgobj[1].data[1], 0x25);
 310        cc770_write_reg(priv, msgobj[2].data[3], 0x52);
 311        cc770_write_reg(priv, msgobj[10].data[6], 0xc3);
 312        if ((cc770_read_reg(priv, msgobj[1].data[1]) != 0x25) ||
 313            (cc770_read_reg(priv, msgobj[2].data[3]) != 0x52) ||
 314            (cc770_read_reg(priv, msgobj[10].data[6]) != 0xc3)) {
 315                netdev_info(dev, "probing @0x%p failed (pattern)\n",
 316                            priv->reg_base);
 317                return -ENODEV;
 318        }
 319
 320        /* Check if this chip is a CC770 supporting additional functions */
 321        if (cc770_read_reg(priv, control) & CTRL_EAF)
 322                priv->control_normal_mode |= CTRL_EAF;
 323
 324        return 0;
 325}
 326
 327static void cc770_start(struct net_device *dev)
 328{
 329        struct cc770_priv *priv = netdev_priv(dev);
 330
 331        /* leave reset mode */
 332        if (priv->can.state != CAN_STATE_STOPPED)
 333                set_reset_mode(dev);
 334
 335        /* leave reset mode */
 336        set_normal_mode(dev);
 337}
 338
 339static int cc770_set_mode(struct net_device *dev, enum can_mode mode)
 340{
 341        switch (mode) {
 342        case CAN_MODE_START:
 343                cc770_start(dev);
 344                netif_wake_queue(dev);
 345                break;
 346
 347        default:
 348                return -EOPNOTSUPP;
 349        }
 350
 351        return 0;
 352}
 353
 354static int cc770_set_bittiming(struct net_device *dev)
 355{
 356        struct cc770_priv *priv = netdev_priv(dev);
 357        struct can_bittiming *bt = &priv->can.bittiming;
 358        u8 btr0, btr1;
 359
 360        btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
 361        btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
 362                (((bt->phase_seg2 - 1) & 0x7) << 4);
 363        if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
 364                btr1 |= 0x80;
 365
 366        netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
 367
 368        cc770_write_reg(priv, bit_timing_0, btr0);
 369        cc770_write_reg(priv, bit_timing_1, btr1);
 370
 371        return 0;
 372}
 373
 374static int cc770_get_berr_counter(const struct net_device *dev,
 375                                  struct can_berr_counter *bec)
 376{
 377        struct cc770_priv *priv = netdev_priv(dev);
 378
 379        bec->txerr = cc770_read_reg(priv, tx_error_counter);
 380        bec->rxerr = cc770_read_reg(priv, rx_error_counter);
 381
 382        return 0;
 383}
 384
 385static void cc770_tx(struct net_device *dev, int mo)
 386{
 387        struct cc770_priv *priv = netdev_priv(dev);
 388        struct can_frame *cf = (struct can_frame *)priv->tx_skb->data;
 389        u8 dlc, rtr;
 390        u32 id;
 391        int i;
 392
 393        dlc = cf->len;
 394        id = cf->can_id;
 395        rtr = cf->can_id & CAN_RTR_FLAG ? 0 : MSGCFG_DIR;
 396
 397        cc770_write_reg(priv, msgobj[mo].ctrl0,
 398                        MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
 399        cc770_write_reg(priv, msgobj[mo].ctrl1,
 400                        RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES);
 401
 402        if (id & CAN_EFF_FLAG) {
 403                id &= CAN_EFF_MASK;
 404                cc770_write_reg(priv, msgobj[mo].config,
 405                                (dlc << 4) | rtr | MSGCFG_XTD);
 406                cc770_write_reg(priv, msgobj[mo].id[3], id << 3);
 407                cc770_write_reg(priv, msgobj[mo].id[2], id >> 5);
 408                cc770_write_reg(priv, msgobj[mo].id[1], id >> 13);
 409                cc770_write_reg(priv, msgobj[mo].id[0], id >> 21);
 410        } else {
 411                id &= CAN_SFF_MASK;
 412                cc770_write_reg(priv, msgobj[mo].config, (dlc << 4) | rtr);
 413                cc770_write_reg(priv, msgobj[mo].id[0], id >> 3);
 414                cc770_write_reg(priv, msgobj[mo].id[1], id << 5);
 415        }
 416
 417        for (i = 0; i < dlc; i++)
 418                cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
 419
 420        cc770_write_reg(priv, msgobj[mo].ctrl1,
 421                        RMTPND_UNC | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
 422        cc770_write_reg(priv, msgobj[mo].ctrl0,
 423                        MSGVAL_SET | TXIE_SET | RXIE_SET | INTPND_UNC);
 424}
 425
 426static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
 427{
 428        struct cc770_priv *priv = netdev_priv(dev);
 429        unsigned int mo = obj2msgobj(CC770_OBJ_TX);
 430
 431        if (can_dropped_invalid_skb(dev, skb))
 432                return NETDEV_TX_OK;
 433
 434        netif_stop_queue(dev);
 435
 436        if ((cc770_read_reg(priv,
 437                            msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
 438                netdev_err(dev, "TX register is still occupied!\n");
 439                return NETDEV_TX_BUSY;
 440        }
 441
 442        priv->tx_skb = skb;
 443        cc770_tx(dev, mo);
 444
 445        return NETDEV_TX_OK;
 446}
 447
 448static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
 449{
 450        struct cc770_priv *priv = netdev_priv(dev);
 451        struct net_device_stats *stats = &dev->stats;
 452        struct can_frame *cf;
 453        struct sk_buff *skb;
 454        u8 config;
 455        u32 id;
 456        int i;
 457
 458        skb = alloc_can_skb(dev, &cf);
 459        if (!skb)
 460                return;
 461
 462        config = cc770_read_reg(priv, msgobj[mo].config);
 463
 464        if (ctrl1 & RMTPND_SET) {
 465                /*
 466                 * Unfortunately, the chip does not store the real message
 467                 * identifier of the received remote transmission request
 468                 * frame. Therefore we set it to 0.
 469                 */
 470                cf->can_id = CAN_RTR_FLAG;
 471                if (config & MSGCFG_XTD)
 472                        cf->can_id |= CAN_EFF_FLAG;
 473                cf->len = 0;
 474        } else {
 475                if (config & MSGCFG_XTD) {
 476                        id = cc770_read_reg(priv, msgobj[mo].id[3]);
 477                        id |= cc770_read_reg(priv, msgobj[mo].id[2]) << 8;
 478                        id |= cc770_read_reg(priv, msgobj[mo].id[1]) << 16;
 479                        id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 24;
 480                        id >>= 3;
 481                        id |= CAN_EFF_FLAG;
 482                } else {
 483                        id = cc770_read_reg(priv, msgobj[mo].id[1]);
 484                        id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 8;
 485                        id >>= 5;
 486                }
 487
 488                cf->can_id = id;
 489                cf->len = can_cc_dlc2len((config & 0xf0) >> 4);
 490                for (i = 0; i < cf->len; i++)
 491                        cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]);
 492        }
 493
 494        stats->rx_packets++;
 495        stats->rx_bytes += cf->len;
 496        netif_rx(skb);
 497}
 498
 499static int cc770_err(struct net_device *dev, u8 status)
 500{
 501        struct cc770_priv *priv = netdev_priv(dev);
 502        struct net_device_stats *stats = &dev->stats;
 503        struct can_frame *cf;
 504        struct sk_buff *skb;
 505        u8 lec;
 506
 507        netdev_dbg(dev, "status interrupt (%#x)\n", status);
 508
 509        skb = alloc_can_err_skb(dev, &cf);
 510        if (!skb)
 511                return -ENOMEM;
 512
 513        /* Use extended functions of the CC770 */
 514        if (priv->control_normal_mode & CTRL_EAF) {
 515                cf->data[6] = cc770_read_reg(priv, tx_error_counter);
 516                cf->data[7] = cc770_read_reg(priv, rx_error_counter);
 517        }
 518
 519        if (status & STAT_BOFF) {
 520                /* Disable interrupts */
 521                cc770_write_reg(priv, control, CTRL_INI);
 522                cf->can_id |= CAN_ERR_BUSOFF;
 523                priv->can.state = CAN_STATE_BUS_OFF;
 524                priv->can.can_stats.bus_off++;
 525                can_bus_off(dev);
 526        } else if (status & STAT_WARN) {
 527                cf->can_id |= CAN_ERR_CRTL;
 528                /* Only the CC770 does show error passive */
 529                if (cf->data[7] > 127) {
 530                        cf->data[1] = CAN_ERR_CRTL_RX_PASSIVE |
 531                                CAN_ERR_CRTL_TX_PASSIVE;
 532                        priv->can.state = CAN_STATE_ERROR_PASSIVE;
 533                        priv->can.can_stats.error_passive++;
 534                } else {
 535                        cf->data[1] = CAN_ERR_CRTL_RX_WARNING |
 536                                CAN_ERR_CRTL_TX_WARNING;
 537                        priv->can.state = CAN_STATE_ERROR_WARNING;
 538                        priv->can.can_stats.error_warning++;
 539                }
 540        } else {
 541                /* Back to error active */
 542                cf->can_id |= CAN_ERR_PROT;
 543                cf->data[2] = CAN_ERR_PROT_ACTIVE;
 544                priv->can.state = CAN_STATE_ERROR_ACTIVE;
 545        }
 546
 547        lec = status & STAT_LEC_MASK;
 548        if (lec < 7 && lec > 0) {
 549                if (lec == STAT_LEC_ACK) {
 550                        cf->can_id |= CAN_ERR_ACK;
 551                } else {
 552                        cf->can_id |= CAN_ERR_PROT;
 553                        switch (lec) {
 554                        case STAT_LEC_STUFF:
 555                                cf->data[2] |= CAN_ERR_PROT_STUFF;
 556                                break;
 557                        case STAT_LEC_FORM:
 558                                cf->data[2] |= CAN_ERR_PROT_FORM;
 559                                break;
 560                        case STAT_LEC_BIT1:
 561                                cf->data[2] |= CAN_ERR_PROT_BIT1;
 562                                break;
 563                        case STAT_LEC_BIT0:
 564                                cf->data[2] |= CAN_ERR_PROT_BIT0;
 565                                break;
 566                        case STAT_LEC_CRC:
 567                                cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
 568                                break;
 569                        }
 570                }
 571        }
 572
 573
 574        stats->rx_packets++;
 575        stats->rx_bytes += cf->len;
 576        netif_rx(skb);
 577
 578        return 0;
 579}
 580
 581static int cc770_status_interrupt(struct net_device *dev)
 582{
 583        struct cc770_priv *priv = netdev_priv(dev);
 584        u8 status;
 585
 586        status = cc770_read_reg(priv, status);
 587        /* Reset the status register including RXOK and TXOK */
 588        cc770_write_reg(priv, status, STAT_LEC_MASK);
 589
 590        if (status & (STAT_WARN | STAT_BOFF) ||
 591            (status & STAT_LEC_MASK) != STAT_LEC_MASK) {
 592                cc770_err(dev, status);
 593                return status & STAT_BOFF;
 594        }
 595
 596        return 0;
 597}
 598
 599static void cc770_rx_interrupt(struct net_device *dev, unsigned int o)
 600{
 601        struct cc770_priv *priv = netdev_priv(dev);
 602        struct net_device_stats *stats = &dev->stats;
 603        unsigned int mo = obj2msgobj(o);
 604        u8 ctrl1;
 605        int n = CC770_MAX_MSG;
 606
 607        while (n--) {
 608                ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
 609
 610                if (!(ctrl1 & NEWDAT_SET))  {
 611                        /* Check for RTR if additional functions are enabled */
 612                        if (priv->control_normal_mode & CTRL_EAF) {
 613                                if (!(cc770_read_reg(priv, msgobj[mo].ctrl0) &
 614                                      INTPND_SET))
 615                                        break;
 616                        } else {
 617                                break;
 618                        }
 619                }
 620
 621                if (ctrl1 & MSGLST_SET) {
 622                        stats->rx_over_errors++;
 623                        stats->rx_errors++;
 624                }
 625                if (mo < MSGOBJ_LAST)
 626                        cc770_write_reg(priv, msgobj[mo].ctrl1,
 627                                        NEWDAT_RES | MSGLST_RES |
 628                                        TXRQST_UNC | RMTPND_UNC);
 629                cc770_rx(dev, mo, ctrl1);
 630
 631                cc770_write_reg(priv, msgobj[mo].ctrl0,
 632                                MSGVAL_SET | TXIE_RES |
 633                                RXIE_SET | INTPND_RES);
 634                cc770_write_reg(priv, msgobj[mo].ctrl1,
 635                                NEWDAT_RES | MSGLST_RES |
 636                                TXRQST_RES | RMTPND_RES);
 637        }
 638}
 639
 640static void cc770_rtr_interrupt(struct net_device *dev, unsigned int o)
 641{
 642        struct cc770_priv *priv = netdev_priv(dev);
 643        unsigned int mo = obj2msgobj(o);
 644        u8 ctrl0, ctrl1;
 645        int n = CC770_MAX_MSG;
 646
 647        while (n--) {
 648                ctrl0 = cc770_read_reg(priv, msgobj[mo].ctrl0);
 649                if (!(ctrl0 & INTPND_SET))
 650                        break;
 651
 652                ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
 653                cc770_rx(dev, mo, ctrl1);
 654
 655                cc770_write_reg(priv, msgobj[mo].ctrl0,
 656                                MSGVAL_SET | TXIE_RES |
 657                                RXIE_SET | INTPND_RES);
 658                cc770_write_reg(priv, msgobj[mo].ctrl1,
 659                                NEWDAT_RES | CPUUPD_SET |
 660                                TXRQST_RES | RMTPND_RES);
 661        }
 662}
 663
 664static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
 665{
 666        struct cc770_priv *priv = netdev_priv(dev);
 667        struct net_device_stats *stats = &dev->stats;
 668        unsigned int mo = obj2msgobj(o);
 669        struct can_frame *cf;
 670        u8 ctrl1;
 671
 672        ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
 673
 674        cc770_write_reg(priv, msgobj[mo].ctrl0,
 675                        MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
 676        cc770_write_reg(priv, msgobj[mo].ctrl1,
 677                        RMTPND_RES | TXRQST_RES | MSGLST_RES | NEWDAT_RES);
 678
 679        if (unlikely(!priv->tx_skb)) {
 680                netdev_err(dev, "missing tx skb in tx interrupt\n");
 681                return;
 682        }
 683
 684        if (unlikely(ctrl1 & MSGLST_SET)) {
 685                stats->rx_over_errors++;
 686                stats->rx_errors++;
 687        }
 688
 689        /* When the CC770 is sending an RTR message and it receives a regular
 690         * message that matches the id of the RTR message, it will overwrite the
 691         * outgoing message in the TX register. When this happens we must
 692         * process the received message and try to transmit the outgoing skb
 693         * again.
 694         */
 695        if (unlikely(ctrl1 & NEWDAT_SET)) {
 696                cc770_rx(dev, mo, ctrl1);
 697                cc770_tx(dev, mo);
 698                return;
 699        }
 700
 701        cf = (struct can_frame *)priv->tx_skb->data;
 702        stats->tx_bytes += cf->len;
 703        stats->tx_packets++;
 704
 705        can_put_echo_skb(priv->tx_skb, dev, 0, 0);
 706        can_get_echo_skb(dev, 0, NULL);
 707        priv->tx_skb = NULL;
 708
 709        netif_wake_queue(dev);
 710}
 711
 712static irqreturn_t cc770_interrupt(int irq, void *dev_id)
 713{
 714        struct net_device *dev = (struct net_device *)dev_id;
 715        struct cc770_priv *priv = netdev_priv(dev);
 716        u8 intid;
 717        int o, n = 0;
 718
 719        /* Shared interrupts and IRQ off? */
 720        if (priv->can.state == CAN_STATE_STOPPED)
 721                return IRQ_NONE;
 722
 723        if (priv->pre_irq)
 724                priv->pre_irq(priv);
 725
 726        while (n < CC770_MAX_IRQ) {
 727                /* Read the highest pending interrupt request */
 728                intid = cc770_read_reg(priv, interrupt);
 729                if (!intid)
 730                        break;
 731                n++;
 732
 733                if (intid == 1) {
 734                        /* Exit in case of bus-off */
 735                        if (cc770_status_interrupt(dev))
 736                                break;
 737                } else {
 738                        o = intid2obj(intid);
 739
 740                        if (o >= CC770_OBJ_MAX) {
 741                                netdev_err(dev, "Unexpected interrupt id %d\n",
 742                                           intid);
 743                                continue;
 744                        }
 745
 746                        if (priv->obj_flags[o] & CC770_OBJ_FLAG_RTR)
 747                                cc770_rtr_interrupt(dev, o);
 748                        else if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX)
 749                                cc770_rx_interrupt(dev, o);
 750                        else
 751                                cc770_tx_interrupt(dev, o);
 752                }
 753        }
 754
 755        if (priv->post_irq)
 756                priv->post_irq(priv);
 757
 758        if (n >= CC770_MAX_IRQ)
 759                netdev_dbg(dev, "%d messages handled in ISR", n);
 760
 761        return (n) ? IRQ_HANDLED : IRQ_NONE;
 762}
 763
 764static int cc770_open(struct net_device *dev)
 765{
 766        struct cc770_priv *priv = netdev_priv(dev);
 767        int err;
 768
 769        /* set chip into reset mode */
 770        set_reset_mode(dev);
 771
 772        /* common open */
 773        err = open_candev(dev);
 774        if (err)
 775                return err;
 776
 777        err = request_irq(dev->irq, &cc770_interrupt, priv->irq_flags,
 778                          dev->name, dev);
 779        if (err) {
 780                close_candev(dev);
 781                return -EAGAIN;
 782        }
 783
 784        /* init and start chip */
 785        cc770_start(dev);
 786
 787        netif_start_queue(dev);
 788
 789        return 0;
 790}
 791
 792static int cc770_close(struct net_device *dev)
 793{
 794        netif_stop_queue(dev);
 795        set_reset_mode(dev);
 796
 797        free_irq(dev->irq, dev);
 798        close_candev(dev);
 799
 800        return 0;
 801}
 802
 803struct net_device *alloc_cc770dev(int sizeof_priv)
 804{
 805        struct net_device *dev;
 806        struct cc770_priv *priv;
 807
 808        dev = alloc_candev(sizeof(struct cc770_priv) + sizeof_priv,
 809                           CC770_ECHO_SKB_MAX);
 810        if (!dev)
 811                return NULL;
 812
 813        priv = netdev_priv(dev);
 814
 815        priv->dev = dev;
 816        priv->can.bittiming_const = &cc770_bittiming_const;
 817        priv->can.do_set_bittiming = cc770_set_bittiming;
 818        priv->can.do_set_mode = cc770_set_mode;
 819        priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 820        priv->tx_skb = NULL;
 821
 822        memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags));
 823
 824        if (sizeof_priv)
 825                priv->priv = (void *)priv + sizeof(struct cc770_priv);
 826
 827        return dev;
 828}
 829EXPORT_SYMBOL_GPL(alloc_cc770dev);
 830
 831void free_cc770dev(struct net_device *dev)
 832{
 833        free_candev(dev);
 834}
 835EXPORT_SYMBOL_GPL(free_cc770dev);
 836
 837static const struct net_device_ops cc770_netdev_ops = {
 838        .ndo_open = cc770_open,
 839        .ndo_stop = cc770_close,
 840        .ndo_start_xmit = cc770_start_xmit,
 841        .ndo_change_mtu = can_change_mtu,
 842};
 843
 844int register_cc770dev(struct net_device *dev)
 845{
 846        struct cc770_priv *priv = netdev_priv(dev);
 847        int err;
 848
 849        err = cc770_probe_chip(dev);
 850        if (err)
 851                return err;
 852
 853        dev->netdev_ops = &cc770_netdev_ops;
 854
 855        dev->flags |= IFF_ECHO; /* we support local echo */
 856
 857        /* Should we use additional functions? */
 858        if (!i82527_compat && priv->control_normal_mode & CTRL_EAF) {
 859                priv->can.do_get_berr_counter = cc770_get_berr_counter;
 860                priv->control_normal_mode = CTRL_IE | CTRL_EAF | CTRL_EIE;
 861                netdev_dbg(dev, "i82527 mode with additional functions\n");
 862        } else {
 863                priv->control_normal_mode = CTRL_IE | CTRL_EIE;
 864                netdev_dbg(dev, "strict i82527 compatibility mode\n");
 865        }
 866
 867        chipset_init(priv);
 868        set_reset_mode(dev);
 869
 870        return register_candev(dev);
 871}
 872EXPORT_SYMBOL_GPL(register_cc770dev);
 873
 874void unregister_cc770dev(struct net_device *dev)
 875{
 876        set_reset_mode(dev);
 877        unregister_candev(dev);
 878}
 879EXPORT_SYMBOL_GPL(unregister_cc770dev);
 880
 881static __init int cc770_init(void)
 882{
 883        if (msgobj15_eff) {
 884                cc770_obj_flags[CC770_OBJ_RX0] |= CC770_OBJ_FLAG_EFF;
 885                cc770_obj_flags[CC770_OBJ_RX1] &= ~CC770_OBJ_FLAG_EFF;
 886        }
 887
 888        pr_info("CAN netdevice driver\n");
 889
 890        return 0;
 891}
 892module_init(cc770_init);
 893
 894static __exit void cc770_exit(void)
 895{
 896        pr_info("driver removed\n");
 897}
 898module_exit(cc770_exit);
 899