cc770.c (23011B)
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 stats->rx_bytes += cf->len; 494 } 495 stats->rx_packets++; 496 497 netif_rx(skb); 498} 499 500static int cc770_err(struct net_device *dev, u8 status) 501{ 502 struct cc770_priv *priv = netdev_priv(dev); 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 netif_rx(skb); 575 576 return 0; 577} 578 579static int cc770_status_interrupt(struct net_device *dev) 580{ 581 struct cc770_priv *priv = netdev_priv(dev); 582 u8 status; 583 584 status = cc770_read_reg(priv, status); 585 /* Reset the status register including RXOK and TXOK */ 586 cc770_write_reg(priv, status, STAT_LEC_MASK); 587 588 if (status & (STAT_WARN | STAT_BOFF) || 589 (status & STAT_LEC_MASK) != STAT_LEC_MASK) { 590 cc770_err(dev, status); 591 return status & STAT_BOFF; 592 } 593 594 return 0; 595} 596 597static void cc770_rx_interrupt(struct net_device *dev, unsigned int o) 598{ 599 struct cc770_priv *priv = netdev_priv(dev); 600 struct net_device_stats *stats = &dev->stats; 601 unsigned int mo = obj2msgobj(o); 602 u8 ctrl1; 603 int n = CC770_MAX_MSG; 604 605 while (n--) { 606 ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1); 607 608 if (!(ctrl1 & NEWDAT_SET)) { 609 /* Check for RTR if additional functions are enabled */ 610 if (priv->control_normal_mode & CTRL_EAF) { 611 if (!(cc770_read_reg(priv, msgobj[mo].ctrl0) & 612 INTPND_SET)) 613 break; 614 } else { 615 break; 616 } 617 } 618 619 if (ctrl1 & MSGLST_SET) { 620 stats->rx_over_errors++; 621 stats->rx_errors++; 622 } 623 if (mo < MSGOBJ_LAST) 624 cc770_write_reg(priv, msgobj[mo].ctrl1, 625 NEWDAT_RES | MSGLST_RES | 626 TXRQST_UNC | RMTPND_UNC); 627 cc770_rx(dev, mo, ctrl1); 628 629 cc770_write_reg(priv, msgobj[mo].ctrl0, 630 MSGVAL_SET | TXIE_RES | 631 RXIE_SET | INTPND_RES); 632 cc770_write_reg(priv, msgobj[mo].ctrl1, 633 NEWDAT_RES | MSGLST_RES | 634 TXRQST_RES | RMTPND_RES); 635 } 636} 637 638static void cc770_rtr_interrupt(struct net_device *dev, unsigned int o) 639{ 640 struct cc770_priv *priv = netdev_priv(dev); 641 unsigned int mo = obj2msgobj(o); 642 u8 ctrl0, ctrl1; 643 int n = CC770_MAX_MSG; 644 645 while (n--) { 646 ctrl0 = cc770_read_reg(priv, msgobj[mo].ctrl0); 647 if (!(ctrl0 & INTPND_SET)) 648 break; 649 650 ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1); 651 cc770_rx(dev, mo, ctrl1); 652 653 cc770_write_reg(priv, msgobj[mo].ctrl0, 654 MSGVAL_SET | TXIE_RES | 655 RXIE_SET | INTPND_RES); 656 cc770_write_reg(priv, msgobj[mo].ctrl1, 657 NEWDAT_RES | CPUUPD_SET | 658 TXRQST_RES | RMTPND_RES); 659 } 660} 661 662static void cc770_tx_interrupt(struct net_device *dev, unsigned int o) 663{ 664 struct cc770_priv *priv = netdev_priv(dev); 665 struct net_device_stats *stats = &dev->stats; 666 unsigned int mo = obj2msgobj(o); 667 u8 ctrl1; 668 669 ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1); 670 671 cc770_write_reg(priv, msgobj[mo].ctrl0, 672 MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); 673 cc770_write_reg(priv, msgobj[mo].ctrl1, 674 RMTPND_RES | TXRQST_RES | MSGLST_RES | NEWDAT_RES); 675 676 if (unlikely(!priv->tx_skb)) { 677 netdev_err(dev, "missing tx skb in tx interrupt\n"); 678 return; 679 } 680 681 if (unlikely(ctrl1 & MSGLST_SET)) { 682 stats->rx_over_errors++; 683 stats->rx_errors++; 684 } 685 686 /* When the CC770 is sending an RTR message and it receives a regular 687 * message that matches the id of the RTR message, it will overwrite the 688 * outgoing message in the TX register. When this happens we must 689 * process the received message and try to transmit the outgoing skb 690 * again. 691 */ 692 if (unlikely(ctrl1 & NEWDAT_SET)) { 693 cc770_rx(dev, mo, ctrl1); 694 cc770_tx(dev, mo); 695 return; 696 } 697 698 can_put_echo_skb(priv->tx_skb, dev, 0, 0); 699 stats->tx_bytes += can_get_echo_skb(dev, 0, NULL); 700 stats->tx_packets++; 701 priv->tx_skb = NULL; 702 703 netif_wake_queue(dev); 704} 705 706static irqreturn_t cc770_interrupt(int irq, void *dev_id) 707{ 708 struct net_device *dev = (struct net_device *)dev_id; 709 struct cc770_priv *priv = netdev_priv(dev); 710 u8 intid; 711 int o, n = 0; 712 713 /* Shared interrupts and IRQ off? */ 714 if (priv->can.state == CAN_STATE_STOPPED) 715 return IRQ_NONE; 716 717 if (priv->pre_irq) 718 priv->pre_irq(priv); 719 720 while (n < CC770_MAX_IRQ) { 721 /* Read the highest pending interrupt request */ 722 intid = cc770_read_reg(priv, interrupt); 723 if (!intid) 724 break; 725 n++; 726 727 if (intid == 1) { 728 /* Exit in case of bus-off */ 729 if (cc770_status_interrupt(dev)) 730 break; 731 } else { 732 o = intid2obj(intid); 733 734 if (o >= CC770_OBJ_MAX) { 735 netdev_err(dev, "Unexpected interrupt id %d\n", 736 intid); 737 continue; 738 } 739 740 if (priv->obj_flags[o] & CC770_OBJ_FLAG_RTR) 741 cc770_rtr_interrupt(dev, o); 742 else if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX) 743 cc770_rx_interrupt(dev, o); 744 else 745 cc770_tx_interrupt(dev, o); 746 } 747 } 748 749 if (priv->post_irq) 750 priv->post_irq(priv); 751 752 if (n >= CC770_MAX_IRQ) 753 netdev_dbg(dev, "%d messages handled in ISR", n); 754 755 return (n) ? IRQ_HANDLED : IRQ_NONE; 756} 757 758static int cc770_open(struct net_device *dev) 759{ 760 struct cc770_priv *priv = netdev_priv(dev); 761 int err; 762 763 /* set chip into reset mode */ 764 set_reset_mode(dev); 765 766 /* common open */ 767 err = open_candev(dev); 768 if (err) 769 return err; 770 771 err = request_irq(dev->irq, &cc770_interrupt, priv->irq_flags, 772 dev->name, dev); 773 if (err) { 774 close_candev(dev); 775 return -EAGAIN; 776 } 777 778 /* init and start chip */ 779 cc770_start(dev); 780 781 netif_start_queue(dev); 782 783 return 0; 784} 785 786static int cc770_close(struct net_device *dev) 787{ 788 netif_stop_queue(dev); 789 set_reset_mode(dev); 790 791 free_irq(dev->irq, dev); 792 close_candev(dev); 793 794 return 0; 795} 796 797struct net_device *alloc_cc770dev(int sizeof_priv) 798{ 799 struct net_device *dev; 800 struct cc770_priv *priv; 801 802 dev = alloc_candev(sizeof(struct cc770_priv) + sizeof_priv, 803 CC770_ECHO_SKB_MAX); 804 if (!dev) 805 return NULL; 806 807 priv = netdev_priv(dev); 808 809 priv->dev = dev; 810 priv->can.bittiming_const = &cc770_bittiming_const; 811 priv->can.do_set_bittiming = cc770_set_bittiming; 812 priv->can.do_set_mode = cc770_set_mode; 813 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; 814 priv->tx_skb = NULL; 815 816 memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags)); 817 818 if (sizeof_priv) 819 priv->priv = (void *)priv + sizeof(struct cc770_priv); 820 821 return dev; 822} 823EXPORT_SYMBOL_GPL(alloc_cc770dev); 824 825void free_cc770dev(struct net_device *dev) 826{ 827 free_candev(dev); 828} 829EXPORT_SYMBOL_GPL(free_cc770dev); 830 831static const struct net_device_ops cc770_netdev_ops = { 832 .ndo_open = cc770_open, 833 .ndo_stop = cc770_close, 834 .ndo_start_xmit = cc770_start_xmit, 835 .ndo_change_mtu = can_change_mtu, 836}; 837 838int register_cc770dev(struct net_device *dev) 839{ 840 struct cc770_priv *priv = netdev_priv(dev); 841 int err; 842 843 err = cc770_probe_chip(dev); 844 if (err) 845 return err; 846 847 dev->netdev_ops = &cc770_netdev_ops; 848 849 dev->flags |= IFF_ECHO; /* we support local echo */ 850 851 /* Should we use additional functions? */ 852 if (!i82527_compat && priv->control_normal_mode & CTRL_EAF) { 853 priv->can.do_get_berr_counter = cc770_get_berr_counter; 854 priv->control_normal_mode = CTRL_IE | CTRL_EAF | CTRL_EIE; 855 netdev_dbg(dev, "i82527 mode with additional functions\n"); 856 } else { 857 priv->control_normal_mode = CTRL_IE | CTRL_EIE; 858 netdev_dbg(dev, "strict i82527 compatibility mode\n"); 859 } 860 861 chipset_init(priv); 862 set_reset_mode(dev); 863 864 return register_candev(dev); 865} 866EXPORT_SYMBOL_GPL(register_cc770dev); 867 868void unregister_cc770dev(struct net_device *dev) 869{ 870 set_reset_mode(dev); 871 unregister_candev(dev); 872} 873EXPORT_SYMBOL_GPL(unregister_cc770dev); 874 875static __init int cc770_init(void) 876{ 877 if (msgobj15_eff) { 878 cc770_obj_flags[CC770_OBJ_RX0] |= CC770_OBJ_FLAG_EFF; 879 cc770_obj_flags[CC770_OBJ_RX1] &= ~CC770_OBJ_FLAG_EFF; 880 } 881 882 pr_info("CAN netdevice driver\n"); 883 884 return 0; 885} 886module_init(cc770_init); 887 888static __exit void cc770_exit(void) 889{ 890 pr_info("driver removed\n"); 891} 892module_exit(cc770_exit);