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