077-mcfv4e_flexcan.patch 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376
  1. From c44de58d0972d05851512ba8cbd928b7adef5187 Mon Sep 17 00:00:00 2001
  2. From: Kurt Mahan <[email protected]>
  3. Date: Tue, 8 Jul 2008 17:11:33 -0600
  4. Subject: [PATCH] Add FlexCAN support.
  5. LTIBName: mcfv4e-flexcan
  6. Signed-off-by: Kurt Mahan <[email protected]>
  7. Signed-off-by: Huan Wang <[email protected]>
  8. ---
  9. drivers/net/can/Kconfig | 13 ++
  10. drivers/net/can/Makefile | 1 +
  11. drivers/net/can/flexcan/Makefile | 5 +
  12. drivers/net/can/flexcan/flexcan.c | 378 +++++++++++++++++++++++++++++++++
  13. drivers/net/can/flexcan/flexcan.h | 148 +++++++++++++
  14. drivers/net/can/flexcan/mcf548x_can.c | 213 ++++++++++++++++++
  15. include/asm-m68k/m5485sim.h | 2 +
  16. include/linux/can/dev.h | 62 ++++++
  17. include/linux/can/ioctl.h | 152 +++++++++++++
  18. include/linux/can/version.h | 22 ++
  19. net/can/Makefile | 3 +
  20. net/can/dev.c | 292 +++++++++++++++++++++++++
  21. 12 files changed, 1291 insertions(+), 0 deletions(-)
  22. create mode 100644 drivers/net/can/flexcan/Makefile
  23. create mode 100644 drivers/net/can/flexcan/flexcan.c
  24. create mode 100644 drivers/net/can/flexcan/flexcan.h
  25. create mode 100644 drivers/net/can/flexcan/mcf548x_can.c
  26. create mode 100644 include/linux/can/dev.h
  27. create mode 100644 include/linux/can/ioctl.h
  28. create mode 100644 include/linux/can/version.h
  29. create mode 100644 net/can/dev.c
  30. --- a/drivers/net/can/Kconfig
  31. +++ b/drivers/net/can/Kconfig
  32. @@ -12,6 +12,19 @@ config CAN_VCAN
  33. This driver can also be built as a module. If so, the module
  34. will be called vcan.
  35. +config CAN_FLEXCAN
  36. + tristate "Support for Freescale FLEXCAN based chips"
  37. + depends on CAN && (PPC || M68K || M68KNOMMU)
  38. + ---help---
  39. + Say Y here if you want to support for Freescale FlexCAN.
  40. +
  41. +config CAN_MCF547X_8X
  42. + tristate "Freescale MCF547X/MCF548X onboard CAN controller"
  43. + depends on CAN_FLEXCAN && (M547X || M548X)
  44. + ---help---
  45. + Say Y here if you want to support for Freescale MCF547x/MCF548x
  46. + onboard dualCAN controller.
  47. +
  48. config CAN_DEBUG_DEVICES
  49. bool "CAN devices debugging messages"
  50. depends on CAN
  51. --- a/drivers/net/can/Makefile
  52. +++ b/drivers/net/can/Makefile
  53. @@ -3,3 +3,4 @@
  54. #
  55. obj-$(CONFIG_CAN_VCAN) += vcan.o
  56. +obj-$(CONFIG_CAN_FLEXCAN) += flexcan/
  57. --- /dev/null
  58. +++ b/drivers/net/can/flexcan/Makefile
  59. @@ -0,0 +1,5 @@
  60. +
  61. +obj-$(CONFIG_CAN_MCF547X_8X) += flexcan-mcf548x.o
  62. +
  63. +flexcan-mcf548x-objs := flexcan.o mcf548x_can.o
  64. +
  65. --- /dev/null
  66. +++ b/drivers/net/can/flexcan/flexcan.c
  67. @@ -0,0 +1,378 @@
  68. +/*
  69. + * flexcan.c
  70. + *
  71. + * DESCRIPTION:
  72. + * CAN bus driver for the alone generic (as possible as) FLEXCAN controller.
  73. + *
  74. + * AUTHOR:
  75. + * Andrey Volkov <[email protected]>
  76. + *
  77. + * COPYRIGHT:
  78. + * 2005-2006, Varma Electronics Oy
  79. + *
  80. + * LICENCE:
  81. + * This program is free software; you can redistribute it and/or modify
  82. + * it under the terms of the GNU General Public License as published by
  83. + * the Free Software Foundation; either version 2 of the License, or
  84. + * (at your option) any later version.
  85. + *
  86. + * This program is distributed in the hope that it will be useful,
  87. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  88. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  89. + * GNU General Public License for more details.
  90. + *
  91. + * You should have received a copy of the GNU General Public License
  92. + * along with this program; if not, write to the Free Software
  93. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  94. + *
  95. + * HISTORY:
  96. + * 2008-06-23 Support for MCF548x's FlexCAN
  97. + * Huan, Wang <[email protected]>
  98. + */
  99. +
  100. +
  101. +
  102. +#include <linux/kernel.h>
  103. +#include <linux/module.h>
  104. +#include <linux/interrupt.h>
  105. +#include <linux/delay.h>
  106. +#include <linux/netdevice.h>
  107. +#include <linux/if_arp.h>
  108. +#include <linux/if_ether.h>
  109. +#include <linux/can.h>
  110. +#include <linux/list.h>
  111. +#include <linux/io.h>
  112. +
  113. +#include <linux/can/dev.h>
  114. +#include <linux/can/error.h>
  115. +#include "flexcan.h"
  116. +#include <asm/coldfire.h>
  117. +#include <asm/m5485sim.h>
  118. +#include <linux/can/version.h> /* for RCSID. Removed by mkpatch script */
  119. +RCSID("$Id$");
  120. +
  121. +struct flexcan_priv {
  122. + struct can_priv can;
  123. + volatile unsigned long flags;
  124. + u8 shadow_statflg;
  125. + u8 shadow_canrier;
  126. + u8 cur_pri;
  127. + u8 tx_active;
  128. +
  129. + struct list_head tx_head;
  130. + struct napi_struct napi;
  131. + struct net_device *dev;
  132. +};
  133. +
  134. +
  135. +static int flexcan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
  136. +{
  137. + struct can_frame *frame = (struct can_frame *)skb->data;
  138. + struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
  139. + int i, len;
  140. + int txbuf = 0;
  141. + u32 can_id, can_ext, tmp, tmp1;
  142. +
  143. + /* Transmission inactive */
  144. + regs->cantxfg[txbuf].can_dlc = MB_CNT_CODE(0x08);
  145. +
  146. + can_ext = frame->can_id;
  147. + if (can_ext & CAN_EFF_FLAG) {
  148. + /* Frame format is extended */
  149. + regs->cantxfg[txbuf].can_dlc |= (1 << 21);
  150. + regs->cantxfg[txbuf].can_dlc |= (1 << 22);
  151. + can_id = frame->can_id & MB_ID_EXT;
  152. + if (frame->can_id & CAN_RTR_FLAG)
  153. + regs->cantxfg[txbuf].can_dlc |= (1 << 20);
  154. +
  155. + tmp = (can_id & CAN_SFF_MASK) << 18;
  156. + tmp1 = can_id >> 11;
  157. + can_id = tmp | tmp1;
  158. + regs->cantxfg[txbuf].can_id = can_id;
  159. + } else {
  160. + /* Frame format is standard */
  161. + can_id = frame->can_id & MB_ID_EXT;
  162. + if (frame->can_id & CAN_RTR_FLAG)
  163. + regs->cantxfg[txbuf].can_dlc |= (1 << 20);
  164. +
  165. + regs->cantxfg[txbuf].can_id = can_id << 18;
  166. + }
  167. +
  168. + len = 8;
  169. + for (i = 0; i < len; i++)
  170. + regs->cantxfg[txbuf].data[i] = frame->data[i];
  171. +
  172. + regs->cantxfg[txbuf].can_dlc |= len << 16;
  173. + /* Transmission active */
  174. + regs->cantxfg[txbuf].can_dlc |= MB_CNT_CODE(0x0c);
  175. + kfree_skb(skb);
  176. + return NETDEV_TX_OK;
  177. +}
  178. +
  179. +static void flexcan_tx_timeout(struct net_device *dev)
  180. +{
  181. + struct sk_buff *skb;
  182. + struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
  183. + struct can_frame *frame;
  184. + int length = 8;
  185. +
  186. + /* Diable the interrupts */
  187. + regs->imask = IMASK_BUFF_DISABLE_ALL;
  188. +
  189. + skb = dev_alloc_skb(sizeof(struct can_frame));
  190. + if (!skb) {
  191. + if (printk_ratelimit())
  192. + dev_notice(ND2D(dev), "TIMEOUT packet dropped.\n");
  193. + return;
  194. + }
  195. + frame = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
  196. +
  197. + frame->can_dlc = length;
  198. +
  199. + skb->dev = dev;
  200. + skb->protocol = __constant_htons(ETH_P_CAN);
  201. + skb->pkt_type = PACKET_BROADCAST;
  202. + skb->ip_summed = CHECKSUM_UNNECESSARY;
  203. +
  204. + netif_rx(skb);
  205. +}
  206. +
  207. +static irqreturn_t flexcan_isr(int irq, void *dev_id)
  208. +{
  209. + struct net_device *dev = (struct net_device *)dev_id;
  210. + struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
  211. + struct net_device_stats *stats = dev->get_stats(dev);
  212. + struct sk_buff *skb;
  213. + struct can_frame *frame;
  214. + u32 iflags, oflags;
  215. + int i, k;
  216. + int retval = 1;
  217. +
  218. + iflags = regs->iflag;
  219. + oflags = iflags;
  220. + for (i = 0; i < 16; i++) {
  221. + if (iflags & (0x01 << i)) {
  222. + struct flexcan_mb *mb = &regs->cantxfg[i];
  223. + int ctrl = mb->can_dlc;
  224. + int code = (ctrl >> 24) & 0x0f;
  225. + int length = (ctrl >> 16) & 0x0f;
  226. + u32 tmp, tmp1;
  227. +
  228. + if (code < 8 && (length > 0)) {
  229. + /* receive frame */
  230. + skb = dev_alloc_skb(sizeof(struct can_frame));
  231. + if (!skb)
  232. + dev_notice(ND2D(dev),
  233. + "Packets dropped.\n");
  234. + skb->dev = dev;
  235. + frame = (struct can_frame *)skb_put(skb,
  236. + sizeof(struct can_frame));
  237. +
  238. + frame->can_id &= 0x0;
  239. + frame->can_dlc = length;
  240. + tmp1 = mb->can_id & MB_ID_EXT;
  241. + if (ctrl & MB_CNT_IDE) {
  242. + tmp = tmp1;
  243. + tmp = (tmp >> 18) & CAN_SFF_MASK;
  244. + frame->can_id = (tmp1 << 11) | tmp;
  245. + frame->can_id &= CAN_EFF_MASK;
  246. + frame->can_id |= CAN_EFF_FLAG;
  247. + if (ctrl & MB_CNT_RTR)
  248. + frame->can_id |= CAN_RTR_FLAG;
  249. + } else {
  250. + frame->can_id = tmp1 >> 18;
  251. + if (ctrl & MB_CNT_RTR)
  252. + frame->can_id |= CAN_RTR_FLAG;
  253. + }
  254. +
  255. + for (k = 0; k < 8; k++)
  256. + frame->data[k] = mb->data[k];
  257. +
  258. + mb->can_dlc &= MB_CODE_MASK;
  259. + mb->can_dlc |= MB_CNT_CODE(0x04);
  260. +
  261. + stats->rx_packets++;
  262. + stats->rx_bytes += frame->can_dlc;
  263. + skb->dev = dev;
  264. + skb->protocol = __constant_htons(ETH_P_CAN);
  265. + skb->ip_summed = CHECKSUM_UNNECESSARY;
  266. +
  267. + retval = netif_rx(skb);
  268. + if (retval == NET_RX_DROP)
  269. + dev_notice(ND2D(dev),
  270. + "Packets dropped.\n");
  271. + } else {
  272. + /* transmit frame */
  273. + mb->can_dlc = MB_CNT_CODE(0x04);
  274. + }
  275. + }
  276. + }
  277. + regs->iflag = oflags;
  278. +
  279. + return IRQ_HANDLED;
  280. +}
  281. +
  282. +static int flexcan_do_set_bit_time(struct net_device *dev,
  283. + struct can_bittime *bt)
  284. +{
  285. + struct flexcan_priv *priv = netdev_priv(dev);
  286. + struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
  287. + int ret = 0;
  288. + u32 reg;
  289. +
  290. + if (bt->type != CAN_BITTIME_STD)
  291. + return -EINVAL;
  292. +
  293. + spin_lock_irq(&priv->can.irq_lock);
  294. +
  295. + reg = CANCTRL_PRESDIV(bt->std.brp) | CANCTRL_PSEG1(bt->std.phase_seg1
  296. + - 1) | CANCTRL_PSEG2(bt->std.phase_seg2 - 1);
  297. + regs->canctrl &= CANCTRL_BITTIME;
  298. + regs->canctrl |= (reg | CANCTRL_SAMP(bt->std.sam) |
  299. + CANCTRL_PROPSEG(bt->std.prop_seg - 1));
  300. +
  301. + spin_unlock_irq(&priv->can.irq_lock);
  302. + return ret;
  303. +}
  304. +
  305. +
  306. +static int flexcan_open(struct net_device *dev)
  307. +{
  308. + int ret, i, j;
  309. + struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
  310. +
  311. +#if defined(CONFIG_M547X_8X)
  312. + MCF_PAR_TIMER = MCF_PAR_TIMER | 0x28;
  313. + MCF_PAR_TIMER = MCF_PAR_TIMER & 0xf8;
  314. + MCF_PAR_DSPI = MCF_PAR_DSPI | 0x0a00;
  315. + MCF_PAR_FECI2CIRQ = MCF_PAR_FECI2CIRQ | 0x0283;
  316. + MCF_PAR_PSCn(2) = MCF_PAR_PSCn(2) & 0x0f;
  317. + MCF_PAR_PSCn(2) = MCF_PAR_PSCn(2) | 0x50;
  318. +#endif
  319. +
  320. + regs->canmcr |= CANMCR_SOFTRST;
  321. + regs->canmcr |= CANMCR_MDIS;
  322. + udelay(10);
  323. +
  324. + if ((regs->canmcr & CANMCR_SOFTRST) != 0x0) {
  325. + dev_err(ND2D(dev), "Failed to softreset can module.\n");
  326. + return -1;
  327. + }
  328. +
  329. + /* Enable error and bus off interrupt */
  330. + regs->canctrl |= (CANCTRL_RJW(3) | CANCTRL_ERRMSK |
  331. + CANCTRL_BOFFMSK);
  332. +
  333. + /* Set lowest buffer transmitted first */
  334. + regs->canctrl |= CANCTRL_LBUF;
  335. +
  336. + for (i = 0; i < 16; i++) {
  337. + regs->cantxfg[i].can_dlc = 0;
  338. + regs->cantxfg[i].can_id = 0;
  339. + for (j = 0; j < 8; j++)
  340. + regs->cantxfg[i].data[j] = 0;
  341. +
  342. + /* Put MB into rx queue */
  343. + regs->cantxfg[i].can_dlc = MB_CNT_CODE(0x04);
  344. + }
  345. +
  346. + /* acceptance mask/acceptance code (accept everything) */
  347. + regs->rxgmask = 0x00000000;
  348. + regs->rx14mask = 0x00000000;
  349. + regs->rx15mask = 0x00000000;
  350. + /* extended frame */
  351. + regs->cantxfg[14].can_dlc |= 0x600000;
  352. + /* Enable flexcan module */
  353. + regs->canmcr &= ~CANMCR_MDIS;
  354. + /* Synchronize with the can bus */
  355. + regs->canmcr &= ~CANMCR_HALT;
  356. +
  357. +#if defined(CONFIG_M547X_8X)
  358. + for (i = 0; i < 2; i++) {
  359. + MCF_ICR(ISC_CANn_MBOR(i)) = 0x33;
  360. + MCF_ICR(ISC_CANn_ERR(i)) = 0x33;
  361. + MCF_ICR(ISC_CANn_BUSOFF(i)) = 0x33;
  362. + }
  363. +
  364. + ret = request_irq(dev->irq + 64, flexcan_isr, IRQF_DISABLED,
  365. + dev->name, dev);
  366. + ret = request_irq(dev->irq + 1 + 64, flexcan_isr, IRQF_DISABLED,
  367. + dev->name, dev);
  368. + ret = request_irq(dev->irq + 2 + 64, flexcan_isr, IRQF_DISABLED,
  369. + dev->name, dev);
  370. + if (ret < 0) {
  371. + printk(KERN_ERR "%s - failed to attach interrupt.\n",
  372. + dev->name);
  373. + return ret;
  374. + }
  375. +#endif
  376. +
  377. + /* Enable all interrupts */
  378. + regs->imask = IMASK_BUFF_ENABLE_ALL;
  379. + netif_start_queue(dev);
  380. + return 0;
  381. +}
  382. +
  383. +static int flexcan_close(struct net_device *dev)
  384. +{
  385. + struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
  386. +
  387. + netif_stop_queue(dev);
  388. +
  389. + /* Disable all interrupts */
  390. + regs->imask = IMASK_BUFF_DISABLE_ALL;
  391. + free_irq(dev->irq + 64, dev);
  392. + free_irq(dev->irq + 1 + 64, dev);
  393. + free_irq(dev->irq + 2 + 64, dev);
  394. +
  395. + /* Disable module */
  396. + regs->canmcr |= CANMCR_MDIS;
  397. + return 0;
  398. +}
  399. +
  400. +int register_flexcandev(struct net_device *dev, int clock_src)
  401. +{
  402. + struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
  403. +
  404. + regs->canmcr &= ~CANMCR_MDIS;
  405. + udelay(100);
  406. + regs->canmcr |= (CANMCR_FRZ | CANMCR_HALT);
  407. + return register_netdev(dev);
  408. +}
  409. +EXPORT_SYMBOL(register_flexcandev);
  410. +
  411. +void unregister_flexcandev(struct net_device *dev)
  412. +{
  413. + struct flexcan_regs *regs = (struct flexcan_regs *)dev->base_addr;
  414. +
  415. + regs->canmcr |= (CANMCR_FRZ | CANMCR_HALT);
  416. + regs->canmcr |= CANMCR_MDIS;
  417. +
  418. + unregister_netdev(dev);
  419. +}
  420. +EXPORT_SYMBOL(unregister_flexcandev);
  421. +
  422. +struct net_device *alloc_flexcandev(void)
  423. +{
  424. + struct net_device *dev;
  425. + struct flexcan_priv *priv;
  426. +
  427. + dev = alloc_candev(sizeof(struct flexcan_priv));
  428. + if (!dev)
  429. + return NULL;
  430. +
  431. + priv = netdev_priv(dev);
  432. + priv->dev = dev;
  433. + dev->open = flexcan_open;
  434. + dev->stop = flexcan_close;
  435. + dev->hard_start_xmit = flexcan_hard_start_xmit;
  436. + dev->tx_timeout = flexcan_tx_timeout;
  437. + dev->flags |= IFF_NOARP;
  438. + priv->can.do_set_bit_time = flexcan_do_set_bit_time;
  439. + return dev;
  440. +}
  441. +EXPORT_SYMBOL(alloc_flexcandev);
  442. +
  443. +MODULE_AUTHOR("Andrey Volkov <[email protected]>");
  444. +MODULE_LICENSE("GPL v2");
  445. +MODULE_DESCRIPTION("CAN port driver for flexcan based chip");
  446. --- /dev/null
  447. +++ b/drivers/net/can/flexcan/flexcan.h
  448. @@ -0,0 +1,148 @@
  449. +/*
  450. + * flexcan.h
  451. + *
  452. + * DESCRIPTION:
  453. + * Definitions of consts/structs to drive the Freescale FLEXCAN.
  454. + *
  455. + */
  456. +
  457. +#ifndef __FLEXCAN_H__
  458. +#define __FLEXCAN_H__
  459. +
  460. +#include <linux/autoconf.h>
  461. +#include <linux/types.h>
  462. +
  463. +/* FLEXCAN module configuration register (CANMCR) bits */
  464. +#define CANMCR_MDIS 0x80000000
  465. +#define CANMCR_FRZ 0x40000000
  466. +#define CANMCR_HALT 0x10000000
  467. +#define CANMCR_SOFTRST 0x02000000
  468. +#define CANMCR_FRZACK 0x01000000
  469. +#define CANMCR_SUPV 0x00800000
  470. +#define CANMCR_MAXMB(x) ((x)&0x0f)
  471. +
  472. +/* FLEXCAN control register (CANCTRL) bits */
  473. +#define CANCTRL_PRESDIV(x) (((x)&0xff)<<24)
  474. +#define CANCTRL_RJW(x) (((x)&0x03)<<22)
  475. +#define CANCTRL_PSEG1(x) (((x)&0x07)<<19)
  476. +#define CANCTRL_PSEG2(x) (((x)&0x07)<<16)
  477. +#define CANCTRL_BOFFMSK 0x00008000
  478. +#define CANCTRL_ERRMSK 0x00004000
  479. +#define CANCTRL_LPB 0x00001000
  480. +#define CANCTRL_SAMP(x) (((x)&0x1)<<7)
  481. +#define CANCTRL_BOFFREC 0x00000040
  482. +#define CANCTRL_TSYNC 0x00000020
  483. +#define CANCTRL_LBUF 0x00000010
  484. +#define CANCTRL_LOM 0x00000008
  485. +#define CANCTRL_PROPSEG(x) ((x)&0x07)
  486. +#define CANCTRL_BITTIME 0x00c0d078
  487. +
  488. +/* FLEXCAN error counter register (ERRCNT) bits */
  489. +#define ERRCNT_REXECTR(x) (((x)&0xff)<<8)
  490. +#define ERRCNT_TXECTR(x) ((x)&0xff)
  491. +
  492. +/* FLEXCAN error and status register (ERRSTAT) bits */
  493. +#define ERRSTAT_BITERR(x) (((x)&0x03)<<14)
  494. +#define ERRSTAT_ACKERR 0x00002000
  495. +#define ERRSTAT_CRCERR 0x00001000
  496. +#define ERRSTAT_FRMERR 0x00000800
  497. +#define ERRSTAT_STFERR 0x00000400
  498. +#define ERRSTAT_TXWRN 0x00000200
  499. +#define ERRSTAT_RXWRN 0x00000100
  500. +#define ERRSTAT_IDLE 0x00000080
  501. +#define ERRSTAT_TXRX 0x00000040
  502. +#define ERRSTAT_FLTCONF(x) (((x)&0x03)<<4)
  503. +#define ERRSTAT_BOFFINT 0x00000004
  504. +#define ERRSTAT_ERRINT 0x00000002
  505. +
  506. +/* FLEXCAN interrupt mask register (IMASK) bits */
  507. +#define IMASK_BUF15M 0x8000
  508. +#define IMASK_BUF14M 0x4000
  509. +#define IMASK_BUF13M 0x2000
  510. +#define IMASK_BUF12M 0x1000
  511. +#define IMASK_BUF11M 0x0800
  512. +#define IMASK_BUF10M 0x0400
  513. +#define IMASK_BUF9M 0x0200
  514. +#define IMASK_BUF8M 0x0100
  515. +#define IMASK_BUF7M 0x0080
  516. +#define IMASK_BUF6M 0x0040
  517. +#define IMASK_BUF5M 0x0020
  518. +#define IMASK_BUF4M 0x0010
  519. +#define IMASK_BUF3M 0x0008
  520. +#define IMASK_BUF2M 0x0004
  521. +#define IMASK_BUF1M 0x0002
  522. +#define IMASK_BUF0M 0x0001
  523. +#define IMASK_BUFnM(x) (0x1<<(x))
  524. +#define IMASK_BUFF_ENABLE_ALL 0xffff
  525. +#define IMASK_BUFF_DISABLE_ALL 0x0000
  526. +
  527. +/* FLEXCAN interrupt flag register (IFLAG) bits */
  528. +#define IFLAG_BUF15M 0x8000
  529. +#define IFLAG_BUF14M 0x4000
  530. +#define IFLAG_BUF13M 0x2000
  531. +#define IFLAG_BUF12M 0x1000
  532. +#define IFLAG_BUF11M 0x0800
  533. +#define IFLAG_BUF10M 0x0400
  534. +#define IFLAG_BUF9M 0x0200
  535. +#define IFLAG_BUF8M 0x0100
  536. +#define IFLAG_BUF7M 0x0080
  537. +#define IFLAG_BUF6M 0x0040
  538. +#define IFLAG_BUF5M 0x0020
  539. +#define IFLAG_BUF4M 0x0010
  540. +#define IFLAG_BUF3M 0x0008
  541. +#define IFLAG_BUF2M 0x0004
  542. +#define IFLAG_BUF1M 0x0002
  543. +#define IFLAG_BUF0M 0x0001
  544. +#define IFLAG_BUFnM(x) (0x1<<(x))
  545. +#define IFLAG_BUFF_SET_ALL 0xffff
  546. +#define IFLAG_BUFF_DISABLE_ALL 0x0000
  547. +
  548. +/* FLEXCAN message buffers */
  549. +#define MB_CNT_CODE(x) (((x)&0x0f)<<24)
  550. +#define MB_CNT_SRR 0x00400000
  551. +#define MB_CNT_IDE 0x00200000
  552. +#define MB_CNT_RTR 0x00100000
  553. +#define MB_CNT_LENGTH(x) (((x)&0x0f)<<16)
  554. +#define MB_CNT_TIMESTAMP(x) ((x)&0xffff)
  555. +
  556. +#define MB_ID_STD ((0x7ff)<<18)
  557. +#define MB_ID_EXT 0x1fffffff
  558. +#define MB_CODE_MASK 0xf0ffffff
  559. +
  560. +/* Structure of the message buffer */
  561. +struct flexcan_mb {
  562. + u32 can_dlc;
  563. + u32 can_id;
  564. + u8 data[8];
  565. +};
  566. +
  567. +/* Structure of the hardware registers */
  568. +struct flexcan_regs {
  569. + u32 canmcr;
  570. + u32 canctrl;
  571. + u32 timer;
  572. + u32 reserved1;
  573. + u32 rxgmask;
  574. + u32 rx14mask;
  575. + u32 rx15mask;
  576. + u32 errcnt;
  577. + u32 errstat;
  578. + u32 reserved2;
  579. + u32 imask;
  580. + u32 reserved3;
  581. + u32 iflag;
  582. + u32 reserved4[19];
  583. + struct flexcan_mb cantxfg[16];
  584. +};
  585. +
  586. +struct flexcan_platform_data {
  587. + u8 clock_src; /* FLEXCAN clock source CRIN or SYSCLK */
  588. + u32 clock_frq; /* can ref. clock, in Hz */
  589. +};
  590. +
  591. +struct net_device *alloc_flexcandev(void);
  592. +
  593. +extern int register_flexcandev(struct net_device *dev, int clock_src);
  594. +extern void unregister_flexcandev(struct net_device *dev);
  595. +
  596. +#endif /* __FLEXCAN_H__ */
  597. --- /dev/null
  598. +++ b/drivers/net/can/flexcan/mcf548x_can.c
  599. @@ -0,0 +1,213 @@
  600. +/*
  601. + * DESCRIPTION:
  602. + * CAN bus driver for the Freescale MCF548x embedded CPU.
  603. + *
  604. + * AUTHOR:
  605. + * Andrey Volkov <[email protected]>
  606. + *
  607. + * COPYRIGHT:
  608. + * 2004-2005, Varma Electronics Oy
  609. + *
  610. + * LICENCE:
  611. + * This program is free software; you can redistribute it and/or modify
  612. + * it under the terms of the GNU General Public License as published by
  613. + * the Free Software Foundation; either version 2 of the License, or
  614. + * (at your option) any later version.
  615. + *
  616. + * This program is distributed in the hope that it will be useful,
  617. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  618. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  619. + * GNU General Public License for more details.
  620. + *
  621. + * You should have received a copy of the GNU General Public License
  622. + * along with this program; if not, write to the Free Software
  623. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  624. + *
  625. + * HISTORY:
  626. + * 2008-06-23 support for MCF548x's FlexCAN
  627. + * Huan, Wang <[email protected]>
  628. + * 2005-02-03 created
  629. + *
  630. + */
  631. +
  632. +#include <linux/kernel.h>
  633. +#include <linux/module.h>
  634. +#include <linux/interrupt.h>
  635. +#include <linux/platform_device.h>
  636. +#include <linux/netdevice.h>
  637. +#include <linux/can.h>
  638. +#include <linux/can/dev.h>
  639. +#include <linux/io.h>
  640. +
  641. +#include "flexcan.h"
  642. +#include <asm/coldfire.h>
  643. +#include <asm/m5485sim.h>
  644. +#include <linux/can/version.h> /* for RCSID. Removed by mkpatch script */
  645. +
  646. +RCSID("$Id$");
  647. +
  648. +#define PDEV_MAX 2
  649. +
  650. +struct platform_device *pdev[PDEV_MAX];
  651. +
  652. +static int __devinit mcf548x_can_probe(struct platform_device *pdev)
  653. +{
  654. + struct resource *mem;
  655. + struct net_device *dev;
  656. + struct flexcan_platform_data *pdata = pdev->dev.platform_data;
  657. + struct can_priv *can;
  658. + u32 mem_size;
  659. + int ret = -ENODEV;
  660. +
  661. + if (!pdata)
  662. + return ret;
  663. +
  664. + dev = alloc_flexcandev();
  665. + if (!dev)
  666. + return -ENOMEM;
  667. + can = netdev_priv(dev);
  668. +
  669. + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  670. +
  671. + dev->irq = platform_get_irq(pdev, 0);
  672. + if (!mem || !dev->irq)
  673. + goto req_error;
  674. +
  675. + mem_size = mem->end - mem->start + 1;
  676. + if (!request_mem_region(mem->start, mem_size, pdev->dev.driver->name)) {
  677. + dev_err(&pdev->dev, "resource unavailable\n");
  678. + goto req_error;
  679. + }
  680. + SET_NETDEV_DEV(dev, &pdev->dev);
  681. +
  682. + dev->base_addr = (unsigned long)ioremap_nocache(mem->start, mem_size);
  683. + if (!dev->base_addr) {
  684. + dev_err(&pdev->dev, "failed to map can port\n");
  685. + ret = -ENOMEM;
  686. + goto fail_map;
  687. + }
  688. + can->can_sys_clock = pdata->clock_frq;
  689. + platform_set_drvdata(pdev, dev);
  690. + ret = register_flexcandev(dev, pdata->clock_src);
  691. + if (ret >= 0) {
  692. + dev_info(&pdev->dev, "probe for port 0x%lX done\n",
  693. + dev->base_addr);
  694. + return ret;
  695. + }
  696. +
  697. + iounmap((unsigned long *)dev->base_addr);
  698. +fail_map:
  699. + release_mem_region(mem->start, mem_size);
  700. +req_error:
  701. + free_candev(dev);
  702. + dev_err(&pdev->dev, "probe failed\n");
  703. + return ret;
  704. +}
  705. +
  706. +static int __devexit mcf548x_can_remove(struct platform_device *pdev)
  707. +{
  708. + struct net_device *dev = platform_get_drvdata(pdev);
  709. + struct resource *mem;
  710. +
  711. + platform_set_drvdata(pdev, NULL);
  712. + unregister_flexcandev(dev);
  713. + iounmap((unsigned long *)dev->base_addr);
  714. +
  715. + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  716. + release_mem_region(mem->start, mem->end - mem->start + 1);
  717. + free_candev(dev);
  718. + return 0;
  719. +}
  720. +
  721. +static struct platform_driver mcf548x_can_driver = {
  722. + .driver = {
  723. + .name = "mcf548x-flexcan",
  724. + },
  725. + .probe = mcf548x_can_probe,
  726. + .remove = __devexit_p(mcf548x_can_remove),
  727. +};
  728. +
  729. +static struct resource mcf548x_can0_resources[] = {
  730. + [0] = {
  731. + .start = MCF_MBAR + 0x0000A000,
  732. + .end = MCF_MBAR + 0x0000A7FF,
  733. + .flags = IORESOURCE_MEM,
  734. + },
  735. + [1] = {
  736. + .start = 49,
  737. + .end = 49,
  738. + .flags = IORESOURCE_IRQ,
  739. + },
  740. +};
  741. +
  742. +static struct resource mcf548x_can1_resources[] = {
  743. + [0] = {
  744. + .start = MCF_MBAR + 0x0000A800,
  745. + .end = MCF_MBAR + 0x0000AFFF,
  746. + .flags = IORESOURCE_MEM,
  747. + },
  748. + [1] = {
  749. + .start = 55,
  750. + .end = 55,
  751. + .flags = IORESOURCE_IRQ,
  752. + },
  753. +};
  754. +
  755. +
  756. +static int __init mcf548x_of_to_pdev(void)
  757. +{
  758. + unsigned int i;
  759. + int err = -ENODEV;
  760. + struct flexcan_platform_data pdata;
  761. +
  762. + pdev[0] = platform_device_register_simple("mcf548x-flexcan", 0,
  763. + mcf548x_can0_resources, 2);
  764. + if (IS_ERR(pdev[0])) {
  765. + err = PTR_ERR(pdev[0]);
  766. + return err;
  767. + }
  768. + pdev[1] = platform_device_register_simple("mcf548x-flexcan", 1,
  769. + mcf548x_can1_resources, 2);
  770. + if (IS_ERR(pdev[1])) {
  771. + err = PTR_ERR(pdev[1]);
  772. + return err;
  773. + }
  774. +
  775. + /* FlexCAN clock */
  776. + pdata.clock_frq = 100000000;
  777. +
  778. + for (i = 0; i < PDEV_MAX; i++) {
  779. + err = platform_device_add_data(pdev[i], &pdata, sizeof(pdata));
  780. + if (err)
  781. + return err;
  782. + }
  783. + return err;
  784. +}
  785. +
  786. +int __init mcf548x_can_init(void)
  787. +{
  788. + int err = mcf548x_of_to_pdev();
  789. +
  790. + if (err) {
  791. + printk(KERN_ERR "%s init failed with err=%d\n",
  792. + mcf548x_can_driver.driver.name, err);
  793. + return err;
  794. + }
  795. +
  796. + return platform_driver_register(&mcf548x_can_driver);
  797. +}
  798. +
  799. +void __exit mcf548x_can_exit(void)
  800. +{
  801. + int i;
  802. + platform_driver_unregister(&mcf548x_can_driver);
  803. + for (i = 0; i < PDEV_MAX; i++)
  804. + platform_device_unregister(pdev[i]);
  805. +}
  806. +
  807. +module_init(mcf548x_can_init);
  808. +module_exit(mcf548x_can_exit);
  809. +
  810. +MODULE_AUTHOR("Andrey Volkov <[email protected]>");
  811. +MODULE_DESCRIPTION("Freescale MCF548x CAN driver");
  812. +MODULE_LICENSE("GPL v2");
  813. --- a/include/asm-m68k/m5485sim.h
  814. +++ b/include/asm-m68k/m5485sim.h
  815. @@ -186,6 +186,8 @@
  816. #define MCF_PAR_PCIBR MCF_REG16(0x000A4A)
  817. #define MCF_PAR_PSCn(x) MCF_REG08(0x000A4F-((x)&0x3))
  818. #define MCF_PAR_FECI2CIRQ MCF_REG16(0x000A44)
  819. +#define MCF_PAR_DSPI MCF_REG16(0x000A50)
  820. +#define MCF_PAR_TIMER MCF_REG08(0X000A52)
  821. #define MCF_EPPAR MCF_REG16(0x000F00)
  822. #define MCF_EPIER MCF_REG08(0x000F05)
  823. #define MCF_EPFR MCF_REG08(0x000F0C)
  824. --- /dev/null
  825. +++ b/include/linux/can/dev.h
  826. @@ -0,0 +1,62 @@
  827. +/*
  828. + * linux/can/dev.h
  829. + *
  830. + * Definitions for CAN controller network devices lib (work in progress)
  831. + *
  832. + * * * $Id$
  833. + *
  834. + * Author: Andrey Volkov <[email protected]>
  835. + * Copyright (c) 2006 Varma Electronics Oy
  836. + *
  837. + */
  838. +
  839. +#ifndef CAN_DEVICE_H
  840. +#define CAN_DEVICE_H
  841. +
  842. +#include <linux/version.h>
  843. +#include <linux/can/error.h>
  844. +#include <linux/can/ioctl.h>
  845. +
  846. +struct can_priv {
  847. + struct can_device_stats can_stats;
  848. +
  849. + /* can-bus oscillator frequency, in Hz,
  850. + BE CAREFUL! SOME CONTROLLERS (LIKE SJA1000)
  851. + FOOLISH ABOUT THIS FRQ (for sja1000 as ex. this
  852. + clock must be xtal clock divided by 2). */
  853. + u32 can_sys_clock;
  854. +
  855. + /* by default max_brp is equal 64,
  856. + but for a Freescale TouCAN, as ex., it can be 255*/
  857. + u32 max_brp;
  858. + /* For the mostly all controllers, max_sjw is equal 4, but
  859. + some, hmm, CAN implementations hardwared it to 1 */
  860. + u8 max_sjw;
  861. +
  862. + u32 baudrate; /* in bauds */
  863. + struct can_bittime bit_time;
  864. +
  865. + spinlock_t irq_lock;
  866. + /* Please hold this lock when touching net_stats/can_stats*/
  867. + spinlock_t stats_lock;
  868. +
  869. + can_state_t state;
  870. + can_mode_t mode;
  871. + can_ctrlmode_t ctrlmode;
  872. +
  873. + int (*do_set_bit_time)(struct net_device *dev, struct can_bittime *br);
  874. + int (*do_get_state) (struct net_device *dev, can_state_t *state);
  875. + int (*do_set_mode) (struct net_device *dev, can_mode_t mode);
  876. + int (*do_set_ctrlmode)(struct net_device *dev, can_ctrlmode_t ctrlmode);
  877. + int (*do_get_ctrlmode)(struct net_device *dev, can_ctrlmode_t *ctrlmode);
  878. +};
  879. +
  880. +#define ND2D(_ndev) (_ndev->dev.parent)
  881. +
  882. +struct net_device *alloc_candev(int sizeof_priv);
  883. +void free_candev(struct net_device *dev);
  884. +
  885. +int can_calc_bit_time(struct can_priv *can, u32 baudrate,
  886. + struct can_bittime_std *bit_time);
  887. +
  888. +#endif /* CAN_DEVICE_H */
  889. --- /dev/null
  890. +++ b/include/linux/can/ioctl.h
  891. @@ -0,0 +1,152 @@
  892. +/*
  893. + * linux/can/ioctl.h
  894. + *
  895. + * Definitions for CAN controller setup (work in progress)
  896. + *
  897. + * $Id$
  898. + *
  899. + * Send feedback to <[email protected]>
  900. + *
  901. + */
  902. +
  903. +#ifndef CAN_IOCTL_H
  904. +#define CAN_IOCTL_H
  905. +
  906. +#include <linux/sockios.h>
  907. +
  908. +
  909. +/* max. 16 private ioctls */
  910. +
  911. +#define SIOCSCANBAUDRATE (SIOCDEVPRIVATE+0)
  912. +#define SIOCGCANBAUDRATE (SIOCDEVPRIVATE+1)
  913. +
  914. +#define SIOCSCANCUSTOMBITTIME (SIOCDEVPRIVATE+2)
  915. +#define SIOCGCANCUSTOMBITTIME (SIOCDEVPRIVATE+3)
  916. +
  917. +#define SIOCSCANMODE (SIOCDEVPRIVATE+4)
  918. +#define SIOCGCANMODE (SIOCDEVPRIVATE+5)
  919. +
  920. +#define SIOCSCANCTRLMODE (SIOCDEVPRIVATE+6)
  921. +#define SIOCGCANCTRLMODE (SIOCDEVPRIVATE+7)
  922. +
  923. +#define SIOCSCANFILTER (SIOCDEVPRIVATE+8)
  924. +#define SIOCGCANFILTER (SIOCDEVPRIVATE+9)
  925. +
  926. +#define SIOCGCANSTATE (SIOCDEVPRIVATE+10)
  927. +#define SIOCGCANSTATS (SIOCDEVPRIVATE+11)
  928. +
  929. +#define SIOCSCANERRORCONFIG (SIOCDEVPRIVATE+12)
  930. +#define SIOCGCANERRORCONFIG (SIOCDEVPRIVATE+13)
  931. +
  932. +/* parameters for ioctls */
  933. +
  934. +/* SIOC[SG]CANBAUDRATE */
  935. +/* baudrate for CAN-controller in bits per second. */
  936. +/* 0 = Scan for baudrate (Autobaud) */
  937. +
  938. +typedef __u32 can_baudrate_t;
  939. +
  940. +
  941. +/* SIOC[SG]CANCUSTOMBITTIME */
  942. +
  943. +typedef enum CAN_BITTIME_TYPE {
  944. + CAN_BITTIME_STD,
  945. + CAN_BITTIME_BTR
  946. +} can_bittime_type_t;
  947. +
  948. +/* TSEG1 of controllers usually is a sum of synch_seg (always 1),
  949. + * prop_seg and phase_seg1, TSEG2 = phase_seg2 */
  950. +
  951. +struct can_bittime_std {
  952. + __u32 brp; /* baud rate prescaler */
  953. + __u8 prop_seg; /* from 1 to 8 */
  954. + __u8 phase_seg1; /* from 1 to 8 */
  955. + __u8 phase_seg2; /* from 1 to 8 */
  956. + __u8 sjw:7; /* from 1 to 4 */
  957. + __u8 sam:1; /* 1 - enable triple sampling */
  958. +};
  959. +
  960. +struct can_bittime_btr {
  961. + __u8 btr0;
  962. + __u8 btr1;
  963. +};
  964. +
  965. +struct can_bittime {
  966. + can_bittime_type_t type;
  967. + union {
  968. + struct can_bittime_std std;
  969. + struct can_bittime_btr btr;
  970. + };
  971. +};
  972. +
  973. +#define CAN_BAUDRATE_UNCONFIGURED ((__u32) 0xFFFFFFFFU)
  974. +#define CAN_BAUDRATE_UNKNOWN 0
  975. +
  976. +/* SIOC[SG]CANMODE */
  977. +
  978. +typedef __u32 can_mode_t;
  979. +
  980. +#define CAN_MODE_STOP 0
  981. +#define CAN_MODE_START 1
  982. +#define CAN_MODE_SLEEP 2
  983. +
  984. +
  985. +/* SIOC[SG]CANCTRLMODE */
  986. +
  987. +typedef __u32 can_ctrlmode_t;
  988. +
  989. +#define CAN_CTRLMODE_LOOPBACK 0x1
  990. +#define CAN_CTRLMODE_LISTENONLY 0x2
  991. +
  992. +
  993. +/* SIOCGCANFILTER */
  994. +
  995. +typedef __u32 can_filter_t;
  996. +
  997. +/* filter modes (may vary due to controller specific capabilities) */
  998. +#define CAN_FILTER_CAPAB 0 /* get filter type capabilities
  999. + (32 Bit value) */
  1000. +#define CAN_FILTER_MASK_VALUE 1 /* easy bit filter (see struct can_filter) */
  1001. +#define CAN_FILTER_SFF_BITMASK 2 /* bitfield with 2048 bit SFF filter */
  1002. + /* filters 3 - 31 currently undefined */
  1003. +
  1004. +#define CAN_FILTER_MAX 31 /* max. filter type value */
  1005. +
  1006. +
  1007. +/* SIOCGCANSTATE */
  1008. +
  1009. +typedef __u32 can_state_t;
  1010. +
  1011. +#define CAN_STATE_ACTIVE 0
  1012. +#define CAN_STATE_BUS_WARNING 1
  1013. +#define CAN_STATE_BUS_PASSIVE 2
  1014. +#define CAN_STATE_BUS_OFF 3
  1015. +#define CAN_STATE_SCANNING_BAUDRATE 4
  1016. +#define CAN_STATE_STOPPED 5
  1017. +#define CAN_STATE_SLEEPING 6
  1018. +
  1019. +
  1020. +/* SIOCGCANSTATS */
  1021. +
  1022. +struct can_device_stats {
  1023. + int error_warning;
  1024. + int data_overrun;
  1025. + int wakeup;
  1026. + int bus_error;
  1027. + int error_passive;
  1028. + int arbitration_lost;
  1029. + int restarts;
  1030. + int bus_error_at_init;
  1031. +};
  1032. +
  1033. +/* SIOC[SG]CANERRORCONFIG */
  1034. +
  1035. +typedef enum CAN_ERRCFG_TYPE {
  1036. + CAN_ERRCFG_MASK,
  1037. + CAN_ERRCFG_BUSERR,
  1038. + CAN_ERRCFG_BUSOFF
  1039. +} can_errcfg_type_t;
  1040. +
  1041. +/* tbd */
  1042. +
  1043. +#endif /* CAN_IOCTL_H */
  1044. --- /dev/null
  1045. +++ b/include/linux/can/version.h
  1046. @@ -0,0 +1,22 @@
  1047. +/*
  1048. + * linux/can/version.h
  1049. + *
  1050. + * Version information for the CAN network layer implementation
  1051. +
  1052. + * Author: Urs Thuermann <[email protected]>
  1053. + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
  1054. + * All rights reserved.
  1055. + *
  1056. + * Send feedback to <[email protected]>
  1057. + *
  1058. + */
  1059. +
  1060. +#ifndef CAN_VERSION_H
  1061. +#define CAN_VERSION_H
  1062. +
  1063. +#define RCSID(s) asm(".section .rodata.str1.1,\"aMS\",@progbits,1\n\t" \
  1064. + ".string \"" s "\"\n\t.previous\n")
  1065. +
  1066. +RCSID("$Id$");
  1067. +
  1068. +#endif /* CAN_VERSION_H */
  1069. --- a/net/can/Makefile
  1070. +++ b/net/can/Makefile
  1071. @@ -10,3 +10,6 @@ can-raw-objs := raw.o
  1072. obj-$(CONFIG_CAN_BCM) += can-bcm.o
  1073. can-bcm-objs := bcm.o
  1074. +
  1075. +obj-$(CONFIG_CAN) += candev.o
  1076. +candev-objs := dev.o
  1077. --- /dev/null
  1078. +++ b/net/can/dev.c
  1079. @@ -0,0 +1,292 @@
  1080. +/*
  1081. + * $Id$
  1082. + *
  1083. + * Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
  1084. + * Copyright (C) 2006 Andrey Volkov, Varma Electronics
  1085. + *
  1086. + * This program is free software; you can redistribute it and/or modify
  1087. + * it under the terms of the version 2 of the GNU General Public License
  1088. + * as published by the Free Software Foundation
  1089. + *
  1090. + * This program is distributed in the hope that it will be useful,
  1091. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1092. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1093. + * GNU General Public License for more details.
  1094. + *
  1095. + * You should have received a copy of the GNU General Public License
  1096. + * along with this program; if not, write to the Free Software
  1097. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  1098. + */
  1099. +
  1100. +#include <linux/module.h>
  1101. +#include <linux/netdevice.h>
  1102. +#include <linux/if_arp.h>
  1103. +#include <linux/can.h>
  1104. +#include <linux/can/dev.h>
  1105. +
  1106. +MODULE_DESCRIPTION("CAN netdevice library");
  1107. +MODULE_LICENSE("GPL v2");
  1108. +MODULE_AUTHOR("Marc Kleine-Budde <[email protected]>, "
  1109. + "Andrey Volkov <[email protected]>");
  1110. +
  1111. +/*
  1112. + Abstract:
  1113. + Baud rate calculated with next formula:
  1114. + baud = frq/(brp*(1 + prop_seg+ phase_seg1 + phase_seg2))
  1115. +
  1116. + This calc function based on work of Florian Hartwich and Armin Bassemi
  1117. + "The Configuration of the CAN Bit Timing"
  1118. + (http://www.semiconductors.bosch.de/pdf/CiA99Paper.pdf)
  1119. +
  1120. + Parameters:
  1121. + [in]
  1122. + bit_time_nsec - expected bit time in nanosecs
  1123. +
  1124. + [out]
  1125. + bit_time - calculated time segments, for meaning of
  1126. + each field read CAN standard.
  1127. +*/
  1128. +
  1129. +#define DEFAULT_MAX_BRP 64U
  1130. +#define DEFAULT_MAX_SJW 4U
  1131. +
  1132. +/* All below values in tq units */
  1133. +#define MAX_BIT_TIME 25U
  1134. +#define MIN_BIT_TIME 8U
  1135. +#define MAX_PROP_SEG 8U
  1136. +#define MAX_PHASE_SEG1 8U
  1137. +#define MAX_PHASE_SEG2 8U
  1138. +
  1139. +int can_calc_bit_time(struct can_priv *can, u32 baudrate,
  1140. + struct can_bittime_std *bit_time)
  1141. +{
  1142. + int best_error = -1; /* Ariphmetic error */
  1143. + int df, best_df = -1; /* oscillator's tolerance range */
  1144. + u32 quanta; /*in tq units*/
  1145. + u32 brp, phase_seg1, phase_seg2, sjw, prop_seg;
  1146. + u32 brp_min, brp_max, brp_expected;
  1147. + u64 tmp;
  1148. +
  1149. + /* baudrate range [1baud,1Mbaud] */
  1150. + if (baudrate == 0 || baudrate > 1000000UL)
  1151. + return -EINVAL;
  1152. +
  1153. + tmp = (u64)can->can_sys_clock*1000;
  1154. + do_div(tmp, baudrate);
  1155. + brp_expected = (u32)tmp;
  1156. +
  1157. + brp_min = brp_expected / (1000 * MAX_BIT_TIME);
  1158. + if (brp_min == 0)
  1159. + brp_min = 1;
  1160. + if (brp_min > can->max_brp)
  1161. + return -ERANGE;
  1162. +
  1163. + brp_max = (brp_expected + 500 * MIN_BIT_TIME) / (1000 * MIN_BIT_TIME);
  1164. + if (brp_max == 0)
  1165. + brp_max = 1;
  1166. + if (brp_max > can->max_brp)
  1167. + brp_max = can->max_brp;
  1168. +
  1169. + for (brp = brp_min; brp <= brp_max; brp++) {
  1170. + quanta = brp_expected / (brp * 1000);
  1171. + if (quanta < MAX_BIT_TIME && quanta * brp * 1000 !=
  1172. + brp_expected)
  1173. + quanta++;
  1174. + if (quanta < MIN_BIT_TIME || quanta > MAX_BIT_TIME)
  1175. + continue;
  1176. +
  1177. + phase_seg2 = min((quanta - 3) / 2, MAX_PHASE_SEG2);
  1178. + for (sjw = can->max_sjw; sjw > 0; sjw--) {
  1179. + for (; phase_seg2 > sjw; phase_seg2--) {
  1180. + u32 err1, err2;
  1181. + phase_seg1 = phase_seg2 % 2 ?
  1182. + phase_seg2-1 : phase_seg2;
  1183. + prop_seg = quanta-1 - phase_seg2 - phase_seg1;
  1184. + /*
  1185. + * FIXME: support of longer lines
  1186. + * (i.e. bigger prop_seg) is more prefered
  1187. + * than support of cheap oscillators
  1188. + * (i.e. bigger df/phase_seg1/phase_seg2)
  1189. + * */
  1190. +
  1191. + if (prop_seg < phase_seg1)
  1192. + continue;
  1193. + if (prop_seg > MAX_PROP_SEG)
  1194. + goto next_brp;
  1195. +
  1196. + err1 = phase_seg1 * brp * 500 * 1000 /
  1197. + (13 * brp_expected - phase_seg2 *
  1198. + brp * 1000);
  1199. + err2 = sjw * brp * 50 * 1000 / brp_expected;
  1200. +
  1201. + df = min(err1, err2);
  1202. + if (df >= best_df) {
  1203. + unsigned error = abs(brp_expected * 10 /
  1204. + (brp * (1 + prop_seg +
  1205. + phase_seg1 +
  1206. + phase_seg2)) - 10000);
  1207. +
  1208. + if (error > 10 || error > best_error)
  1209. + continue;
  1210. +
  1211. + if (error == best_error && prop_seg <
  1212. + bit_time->prop_seg)
  1213. + continue;
  1214. +
  1215. + best_error = error;
  1216. + best_df = df;
  1217. + bit_time->brp = brp;
  1218. + bit_time->prop_seg = prop_seg;
  1219. + bit_time->phase_seg1 = phase_seg1;
  1220. + bit_time->phase_seg2 = phase_seg2;
  1221. + bit_time->sjw = sjw;
  1222. + bit_time->sam =
  1223. + (bit_time->phase_seg1 > 3);
  1224. + }
  1225. + }
  1226. + }
  1227. +next_brp: ;
  1228. + }
  1229. +
  1230. + if (best_error < 0)
  1231. + return -EDOM;
  1232. + return 0;
  1233. +}
  1234. +EXPORT_SYMBOL(can_calc_bit_time);
  1235. +
  1236. +static int can_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  1237. +{
  1238. + struct can_priv *can = netdev_priv(dev);
  1239. + struct can_bittime *bt = (struct can_bittime *)&ifr->ifr_ifru;
  1240. + ulong *baudrate = (ulong *)&ifr->ifr_ifru;
  1241. + int ret = -EOPNOTSUPP;
  1242. +
  1243. + dev_dbg(ND2D(dev), "(%s) 0x%08x %p\n", __func__, cmd, &ifr->ifr_ifru);
  1244. +
  1245. + switch (cmd) {
  1246. + case SIOCSCANBAUDRATE:
  1247. + if (can->do_set_bit_time) {
  1248. + struct can_bittime bit_time;
  1249. + ret = can_calc_bit_time(can, *baudrate, &bit_time.std);
  1250. + if (ret != 0)
  1251. + break;
  1252. + bit_time.type = CAN_BITTIME_STD;
  1253. + ret = can->do_set_bit_time(dev, &bit_time);
  1254. + if (!ret) {
  1255. + can->baudrate = *baudrate;
  1256. + can->bit_time = bit_time;
  1257. + }
  1258. + }
  1259. + break;
  1260. + case SIOCGCANBAUDRATE:
  1261. + *baudrate = can->baudrate;
  1262. + ret = 0;
  1263. + break;
  1264. + case SIOCSCANCUSTOMBITTIME:
  1265. + if (can->do_set_bit_time) {
  1266. + ret = can->do_set_bit_time(dev, bt);
  1267. + if (!ret) {
  1268. + can->bit_time = *bt;
  1269. + if (bt->type == CAN_BITTIME_STD && bt->std.brp) {
  1270. + can->baudrate = can->can_sys_clock /
  1271. + (bt->std.brp * (1 + bt->std.prop_seg +
  1272. + bt->std.phase_seg1 +
  1273. + bt->std.phase_seg2));
  1274. + } else
  1275. + can->baudrate = CAN_BAUDRATE_UNKNOWN;
  1276. + }
  1277. + }
  1278. + break;
  1279. + case SIOCGCANCUSTOMBITTIME:
  1280. + *bt = can->bit_time;
  1281. + ret = 0;
  1282. + break;
  1283. + case SIOCSCANMODE:
  1284. + if (can->do_set_mode) {
  1285. + can_mode_t mode =
  1286. + *((can_mode_t *)(&ifr->ifr_ifru));
  1287. + if (mode == CAN_MODE_START &&
  1288. + can->baudrate == CAN_BAUDRATE_UNCONFIGURED) {
  1289. + dev_info(ND2D(dev), "Impossible to start \
  1290. + on UNKNOWN speed\n");
  1291. + ret = EINVAL;
  1292. + } else
  1293. + return can->do_set_mode(dev, mode);
  1294. + }
  1295. + break;
  1296. + case SIOCGCANMODE:
  1297. + *((can_mode_t *)(&ifr->ifr_ifru)) = can->mode;
  1298. + ret = 0;
  1299. + break;
  1300. + case SIOCSCANCTRLMODE:
  1301. + if (can->do_set_ctrlmode) {
  1302. + can_ctrlmode_t ctrlmode =
  1303. + *((can_ctrlmode_t *)(&ifr->ifr_ifru));
  1304. + return can->do_set_ctrlmode(dev, ctrlmode);
  1305. + }
  1306. + break;
  1307. + case SIOCGCANCTRLMODE:
  1308. + *((can_ctrlmode_t *)(&ifr->ifr_ifru)) = can->ctrlmode;
  1309. + ret = 0;
  1310. + break;
  1311. + case SIOCSCANFILTER:
  1312. + break;
  1313. + case SIOCGCANFILTER:
  1314. + break;
  1315. + case SIOCGCANSTATE:
  1316. + if (can->do_get_state)
  1317. + return can->do_get_state(dev,
  1318. + (can_state_t *)(&ifr->ifr_ifru));
  1319. + break;
  1320. + case SIOCGCANSTATS:
  1321. + *((struct can_device_stats *)(&ifr->ifr_ifru)) = can->can_stats;
  1322. + ret = 0;
  1323. + break;
  1324. + }
  1325. +
  1326. + return ret;
  1327. +}
  1328. +
  1329. +static void can_setup(struct net_device *dev)
  1330. +{
  1331. + dev->type = ARPHRD_CAN;
  1332. + dev->mtu = sizeof(struct can_frame);
  1333. + dev->do_ioctl = can_ioctl;
  1334. + dev->hard_header_len = 0;
  1335. + dev->addr_len = 0;
  1336. + dev->tx_queue_len = 10;
  1337. +
  1338. + /* New-style flags. */
  1339. + dev->flags = IFF_NOARP;
  1340. + dev->features = NETIF_F_NO_CSUM;
  1341. +}
  1342. +
  1343. +/*
  1344. + * Function alloc_candev
  1345. + * Allocates and sets up an CAN device
  1346. + */
  1347. +struct net_device *alloc_candev(int sizeof_priv)
  1348. +{
  1349. + struct net_device *dev;
  1350. + struct can_priv *priv;
  1351. +
  1352. + dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
  1353. + if (!dev)
  1354. + return NULL;
  1355. +
  1356. + priv = netdev_priv(dev);
  1357. +
  1358. + priv->baudrate = CAN_BAUDRATE_UNCONFIGURED;
  1359. + priv->max_brp = DEFAULT_MAX_BRP;
  1360. + priv->max_sjw = DEFAULT_MAX_SJW;
  1361. + spin_lock_init(&priv->irq_lock);
  1362. +
  1363. + return dev;
  1364. +}
  1365. +EXPORT_SYMBOL(alloc_candev);
  1366. +
  1367. +void free_candev(struct net_device *dev)
  1368. +{
  1369. + free_netdev(dev);
  1370. +}
  1371. +EXPORT_SYMBOL(free_candev);