diff options
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/Kconfig | 6 | ||||
-rw-r--r-- | drivers/net/can/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/can/at91_can.c | 138 | ||||
-rw-r--r-- | drivers/net/can/c_can/Kconfig | 15 | ||||
-rw-r--r-- | drivers/net/can/c_can/Makefile | 8 | ||||
-rw-r--r-- | drivers/net/can/c_can/c_can.c | 1158 | ||||
-rw-r--r-- | drivers/net/can/c_can/c_can.h | 86 | ||||
-rw-r--r-- | drivers/net/can/c_can/c_can_platform.c | 215 | ||||
-rw-r--r-- | drivers/net/can/janz-ican3.c | 2 | ||||
-rw-r--r-- | drivers/net/can/mcp251x.c | 2 | ||||
-rw-r--r-- | drivers/net/can/mscan/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/can/pch_can.c | 5 | ||||
-rw-r--r-- | drivers/net/can/softing/Kconfig | 30 | ||||
-rw-r--r-- | drivers/net/can/softing/Makefile | 6 | ||||
-rw-r--r-- | drivers/net/can/softing/softing.h | 167 | ||||
-rw-r--r-- | drivers/net/can/softing/softing_cs.c | 360 | ||||
-rw-r--r-- | drivers/net/can/softing/softing_fw.c | 691 | ||||
-rw-r--r-- | drivers/net/can/softing/softing_main.c | 893 | ||||
-rw-r--r-- | drivers/net/can/softing/softing_platform.h | 40 |
19 files changed, 3794 insertions, 32 deletions
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index d5a9db60ade9..1d699e3df547 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
@@ -23,7 +23,7 @@ config CAN_SLCAN | |||
23 | 23 | ||
24 | As only the sending and receiving of CAN frames is implemented, this | 24 | As only the sending and receiving of CAN frames is implemented, this |
25 | driver should work with the (serial/USB) CAN hardware from: | 25 | driver should work with the (serial/USB) CAN hardware from: |
26 | www.canusb.com / www.can232.com / www.mictronic.com / www.canhack.de | 26 | www.canusb.com / www.can232.com / www.mictronics.de / www.canhack.de |
27 | 27 | ||
28 | Userspace tools to attach the SLCAN line discipline (slcan_attach, | 28 | Userspace tools to attach the SLCAN line discipline (slcan_attach, |
29 | slcand) can be found in the can-utils at the SocketCAN SVN, see | 29 | slcand) can be found in the can-utils at the SocketCAN SVN, see |
@@ -115,8 +115,12 @@ source "drivers/net/can/mscan/Kconfig" | |||
115 | 115 | ||
116 | source "drivers/net/can/sja1000/Kconfig" | 116 | source "drivers/net/can/sja1000/Kconfig" |
117 | 117 | ||
118 | source "drivers/net/can/c_can/Kconfig" | ||
119 | |||
118 | source "drivers/net/can/usb/Kconfig" | 120 | source "drivers/net/can/usb/Kconfig" |
119 | 121 | ||
122 | source "drivers/net/can/softing/Kconfig" | ||
123 | |||
120 | config CAN_DEBUG_DEVICES | 124 | config CAN_DEBUG_DEVICES |
121 | bool "CAN devices debugging messages" | 125 | bool "CAN devices debugging messages" |
122 | depends on CAN | 126 | depends on CAN |
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 07ca159ba3f9..24ebfe8d758a 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile | |||
@@ -9,9 +9,11 @@ obj-$(CONFIG_CAN_DEV) += can-dev.o | |||
9 | can-dev-y := dev.o | 9 | can-dev-y := dev.o |
10 | 10 | ||
11 | obj-y += usb/ | 11 | obj-y += usb/ |
12 | obj-y += softing/ | ||
12 | 13 | ||
13 | obj-$(CONFIG_CAN_SJA1000) += sja1000/ | 14 | obj-$(CONFIG_CAN_SJA1000) += sja1000/ |
14 | obj-$(CONFIG_CAN_MSCAN) += mscan/ | 15 | obj-$(CONFIG_CAN_MSCAN) += mscan/ |
16 | obj-$(CONFIG_CAN_C_CAN) += c_can/ | ||
15 | obj-$(CONFIG_CAN_AT91) += at91_can.o | 17 | obj-$(CONFIG_CAN_AT91) += at91_can.o |
16 | obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o | 18 | obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o |
17 | obj-$(CONFIG_CAN_MCP251X) += mcp251x.o | 19 | obj-$(CONFIG_CAN_MCP251X) += mcp251x.o |
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 7ef83d06f7ed..57d2ffbbb433 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * at91_can.c - CAN network driver for AT91 SoC CAN controller | 2 | * at91_can.c - CAN network driver for AT91 SoC CAN controller |
3 | * | 3 | * |
4 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> | 4 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> |
5 | * (C) 2008, 2009, 2010 by Marc Kleine-Budde <kernel@pengutronix.de> | 5 | * (C) 2008, 2009, 2010, 2011 by Marc Kleine-Budde <kernel@pengutronix.de> |
6 | * | 6 | * |
7 | * This software may be distributed under the terms of the GNU General | 7 | * This software may be distributed under the terms of the GNU General |
8 | * Public License ("GPL") version 2 as distributed in the 'COPYING' | 8 | * Public License ("GPL") version 2 as distributed in the 'COPYING' |
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/netdevice.h> | 31 | #include <linux/netdevice.h> |
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/rtnetlink.h> | ||
33 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
34 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
35 | #include <linux/string.h> | 36 | #include <linux/string.h> |
@@ -40,22 +41,23 @@ | |||
40 | 41 | ||
41 | #include <mach/board.h> | 42 | #include <mach/board.h> |
42 | 43 | ||
43 | #define AT91_NAPI_WEIGHT 12 | 44 | #define AT91_NAPI_WEIGHT 11 |
44 | 45 | ||
45 | /* | 46 | /* |
46 | * RX/TX Mailbox split | 47 | * RX/TX Mailbox split |
47 | * don't dare to touch | 48 | * don't dare to touch |
48 | */ | 49 | */ |
49 | #define AT91_MB_RX_NUM 12 | 50 | #define AT91_MB_RX_NUM 11 |
50 | #define AT91_MB_TX_SHIFT 2 | 51 | #define AT91_MB_TX_SHIFT 2 |
51 | 52 | ||
52 | #define AT91_MB_RX_FIRST 0 | 53 | #define AT91_MB_RX_FIRST 1 |
53 | #define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) | 54 | #define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) |
54 | 55 | ||
55 | #define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) | 56 | #define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) |
56 | #define AT91_MB_RX_SPLIT 8 | 57 | #define AT91_MB_RX_SPLIT 8 |
57 | #define AT91_MB_RX_LOW_LAST (AT91_MB_RX_SPLIT - 1) | 58 | #define AT91_MB_RX_LOW_LAST (AT91_MB_RX_SPLIT - 1) |
58 | #define AT91_MB_RX_LOW_MASK (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT)) | 59 | #define AT91_MB_RX_LOW_MASK (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT) & \ |
60 | ~AT91_MB_RX_MASK(AT91_MB_RX_FIRST)) | ||
59 | 61 | ||
60 | #define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) | 62 | #define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) |
61 | #define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) | 63 | #define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) |
@@ -168,6 +170,8 @@ struct at91_priv { | |||
168 | 170 | ||
169 | struct clk *clk; | 171 | struct clk *clk; |
170 | struct at91_can_data *pdata; | 172 | struct at91_can_data *pdata; |
173 | |||
174 | canid_t mb0_id; | ||
171 | }; | 175 | }; |
172 | 176 | ||
173 | static struct can_bittiming_const at91_bittiming_const = { | 177 | static struct can_bittiming_const at91_bittiming_const = { |
@@ -220,6 +224,18 @@ static inline void set_mb_mode(const struct at91_priv *priv, unsigned int mb, | |||
220 | set_mb_mode_prio(priv, mb, mode, 0); | 224 | set_mb_mode_prio(priv, mb, mode, 0); |
221 | } | 225 | } |
222 | 226 | ||
227 | static inline u32 at91_can_id_to_reg_mid(canid_t can_id) | ||
228 | { | ||
229 | u32 reg_mid; | ||
230 | |||
231 | if (can_id & CAN_EFF_FLAG) | ||
232 | reg_mid = (can_id & CAN_EFF_MASK) | AT91_MID_MIDE; | ||
233 | else | ||
234 | reg_mid = (can_id & CAN_SFF_MASK) << 18; | ||
235 | |||
236 | return reg_mid; | ||
237 | } | ||
238 | |||
223 | /* | 239 | /* |
224 | * Swtich transceiver on or off | 240 | * Swtich transceiver on or off |
225 | */ | 241 | */ |
@@ -233,12 +249,22 @@ static void at91_setup_mailboxes(struct net_device *dev) | |||
233 | { | 249 | { |
234 | struct at91_priv *priv = netdev_priv(dev); | 250 | struct at91_priv *priv = netdev_priv(dev); |
235 | unsigned int i; | 251 | unsigned int i; |
252 | u32 reg_mid; | ||
236 | 253 | ||
237 | /* | 254 | /* |
238 | * The first 12 mailboxes are used as a reception FIFO. The | 255 | * Due to a chip bug (errata 50.2.6.3 & 50.3.5.3) the first |
239 | * last mailbox is configured with overwrite option. The | 256 | * mailbox is disabled. The next 11 mailboxes are used as a |
240 | * overwrite flag indicates a FIFO overflow. | 257 | * reception FIFO. The last mailbox is configured with |
258 | * overwrite option. The overwrite flag indicates a FIFO | ||
259 | * overflow. | ||
241 | */ | 260 | */ |
261 | reg_mid = at91_can_id_to_reg_mid(priv->mb0_id); | ||
262 | for (i = 0; i < AT91_MB_RX_FIRST; i++) { | ||
263 | set_mb_mode(priv, i, AT91_MB_MODE_DISABLED); | ||
264 | at91_write(priv, AT91_MID(i), reg_mid); | ||
265 | at91_write(priv, AT91_MCR(i), 0x0); /* clear dlc */ | ||
266 | } | ||
267 | |||
242 | for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) | 268 | for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) |
243 | set_mb_mode(priv, i, AT91_MB_MODE_RX); | 269 | set_mb_mode(priv, i, AT91_MB_MODE_RX); |
244 | set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); | 270 | set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); |
@@ -254,7 +280,8 @@ static void at91_setup_mailboxes(struct net_device *dev) | |||
254 | set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0); | 280 | set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0); |
255 | 281 | ||
256 | /* Reset tx and rx helper pointers */ | 282 | /* Reset tx and rx helper pointers */ |
257 | priv->tx_next = priv->tx_echo = priv->rx_next = 0; | 283 | priv->tx_next = priv->tx_echo = 0; |
284 | priv->rx_next = AT91_MB_RX_FIRST; | ||
258 | } | 285 | } |
259 | 286 | ||
260 | static int at91_set_bittiming(struct net_device *dev) | 287 | static int at91_set_bittiming(struct net_device *dev) |
@@ -372,12 +399,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
372 | netdev_err(dev, "BUG! TX buffer full when queue awake!\n"); | 399 | netdev_err(dev, "BUG! TX buffer full when queue awake!\n"); |
373 | return NETDEV_TX_BUSY; | 400 | return NETDEV_TX_BUSY; |
374 | } | 401 | } |
375 | 402 | reg_mid = at91_can_id_to_reg_mid(cf->can_id); | |
376 | if (cf->can_id & CAN_EFF_FLAG) | ||
377 | reg_mid = (cf->can_id & CAN_EFF_MASK) | AT91_MID_MIDE; | ||
378 | else | ||
379 | reg_mid = (cf->can_id & CAN_SFF_MASK) << 18; | ||
380 | |||
381 | reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) | | 403 | reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) | |
382 | (cf->can_dlc << 16) | AT91_MCR_MTCR; | 404 | (cf->can_dlc << 16) | AT91_MCR_MTCR; |
383 | 405 | ||
@@ -539,27 +561,31 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) | |||
539 | * | 561 | * |
540 | * Theory of Operation: | 562 | * Theory of Operation: |
541 | * | 563 | * |
542 | * 12 of the 16 mailboxes on the chip are reserved for RX. we split | 564 | * 11 of the 16 mailboxes on the chip are reserved for RX. we split |
543 | * them into 2 groups. The lower group holds 8 and upper 4 mailboxes. | 565 | * them into 2 groups. The lower group holds 7 and upper 4 mailboxes. |
544 | * | 566 | * |
545 | * Like it or not, but the chip always saves a received CAN message | 567 | * Like it or not, but the chip always saves a received CAN message |
546 | * into the first free mailbox it finds (starting with the | 568 | * into the first free mailbox it finds (starting with the |
547 | * lowest). This makes it very difficult to read the messages in the | 569 | * lowest). This makes it very difficult to read the messages in the |
548 | * right order from the chip. This is how we work around that problem: | 570 | * right order from the chip. This is how we work around that problem: |
549 | * | 571 | * |
550 | * The first message goes into mb nr. 0 and issues an interrupt. All | 572 | * The first message goes into mb nr. 1 and issues an interrupt. All |
551 | * rx ints are disabled in the interrupt handler and a napi poll is | 573 | * rx ints are disabled in the interrupt handler and a napi poll is |
552 | * scheduled. We read the mailbox, but do _not_ reenable the mb (to | 574 | * scheduled. We read the mailbox, but do _not_ reenable the mb (to |
553 | * receive another message). | 575 | * receive another message). |
554 | * | 576 | * |
555 | * lower mbxs upper | 577 | * lower mbxs upper |
556 | * ______^______ __^__ | 578 | * ____^______ __^__ |
557 | * / \ / \ | 579 | * / \ / \ |
558 | * +-+-+-+-+-+-+-+-++-+-+-+-+ | 580 | * +-+-+-+-+-+-+-+-++-+-+-+-+ |
559 | * |x|x|x|x|x|x|x|x|| | | | | | 581 | * | |x|x|x|x|x|x|x|| | | | | |
560 | * +-+-+-+-+-+-+-+-++-+-+-+-+ | 582 | * +-+-+-+-+-+-+-+-++-+-+-+-+ |
561 | * 0 0 0 0 0 0 0 0 0 0 1 1 \ mail | 583 | * 0 0 0 0 0 0 0 0 0 0 1 1 \ mail |
562 | * 0 1 2 3 4 5 6 7 8 9 0 1 / box | 584 | * 0 1 2 3 4 5 6 7 8 9 0 1 / box |
585 | * ^ | ||
586 | * | | ||
587 | * \ | ||
588 | * unused, due to chip bug | ||
563 | * | 589 | * |
564 | * The variable priv->rx_next points to the next mailbox to read a | 590 | * The variable priv->rx_next points to the next mailbox to read a |
565 | * message from. As long we're in the lower mailboxes we just read the | 591 | * message from. As long we're in the lower mailboxes we just read the |
@@ -590,10 +616,10 @@ static int at91_poll_rx(struct net_device *dev, int quota) | |||
590 | "order of incoming frames cannot be guaranteed\n"); | 616 | "order of incoming frames cannot be guaranteed\n"); |
591 | 617 | ||
592 | again: | 618 | again: |
593 | for (mb = find_next_bit(addr, AT91_MB_RX_NUM, priv->rx_next); | 619 | for (mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, priv->rx_next); |
594 | mb < AT91_MB_RX_NUM && quota > 0; | 620 | mb < AT91_MB_RX_LAST + 1 && quota > 0; |
595 | reg_sr = at91_read(priv, AT91_SR), | 621 | reg_sr = at91_read(priv, AT91_SR), |
596 | mb = find_next_bit(addr, AT91_MB_RX_NUM, ++priv->rx_next)) { | 622 | mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, ++priv->rx_next)) { |
597 | at91_read_msg(dev, mb); | 623 | at91_read_msg(dev, mb); |
598 | 624 | ||
599 | /* reactivate mailboxes */ | 625 | /* reactivate mailboxes */ |
@@ -610,8 +636,8 @@ static int at91_poll_rx(struct net_device *dev, int quota) | |||
610 | 636 | ||
611 | /* upper group completed, look again in lower */ | 637 | /* upper group completed, look again in lower */ |
612 | if (priv->rx_next > AT91_MB_RX_LOW_LAST && | 638 | if (priv->rx_next > AT91_MB_RX_LOW_LAST && |
613 | quota > 0 && mb >= AT91_MB_RX_NUM) { | 639 | quota > 0 && mb > AT91_MB_RX_LAST) { |
614 | priv->rx_next = 0; | 640 | priv->rx_next = AT91_MB_RX_FIRST; |
615 | goto again; | 641 | goto again; |
616 | } | 642 | } |
617 | 643 | ||
@@ -1037,6 +1063,64 @@ static const struct net_device_ops at91_netdev_ops = { | |||
1037 | .ndo_start_xmit = at91_start_xmit, | 1063 | .ndo_start_xmit = at91_start_xmit, |
1038 | }; | 1064 | }; |
1039 | 1065 | ||
1066 | static ssize_t at91_sysfs_show_mb0_id(struct device *dev, | ||
1067 | struct device_attribute *attr, char *buf) | ||
1068 | { | ||
1069 | struct at91_priv *priv = netdev_priv(to_net_dev(dev)); | ||
1070 | |||
1071 | if (priv->mb0_id & CAN_EFF_FLAG) | ||
1072 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", priv->mb0_id); | ||
1073 | else | ||
1074 | return snprintf(buf, PAGE_SIZE, "0x%03x\n", priv->mb0_id); | ||
1075 | } | ||
1076 | |||
1077 | static ssize_t at91_sysfs_set_mb0_id(struct device *dev, | ||
1078 | struct device_attribute *attr, const char *buf, size_t count) | ||
1079 | { | ||
1080 | struct net_device *ndev = to_net_dev(dev); | ||
1081 | struct at91_priv *priv = netdev_priv(ndev); | ||
1082 | unsigned long can_id; | ||
1083 | ssize_t ret; | ||
1084 | int err; | ||
1085 | |||
1086 | rtnl_lock(); | ||
1087 | |||
1088 | if (ndev->flags & IFF_UP) { | ||
1089 | ret = -EBUSY; | ||
1090 | goto out; | ||
1091 | } | ||
1092 | |||
1093 | err = strict_strtoul(buf, 0, &can_id); | ||
1094 | if (err) { | ||
1095 | ret = err; | ||
1096 | goto out; | ||
1097 | } | ||
1098 | |||
1099 | if (can_id & CAN_EFF_FLAG) | ||
1100 | can_id &= CAN_EFF_MASK | CAN_EFF_FLAG; | ||
1101 | else | ||
1102 | can_id &= CAN_SFF_MASK; | ||
1103 | |||
1104 | priv->mb0_id = can_id; | ||
1105 | ret = count; | ||
1106 | |||
1107 | out: | ||
1108 | rtnl_unlock(); | ||
1109 | return ret; | ||
1110 | } | ||
1111 | |||
1112 | static DEVICE_ATTR(mb0_id, S_IWUSR | S_IRUGO, | ||
1113 | at91_sysfs_show_mb0_id, at91_sysfs_set_mb0_id); | ||
1114 | |||
1115 | static struct attribute *at91_sysfs_attrs[] = { | ||
1116 | &dev_attr_mb0_id.attr, | ||
1117 | NULL, | ||
1118 | }; | ||
1119 | |||
1120 | static struct attribute_group at91_sysfs_attr_group = { | ||
1121 | .attrs = at91_sysfs_attrs, | ||
1122 | }; | ||
1123 | |||
1040 | static int __devinit at91_can_probe(struct platform_device *pdev) | 1124 | static int __devinit at91_can_probe(struct platform_device *pdev) |
1041 | { | 1125 | { |
1042 | struct net_device *dev; | 1126 | struct net_device *dev; |
@@ -1082,6 +1166,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev) | |||
1082 | dev->netdev_ops = &at91_netdev_ops; | 1166 | dev->netdev_ops = &at91_netdev_ops; |
1083 | dev->irq = irq; | 1167 | dev->irq = irq; |
1084 | dev->flags |= IFF_ECHO; | 1168 | dev->flags |= IFF_ECHO; |
1169 | dev->sysfs_groups[0] = &at91_sysfs_attr_group; | ||
1085 | 1170 | ||
1086 | priv = netdev_priv(dev); | 1171 | priv = netdev_priv(dev); |
1087 | priv->can.clock.freq = clk_get_rate(clk); | 1172 | priv->can.clock.freq = clk_get_rate(clk); |
@@ -1093,6 +1178,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev) | |||
1093 | priv->dev = dev; | 1178 | priv->dev = dev; |
1094 | priv->clk = clk; | 1179 | priv->clk = clk; |
1095 | priv->pdata = pdev->dev.platform_data; | 1180 | priv->pdata = pdev->dev.platform_data; |
1181 | priv->mb0_id = 0x7ff; | ||
1096 | 1182 | ||
1097 | netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT); | 1183 | netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT); |
1098 | 1184 | ||
diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig new file mode 100644 index 000000000000..ffb9773d102d --- /dev/null +++ b/drivers/net/can/c_can/Kconfig | |||
@@ -0,0 +1,15 @@ | |||
1 | menuconfig CAN_C_CAN | ||
2 | tristate "Bosch C_CAN devices" | ||
3 | depends on CAN_DEV && HAS_IOMEM | ||
4 | |||
5 | if CAN_C_CAN | ||
6 | |||
7 | config CAN_C_CAN_PLATFORM | ||
8 | tristate "Generic Platform Bus based C_CAN driver" | ||
9 | ---help--- | ||
10 | This driver adds support for the C_CAN chips connected to | ||
11 | the "platform bus" (Linux abstraction for directly to the | ||
12 | processor attached devices) which can be found on various | ||
13 | boards from ST Microelectronics (http://www.st.com) | ||
14 | like the SPEAr1310 and SPEAr320 evaluation boards. | ||
15 | endif | ||
diff --git a/drivers/net/can/c_can/Makefile b/drivers/net/can/c_can/Makefile new file mode 100644 index 000000000000..9273f6d5c4b7 --- /dev/null +++ b/drivers/net/can/c_can/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the Bosch C_CAN controller drivers. | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_CAN_C_CAN) += c_can.o | ||
6 | obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o | ||
7 | |||
8 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG | ||
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c new file mode 100644 index 000000000000..14050786218a --- /dev/null +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -0,0 +1,1158 @@ | |||
1 | /* | ||
2 | * CAN bus driver for Bosch C_CAN controller | ||
3 | * | ||
4 | * Copyright (C) 2010 ST Microelectronics | ||
5 | * Bhupesh Sharma <bhupesh.sharma@st.com> | ||
6 | * | ||
7 | * Borrowed heavily from the C_CAN driver originally written by: | ||
8 | * Copyright (C) 2007 | ||
9 | * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de> | ||
10 | * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch> | ||
11 | * | ||
12 | * TX and RX NAPI implementation has been borrowed from at91 CAN driver | ||
13 | * written by: | ||
14 | * Copyright | ||
15 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> | ||
16 | * (C) 2008, 2009 by Marc Kleine-Budde <kernel@pengutronix.de> | ||
17 | * | ||
18 | * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. | ||
19 | * Bosch C_CAN user manual can be obtained from: | ||
20 | * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ | ||
21 | * users_manual_c_can.pdf | ||
22 | * | ||
23 | * This file is licensed under the terms of the GNU General Public | ||
24 | * License version 2. This program is licensed "as is" without any | ||
25 | * warranty of any kind, whether express or implied. | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/version.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/netdevice.h> | ||
34 | #include <linux/if_arp.h> | ||
35 | #include <linux/if_ether.h> | ||
36 | #include <linux/list.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <linux/io.h> | ||
39 | |||
40 | #include <linux/can.h> | ||
41 | #include <linux/can/dev.h> | ||
42 | #include <linux/can/error.h> | ||
43 | |||
44 | #include "c_can.h" | ||
45 | |||
46 | /* control register */ | ||
47 | #define CONTROL_TEST BIT(7) | ||
48 | #define CONTROL_CCE BIT(6) | ||
49 | #define CONTROL_DISABLE_AR BIT(5) | ||
50 | #define CONTROL_ENABLE_AR (0 << 5) | ||
51 | #define CONTROL_EIE BIT(3) | ||
52 | #define CONTROL_SIE BIT(2) | ||
53 | #define CONTROL_IE BIT(1) | ||
54 | #define CONTROL_INIT BIT(0) | ||
55 | |||
56 | /* test register */ | ||
57 | #define TEST_RX BIT(7) | ||
58 | #define TEST_TX1 BIT(6) | ||
59 | #define TEST_TX2 BIT(5) | ||
60 | #define TEST_LBACK BIT(4) | ||
61 | #define TEST_SILENT BIT(3) | ||
62 | #define TEST_BASIC BIT(2) | ||
63 | |||
64 | /* status register */ | ||
65 | #define STATUS_BOFF BIT(7) | ||
66 | #define STATUS_EWARN BIT(6) | ||
67 | #define STATUS_EPASS BIT(5) | ||
68 | #define STATUS_RXOK BIT(4) | ||
69 | #define STATUS_TXOK BIT(3) | ||
70 | |||
71 | /* error counter register */ | ||
72 | #define ERR_CNT_TEC_MASK 0xff | ||
73 | #define ERR_CNT_TEC_SHIFT 0 | ||
74 | #define ERR_CNT_REC_SHIFT 8 | ||
75 | #define ERR_CNT_REC_MASK (0x7f << ERR_CNT_REC_SHIFT) | ||
76 | #define ERR_CNT_RP_SHIFT 15 | ||
77 | #define ERR_CNT_RP_MASK (0x1 << ERR_CNT_RP_SHIFT) | ||
78 | |||
79 | /* bit-timing register */ | ||
80 | #define BTR_BRP_MASK 0x3f | ||
81 | #define BTR_BRP_SHIFT 0 | ||
82 | #define BTR_SJW_SHIFT 6 | ||
83 | #define BTR_SJW_MASK (0x3 << BTR_SJW_SHIFT) | ||
84 | #define BTR_TSEG1_SHIFT 8 | ||
85 | #define BTR_TSEG1_MASK (0xf << BTR_TSEG1_SHIFT) | ||
86 | #define BTR_TSEG2_SHIFT 12 | ||
87 | #define BTR_TSEG2_MASK (0x7 << BTR_TSEG2_SHIFT) | ||
88 | |||
89 | /* brp extension register */ | ||
90 | #define BRP_EXT_BRPE_MASK 0x0f | ||
91 | #define BRP_EXT_BRPE_SHIFT 0 | ||
92 | |||
93 | /* IFx command request */ | ||
94 | #define IF_COMR_BUSY BIT(15) | ||
95 | |||
96 | /* IFx command mask */ | ||
97 | #define IF_COMM_WR BIT(7) | ||
98 | #define IF_COMM_MASK BIT(6) | ||
99 | #define IF_COMM_ARB BIT(5) | ||
100 | #define IF_COMM_CONTROL BIT(4) | ||
101 | #define IF_COMM_CLR_INT_PND BIT(3) | ||
102 | #define IF_COMM_TXRQST BIT(2) | ||
103 | #define IF_COMM_DATAA BIT(1) | ||
104 | #define IF_COMM_DATAB BIT(0) | ||
105 | #define IF_COMM_ALL (IF_COMM_MASK | IF_COMM_ARB | \ | ||
106 | IF_COMM_CONTROL | IF_COMM_TXRQST | \ | ||
107 | IF_COMM_DATAA | IF_COMM_DATAB) | ||
108 | |||
109 | /* IFx arbitration */ | ||
110 | #define IF_ARB_MSGVAL BIT(15) | ||
111 | #define IF_ARB_MSGXTD BIT(14) | ||
112 | #define IF_ARB_TRANSMIT BIT(13) | ||
113 | |||
114 | /* IFx message control */ | ||
115 | #define IF_MCONT_NEWDAT BIT(15) | ||
116 | #define IF_MCONT_MSGLST BIT(14) | ||
117 | #define IF_MCONT_CLR_MSGLST (0 << 14) | ||
118 | #define IF_MCONT_INTPND BIT(13) | ||
119 | #define IF_MCONT_UMASK BIT(12) | ||
120 | #define IF_MCONT_TXIE BIT(11) | ||
121 | #define IF_MCONT_RXIE BIT(10) | ||
122 | #define IF_MCONT_RMTEN BIT(9) | ||
123 | #define IF_MCONT_TXRQST BIT(8) | ||
124 | #define IF_MCONT_EOB BIT(7) | ||
125 | #define IF_MCONT_DLC_MASK 0xf | ||
126 | |||
127 | /* | ||
128 | * IFx register masks: | ||
129 | * allow easy operation on 16-bit registers when the | ||
130 | * argument is 32-bit instead | ||
131 | */ | ||
132 | #define IFX_WRITE_LOW_16BIT(x) ((x) & 0xFFFF) | ||
133 | #define IFX_WRITE_HIGH_16BIT(x) (((x) & 0xFFFF0000) >> 16) | ||
134 | |||
135 | /* message object split */ | ||
136 | #define C_CAN_NO_OF_OBJECTS 32 | ||
137 | #define C_CAN_MSG_OBJ_RX_NUM 16 | ||
138 | #define C_CAN_MSG_OBJ_TX_NUM 16 | ||
139 | |||
140 | #define C_CAN_MSG_OBJ_RX_FIRST 1 | ||
141 | #define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \ | ||
142 | C_CAN_MSG_OBJ_RX_NUM - 1) | ||
143 | |||
144 | #define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1) | ||
145 | #define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \ | ||
146 | C_CAN_MSG_OBJ_TX_NUM - 1) | ||
147 | |||
148 | #define C_CAN_MSG_OBJ_RX_SPLIT 9 | ||
149 | #define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) | ||
150 | |||
151 | #define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) | ||
152 | #define RECEIVE_OBJECT_BITS 0x0000ffff | ||
153 | |||
154 | /* status interrupt */ | ||
155 | #define STATUS_INTERRUPT 0x8000 | ||
156 | |||
157 | /* global interrupt masks */ | ||
158 | #define ENABLE_ALL_INTERRUPTS 1 | ||
159 | #define DISABLE_ALL_INTERRUPTS 0 | ||
160 | |||
161 | /* minimum timeout for checking BUSY status */ | ||
162 | #define MIN_TIMEOUT_VALUE 6 | ||
163 | |||
164 | /* napi related */ | ||
165 | #define C_CAN_NAPI_WEIGHT C_CAN_MSG_OBJ_RX_NUM | ||
166 | |||
167 | /* c_can lec values */ | ||
168 | enum c_can_lec_type { | ||
169 | LEC_NO_ERROR = 0, | ||
170 | LEC_STUFF_ERROR, | ||
171 | LEC_FORM_ERROR, | ||
172 | LEC_ACK_ERROR, | ||
173 | LEC_BIT1_ERROR, | ||
174 | LEC_BIT0_ERROR, | ||
175 | LEC_CRC_ERROR, | ||
176 | LEC_UNUSED, | ||
177 | }; | ||
178 | |||
179 | /* | ||
180 | * c_can error types: | ||
181 | * Bus errors (BUS_OFF, ERROR_WARNING, ERROR_PASSIVE) are supported | ||
182 | */ | ||
183 | enum c_can_bus_error_types { | ||
184 | C_CAN_NO_ERROR = 0, | ||
185 | C_CAN_BUS_OFF, | ||
186 | C_CAN_ERROR_WARNING, | ||
187 | C_CAN_ERROR_PASSIVE, | ||
188 | }; | ||
189 | |||
190 | static struct can_bittiming_const c_can_bittiming_const = { | ||
191 | .name = KBUILD_MODNAME, | ||
192 | .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | ||
193 | .tseg1_max = 16, | ||
194 | .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | ||
195 | .tseg2_max = 8, | ||
196 | .sjw_max = 4, | ||
197 | .brp_min = 1, | ||
198 | .brp_max = 1024, /* 6-bit BRP field + 4-bit BRPE field*/ | ||
199 | .brp_inc = 1, | ||
200 | }; | ||
201 | |||
202 | static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) | ||
203 | { | ||
204 | return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) + | ||
205 | C_CAN_MSG_OBJ_TX_FIRST; | ||
206 | } | ||
207 | |||
208 | static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv) | ||
209 | { | ||
210 | return (priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) + | ||
211 | C_CAN_MSG_OBJ_TX_FIRST; | ||
212 | } | ||
213 | |||
214 | static u32 c_can_read_reg32(struct c_can_priv *priv, void *reg) | ||
215 | { | ||
216 | u32 val = priv->read_reg(priv, reg); | ||
217 | val |= ((u32) priv->read_reg(priv, reg + 2)) << 16; | ||
218 | return val; | ||
219 | } | ||
220 | |||
221 | static void c_can_enable_all_interrupts(struct c_can_priv *priv, | ||
222 | int enable) | ||
223 | { | ||
224 | unsigned int cntrl_save = priv->read_reg(priv, | ||
225 | &priv->regs->control); | ||
226 | |||
227 | if (enable) | ||
228 | cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE); | ||
229 | else | ||
230 | cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE); | ||
231 | |||
232 | priv->write_reg(priv, &priv->regs->control, cntrl_save); | ||
233 | } | ||
234 | |||
235 | static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) | ||
236 | { | ||
237 | int count = MIN_TIMEOUT_VALUE; | ||
238 | |||
239 | while (count && priv->read_reg(priv, | ||
240 | &priv->regs->ifregs[iface].com_req) & | ||
241 | IF_COMR_BUSY) { | ||
242 | count--; | ||
243 | udelay(1); | ||
244 | } | ||
245 | |||
246 | if (!count) | ||
247 | return 1; | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static inline void c_can_object_get(struct net_device *dev, | ||
253 | int iface, int objno, int mask) | ||
254 | { | ||
255 | struct c_can_priv *priv = netdev_priv(dev); | ||
256 | |||
257 | /* | ||
258 | * As per specs, after writting the message object number in the | ||
259 | * IF command request register the transfer b/w interface | ||
260 | * register and message RAM must be complete in 6 CAN-CLK | ||
261 | * period. | ||
262 | */ | ||
263 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, | ||
264 | IFX_WRITE_LOW_16BIT(mask)); | ||
265 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, | ||
266 | IFX_WRITE_LOW_16BIT(objno)); | ||
267 | |||
268 | if (c_can_msg_obj_is_busy(priv, iface)) | ||
269 | netdev_err(dev, "timed out in object get\n"); | ||
270 | } | ||
271 | |||
272 | static inline void c_can_object_put(struct net_device *dev, | ||
273 | int iface, int objno, int mask) | ||
274 | { | ||
275 | struct c_can_priv *priv = netdev_priv(dev); | ||
276 | |||
277 | /* | ||
278 | * As per specs, after writting the message object number in the | ||
279 | * IF command request register the transfer b/w interface | ||
280 | * register and message RAM must be complete in 6 CAN-CLK | ||
281 | * period. | ||
282 | */ | ||
283 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, | ||
284 | (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask))); | ||
285 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, | ||
286 | IFX_WRITE_LOW_16BIT(objno)); | ||
287 | |||
288 | if (c_can_msg_obj_is_busy(priv, iface)) | ||
289 | netdev_err(dev, "timed out in object put\n"); | ||
290 | } | ||
291 | |||
292 | static void c_can_write_msg_object(struct net_device *dev, | ||
293 | int iface, struct can_frame *frame, int objno) | ||
294 | { | ||
295 | int i; | ||
296 | u16 flags = 0; | ||
297 | unsigned int id; | ||
298 | struct c_can_priv *priv = netdev_priv(dev); | ||
299 | |||
300 | if (!(frame->can_id & CAN_RTR_FLAG)) | ||
301 | flags |= IF_ARB_TRANSMIT; | ||
302 | |||
303 | if (frame->can_id & CAN_EFF_FLAG) { | ||
304 | id = frame->can_id & CAN_EFF_MASK; | ||
305 | flags |= IF_ARB_MSGXTD; | ||
306 | } else | ||
307 | id = ((frame->can_id & CAN_SFF_MASK) << 18); | ||
308 | |||
309 | flags |= IF_ARB_MSGVAL; | ||
310 | |||
311 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, | ||
312 | IFX_WRITE_LOW_16BIT(id)); | ||
313 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, flags | | ||
314 | IFX_WRITE_HIGH_16BIT(id)); | ||
315 | |||
316 | for (i = 0; i < frame->can_dlc; i += 2) { | ||
317 | priv->write_reg(priv, &priv->regs->ifregs[iface].data[i / 2], | ||
318 | frame->data[i] | (frame->data[i + 1] << 8)); | ||
319 | } | ||
320 | |||
321 | /* enable interrupt for this message object */ | ||
322 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
323 | IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | | ||
324 | frame->can_dlc); | ||
325 | c_can_object_put(dev, iface, objno, IF_COMM_ALL); | ||
326 | } | ||
327 | |||
328 | static inline void c_can_mark_rx_msg_obj(struct net_device *dev, | ||
329 | int iface, int ctrl_mask, | ||
330 | int obj) | ||
331 | { | ||
332 | struct c_can_priv *priv = netdev_priv(dev); | ||
333 | |||
334 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
335 | ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND)); | ||
336 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); | ||
337 | |||
338 | } | ||
339 | |||
340 | static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, | ||
341 | int iface, | ||
342 | int ctrl_mask) | ||
343 | { | ||
344 | int i; | ||
345 | struct c_can_priv *priv = netdev_priv(dev); | ||
346 | |||
347 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { | ||
348 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
349 | ctrl_mask & ~(IF_MCONT_MSGLST | | ||
350 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); | ||
351 | c_can_object_put(dev, iface, i, IF_COMM_CONTROL); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | static inline void c_can_activate_rx_msg_obj(struct net_device *dev, | ||
356 | int iface, int ctrl_mask, | ||
357 | int obj) | ||
358 | { | ||
359 | struct c_can_priv *priv = netdev_priv(dev); | ||
360 | |||
361 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
362 | ctrl_mask & ~(IF_MCONT_MSGLST | | ||
363 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); | ||
364 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); | ||
365 | } | ||
366 | |||
367 | static void c_can_handle_lost_msg_obj(struct net_device *dev, | ||
368 | int iface, int objno) | ||
369 | { | ||
370 | struct c_can_priv *priv = netdev_priv(dev); | ||
371 | struct net_device_stats *stats = &dev->stats; | ||
372 | struct sk_buff *skb; | ||
373 | struct can_frame *frame; | ||
374 | |||
375 | netdev_err(dev, "msg lost in buffer %d\n", objno); | ||
376 | |||
377 | c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); | ||
378 | |||
379 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
380 | IF_MCONT_CLR_MSGLST); | ||
381 | |||
382 | c_can_object_put(dev, 0, objno, IF_COMM_CONTROL); | ||
383 | |||
384 | /* create an error msg */ | ||
385 | skb = alloc_can_err_skb(dev, &frame); | ||
386 | if (unlikely(!skb)) | ||
387 | return; | ||
388 | |||
389 | frame->can_id |= CAN_ERR_CRTL; | ||
390 | frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | ||
391 | stats->rx_errors++; | ||
392 | stats->rx_over_errors++; | ||
393 | |||
394 | netif_receive_skb(skb); | ||
395 | } | ||
396 | |||
397 | static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) | ||
398 | { | ||
399 | u16 flags, data; | ||
400 | int i; | ||
401 | unsigned int val; | ||
402 | struct c_can_priv *priv = netdev_priv(dev); | ||
403 | struct net_device_stats *stats = &dev->stats; | ||
404 | struct sk_buff *skb; | ||
405 | struct can_frame *frame; | ||
406 | |||
407 | skb = alloc_can_skb(dev, &frame); | ||
408 | if (!skb) { | ||
409 | stats->rx_dropped++; | ||
410 | return -ENOMEM; | ||
411 | } | ||
412 | |||
413 | frame->can_dlc = get_can_dlc(ctrl & 0x0F); | ||
414 | |||
415 | flags = priv->read_reg(priv, &priv->regs->ifregs[iface].arb2); | ||
416 | val = priv->read_reg(priv, &priv->regs->ifregs[iface].arb1) | | ||
417 | (flags << 16); | ||
418 | |||
419 | if (flags & IF_ARB_MSGXTD) | ||
420 | frame->can_id = (val & CAN_EFF_MASK) | CAN_EFF_FLAG; | ||
421 | else | ||
422 | frame->can_id = (val >> 18) & CAN_SFF_MASK; | ||
423 | |||
424 | if (flags & IF_ARB_TRANSMIT) | ||
425 | frame->can_id |= CAN_RTR_FLAG; | ||
426 | else { | ||
427 | for (i = 0; i < frame->can_dlc; i += 2) { | ||
428 | data = priv->read_reg(priv, | ||
429 | &priv->regs->ifregs[iface].data[i / 2]); | ||
430 | frame->data[i] = data; | ||
431 | frame->data[i + 1] = data >> 8; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | netif_receive_skb(skb); | ||
436 | |||
437 | stats->rx_packets++; | ||
438 | stats->rx_bytes += frame->can_dlc; | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | static void c_can_setup_receive_object(struct net_device *dev, int iface, | ||
444 | int objno, unsigned int mask, | ||
445 | unsigned int id, unsigned int mcont) | ||
446 | { | ||
447 | struct c_can_priv *priv = netdev_priv(dev); | ||
448 | |||
449 | priv->write_reg(priv, &priv->regs->ifregs[iface].mask1, | ||
450 | IFX_WRITE_LOW_16BIT(mask)); | ||
451 | priv->write_reg(priv, &priv->regs->ifregs[iface].mask2, | ||
452 | IFX_WRITE_HIGH_16BIT(mask)); | ||
453 | |||
454 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, | ||
455 | IFX_WRITE_LOW_16BIT(id)); | ||
456 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, | ||
457 | (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id))); | ||
458 | |||
459 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, mcont); | ||
460 | c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); | ||
461 | |||
462 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, | ||
463 | c_can_read_reg32(priv, &priv->regs->msgval1)); | ||
464 | } | ||
465 | |||
466 | static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno) | ||
467 | { | ||
468 | struct c_can_priv *priv = netdev_priv(dev); | ||
469 | |||
470 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, 0); | ||
471 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, 0); | ||
472 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, 0); | ||
473 | |||
474 | c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL); | ||
475 | |||
476 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, | ||
477 | c_can_read_reg32(priv, &priv->regs->msgval1)); | ||
478 | } | ||
479 | |||
480 | static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno) | ||
481 | { | ||
482 | int val = c_can_read_reg32(priv, &priv->regs->txrqst1); | ||
483 | |||
484 | /* | ||
485 | * as transmission request register's bit n-1 corresponds to | ||
486 | * message object n, we need to handle the same properly. | ||
487 | */ | ||
488 | if (val & (1 << (objno - 1))) | ||
489 | return 1; | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, | ||
495 | struct net_device *dev) | ||
496 | { | ||
497 | u32 msg_obj_no; | ||
498 | struct c_can_priv *priv = netdev_priv(dev); | ||
499 | struct can_frame *frame = (struct can_frame *)skb->data; | ||
500 | |||
501 | if (can_dropped_invalid_skb(dev, skb)) | ||
502 | return NETDEV_TX_OK; | ||
503 | |||
504 | msg_obj_no = get_tx_next_msg_obj(priv); | ||
505 | |||
506 | /* prepare message object for transmission */ | ||
507 | c_can_write_msg_object(dev, 0, frame, msg_obj_no); | ||
508 | can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); | ||
509 | |||
510 | /* | ||
511 | * we have to stop the queue in case of a wrap around or | ||
512 | * if the next TX message object is still in use | ||
513 | */ | ||
514 | priv->tx_next++; | ||
515 | if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv)) || | ||
516 | (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0) | ||
517 | netif_stop_queue(dev); | ||
518 | |||
519 | return NETDEV_TX_OK; | ||
520 | } | ||
521 | |||
522 | static int c_can_set_bittiming(struct net_device *dev) | ||
523 | { | ||
524 | unsigned int reg_btr, reg_brpe, ctrl_save; | ||
525 | u8 brp, brpe, sjw, tseg1, tseg2; | ||
526 | u32 ten_bit_brp; | ||
527 | struct c_can_priv *priv = netdev_priv(dev); | ||
528 | const struct can_bittiming *bt = &priv->can.bittiming; | ||
529 | |||
530 | /* c_can provides a 6-bit brp and 4-bit brpe fields */ | ||
531 | ten_bit_brp = bt->brp - 1; | ||
532 | brp = ten_bit_brp & BTR_BRP_MASK; | ||
533 | brpe = ten_bit_brp >> 6; | ||
534 | |||
535 | sjw = bt->sjw - 1; | ||
536 | tseg1 = bt->prop_seg + bt->phase_seg1 - 1; | ||
537 | tseg2 = bt->phase_seg2 - 1; | ||
538 | reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) | | ||
539 | (tseg2 << BTR_TSEG2_SHIFT); | ||
540 | reg_brpe = brpe & BRP_EXT_BRPE_MASK; | ||
541 | |||
542 | netdev_info(dev, | ||
543 | "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); | ||
544 | |||
545 | ctrl_save = priv->read_reg(priv, &priv->regs->control); | ||
546 | priv->write_reg(priv, &priv->regs->control, | ||
547 | ctrl_save | CONTROL_CCE | CONTROL_INIT); | ||
548 | priv->write_reg(priv, &priv->regs->btr, reg_btr); | ||
549 | priv->write_reg(priv, &priv->regs->brp_ext, reg_brpe); | ||
550 | priv->write_reg(priv, &priv->regs->control, ctrl_save); | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | /* | ||
556 | * Configure C_CAN message objects for Tx and Rx purposes: | ||
557 | * C_CAN provides a total of 32 message objects that can be configured | ||
558 | * either for Tx or Rx purposes. Here the first 16 message objects are used as | ||
559 | * a reception FIFO. The end of reception FIFO is signified by the EoB bit | ||
560 | * being SET. The remaining 16 message objects are kept aside for Tx purposes. | ||
561 | * See user guide document for further details on configuring message | ||
562 | * objects. | ||
563 | */ | ||
564 | static void c_can_configure_msg_objects(struct net_device *dev) | ||
565 | { | ||
566 | int i; | ||
567 | |||
568 | /* first invalidate all message objects */ | ||
569 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++) | ||
570 | c_can_inval_msg_object(dev, 0, i); | ||
571 | |||
572 | /* setup receive message objects */ | ||
573 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) | ||
574 | c_can_setup_receive_object(dev, 0, i, 0, 0, | ||
575 | (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); | ||
576 | |||
577 | c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0, | ||
578 | IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * Configure C_CAN chip: | ||
583 | * - enable/disable auto-retransmission | ||
584 | * - set operating mode | ||
585 | * - configure message objects | ||
586 | */ | ||
587 | static void c_can_chip_config(struct net_device *dev) | ||
588 | { | ||
589 | struct c_can_priv *priv = netdev_priv(dev); | ||
590 | |||
591 | if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) | ||
592 | /* disable automatic retransmission */ | ||
593 | priv->write_reg(priv, &priv->regs->control, | ||
594 | CONTROL_DISABLE_AR); | ||
595 | else | ||
596 | /* enable automatic retransmission */ | ||
597 | priv->write_reg(priv, &priv->regs->control, | ||
598 | CONTROL_ENABLE_AR); | ||
599 | |||
600 | if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & | ||
601 | CAN_CTRLMODE_LOOPBACK)) { | ||
602 | /* loopback + silent mode : useful for hot self-test */ | ||
603 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | ||
604 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | ||
605 | priv->write_reg(priv, &priv->regs->test, | ||
606 | TEST_LBACK | TEST_SILENT); | ||
607 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { | ||
608 | /* loopback mode : useful for self-test function */ | ||
609 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | ||
610 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | ||
611 | priv->write_reg(priv, &priv->regs->test, TEST_LBACK); | ||
612 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { | ||
613 | /* silent mode : bus-monitoring mode */ | ||
614 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | ||
615 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | ||
616 | priv->write_reg(priv, &priv->regs->test, TEST_SILENT); | ||
617 | } else | ||
618 | /* normal mode*/ | ||
619 | priv->write_reg(priv, &priv->regs->control, | ||
620 | CONTROL_EIE | CONTROL_SIE | CONTROL_IE); | ||
621 | |||
622 | /* configure message objects */ | ||
623 | c_can_configure_msg_objects(dev); | ||
624 | |||
625 | /* set a `lec` value so that we can check for updates later */ | ||
626 | priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); | ||
627 | |||
628 | /* set bittiming params */ | ||
629 | c_can_set_bittiming(dev); | ||
630 | } | ||
631 | |||
632 | static void c_can_start(struct net_device *dev) | ||
633 | { | ||
634 | struct c_can_priv *priv = netdev_priv(dev); | ||
635 | |||
636 | /* enable status change, error and module interrupts */ | ||
637 | c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); | ||
638 | |||
639 | /* basic c_can configuration */ | ||
640 | c_can_chip_config(dev); | ||
641 | |||
642 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
643 | |||
644 | /* reset tx helper pointers */ | ||
645 | priv->tx_next = priv->tx_echo = 0; | ||
646 | } | ||
647 | |||
648 | static void c_can_stop(struct net_device *dev) | ||
649 | { | ||
650 | struct c_can_priv *priv = netdev_priv(dev); | ||
651 | |||
652 | /* disable all interrupts */ | ||
653 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
654 | |||
655 | /* set the state as STOPPED */ | ||
656 | priv->can.state = CAN_STATE_STOPPED; | ||
657 | } | ||
658 | |||
659 | static int c_can_set_mode(struct net_device *dev, enum can_mode mode) | ||
660 | { | ||
661 | switch (mode) { | ||
662 | case CAN_MODE_START: | ||
663 | c_can_start(dev); | ||
664 | netif_wake_queue(dev); | ||
665 | break; | ||
666 | default: | ||
667 | return -EOPNOTSUPP; | ||
668 | } | ||
669 | |||
670 | return 0; | ||
671 | } | ||
672 | |||
673 | static int c_can_get_berr_counter(const struct net_device *dev, | ||
674 | struct can_berr_counter *bec) | ||
675 | { | ||
676 | unsigned int reg_err_counter; | ||
677 | struct c_can_priv *priv = netdev_priv(dev); | ||
678 | |||
679 | reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); | ||
680 | bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >> | ||
681 | ERR_CNT_REC_SHIFT; | ||
682 | bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK; | ||
683 | |||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | /* | ||
688 | * theory of operation: | ||
689 | * | ||
690 | * priv->tx_echo holds the number of the oldest can_frame put for | ||
691 | * transmission into the hardware, but not yet ACKed by the CAN tx | ||
692 | * complete IRQ. | ||
693 | * | ||
694 | * We iterate from priv->tx_echo to priv->tx_next and check if the | ||
695 | * packet has been transmitted, echo it back to the CAN framework. | ||
696 | * If we discover a not yet transmitted package, stop looking for more. | ||
697 | */ | ||
698 | static void c_can_do_tx(struct net_device *dev) | ||
699 | { | ||
700 | u32 val; | ||
701 | u32 msg_obj_no; | ||
702 | struct c_can_priv *priv = netdev_priv(dev); | ||
703 | struct net_device_stats *stats = &dev->stats; | ||
704 | |||
705 | for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { | ||
706 | msg_obj_no = get_tx_echo_msg_obj(priv); | ||
707 | c_can_inval_msg_object(dev, 0, msg_obj_no); | ||
708 | val = c_can_read_reg32(priv, &priv->regs->txrqst1); | ||
709 | if (!(val & (1 << msg_obj_no))) { | ||
710 | can_get_echo_skb(dev, | ||
711 | msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); | ||
712 | stats->tx_bytes += priv->read_reg(priv, | ||
713 | &priv->regs->ifregs[0].msg_cntrl) | ||
714 | & IF_MCONT_DLC_MASK; | ||
715 | stats->tx_packets++; | ||
716 | } | ||
717 | } | ||
718 | |||
719 | /* restart queue if wrap-up or if queue stalled on last pkt */ | ||
720 | if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) || | ||
721 | ((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) | ||
722 | netif_wake_queue(dev); | ||
723 | } | ||
724 | |||
725 | /* | ||
726 | * theory of operation: | ||
727 | * | ||
728 | * c_can core saves a received CAN message into the first free message | ||
729 | * object it finds free (starting with the lowest). Bits NEWDAT and | ||
730 | * INTPND are set for this message object indicating that a new message | ||
731 | * has arrived. To work-around this issue, we keep two groups of message | ||
732 | * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. | ||
733 | * | ||
734 | * To ensure in-order frame reception we use the following | ||
735 | * approach while re-activating a message object to receive further | ||
736 | * frames: | ||
737 | * - if the current message object number is lower than | ||
738 | * C_CAN_MSG_RX_LOW_LAST, do not clear the NEWDAT bit while clearing | ||
739 | * the INTPND bit. | ||
740 | * - if the current message object number is equal to | ||
741 | * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of all lower | ||
742 | * receive message objects. | ||
743 | * - if the current message object number is greater than | ||
744 | * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of | ||
745 | * only this message object. | ||
746 | */ | ||
747 | static int c_can_do_rx_poll(struct net_device *dev, int quota) | ||
748 | { | ||
749 | u32 num_rx_pkts = 0; | ||
750 | unsigned int msg_obj, msg_ctrl_save; | ||
751 | struct c_can_priv *priv = netdev_priv(dev); | ||
752 | u32 val = c_can_read_reg32(priv, &priv->regs->intpnd1); | ||
753 | |||
754 | for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; | ||
755 | msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0; | ||
756 | val = c_can_read_reg32(priv, &priv->regs->intpnd1), | ||
757 | msg_obj++) { | ||
758 | /* | ||
759 | * as interrupt pending register's bit n-1 corresponds to | ||
760 | * message object n, we need to handle the same properly. | ||
761 | */ | ||
762 | if (val & (1 << (msg_obj - 1))) { | ||
763 | c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & | ||
764 | ~IF_COMM_TXRQST); | ||
765 | msg_ctrl_save = priv->read_reg(priv, | ||
766 | &priv->regs->ifregs[0].msg_cntrl); | ||
767 | |||
768 | if (msg_ctrl_save & IF_MCONT_EOB) | ||
769 | return num_rx_pkts; | ||
770 | |||
771 | if (msg_ctrl_save & IF_MCONT_MSGLST) { | ||
772 | c_can_handle_lost_msg_obj(dev, 0, msg_obj); | ||
773 | num_rx_pkts++; | ||
774 | quota--; | ||
775 | continue; | ||
776 | } | ||
777 | |||
778 | if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) | ||
779 | continue; | ||
780 | |||
781 | /* read the data from the message object */ | ||
782 | c_can_read_msg_object(dev, 0, msg_ctrl_save); | ||
783 | |||
784 | if (msg_obj < C_CAN_MSG_RX_LOW_LAST) | ||
785 | c_can_mark_rx_msg_obj(dev, 0, | ||
786 | msg_ctrl_save, msg_obj); | ||
787 | else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) | ||
788 | /* activate this msg obj */ | ||
789 | c_can_activate_rx_msg_obj(dev, 0, | ||
790 | msg_ctrl_save, msg_obj); | ||
791 | else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) | ||
792 | /* activate all lower message objects */ | ||
793 | c_can_activate_all_lower_rx_msg_obj(dev, | ||
794 | 0, msg_ctrl_save); | ||
795 | |||
796 | num_rx_pkts++; | ||
797 | quota--; | ||
798 | } | ||
799 | } | ||
800 | |||
801 | return num_rx_pkts; | ||
802 | } | ||
803 | |||
804 | static inline int c_can_has_and_handle_berr(struct c_can_priv *priv) | ||
805 | { | ||
806 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && | ||
807 | (priv->current_status & LEC_UNUSED); | ||
808 | } | ||
809 | |||
810 | static int c_can_handle_state_change(struct net_device *dev, | ||
811 | enum c_can_bus_error_types error_type) | ||
812 | { | ||
813 | unsigned int reg_err_counter; | ||
814 | unsigned int rx_err_passive; | ||
815 | struct c_can_priv *priv = netdev_priv(dev); | ||
816 | struct net_device_stats *stats = &dev->stats; | ||
817 | struct can_frame *cf; | ||
818 | struct sk_buff *skb; | ||
819 | struct can_berr_counter bec; | ||
820 | |||
821 | /* propogate the error condition to the CAN stack */ | ||
822 | skb = alloc_can_err_skb(dev, &cf); | ||
823 | if (unlikely(!skb)) | ||
824 | return 0; | ||
825 | |||
826 | c_can_get_berr_counter(dev, &bec); | ||
827 | reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); | ||
828 | rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >> | ||
829 | ERR_CNT_RP_SHIFT; | ||
830 | |||
831 | switch (error_type) { | ||
832 | case C_CAN_ERROR_WARNING: | ||
833 | /* error warning state */ | ||
834 | priv->can.can_stats.error_warning++; | ||
835 | priv->can.state = CAN_STATE_ERROR_WARNING; | ||
836 | cf->can_id |= CAN_ERR_CRTL; | ||
837 | cf->data[1] = (bec.txerr > bec.rxerr) ? | ||
838 | CAN_ERR_CRTL_TX_WARNING : | ||
839 | CAN_ERR_CRTL_RX_WARNING; | ||
840 | cf->data[6] = bec.txerr; | ||
841 | cf->data[7] = bec.rxerr; | ||
842 | |||
843 | break; | ||
844 | case C_CAN_ERROR_PASSIVE: | ||
845 | /* error passive state */ | ||
846 | priv->can.can_stats.error_passive++; | ||
847 | priv->can.state = CAN_STATE_ERROR_PASSIVE; | ||
848 | cf->can_id |= CAN_ERR_CRTL; | ||
849 | if (rx_err_passive) | ||
850 | cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; | ||
851 | if (bec.txerr > 127) | ||
852 | cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; | ||
853 | |||
854 | cf->data[6] = bec.txerr; | ||
855 | cf->data[7] = bec.rxerr; | ||
856 | break; | ||
857 | case C_CAN_BUS_OFF: | ||
858 | /* bus-off state */ | ||
859 | priv->can.state = CAN_STATE_BUS_OFF; | ||
860 | cf->can_id |= CAN_ERR_BUSOFF; | ||
861 | /* | ||
862 | * disable all interrupts in bus-off mode to ensure that | ||
863 | * the CPU is not hogged down | ||
864 | */ | ||
865 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
866 | can_bus_off(dev); | ||
867 | break; | ||
868 | default: | ||
869 | break; | ||
870 | } | ||
871 | |||
872 | netif_receive_skb(skb); | ||
873 | stats->rx_packets++; | ||
874 | stats->rx_bytes += cf->can_dlc; | ||
875 | |||
876 | return 1; | ||
877 | } | ||
878 | |||
879 | static int c_can_handle_bus_err(struct net_device *dev, | ||
880 | enum c_can_lec_type lec_type) | ||
881 | { | ||
882 | struct c_can_priv *priv = netdev_priv(dev); | ||
883 | struct net_device_stats *stats = &dev->stats; | ||
884 | struct can_frame *cf; | ||
885 | struct sk_buff *skb; | ||
886 | |||
887 | /* | ||
888 | * early exit if no lec update or no error. | ||
889 | * no lec update means that no CAN bus event has been detected | ||
890 | * since CPU wrote 0x7 value to status reg. | ||
891 | */ | ||
892 | if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) | ||
893 | return 0; | ||
894 | |||
895 | /* propogate the error condition to the CAN stack */ | ||
896 | skb = alloc_can_err_skb(dev, &cf); | ||
897 | if (unlikely(!skb)) | ||
898 | return 0; | ||
899 | |||
900 | /* | ||
901 | * check for 'last error code' which tells us the | ||
902 | * type of the last error to occur on the CAN bus | ||
903 | */ | ||
904 | |||
905 | /* common for all type of bus errors */ | ||
906 | priv->can.can_stats.bus_error++; | ||
907 | stats->rx_errors++; | ||
908 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | ||
909 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
910 | |||
911 | switch (lec_type) { | ||
912 | case LEC_STUFF_ERROR: | ||
913 | netdev_dbg(dev, "stuff error\n"); | ||
914 | cf->data[2] |= CAN_ERR_PROT_STUFF; | ||
915 | break; | ||
916 | case LEC_FORM_ERROR: | ||
917 | netdev_dbg(dev, "form error\n"); | ||
918 | cf->data[2] |= CAN_ERR_PROT_FORM; | ||
919 | break; | ||
920 | case LEC_ACK_ERROR: | ||
921 | netdev_dbg(dev, "ack error\n"); | ||
922 | cf->data[2] |= (CAN_ERR_PROT_LOC_ACK | | ||
923 | CAN_ERR_PROT_LOC_ACK_DEL); | ||
924 | break; | ||
925 | case LEC_BIT1_ERROR: | ||
926 | netdev_dbg(dev, "bit1 error\n"); | ||
927 | cf->data[2] |= CAN_ERR_PROT_BIT1; | ||
928 | break; | ||
929 | case LEC_BIT0_ERROR: | ||
930 | netdev_dbg(dev, "bit0 error\n"); | ||
931 | cf->data[2] |= CAN_ERR_PROT_BIT0; | ||
932 | break; | ||
933 | case LEC_CRC_ERROR: | ||
934 | netdev_dbg(dev, "CRC error\n"); | ||
935 | cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ | | ||
936 | CAN_ERR_PROT_LOC_CRC_DEL); | ||
937 | break; | ||
938 | default: | ||
939 | break; | ||
940 | } | ||
941 | |||
942 | /* set a `lec` value so that we can check for updates later */ | ||
943 | priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); | ||
944 | |||
945 | netif_receive_skb(skb); | ||
946 | stats->rx_packets++; | ||
947 | stats->rx_bytes += cf->can_dlc; | ||
948 | |||
949 | return 1; | ||
950 | } | ||
951 | |||
952 | static int c_can_poll(struct napi_struct *napi, int quota) | ||
953 | { | ||
954 | u16 irqstatus; | ||
955 | int lec_type = 0; | ||
956 | int work_done = 0; | ||
957 | struct net_device *dev = napi->dev; | ||
958 | struct c_can_priv *priv = netdev_priv(dev); | ||
959 | |||
960 | irqstatus = priv->read_reg(priv, &priv->regs->interrupt); | ||
961 | if (!irqstatus) | ||
962 | goto end; | ||
963 | |||
964 | /* status events have the highest priority */ | ||
965 | if (irqstatus == STATUS_INTERRUPT) { | ||
966 | priv->current_status = priv->read_reg(priv, | ||
967 | &priv->regs->status); | ||
968 | |||
969 | /* handle Tx/Rx events */ | ||
970 | if (priv->current_status & STATUS_TXOK) | ||
971 | priv->write_reg(priv, &priv->regs->status, | ||
972 | priv->current_status & ~STATUS_TXOK); | ||
973 | |||
974 | if (priv->current_status & STATUS_RXOK) | ||
975 | priv->write_reg(priv, &priv->regs->status, | ||
976 | priv->current_status & ~STATUS_RXOK); | ||
977 | |||
978 | /* handle state changes */ | ||
979 | if ((priv->current_status & STATUS_EWARN) && | ||
980 | (!(priv->last_status & STATUS_EWARN))) { | ||
981 | netdev_dbg(dev, "entered error warning state\n"); | ||
982 | work_done += c_can_handle_state_change(dev, | ||
983 | C_CAN_ERROR_WARNING); | ||
984 | } | ||
985 | if ((priv->current_status & STATUS_EPASS) && | ||
986 | (!(priv->last_status & STATUS_EPASS))) { | ||
987 | netdev_dbg(dev, "entered error passive state\n"); | ||
988 | work_done += c_can_handle_state_change(dev, | ||
989 | C_CAN_ERROR_PASSIVE); | ||
990 | } | ||
991 | if ((priv->current_status & STATUS_BOFF) && | ||
992 | (!(priv->last_status & STATUS_BOFF))) { | ||
993 | netdev_dbg(dev, "entered bus off state\n"); | ||
994 | work_done += c_can_handle_state_change(dev, | ||
995 | C_CAN_BUS_OFF); | ||
996 | } | ||
997 | |||
998 | /* handle bus recovery events */ | ||
999 | if ((!(priv->current_status & STATUS_BOFF)) && | ||
1000 | (priv->last_status & STATUS_BOFF)) { | ||
1001 | netdev_dbg(dev, "left bus off state\n"); | ||
1002 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
1003 | } | ||
1004 | if ((!(priv->current_status & STATUS_EPASS)) && | ||
1005 | (priv->last_status & STATUS_EPASS)) { | ||
1006 | netdev_dbg(dev, "left error passive state\n"); | ||
1007 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
1008 | } | ||
1009 | |||
1010 | priv->last_status = priv->current_status; | ||
1011 | |||
1012 | /* handle lec errors on the bus */ | ||
1013 | lec_type = c_can_has_and_handle_berr(priv); | ||
1014 | if (lec_type) | ||
1015 | work_done += c_can_handle_bus_err(dev, lec_type); | ||
1016 | } else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) && | ||
1017 | (irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) { | ||
1018 | /* handle events corresponding to receive message objects */ | ||
1019 | work_done += c_can_do_rx_poll(dev, (quota - work_done)); | ||
1020 | } else if ((irqstatus >= C_CAN_MSG_OBJ_TX_FIRST) && | ||
1021 | (irqstatus <= C_CAN_MSG_OBJ_TX_LAST)) { | ||
1022 | /* handle events corresponding to transmit message objects */ | ||
1023 | c_can_do_tx(dev); | ||
1024 | } | ||
1025 | |||
1026 | end: | ||
1027 | if (work_done < quota) { | ||
1028 | napi_complete(napi); | ||
1029 | /* enable all IRQs */ | ||
1030 | c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); | ||
1031 | } | ||
1032 | |||
1033 | return work_done; | ||
1034 | } | ||
1035 | |||
1036 | static irqreturn_t c_can_isr(int irq, void *dev_id) | ||
1037 | { | ||
1038 | u16 irqstatus; | ||
1039 | struct net_device *dev = (struct net_device *)dev_id; | ||
1040 | struct c_can_priv *priv = netdev_priv(dev); | ||
1041 | |||
1042 | irqstatus = priv->read_reg(priv, &priv->regs->interrupt); | ||
1043 | if (!irqstatus) | ||
1044 | return IRQ_NONE; | ||
1045 | |||
1046 | /* disable all interrupts and schedule the NAPI */ | ||
1047 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
1048 | napi_schedule(&priv->napi); | ||
1049 | |||
1050 | return IRQ_HANDLED; | ||
1051 | } | ||
1052 | |||
1053 | static int c_can_open(struct net_device *dev) | ||
1054 | { | ||
1055 | int err; | ||
1056 | struct c_can_priv *priv = netdev_priv(dev); | ||
1057 | |||
1058 | /* open the can device */ | ||
1059 | err = open_candev(dev); | ||
1060 | if (err) { | ||
1061 | netdev_err(dev, "failed to open can device\n"); | ||
1062 | return err; | ||
1063 | } | ||
1064 | |||
1065 | /* register interrupt handler */ | ||
1066 | err = request_irq(dev->irq, &c_can_isr, IRQF_SHARED, dev->name, | ||
1067 | dev); | ||
1068 | if (err < 0) { | ||
1069 | netdev_err(dev, "failed to request interrupt\n"); | ||
1070 | goto exit_irq_fail; | ||
1071 | } | ||
1072 | |||
1073 | /* start the c_can controller */ | ||
1074 | c_can_start(dev); | ||
1075 | |||
1076 | napi_enable(&priv->napi); | ||
1077 | netif_start_queue(dev); | ||
1078 | |||
1079 | return 0; | ||
1080 | |||
1081 | exit_irq_fail: | ||
1082 | close_candev(dev); | ||
1083 | return err; | ||
1084 | } | ||
1085 | |||
1086 | static int c_can_close(struct net_device *dev) | ||
1087 | { | ||
1088 | struct c_can_priv *priv = netdev_priv(dev); | ||
1089 | |||
1090 | netif_stop_queue(dev); | ||
1091 | napi_disable(&priv->napi); | ||
1092 | c_can_stop(dev); | ||
1093 | free_irq(dev->irq, dev); | ||
1094 | close_candev(dev); | ||
1095 | |||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1099 | struct net_device *alloc_c_can_dev(void) | ||
1100 | { | ||
1101 | struct net_device *dev; | ||
1102 | struct c_can_priv *priv; | ||
1103 | |||
1104 | dev = alloc_candev(sizeof(struct c_can_priv), C_CAN_MSG_OBJ_TX_NUM); | ||
1105 | if (!dev) | ||
1106 | return NULL; | ||
1107 | |||
1108 | priv = netdev_priv(dev); | ||
1109 | netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT); | ||
1110 | |||
1111 | priv->dev = dev; | ||
1112 | priv->can.bittiming_const = &c_can_bittiming_const; | ||
1113 | priv->can.do_set_mode = c_can_set_mode; | ||
1114 | priv->can.do_get_berr_counter = c_can_get_berr_counter; | ||
1115 | priv->can.ctrlmode_supported = CAN_CTRLMODE_ONE_SHOT | | ||
1116 | CAN_CTRLMODE_LOOPBACK | | ||
1117 | CAN_CTRLMODE_LISTENONLY | | ||
1118 | CAN_CTRLMODE_BERR_REPORTING; | ||
1119 | |||
1120 | return dev; | ||
1121 | } | ||
1122 | EXPORT_SYMBOL_GPL(alloc_c_can_dev); | ||
1123 | |||
1124 | void free_c_can_dev(struct net_device *dev) | ||
1125 | { | ||
1126 | free_candev(dev); | ||
1127 | } | ||
1128 | EXPORT_SYMBOL_GPL(free_c_can_dev); | ||
1129 | |||
1130 | static const struct net_device_ops c_can_netdev_ops = { | ||
1131 | .ndo_open = c_can_open, | ||
1132 | .ndo_stop = c_can_close, | ||
1133 | .ndo_start_xmit = c_can_start_xmit, | ||
1134 | }; | ||
1135 | |||
1136 | int register_c_can_dev(struct net_device *dev) | ||
1137 | { | ||
1138 | dev->flags |= IFF_ECHO; /* we support local echo */ | ||
1139 | dev->netdev_ops = &c_can_netdev_ops; | ||
1140 | |||
1141 | return register_candev(dev); | ||
1142 | } | ||
1143 | EXPORT_SYMBOL_GPL(register_c_can_dev); | ||
1144 | |||
1145 | void unregister_c_can_dev(struct net_device *dev) | ||
1146 | { | ||
1147 | struct c_can_priv *priv = netdev_priv(dev); | ||
1148 | |||
1149 | /* disable all interrupts */ | ||
1150 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
1151 | |||
1152 | unregister_candev(dev); | ||
1153 | } | ||
1154 | EXPORT_SYMBOL_GPL(unregister_c_can_dev); | ||
1155 | |||
1156 | MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>"); | ||
1157 | MODULE_LICENSE("GPL v2"); | ||
1158 | MODULE_DESCRIPTION("CAN bus driver for Bosch C_CAN controller"); | ||
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h new file mode 100644 index 000000000000..9b7fbef3d09a --- /dev/null +++ b/drivers/net/can/c_can/c_can.h | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * CAN bus driver for Bosch C_CAN controller | ||
3 | * | ||
4 | * Copyright (C) 2010 ST Microelectronics | ||
5 | * Bhupesh Sharma <bhupesh.sharma@st.com> | ||
6 | * | ||
7 | * Borrowed heavily from the C_CAN driver originally written by: | ||
8 | * Copyright (C) 2007 | ||
9 | * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de> | ||
10 | * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch> | ||
11 | * | ||
12 | * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. | ||
13 | * Bosch C_CAN user manual can be obtained from: | ||
14 | * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ | ||
15 | * users_manual_c_can.pdf | ||
16 | * | ||
17 | * This file is licensed under the terms of the GNU General Public | ||
18 | * License version 2. This program is licensed "as is" without any | ||
19 | * warranty of any kind, whether express or implied. | ||
20 | */ | ||
21 | |||
22 | #ifndef C_CAN_H | ||
23 | #define C_CAN_H | ||
24 | |||
25 | /* c_can IF registers */ | ||
26 | struct c_can_if_regs { | ||
27 | u16 com_req; | ||
28 | u16 com_mask; | ||
29 | u16 mask1; | ||
30 | u16 mask2; | ||
31 | u16 arb1; | ||
32 | u16 arb2; | ||
33 | u16 msg_cntrl; | ||
34 | u16 data[4]; | ||
35 | u16 _reserved[13]; | ||
36 | }; | ||
37 | |||
38 | /* c_can hardware registers */ | ||
39 | struct c_can_regs { | ||
40 | u16 control; | ||
41 | u16 status; | ||
42 | u16 err_cnt; | ||
43 | u16 btr; | ||
44 | u16 interrupt; | ||
45 | u16 test; | ||
46 | u16 brp_ext; | ||
47 | u16 _reserved1; | ||
48 | struct c_can_if_regs ifregs[2]; /* [0] = IF1 and [1] = IF2 */ | ||
49 | u16 _reserved2[8]; | ||
50 | u16 txrqst1; | ||
51 | u16 txrqst2; | ||
52 | u16 _reserved3[6]; | ||
53 | u16 newdat1; | ||
54 | u16 newdat2; | ||
55 | u16 _reserved4[6]; | ||
56 | u16 intpnd1; | ||
57 | u16 intpnd2; | ||
58 | u16 _reserved5[6]; | ||
59 | u16 msgval1; | ||
60 | u16 msgval2; | ||
61 | u16 _reserved6[6]; | ||
62 | }; | ||
63 | |||
64 | /* c_can private data structure */ | ||
65 | struct c_can_priv { | ||
66 | struct can_priv can; /* must be the first member */ | ||
67 | struct napi_struct napi; | ||
68 | struct net_device *dev; | ||
69 | int tx_object; | ||
70 | int current_status; | ||
71 | int last_status; | ||
72 | u16 (*read_reg) (struct c_can_priv *priv, void *reg); | ||
73 | void (*write_reg) (struct c_can_priv *priv, void *reg, u16 val); | ||
74 | struct c_can_regs __iomem *regs; | ||
75 | unsigned long irq_flags; /* for request_irq() */ | ||
76 | unsigned int tx_next; | ||
77 | unsigned int tx_echo; | ||
78 | void *priv; /* for board-specific data */ | ||
79 | }; | ||
80 | |||
81 | struct net_device *alloc_c_can_dev(void); | ||
82 | void free_c_can_dev(struct net_device *dev); | ||
83 | int register_c_can_dev(struct net_device *dev); | ||
84 | void unregister_c_can_dev(struct net_device *dev); | ||
85 | |||
86 | #endif /* C_CAN_H */ | ||
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c new file mode 100644 index 000000000000..e629b961ae2d --- /dev/null +++ b/drivers/net/can/c_can/c_can_platform.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * Platform CAN bus driver for Bosch C_CAN controller | ||
3 | * | ||
4 | * Copyright (C) 2010 ST Microelectronics | ||
5 | * Bhupesh Sharma <bhupesh.sharma@st.com> | ||
6 | * | ||
7 | * Borrowed heavily from the C_CAN driver originally written by: | ||
8 | * Copyright (C) 2007 | ||
9 | * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de> | ||
10 | * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch> | ||
11 | * | ||
12 | * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. | ||
13 | * Bosch C_CAN user manual can be obtained from: | ||
14 | * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ | ||
15 | * users_manual_c_can.pdf | ||
16 | * | ||
17 | * This file is licensed under the terms of the GNU General Public | ||
18 | * License version 2. This program is licensed "as is" without any | ||
19 | * warranty of any kind, whether express or implied. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/version.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/if_arp.h> | ||
29 | #include <linux/if_ether.h> | ||
30 | #include <linux/list.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/io.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/clk.h> | ||
35 | |||
36 | #include <linux/can/dev.h> | ||
37 | |||
38 | #include "c_can.h" | ||
39 | |||
40 | /* | ||
41 | * 16-bit c_can registers can be arranged differently in the memory | ||
42 | * architecture of different implementations. For example: 16-bit | ||
43 | * registers can be aligned to a 16-bit boundary or 32-bit boundary etc. | ||
44 | * Handle the same by providing a common read/write interface. | ||
45 | */ | ||
46 | static u16 c_can_plat_read_reg_aligned_to_16bit(struct c_can_priv *priv, | ||
47 | void *reg) | ||
48 | { | ||
49 | return readw(reg); | ||
50 | } | ||
51 | |||
52 | static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv *priv, | ||
53 | void *reg, u16 val) | ||
54 | { | ||
55 | writew(val, reg); | ||
56 | } | ||
57 | |||
58 | static u16 c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv *priv, | ||
59 | void *reg) | ||
60 | { | ||
61 | return readw(reg + (long)reg - (long)priv->regs); | ||
62 | } | ||
63 | |||
64 | static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv, | ||
65 | void *reg, u16 val) | ||
66 | { | ||
67 | writew(val, reg + (long)reg - (long)priv->regs); | ||
68 | } | ||
69 | |||
70 | static int __devinit c_can_plat_probe(struct platform_device *pdev) | ||
71 | { | ||
72 | int ret; | ||
73 | void __iomem *addr; | ||
74 | struct net_device *dev; | ||
75 | struct c_can_priv *priv; | ||
76 | struct resource *mem, *irq; | ||
77 | #ifdef CONFIG_HAVE_CLK | ||
78 | struct clk *clk; | ||
79 | |||
80 | /* get the appropriate clk */ | ||
81 | clk = clk_get(&pdev->dev, NULL); | ||
82 | if (IS_ERR(clk)) { | ||
83 | dev_err(&pdev->dev, "no clock defined\n"); | ||
84 | ret = -ENODEV; | ||
85 | goto exit; | ||
86 | } | ||
87 | #endif | ||
88 | |||
89 | /* get the platform data */ | ||
90 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
91 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
92 | if (!mem || (irq <= 0)) { | ||
93 | ret = -ENODEV; | ||
94 | goto exit_free_clk; | ||
95 | } | ||
96 | |||
97 | if (!request_mem_region(mem->start, resource_size(mem), | ||
98 | KBUILD_MODNAME)) { | ||
99 | dev_err(&pdev->dev, "resource unavailable\n"); | ||
100 | ret = -ENODEV; | ||
101 | goto exit_free_clk; | ||
102 | } | ||
103 | |||
104 | addr = ioremap(mem->start, resource_size(mem)); | ||
105 | if (!addr) { | ||
106 | dev_err(&pdev->dev, "failed to map can port\n"); | ||
107 | ret = -ENOMEM; | ||
108 | goto exit_release_mem; | ||
109 | } | ||
110 | |||
111 | /* allocate the c_can device */ | ||
112 | dev = alloc_c_can_dev(); | ||
113 | if (!dev) { | ||
114 | ret = -ENOMEM; | ||
115 | goto exit_iounmap; | ||
116 | } | ||
117 | |||
118 | priv = netdev_priv(dev); | ||
119 | |||
120 | dev->irq = irq->start; | ||
121 | priv->regs = addr; | ||
122 | #ifdef CONFIG_HAVE_CLK | ||
123 | priv->can.clock.freq = clk_get_rate(clk); | ||
124 | priv->priv = clk; | ||
125 | #endif | ||
126 | |||
127 | switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { | ||
128 | case IORESOURCE_MEM_32BIT: | ||
129 | priv->read_reg = c_can_plat_read_reg_aligned_to_32bit; | ||
130 | priv->write_reg = c_can_plat_write_reg_aligned_to_32bit; | ||
131 | break; | ||
132 | case IORESOURCE_MEM_16BIT: | ||
133 | default: | ||
134 | priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; | ||
135 | priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; | ||
136 | break; | ||
137 | } | ||
138 | |||
139 | platform_set_drvdata(pdev, dev); | ||
140 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
141 | |||
142 | ret = register_c_can_dev(dev); | ||
143 | if (ret) { | ||
144 | dev_err(&pdev->dev, "registering %s failed (err=%d)\n", | ||
145 | KBUILD_MODNAME, ret); | ||
146 | goto exit_free_device; | ||
147 | } | ||
148 | |||
149 | dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", | ||
150 | KBUILD_MODNAME, priv->regs, dev->irq); | ||
151 | return 0; | ||
152 | |||
153 | exit_free_device: | ||
154 | platform_set_drvdata(pdev, NULL); | ||
155 | free_c_can_dev(dev); | ||
156 | exit_iounmap: | ||
157 | iounmap(addr); | ||
158 | exit_release_mem: | ||
159 | release_mem_region(mem->start, resource_size(mem)); | ||
160 | exit_free_clk: | ||
161 | #ifdef CONFIG_HAVE_CLK | ||
162 | clk_put(clk); | ||
163 | exit: | ||
164 | #endif | ||
165 | dev_err(&pdev->dev, "probe failed\n"); | ||
166 | |||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | static int __devexit c_can_plat_remove(struct platform_device *pdev) | ||
171 | { | ||
172 | struct net_device *dev = platform_get_drvdata(pdev); | ||
173 | struct c_can_priv *priv = netdev_priv(dev); | ||
174 | struct resource *mem; | ||
175 | |||
176 | unregister_c_can_dev(dev); | ||
177 | platform_set_drvdata(pdev, NULL); | ||
178 | |||
179 | free_c_can_dev(dev); | ||
180 | iounmap(priv->regs); | ||
181 | |||
182 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
183 | release_mem_region(mem->start, resource_size(mem)); | ||
184 | |||
185 | #ifdef CONFIG_HAVE_CLK | ||
186 | clk_put(priv->priv); | ||
187 | #endif | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static struct platform_driver c_can_plat_driver = { | ||
193 | .driver = { | ||
194 | .name = KBUILD_MODNAME, | ||
195 | .owner = THIS_MODULE, | ||
196 | }, | ||
197 | .probe = c_can_plat_probe, | ||
198 | .remove = __devexit_p(c_can_plat_remove), | ||
199 | }; | ||
200 | |||
201 | static int __init c_can_plat_init(void) | ||
202 | { | ||
203 | return platform_driver_register(&c_can_plat_driver); | ||
204 | } | ||
205 | module_init(c_can_plat_init); | ||
206 | |||
207 | static void __exit c_can_plat_exit(void) | ||
208 | { | ||
209 | platform_driver_unregister(&c_can_plat_driver); | ||
210 | } | ||
211 | module_exit(c_can_plat_exit); | ||
212 | |||
213 | MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>"); | ||
214 | MODULE_LICENSE("GPL v2"); | ||
215 | MODULE_DESCRIPTION("Platform CAN bus driver for Bosch C_CAN controller"); | ||
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index b9a6d7a5a739..366f5cc050ae 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c | |||
@@ -1618,7 +1618,7 @@ static ssize_t ican3_sysfs_set_term(struct device *dev, | |||
1618 | return count; | 1618 | return count; |
1619 | } | 1619 | } |
1620 | 1620 | ||
1621 | static DEVICE_ATTR(termination, S_IWUGO | S_IRUGO, ican3_sysfs_show_term, | 1621 | static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term, |
1622 | ican3_sysfs_set_term); | 1622 | ican3_sysfs_set_term); |
1623 | 1623 | ||
1624 | static struct attribute *ican3_sysfs_attrs[] = { | 1624 | static struct attribute *ican3_sysfs_attrs[] = { |
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 7ab534aee452..7513c4523ac4 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
@@ -940,7 +940,7 @@ static int mcp251x_open(struct net_device *net) | |||
940 | goto open_unlock; | 940 | goto open_unlock; |
941 | } | 941 | } |
942 | 942 | ||
943 | priv->wq = create_freezeable_workqueue("mcp251x_wq"); | 943 | priv->wq = create_freezable_workqueue("mcp251x_wq"); |
944 | INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); | 944 | INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); |
945 | INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); | 945 | INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); |
946 | 946 | ||
diff --git a/drivers/net/can/mscan/Kconfig b/drivers/net/can/mscan/Kconfig index 27d1d398e25e..d38706958af6 100644 --- a/drivers/net/can/mscan/Kconfig +++ b/drivers/net/can/mscan/Kconfig | |||
@@ -1,5 +1,5 @@ | |||
1 | config CAN_MSCAN | 1 | config CAN_MSCAN |
2 | depends on CAN_DEV && (PPC || M68K || M68KNOMMU) | 2 | depends on CAN_DEV && (PPC || M68K) |
3 | tristate "Support for Freescale MSCAN based chips" | 3 | tristate "Support for Freescale MSCAN based chips" |
4 | ---help--- | 4 | ---help--- |
5 | The Motorola Scalable Controller Area Network (MSCAN) definition | 5 | The Motorola Scalable Controller Area Network (MSCAN) definition |
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index c42e97268248..e54712b22c27 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c | |||
@@ -185,7 +185,7 @@ struct pch_can_priv { | |||
185 | 185 | ||
186 | static struct can_bittiming_const pch_can_bittiming_const = { | 186 | static struct can_bittiming_const pch_can_bittiming_const = { |
187 | .name = KBUILD_MODNAME, | 187 | .name = KBUILD_MODNAME, |
188 | .tseg1_min = 1, | 188 | .tseg1_min = 2, |
189 | .tseg1_max = 16, | 189 | .tseg1_max = 16, |
190 | .tseg2_min = 1, | 190 | .tseg2_min = 1, |
191 | .tseg2_max = 8, | 191 | .tseg2_max = 8, |
@@ -959,13 +959,13 @@ static void __devexit pch_can_remove(struct pci_dev *pdev) | |||
959 | struct pch_can_priv *priv = netdev_priv(ndev); | 959 | struct pch_can_priv *priv = netdev_priv(ndev); |
960 | 960 | ||
961 | unregister_candev(priv->ndev); | 961 | unregister_candev(priv->ndev); |
962 | pci_iounmap(pdev, priv->regs); | ||
963 | if (priv->use_msi) | 962 | if (priv->use_msi) |
964 | pci_disable_msi(priv->dev); | 963 | pci_disable_msi(priv->dev); |
965 | pci_release_regions(pdev); | 964 | pci_release_regions(pdev); |
966 | pci_disable_device(pdev); | 965 | pci_disable_device(pdev); |
967 | pci_set_drvdata(pdev, NULL); | 966 | pci_set_drvdata(pdev, NULL); |
968 | pch_can_reset(priv); | 967 | pch_can_reset(priv); |
968 | pci_iounmap(pdev, priv->regs); | ||
969 | free_candev(priv->ndev); | 969 | free_candev(priv->ndev); |
970 | } | 970 | } |
971 | 971 | ||
@@ -1238,6 +1238,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, | |||
1238 | priv->use_msi = 0; | 1238 | priv->use_msi = 0; |
1239 | } else { | 1239 | } else { |
1240 | netdev_err(ndev, "PCH CAN opened with MSI\n"); | 1240 | netdev_err(ndev, "PCH CAN opened with MSI\n"); |
1241 | pci_set_master(pdev); | ||
1241 | priv->use_msi = 1; | 1242 | priv->use_msi = 1; |
1242 | } | 1243 | } |
1243 | 1244 | ||
diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig new file mode 100644 index 000000000000..5de46a9a77bb --- /dev/null +++ b/drivers/net/can/softing/Kconfig | |||
@@ -0,0 +1,30 @@ | |||
1 | config CAN_SOFTING | ||
2 | tristate "Softing Gmbh CAN generic support" | ||
3 | depends on CAN_DEV && HAS_IOMEM | ||
4 | ---help--- | ||
5 | Support for CAN cards from Softing Gmbh & some cards | ||
6 | from Vector Gmbh. | ||
7 | Softing Gmbh CAN cards come with 1 or 2 physical busses. | ||
8 | Those cards typically use Dual Port RAM to communicate | ||
9 | with the host CPU. The interface is then identical for PCI | ||
10 | and PCMCIA cards. This driver operates on a platform device, | ||
11 | which has been created by softing_cs or softing_pci driver. | ||
12 | Warning: | ||
13 | The API of the card does not allow fine control per bus, but | ||
14 | controls the 2 busses on the card together. | ||
15 | As such, some actions (start/stop/busoff recovery) on 1 bus | ||
16 | must bring down the other bus too temporarily. | ||
17 | |||
18 | config CAN_SOFTING_CS | ||
19 | tristate "Softing Gmbh CAN pcmcia cards" | ||
20 | depends on PCMCIA | ||
21 | depends on CAN_SOFTING | ||
22 | ---help--- | ||
23 | Support for PCMCIA cards from Softing Gmbh & some cards | ||
24 | from Vector Gmbh. | ||
25 | You need firmware for these, which you can get at | ||
26 | http://developer.berlios.de/projects/socketcan/ | ||
27 | This version of the driver is written against | ||
28 | firmware version 4.6 (softing-fw-4.6-binaries.tar.gz) | ||
29 | In order to use the card as CAN device, you need the Softing generic | ||
30 | support too. | ||
diff --git a/drivers/net/can/softing/Makefile b/drivers/net/can/softing/Makefile new file mode 100644 index 000000000000..c5e5016c742e --- /dev/null +++ b/drivers/net/can/softing/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | |||
2 | softing-y := softing_main.o softing_fw.o | ||
3 | obj-$(CONFIG_CAN_SOFTING) += softing.o | ||
4 | obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o | ||
5 | |||
6 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG | ||
diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h new file mode 100644 index 000000000000..7ec9f4db3d52 --- /dev/null +++ b/drivers/net/can/softing/softing.h | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | * softing common interfaces | ||
3 | * | ||
4 | * by Kurt Van Dijck, 2008-2010 | ||
5 | */ | ||
6 | |||
7 | #include <linux/atomic.h> | ||
8 | #include <linux/netdevice.h> | ||
9 | #include <linux/ktime.h> | ||
10 | #include <linux/mutex.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/can.h> | ||
13 | #include <linux/can/dev.h> | ||
14 | |||
15 | #include "softing_platform.h" | ||
16 | |||
17 | struct softing; | ||
18 | |||
19 | struct softing_priv { | ||
20 | struct can_priv can; /* must be the first member! */ | ||
21 | struct net_device *netdev; | ||
22 | struct softing *card; | ||
23 | struct { | ||
24 | int pending; | ||
25 | /* variables wich hold the circular buffer */ | ||
26 | int echo_put; | ||
27 | int echo_get; | ||
28 | } tx; | ||
29 | struct can_bittiming_const btr_const; | ||
30 | int index; | ||
31 | uint8_t output; | ||
32 | uint16_t chip; | ||
33 | }; | ||
34 | #define netdev2softing(netdev) ((struct softing_priv *)netdev_priv(netdev)) | ||
35 | |||
36 | struct softing { | ||
37 | const struct softing_platform_data *pdat; | ||
38 | struct platform_device *pdev; | ||
39 | struct net_device *net[2]; | ||
40 | spinlock_t spin; /* protect this structure & DPRAM access */ | ||
41 | ktime_t ts_ref; | ||
42 | ktime_t ts_overflow; /* timestamp overflow value, in ktime */ | ||
43 | |||
44 | struct { | ||
45 | /* indication of firmware status */ | ||
46 | int up; | ||
47 | /* protection of the 'up' variable */ | ||
48 | struct mutex lock; | ||
49 | } fw; | ||
50 | struct { | ||
51 | int nr; | ||
52 | int requested; | ||
53 | int svc_count; | ||
54 | unsigned int dpram_position; | ||
55 | } irq; | ||
56 | struct { | ||
57 | int pending; | ||
58 | int last_bus; | ||
59 | /* | ||
60 | * keep the bus that last tx'd a message, | ||
61 | * in order to let every netdev queue resume | ||
62 | */ | ||
63 | } tx; | ||
64 | __iomem uint8_t *dpram; | ||
65 | unsigned long dpram_phys; | ||
66 | unsigned long dpram_size; | ||
67 | struct { | ||
68 | uint16_t fw_version, hw_version, license, serial; | ||
69 | uint16_t chip[2]; | ||
70 | unsigned int freq; /* remote cpu's operating frequency */ | ||
71 | } id; | ||
72 | }; | ||
73 | |||
74 | extern int softing_default_output(struct net_device *netdev); | ||
75 | |||
76 | extern ktime_t softing_raw2ktime(struct softing *card, u32 raw); | ||
77 | |||
78 | extern int softing_chip_poweron(struct softing *card); | ||
79 | |||
80 | extern int softing_bootloader_command(struct softing *card, int16_t cmd, | ||
81 | const char *msg); | ||
82 | |||
83 | /* Load firmware after reset */ | ||
84 | extern int softing_load_fw(const char *file, struct softing *card, | ||
85 | __iomem uint8_t *virt, unsigned int size, int offset); | ||
86 | |||
87 | /* Load final application firmware after bootloader */ | ||
88 | extern int softing_load_app_fw(const char *file, struct softing *card); | ||
89 | |||
90 | /* | ||
91 | * enable or disable irq | ||
92 | * only called with fw.lock locked | ||
93 | */ | ||
94 | extern int softing_enable_irq(struct softing *card, int enable); | ||
95 | |||
96 | /* start/stop 1 bus on card */ | ||
97 | extern int softing_startstop(struct net_device *netdev, int up); | ||
98 | |||
99 | /* netif_rx() */ | ||
100 | extern int softing_netdev_rx(struct net_device *netdev, | ||
101 | const struct can_frame *msg, ktime_t ktime); | ||
102 | |||
103 | /* SOFTING DPRAM mappings */ | ||
104 | #define DPRAM_RX 0x0000 | ||
105 | #define DPRAM_RX_SIZE 32 | ||
106 | #define DPRAM_RX_CNT 16 | ||
107 | #define DPRAM_RX_RD 0x0201 /* uint8_t */ | ||
108 | #define DPRAM_RX_WR 0x0205 /* uint8_t */ | ||
109 | #define DPRAM_RX_LOST 0x0207 /* uint8_t */ | ||
110 | |||
111 | #define DPRAM_FCT_PARAM 0x0300 /* int16_t [20] */ | ||
112 | #define DPRAM_FCT_RESULT 0x0328 /* int16_t */ | ||
113 | #define DPRAM_FCT_HOST 0x032b /* uint16_t */ | ||
114 | |||
115 | #define DPRAM_INFO_BUSSTATE 0x0331 /* uint16_t */ | ||
116 | #define DPRAM_INFO_BUSSTATE2 0x0335 /* uint16_t */ | ||
117 | #define DPRAM_INFO_ERRSTATE 0x0339 /* uint16_t */ | ||
118 | #define DPRAM_INFO_ERRSTATE2 0x033d /* uint16_t */ | ||
119 | #define DPRAM_RESET 0x0341 /* uint16_t */ | ||
120 | #define DPRAM_CLR_RECV_FIFO 0x0345 /* uint16_t */ | ||
121 | #define DPRAM_RESET_TIME 0x034d /* uint16_t */ | ||
122 | #define DPRAM_TIME 0x0350 /* uint64_t */ | ||
123 | #define DPRAM_WR_START 0x0358 /* uint8_t */ | ||
124 | #define DPRAM_WR_END 0x0359 /* uint8_t */ | ||
125 | #define DPRAM_RESET_RX_FIFO 0x0361 /* uint16_t */ | ||
126 | #define DPRAM_RESET_TX_FIFO 0x0364 /* uint8_t */ | ||
127 | #define DPRAM_READ_FIFO_LEVEL 0x0365 /* uint8_t */ | ||
128 | #define DPRAM_RX_FIFO_LEVEL 0x0366 /* uint16_t */ | ||
129 | #define DPRAM_TX_FIFO_LEVEL 0x0366 /* uint16_t */ | ||
130 | |||
131 | #define DPRAM_TX 0x0400 /* uint16_t */ | ||
132 | #define DPRAM_TX_SIZE 16 | ||
133 | #define DPRAM_TX_CNT 32 | ||
134 | #define DPRAM_TX_RD 0x0601 /* uint8_t */ | ||
135 | #define DPRAM_TX_WR 0x0605 /* uint8_t */ | ||
136 | |||
137 | #define DPRAM_COMMAND 0x07e0 /* uint16_t */ | ||
138 | #define DPRAM_RECEIPT 0x07f0 /* uint16_t */ | ||
139 | #define DPRAM_IRQ_TOHOST 0x07fe /* uint8_t */ | ||
140 | #define DPRAM_IRQ_TOCARD 0x07ff /* uint8_t */ | ||
141 | |||
142 | #define DPRAM_V2_RESET 0x0e00 /* uint8_t */ | ||
143 | #define DPRAM_V2_IRQ_TOHOST 0x0e02 /* uint8_t */ | ||
144 | |||
145 | #define TXMAX (DPRAM_TX_CNT - 1) | ||
146 | |||
147 | /* DPRAM return codes */ | ||
148 | #define RES_NONE 0 | ||
149 | #define RES_OK 1 | ||
150 | #define RES_NOK 2 | ||
151 | #define RES_UNKNOWN 3 | ||
152 | /* DPRAM flags */ | ||
153 | #define CMD_TX 0x01 | ||
154 | #define CMD_ACK 0x02 | ||
155 | #define CMD_XTD 0x04 | ||
156 | #define CMD_RTR 0x08 | ||
157 | #define CMD_ERR 0x10 | ||
158 | #define CMD_BUS2 0x80 | ||
159 | |||
160 | /* returned fifo entry bus state masks */ | ||
161 | #define SF_MASK_BUSOFF 0x80 | ||
162 | #define SF_MASK_EPASSIVE 0x60 | ||
163 | |||
164 | /* bus states */ | ||
165 | #define STATE_BUSOFF 2 | ||
166 | #define STATE_EPASSIVE 1 | ||
167 | #define STATE_EACTIVE 0 | ||
diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c new file mode 100644 index 000000000000..c11bb4de8630 --- /dev/null +++ b/drivers/net/can/softing/softing_cs.c | |||
@@ -0,0 +1,360 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2010 | ||
3 | * | ||
4 | * - Kurt Van Dijck, EIA Electronics | ||
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 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #include <pcmcia/cistpl.h> | ||
25 | #include <pcmcia/ds.h> | ||
26 | |||
27 | #include "softing_platform.h" | ||
28 | |||
29 | static int softingcs_index; | ||
30 | static spinlock_t softingcs_index_lock; | ||
31 | |||
32 | static int softingcs_reset(struct platform_device *pdev, int v); | ||
33 | static int softingcs_enable_irq(struct platform_device *pdev, int v); | ||
34 | |||
35 | /* | ||
36 | * platform_data descriptions | ||
37 | */ | ||
38 | #define MHZ (1000*1000) | ||
39 | static const struct softing_platform_data softingcs_platform_data[] = { | ||
40 | { | ||
41 | .name = "CANcard", | ||
42 | .manf = 0x0168, .prod = 0x001, | ||
43 | .generation = 1, | ||
44 | .nbus = 2, | ||
45 | .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, | ||
46 | .dpram_size = 0x0800, | ||
47 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
48 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
49 | .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, | ||
50 | .reset = softingcs_reset, | ||
51 | .enable_irq = softingcs_enable_irq, | ||
52 | }, { | ||
53 | .name = "CANcard-NEC", | ||
54 | .manf = 0x0168, .prod = 0x002, | ||
55 | .generation = 1, | ||
56 | .nbus = 2, | ||
57 | .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, | ||
58 | .dpram_size = 0x0800, | ||
59 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
60 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
61 | .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, | ||
62 | .reset = softingcs_reset, | ||
63 | .enable_irq = softingcs_enable_irq, | ||
64 | }, { | ||
65 | .name = "CANcard-SJA", | ||
66 | .manf = 0x0168, .prod = 0x004, | ||
67 | .generation = 1, | ||
68 | .nbus = 2, | ||
69 | .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, | ||
70 | .dpram_size = 0x0800, | ||
71 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
72 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
73 | .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, | ||
74 | .reset = softingcs_reset, | ||
75 | .enable_irq = softingcs_enable_irq, | ||
76 | }, { | ||
77 | .name = "CANcard-2", | ||
78 | .manf = 0x0168, .prod = 0x005, | ||
79 | .generation = 2, | ||
80 | .nbus = 2, | ||
81 | .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
82 | .dpram_size = 0x1000, | ||
83 | .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, | ||
84 | .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, | ||
85 | .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, | ||
86 | .reset = softingcs_reset, | ||
87 | .enable_irq = NULL, | ||
88 | }, { | ||
89 | .name = "Vector-CANcard", | ||
90 | .manf = 0x0168, .prod = 0x081, | ||
91 | .generation = 1, | ||
92 | .nbus = 2, | ||
93 | .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
94 | .dpram_size = 0x0800, | ||
95 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
96 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
97 | .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, | ||
98 | .reset = softingcs_reset, | ||
99 | .enable_irq = softingcs_enable_irq, | ||
100 | }, { | ||
101 | .name = "Vector-CANcard-SJA", | ||
102 | .manf = 0x0168, .prod = 0x084, | ||
103 | .generation = 1, | ||
104 | .nbus = 2, | ||
105 | .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, | ||
106 | .dpram_size = 0x0800, | ||
107 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
108 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
109 | .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, | ||
110 | .reset = softingcs_reset, | ||
111 | .enable_irq = softingcs_enable_irq, | ||
112 | }, { | ||
113 | .name = "Vector-CANcard-2", | ||
114 | .manf = 0x0168, .prod = 0x085, | ||
115 | .generation = 2, | ||
116 | .nbus = 2, | ||
117 | .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
118 | .dpram_size = 0x1000, | ||
119 | .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, | ||
120 | .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, | ||
121 | .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, | ||
122 | .reset = softingcs_reset, | ||
123 | .enable_irq = NULL, | ||
124 | }, { | ||
125 | .name = "EDICcard-NEC", | ||
126 | .manf = 0x0168, .prod = 0x102, | ||
127 | .generation = 1, | ||
128 | .nbus = 2, | ||
129 | .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
130 | .dpram_size = 0x0800, | ||
131 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
132 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
133 | .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, | ||
134 | .reset = softingcs_reset, | ||
135 | .enable_irq = softingcs_enable_irq, | ||
136 | }, { | ||
137 | .name = "EDICcard-2", | ||
138 | .manf = 0x0168, .prod = 0x105, | ||
139 | .generation = 2, | ||
140 | .nbus = 2, | ||
141 | .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
142 | .dpram_size = 0x1000, | ||
143 | .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, | ||
144 | .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, | ||
145 | .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, | ||
146 | .reset = softingcs_reset, | ||
147 | .enable_irq = NULL, | ||
148 | }, { | ||
149 | 0, 0, | ||
150 | }, | ||
151 | }; | ||
152 | |||
153 | MODULE_FIRMWARE(fw_dir "bcard.bin"); | ||
154 | MODULE_FIRMWARE(fw_dir "ldcard.bin"); | ||
155 | MODULE_FIRMWARE(fw_dir "cancard.bin"); | ||
156 | MODULE_FIRMWARE(fw_dir "cansja.bin"); | ||
157 | |||
158 | MODULE_FIRMWARE(fw_dir "bcard2.bin"); | ||
159 | MODULE_FIRMWARE(fw_dir "ldcard2.bin"); | ||
160 | MODULE_FIRMWARE(fw_dir "cancrd2.bin"); | ||
161 | |||
162 | static __devinit const struct softing_platform_data | ||
163 | *softingcs_find_platform_data(unsigned int manf, unsigned int prod) | ||
164 | { | ||
165 | const struct softing_platform_data *lp; | ||
166 | |||
167 | for (lp = softingcs_platform_data; lp->manf; ++lp) { | ||
168 | if ((lp->manf == manf) && (lp->prod == prod)) | ||
169 | return lp; | ||
170 | } | ||
171 | return NULL; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * platformdata callbacks | ||
176 | */ | ||
177 | static int softingcs_reset(struct platform_device *pdev, int v) | ||
178 | { | ||
179 | struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); | ||
180 | |||
181 | dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20); | ||
182 | return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20); | ||
183 | } | ||
184 | |||
185 | static int softingcs_enable_irq(struct platform_device *pdev, int v) | ||
186 | { | ||
187 | struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); | ||
188 | |||
189 | dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0); | ||
190 | return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0); | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * pcmcia check | ||
195 | */ | ||
196 | static __devinit int softingcs_probe_config(struct pcmcia_device *pcmcia, | ||
197 | void *priv_data) | ||
198 | { | ||
199 | struct softing_platform_data *pdat = priv_data; | ||
200 | struct resource *pres; | ||
201 | int memspeed = 0; | ||
202 | |||
203 | WARN_ON(!pdat); | ||
204 | pres = pcmcia->resource[PCMCIA_IOMEM_0]; | ||
205 | if (resource_size(pres) < 0x1000) | ||
206 | return -ERANGE; | ||
207 | |||
208 | pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE; | ||
209 | if (pdat->generation < 2) { | ||
210 | pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8; | ||
211 | memspeed = 3; | ||
212 | } else { | ||
213 | pres->flags |= WIN_DATA_WIDTH_16; | ||
214 | } | ||
215 | return pcmcia_request_window(pcmcia, pres, memspeed); | ||
216 | } | ||
217 | |||
218 | static __devexit void softingcs_remove(struct pcmcia_device *pcmcia) | ||
219 | { | ||
220 | struct platform_device *pdev = pcmcia->priv; | ||
221 | |||
222 | /* free bits */ | ||
223 | platform_device_unregister(pdev); | ||
224 | /* release pcmcia stuff */ | ||
225 | pcmcia_disable_device(pcmcia); | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * platform_device wrapper | ||
230 | * pdev->resource has 2 entries: io & irq | ||
231 | */ | ||
232 | static void softingcs_pdev_release(struct device *dev) | ||
233 | { | ||
234 | struct platform_device *pdev = to_platform_device(dev); | ||
235 | kfree(pdev); | ||
236 | } | ||
237 | |||
238 | static __devinit int softingcs_probe(struct pcmcia_device *pcmcia) | ||
239 | { | ||
240 | int ret; | ||
241 | struct platform_device *pdev; | ||
242 | const struct softing_platform_data *pdat; | ||
243 | struct resource *pres; | ||
244 | struct dev { | ||
245 | struct platform_device pdev; | ||
246 | struct resource res[2]; | ||
247 | } *dev; | ||
248 | |||
249 | /* find matching platform_data */ | ||
250 | pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id); | ||
251 | if (!pdat) | ||
252 | return -ENOTTY; | ||
253 | |||
254 | /* setup pcmcia device */ | ||
255 | pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM | | ||
256 | CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; | ||
257 | ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat); | ||
258 | if (ret) | ||
259 | goto pcmcia_failed; | ||
260 | |||
261 | ret = pcmcia_enable_device(pcmcia); | ||
262 | if (ret < 0) | ||
263 | goto pcmcia_failed; | ||
264 | |||
265 | pres = pcmcia->resource[PCMCIA_IOMEM_0]; | ||
266 | if (!pres) { | ||
267 | ret = -EBADF; | ||
268 | goto pcmcia_bad; | ||
269 | } | ||
270 | |||
271 | /* create softing platform device */ | ||
272 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
273 | if (!dev) { | ||
274 | ret = -ENOMEM; | ||
275 | goto mem_failed; | ||
276 | } | ||
277 | dev->pdev.resource = dev->res; | ||
278 | dev->pdev.num_resources = ARRAY_SIZE(dev->res); | ||
279 | dev->pdev.dev.release = softingcs_pdev_release; | ||
280 | |||
281 | pdev = &dev->pdev; | ||
282 | pdev->dev.platform_data = (void *)pdat; | ||
283 | pdev->dev.parent = &pcmcia->dev; | ||
284 | pcmcia->priv = pdev; | ||
285 | |||
286 | /* platform device resources */ | ||
287 | pdev->resource[0].flags = IORESOURCE_MEM; | ||
288 | pdev->resource[0].start = pres->start; | ||
289 | pdev->resource[0].end = pres->end; | ||
290 | |||
291 | pdev->resource[1].flags = IORESOURCE_IRQ; | ||
292 | pdev->resource[1].start = pcmcia->irq; | ||
293 | pdev->resource[1].end = pdev->resource[1].start; | ||
294 | |||
295 | /* platform device setup */ | ||
296 | spin_lock(&softingcs_index_lock); | ||
297 | pdev->id = softingcs_index++; | ||
298 | spin_unlock(&softingcs_index_lock); | ||
299 | pdev->name = "softing"; | ||
300 | dev_set_name(&pdev->dev, "softingcs.%i", pdev->id); | ||
301 | ret = platform_device_register(pdev); | ||
302 | if (ret < 0) | ||
303 | goto platform_failed; | ||
304 | |||
305 | dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev)); | ||
306 | return 0; | ||
307 | |||
308 | platform_failed: | ||
309 | kfree(dev); | ||
310 | mem_failed: | ||
311 | pcmcia_bad: | ||
312 | pcmcia_failed: | ||
313 | pcmcia_disable_device(pcmcia); | ||
314 | pcmcia->priv = NULL; | ||
315 | return ret ?: -ENODEV; | ||
316 | } | ||
317 | |||
318 | static /*const*/ struct pcmcia_device_id softingcs_ids[] = { | ||
319 | /* softing */ | ||
320 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001), | ||
321 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002), | ||
322 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004), | ||
323 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005), | ||
324 | /* vector, manufacturer? */ | ||
325 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081), | ||
326 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084), | ||
327 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085), | ||
328 | /* EDIC */ | ||
329 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102), | ||
330 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105), | ||
331 | PCMCIA_DEVICE_NULL, | ||
332 | }; | ||
333 | |||
334 | MODULE_DEVICE_TABLE(pcmcia, softingcs_ids); | ||
335 | |||
336 | static struct pcmcia_driver softingcs_driver = { | ||
337 | .owner = THIS_MODULE, | ||
338 | .name = "softingcs", | ||
339 | .id_table = softingcs_ids, | ||
340 | .probe = softingcs_probe, | ||
341 | .remove = __devexit_p(softingcs_remove), | ||
342 | }; | ||
343 | |||
344 | static int __init softingcs_start(void) | ||
345 | { | ||
346 | spin_lock_init(&softingcs_index_lock); | ||
347 | return pcmcia_register_driver(&softingcs_driver); | ||
348 | } | ||
349 | |||
350 | static void __exit softingcs_stop(void) | ||
351 | { | ||
352 | pcmcia_unregister_driver(&softingcs_driver); | ||
353 | } | ||
354 | |||
355 | module_init(softingcs_start); | ||
356 | module_exit(softingcs_stop); | ||
357 | |||
358 | MODULE_DESCRIPTION("softing CANcard driver" | ||
359 | ", links PCMCIA card to softing driver"); | ||
360 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c new file mode 100644 index 000000000000..b520784fb197 --- /dev/null +++ b/drivers/net/can/softing/softing_fw.c | |||
@@ -0,0 +1,691 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2010 | ||
3 | * | ||
4 | * - Kurt Van Dijck, EIA Electronics | ||
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 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/firmware.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <asm/div64.h> | ||
23 | |||
24 | #include "softing.h" | ||
25 | |||
26 | /* | ||
27 | * low level DPRAM command. | ||
28 | * Make sure that card->dpram[DPRAM_FCT_HOST] is preset | ||
29 | */ | ||
30 | static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector, | ||
31 | const char *msg) | ||
32 | { | ||
33 | int ret; | ||
34 | unsigned long stamp; | ||
35 | |||
36 | iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]); | ||
37 | iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]); | ||
38 | iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]); | ||
39 | /* be sure to flush this to the card */ | ||
40 | wmb(); | ||
41 | stamp = jiffies + 1 * HZ; | ||
42 | /* wait for card */ | ||
43 | do { | ||
44 | /* DPRAM_FCT_HOST is _not_ aligned */ | ||
45 | ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) + | ||
46 | (ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8); | ||
47 | /* don't have any cached variables */ | ||
48 | rmb(); | ||
49 | if (ret == RES_OK) | ||
50 | /* read return-value now */ | ||
51 | return ioread16(&card->dpram[DPRAM_FCT_RESULT]); | ||
52 | |||
53 | if ((ret != vector) || time_after(jiffies, stamp)) | ||
54 | break; | ||
55 | /* process context => relax */ | ||
56 | usleep_range(500, 10000); | ||
57 | } while (1); | ||
58 | |||
59 | ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; | ||
60 | dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n", msg, ret); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg) | ||
65 | { | ||
66 | int ret; | ||
67 | |||
68 | ret = _softing_fct_cmd(card, cmd, 0, msg); | ||
69 | if (ret > 0) { | ||
70 | dev_alert(&card->pdev->dev, "%s returned %u\n", msg, ret); | ||
71 | ret = -EIO; | ||
72 | } | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | int softing_bootloader_command(struct softing *card, int16_t cmd, | ||
77 | const char *msg) | ||
78 | { | ||
79 | int ret; | ||
80 | unsigned long stamp; | ||
81 | |||
82 | iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]); | ||
83 | iowrite16(cmd, &card->dpram[DPRAM_COMMAND]); | ||
84 | /* be sure to flush this to the card */ | ||
85 | wmb(); | ||
86 | stamp = jiffies + 3 * HZ; | ||
87 | /* wait for card */ | ||
88 | do { | ||
89 | ret = ioread16(&card->dpram[DPRAM_RECEIPT]); | ||
90 | /* don't have any cached variables */ | ||
91 | rmb(); | ||
92 | if (ret == RES_OK) | ||
93 | return 0; | ||
94 | if (time_after(jiffies, stamp)) | ||
95 | break; | ||
96 | /* process context => relax */ | ||
97 | usleep_range(500, 10000); | ||
98 | } while (!signal_pending(current)); | ||
99 | |||
100 | ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; | ||
101 | dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n", msg, ret); | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr, | ||
106 | uint16_t *plen, const uint8_t **pdat) | ||
107 | { | ||
108 | uint16_t checksum[2]; | ||
109 | const uint8_t *mem; | ||
110 | const uint8_t *end; | ||
111 | |||
112 | /* | ||
113 | * firmware records are a binary, unaligned stream composed of: | ||
114 | * uint16_t type; | ||
115 | * uint32_t addr; | ||
116 | * uint16_t len; | ||
117 | * uint8_t dat[len]; | ||
118 | * uint16_t checksum; | ||
119 | * all values in little endian. | ||
120 | * We could define a struct for this, with __attribute__((packed)), | ||
121 | * but would that solve the alignment in _all_ cases (cfr. the | ||
122 | * struct itself may be an odd address)? | ||
123 | * | ||
124 | * I chose to use leXX_to_cpup() since this solves both | ||
125 | * endianness & alignment. | ||
126 | */ | ||
127 | mem = *pmem; | ||
128 | *ptype = le16_to_cpup((void *)&mem[0]); | ||
129 | *paddr = le32_to_cpup((void *)&mem[2]); | ||
130 | *plen = le16_to_cpup((void *)&mem[6]); | ||
131 | *pdat = &mem[8]; | ||
132 | /* verify checksum */ | ||
133 | end = &mem[8 + *plen]; | ||
134 | checksum[0] = le16_to_cpup((void *)end); | ||
135 | for (checksum[1] = 0; mem < end; ++mem) | ||
136 | checksum[1] += *mem; | ||
137 | if (checksum[0] != checksum[1]) | ||
138 | return -EINVAL; | ||
139 | /* increment */ | ||
140 | *pmem += 10 + *plen; | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | int softing_load_fw(const char *file, struct softing *card, | ||
145 | __iomem uint8_t *dpram, unsigned int size, int offset) | ||
146 | { | ||
147 | const struct firmware *fw; | ||
148 | int ret; | ||
149 | const uint8_t *mem, *end, *dat; | ||
150 | uint16_t type, len; | ||
151 | uint32_t addr; | ||
152 | uint8_t *buf = NULL; | ||
153 | int buflen = 0; | ||
154 | int8_t type_end = 0; | ||
155 | |||
156 | ret = request_firmware(&fw, file, &card->pdev->dev); | ||
157 | if (ret < 0) | ||
158 | return ret; | ||
159 | dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes" | ||
160 | ", offset %c0x%04x\n", | ||
161 | card->pdat->name, file, (unsigned int)fw->size, | ||
162 | (offset >= 0) ? '+' : '-', (unsigned int)abs(offset)); | ||
163 | /* parse the firmware */ | ||
164 | mem = fw->data; | ||
165 | end = &mem[fw->size]; | ||
166 | /* look for header record */ | ||
167 | ret = fw_parse(&mem, &type, &addr, &len, &dat); | ||
168 | if (ret < 0) | ||
169 | goto failed; | ||
170 | if (type != 0xffff) | ||
171 | goto failed; | ||
172 | if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) { | ||
173 | ret = -EINVAL; | ||
174 | goto failed; | ||
175 | } | ||
176 | /* ok, we had a header */ | ||
177 | while (mem < end) { | ||
178 | ret = fw_parse(&mem, &type, &addr, &len, &dat); | ||
179 | if (ret < 0) | ||
180 | goto failed; | ||
181 | if (type == 3) { | ||
182 | /* start address, not used here */ | ||
183 | continue; | ||
184 | } else if (type == 1) { | ||
185 | /* eof */ | ||
186 | type_end = 1; | ||
187 | break; | ||
188 | } else if (type != 0) { | ||
189 | ret = -EINVAL; | ||
190 | goto failed; | ||
191 | } | ||
192 | |||
193 | if ((addr + len + offset) > size) | ||
194 | goto failed; | ||
195 | memcpy_toio(&dpram[addr + offset], dat, len); | ||
196 | /* be sure to flush caches from IO space */ | ||
197 | mb(); | ||
198 | if (len > buflen) { | ||
199 | /* align buflen */ | ||
200 | buflen = (len + (1024-1)) & ~(1024-1); | ||
201 | buf = krealloc(buf, buflen, GFP_KERNEL); | ||
202 | if (!buf) { | ||
203 | ret = -ENOMEM; | ||
204 | goto failed; | ||
205 | } | ||
206 | } | ||
207 | /* verify record data */ | ||
208 | memcpy_fromio(buf, &dpram[addr + offset], len); | ||
209 | if (memcmp(buf, dat, len)) { | ||
210 | /* is not ok */ | ||
211 | dev_alert(&card->pdev->dev, "DPRAM readback failed\n"); | ||
212 | ret = -EIO; | ||
213 | goto failed; | ||
214 | } | ||
215 | } | ||
216 | if (!type_end) | ||
217 | /* no end record seen */ | ||
218 | goto failed; | ||
219 | ret = 0; | ||
220 | failed: | ||
221 | kfree(buf); | ||
222 | release_firmware(fw); | ||
223 | if (ret < 0) | ||
224 | dev_info(&card->pdev->dev, "firmware %s failed\n", file); | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | int softing_load_app_fw(const char *file, struct softing *card) | ||
229 | { | ||
230 | const struct firmware *fw; | ||
231 | const uint8_t *mem, *end, *dat; | ||
232 | int ret, j; | ||
233 | uint16_t type, len; | ||
234 | uint32_t addr, start_addr = 0; | ||
235 | unsigned int sum, rx_sum; | ||
236 | int8_t type_end = 0, type_entrypoint = 0; | ||
237 | |||
238 | ret = request_firmware(&fw, file, &card->pdev->dev); | ||
239 | if (ret) { | ||
240 | dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n", | ||
241 | file, ret); | ||
242 | return ret; | ||
243 | } | ||
244 | dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n", | ||
245 | file, (unsigned long)fw->size); | ||
246 | /* parse the firmware */ | ||
247 | mem = fw->data; | ||
248 | end = &mem[fw->size]; | ||
249 | /* look for header record */ | ||
250 | ret = fw_parse(&mem, &type, &addr, &len, &dat); | ||
251 | if (ret) | ||
252 | goto failed; | ||
253 | ret = -EINVAL; | ||
254 | if (type != 0xffff) { | ||
255 | dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n", | ||
256 | type); | ||
257 | goto failed; | ||
258 | } | ||
259 | if (strncmp("Structured Binary Format, Softing GmbH", dat, len)) { | ||
260 | dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n", | ||
261 | len, dat); | ||
262 | goto failed; | ||
263 | } | ||
264 | /* ok, we had a header */ | ||
265 | while (mem < end) { | ||
266 | ret = fw_parse(&mem, &type, &addr, &len, &dat); | ||
267 | if (ret) | ||
268 | goto failed; | ||
269 | |||
270 | if (type == 3) { | ||
271 | /* start address */ | ||
272 | start_addr = addr; | ||
273 | type_entrypoint = 1; | ||
274 | continue; | ||
275 | } else if (type == 1) { | ||
276 | /* eof */ | ||
277 | type_end = 1; | ||
278 | break; | ||
279 | } else if (type != 0) { | ||
280 | dev_alert(&card->pdev->dev, | ||
281 | "unknown record type 0x%04x\n", type); | ||
282 | ret = -EINVAL; | ||
283 | goto failed; | ||
284 | } | ||
285 | |||
286 | /* regualar data */ | ||
287 | for (sum = 0, j = 0; j < len; ++j) | ||
288 | sum += dat[j]; | ||
289 | /* work in 16bit (target) */ | ||
290 | sum &= 0xffff; | ||
291 | |||
292 | memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len); | ||
293 | iowrite32(card->pdat->app.offs + card->pdat->app.addr, | ||
294 | &card->dpram[DPRAM_COMMAND + 2]); | ||
295 | iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]); | ||
296 | iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]); | ||
297 | iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]); | ||
298 | ret = softing_bootloader_command(card, 1, "loading app."); | ||
299 | if (ret < 0) | ||
300 | goto failed; | ||
301 | /* verify checksum */ | ||
302 | rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]); | ||
303 | if (rx_sum != sum) { | ||
304 | dev_alert(&card->pdev->dev, "SRAM seems to be damaged" | ||
305 | ", wanted 0x%04x, got 0x%04x\n", sum, rx_sum); | ||
306 | ret = -EIO; | ||
307 | goto failed; | ||
308 | } | ||
309 | } | ||
310 | if (!type_end || !type_entrypoint) | ||
311 | goto failed; | ||
312 | /* start application in card */ | ||
313 | iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]); | ||
314 | iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]); | ||
315 | ret = softing_bootloader_command(card, 3, "start app."); | ||
316 | if (ret < 0) | ||
317 | goto failed; | ||
318 | ret = 0; | ||
319 | failed: | ||
320 | release_firmware(fw); | ||
321 | if (ret < 0) | ||
322 | dev_info(&card->pdev->dev, "firmware %s failed\n", file); | ||
323 | return ret; | ||
324 | } | ||
325 | |||
326 | static int softing_reset_chip(struct softing *card) | ||
327 | { | ||
328 | int ret; | ||
329 | |||
330 | do { | ||
331 | /* reset chip */ | ||
332 | iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]); | ||
333 | iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]); | ||
334 | iowrite8(1, &card->dpram[DPRAM_RESET]); | ||
335 | iowrite8(0, &card->dpram[DPRAM_RESET+1]); | ||
336 | |||
337 | ret = softing_fct_cmd(card, 0, "reset_can"); | ||
338 | if (!ret) | ||
339 | break; | ||
340 | if (signal_pending(current)) | ||
341 | /* don't wait any longer */ | ||
342 | break; | ||
343 | } while (1); | ||
344 | card->tx.pending = 0; | ||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | int softing_chip_poweron(struct softing *card) | ||
349 | { | ||
350 | int ret; | ||
351 | /* sync */ | ||
352 | ret = _softing_fct_cmd(card, 99, 0x55, "sync-a"); | ||
353 | if (ret < 0) | ||
354 | goto failed; | ||
355 | |||
356 | ret = _softing_fct_cmd(card, 99, 0xaa, "sync-b"); | ||
357 | if (ret < 0) | ||
358 | goto failed; | ||
359 | |||
360 | ret = softing_reset_chip(card); | ||
361 | if (ret < 0) | ||
362 | goto failed; | ||
363 | /* get_serial */ | ||
364 | ret = softing_fct_cmd(card, 43, "get_serial_number"); | ||
365 | if (ret < 0) | ||
366 | goto failed; | ||
367 | card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]); | ||
368 | /* get_version */ | ||
369 | ret = softing_fct_cmd(card, 12, "get_version"); | ||
370 | if (ret < 0) | ||
371 | goto failed; | ||
372 | card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]); | ||
373 | card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]); | ||
374 | card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]); | ||
375 | card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]); | ||
376 | card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]); | ||
377 | return 0; | ||
378 | failed: | ||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | static void softing_initialize_timestamp(struct softing *card) | ||
383 | { | ||
384 | uint64_t ovf; | ||
385 | |||
386 | card->ts_ref = ktime_get(); | ||
387 | |||
388 | /* 16MHz is the reference */ | ||
389 | ovf = 0x100000000ULL * 16; | ||
390 | do_div(ovf, card->pdat->freq ?: 16); | ||
391 | |||
392 | card->ts_overflow = ktime_add_us(ktime_set(0, 0), ovf); | ||
393 | } | ||
394 | |||
395 | ktime_t softing_raw2ktime(struct softing *card, u32 raw) | ||
396 | { | ||
397 | uint64_t rawl; | ||
398 | ktime_t now, real_offset; | ||
399 | ktime_t target; | ||
400 | ktime_t tmp; | ||
401 | |||
402 | now = ktime_get(); | ||
403 | real_offset = ktime_sub(ktime_get_real(), now); | ||
404 | |||
405 | /* find nsec from card */ | ||
406 | rawl = raw * 16; | ||
407 | do_div(rawl, card->pdat->freq ?: 16); | ||
408 | target = ktime_add_us(card->ts_ref, rawl); | ||
409 | /* test for overflows */ | ||
410 | tmp = ktime_add(target, card->ts_overflow); | ||
411 | while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) { | ||
412 | card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow); | ||
413 | target = tmp; | ||
414 | tmp = ktime_add(target, card->ts_overflow); | ||
415 | } | ||
416 | return ktime_add(target, real_offset); | ||
417 | } | ||
418 | |||
419 | static inline int softing_error_reporting(struct net_device *netdev) | ||
420 | { | ||
421 | struct softing_priv *priv = netdev_priv(netdev); | ||
422 | |||
423 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) | ||
424 | ? 1 : 0; | ||
425 | } | ||
426 | |||
427 | int softing_startstop(struct net_device *dev, int up) | ||
428 | { | ||
429 | int ret; | ||
430 | struct softing *card; | ||
431 | struct softing_priv *priv; | ||
432 | struct net_device *netdev; | ||
433 | int bus_bitmask_start; | ||
434 | int j, error_reporting; | ||
435 | struct can_frame msg; | ||
436 | const struct can_bittiming *bt; | ||
437 | |||
438 | priv = netdev_priv(dev); | ||
439 | card = priv->card; | ||
440 | |||
441 | if (!card->fw.up) | ||
442 | return -EIO; | ||
443 | |||
444 | ret = mutex_lock_interruptible(&card->fw.lock); | ||
445 | if (ret) | ||
446 | return ret; | ||
447 | |||
448 | bus_bitmask_start = 0; | ||
449 | if (dev && up) | ||
450 | /* prepare to start this bus as well */ | ||
451 | bus_bitmask_start |= (1 << priv->index); | ||
452 | /* bring netdevs down */ | ||
453 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
454 | netdev = card->net[j]; | ||
455 | if (!netdev) | ||
456 | continue; | ||
457 | priv = netdev_priv(netdev); | ||
458 | |||
459 | if (dev != netdev) | ||
460 | netif_stop_queue(netdev); | ||
461 | |||
462 | if (netif_running(netdev)) { | ||
463 | if (dev != netdev) | ||
464 | bus_bitmask_start |= (1 << j); | ||
465 | priv->tx.pending = 0; | ||
466 | priv->tx.echo_put = 0; | ||
467 | priv->tx.echo_get = 0; | ||
468 | /* | ||
469 | * this bus' may just have called open_candev() | ||
470 | * which is rather stupid to call close_candev() | ||
471 | * already | ||
472 | * but we may come here from busoff recovery too | ||
473 | * in which case the echo_skb _needs_ flushing too. | ||
474 | * just be sure to call open_candev() again | ||
475 | */ | ||
476 | close_candev(netdev); | ||
477 | } | ||
478 | priv->can.state = CAN_STATE_STOPPED; | ||
479 | } | ||
480 | card->tx.pending = 0; | ||
481 | |||
482 | softing_enable_irq(card, 0); | ||
483 | ret = softing_reset_chip(card); | ||
484 | if (ret) | ||
485 | goto failed; | ||
486 | if (!bus_bitmask_start) | ||
487 | /* no busses to be brought up */ | ||
488 | goto card_done; | ||
489 | |||
490 | if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2) | ||
491 | && (softing_error_reporting(card->net[0]) | ||
492 | != softing_error_reporting(card->net[1]))) { | ||
493 | dev_alert(&card->pdev->dev, | ||
494 | "err_reporting flag differs for busses\n"); | ||
495 | goto invalid; | ||
496 | } | ||
497 | error_reporting = 0; | ||
498 | if (bus_bitmask_start & 1) { | ||
499 | netdev = card->net[0]; | ||
500 | priv = netdev_priv(netdev); | ||
501 | error_reporting += softing_error_reporting(netdev); | ||
502 | /* init chip 1 */ | ||
503 | bt = &priv->can.bittiming; | ||
504 | iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
505 | iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
506 | iowrite16(bt->phase_seg1 + bt->prop_seg, | ||
507 | &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
508 | iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
509 | iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, | ||
510 | &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
511 | ret = softing_fct_cmd(card, 1, "initialize_chip[0]"); | ||
512 | if (ret < 0) | ||
513 | goto failed; | ||
514 | /* set mode */ | ||
515 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
516 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
517 | ret = softing_fct_cmd(card, 3, "set_mode[0]"); | ||
518 | if (ret < 0) | ||
519 | goto failed; | ||
520 | /* set filter */ | ||
521 | /* 11bit id & mask */ | ||
522 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
523 | iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
524 | /* 29bit id.lo & mask.lo & id.hi & mask.hi */ | ||
525 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
526 | iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
527 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
528 | iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); | ||
529 | ret = softing_fct_cmd(card, 7, "set_filter[0]"); | ||
530 | if (ret < 0) | ||
531 | goto failed; | ||
532 | /* set output control */ | ||
533 | iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
534 | ret = softing_fct_cmd(card, 5, "set_output[0]"); | ||
535 | if (ret < 0) | ||
536 | goto failed; | ||
537 | } | ||
538 | if (bus_bitmask_start & 2) { | ||
539 | netdev = card->net[1]; | ||
540 | priv = netdev_priv(netdev); | ||
541 | error_reporting += softing_error_reporting(netdev); | ||
542 | /* init chip2 */ | ||
543 | bt = &priv->can.bittiming; | ||
544 | iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
545 | iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
546 | iowrite16(bt->phase_seg1 + bt->prop_seg, | ||
547 | &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
548 | iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
549 | iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, | ||
550 | &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
551 | ret = softing_fct_cmd(card, 2, "initialize_chip[1]"); | ||
552 | if (ret < 0) | ||
553 | goto failed; | ||
554 | /* set mode2 */ | ||
555 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
556 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
557 | ret = softing_fct_cmd(card, 4, "set_mode[1]"); | ||
558 | if (ret < 0) | ||
559 | goto failed; | ||
560 | /* set filter2 */ | ||
561 | /* 11bit id & mask */ | ||
562 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
563 | iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
564 | /* 29bit id.lo & mask.lo & id.hi & mask.hi */ | ||
565 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
566 | iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
567 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
568 | iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); | ||
569 | ret = softing_fct_cmd(card, 8, "set_filter[1]"); | ||
570 | if (ret < 0) | ||
571 | goto failed; | ||
572 | /* set output control2 */ | ||
573 | iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
574 | ret = softing_fct_cmd(card, 6, "set_output[1]"); | ||
575 | if (ret < 0) | ||
576 | goto failed; | ||
577 | } | ||
578 | /* enable_error_frame */ | ||
579 | /* | ||
580 | * Error reporting is switched off at the moment since | ||
581 | * the receiving of them is not yet 100% verified | ||
582 | * This should be enabled sooner or later | ||
583 | * | ||
584 | if (error_reporting) { | ||
585 | ret = softing_fct_cmd(card, 51, "enable_error_frame"); | ||
586 | if (ret < 0) | ||
587 | goto failed; | ||
588 | } | ||
589 | */ | ||
590 | /* initialize interface */ | ||
591 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
592 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
593 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
594 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
595 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
596 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]); | ||
597 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]); | ||
598 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]); | ||
599 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]); | ||
600 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]); | ||
601 | ret = softing_fct_cmd(card, 17, "initialize_interface"); | ||
602 | if (ret < 0) | ||
603 | goto failed; | ||
604 | /* enable_fifo */ | ||
605 | ret = softing_fct_cmd(card, 36, "enable_fifo"); | ||
606 | if (ret < 0) | ||
607 | goto failed; | ||
608 | /* enable fifo tx ack */ | ||
609 | ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]"); | ||
610 | if (ret < 0) | ||
611 | goto failed; | ||
612 | /* enable fifo tx ack2 */ | ||
613 | ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]"); | ||
614 | if (ret < 0) | ||
615 | goto failed; | ||
616 | /* start_chip */ | ||
617 | ret = softing_fct_cmd(card, 11, "start_chip"); | ||
618 | if (ret < 0) | ||
619 | goto failed; | ||
620 | iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]); | ||
621 | iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]); | ||
622 | if (card->pdat->generation < 2) { | ||
623 | iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); | ||
624 | /* flush the DPRAM caches */ | ||
625 | wmb(); | ||
626 | } | ||
627 | |||
628 | softing_initialize_timestamp(card); | ||
629 | |||
630 | /* | ||
631 | * do socketcan notifications/status changes | ||
632 | * from here, no errors should occur, or the failed: part | ||
633 | * must be reviewed | ||
634 | */ | ||
635 | memset(&msg, 0, sizeof(msg)); | ||
636 | msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED; | ||
637 | msg.can_dlc = CAN_ERR_DLC; | ||
638 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
639 | if (!(bus_bitmask_start & (1 << j))) | ||
640 | continue; | ||
641 | netdev = card->net[j]; | ||
642 | if (!netdev) | ||
643 | continue; | ||
644 | priv = netdev_priv(netdev); | ||
645 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
646 | open_candev(netdev); | ||
647 | if (dev != netdev) { | ||
648 | /* notify other busses on the restart */ | ||
649 | softing_netdev_rx(netdev, &msg, ktime_set(0, 0)); | ||
650 | ++priv->can.can_stats.restarts; | ||
651 | } | ||
652 | netif_wake_queue(netdev); | ||
653 | } | ||
654 | |||
655 | /* enable interrupts */ | ||
656 | ret = softing_enable_irq(card, 1); | ||
657 | if (ret) | ||
658 | goto failed; | ||
659 | card_done: | ||
660 | mutex_unlock(&card->fw.lock); | ||
661 | return 0; | ||
662 | invalid: | ||
663 | ret = -EINVAL; | ||
664 | failed: | ||
665 | softing_enable_irq(card, 0); | ||
666 | softing_reset_chip(card); | ||
667 | mutex_unlock(&card->fw.lock); | ||
668 | /* bring all other interfaces down */ | ||
669 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
670 | netdev = card->net[j]; | ||
671 | if (!netdev) | ||
672 | continue; | ||
673 | dev_close(netdev); | ||
674 | } | ||
675 | return ret; | ||
676 | } | ||
677 | |||
678 | int softing_default_output(struct net_device *netdev) | ||
679 | { | ||
680 | struct softing_priv *priv = netdev_priv(netdev); | ||
681 | struct softing *card = priv->card; | ||
682 | |||
683 | switch (priv->chip) { | ||
684 | case 1000: | ||
685 | return (card->pdat->generation < 2) ? 0xfb : 0xfa; | ||
686 | case 5: | ||
687 | return 0x60; | ||
688 | default: | ||
689 | return 0x40; | ||
690 | } | ||
691 | } | ||
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c new file mode 100644 index 000000000000..5157e15e96eb --- /dev/null +++ b/drivers/net/can/softing/softing_main.c | |||
@@ -0,0 +1,893 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2010 | ||
3 | * | ||
4 | * - Kurt Van Dijck, EIA Electronics | ||
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 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/version.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "softing.h" | ||
26 | |||
27 | #define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1) | ||
28 | |||
29 | /* | ||
30 | * test is a specific CAN netdev | ||
31 | * is online (ie. up 'n running, not sleeping, not busoff | ||
32 | */ | ||
33 | static inline int canif_is_active(struct net_device *netdev) | ||
34 | { | ||
35 | struct can_priv *can = netdev_priv(netdev); | ||
36 | |||
37 | if (!netif_running(netdev)) | ||
38 | return 0; | ||
39 | return (can->state <= CAN_STATE_ERROR_PASSIVE); | ||
40 | } | ||
41 | |||
42 | /* reset DPRAM */ | ||
43 | static inline void softing_set_reset_dpram(struct softing *card) | ||
44 | { | ||
45 | if (card->pdat->generation >= 2) { | ||
46 | spin_lock_bh(&card->spin); | ||
47 | iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1, | ||
48 | &card->dpram[DPRAM_V2_RESET]); | ||
49 | spin_unlock_bh(&card->spin); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | static inline void softing_clr_reset_dpram(struct softing *card) | ||
54 | { | ||
55 | if (card->pdat->generation >= 2) { | ||
56 | spin_lock_bh(&card->spin); | ||
57 | iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1, | ||
58 | &card->dpram[DPRAM_V2_RESET]); | ||
59 | spin_unlock_bh(&card->spin); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | /* trigger the tx queue-ing */ | ||
64 | static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb, | ||
65 | struct net_device *dev) | ||
66 | { | ||
67 | struct softing_priv *priv = netdev_priv(dev); | ||
68 | struct softing *card = priv->card; | ||
69 | int ret; | ||
70 | uint8_t *ptr; | ||
71 | uint8_t fifo_wr, fifo_rd; | ||
72 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
73 | uint8_t buf[DPRAM_TX_SIZE]; | ||
74 | |||
75 | if (can_dropped_invalid_skb(dev, skb)) | ||
76 | return NETDEV_TX_OK; | ||
77 | |||
78 | spin_lock(&card->spin); | ||
79 | |||
80 | ret = NETDEV_TX_BUSY; | ||
81 | if (!card->fw.up || | ||
82 | (card->tx.pending >= TXMAX) || | ||
83 | (priv->tx.pending >= TX_ECHO_SKB_MAX)) | ||
84 | goto xmit_done; | ||
85 | fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]); | ||
86 | fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]); | ||
87 | if (fifo_wr == fifo_rd) | ||
88 | /* fifo full */ | ||
89 | goto xmit_done; | ||
90 | memset(buf, 0, sizeof(buf)); | ||
91 | ptr = buf; | ||
92 | *ptr = CMD_TX; | ||
93 | if (cf->can_id & CAN_RTR_FLAG) | ||
94 | *ptr |= CMD_RTR; | ||
95 | if (cf->can_id & CAN_EFF_FLAG) | ||
96 | *ptr |= CMD_XTD; | ||
97 | if (priv->index) | ||
98 | *ptr |= CMD_BUS2; | ||
99 | ++ptr; | ||
100 | *ptr++ = cf->can_dlc; | ||
101 | *ptr++ = (cf->can_id >> 0); | ||
102 | *ptr++ = (cf->can_id >> 8); | ||
103 | if (cf->can_id & CAN_EFF_FLAG) { | ||
104 | *ptr++ = (cf->can_id >> 16); | ||
105 | *ptr++ = (cf->can_id >> 24); | ||
106 | } else { | ||
107 | /* increment 1, not 2 as you might think */ | ||
108 | ptr += 1; | ||
109 | } | ||
110 | if (!(cf->can_id & CAN_RTR_FLAG)) | ||
111 | memcpy(ptr, &cf->data[0], cf->can_dlc); | ||
112 | memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr], | ||
113 | buf, DPRAM_TX_SIZE); | ||
114 | if (++fifo_wr >= DPRAM_TX_CNT) | ||
115 | fifo_wr = 0; | ||
116 | iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]); | ||
117 | card->tx.last_bus = priv->index; | ||
118 | ++card->tx.pending; | ||
119 | ++priv->tx.pending; | ||
120 | can_put_echo_skb(skb, dev, priv->tx.echo_put); | ||
121 | ++priv->tx.echo_put; | ||
122 | if (priv->tx.echo_put >= TX_ECHO_SKB_MAX) | ||
123 | priv->tx.echo_put = 0; | ||
124 | /* can_put_echo_skb() saves the skb, safe to return TX_OK */ | ||
125 | ret = NETDEV_TX_OK; | ||
126 | xmit_done: | ||
127 | spin_unlock(&card->spin); | ||
128 | if (card->tx.pending >= TXMAX) { | ||
129 | int j; | ||
130 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
131 | if (card->net[j]) | ||
132 | netif_stop_queue(card->net[j]); | ||
133 | } | ||
134 | } | ||
135 | if (ret != NETDEV_TX_OK) | ||
136 | netif_stop_queue(dev); | ||
137 | |||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * shortcut for skb delivery | ||
143 | */ | ||
144 | int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg, | ||
145 | ktime_t ktime) | ||
146 | { | ||
147 | struct sk_buff *skb; | ||
148 | struct can_frame *cf; | ||
149 | |||
150 | skb = alloc_can_skb(netdev, &cf); | ||
151 | if (!skb) | ||
152 | return -ENOMEM; | ||
153 | memcpy(cf, msg, sizeof(*msg)); | ||
154 | skb->tstamp = ktime; | ||
155 | return netif_rx(skb); | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * softing_handle_1 | ||
160 | * pop 1 entry from the DPRAM queue, and process | ||
161 | */ | ||
162 | static int softing_handle_1(struct softing *card) | ||
163 | { | ||
164 | struct net_device *netdev; | ||
165 | struct softing_priv *priv; | ||
166 | ktime_t ktime; | ||
167 | struct can_frame msg; | ||
168 | int cnt = 0, lost_msg; | ||
169 | uint8_t fifo_rd, fifo_wr, cmd; | ||
170 | uint8_t *ptr; | ||
171 | uint32_t tmp_u32; | ||
172 | uint8_t buf[DPRAM_RX_SIZE]; | ||
173 | |||
174 | memset(&msg, 0, sizeof(msg)); | ||
175 | /* test for lost msgs */ | ||
176 | lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]); | ||
177 | if (lost_msg) { | ||
178 | int j; | ||
179 | /* reset condition */ | ||
180 | iowrite8(0, &card->dpram[DPRAM_RX_LOST]); | ||
181 | /* prepare msg */ | ||
182 | msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL; | ||
183 | msg.can_dlc = CAN_ERR_DLC; | ||
184 | msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | ||
185 | /* | ||
186 | * service to all busses, we don't know which it was applicable | ||
187 | * but only service busses that are online | ||
188 | */ | ||
189 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
190 | netdev = card->net[j]; | ||
191 | if (!netdev) | ||
192 | continue; | ||
193 | if (!canif_is_active(netdev)) | ||
194 | /* a dead bus has no overflows */ | ||
195 | continue; | ||
196 | ++netdev->stats.rx_over_errors; | ||
197 | softing_netdev_rx(netdev, &msg, ktime_set(0, 0)); | ||
198 | } | ||
199 | /* prepare for other use */ | ||
200 | memset(&msg, 0, sizeof(msg)); | ||
201 | ++cnt; | ||
202 | } | ||
203 | |||
204 | fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]); | ||
205 | fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]); | ||
206 | |||
207 | if (++fifo_rd >= DPRAM_RX_CNT) | ||
208 | fifo_rd = 0; | ||
209 | if (fifo_wr == fifo_rd) | ||
210 | return cnt; | ||
211 | |||
212 | memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd], | ||
213 | DPRAM_RX_SIZE); | ||
214 | mb(); | ||
215 | /* trigger dual port RAM */ | ||
216 | iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]); | ||
217 | |||
218 | ptr = buf; | ||
219 | cmd = *ptr++; | ||
220 | if (cmd == 0xff) | ||
221 | /* not quite usefull, probably the card has got out */ | ||
222 | return 0; | ||
223 | netdev = card->net[0]; | ||
224 | if (cmd & CMD_BUS2) | ||
225 | netdev = card->net[1]; | ||
226 | priv = netdev_priv(netdev); | ||
227 | |||
228 | if (cmd & CMD_ERR) { | ||
229 | uint8_t can_state, state; | ||
230 | |||
231 | state = *ptr++; | ||
232 | |||
233 | msg.can_id = CAN_ERR_FLAG; | ||
234 | msg.can_dlc = CAN_ERR_DLC; | ||
235 | |||
236 | if (state & SF_MASK_BUSOFF) { | ||
237 | can_state = CAN_STATE_BUS_OFF; | ||
238 | msg.can_id |= CAN_ERR_BUSOFF; | ||
239 | state = STATE_BUSOFF; | ||
240 | } else if (state & SF_MASK_EPASSIVE) { | ||
241 | can_state = CAN_STATE_ERROR_PASSIVE; | ||
242 | msg.can_id |= CAN_ERR_CRTL; | ||
243 | msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE; | ||
244 | state = STATE_EPASSIVE; | ||
245 | } else { | ||
246 | can_state = CAN_STATE_ERROR_ACTIVE; | ||
247 | msg.can_id |= CAN_ERR_CRTL; | ||
248 | state = STATE_EACTIVE; | ||
249 | } | ||
250 | /* update DPRAM */ | ||
251 | iowrite8(state, &card->dpram[priv->index ? | ||
252 | DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]); | ||
253 | /* timestamp */ | ||
254 | tmp_u32 = le32_to_cpup((void *)ptr); | ||
255 | ptr += 4; | ||
256 | ktime = softing_raw2ktime(card, tmp_u32); | ||
257 | |||
258 | ++netdev->stats.rx_errors; | ||
259 | /* update internal status */ | ||
260 | if (can_state != priv->can.state) { | ||
261 | priv->can.state = can_state; | ||
262 | if (can_state == CAN_STATE_ERROR_PASSIVE) | ||
263 | ++priv->can.can_stats.error_passive; | ||
264 | else if (can_state == CAN_STATE_BUS_OFF) { | ||
265 | /* this calls can_close_cleanup() */ | ||
266 | can_bus_off(netdev); | ||
267 | netif_stop_queue(netdev); | ||
268 | } | ||
269 | /* trigger socketcan */ | ||
270 | softing_netdev_rx(netdev, &msg, ktime); | ||
271 | } | ||
272 | |||
273 | } else { | ||
274 | if (cmd & CMD_RTR) | ||
275 | msg.can_id |= CAN_RTR_FLAG; | ||
276 | msg.can_dlc = get_can_dlc(*ptr++); | ||
277 | if (cmd & CMD_XTD) { | ||
278 | msg.can_id |= CAN_EFF_FLAG; | ||
279 | msg.can_id |= le32_to_cpup((void *)ptr); | ||
280 | ptr += 4; | ||
281 | } else { | ||
282 | msg.can_id |= le16_to_cpup((void *)ptr); | ||
283 | ptr += 2; | ||
284 | } | ||
285 | /* timestamp */ | ||
286 | tmp_u32 = le32_to_cpup((void *)ptr); | ||
287 | ptr += 4; | ||
288 | ktime = softing_raw2ktime(card, tmp_u32); | ||
289 | if (!(msg.can_id & CAN_RTR_FLAG)) | ||
290 | memcpy(&msg.data[0], ptr, 8); | ||
291 | ptr += 8; | ||
292 | /* update socket */ | ||
293 | if (cmd & CMD_ACK) { | ||
294 | /* acknowledge, was tx msg */ | ||
295 | struct sk_buff *skb; | ||
296 | skb = priv->can.echo_skb[priv->tx.echo_get]; | ||
297 | if (skb) | ||
298 | skb->tstamp = ktime; | ||
299 | can_get_echo_skb(netdev, priv->tx.echo_get); | ||
300 | ++priv->tx.echo_get; | ||
301 | if (priv->tx.echo_get >= TX_ECHO_SKB_MAX) | ||
302 | priv->tx.echo_get = 0; | ||
303 | if (priv->tx.pending) | ||
304 | --priv->tx.pending; | ||
305 | if (card->tx.pending) | ||
306 | --card->tx.pending; | ||
307 | ++netdev->stats.tx_packets; | ||
308 | if (!(msg.can_id & CAN_RTR_FLAG)) | ||
309 | netdev->stats.tx_bytes += msg.can_dlc; | ||
310 | } else { | ||
311 | int ret; | ||
312 | |||
313 | ret = softing_netdev_rx(netdev, &msg, ktime); | ||
314 | if (ret == NET_RX_SUCCESS) { | ||
315 | ++netdev->stats.rx_packets; | ||
316 | if (!(msg.can_id & CAN_RTR_FLAG)) | ||
317 | netdev->stats.rx_bytes += msg.can_dlc; | ||
318 | } else { | ||
319 | ++netdev->stats.rx_dropped; | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | ++cnt; | ||
324 | return cnt; | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * real interrupt handler | ||
329 | */ | ||
330 | static irqreturn_t softing_irq_thread(int irq, void *dev_id) | ||
331 | { | ||
332 | struct softing *card = (struct softing *)dev_id; | ||
333 | struct net_device *netdev; | ||
334 | struct softing_priv *priv; | ||
335 | int j, offset, work_done; | ||
336 | |||
337 | work_done = 0; | ||
338 | spin_lock_bh(&card->spin); | ||
339 | while (softing_handle_1(card) > 0) { | ||
340 | ++card->irq.svc_count; | ||
341 | ++work_done; | ||
342 | } | ||
343 | spin_unlock_bh(&card->spin); | ||
344 | /* resume tx queue's */ | ||
345 | offset = card->tx.last_bus; | ||
346 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
347 | if (card->tx.pending >= TXMAX) | ||
348 | break; | ||
349 | netdev = card->net[(j + offset + 1) % card->pdat->nbus]; | ||
350 | if (!netdev) | ||
351 | continue; | ||
352 | priv = netdev_priv(netdev); | ||
353 | if (!canif_is_active(netdev)) | ||
354 | /* it makes no sense to wake dead busses */ | ||
355 | continue; | ||
356 | if (priv->tx.pending >= TX_ECHO_SKB_MAX) | ||
357 | continue; | ||
358 | ++work_done; | ||
359 | netif_wake_queue(netdev); | ||
360 | } | ||
361 | return work_done ? IRQ_HANDLED : IRQ_NONE; | ||
362 | } | ||
363 | |||
364 | /* | ||
365 | * interrupt routines: | ||
366 | * schedule the 'real interrupt handler' | ||
367 | */ | ||
368 | static irqreturn_t softing_irq_v2(int irq, void *dev_id) | ||
369 | { | ||
370 | struct softing *card = (struct softing *)dev_id; | ||
371 | uint8_t ir; | ||
372 | |||
373 | ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]); | ||
374 | iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); | ||
375 | return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE; | ||
376 | } | ||
377 | |||
378 | static irqreturn_t softing_irq_v1(int irq, void *dev_id) | ||
379 | { | ||
380 | struct softing *card = (struct softing *)dev_id; | ||
381 | uint8_t ir; | ||
382 | |||
383 | ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]); | ||
384 | iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]); | ||
385 | return ir ? IRQ_WAKE_THREAD : IRQ_NONE; | ||
386 | } | ||
387 | |||
388 | /* | ||
389 | * netdev/candev inter-operability | ||
390 | */ | ||
391 | static int softing_netdev_open(struct net_device *ndev) | ||
392 | { | ||
393 | int ret; | ||
394 | |||
395 | /* check or determine and set bittime */ | ||
396 | ret = open_candev(ndev); | ||
397 | if (!ret) | ||
398 | ret = softing_startstop(ndev, 1); | ||
399 | return ret; | ||
400 | } | ||
401 | |||
402 | static int softing_netdev_stop(struct net_device *ndev) | ||
403 | { | ||
404 | int ret; | ||
405 | |||
406 | netif_stop_queue(ndev); | ||
407 | |||
408 | /* softing cycle does close_candev() */ | ||
409 | ret = softing_startstop(ndev, 0); | ||
410 | return ret; | ||
411 | } | ||
412 | |||
413 | static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode) | ||
414 | { | ||
415 | int ret; | ||
416 | |||
417 | switch (mode) { | ||
418 | case CAN_MODE_START: | ||
419 | /* softing_startstop does close_candev() */ | ||
420 | ret = softing_startstop(ndev, 1); | ||
421 | return ret; | ||
422 | case CAN_MODE_STOP: | ||
423 | case CAN_MODE_SLEEP: | ||
424 | return -EOPNOTSUPP; | ||
425 | } | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * Softing device management helpers | ||
431 | */ | ||
432 | int softing_enable_irq(struct softing *card, int enable) | ||
433 | { | ||
434 | int ret; | ||
435 | |||
436 | if (!card->irq.nr) { | ||
437 | return 0; | ||
438 | } else if (card->irq.requested && !enable) { | ||
439 | free_irq(card->irq.nr, card); | ||
440 | card->irq.requested = 0; | ||
441 | } else if (!card->irq.requested && enable) { | ||
442 | ret = request_threaded_irq(card->irq.nr, | ||
443 | (card->pdat->generation >= 2) ? | ||
444 | softing_irq_v2 : softing_irq_v1, | ||
445 | softing_irq_thread, IRQF_SHARED, | ||
446 | dev_name(&card->pdev->dev), card); | ||
447 | if (ret) { | ||
448 | dev_alert(&card->pdev->dev, | ||
449 | "request_threaded_irq(%u) failed\n", | ||
450 | card->irq.nr); | ||
451 | return ret; | ||
452 | } | ||
453 | card->irq.requested = 1; | ||
454 | } | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static void softing_card_shutdown(struct softing *card) | ||
459 | { | ||
460 | int fw_up = 0; | ||
461 | |||
462 | if (mutex_lock_interruptible(&card->fw.lock)) | ||
463 | /* return -ERESTARTSYS */; | ||
464 | fw_up = card->fw.up; | ||
465 | card->fw.up = 0; | ||
466 | |||
467 | if (card->irq.requested && card->irq.nr) { | ||
468 | free_irq(card->irq.nr, card); | ||
469 | card->irq.requested = 0; | ||
470 | } | ||
471 | if (fw_up) { | ||
472 | if (card->pdat->enable_irq) | ||
473 | card->pdat->enable_irq(card->pdev, 0); | ||
474 | softing_set_reset_dpram(card); | ||
475 | if (card->pdat->reset) | ||
476 | card->pdat->reset(card->pdev, 1); | ||
477 | } | ||
478 | mutex_unlock(&card->fw.lock); | ||
479 | } | ||
480 | |||
481 | static __devinit int softing_card_boot(struct softing *card) | ||
482 | { | ||
483 | int ret, j; | ||
484 | static const uint8_t stream[] = { | ||
485 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }; | ||
486 | unsigned char back[sizeof(stream)]; | ||
487 | |||
488 | if (mutex_lock_interruptible(&card->fw.lock)) | ||
489 | return -ERESTARTSYS; | ||
490 | if (card->fw.up) { | ||
491 | mutex_unlock(&card->fw.lock); | ||
492 | return 0; | ||
493 | } | ||
494 | /* reset board */ | ||
495 | if (card->pdat->enable_irq) | ||
496 | card->pdat->enable_irq(card->pdev, 1); | ||
497 | /* boot card */ | ||
498 | softing_set_reset_dpram(card); | ||
499 | if (card->pdat->reset) | ||
500 | card->pdat->reset(card->pdev, 1); | ||
501 | for (j = 0; (j + sizeof(stream)) < card->dpram_size; | ||
502 | j += sizeof(stream)) { | ||
503 | |||
504 | memcpy_toio(&card->dpram[j], stream, sizeof(stream)); | ||
505 | /* flush IO cache */ | ||
506 | mb(); | ||
507 | memcpy_fromio(back, &card->dpram[j], sizeof(stream)); | ||
508 | |||
509 | if (!memcmp(back, stream, sizeof(stream))) | ||
510 | continue; | ||
511 | /* memory is not equal */ | ||
512 | dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j); | ||
513 | ret = -EIO; | ||
514 | goto failed; | ||
515 | } | ||
516 | wmb(); | ||
517 | /* load boot firmware */ | ||
518 | ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram, | ||
519 | card->dpram_size, | ||
520 | card->pdat->boot.offs - card->pdat->boot.addr); | ||
521 | if (ret < 0) | ||
522 | goto failed; | ||
523 | /* load loader firmware */ | ||
524 | ret = softing_load_fw(card->pdat->load.fw, card, card->dpram, | ||
525 | card->dpram_size, | ||
526 | card->pdat->load.offs - card->pdat->load.addr); | ||
527 | if (ret < 0) | ||
528 | goto failed; | ||
529 | |||
530 | if (card->pdat->reset) | ||
531 | card->pdat->reset(card->pdev, 0); | ||
532 | softing_clr_reset_dpram(card); | ||
533 | ret = softing_bootloader_command(card, 0, "card boot"); | ||
534 | if (ret < 0) | ||
535 | goto failed; | ||
536 | ret = softing_load_app_fw(card->pdat->app.fw, card); | ||
537 | if (ret < 0) | ||
538 | goto failed; | ||
539 | |||
540 | ret = softing_chip_poweron(card); | ||
541 | if (ret < 0) | ||
542 | goto failed; | ||
543 | |||
544 | card->fw.up = 1; | ||
545 | mutex_unlock(&card->fw.lock); | ||
546 | return 0; | ||
547 | failed: | ||
548 | card->fw.up = 0; | ||
549 | if (card->pdat->enable_irq) | ||
550 | card->pdat->enable_irq(card->pdev, 0); | ||
551 | softing_set_reset_dpram(card); | ||
552 | if (card->pdat->reset) | ||
553 | card->pdat->reset(card->pdev, 1); | ||
554 | mutex_unlock(&card->fw.lock); | ||
555 | return ret; | ||
556 | } | ||
557 | |||
558 | /* | ||
559 | * netdev sysfs | ||
560 | */ | ||
561 | static ssize_t show_channel(struct device *dev, struct device_attribute *attr, | ||
562 | char *buf) | ||
563 | { | ||
564 | struct net_device *ndev = to_net_dev(dev); | ||
565 | struct softing_priv *priv = netdev2softing(ndev); | ||
566 | |||
567 | return sprintf(buf, "%i\n", priv->index); | ||
568 | } | ||
569 | |||
570 | static ssize_t show_chip(struct device *dev, struct device_attribute *attr, | ||
571 | char *buf) | ||
572 | { | ||
573 | struct net_device *ndev = to_net_dev(dev); | ||
574 | struct softing_priv *priv = netdev2softing(ndev); | ||
575 | |||
576 | return sprintf(buf, "%i\n", priv->chip); | ||
577 | } | ||
578 | |||
579 | static ssize_t show_output(struct device *dev, struct device_attribute *attr, | ||
580 | char *buf) | ||
581 | { | ||
582 | struct net_device *ndev = to_net_dev(dev); | ||
583 | struct softing_priv *priv = netdev2softing(ndev); | ||
584 | |||
585 | return sprintf(buf, "0x%02x\n", priv->output); | ||
586 | } | ||
587 | |||
588 | static ssize_t store_output(struct device *dev, struct device_attribute *attr, | ||
589 | const char *buf, size_t count) | ||
590 | { | ||
591 | struct net_device *ndev = to_net_dev(dev); | ||
592 | struct softing_priv *priv = netdev2softing(ndev); | ||
593 | struct softing *card = priv->card; | ||
594 | unsigned long val; | ||
595 | int ret; | ||
596 | |||
597 | ret = strict_strtoul(buf, 0, &val); | ||
598 | if (ret < 0) | ||
599 | return ret; | ||
600 | val &= 0xFF; | ||
601 | |||
602 | ret = mutex_lock_interruptible(&card->fw.lock); | ||
603 | if (ret) | ||
604 | return -ERESTARTSYS; | ||
605 | if (netif_running(ndev)) { | ||
606 | mutex_unlock(&card->fw.lock); | ||
607 | return -EBUSY; | ||
608 | } | ||
609 | priv->output = val; | ||
610 | mutex_unlock(&card->fw.lock); | ||
611 | return count; | ||
612 | } | ||
613 | |||
614 | static const DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); | ||
615 | static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL); | ||
616 | static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output); | ||
617 | |||
618 | static const struct attribute *const netdev_sysfs_attrs[] = { | ||
619 | &dev_attr_channel.attr, | ||
620 | &dev_attr_chip.attr, | ||
621 | &dev_attr_output.attr, | ||
622 | NULL, | ||
623 | }; | ||
624 | static const struct attribute_group netdev_sysfs_group = { | ||
625 | .name = NULL, | ||
626 | .attrs = (struct attribute **)netdev_sysfs_attrs, | ||
627 | }; | ||
628 | |||
629 | static const struct net_device_ops softing_netdev_ops = { | ||
630 | .ndo_open = softing_netdev_open, | ||
631 | .ndo_stop = softing_netdev_stop, | ||
632 | .ndo_start_xmit = softing_netdev_start_xmit, | ||
633 | }; | ||
634 | |||
635 | static const struct can_bittiming_const softing_btr_const = { | ||
636 | .tseg1_min = 1, | ||
637 | .tseg1_max = 16, | ||
638 | .tseg2_min = 1, | ||
639 | .tseg2_max = 8, | ||
640 | .sjw_max = 4, /* overruled */ | ||
641 | .brp_min = 1, | ||
642 | .brp_max = 32, /* overruled */ | ||
643 | .brp_inc = 1, | ||
644 | }; | ||
645 | |||
646 | |||
647 | static __devinit struct net_device *softing_netdev_create(struct softing *card, | ||
648 | uint16_t chip_id) | ||
649 | { | ||
650 | struct net_device *netdev; | ||
651 | struct softing_priv *priv; | ||
652 | |||
653 | netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); | ||
654 | if (!netdev) { | ||
655 | dev_alert(&card->pdev->dev, "alloc_candev failed\n"); | ||
656 | return NULL; | ||
657 | } | ||
658 | priv = netdev_priv(netdev); | ||
659 | priv->netdev = netdev; | ||
660 | priv->card = card; | ||
661 | memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const)); | ||
662 | priv->btr_const.brp_max = card->pdat->max_brp; | ||
663 | priv->btr_const.sjw_max = card->pdat->max_sjw; | ||
664 | priv->can.bittiming_const = &priv->btr_const; | ||
665 | priv->can.clock.freq = 8000000; | ||
666 | priv->chip = chip_id; | ||
667 | priv->output = softing_default_output(netdev); | ||
668 | SET_NETDEV_DEV(netdev, &card->pdev->dev); | ||
669 | |||
670 | netdev->flags |= IFF_ECHO; | ||
671 | netdev->netdev_ops = &softing_netdev_ops; | ||
672 | priv->can.do_set_mode = softing_candev_set_mode; | ||
673 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | ||
674 | |||
675 | return netdev; | ||
676 | } | ||
677 | |||
678 | static __devinit int softing_netdev_register(struct net_device *netdev) | ||
679 | { | ||
680 | int ret; | ||
681 | |||
682 | netdev->sysfs_groups[0] = &netdev_sysfs_group; | ||
683 | ret = register_candev(netdev); | ||
684 | if (ret) { | ||
685 | dev_alert(&netdev->dev, "register failed\n"); | ||
686 | return ret; | ||
687 | } | ||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | static void softing_netdev_cleanup(struct net_device *netdev) | ||
692 | { | ||
693 | unregister_candev(netdev); | ||
694 | free_candev(netdev); | ||
695 | } | ||
696 | |||
697 | /* | ||
698 | * sysfs for Platform device | ||
699 | */ | ||
700 | #define DEV_ATTR_RO(name, member) \ | ||
701 | static ssize_t show_##name(struct device *dev, \ | ||
702 | struct device_attribute *attr, char *buf) \ | ||
703 | { \ | ||
704 | struct softing *card = platform_get_drvdata(to_platform_device(dev)); \ | ||
705 | return sprintf(buf, "%u\n", card->member); \ | ||
706 | } \ | ||
707 | static DEVICE_ATTR(name, 0444, show_##name, NULL) | ||
708 | |||
709 | #define DEV_ATTR_RO_STR(name, member) \ | ||
710 | static ssize_t show_##name(struct device *dev, \ | ||
711 | struct device_attribute *attr, char *buf) \ | ||
712 | { \ | ||
713 | struct softing *card = platform_get_drvdata(to_platform_device(dev)); \ | ||
714 | return sprintf(buf, "%s\n", card->member); \ | ||
715 | } \ | ||
716 | static DEVICE_ATTR(name, 0444, show_##name, NULL) | ||
717 | |||
718 | DEV_ATTR_RO(serial, id.serial); | ||
719 | DEV_ATTR_RO_STR(firmware, pdat->app.fw); | ||
720 | DEV_ATTR_RO(firmware_version, id.fw_version); | ||
721 | DEV_ATTR_RO_STR(hardware, pdat->name); | ||
722 | DEV_ATTR_RO(hardware_version, id.hw_version); | ||
723 | DEV_ATTR_RO(license, id.license); | ||
724 | DEV_ATTR_RO(frequency, id.freq); | ||
725 | DEV_ATTR_RO(txpending, tx.pending); | ||
726 | |||
727 | static struct attribute *softing_pdev_attrs[] = { | ||
728 | &dev_attr_serial.attr, | ||
729 | &dev_attr_firmware.attr, | ||
730 | &dev_attr_firmware_version.attr, | ||
731 | &dev_attr_hardware.attr, | ||
732 | &dev_attr_hardware_version.attr, | ||
733 | &dev_attr_license.attr, | ||
734 | &dev_attr_frequency.attr, | ||
735 | &dev_attr_txpending.attr, | ||
736 | NULL, | ||
737 | }; | ||
738 | |||
739 | static const struct attribute_group softing_pdev_group = { | ||
740 | .name = NULL, | ||
741 | .attrs = softing_pdev_attrs, | ||
742 | }; | ||
743 | |||
744 | /* | ||
745 | * platform driver | ||
746 | */ | ||
747 | static __devexit int softing_pdev_remove(struct platform_device *pdev) | ||
748 | { | ||
749 | struct softing *card = platform_get_drvdata(pdev); | ||
750 | int j; | ||
751 | |||
752 | /* first, disable card*/ | ||
753 | softing_card_shutdown(card); | ||
754 | |||
755 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
756 | if (!card->net[j]) | ||
757 | continue; | ||
758 | softing_netdev_cleanup(card->net[j]); | ||
759 | card->net[j] = NULL; | ||
760 | } | ||
761 | sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); | ||
762 | |||
763 | iounmap(card->dpram); | ||
764 | kfree(card); | ||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | static __devinit int softing_pdev_probe(struct platform_device *pdev) | ||
769 | { | ||
770 | const struct softing_platform_data *pdat = pdev->dev.platform_data; | ||
771 | struct softing *card; | ||
772 | struct net_device *netdev; | ||
773 | struct softing_priv *priv; | ||
774 | struct resource *pres; | ||
775 | int ret; | ||
776 | int j; | ||
777 | |||
778 | if (!pdat) { | ||
779 | dev_warn(&pdev->dev, "no platform data\n"); | ||
780 | return -EINVAL; | ||
781 | } | ||
782 | if (pdat->nbus > ARRAY_SIZE(card->net)) { | ||
783 | dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus); | ||
784 | return -EINVAL; | ||
785 | } | ||
786 | |||
787 | card = kzalloc(sizeof(*card), GFP_KERNEL); | ||
788 | if (!card) | ||
789 | return -ENOMEM; | ||
790 | card->pdat = pdat; | ||
791 | card->pdev = pdev; | ||
792 | platform_set_drvdata(pdev, card); | ||
793 | mutex_init(&card->fw.lock); | ||
794 | spin_lock_init(&card->spin); | ||
795 | |||
796 | ret = -EINVAL; | ||
797 | pres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
798 | if (!pres) | ||
799 | goto platform_resource_failed;; | ||
800 | card->dpram_phys = pres->start; | ||
801 | card->dpram_size = pres->end - pres->start + 1; | ||
802 | card->dpram = ioremap_nocache(card->dpram_phys, card->dpram_size); | ||
803 | if (!card->dpram) { | ||
804 | dev_alert(&card->pdev->dev, "dpram ioremap failed\n"); | ||
805 | goto ioremap_failed; | ||
806 | } | ||
807 | |||
808 | pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
809 | if (pres) | ||
810 | card->irq.nr = pres->start; | ||
811 | |||
812 | /* reset card */ | ||
813 | ret = softing_card_boot(card); | ||
814 | if (ret < 0) { | ||
815 | dev_alert(&pdev->dev, "failed to boot\n"); | ||
816 | goto boot_failed; | ||
817 | } | ||
818 | |||
819 | /* only now, the chip's are known */ | ||
820 | card->id.freq = card->pdat->freq; | ||
821 | |||
822 | ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group); | ||
823 | if (ret < 0) { | ||
824 | dev_alert(&card->pdev->dev, "sysfs failed\n"); | ||
825 | goto sysfs_failed; | ||
826 | } | ||
827 | |||
828 | ret = -ENOMEM; | ||
829 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
830 | card->net[j] = netdev = | ||
831 | softing_netdev_create(card, card->id.chip[j]); | ||
832 | if (!netdev) { | ||
833 | dev_alert(&pdev->dev, "failed to make can[%i]", j); | ||
834 | goto netdev_failed; | ||
835 | } | ||
836 | priv = netdev_priv(card->net[j]); | ||
837 | priv->index = j; | ||
838 | ret = softing_netdev_register(netdev); | ||
839 | if (ret) { | ||
840 | free_candev(netdev); | ||
841 | card->net[j] = NULL; | ||
842 | dev_alert(&card->pdev->dev, | ||
843 | "failed to register can[%i]\n", j); | ||
844 | goto netdev_failed; | ||
845 | } | ||
846 | } | ||
847 | dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name); | ||
848 | return 0; | ||
849 | |||
850 | netdev_failed: | ||
851 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
852 | if (!card->net[j]) | ||
853 | continue; | ||
854 | softing_netdev_cleanup(card->net[j]); | ||
855 | } | ||
856 | sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); | ||
857 | sysfs_failed: | ||
858 | softing_card_shutdown(card); | ||
859 | boot_failed: | ||
860 | iounmap(card->dpram); | ||
861 | ioremap_failed: | ||
862 | platform_resource_failed: | ||
863 | kfree(card); | ||
864 | return ret; | ||
865 | } | ||
866 | |||
867 | static struct platform_driver softing_driver = { | ||
868 | .driver = { | ||
869 | .name = "softing", | ||
870 | .owner = THIS_MODULE, | ||
871 | }, | ||
872 | .probe = softing_pdev_probe, | ||
873 | .remove = __devexit_p(softing_pdev_remove), | ||
874 | }; | ||
875 | |||
876 | MODULE_ALIAS("platform:softing"); | ||
877 | |||
878 | static int __init softing_start(void) | ||
879 | { | ||
880 | return platform_driver_register(&softing_driver); | ||
881 | } | ||
882 | |||
883 | static void __exit softing_stop(void) | ||
884 | { | ||
885 | platform_driver_unregister(&softing_driver); | ||
886 | } | ||
887 | |||
888 | module_init(softing_start); | ||
889 | module_exit(softing_stop); | ||
890 | |||
891 | MODULE_DESCRIPTION("Softing DPRAM CAN driver"); | ||
892 | MODULE_AUTHOR("Kurt Van Dijck <kurt.van.dijck@eia.be>"); | ||
893 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/can/softing/softing_platform.h b/drivers/net/can/softing/softing_platform.h new file mode 100644 index 000000000000..ebbf69815623 --- /dev/null +++ b/drivers/net/can/softing/softing_platform.h | |||
@@ -0,0 +1,40 @@ | |||
1 | |||
2 | #include <linux/platform_device.h> | ||
3 | |||
4 | #ifndef _SOFTING_DEVICE_H_ | ||
5 | #define _SOFTING_DEVICE_H_ | ||
6 | |||
7 | /* softing firmware directory prefix */ | ||
8 | #define fw_dir "softing-4.6/" | ||
9 | |||
10 | struct softing_platform_data { | ||
11 | unsigned int manf; | ||
12 | unsigned int prod; | ||
13 | /* | ||
14 | * generation | ||
15 | * 1st with NEC or SJA1000 | ||
16 | * 8bit, exclusive interrupt, ... | ||
17 | * 2nd only SJA1000 | ||
18 | * 16bit, shared interrupt | ||
19 | */ | ||
20 | int generation; | ||
21 | int nbus; /* # busses on device */ | ||
22 | unsigned int freq; /* operating frequency in Hz */ | ||
23 | unsigned int max_brp; | ||
24 | unsigned int max_sjw; | ||
25 | unsigned long dpram_size; | ||
26 | const char *name; | ||
27 | struct { | ||
28 | unsigned long offs; | ||
29 | unsigned long addr; | ||
30 | const char *fw; | ||
31 | } boot, load, app; | ||
32 | /* | ||
33 | * reset() function | ||
34 | * bring pdev in or out of reset, depending on value | ||
35 | */ | ||
36 | int (*reset)(struct platform_device *pdev, int value); | ||
37 | int (*enable_irq)(struct platform_device *pdev, int value); | ||
38 | }; | ||
39 | |||
40 | #endif | ||