30 #include <linux/version.h>
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/list.h>
35 #include <linux/netdevice.h>
36 #include <linux/etherdevice.h>
37 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
38 # include <uapi/linux/can.h>
40 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
41 # include <linux/can.h>
43 # error Only Linux Kernel 3.6 and above are supported
49 #include <asm-generic/errno-base.h>
50 #include <asm-generic/errno.h>
66 struct net_device *
dev;
79 printk(
"ce_gw: ce_gw_open called\n");
81 if (!netif_device_present(dev)) {
82 pr_err(
"ce_gw_dev_open: Device not registered");
86 netif_start_queue(dev);
100 printk (
"ce_gw_dev: ce_gw_release called\n");
101 netif_stop_queue(dev);
116 struct net_device *dev)
118 printk (
"ce_gw_dev: dummy xmit function called....\n");
123 struct hlist_node *node;
125 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
126 hlist_for_each_entry_safe(job, node, &priv->
job_src, list_dev) {
129 struct hlist_node *pos;
130 hlist_for_each_entry_safe(job, pos, node, &priv->
job_src,
157 printk (
"ce_gw_dev: device init called\n");
175 struct hlist_node *node;
177 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
178 hlist_for_each_entry_safe(dl, node, &ce_gw_dev_allocated, list_alloc) {
181 struct hlist_node *pos;
182 hlist_for_each_entry_safe(dl, pos, node, &ce_gw_dev_allocated,
185 if (dl->
dev == eth_dev)
195 struct hlist_node *node;
197 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
198 hlist_for_each_entry_safe(dl, node, &ce_gw_dev_registered, list_reg) {
201 struct hlist_node *pos;
202 hlist_for_each_entry_safe(dl, pos, node, &ce_gw_dev_registered,
205 if (dl->
dev == eth_dev)
209 pr_debug(
"ce_gw_is_registered_dev: Device not registered\n");
215 int mtu = ETH_DATA_LEN;
223 mtu = CANFD_MAX_DLEN;
229 if ((flags & CE_GW_F_CAN_FD) == CE_GW_F_CAN_FD) {
230 mtu =
sizeof(
struct canfd_frame);
232 mtu =
sizeof(
struct can_frame);
242 pr_err(
"ce_gw_dev: Type not defined.");
245 if (dev->mtu >= mtu) {
264 if (job->
src.
dev == eth_dev) {
266 }
else if (job->
dst.
dev == eth_dev) {
269 pr_err(
"ce_gw_dev_job_add: Invalid Arguments");
280 pr_debug(
"ce_gw_dev: Alloc Device\n");
281 struct net_device *dev;
284 dev_name, ether_setup);
286 pr_err(
"ce_gw_dev: Error allocation etherdev.");
287 goto ce_gw_dev_create_error;
298 dl = kmem_cache_alloc(ce_gw_dev_cache, GFP_KERNEL);
300 pr_err(
"ce_gw_dev: cache alloc failed");
301 goto ce_gw_dev_create_error_cache;
306 hlist_add_head_rcu(&dl->
list_alloc, &ce_gw_dev_allocated);
310 ce_gw_dev_create_error_cache:
311 kmem_cache_free(ce_gw_dev_cache, dl);
313 ce_gw_dev_create_error:
319 pr_debug(
"ce_gw_dev: Free Device %s\n", eth_dev->name);
322 struct hlist_node *node;
325 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
326 hlist_for_each_entry_safe(dl, node, &ce_gw_dev_allocated, list_alloc) {
329 struct hlist_node *pos;
330 hlist_for_each_entry_safe(dl, pos, node, &ce_gw_dev_allocated,
333 if (dl->
dev == eth_dev)
337 if (dl == NULL || dl->
dev != eth_dev) {
338 pr_err(
"ce_gw_dev: Device not found in list\n");
343 free_netdev(eth_dev);
344 kmem_cache_free(ce_gw_dev_cache, dl);
358 dev->mtu = CANFD_MAX_DLEN;
360 dev->mtu = CAN_MAX_DLEN;
364 if ((flags & CE_GW_F_CAN_FD) == CE_GW_F_CAN_FD) {
365 dev->mtu =
sizeof(
struct canfd_frame);
367 dev->mtu =
sizeof(
struct can_frame);
377 pr_err(
"ce_gw_dev: Type not defined.");
383 struct net_device *dev;
393 pr_debug(
"ce_gw_dev: Register Device\n");
395 err = register_netdev(eth_dev);
398 struct hlist_node *node;
401 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
402 hlist_for_each_entry_safe(dl, node, &ce_gw_dev_allocated, list_alloc) {
405 struct hlist_node *pos;
406 hlist_for_each_entry_safe(dl, pos, node, &ce_gw_dev_allocated,
409 if (dl->
dev == eth_dev)
413 if (dl == NULL || dl->
dev != eth_dev) {
414 pr_err(
"ce_gw_dev: Device not found in list\n");
415 goto ce_gw_dev_register_error;
418 hlist_add_head_rcu(&dl->
list_reg, &ce_gw_dev_registered);
420 pr_err(
"ce_gw_dev: Device not add to list correct\n");
425 ce_gw_dev_register_error:
426 unregister_netdev(eth_dev);
431 pr_debug(
"ce_gw_dev: Unregister Device %s\n", eth_dev->name);
435 pr_debug(
"ce_gw_dev: Deleting all Routes of %s\n", eth_dev->name);
440 struct hlist_node *node;
441 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
442 hlist_for_each_entry_safe(job, node, &priv->
job_src, list_dev) {
445 struct hlist_node *pos;
446 hlist_for_each_entry_safe(job, pos, node, &priv->
job_src, list_dev) {
451 pr_err(
"ce_gw_dev: route with id %u "
452 "deleting failed: %d", job->
id, err);
460 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
461 hlist_for_each_entry_safe(job, node, &priv->
job_dst, list_dev) {
465 hlist_for_each_entry_safe(job, pos, node, &priv->
job_dst, list_dev) {
470 pr_err(
"ce_gw_dev: route with id %u "
471 "deleting failed: %d", job->
id, err);
476 pr_debug(
"ce_gw_dev: Call unregister_netdev() of %s\n", eth_dev->name);
477 unregister_netdev(eth_dev);
483 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
484 hlist_for_each_entry_safe(dl, node, &ce_gw_dev_registered,
list_reg) {
488 hlist_for_each_entry_safe(dl, pos, node, &ce_gw_dev_registered,
491 if (dl->
dev == eth_dev)
495 if (dl == NULL || &dl->
list_reg == NULL) {
496 pr_err(
"ce_gw_dev: Device not correct in internal list\n");
504 ce_gw_dev_cache = kmem_cache_create(
"can_eth_gw_dev",
507 if (!ce_gw_dev_cache)
515 struct hlist_node *node;
518 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
519 hlist_for_each_entry_safe(dl, node, &ce_gw_dev_registered, list_reg) {
522 struct hlist_node *pos;
523 hlist_for_each_entry_safe(dl, pos, node, &ce_gw_dev_registered,
533 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
534 hlist_for_each_entry_safe(dl, node, &ce_gw_dev_allocated, list_alloc) {
538 hlist_for_each_entry_safe(dl, pos, node, &ce_gw_dev_allocated,
544 kmem_cache_destroy(ce_gw_dev_cache);