diff options
author | David S. Miller <davem@davemloft.net> | 2013-01-28 00:19:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-28 00:19:34 -0500 |
commit | 61550022b9586972082904b80de26a464c558437 (patch) | |
tree | 590c21eed5f723162d3821a398b6d3831f75a488 | |
parent | 0e36cbb344575e481167e090f0926701f83207d6 (diff) | |
parent | e6afa00a1409bc3bceed9ccb33111519463dfe7b (diff) |
Merge branch 'for-davem' of git://gitorious.org/linux-can/linux-can-next
Marc Kleine-Budde says:
====================
this is a pull-request for net-next/master. There is are 9 patches by
Fabio Baltieri and Kurt Van Dijck which add LED infrastructure and
support for CAN devices. Bernd Krumboeck adds a driver for the USB CAN
adapter from 8 devices. Oliver Hartkopp improves the CAN gateway
functionality. There are 4 patches by me, which clean up the CAN's
Kconfig.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
27 files changed, 1488 insertions, 60 deletions
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index b56bd9e80957..1cca19f1c490 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
@@ -1,9 +1,7 @@ | |||
1 | menu "CAN Device Drivers" | 1 | menu "CAN Device Drivers" |
2 | depends on CAN | ||
3 | 2 | ||
4 | config CAN_VCAN | 3 | config CAN_VCAN |
5 | tristate "Virtual Local CAN Interface (vcan)" | 4 | tristate "Virtual Local CAN Interface (vcan)" |
6 | depends on CAN | ||
7 | ---help--- | 5 | ---help--- |
8 | Similar to the network loopback devices, vcan offers a | 6 | Similar to the network loopback devices, vcan offers a |
9 | virtual local CAN interface. | 7 | virtual local CAN interface. |
@@ -13,7 +11,6 @@ config CAN_VCAN | |||
13 | 11 | ||
14 | config CAN_SLCAN | 12 | config CAN_SLCAN |
15 | tristate "Serial / USB serial CAN Adaptors (slcan)" | 13 | tristate "Serial / USB serial CAN Adaptors (slcan)" |
16 | depends on CAN | ||
17 | ---help--- | 14 | ---help--- |
18 | CAN driver for several 'low cost' CAN interfaces that are attached | 15 | CAN driver for several 'low cost' CAN interfaces that are attached |
19 | via serial lines or via USB-to-serial adapters using the LAWICEL | 16 | via serial lines or via USB-to-serial adapters using the LAWICEL |
@@ -33,16 +30,16 @@ config CAN_SLCAN | |||
33 | 30 | ||
34 | config CAN_DEV | 31 | config CAN_DEV |
35 | tristate "Platform CAN drivers with Netlink support" | 32 | tristate "Platform CAN drivers with Netlink support" |
36 | depends on CAN | ||
37 | default y | 33 | default y |
38 | ---help--- | 34 | ---help--- |
39 | Enables the common framework for platform CAN drivers with Netlink | 35 | Enables the common framework for platform CAN drivers with Netlink |
40 | support. This is the standard library for CAN drivers. | 36 | support. This is the standard library for CAN drivers. |
41 | If unsure, say Y. | 37 | If unsure, say Y. |
42 | 38 | ||
39 | if CAN_DEV | ||
40 | |||
43 | config CAN_CALC_BITTIMING | 41 | config CAN_CALC_BITTIMING |
44 | bool "CAN bit-timing calculation" | 42 | bool "CAN bit-timing calculation" |
45 | depends on CAN_DEV | ||
46 | default y | 43 | default y |
47 | ---help--- | 44 | ---help--- |
48 | If enabled, CAN bit-timing parameters will be calculated for the | 45 | If enabled, CAN bit-timing parameters will be calculated for the |
@@ -54,15 +51,26 @@ config CAN_CALC_BITTIMING | |||
54 | arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". | 51 | arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". |
55 | If unsure, say Y. | 52 | If unsure, say Y. |
56 | 53 | ||
54 | config CAN_LEDS | ||
55 | bool "Enable LED triggers for Netlink based drivers" | ||
56 | depends on LEDS_CLASS | ||
57 | select LEDS_TRIGGERS | ||
58 | ---help--- | ||
59 | This option adds two LED triggers for packet receive and transmit | ||
60 | events on each supported CAN device. | ||
61 | |||
62 | Say Y here if you are working on a system with led-class supported | ||
63 | LEDs and you want to use them as canbus activity indicators. | ||
64 | |||
57 | config CAN_AT91 | 65 | config CAN_AT91 |
58 | tristate "Atmel AT91 onchip CAN controller" | 66 | tristate "Atmel AT91 onchip CAN controller" |
59 | depends on CAN_DEV && (ARCH_AT91SAM9263 || ARCH_AT91SAM9X5) | 67 | depends on ARCH_AT91SAM9263 || ARCH_AT91SAM9X5 |
60 | ---help--- | 68 | ---help--- |
61 | This is a driver for the SoC CAN controller in Atmel's AT91SAM9263 | 69 | This is a driver for the SoC CAN controller in Atmel's AT91SAM9263 |
62 | and AT91SAM9X5 processors. | 70 | and AT91SAM9X5 processors. |
63 | 71 | ||
64 | config CAN_TI_HECC | 72 | config CAN_TI_HECC |
65 | depends on CAN_DEV && ARCH_OMAP3 | 73 | depends on ARCH_OMAP3 |
66 | tristate "TI High End CAN Controller" | 74 | tristate "TI High End CAN Controller" |
67 | ---help--- | 75 | ---help--- |
68 | Driver for TI HECC (High End CAN Controller) module found on many | 76 | Driver for TI HECC (High End CAN Controller) module found on many |
@@ -70,12 +78,12 @@ config CAN_TI_HECC | |||
70 | 78 | ||
71 | config CAN_MCP251X | 79 | config CAN_MCP251X |
72 | tristate "Microchip MCP251x SPI CAN controllers" | 80 | tristate "Microchip MCP251x SPI CAN controllers" |
73 | depends on CAN_DEV && SPI && HAS_DMA | 81 | depends on SPI && HAS_DMA |
74 | ---help--- | 82 | ---help--- |
75 | Driver for the Microchip MCP251x SPI CAN controllers. | 83 | Driver for the Microchip MCP251x SPI CAN controllers. |
76 | 84 | ||
77 | config CAN_BFIN | 85 | config CAN_BFIN |
78 | depends on CAN_DEV && (BF534 || BF536 || BF537 || BF538 || BF539 || BF54x) | 86 | depends on BF534 || BF536 || BF537 || BF538 || BF539 || BF54x |
79 | tristate "Analog Devices Blackfin on-chip CAN" | 87 | tristate "Analog Devices Blackfin on-chip CAN" |
80 | ---help--- | 88 | ---help--- |
81 | Driver for the Analog Devices Blackfin on-chip CAN controllers | 89 | Driver for the Analog Devices Blackfin on-chip CAN controllers |
@@ -85,7 +93,7 @@ config CAN_BFIN | |||
85 | 93 | ||
86 | config CAN_JANZ_ICAN3 | 94 | config CAN_JANZ_ICAN3 |
87 | tristate "Janz VMOD-ICAN3 Intelligent CAN controller" | 95 | tristate "Janz VMOD-ICAN3 Intelligent CAN controller" |
88 | depends on CAN_DEV && MFD_JANZ_CMODIO | 96 | depends on MFD_JANZ_CMODIO |
89 | ---help--- | 97 | ---help--- |
90 | Driver for Janz VMOD-ICAN3 Intelligent CAN controller module, which | 98 | Driver for Janz VMOD-ICAN3 Intelligent CAN controller module, which |
91 | connects to a MODULbus carrier board. | 99 | connects to a MODULbus carrier board. |
@@ -98,13 +106,13 @@ config HAVE_CAN_FLEXCAN | |||
98 | 106 | ||
99 | config CAN_FLEXCAN | 107 | config CAN_FLEXCAN |
100 | tristate "Support for Freescale FLEXCAN based chips" | 108 | tristate "Support for Freescale FLEXCAN based chips" |
101 | depends on CAN_DEV && HAVE_CAN_FLEXCAN | 109 | depends on HAVE_CAN_FLEXCAN |
102 | ---help--- | 110 | ---help--- |
103 | Say Y here if you want to support for Freescale FlexCAN. | 111 | Say Y here if you want to support for Freescale FlexCAN. |
104 | 112 | ||
105 | config PCH_CAN | 113 | config PCH_CAN |
106 | tristate "Intel EG20T PCH CAN controller" | 114 | tristate "Intel EG20T PCH CAN controller" |
107 | depends on CAN_DEV && PCI | 115 | depends on PCI |
108 | ---help--- | 116 | ---help--- |
109 | This driver is for PCH CAN of Topcliff (Intel EG20T PCH) which | 117 | This driver is for PCH CAN of Topcliff (Intel EG20T PCH) which |
110 | is an IOH for x86 embedded processor (Intel Atom E6xx series). | 118 | is an IOH for x86 embedded processor (Intel Atom E6xx series). |
@@ -112,7 +120,7 @@ config PCH_CAN | |||
112 | 120 | ||
113 | config CAN_GRCAN | 121 | config CAN_GRCAN |
114 | tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices" | 122 | tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices" |
115 | depends on CAN_DEV && OF | 123 | depends on OF |
116 | ---help--- | 124 | ---help--- |
117 | Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN. | 125 | Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN. |
118 | Note that the driver supports little endian, even though little | 126 | Note that the driver supports little endian, even though little |
@@ -131,9 +139,10 @@ source "drivers/net/can/usb/Kconfig" | |||
131 | 139 | ||
132 | source "drivers/net/can/softing/Kconfig" | 140 | source "drivers/net/can/softing/Kconfig" |
133 | 141 | ||
142 | endif | ||
143 | |||
134 | config CAN_DEBUG_DEVICES | 144 | config CAN_DEBUG_DEVICES |
135 | bool "CAN devices debugging messages" | 145 | bool "CAN devices debugging messages" |
136 | depends on CAN | ||
137 | ---help--- | 146 | ---help--- |
138 | Say Y here if you want the CAN device drivers to produce a bunch of | 147 | Say Y here if you want the CAN device drivers to produce a bunch of |
139 | debug messages to the system log. Select this if you are having | 148 | debug messages to the system log. Select this if you are having |
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 7de59862bbe9..c7440392adbb 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile | |||
@@ -8,6 +8,8 @@ obj-$(CONFIG_CAN_SLCAN) += slcan.o | |||
8 | obj-$(CONFIG_CAN_DEV) += can-dev.o | 8 | obj-$(CONFIG_CAN_DEV) += can-dev.o |
9 | can-dev-y := dev.o | 9 | can-dev-y := dev.o |
10 | 10 | ||
11 | can-dev-$(CONFIG_CAN_LEDS) += led.o | ||
12 | |||
11 | obj-y += usb/ | 13 | obj-y += usb/ |
12 | obj-y += softing/ | 14 | obj-y += softing/ |
13 | 15 | ||
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 81baefda037b..44f363792b59 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include <linux/can/dev.h> | 38 | #include <linux/can/dev.h> |
39 | #include <linux/can/error.h> | 39 | #include <linux/can/error.h> |
40 | #include <linux/can/led.h> | ||
40 | 41 | ||
41 | #define AT91_MB_MASK(i) ((1 << (i)) - 1) | 42 | #define AT91_MB_MASK(i) ((1 << (i)) - 1) |
42 | 43 | ||
@@ -641,6 +642,8 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) | |||
641 | 642 | ||
642 | stats->rx_packets++; | 643 | stats->rx_packets++; |
643 | stats->rx_bytes += cf->can_dlc; | 644 | stats->rx_bytes += cf->can_dlc; |
645 | |||
646 | can_led_event(dev, CAN_LED_EVENT_RX); | ||
644 | } | 647 | } |
645 | 648 | ||
646 | /** | 649 | /** |
@@ -875,6 +878,7 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr) | |||
875 | /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ | 878 | /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ |
876 | can_get_echo_skb(dev, mb - get_mb_tx_first(priv)); | 879 | can_get_echo_skb(dev, mb - get_mb_tx_first(priv)); |
877 | dev->stats.tx_packets++; | 880 | dev->stats.tx_packets++; |
881 | can_led_event(dev, CAN_LED_EVENT_TX); | ||
878 | } | 882 | } |
879 | } | 883 | } |
880 | 884 | ||
@@ -1128,6 +1132,8 @@ static int at91_open(struct net_device *dev) | |||
1128 | goto out_close; | 1132 | goto out_close; |
1129 | } | 1133 | } |
1130 | 1134 | ||
1135 | can_led_event(dev, CAN_LED_EVENT_OPEN); | ||
1136 | |||
1131 | /* start chip and queuing */ | 1137 | /* start chip and queuing */ |
1132 | at91_chip_start(dev); | 1138 | at91_chip_start(dev); |
1133 | napi_enable(&priv->napi); | 1139 | napi_enable(&priv->napi); |
@@ -1159,6 +1165,8 @@ static int at91_close(struct net_device *dev) | |||
1159 | 1165 | ||
1160 | close_candev(dev); | 1166 | close_candev(dev); |
1161 | 1167 | ||
1168 | can_led_event(dev, CAN_LED_EVENT_STOP); | ||
1169 | |||
1162 | return 0; | 1170 | return 0; |
1163 | } | 1171 | } |
1164 | 1172 | ||
@@ -1321,6 +1329,8 @@ static int at91_can_probe(struct platform_device *pdev) | |||
1321 | goto exit_free; | 1329 | goto exit_free; |
1322 | } | 1330 | } |
1323 | 1331 | ||
1332 | devm_can_led_init(dev); | ||
1333 | |||
1324 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", | 1334 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", |
1325 | priv->reg_base, dev->irq); | 1335 | priv->reg_base, dev->irq); |
1326 | 1336 | ||
diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig index 3b83bafcd947..61ffc12d8fd8 100644 --- a/drivers/net/can/c_can/Kconfig +++ b/drivers/net/can/c_can/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | menuconfig CAN_C_CAN | 1 | menuconfig CAN_C_CAN |
2 | tristate "Bosch C_CAN/D_CAN devices" | 2 | tristate "Bosch C_CAN/D_CAN devices" |
3 | depends on CAN_DEV && HAS_IOMEM | 3 | depends on HAS_IOMEM |
4 | 4 | ||
5 | if CAN_C_CAN | 5 | if CAN_C_CAN |
6 | 6 | ||
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 5233b8f58d77..57eb1e77865d 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/can.h> | 39 | #include <linux/can.h> |
40 | #include <linux/can/dev.h> | 40 | #include <linux/can/dev.h> |
41 | #include <linux/can/error.h> | 41 | #include <linux/can/error.h> |
42 | #include <linux/can/led.h> | ||
42 | 43 | ||
43 | #include "c_can.h" | 44 | #include "c_can.h" |
44 | 45 | ||
@@ -477,6 +478,8 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) | |||
477 | stats->rx_packets++; | 478 | stats->rx_packets++; |
478 | stats->rx_bytes += frame->can_dlc; | 479 | stats->rx_bytes += frame->can_dlc; |
479 | 480 | ||
481 | can_led_event(dev, CAN_LED_EVENT_RX); | ||
482 | |||
480 | return 0; | 483 | return 0; |
481 | } | 484 | } |
482 | 485 | ||
@@ -751,6 +754,7 @@ static void c_can_do_tx(struct net_device *dev) | |||
751 | C_CAN_IFACE(MSGCTRL_REG, 0)) | 754 | C_CAN_IFACE(MSGCTRL_REG, 0)) |
752 | & IF_MCONT_DLC_MASK; | 755 | & IF_MCONT_DLC_MASK; |
753 | stats->tx_packets++; | 756 | stats->tx_packets++; |
757 | can_led_event(dev, CAN_LED_EVENT_TX); | ||
754 | c_can_inval_msg_object(dev, 0, msg_obj_no); | 758 | c_can_inval_msg_object(dev, 0, msg_obj_no); |
755 | } else { | 759 | } else { |
756 | break; | 760 | break; |
@@ -1115,6 +1119,8 @@ static int c_can_open(struct net_device *dev) | |||
1115 | 1119 | ||
1116 | napi_enable(&priv->napi); | 1120 | napi_enable(&priv->napi); |
1117 | 1121 | ||
1122 | can_led_event(dev, CAN_LED_EVENT_OPEN); | ||
1123 | |||
1118 | /* start the c_can controller */ | 1124 | /* start the c_can controller */ |
1119 | c_can_start(dev); | 1125 | c_can_start(dev); |
1120 | 1126 | ||
@@ -1143,6 +1149,8 @@ static int c_can_close(struct net_device *dev) | |||
1143 | c_can_reset_ram(priv, false); | 1149 | c_can_reset_ram(priv, false); |
1144 | c_can_pm_runtime_put_sync(priv); | 1150 | c_can_pm_runtime_put_sync(priv); |
1145 | 1151 | ||
1152 | can_led_event(dev, CAN_LED_EVENT_STOP); | ||
1153 | |||
1146 | return 0; | 1154 | return 0; |
1147 | } | 1155 | } |
1148 | 1156 | ||
@@ -1268,6 +1276,8 @@ int register_c_can_dev(struct net_device *dev) | |||
1268 | err = register_candev(dev); | 1276 | err = register_candev(dev); |
1269 | if (err) | 1277 | if (err) |
1270 | c_can_pm_runtime_disable(priv); | 1278 | c_can_pm_runtime_disable(priv); |
1279 | else | ||
1280 | devm_can_led_init(dev); | ||
1271 | 1281 | ||
1272 | return err; | 1282 | return err; |
1273 | } | 1283 | } |
diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig index 22c07a8c8b43..6a9a5ba79220 100644 --- a/drivers/net/can/cc770/Kconfig +++ b/drivers/net/can/cc770/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | menuconfig CAN_CC770 | 1 | menuconfig CAN_CC770 |
2 | tristate "Bosch CC770 and Intel AN82527 devices" | 2 | tristate "Bosch CC770 and Intel AN82527 devices" |
3 | depends on CAN_DEV && HAS_IOMEM | 3 | depends on HAS_IOMEM |
4 | 4 | ||
5 | if CAN_CC770 | 5 | if CAN_CC770 |
6 | 6 | ||
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 8233e5ed2939..59ada082a994 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -24,7 +24,9 @@ | |||
24 | #include <linux/if_arp.h> | 24 | #include <linux/if_arp.h> |
25 | #include <linux/can.h> | 25 | #include <linux/can.h> |
26 | #include <linux/can/dev.h> | 26 | #include <linux/can/dev.h> |
27 | #include <linux/can/skb.h> | ||
27 | #include <linux/can/netlink.h> | 28 | #include <linux/can/netlink.h> |
29 | #include <linux/can/led.h> | ||
28 | #include <net/rtnetlink.h> | 30 | #include <net/rtnetlink.h> |
29 | 31 | ||
30 | #define MOD_DESC "CAN device driver interface" | 32 | #define MOD_DESC "CAN device driver interface" |
@@ -501,13 +503,18 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) | |||
501 | { | 503 | { |
502 | struct sk_buff *skb; | 504 | struct sk_buff *skb; |
503 | 505 | ||
504 | skb = netdev_alloc_skb(dev, sizeof(struct can_frame)); | 506 | skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + |
507 | sizeof(struct can_frame)); | ||
505 | if (unlikely(!skb)) | 508 | if (unlikely(!skb)) |
506 | return NULL; | 509 | return NULL; |
507 | 510 | ||
508 | skb->protocol = htons(ETH_P_CAN); | 511 | skb->protocol = htons(ETH_P_CAN); |
509 | skb->pkt_type = PACKET_BROADCAST; | 512 | skb->pkt_type = PACKET_BROADCAST; |
510 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 513 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
514 | |||
515 | skb_reserve(skb, sizeof(struct can_skb_priv)); | ||
516 | ((struct can_skb_priv *)(skb->head))->ifindex = dev->ifindex; | ||
517 | |||
511 | *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); | 518 | *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame)); |
512 | memset(*cf, 0, sizeof(struct can_frame)); | 519 | memset(*cf, 0, sizeof(struct can_frame)); |
513 | 520 | ||
@@ -794,10 +801,25 @@ void unregister_candev(struct net_device *dev) | |||
794 | } | 801 | } |
795 | EXPORT_SYMBOL_GPL(unregister_candev); | 802 | EXPORT_SYMBOL_GPL(unregister_candev); |
796 | 803 | ||
804 | /* | ||
805 | * Test if a network device is a candev based device | ||
806 | * and return the can_priv* if so. | ||
807 | */ | ||
808 | struct can_priv *safe_candev_priv(struct net_device *dev) | ||
809 | { | ||
810 | if ((dev->type != ARPHRD_CAN) || (dev->rtnl_link_ops != &can_link_ops)) | ||
811 | return NULL; | ||
812 | |||
813 | return netdev_priv(dev); | ||
814 | } | ||
815 | EXPORT_SYMBOL_GPL(safe_candev_priv); | ||
816 | |||
797 | static __init int can_dev_init(void) | 817 | static __init int can_dev_init(void) |
798 | { | 818 | { |
799 | int err; | 819 | int err; |
800 | 820 | ||
821 | can_led_notifier_init(); | ||
822 | |||
801 | err = rtnl_link_register(&can_link_ops); | 823 | err = rtnl_link_register(&can_link_ops); |
802 | if (!err) | 824 | if (!err) |
803 | printk(KERN_INFO MOD_DESC "\n"); | 825 | printk(KERN_INFO MOD_DESC "\n"); |
@@ -809,6 +831,8 @@ module_init(can_dev_init); | |||
809 | static __exit void can_dev_exit(void) | 831 | static __exit void can_dev_exit(void) |
810 | { | 832 | { |
811 | rtnl_link_unregister(&can_link_ops); | 833 | rtnl_link_unregister(&can_link_ops); |
834 | |||
835 | can_led_notifier_exit(); | ||
812 | } | 836 | } |
813 | module_exit(can_dev_exit); | 837 | module_exit(can_dev_exit); |
814 | 838 | ||
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 0289a6d86f66..769d29ed106d 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/can.h> | 23 | #include <linux/can.h> |
24 | #include <linux/can/dev.h> | 24 | #include <linux/can/dev.h> |
25 | #include <linux/can/error.h> | 25 | #include <linux/can/error.h> |
26 | #include <linux/can/led.h> | ||
26 | #include <linux/can/platform/flexcan.h> | 27 | #include <linux/can/platform/flexcan.h> |
27 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
@@ -564,6 +565,8 @@ static int flexcan_read_frame(struct net_device *dev) | |||
564 | stats->rx_packets++; | 565 | stats->rx_packets++; |
565 | stats->rx_bytes += cf->can_dlc; | 566 | stats->rx_bytes += cf->can_dlc; |
566 | 567 | ||
568 | can_led_event(dev, CAN_LED_EVENT_RX); | ||
569 | |||
567 | return 1; | 570 | return 1; |
568 | } | 571 | } |
569 | 572 | ||
@@ -652,6 +655,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
652 | if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) { | 655 | if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) { |
653 | stats->tx_bytes += can_get_echo_skb(dev, 0); | 656 | stats->tx_bytes += can_get_echo_skb(dev, 0); |
654 | stats->tx_packets++; | 657 | stats->tx_packets++; |
658 | can_led_event(dev, CAN_LED_EVENT_TX); | ||
655 | flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); | 659 | flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); |
656 | netif_wake_queue(dev); | 660 | netif_wake_queue(dev); |
657 | } | 661 | } |
@@ -865,6 +869,9 @@ static int flexcan_open(struct net_device *dev) | |||
865 | err = flexcan_chip_start(dev); | 869 | err = flexcan_chip_start(dev); |
866 | if (err) | 870 | if (err) |
867 | goto out_close; | 871 | goto out_close; |
872 | |||
873 | can_led_event(dev, CAN_LED_EVENT_OPEN); | ||
874 | |||
868 | napi_enable(&priv->napi); | 875 | napi_enable(&priv->napi); |
869 | netif_start_queue(dev); | 876 | netif_start_queue(dev); |
870 | 877 | ||
@@ -893,6 +900,8 @@ static int flexcan_close(struct net_device *dev) | |||
893 | 900 | ||
894 | close_candev(dev); | 901 | close_candev(dev); |
895 | 902 | ||
903 | can_led_event(dev, CAN_LED_EVENT_STOP); | ||
904 | |||
896 | return 0; | 905 | return 0; |
897 | } | 906 | } |
898 | 907 | ||
@@ -1092,6 +1101,8 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1092 | goto failed_register; | 1101 | goto failed_register; |
1093 | } | 1102 | } |
1094 | 1103 | ||
1104 | devm_can_led_init(dev); | ||
1105 | |||
1095 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", | 1106 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", |
1096 | priv->base, dev->irq); | 1107 | priv->base, dev->irq); |
1097 | 1108 | ||
diff --git a/drivers/net/can/led.c b/drivers/net/can/led.c new file mode 100644 index 000000000000..f27fca65dc4a --- /dev/null +++ b/drivers/net/can/led.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com> | ||
3 | * Copyright 2012, Kurt Van Dijck <kurt.van.dijck@eia.be> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/netdevice.h> | ||
15 | #include <linux/can/dev.h> | ||
16 | |||
17 | #include <linux/can/led.h> | ||
18 | |||
19 | static unsigned long led_delay = 50; | ||
20 | module_param(led_delay, ulong, 0644); | ||
21 | MODULE_PARM_DESC(led_delay, | ||
22 | "blink delay time for activity leds (msecs, default: 50)."); | ||
23 | |||
24 | /* Trigger a LED event in response to a CAN device event */ | ||
25 | void can_led_event(struct net_device *netdev, enum can_led_event event) | ||
26 | { | ||
27 | struct can_priv *priv = netdev_priv(netdev); | ||
28 | |||
29 | switch (event) { | ||
30 | case CAN_LED_EVENT_OPEN: | ||
31 | led_trigger_event(priv->tx_led_trig, LED_FULL); | ||
32 | led_trigger_event(priv->rx_led_trig, LED_FULL); | ||
33 | break; | ||
34 | case CAN_LED_EVENT_STOP: | ||
35 | led_trigger_event(priv->tx_led_trig, LED_OFF); | ||
36 | led_trigger_event(priv->rx_led_trig, LED_OFF); | ||
37 | break; | ||
38 | case CAN_LED_EVENT_TX: | ||
39 | if (led_delay) | ||
40 | led_trigger_blink_oneshot(priv->tx_led_trig, | ||
41 | &led_delay, &led_delay, 1); | ||
42 | break; | ||
43 | case CAN_LED_EVENT_RX: | ||
44 | if (led_delay) | ||
45 | led_trigger_blink_oneshot(priv->rx_led_trig, | ||
46 | &led_delay, &led_delay, 1); | ||
47 | break; | ||
48 | } | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(can_led_event); | ||
51 | |||
52 | static void can_led_release(struct device *gendev, void *res) | ||
53 | { | ||
54 | struct can_priv *priv = netdev_priv(to_net_dev(gendev)); | ||
55 | |||
56 | led_trigger_unregister_simple(priv->tx_led_trig); | ||
57 | led_trigger_unregister_simple(priv->rx_led_trig); | ||
58 | } | ||
59 | |||
60 | /* Register CAN LED triggers for a CAN device | ||
61 | * | ||
62 | * This is normally called from a driver's probe function | ||
63 | */ | ||
64 | void devm_can_led_init(struct net_device *netdev) | ||
65 | { | ||
66 | struct can_priv *priv = netdev_priv(netdev); | ||
67 | void *res; | ||
68 | |||
69 | res = devres_alloc(can_led_release, 0, GFP_KERNEL); | ||
70 | if (!res) { | ||
71 | netdev_err(netdev, "cannot register LED triggers\n"); | ||
72 | return; | ||
73 | } | ||
74 | |||
75 | snprintf(priv->tx_led_trig_name, sizeof(priv->tx_led_trig_name), | ||
76 | "%s-tx", netdev->name); | ||
77 | snprintf(priv->rx_led_trig_name, sizeof(priv->rx_led_trig_name), | ||
78 | "%s-rx", netdev->name); | ||
79 | |||
80 | led_trigger_register_simple(priv->tx_led_trig_name, | ||
81 | &priv->tx_led_trig); | ||
82 | led_trigger_register_simple(priv->rx_led_trig_name, | ||
83 | &priv->rx_led_trig); | ||
84 | |||
85 | devres_add(&netdev->dev, res); | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(devm_can_led_init); | ||
88 | |||
89 | /* NETDEV rename notifier to rename the associated led triggers too */ | ||
90 | static int can_led_notifier(struct notifier_block *nb, unsigned long msg, | ||
91 | void *data) | ||
92 | { | ||
93 | struct net_device *netdev = data; | ||
94 | struct can_priv *priv = safe_candev_priv(netdev); | ||
95 | char name[CAN_LED_NAME_SZ]; | ||
96 | |||
97 | if (!priv) | ||
98 | return NOTIFY_DONE; | ||
99 | |||
100 | if (msg == NETDEV_CHANGENAME) { | ||
101 | snprintf(name, sizeof(name), "%s-tx", netdev->name); | ||
102 | led_trigger_rename_static(name, priv->tx_led_trig); | ||
103 | |||
104 | snprintf(name, sizeof(name), "%s-rx", netdev->name); | ||
105 | led_trigger_rename_static(name, priv->rx_led_trig); | ||
106 | } | ||
107 | |||
108 | return NOTIFY_DONE; | ||
109 | } | ||
110 | |||
111 | /* notifier block for netdevice event */ | ||
112 | static struct notifier_block can_netdev_notifier __read_mostly = { | ||
113 | .notifier_call = can_led_notifier, | ||
114 | }; | ||
115 | |||
116 | int __init can_led_notifier_init(void) | ||
117 | { | ||
118 | return register_netdevice_notifier(&can_netdev_notifier); | ||
119 | } | ||
120 | |||
121 | void __exit can_led_notifier_exit(void) | ||
122 | { | ||
123 | unregister_netdevice_notifier(&can_netdev_notifier); | ||
124 | } | ||
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 5eaf47b8e37b..f32b9fc6a983 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
@@ -60,6 +60,7 @@ | |||
60 | 60 | ||
61 | #include <linux/can/core.h> | 61 | #include <linux/can/core.h> |
62 | #include <linux/can/dev.h> | 62 | #include <linux/can/dev.h> |
63 | #include <linux/can/led.h> | ||
63 | #include <linux/can/platform/mcp251x.h> | 64 | #include <linux/can/platform/mcp251x.h> |
64 | #include <linux/completion.h> | 65 | #include <linux/completion.h> |
65 | #include <linux/delay.h> | 66 | #include <linux/delay.h> |
@@ -494,6 +495,9 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) | |||
494 | 495 | ||
495 | priv->net->stats.rx_packets++; | 496 | priv->net->stats.rx_packets++; |
496 | priv->net->stats.rx_bytes += frame->can_dlc; | 497 | priv->net->stats.rx_bytes += frame->can_dlc; |
498 | |||
499 | can_led_event(priv->net, CAN_LED_EVENT_RX); | ||
500 | |||
497 | netif_rx_ni(skb); | 501 | netif_rx_ni(skb); |
498 | } | 502 | } |
499 | 503 | ||
@@ -707,6 +711,8 @@ static int mcp251x_stop(struct net_device *net) | |||
707 | 711 | ||
708 | mutex_unlock(&priv->mcp_lock); | 712 | mutex_unlock(&priv->mcp_lock); |
709 | 713 | ||
714 | can_led_event(net, CAN_LED_EVENT_STOP); | ||
715 | |||
710 | return 0; | 716 | return 0; |
711 | } | 717 | } |
712 | 718 | ||
@@ -905,6 +911,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) | |||
905 | if (intf & CANINTF_TX) { | 911 | if (intf & CANINTF_TX) { |
906 | net->stats.tx_packets++; | 912 | net->stats.tx_packets++; |
907 | net->stats.tx_bytes += priv->tx_len - 1; | 913 | net->stats.tx_bytes += priv->tx_len - 1; |
914 | can_led_event(net, CAN_LED_EVENT_TX); | ||
908 | if (priv->tx_len) { | 915 | if (priv->tx_len) { |
909 | can_get_echo_skb(net, 0); | 916 | can_get_echo_skb(net, 0); |
910 | priv->tx_len = 0; | 917 | priv->tx_len = 0; |
@@ -968,6 +975,9 @@ static int mcp251x_open(struct net_device *net) | |||
968 | mcp251x_open_clean(net); | 975 | mcp251x_open_clean(net); |
969 | goto open_unlock; | 976 | goto open_unlock; |
970 | } | 977 | } |
978 | |||
979 | can_led_event(net, CAN_LED_EVENT_OPEN); | ||
980 | |||
971 | netif_wake_queue(net); | 981 | netif_wake_queue(net); |
972 | 982 | ||
973 | open_unlock: | 983 | open_unlock: |
@@ -1077,10 +1087,15 @@ static int mcp251x_can_probe(struct spi_device *spi) | |||
1077 | pdata->transceiver_enable(0); | 1087 | pdata->transceiver_enable(0); |
1078 | 1088 | ||
1079 | ret = register_candev(net); | 1089 | ret = register_candev(net); |
1080 | if (!ret) { | 1090 | if (ret) |
1081 | dev_info(&spi->dev, "probed\n"); | 1091 | goto error_probe; |
1082 | return ret; | 1092 | |
1083 | } | 1093 | devm_can_led_init(net); |
1094 | |||
1095 | dev_info(&spi->dev, "probed\n"); | ||
1096 | |||
1097 | return ret; | ||
1098 | |||
1084 | error_probe: | 1099 | error_probe: |
1085 | if (!mcp251x_enable_dma) | 1100 | if (!mcp251x_enable_dma) |
1086 | kfree(priv->spi_rx_buf); | 1101 | kfree(priv->spi_rx_buf); |
diff --git a/drivers/net/can/mscan/Kconfig b/drivers/net/can/mscan/Kconfig index d38706958af6..f19be5269e7b 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) | 2 | depends on 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/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig index 92f73c708a3d..b39ca5b3ea7f 100644 --- a/drivers/net/can/sja1000/Kconfig +++ b/drivers/net/can/sja1000/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | menuconfig CAN_SJA1000 | 1 | menuconfig CAN_SJA1000 |
2 | tristate "Philips/NXP SJA1000 devices" | 2 | tristate "Philips/NXP SJA1000 devices" |
3 | depends on CAN_DEV && HAS_IOMEM | 3 | depends on HAS_IOMEM |
4 | 4 | ||
5 | if CAN_SJA1000 | 5 | if CAN_SJA1000 |
6 | 6 | ||
@@ -99,11 +99,11 @@ config CAN_TSCAN1 | |||
99 | tristate "TS-CAN1 PC104 boards" | 99 | tristate "TS-CAN1 PC104 boards" |
100 | depends on ISA | 100 | depends on ISA |
101 | help | 101 | help |
102 | This driver is for Technologic Systems' TSCAN-1 PC104 boards. | 102 | This driver is for Technologic Systems' TSCAN-1 PC104 boards. |
103 | http://www.embeddedarm.com/products/board-detail.php?product=TS-CAN1 | 103 | http://www.embeddedarm.com/products/board-detail.php?product=TS-CAN1 |
104 | The driver supports multiple boards and automatically configures them: | 104 | The driver supports multiple boards and automatically configures them: |
105 | PLD IO base addresses are read from jumpers JP1 and JP2, | 105 | PLD IO base addresses are read from jumpers JP1 and JP2, |
106 | IRQ numbers are read from jumpers JP4 and JP5, | 106 | IRQ numbers are read from jumpers JP4 and JP5, |
107 | SJA1000 IO base addresses are chosen heuristically (first that works). | 107 | SJA1000 IO base addresses are chosen heuristically (first that works). |
108 | 108 | ||
109 | endif | 109 | endif |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 83ee11eca0e2..daf4013a8fc7 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -60,6 +60,7 @@ | |||
60 | 60 | ||
61 | #include <linux/can/dev.h> | 61 | #include <linux/can/dev.h> |
62 | #include <linux/can/error.h> | 62 | #include <linux/can/error.h> |
63 | #include <linux/can/led.h> | ||
63 | 64 | ||
64 | #include "sja1000.h" | 65 | #include "sja1000.h" |
65 | 66 | ||
@@ -368,6 +369,8 @@ static void sja1000_rx(struct net_device *dev) | |||
368 | 369 | ||
369 | stats->rx_packets++; | 370 | stats->rx_packets++; |
370 | stats->rx_bytes += cf->can_dlc; | 371 | stats->rx_bytes += cf->can_dlc; |
372 | |||
373 | can_led_event(dev, CAN_LED_EVENT_RX); | ||
371 | } | 374 | } |
372 | 375 | ||
373 | static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) | 376 | static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) |
@@ -521,6 +524,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) | |||
521 | can_get_echo_skb(dev, 0); | 524 | can_get_echo_skb(dev, 0); |
522 | } | 525 | } |
523 | netif_wake_queue(dev); | 526 | netif_wake_queue(dev); |
527 | can_led_event(dev, CAN_LED_EVENT_TX); | ||
524 | } | 528 | } |
525 | if (isrc & IRQ_RI) { | 529 | if (isrc & IRQ_RI) { |
526 | /* receive interrupt */ | 530 | /* receive interrupt */ |
@@ -575,6 +579,8 @@ static int sja1000_open(struct net_device *dev) | |||
575 | /* init and start chi */ | 579 | /* init and start chi */ |
576 | sja1000_start(dev); | 580 | sja1000_start(dev); |
577 | 581 | ||
582 | can_led_event(dev, CAN_LED_EVENT_OPEN); | ||
583 | |||
578 | netif_start_queue(dev); | 584 | netif_start_queue(dev); |
579 | 585 | ||
580 | return 0; | 586 | return 0; |
@@ -592,6 +598,8 @@ static int sja1000_close(struct net_device *dev) | |||
592 | 598 | ||
593 | close_candev(dev); | 599 | close_candev(dev); |
594 | 600 | ||
601 | can_led_event(dev, CAN_LED_EVENT_STOP); | ||
602 | |||
595 | return 0; | 603 | return 0; |
596 | } | 604 | } |
597 | 605 | ||
@@ -639,6 +647,8 @@ static const struct net_device_ops sja1000_netdev_ops = { | |||
639 | 647 | ||
640 | int register_sja1000dev(struct net_device *dev) | 648 | int register_sja1000dev(struct net_device *dev) |
641 | { | 649 | { |
650 | int ret; | ||
651 | |||
642 | if (!sja1000_probe_chip(dev)) | 652 | if (!sja1000_probe_chip(dev)) |
643 | return -ENODEV; | 653 | return -ENODEV; |
644 | 654 | ||
@@ -648,7 +658,12 @@ int register_sja1000dev(struct net_device *dev) | |||
648 | set_reset_mode(dev); | 658 | set_reset_mode(dev); |
649 | chipset_init(dev); | 659 | chipset_init(dev); |
650 | 660 | ||
651 | return register_candev(dev); | 661 | ret = register_candev(dev); |
662 | |||
663 | if (!ret) | ||
664 | devm_can_led_init(dev); | ||
665 | |||
666 | return ret; | ||
652 | } | 667 | } |
653 | EXPORT_SYMBOL_GPL(register_sja1000dev); | 668 | EXPORT_SYMBOL_GPL(register_sja1000dev); |
654 | 669 | ||
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index adc3708d8829..e79a8d10e0fc 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/init.h> | 55 | #include <linux/init.h> |
56 | #include <linux/kernel.h> | 56 | #include <linux/kernel.h> |
57 | #include <linux/can.h> | 57 | #include <linux/can.h> |
58 | #include <linux/can/skb.h> | ||
58 | 59 | ||
59 | static __initconst const char banner[] = | 60 | static __initconst const char banner[] = |
60 | KERN_INFO "slcan: serial line CAN interface driver\n"; | 61 | KERN_INFO "slcan: serial line CAN interface driver\n"; |
@@ -184,7 +185,8 @@ static void slc_bump(struct slcan *sl) | |||
184 | cf.data[i] |= tmp; | 185 | cf.data[i] |= tmp; |
185 | } | 186 | } |
186 | 187 | ||
187 | skb = dev_alloc_skb(sizeof(struct can_frame)); | 188 | skb = dev_alloc_skb(sizeof(struct can_frame) + |
189 | sizeof(struct can_skb_priv)); | ||
188 | if (!skb) | 190 | if (!skb) |
189 | return; | 191 | return; |
190 | 192 | ||
@@ -192,6 +194,10 @@ static void slc_bump(struct slcan *sl) | |||
192 | skb->protocol = htons(ETH_P_CAN); | 194 | skb->protocol = htons(ETH_P_CAN); |
193 | skb->pkt_type = PACKET_BROADCAST; | 195 | skb->pkt_type = PACKET_BROADCAST; |
194 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 196 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
197 | |||
198 | skb_reserve(skb, sizeof(struct can_skb_priv)); | ||
199 | ((struct can_skb_priv *)(skb->head))->ifindex = sl->dev->ifindex; | ||
200 | |||
195 | memcpy(skb_put(skb, sizeof(struct can_frame)), | 201 | memcpy(skb_put(skb, sizeof(struct can_frame)), |
196 | &cf, sizeof(struct can_frame)); | 202 | &cf, sizeof(struct can_frame)); |
197 | netif_rx_ni(skb); | 203 | netif_rx_ni(skb); |
diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig index 5de46a9a77bb..96b6fe158b5b 100644 --- a/drivers/net/can/softing/Kconfig +++ b/drivers/net/can/softing/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config CAN_SOFTING | 1 | config CAN_SOFTING |
2 | tristate "Softing Gmbh CAN generic support" | 2 | tristate "Softing Gmbh CAN generic support" |
3 | depends on CAN_DEV && HAS_IOMEM | 3 | depends on HAS_IOMEM |
4 | ---help--- | 4 | ---help--- |
5 | Support for CAN cards from Softing Gmbh & some cards | 5 | Support for CAN cards from Softing Gmbh & some cards |
6 | from Vector Gmbh. | 6 | from Vector Gmbh. |
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index f898c6363729..f52a9755fb3e 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
@@ -50,6 +50,7 @@ | |||
50 | 50 | ||
51 | #include <linux/can/dev.h> | 51 | #include <linux/can/dev.h> |
52 | #include <linux/can/error.h> | 52 | #include <linux/can/error.h> |
53 | #include <linux/can/led.h> | ||
53 | #include <linux/can/platform/ti_hecc.h> | 54 | #include <linux/can/platform/ti_hecc.h> |
54 | 55 | ||
55 | #define DRV_NAME "ti_hecc" | 56 | #define DRV_NAME "ti_hecc" |
@@ -593,6 +594,7 @@ static int ti_hecc_rx_pkt(struct ti_hecc_priv *priv, int mbxno) | |||
593 | spin_unlock_irqrestore(&priv->mbx_lock, flags); | 594 | spin_unlock_irqrestore(&priv->mbx_lock, flags); |
594 | 595 | ||
595 | stats->rx_bytes += cf->can_dlc; | 596 | stats->rx_bytes += cf->can_dlc; |
597 | can_led_event(priv->ndev, CAN_LED_EVENT_RX); | ||
596 | netif_receive_skb(skb); | 598 | netif_receive_skb(skb); |
597 | stats->rx_packets++; | 599 | stats->rx_packets++; |
598 | 600 | ||
@@ -796,6 +798,7 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id) | |||
796 | stats->tx_bytes += hecc_read_mbx(priv, mbxno, | 798 | stats->tx_bytes += hecc_read_mbx(priv, mbxno, |
797 | HECC_CANMCF) & 0xF; | 799 | HECC_CANMCF) & 0xF; |
798 | stats->tx_packets++; | 800 | stats->tx_packets++; |
801 | can_led_event(ndev, CAN_LED_EVENT_TX); | ||
799 | can_get_echo_skb(ndev, mbxno); | 802 | can_get_echo_skb(ndev, mbxno); |
800 | --priv->tx_tail; | 803 | --priv->tx_tail; |
801 | } | 804 | } |
@@ -851,6 +854,8 @@ static int ti_hecc_open(struct net_device *ndev) | |||
851 | return err; | 854 | return err; |
852 | } | 855 | } |
853 | 856 | ||
857 | can_led_event(ndev, CAN_LED_EVENT_OPEN); | ||
858 | |||
854 | ti_hecc_start(ndev); | 859 | ti_hecc_start(ndev); |
855 | napi_enable(&priv->napi); | 860 | napi_enable(&priv->napi); |
856 | netif_start_queue(ndev); | 861 | netif_start_queue(ndev); |
@@ -869,6 +874,8 @@ static int ti_hecc_close(struct net_device *ndev) | |||
869 | close_candev(ndev); | 874 | close_candev(ndev); |
870 | ti_hecc_transceiver_switch(priv, 0); | 875 | ti_hecc_transceiver_switch(priv, 0); |
871 | 876 | ||
877 | can_led_event(ndev, CAN_LED_EVENT_STOP); | ||
878 | |||
872 | return 0; | 879 | return 0; |
873 | } | 880 | } |
874 | 881 | ||
@@ -961,6 +968,9 @@ static int ti_hecc_probe(struct platform_device *pdev) | |||
961 | dev_err(&pdev->dev, "register_candev() failed\n"); | 968 | dev_err(&pdev->dev, "register_candev() failed\n"); |
962 | goto probe_exit_clk; | 969 | goto probe_exit_clk; |
963 | } | 970 | } |
971 | |||
972 | devm_can_led_init(ndev); | ||
973 | |||
964 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%u)\n", | 974 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%u)\n", |
965 | priv->base, (u32) ndev->irq); | 975 | priv->base, (u32) ndev->irq); |
966 | 976 | ||
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig index a4e4bee35710..fc96a3d83ebe 100644 --- a/drivers/net/can/usb/Kconfig +++ b/drivers/net/can/usb/Kconfig | |||
@@ -1,5 +1,5 @@ | |||
1 | menu "CAN USB interfaces" | 1 | menu "CAN USB interfaces" |
2 | depends on USB && CAN_DEV | 2 | depends on USB |
3 | 3 | ||
4 | config CAN_EMS_USB | 4 | config CAN_EMS_USB |
5 | tristate "EMS CPC-USB/ARM7 CAN/USB interface" | 5 | tristate "EMS CPC-USB/ARM7 CAN/USB interface" |
@@ -48,4 +48,10 @@ config CAN_PEAK_USB | |||
48 | This driver supports the PCAN-USB and PCAN-USB Pro adapters | 48 | This driver supports the PCAN-USB and PCAN-USB Pro adapters |
49 | from PEAK-System Technik (http://www.peak-system.com). | 49 | from PEAK-System Technik (http://www.peak-system.com). |
50 | 50 | ||
51 | config CAN_8DEV_USB | ||
52 | tristate "8 devices USB2CAN interface" | ||
53 | ---help--- | ||
54 | This driver supports the USB2CAN interface | ||
55 | from 8 devices (http://www.8devices.com). | ||
56 | |||
51 | endmenu | 57 | endmenu |
diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile index 80a2ee41fd61..becef460a91a 100644 --- a/drivers/net/can/usb/Makefile +++ b/drivers/net/can/usb/Makefile | |||
@@ -6,5 +6,6 @@ obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o | |||
6 | obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o | 6 | obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o |
7 | obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o | 7 | obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o |
8 | obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/ | 8 | obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/ |
9 | obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o | ||
9 | 10 | ||
10 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG | 11 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG |
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c new file mode 100644 index 000000000000..f789e6f54a55 --- /dev/null +++ b/drivers/net/can/usb/usb_8dev.c | |||
@@ -0,0 +1,1033 @@ | |||
1 | /* | ||
2 | * CAN driver for "8 devices" USB2CAN converter | ||
3 | * | ||
4 | * Copyright (C) 2012 Bernd Krumboeck (krumboeck@universalnet.at) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published | ||
8 | * by the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program. | ||
17 | * | ||
18 | * This driver is inspired by the 3.2.0 version of drivers/net/can/usb/ems_usb.c | ||
19 | * and drivers/net/can/usb/esd_usb2.c | ||
20 | * | ||
21 | * Many thanks to Gerhard Bertelsmann (info@gerhard-bertelsmann.de) | ||
22 | * for testing and fixing this driver. Also many thanks to "8 devices", | ||
23 | * who were very cooperative and answered my questions. | ||
24 | */ | ||
25 | |||
26 | #include <linux/init.h> | ||
27 | #include <linux/signal.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/netdevice.h> | ||
31 | #include <linux/usb.h> | ||
32 | |||
33 | #include <linux/can.h> | ||
34 | #include <linux/can/dev.h> | ||
35 | #include <linux/can/error.h> | ||
36 | #include <linux/can/led.h> | ||
37 | |||
38 | /* driver constants */ | ||
39 | #define MAX_RX_URBS 20 | ||
40 | #define MAX_TX_URBS 20 | ||
41 | #define RX_BUFFER_SIZE 64 | ||
42 | |||
43 | /* vendor and product id */ | ||
44 | #define USB_8DEV_VENDOR_ID 0x0483 | ||
45 | #define USB_8DEV_PRODUCT_ID 0x1234 | ||
46 | |||
47 | /* endpoints */ | ||
48 | enum usb_8dev_endpoint { | ||
49 | USB_8DEV_ENDP_DATA_RX = 1, | ||
50 | USB_8DEV_ENDP_DATA_TX, | ||
51 | USB_8DEV_ENDP_CMD_RX, | ||
52 | USB_8DEV_ENDP_CMD_TX | ||
53 | }; | ||
54 | |||
55 | /* device CAN clock */ | ||
56 | #define USB_8DEV_ABP_CLOCK 32000000 | ||
57 | |||
58 | /* setup flags */ | ||
59 | #define USB_8DEV_SILENT 0x01 | ||
60 | #define USB_8DEV_LOOPBACK 0x02 | ||
61 | #define USB_8DEV_DISABLE_AUTO_RESTRANS 0x04 | ||
62 | #define USB_8DEV_STATUS_FRAME 0x08 | ||
63 | |||
64 | /* commands */ | ||
65 | enum usb_8dev_cmd { | ||
66 | USB_8DEV_RESET = 1, | ||
67 | USB_8DEV_OPEN, | ||
68 | USB_8DEV_CLOSE, | ||
69 | USB_8DEV_SET_SPEED, | ||
70 | USB_8DEV_SET_MASK_FILTER, | ||
71 | USB_8DEV_GET_STATUS, | ||
72 | USB_8DEV_GET_STATISTICS, | ||
73 | USB_8DEV_GET_SERIAL, | ||
74 | USB_8DEV_GET_SOFTW_VER, | ||
75 | USB_8DEV_GET_HARDW_VER, | ||
76 | USB_8DEV_RESET_TIMESTAMP, | ||
77 | USB_8DEV_GET_SOFTW_HARDW_VER | ||
78 | }; | ||
79 | |||
80 | /* command options */ | ||
81 | #define USB_8DEV_BAUD_MANUAL 0x09 | ||
82 | #define USB_8DEV_CMD_START 0x11 | ||
83 | #define USB_8DEV_CMD_END 0x22 | ||
84 | |||
85 | #define USB_8DEV_CMD_SUCCESS 0 | ||
86 | #define USB_8DEV_CMD_ERROR 255 | ||
87 | |||
88 | #define USB_8DEV_CMD_TIMEOUT 1000 | ||
89 | |||
90 | /* frames */ | ||
91 | #define USB_8DEV_DATA_START 0x55 | ||
92 | #define USB_8DEV_DATA_END 0xAA | ||
93 | |||
94 | #define USB_8DEV_TYPE_CAN_FRAME 0 | ||
95 | #define USB_8DEV_TYPE_ERROR_FRAME 3 | ||
96 | |||
97 | #define USB_8DEV_EXTID 0x01 | ||
98 | #define USB_8DEV_RTR 0x02 | ||
99 | #define USB_8DEV_ERR_FLAG 0x04 | ||
100 | |||
101 | /* status */ | ||
102 | #define USB_8DEV_STATUSMSG_OK 0x00 /* Normal condition. */ | ||
103 | #define USB_8DEV_STATUSMSG_OVERRUN 0x01 /* Overrun occured when sending */ | ||
104 | #define USB_8DEV_STATUSMSG_BUSLIGHT 0x02 /* Error counter has reached 96 */ | ||
105 | #define USB_8DEV_STATUSMSG_BUSHEAVY 0x03 /* Error count. has reached 128 */ | ||
106 | #define USB_8DEV_STATUSMSG_BUSOFF 0x04 /* Device is in BUSOFF */ | ||
107 | #define USB_8DEV_STATUSMSG_STUFF 0x20 /* Stuff Error */ | ||
108 | #define USB_8DEV_STATUSMSG_FORM 0x21 /* Form Error */ | ||
109 | #define USB_8DEV_STATUSMSG_ACK 0x23 /* Ack Error */ | ||
110 | #define USB_8DEV_STATUSMSG_BIT0 0x24 /* Bit1 Error */ | ||
111 | #define USB_8DEV_STATUSMSG_BIT1 0x25 /* Bit0 Error */ | ||
112 | #define USB_8DEV_STATUSMSG_CRC 0x27 /* CRC Error */ | ||
113 | |||
114 | #define USB_8DEV_RP_MASK 0x7F /* Mask for Receive Error Bit */ | ||
115 | |||
116 | |||
117 | /* table of devices that work with this driver */ | ||
118 | static const struct usb_device_id usb_8dev_table[] = { | ||
119 | { USB_DEVICE(USB_8DEV_VENDOR_ID, USB_8DEV_PRODUCT_ID) }, | ||
120 | { } /* Terminating entry */ | ||
121 | }; | ||
122 | |||
123 | MODULE_DEVICE_TABLE(usb, usb_8dev_table); | ||
124 | |||
125 | struct usb_8dev_tx_urb_context { | ||
126 | struct usb_8dev_priv *priv; | ||
127 | |||
128 | u32 echo_index; | ||
129 | u8 dlc; | ||
130 | }; | ||
131 | |||
132 | /* Structure to hold all of our device specific stuff */ | ||
133 | struct usb_8dev_priv { | ||
134 | struct can_priv can; /* must be the first member */ | ||
135 | |||
136 | struct sk_buff *echo_skb[MAX_TX_URBS]; | ||
137 | |||
138 | struct usb_device *udev; | ||
139 | struct net_device *netdev; | ||
140 | |||
141 | atomic_t active_tx_urbs; | ||
142 | struct usb_anchor tx_submitted; | ||
143 | struct usb_8dev_tx_urb_context tx_contexts[MAX_TX_URBS]; | ||
144 | |||
145 | struct usb_anchor rx_submitted; | ||
146 | |||
147 | struct can_berr_counter bec; | ||
148 | |||
149 | u8 *cmd_msg_buffer; | ||
150 | |||
151 | struct mutex usb_8dev_cmd_lock; | ||
152 | |||
153 | }; | ||
154 | |||
155 | /* tx frame */ | ||
156 | struct __packed usb_8dev_tx_msg { | ||
157 | u8 begin; | ||
158 | u8 flags; /* RTR and EXT_ID flag */ | ||
159 | __be32 id; /* upper 3 bits not used */ | ||
160 | u8 dlc; /* data length code 0-8 bytes */ | ||
161 | u8 data[8]; /* 64-bit data */ | ||
162 | u8 end; | ||
163 | }; | ||
164 | |||
165 | /* rx frame */ | ||
166 | struct __packed usb_8dev_rx_msg { | ||
167 | u8 begin; | ||
168 | u8 type; /* frame type */ | ||
169 | u8 flags; /* RTR and EXT_ID flag */ | ||
170 | __be32 id; /* upper 3 bits not used */ | ||
171 | u8 dlc; /* data length code 0-8 bytes */ | ||
172 | u8 data[8]; /* 64-bit data */ | ||
173 | __be32 timestamp; /* 32-bit timestamp */ | ||
174 | u8 end; | ||
175 | }; | ||
176 | |||
177 | /* command frame */ | ||
178 | struct __packed usb_8dev_cmd_msg { | ||
179 | u8 begin; | ||
180 | u8 channel; /* unkown - always 0 */ | ||
181 | u8 command; /* command to execute */ | ||
182 | u8 opt1; /* optional parameter / return value */ | ||
183 | u8 opt2; /* optional parameter 2 */ | ||
184 | u8 data[10]; /* optional parameter and data */ | ||
185 | u8 end; | ||
186 | }; | ||
187 | |||
188 | static int usb_8dev_send_cmd_msg(struct usb_8dev_priv *priv, u8 *msg, int size) | ||
189 | { | ||
190 | int actual_length; | ||
191 | |||
192 | return usb_bulk_msg(priv->udev, | ||
193 | usb_sndbulkpipe(priv->udev, USB_8DEV_ENDP_CMD_TX), | ||
194 | msg, size, &actual_length, USB_8DEV_CMD_TIMEOUT); | ||
195 | } | ||
196 | |||
197 | static int usb_8dev_wait_cmd_msg(struct usb_8dev_priv *priv, u8 *msg, int size, | ||
198 | int *actual_length) | ||
199 | { | ||
200 | return usb_bulk_msg(priv->udev, | ||
201 | usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_CMD_RX), | ||
202 | msg, size, actual_length, USB_8DEV_CMD_TIMEOUT); | ||
203 | } | ||
204 | |||
205 | /* Send command to device and receive result. | ||
206 | * Command was successful when opt1 = 0. | ||
207 | */ | ||
208 | static int usb_8dev_send_cmd(struct usb_8dev_priv *priv, | ||
209 | struct usb_8dev_cmd_msg *out, | ||
210 | struct usb_8dev_cmd_msg *in) | ||
211 | { | ||
212 | int err; | ||
213 | int num_bytes_read; | ||
214 | struct net_device *netdev; | ||
215 | |||
216 | netdev = priv->netdev; | ||
217 | |||
218 | out->begin = USB_8DEV_CMD_START; | ||
219 | out->end = USB_8DEV_CMD_END; | ||
220 | |||
221 | mutex_lock(&priv->usb_8dev_cmd_lock); | ||
222 | |||
223 | memcpy(priv->cmd_msg_buffer, out, | ||
224 | sizeof(struct usb_8dev_cmd_msg)); | ||
225 | |||
226 | err = usb_8dev_send_cmd_msg(priv, priv->cmd_msg_buffer, | ||
227 | sizeof(struct usb_8dev_cmd_msg)); | ||
228 | if (err < 0) { | ||
229 | netdev_err(netdev, "sending command message failed\n"); | ||
230 | goto failed; | ||
231 | } | ||
232 | |||
233 | err = usb_8dev_wait_cmd_msg(priv, priv->cmd_msg_buffer, | ||
234 | sizeof(struct usb_8dev_cmd_msg), | ||
235 | &num_bytes_read); | ||
236 | if (err < 0) { | ||
237 | netdev_err(netdev, "no command message answer\n"); | ||
238 | goto failed; | ||
239 | } | ||
240 | |||
241 | memcpy(in, priv->cmd_msg_buffer, sizeof(struct usb_8dev_cmd_msg)); | ||
242 | |||
243 | if (in->begin != USB_8DEV_CMD_START || in->end != USB_8DEV_CMD_END || | ||
244 | num_bytes_read != 16 || in->opt1 != 0) | ||
245 | err = -EPROTO; | ||
246 | |||
247 | failed: | ||
248 | mutex_unlock(&priv->usb_8dev_cmd_lock); | ||
249 | return err; | ||
250 | } | ||
251 | |||
252 | /* Send open command to device */ | ||
253 | static int usb_8dev_cmd_open(struct usb_8dev_priv *priv) | ||
254 | { | ||
255 | struct can_bittiming *bt = &priv->can.bittiming; | ||
256 | struct usb_8dev_cmd_msg outmsg; | ||
257 | struct usb_8dev_cmd_msg inmsg; | ||
258 | u32 ctrlmode = priv->can.ctrlmode; | ||
259 | u32 flags = USB_8DEV_STATUS_FRAME; | ||
260 | __be32 beflags; | ||
261 | __be16 bebrp; | ||
262 | |||
263 | memset(&outmsg, 0, sizeof(outmsg)); | ||
264 | outmsg.command = USB_8DEV_OPEN; | ||
265 | outmsg.opt1 = USB_8DEV_BAUD_MANUAL; | ||
266 | outmsg.data[0] = bt->prop_seg + bt->phase_seg1; | ||
267 | outmsg.data[1] = bt->phase_seg2; | ||
268 | outmsg.data[2] = bt->sjw; | ||
269 | |||
270 | /* BRP */ | ||
271 | bebrp = cpu_to_be16((u16)bt->brp); | ||
272 | memcpy(&outmsg.data[3], &bebrp, sizeof(bebrp)); | ||
273 | |||
274 | /* flags */ | ||
275 | if (ctrlmode & CAN_CTRLMODE_LOOPBACK) | ||
276 | flags |= USB_8DEV_LOOPBACK; | ||
277 | if (ctrlmode & CAN_CTRLMODE_LISTENONLY) | ||
278 | flags |= USB_8DEV_SILENT; | ||
279 | if (ctrlmode & CAN_CTRLMODE_ONE_SHOT) | ||
280 | flags |= USB_8DEV_DISABLE_AUTO_RESTRANS; | ||
281 | |||
282 | beflags = cpu_to_be32(flags); | ||
283 | memcpy(&outmsg.data[5], &beflags, sizeof(beflags)); | ||
284 | |||
285 | return usb_8dev_send_cmd(priv, &outmsg, &inmsg); | ||
286 | } | ||
287 | |||
288 | /* Send close command to device */ | ||
289 | static int usb_8dev_cmd_close(struct usb_8dev_priv *priv) | ||
290 | { | ||
291 | struct usb_8dev_cmd_msg inmsg; | ||
292 | struct usb_8dev_cmd_msg outmsg = { | ||
293 | .channel = 0, | ||
294 | .command = USB_8DEV_CLOSE, | ||
295 | .opt1 = 0, | ||
296 | .opt2 = 0 | ||
297 | }; | ||
298 | |||
299 | return usb_8dev_send_cmd(priv, &outmsg, &inmsg); | ||
300 | } | ||
301 | |||
302 | /* Get firmware and hardware version */ | ||
303 | static int usb_8dev_cmd_version(struct usb_8dev_priv *priv, u32 *res) | ||
304 | { | ||
305 | struct usb_8dev_cmd_msg inmsg; | ||
306 | struct usb_8dev_cmd_msg outmsg = { | ||
307 | .channel = 0, | ||
308 | .command = USB_8DEV_GET_SOFTW_HARDW_VER, | ||
309 | .opt1 = 0, | ||
310 | .opt2 = 0 | ||
311 | }; | ||
312 | |||
313 | int err = usb_8dev_send_cmd(priv, &outmsg, &inmsg); | ||
314 | if (err) | ||
315 | return err; | ||
316 | |||
317 | *res = be32_to_cpup((__be32 *)inmsg.data); | ||
318 | |||
319 | return err; | ||
320 | } | ||
321 | |||
322 | /* Set network device mode | ||
323 | * | ||
324 | * Maybe we should leave this function empty, because the device | ||
325 | * set mode variable with open command. | ||
326 | */ | ||
327 | static int usb_8dev_set_mode(struct net_device *netdev, enum can_mode mode) | ||
328 | { | ||
329 | struct usb_8dev_priv *priv = netdev_priv(netdev); | ||
330 | int err = 0; | ||
331 | |||
332 | switch (mode) { | ||
333 | case CAN_MODE_START: | ||
334 | err = usb_8dev_cmd_open(priv); | ||
335 | if (err) | ||
336 | netdev_warn(netdev, "couldn't start device"); | ||
337 | break; | ||
338 | |||
339 | default: | ||
340 | return -EOPNOTSUPP; | ||
341 | } | ||
342 | |||
343 | return err; | ||
344 | } | ||
345 | |||
346 | /* Read error/status frames */ | ||
347 | static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv, | ||
348 | struct usb_8dev_rx_msg *msg) | ||
349 | { | ||
350 | struct can_frame *cf; | ||
351 | struct sk_buff *skb; | ||
352 | struct net_device_stats *stats = &priv->netdev->stats; | ||
353 | |||
354 | /* Error message: | ||
355 | * byte 0: Status | ||
356 | * byte 1: bit 7: Receive Passive | ||
357 | * byte 1: bit 0-6: Receive Error Counter | ||
358 | * byte 2: Transmit Error Counter | ||
359 | * byte 3: Always 0 (maybe reserved for future use) | ||
360 | */ | ||
361 | |||
362 | u8 state = msg->data[0]; | ||
363 | u8 rxerr = msg->data[1] & USB_8DEV_RP_MASK; | ||
364 | u8 txerr = msg->data[2]; | ||
365 | int rx_errors = 0; | ||
366 | int tx_errors = 0; | ||
367 | |||
368 | skb = alloc_can_err_skb(priv->netdev, &cf); | ||
369 | if (!skb) | ||
370 | return; | ||
371 | |||
372 | switch (state) { | ||
373 | case USB_8DEV_STATUSMSG_OK: | ||
374 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
375 | cf->can_id |= CAN_ERR_PROT; | ||
376 | cf->data[2] = CAN_ERR_PROT_ACTIVE; | ||
377 | break; | ||
378 | case USB_8DEV_STATUSMSG_BUSOFF: | ||
379 | priv->can.state = CAN_STATE_BUS_OFF; | ||
380 | cf->can_id |= CAN_ERR_BUSOFF; | ||
381 | can_bus_off(priv->netdev); | ||
382 | break; | ||
383 | case USB_8DEV_STATUSMSG_OVERRUN: | ||
384 | case USB_8DEV_STATUSMSG_BUSLIGHT: | ||
385 | case USB_8DEV_STATUSMSG_BUSHEAVY: | ||
386 | cf->can_id |= CAN_ERR_CRTL; | ||
387 | break; | ||
388 | default: | ||
389 | priv->can.state = CAN_STATE_ERROR_WARNING; | ||
390 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | ||
391 | priv->can.can_stats.bus_error++; | ||
392 | break; | ||
393 | } | ||
394 | |||
395 | switch (state) { | ||
396 | case USB_8DEV_STATUSMSG_OK: | ||
397 | case USB_8DEV_STATUSMSG_BUSOFF: | ||
398 | break; | ||
399 | case USB_8DEV_STATUSMSG_ACK: | ||
400 | cf->can_id |= CAN_ERR_ACK; | ||
401 | tx_errors = 1; | ||
402 | break; | ||
403 | case USB_8DEV_STATUSMSG_CRC: | ||
404 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
405 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | | ||
406 | CAN_ERR_PROT_LOC_CRC_DEL; | ||
407 | rx_errors = 1; | ||
408 | break; | ||
409 | case USB_8DEV_STATUSMSG_BIT0: | ||
410 | cf->data[2] |= CAN_ERR_PROT_BIT0; | ||
411 | tx_errors = 1; | ||
412 | break; | ||
413 | case USB_8DEV_STATUSMSG_BIT1: | ||
414 | cf->data[2] |= CAN_ERR_PROT_BIT1; | ||
415 | tx_errors = 1; | ||
416 | break; | ||
417 | case USB_8DEV_STATUSMSG_FORM: | ||
418 | cf->data[2] |= CAN_ERR_PROT_FORM; | ||
419 | rx_errors = 1; | ||
420 | break; | ||
421 | case USB_8DEV_STATUSMSG_STUFF: | ||
422 | cf->data[2] |= CAN_ERR_PROT_STUFF; | ||
423 | rx_errors = 1; | ||
424 | break; | ||
425 | case USB_8DEV_STATUSMSG_OVERRUN: | ||
426 | cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | ||
427 | stats->rx_over_errors++; | ||
428 | rx_errors = 1; | ||
429 | break; | ||
430 | case USB_8DEV_STATUSMSG_BUSLIGHT: | ||
431 | priv->can.state = CAN_STATE_ERROR_WARNING; | ||
432 | cf->data[1] = (txerr > rxerr) ? | ||
433 | CAN_ERR_CRTL_TX_WARNING : | ||
434 | CAN_ERR_CRTL_RX_WARNING; | ||
435 | priv->can.can_stats.error_warning++; | ||
436 | break; | ||
437 | case USB_8DEV_STATUSMSG_BUSHEAVY: | ||
438 | priv->can.state = CAN_STATE_ERROR_PASSIVE; | ||
439 | cf->data[1] = (txerr > rxerr) ? | ||
440 | CAN_ERR_CRTL_TX_PASSIVE : | ||
441 | CAN_ERR_CRTL_RX_PASSIVE; | ||
442 | priv->can.can_stats.error_passive++; | ||
443 | break; | ||
444 | default: | ||
445 | netdev_warn(priv->netdev, | ||
446 | "Unknown status/error message (%d)\n", state); | ||
447 | break; | ||
448 | } | ||
449 | |||
450 | if (tx_errors) { | ||
451 | cf->data[2] |= CAN_ERR_PROT_TX; | ||
452 | stats->tx_errors++; | ||
453 | } | ||
454 | |||
455 | if (rx_errors) | ||
456 | stats->rx_errors++; | ||
457 | |||
458 | cf->data[6] = txerr; | ||
459 | cf->data[7] = rxerr; | ||
460 | |||
461 | priv->bec.txerr = txerr; | ||
462 | priv->bec.rxerr = rxerr; | ||
463 | |||
464 | netif_rx(skb); | ||
465 | |||
466 | stats->rx_packets++; | ||
467 | stats->rx_bytes += cf->can_dlc; | ||
468 | } | ||
469 | |||
470 | /* Read data and status frames */ | ||
471 | static void usb_8dev_rx_can_msg(struct usb_8dev_priv *priv, | ||
472 | struct usb_8dev_rx_msg *msg) | ||
473 | { | ||
474 | struct can_frame *cf; | ||
475 | struct sk_buff *skb; | ||
476 | struct net_device_stats *stats = &priv->netdev->stats; | ||
477 | |||
478 | if (msg->type == USB_8DEV_TYPE_ERROR_FRAME && | ||
479 | msg->flags == USB_8DEV_ERR_FLAG) { | ||
480 | usb_8dev_rx_err_msg(priv, msg); | ||
481 | } else if (msg->type == USB_8DEV_TYPE_CAN_FRAME) { | ||
482 | skb = alloc_can_skb(priv->netdev, &cf); | ||
483 | if (!skb) | ||
484 | return; | ||
485 | |||
486 | cf->can_id = be32_to_cpu(msg->id); | ||
487 | cf->can_dlc = get_can_dlc(msg->dlc & 0xF); | ||
488 | |||
489 | if (msg->flags & USB_8DEV_EXTID) | ||
490 | cf->can_id |= CAN_EFF_FLAG; | ||
491 | |||
492 | if (msg->flags & USB_8DEV_RTR) | ||
493 | cf->can_id |= CAN_RTR_FLAG; | ||
494 | else | ||
495 | memcpy(cf->data, msg->data, cf->can_dlc); | ||
496 | |||
497 | netif_rx(skb); | ||
498 | |||
499 | stats->rx_packets++; | ||
500 | stats->rx_bytes += cf->can_dlc; | ||
501 | |||
502 | can_led_event(priv->netdev, CAN_LED_EVENT_RX); | ||
503 | } else { | ||
504 | netdev_warn(priv->netdev, "frame type %d unknown", | ||
505 | msg->type); | ||
506 | } | ||
507 | |||
508 | } | ||
509 | |||
510 | /* Callback for reading data from device | ||
511 | * | ||
512 | * Check urb status, call read function and resubmit urb read operation. | ||
513 | */ | ||
514 | static void usb_8dev_read_bulk_callback(struct urb *urb) | ||
515 | { | ||
516 | struct usb_8dev_priv *priv = urb->context; | ||
517 | struct net_device *netdev; | ||
518 | int retval; | ||
519 | int pos = 0; | ||
520 | |||
521 | netdev = priv->netdev; | ||
522 | |||
523 | if (!netif_device_present(netdev)) | ||
524 | return; | ||
525 | |||
526 | switch (urb->status) { | ||
527 | case 0: /* success */ | ||
528 | break; | ||
529 | |||
530 | case -ENOENT: | ||
531 | case -ESHUTDOWN: | ||
532 | return; | ||
533 | |||
534 | default: | ||
535 | netdev_info(netdev, "Rx URB aborted (%d)\n", | ||
536 | urb->status); | ||
537 | goto resubmit_urb; | ||
538 | } | ||
539 | |||
540 | while (pos < urb->actual_length) { | ||
541 | struct usb_8dev_rx_msg *msg; | ||
542 | |||
543 | if (pos + sizeof(struct usb_8dev_rx_msg) > urb->actual_length) { | ||
544 | netdev_err(priv->netdev, "format error\n"); | ||
545 | break; | ||
546 | } | ||
547 | |||
548 | msg = (struct usb_8dev_rx_msg *)(urb->transfer_buffer + pos); | ||
549 | usb_8dev_rx_can_msg(priv, msg); | ||
550 | |||
551 | pos += sizeof(struct usb_8dev_rx_msg); | ||
552 | } | ||
553 | |||
554 | resubmit_urb: | ||
555 | usb_fill_bulk_urb(urb, priv->udev, | ||
556 | usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_RX), | ||
557 | urb->transfer_buffer, RX_BUFFER_SIZE, | ||
558 | usb_8dev_read_bulk_callback, priv); | ||
559 | |||
560 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
561 | |||
562 | if (retval == -ENODEV) | ||
563 | netif_device_detach(netdev); | ||
564 | else if (retval) | ||
565 | netdev_err(netdev, | ||
566 | "failed resubmitting read bulk urb: %d\n", retval); | ||
567 | } | ||
568 | |||
569 | /* Callback handler for write operations | ||
570 | * | ||
571 | * Free allocated buffers, check transmit status and | ||
572 | * calculate statistic. | ||
573 | */ | ||
574 | static void usb_8dev_write_bulk_callback(struct urb *urb) | ||
575 | { | ||
576 | struct usb_8dev_tx_urb_context *context = urb->context; | ||
577 | struct usb_8dev_priv *priv; | ||
578 | struct net_device *netdev; | ||
579 | |||
580 | BUG_ON(!context); | ||
581 | |||
582 | priv = context->priv; | ||
583 | netdev = priv->netdev; | ||
584 | |||
585 | /* free up our allocated buffer */ | ||
586 | usb_free_coherent(urb->dev, urb->transfer_buffer_length, | ||
587 | urb->transfer_buffer, urb->transfer_dma); | ||
588 | |||
589 | atomic_dec(&priv->active_tx_urbs); | ||
590 | |||
591 | if (!netif_device_present(netdev)) | ||
592 | return; | ||
593 | |||
594 | if (urb->status) | ||
595 | netdev_info(netdev, "Tx URB aborted (%d)\n", | ||
596 | urb->status); | ||
597 | |||
598 | netdev->stats.tx_packets++; | ||
599 | netdev->stats.tx_bytes += context->dlc; | ||
600 | |||
601 | can_get_echo_skb(netdev, context->echo_index); | ||
602 | |||
603 | can_led_event(netdev, CAN_LED_EVENT_TX); | ||
604 | |||
605 | /* Release context */ | ||
606 | context->echo_index = MAX_TX_URBS; | ||
607 | |||
608 | netif_wake_queue(netdev); | ||
609 | } | ||
610 | |||
611 | /* Send data to device */ | ||
612 | static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb, | ||
613 | struct net_device *netdev) | ||
614 | { | ||
615 | struct usb_8dev_priv *priv = netdev_priv(netdev); | ||
616 | struct net_device_stats *stats = &netdev->stats; | ||
617 | struct can_frame *cf = (struct can_frame *) skb->data; | ||
618 | struct usb_8dev_tx_msg *msg; | ||
619 | struct urb *urb; | ||
620 | struct usb_8dev_tx_urb_context *context = NULL; | ||
621 | u8 *buf; | ||
622 | int i, err; | ||
623 | size_t size = sizeof(struct usb_8dev_tx_msg); | ||
624 | |||
625 | if (can_dropped_invalid_skb(netdev, skb)) | ||
626 | return NETDEV_TX_OK; | ||
627 | |||
628 | /* create a URB, and a buffer for it, and copy the data to the URB */ | ||
629 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
630 | if (!urb) { | ||
631 | netdev_err(netdev, "No memory left for URBs\n"); | ||
632 | goto nomem; | ||
633 | } | ||
634 | |||
635 | buf = usb_alloc_coherent(priv->udev, size, GFP_ATOMIC, | ||
636 | &urb->transfer_dma); | ||
637 | if (!buf) { | ||
638 | netdev_err(netdev, "No memory left for USB buffer\n"); | ||
639 | goto nomembuf; | ||
640 | } | ||
641 | |||
642 | memset(buf, 0, size); | ||
643 | |||
644 | msg = (struct usb_8dev_tx_msg *)buf; | ||
645 | msg->begin = USB_8DEV_DATA_START; | ||
646 | msg->flags = 0x00; | ||
647 | |||
648 | if (cf->can_id & CAN_RTR_FLAG) | ||
649 | msg->flags |= USB_8DEV_RTR; | ||
650 | |||
651 | if (cf->can_id & CAN_EFF_FLAG) | ||
652 | msg->flags |= USB_8DEV_EXTID; | ||
653 | |||
654 | msg->id = cpu_to_be32(cf->can_id & CAN_ERR_MASK); | ||
655 | msg->dlc = cf->can_dlc; | ||
656 | memcpy(msg->data, cf->data, cf->can_dlc); | ||
657 | msg->end = USB_8DEV_DATA_END; | ||
658 | |||
659 | for (i = 0; i < MAX_TX_URBS; i++) { | ||
660 | if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { | ||
661 | context = &priv->tx_contexts[i]; | ||
662 | break; | ||
663 | } | ||
664 | } | ||
665 | |||
666 | /* May never happen! When this happens we'd more URBs in flight as | ||
667 | * allowed (MAX_TX_URBS). | ||
668 | */ | ||
669 | if (!context) | ||
670 | goto nofreecontext; | ||
671 | |||
672 | context->priv = priv; | ||
673 | context->echo_index = i; | ||
674 | context->dlc = cf->can_dlc; | ||
675 | |||
676 | usb_fill_bulk_urb(urb, priv->udev, | ||
677 | usb_sndbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_TX), | ||
678 | buf, size, usb_8dev_write_bulk_callback, context); | ||
679 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
680 | usb_anchor_urb(urb, &priv->tx_submitted); | ||
681 | |||
682 | can_put_echo_skb(skb, netdev, context->echo_index); | ||
683 | |||
684 | atomic_inc(&priv->active_tx_urbs); | ||
685 | |||
686 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
687 | if (unlikely(err)) | ||
688 | goto failed; | ||
689 | else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS) | ||
690 | /* Slow down tx path */ | ||
691 | netif_stop_queue(netdev); | ||
692 | |||
693 | /* Release our reference to this URB, the USB core will eventually free | ||
694 | * it entirely. | ||
695 | */ | ||
696 | usb_free_urb(urb); | ||
697 | |||
698 | return NETDEV_TX_OK; | ||
699 | |||
700 | nofreecontext: | ||
701 | usb_unanchor_urb(urb); | ||
702 | usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); | ||
703 | |||
704 | netdev_warn(netdev, "couldn't find free context"); | ||
705 | |||
706 | return NETDEV_TX_BUSY; | ||
707 | |||
708 | failed: | ||
709 | can_free_echo_skb(netdev, context->echo_index); | ||
710 | |||
711 | usb_unanchor_urb(urb); | ||
712 | usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); | ||
713 | |||
714 | atomic_dec(&priv->active_tx_urbs); | ||
715 | |||
716 | if (err == -ENODEV) | ||
717 | netif_device_detach(netdev); | ||
718 | else | ||
719 | netdev_warn(netdev, "failed tx_urb %d\n", err); | ||
720 | |||
721 | nomembuf: | ||
722 | usb_free_urb(urb); | ||
723 | |||
724 | nomem: | ||
725 | dev_kfree_skb(skb); | ||
726 | stats->tx_dropped++; | ||
727 | |||
728 | return NETDEV_TX_OK; | ||
729 | } | ||
730 | |||
731 | static int usb_8dev_get_berr_counter(const struct net_device *netdev, | ||
732 | struct can_berr_counter *bec) | ||
733 | { | ||
734 | struct usb_8dev_priv *priv = netdev_priv(netdev); | ||
735 | |||
736 | bec->txerr = priv->bec.txerr; | ||
737 | bec->rxerr = priv->bec.rxerr; | ||
738 | |||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | /* Start USB device */ | ||
743 | static int usb_8dev_start(struct usb_8dev_priv *priv) | ||
744 | { | ||
745 | struct net_device *netdev = priv->netdev; | ||
746 | int err, i; | ||
747 | |||
748 | for (i = 0; i < MAX_RX_URBS; i++) { | ||
749 | struct urb *urb = NULL; | ||
750 | u8 *buf; | ||
751 | |||
752 | /* create a URB, and a buffer for it */ | ||
753 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
754 | if (!urb) { | ||
755 | netdev_err(netdev, "No memory left for URBs\n"); | ||
756 | err = -ENOMEM; | ||
757 | break; | ||
758 | } | ||
759 | |||
760 | buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL, | ||
761 | &urb->transfer_dma); | ||
762 | if (!buf) { | ||
763 | netdev_err(netdev, "No memory left for USB buffer\n"); | ||
764 | usb_free_urb(urb); | ||
765 | err = -ENOMEM; | ||
766 | break; | ||
767 | } | ||
768 | |||
769 | usb_fill_bulk_urb(urb, priv->udev, | ||
770 | usb_rcvbulkpipe(priv->udev, | ||
771 | USB_8DEV_ENDP_DATA_RX), | ||
772 | buf, RX_BUFFER_SIZE, | ||
773 | usb_8dev_read_bulk_callback, priv); | ||
774 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
775 | usb_anchor_urb(urb, &priv->rx_submitted); | ||
776 | |||
777 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
778 | if (err) { | ||
779 | usb_unanchor_urb(urb); | ||
780 | usb_free_coherent(priv->udev, RX_BUFFER_SIZE, buf, | ||
781 | urb->transfer_dma); | ||
782 | break; | ||
783 | } | ||
784 | |||
785 | /* Drop reference, USB core will take care of freeing it */ | ||
786 | usb_free_urb(urb); | ||
787 | } | ||
788 | |||
789 | /* Did we submit any URBs */ | ||
790 | if (i == 0) { | ||
791 | netdev_warn(netdev, "couldn't setup read URBs\n"); | ||
792 | return err; | ||
793 | } | ||
794 | |||
795 | /* Warn if we've couldn't transmit all the URBs */ | ||
796 | if (i < MAX_RX_URBS) | ||
797 | netdev_warn(netdev, "rx performance may be slow\n"); | ||
798 | |||
799 | err = usb_8dev_cmd_open(priv); | ||
800 | if (err) | ||
801 | goto failed; | ||
802 | |||
803 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
804 | |||
805 | return 0; | ||
806 | |||
807 | failed: | ||
808 | if (err == -ENODEV) | ||
809 | netif_device_detach(priv->netdev); | ||
810 | |||
811 | netdev_warn(netdev, "couldn't submit control: %d\n", err); | ||
812 | |||
813 | return err; | ||
814 | } | ||
815 | |||
816 | /* Open USB device */ | ||
817 | static int usb_8dev_open(struct net_device *netdev) | ||
818 | { | ||
819 | struct usb_8dev_priv *priv = netdev_priv(netdev); | ||
820 | int err; | ||
821 | |||
822 | /* common open */ | ||
823 | err = open_candev(netdev); | ||
824 | if (err) | ||
825 | return err; | ||
826 | |||
827 | can_led_event(netdev, CAN_LED_EVENT_OPEN); | ||
828 | |||
829 | /* finally start device */ | ||
830 | err = usb_8dev_start(priv); | ||
831 | if (err) { | ||
832 | if (err == -ENODEV) | ||
833 | netif_device_detach(priv->netdev); | ||
834 | |||
835 | netdev_warn(netdev, "couldn't start device: %d\n", | ||
836 | err); | ||
837 | |||
838 | close_candev(netdev); | ||
839 | |||
840 | return err; | ||
841 | } | ||
842 | |||
843 | netif_start_queue(netdev); | ||
844 | |||
845 | return 0; | ||
846 | } | ||
847 | |||
848 | static void unlink_all_urbs(struct usb_8dev_priv *priv) | ||
849 | { | ||
850 | int i; | ||
851 | |||
852 | usb_kill_anchored_urbs(&priv->rx_submitted); | ||
853 | |||
854 | usb_kill_anchored_urbs(&priv->tx_submitted); | ||
855 | atomic_set(&priv->active_tx_urbs, 0); | ||
856 | |||
857 | for (i = 0; i < MAX_TX_URBS; i++) | ||
858 | priv->tx_contexts[i].echo_index = MAX_TX_URBS; | ||
859 | } | ||
860 | |||
861 | /* Close USB device */ | ||
862 | static int usb_8dev_close(struct net_device *netdev) | ||
863 | { | ||
864 | struct usb_8dev_priv *priv = netdev_priv(netdev); | ||
865 | int err = 0; | ||
866 | |||
867 | /* Send CLOSE command to CAN controller */ | ||
868 | err = usb_8dev_cmd_close(priv); | ||
869 | if (err) | ||
870 | netdev_warn(netdev, "couldn't stop device"); | ||
871 | |||
872 | priv->can.state = CAN_STATE_STOPPED; | ||
873 | |||
874 | netif_stop_queue(netdev); | ||
875 | |||
876 | /* Stop polling */ | ||
877 | unlink_all_urbs(priv); | ||
878 | |||
879 | close_candev(netdev); | ||
880 | |||
881 | can_led_event(netdev, CAN_LED_EVENT_STOP); | ||
882 | |||
883 | return err; | ||
884 | } | ||
885 | |||
886 | static const struct net_device_ops usb_8dev_netdev_ops = { | ||
887 | .ndo_open = usb_8dev_open, | ||
888 | .ndo_stop = usb_8dev_close, | ||
889 | .ndo_start_xmit = usb_8dev_start_xmit, | ||
890 | }; | ||
891 | |||
892 | static const struct can_bittiming_const usb_8dev_bittiming_const = { | ||
893 | .name = "usb_8dev", | ||
894 | .tseg1_min = 1, | ||
895 | .tseg1_max = 16, | ||
896 | .tseg2_min = 1, | ||
897 | .tseg2_max = 8, | ||
898 | .sjw_max = 4, | ||
899 | .brp_min = 1, | ||
900 | .brp_max = 1024, | ||
901 | .brp_inc = 1, | ||
902 | }; | ||
903 | |||
904 | /* Probe USB device | ||
905 | * | ||
906 | * Check device and firmware. | ||
907 | * Set supported modes and bittiming constants. | ||
908 | * Allocate some memory. | ||
909 | */ | ||
910 | static int usb_8dev_probe(struct usb_interface *intf, | ||
911 | const struct usb_device_id *id) | ||
912 | { | ||
913 | struct net_device *netdev; | ||
914 | struct usb_8dev_priv *priv; | ||
915 | int i, err = -ENOMEM; | ||
916 | u32 version; | ||
917 | char buf[18]; | ||
918 | struct usb_device *usbdev = interface_to_usbdev(intf); | ||
919 | |||
920 | /* product id looks strange, better we also check iProduct string */ | ||
921 | if (usb_string(usbdev, usbdev->descriptor.iProduct, buf, | ||
922 | sizeof(buf)) > 0 && strcmp(buf, "USB2CAN converter")) { | ||
923 | dev_info(&usbdev->dev, "ignoring: not an USB2CAN converter\n"); | ||
924 | return -ENODEV; | ||
925 | } | ||
926 | |||
927 | netdev = alloc_candev(sizeof(struct usb_8dev_priv), MAX_TX_URBS); | ||
928 | if (!netdev) { | ||
929 | dev_err(&intf->dev, "Couldn't alloc candev\n"); | ||
930 | return -ENOMEM; | ||
931 | } | ||
932 | |||
933 | priv = netdev_priv(netdev); | ||
934 | |||
935 | priv->udev = usbdev; | ||
936 | priv->netdev = netdev; | ||
937 | |||
938 | priv->can.state = CAN_STATE_STOPPED; | ||
939 | priv->can.clock.freq = USB_8DEV_ABP_CLOCK; | ||
940 | priv->can.bittiming_const = &usb_8dev_bittiming_const; | ||
941 | priv->can.do_set_mode = usb_8dev_set_mode; | ||
942 | priv->can.do_get_berr_counter = usb_8dev_get_berr_counter; | ||
943 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | | ||
944 | CAN_CTRLMODE_LISTENONLY | | ||
945 | CAN_CTRLMODE_ONE_SHOT; | ||
946 | |||
947 | netdev->netdev_ops = &usb_8dev_netdev_ops; | ||
948 | |||
949 | netdev->flags |= IFF_ECHO; /* we support local echo */ | ||
950 | |||
951 | init_usb_anchor(&priv->rx_submitted); | ||
952 | |||
953 | init_usb_anchor(&priv->tx_submitted); | ||
954 | atomic_set(&priv->active_tx_urbs, 0); | ||
955 | |||
956 | for (i = 0; i < MAX_TX_URBS; i++) | ||
957 | priv->tx_contexts[i].echo_index = MAX_TX_URBS; | ||
958 | |||
959 | priv->cmd_msg_buffer = kzalloc(sizeof(struct usb_8dev_cmd_msg), | ||
960 | GFP_KERNEL); | ||
961 | if (!priv->cmd_msg_buffer) { | ||
962 | netdev_err(netdev, "Couldn't alloc Tx buffer\n"); | ||
963 | goto cleanup_candev; | ||
964 | } | ||
965 | |||
966 | usb_set_intfdata(intf, priv); | ||
967 | |||
968 | SET_NETDEV_DEV(netdev, &intf->dev); | ||
969 | |||
970 | mutex_init(&priv->usb_8dev_cmd_lock); | ||
971 | |||
972 | err = register_candev(netdev); | ||
973 | if (err) { | ||
974 | netdev_err(netdev, | ||
975 | "couldn't register CAN device: %d\n", err); | ||
976 | goto cleanup_cmd_msg_buffer; | ||
977 | } | ||
978 | |||
979 | err = usb_8dev_cmd_version(priv, &version); | ||
980 | if (err) { | ||
981 | netdev_err(netdev, "can't get firmware version\n"); | ||
982 | goto cleanup_cmd_msg_buffer; | ||
983 | } else { | ||
984 | netdev_info(netdev, | ||
985 | "firmware: %d.%d, hardware: %d.%d\n", | ||
986 | (version>>24) & 0xff, (version>>16) & 0xff, | ||
987 | (version>>8) & 0xff, version & 0xff); | ||
988 | } | ||
989 | |||
990 | devm_can_led_init(netdev); | ||
991 | |||
992 | return 0; | ||
993 | |||
994 | cleanup_cmd_msg_buffer: | ||
995 | kfree(priv->cmd_msg_buffer); | ||
996 | |||
997 | cleanup_candev: | ||
998 | free_candev(netdev); | ||
999 | |||
1000 | return err; | ||
1001 | |||
1002 | } | ||
1003 | |||
1004 | /* Called by the usb core when driver is unloaded or device is removed */ | ||
1005 | static void usb_8dev_disconnect(struct usb_interface *intf) | ||
1006 | { | ||
1007 | struct usb_8dev_priv *priv = usb_get_intfdata(intf); | ||
1008 | |||
1009 | usb_set_intfdata(intf, NULL); | ||
1010 | |||
1011 | if (priv) { | ||
1012 | netdev_info(priv->netdev, "device disconnected\n"); | ||
1013 | |||
1014 | unregister_netdev(priv->netdev); | ||
1015 | free_candev(priv->netdev); | ||
1016 | |||
1017 | unlink_all_urbs(priv); | ||
1018 | } | ||
1019 | |||
1020 | } | ||
1021 | |||
1022 | static struct usb_driver usb_8dev_driver = { | ||
1023 | .name = "usb_8dev", | ||
1024 | .probe = usb_8dev_probe, | ||
1025 | .disconnect = usb_8dev_disconnect, | ||
1026 | .id_table = usb_8dev_table, | ||
1027 | }; | ||
1028 | |||
1029 | module_usb_driver(usb_8dev_driver); | ||
1030 | |||
1031 | MODULE_AUTHOR("Bernd Krumboeck <krumboeck@universalnet.at>"); | ||
1032 | MODULE_DESCRIPTION("CAN driver for 8 devices USB2CAN interfaces"); | ||
1033 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 2b2fc345afca..fb0ab651a041 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/can.h> | 16 | #include <linux/can.h> |
17 | #include <linux/can/netlink.h> | 17 | #include <linux/can/netlink.h> |
18 | #include <linux/can/error.h> | 18 | #include <linux/can/error.h> |
19 | #include <linux/can/led.h> | ||
19 | 20 | ||
20 | /* | 21 | /* |
21 | * CAN mode | 22 | * CAN mode |
@@ -52,6 +53,13 @@ struct can_priv { | |||
52 | 53 | ||
53 | unsigned int echo_skb_max; | 54 | unsigned int echo_skb_max; |
54 | struct sk_buff **echo_skb; | 55 | struct sk_buff **echo_skb; |
56 | |||
57 | #ifdef CONFIG_CAN_LEDS | ||
58 | struct led_trigger *tx_led_trig; | ||
59 | char tx_led_trig_name[CAN_LED_NAME_SZ]; | ||
60 | struct led_trigger *rx_led_trig; | ||
61 | char rx_led_trig_name[CAN_LED_NAME_SZ]; | ||
62 | #endif | ||
55 | }; | 63 | }; |
56 | 64 | ||
57 | /* | 65 | /* |
@@ -98,6 +106,9 @@ u8 can_len2dlc(u8 len); | |||
98 | struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max); | 106 | struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max); |
99 | void free_candev(struct net_device *dev); | 107 | void free_candev(struct net_device *dev); |
100 | 108 | ||
109 | /* a candev safe wrapper around netdev_priv */ | ||
110 | struct can_priv *safe_candev_priv(struct net_device *dev); | ||
111 | |||
101 | int open_candev(struct net_device *dev); | 112 | int open_candev(struct net_device *dev); |
102 | void close_candev(struct net_device *dev); | 113 | void close_candev(struct net_device *dev); |
103 | 114 | ||
diff --git a/include/linux/can/led.h b/include/linux/can/led.h new file mode 100644 index 000000000000..9c1167baf273 --- /dev/null +++ b/include/linux/can/led.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef CAN_LED_H | ||
10 | #define CAN_LED_H | ||
11 | |||
12 | #include <linux/if.h> | ||
13 | #include <linux/leds.h> | ||
14 | |||
15 | enum can_led_event { | ||
16 | CAN_LED_EVENT_OPEN, | ||
17 | CAN_LED_EVENT_STOP, | ||
18 | CAN_LED_EVENT_TX, | ||
19 | CAN_LED_EVENT_RX, | ||
20 | }; | ||
21 | |||
22 | #ifdef CONFIG_CAN_LEDS | ||
23 | |||
24 | /* keep space for interface name + "-tx"/"-rx" suffix and null terminator */ | ||
25 | #define CAN_LED_NAME_SZ (IFNAMSIZ + 4) | ||
26 | |||
27 | void can_led_event(struct net_device *netdev, enum can_led_event event); | ||
28 | void devm_can_led_init(struct net_device *netdev); | ||
29 | int __init can_led_notifier_init(void); | ||
30 | void __exit can_led_notifier_exit(void); | ||
31 | |||
32 | #else | ||
33 | |||
34 | static inline void can_led_event(struct net_device *netdev, | ||
35 | enum can_led_event event) | ||
36 | { | ||
37 | } | ||
38 | static inline void devm_can_led_init(struct net_device *netdev) | ||
39 | { | ||
40 | } | ||
41 | static inline int can_led_notifier_init(void) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | static inline void can_led_notifier_exit(void) | ||
46 | { | ||
47 | } | ||
48 | |||
49 | #endif | ||
50 | |||
51 | #endif | ||
diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h new file mode 100644 index 000000000000..4b0f24d3a878 --- /dev/null +++ b/include/linux/can/skb.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * linux/can/skb.h | ||
3 | * | ||
4 | * Definitions for the CAN network socket buffer | ||
5 | * | ||
6 | * Copyright (C) 2012 Oliver Hartkopp <socketcan@hartkopp.net> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef CAN_SKB_H | ||
11 | #define CAN_SKB_H | ||
12 | |||
13 | #include <linux/types.h> | ||
14 | #include <linux/can.h> | ||
15 | |||
16 | /* | ||
17 | * The struct can_skb_priv is used to transport additional information along | ||
18 | * with the stored struct can(fd)_frame that can not be contained in existing | ||
19 | * struct sk_buff elements. | ||
20 | * N.B. that this information must not be modified in cloned CAN sk_buffs. | ||
21 | * To modify the CAN frame content or the struct can_skb_priv content | ||
22 | * skb_copy() needs to be used instead of skb_clone(). | ||
23 | */ | ||
24 | |||
25 | /** | ||
26 | * struct can_skb_priv - private additional data inside CAN sk_buffs | ||
27 | * @ifindex: ifindex of the first interface the CAN frame appeared on | ||
28 | * @cf: align to the following CAN frame at skb->data | ||
29 | */ | ||
30 | struct can_skb_priv { | ||
31 | int ifindex; | ||
32 | struct can_frame cf[0]; | ||
33 | }; | ||
34 | |||
35 | #endif /* CAN_SKB_H */ | ||
diff --git a/include/uapi/linux/can/gw.h b/include/uapi/linux/can/gw.h index 8e1db18c3cb6..ae07bec74f4b 100644 --- a/include/uapi/linux/can/gw.h +++ b/include/uapi/linux/can/gw.h | |||
@@ -44,6 +44,7 @@ enum { | |||
44 | CGW_SRC_IF, /* ifindex of source network interface */ | 44 | CGW_SRC_IF, /* ifindex of source network interface */ |
45 | CGW_DST_IF, /* ifindex of destination network interface */ | 45 | CGW_DST_IF, /* ifindex of destination network interface */ |
46 | CGW_FILTER, /* specify struct can_filter on source CAN device */ | 46 | CGW_FILTER, /* specify struct can_filter on source CAN device */ |
47 | CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */ | ||
47 | __CGW_MAX | 48 | __CGW_MAX |
48 | }; | 49 | }; |
49 | 50 | ||
@@ -51,6 +52,7 @@ enum { | |||
51 | 52 | ||
52 | #define CGW_FLAGS_CAN_ECHO 0x01 | 53 | #define CGW_FLAGS_CAN_ECHO 0x01 |
53 | #define CGW_FLAGS_CAN_SRC_TSTAMP 0x02 | 54 | #define CGW_FLAGS_CAN_SRC_TSTAMP 0x02 |
55 | #define CGW_FLAGS_CAN_IIF_TX_OK 0x04 | ||
54 | 56 | ||
55 | #define CGW_MOD_FUNCS 4 /* AND OR XOR SET */ | 57 | #define CGW_MOD_FUNCS 4 /* AND OR XOR SET */ |
56 | 58 | ||
diff --git a/net/can/Kconfig b/net/can/Kconfig index 03200699d274..a15c0e0d1fc7 100644 --- a/net/can/Kconfig +++ b/net/can/Kconfig | |||
@@ -16,10 +16,11 @@ menuconfig CAN | |||
16 | If you want CAN support you should say Y here and also to the | 16 | If you want CAN support you should say Y here and also to the |
17 | specific driver for your controller(s) below. | 17 | specific driver for your controller(s) below. |
18 | 18 | ||
19 | if CAN | ||
20 | |||
19 | config CAN_RAW | 21 | config CAN_RAW |
20 | tristate "Raw CAN Protocol (raw access with CAN-ID filtering)" | 22 | tristate "Raw CAN Protocol (raw access with CAN-ID filtering)" |
21 | depends on CAN | 23 | default y |
22 | default N | ||
23 | ---help--- | 24 | ---help--- |
24 | The raw CAN protocol option offers access to the CAN bus via | 25 | The raw CAN protocol option offers access to the CAN bus via |
25 | the BSD socket API. You probably want to use the raw socket in | 26 | the BSD socket API. You probably want to use the raw socket in |
@@ -29,8 +30,7 @@ config CAN_RAW | |||
29 | 30 | ||
30 | config CAN_BCM | 31 | config CAN_BCM |
31 | tristate "Broadcast Manager CAN Protocol (with content filtering)" | 32 | tristate "Broadcast Manager CAN Protocol (with content filtering)" |
32 | depends on CAN | 33 | default y |
33 | default N | ||
34 | ---help--- | 34 | ---help--- |
35 | The Broadcast Manager offers content filtering, timeout monitoring, | 35 | The Broadcast Manager offers content filtering, timeout monitoring, |
36 | sending of RTR frames, and cyclic CAN messages without permanent user | 36 | sending of RTR frames, and cyclic CAN messages without permanent user |
@@ -42,8 +42,7 @@ config CAN_BCM | |||
42 | 42 | ||
43 | config CAN_GW | 43 | config CAN_GW |
44 | tristate "CAN Gateway/Router (with netlink configuration)" | 44 | tristate "CAN Gateway/Router (with netlink configuration)" |
45 | depends on CAN | 45 | default y |
46 | default N | ||
47 | ---help--- | 46 | ---help--- |
48 | The CAN Gateway/Router is used to route (and modify) CAN frames. | 47 | The CAN Gateway/Router is used to route (and modify) CAN frames. |
49 | It is based on the PF_CAN core infrastructure for msg filtering and | 48 | It is based on the PF_CAN core infrastructure for msg filtering and |
@@ -53,3 +52,5 @@ config CAN_GW | |||
53 | by the netlink configuration interface known e.g. from iptables. | 52 | by the netlink configuration interface known e.g. from iptables. |
54 | 53 | ||
55 | source "drivers/net/can/Kconfig" | 54 | source "drivers/net/can/Kconfig" |
55 | |||
56 | endif | ||
diff --git a/net/can/bcm.c b/net/can/bcm.c index 969b7cdff59d..ccc27b9e8384 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/skbuff.h> | 54 | #include <linux/skbuff.h> |
55 | #include <linux/can.h> | 55 | #include <linux/can.h> |
56 | #include <linux/can/core.h> | 56 | #include <linux/can/core.h> |
57 | #include <linux/can/skb.h> | ||
57 | #include <linux/can/bcm.h> | 58 | #include <linux/can/bcm.h> |
58 | #include <linux/slab.h> | 59 | #include <linux/slab.h> |
59 | #include <net/sock.h> | 60 | #include <net/sock.h> |
@@ -256,10 +257,13 @@ static void bcm_can_tx(struct bcm_op *op) | |||
256 | return; | 257 | return; |
257 | } | 258 | } |
258 | 259 | ||
259 | skb = alloc_skb(CFSIZ, gfp_any()); | 260 | skb = alloc_skb(CFSIZ + sizeof(struct can_skb_priv), gfp_any()); |
260 | if (!skb) | 261 | if (!skb) |
261 | goto out; | 262 | goto out; |
262 | 263 | ||
264 | skb_reserve(skb, sizeof(struct can_skb_priv)); | ||
265 | ((struct can_skb_priv *)(skb->head))->ifindex = dev->ifindex; | ||
266 | |||
263 | memcpy(skb_put(skb, CFSIZ), cf, CFSIZ); | 267 | memcpy(skb_put(skb, CFSIZ), cf, CFSIZ); |
264 | 268 | ||
265 | /* send with loopback */ | 269 | /* send with loopback */ |
@@ -1199,11 +1203,12 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk) | |||
1199 | if (!ifindex) | 1203 | if (!ifindex) |
1200 | return -ENODEV; | 1204 | return -ENODEV; |
1201 | 1205 | ||
1202 | skb = alloc_skb(CFSIZ, GFP_KERNEL); | 1206 | skb = alloc_skb(CFSIZ + sizeof(struct can_skb_priv), GFP_KERNEL); |
1203 | |||
1204 | if (!skb) | 1207 | if (!skb) |
1205 | return -ENOMEM; | 1208 | return -ENOMEM; |
1206 | 1209 | ||
1210 | skb_reserve(skb, sizeof(struct can_skb_priv)); | ||
1211 | |||
1207 | err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ); | 1212 | err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ); |
1208 | if (err < 0) { | 1213 | if (err < 0) { |
1209 | kfree_skb(skb); | 1214 | kfree_skb(skb); |
@@ -1216,6 +1221,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk) | |||
1216 | return -ENODEV; | 1221 | return -ENODEV; |
1217 | } | 1222 | } |
1218 | 1223 | ||
1224 | ((struct can_skb_priv *)(skb->head))->ifindex = dev->ifindex; | ||
1219 | skb->dev = dev; | 1225 | skb->dev = dev; |
1220 | skb->sk = sk; | 1226 | skb->sk = sk; |
1221 | err = can_send(skb, 1); /* send with loopback */ | 1227 | err = can_send(skb, 1); /* send with loopback */ |
diff --git a/net/can/gw.c b/net/can/gw.c index 574dda78eb0f..acdd4656cc3b 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <linux/types.h> | 44 | #include <linux/types.h> |
45 | #include <linux/kernel.h> | ||
45 | #include <linux/list.h> | 46 | #include <linux/list.h> |
46 | #include <linux/spinlock.h> | 47 | #include <linux/spinlock.h> |
47 | #include <linux/rcupdate.h> | 48 | #include <linux/rcupdate.h> |
@@ -52,19 +53,31 @@ | |||
52 | #include <linux/skbuff.h> | 53 | #include <linux/skbuff.h> |
53 | #include <linux/can.h> | 54 | #include <linux/can.h> |
54 | #include <linux/can/core.h> | 55 | #include <linux/can/core.h> |
56 | #include <linux/can/skb.h> | ||
55 | #include <linux/can/gw.h> | 57 | #include <linux/can/gw.h> |
56 | #include <net/rtnetlink.h> | 58 | #include <net/rtnetlink.h> |
57 | #include <net/net_namespace.h> | 59 | #include <net/net_namespace.h> |
58 | #include <net/sock.h> | 60 | #include <net/sock.h> |
59 | 61 | ||
60 | #define CAN_GW_VERSION "20101209" | 62 | #define CAN_GW_VERSION "20130117" |
61 | static __initconst const char banner[] = | 63 | #define CAN_GW_NAME "can-gw" |
62 | KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n"; | ||
63 | 64 | ||
64 | MODULE_DESCRIPTION("PF_CAN netlink gateway"); | 65 | MODULE_DESCRIPTION("PF_CAN netlink gateway"); |
65 | MODULE_LICENSE("Dual BSD/GPL"); | 66 | MODULE_LICENSE("Dual BSD/GPL"); |
66 | MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>"); | 67 | MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>"); |
67 | MODULE_ALIAS("can-gw"); | 68 | MODULE_ALIAS(CAN_GW_NAME); |
69 | |||
70 | #define CGW_MIN_HOPS 1 | ||
71 | #define CGW_MAX_HOPS 6 | ||
72 | #define CGW_DEFAULT_HOPS 1 | ||
73 | |||
74 | static unsigned int max_hops __read_mostly = CGW_DEFAULT_HOPS; | ||
75 | module_param(max_hops, uint, S_IRUGO); | ||
76 | MODULE_PARM_DESC(max_hops, | ||
77 | "maximum " CAN_GW_NAME " routing hops for CAN frames " | ||
78 | "(valid values: " __stringify(CGW_MIN_HOPS) "-" | ||
79 | __stringify(CGW_MAX_HOPS) " hops, " | ||
80 | "default: " __stringify(CGW_DEFAULT_HOPS) ")"); | ||
68 | 81 | ||
69 | static HLIST_HEAD(cgw_list); | 82 | static HLIST_HEAD(cgw_list); |
70 | static struct notifier_block notifier; | 83 | static struct notifier_block notifier; |
@@ -118,6 +131,7 @@ struct cgw_job { | |||
118 | struct rcu_head rcu; | 131 | struct rcu_head rcu; |
119 | u32 handled_frames; | 132 | u32 handled_frames; |
120 | u32 dropped_frames; | 133 | u32 dropped_frames; |
134 | u32 deleted_frames; | ||
121 | struct cf_mod mod; | 135 | struct cf_mod mod; |
122 | union { | 136 | union { |
123 | /* CAN frame data source */ | 137 | /* CAN frame data source */ |
@@ -338,15 +352,40 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) | |||
338 | struct sk_buff *nskb; | 352 | struct sk_buff *nskb; |
339 | int modidx = 0; | 353 | int modidx = 0; |
340 | 354 | ||
341 | /* do not handle already routed frames - see comment below */ | 355 | /* |
342 | if (skb_mac_header_was_set(skb)) | 356 | * Do not handle CAN frames routed more than 'max_hops' times. |
357 | * In general we should never catch this delimiter which is intended | ||
358 | * to cover a misconfiguration protection (e.g. circular CAN routes). | ||
359 | * | ||
360 | * The Controller Area Network controllers only accept CAN frames with | ||
361 | * correct CRCs - which are not visible in the controller registers. | ||
362 | * According to skbuff.h documentation the csum_start element for IP | ||
363 | * checksums is undefined/unsued when ip_summed == CHECKSUM_UNNECESSARY. | ||
364 | * Only CAN skbs can be processed here which already have this property. | ||
365 | */ | ||
366 | |||
367 | #define cgw_hops(skb) ((skb)->csum_start) | ||
368 | |||
369 | BUG_ON(skb->ip_summed != CHECKSUM_UNNECESSARY); | ||
370 | |||
371 | if (cgw_hops(skb) >= max_hops) { | ||
372 | /* indicate deleted frames due to misconfiguration */ | ||
373 | gwj->deleted_frames++; | ||
343 | return; | 374 | return; |
375 | } | ||
344 | 376 | ||
345 | if (!(gwj->dst.dev->flags & IFF_UP)) { | 377 | if (!(gwj->dst.dev->flags & IFF_UP)) { |
346 | gwj->dropped_frames++; | 378 | gwj->dropped_frames++; |
347 | return; | 379 | return; |
348 | } | 380 | } |
349 | 381 | ||
382 | /* is sending the skb back to the incoming interface not allowed? */ | ||
383 | if (!(gwj->flags & CGW_FLAGS_CAN_IIF_TX_OK) && | ||
384 | skb_headroom(skb) == sizeof(struct can_skb_priv) && | ||
385 | (((struct can_skb_priv *)(skb->head))->ifindex == | ||
386 | gwj->dst.dev->ifindex)) | ||
387 | return; | ||
388 | |||
350 | /* | 389 | /* |
351 | * clone the given skb, which has not been done in can_rcv() | 390 | * clone the given skb, which has not been done in can_rcv() |
352 | * | 391 | * |
@@ -363,15 +402,8 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) | |||
363 | return; | 402 | return; |
364 | } | 403 | } |
365 | 404 | ||
366 | /* | 405 | /* put the incremented hop counter in the cloned skb */ |
367 | * Mark routed frames by setting some mac header length which is | 406 | cgw_hops(nskb) = cgw_hops(skb) + 1; |
368 | * not relevant for the CAN frames located in the skb->data section. | ||
369 | * | ||
370 | * As dev->header_ops is not set in CAN netdevices no one is ever | ||
371 | * accessing the various header offsets in the CAN skbuffs anyway. | ||
372 | * E.g. using the packet socket to read CAN frames is still working. | ||
373 | */ | ||
374 | skb_set_mac_header(nskb, 8); | ||
375 | nskb->dev = gwj->dst.dev; | 407 | nskb->dev = gwj->dst.dev; |
376 | 408 | ||
377 | /* pointer to modifiable CAN frame */ | 409 | /* pointer to modifiable CAN frame */ |
@@ -472,6 +504,11 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type, | |||
472 | goto cancel; | 504 | goto cancel; |
473 | } | 505 | } |
474 | 506 | ||
507 | if (gwj->deleted_frames) { | ||
508 | if (nla_put_u32(skb, CGW_DELETED, gwj->deleted_frames) < 0) | ||
509 | goto cancel; | ||
510 | } | ||
511 | |||
475 | /* check non default settings of attributes */ | 512 | /* check non default settings of attributes */ |
476 | 513 | ||
477 | if (gwj->mod.modtype.and) { | 514 | if (gwj->mod.modtype.and) { |
@@ -771,6 +808,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
771 | 808 | ||
772 | gwj->handled_frames = 0; | 809 | gwj->handled_frames = 0; |
773 | gwj->dropped_frames = 0; | 810 | gwj->dropped_frames = 0; |
811 | gwj->deleted_frames = 0; | ||
774 | gwj->flags = r->flags; | 812 | gwj->flags = r->flags; |
775 | gwj->gwtype = r->gwtype; | 813 | gwj->gwtype = r->gwtype; |
776 | 814 | ||
@@ -895,7 +933,11 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
895 | 933 | ||
896 | static __init int cgw_module_init(void) | 934 | static __init int cgw_module_init(void) |
897 | { | 935 | { |
898 | printk(banner); | 936 | /* sanitize given module parameter */ |
937 | max_hops = clamp_t(unsigned int, max_hops, CGW_MIN_HOPS, CGW_MAX_HOPS); | ||
938 | |||
939 | pr_info("can: netlink gateway (rev " CAN_GW_VERSION ") max_hops=%d\n", | ||
940 | max_hops); | ||
899 | 941 | ||
900 | cgw_cache = kmem_cache_create("can_gw", sizeof(struct cgw_job), | 942 | cgw_cache = kmem_cache_create("can_gw", sizeof(struct cgw_job), |
901 | 0, 0, NULL); | 943 | 0, 0, NULL); |
diff --git a/net/can/raw.c b/net/can/raw.c index 5b0e3e330d97..5d860e8dcc52 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/skbuff.h> | 50 | #include <linux/skbuff.h> |
51 | #include <linux/can.h> | 51 | #include <linux/can.h> |
52 | #include <linux/can/core.h> | 52 | #include <linux/can/core.h> |
53 | #include <linux/can/skb.h> | ||
53 | #include <linux/can/raw.h> | 54 | #include <linux/can/raw.h> |
54 | #include <net/sock.h> | 55 | #include <net/sock.h> |
55 | #include <net/net_namespace.h> | 56 | #include <net/net_namespace.h> |
@@ -699,11 +700,14 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
699 | if (!dev) | 700 | if (!dev) |
700 | return -ENXIO; | 701 | return -ENXIO; |
701 | 702 | ||
702 | skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, | 703 | skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv), |
703 | &err); | 704 | msg->msg_flags & MSG_DONTWAIT, &err); |
704 | if (!skb) | 705 | if (!skb) |
705 | goto put_dev; | 706 | goto put_dev; |
706 | 707 | ||
708 | skb_reserve(skb, sizeof(struct can_skb_priv)); | ||
709 | ((struct can_skb_priv *)(skb->head))->ifindex = dev->ifindex; | ||
710 | |||
707 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 711 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
708 | if (err < 0) | 712 | if (err < 0) |
709 | goto free_skb; | 713 | goto free_skb; |