cc770.c 22 KB

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