Skip to content
Snippets Groups Projects
Commit b8bfb6c0 authored by Florian Pose's avatar Florian Pose
Browse files

Sending via generic device works.

parent 99ac9d87
No related branches found
No related tags found
No related merge requests found
...@@ -45,6 +45,8 @@ ...@@ -45,6 +45,8 @@
#define PFX "ec_generic: " #define PFX "ec_generic: "
#define ETH_P_ETHERCAT 0x88A4
/*****************************************************************************/ /*****************************************************************************/
int __init ec_gen_init_module(void); int __init ec_gen_init_module(void);
...@@ -66,9 +68,7 @@ struct list_head generic_devices; ...@@ -66,9 +68,7 @@ struct list_head generic_devices;
typedef struct { typedef struct {
struct list_head list; struct list_head list;
struct net_device *netdev; struct net_device *netdev;
#if 0 struct socket *socket;
struct net_device *real_netdev;
#endif
ec_device_t *ecdev; ec_device_t *ecdev;
} ec_gen_device_t; } ec_gen_device_t;
...@@ -130,9 +130,7 @@ int ec_gen_device_init( ...@@ -130,9 +130,7 @@ int ec_gen_device_init(
char null = 0x00; char null = 0x00;
dev->ecdev = NULL; dev->ecdev = NULL;
#if 0 dev->socket = NULL;
dev->real_netdev = real_netdev;
#endif
dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, ether_setup); dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, ether_setup);
if (!dev->netdev) { if (!dev->netdev) {
...@@ -158,25 +156,69 @@ void ec_gen_device_clear( ...@@ -158,25 +156,69 @@ void ec_gen_device_clear(
ecdev_close(dev->ecdev); ecdev_close(dev->ecdev);
ecdev_withdraw(dev->ecdev); ecdev_withdraw(dev->ecdev);
} }
if (dev->socket) {
sock_release(dev->socket);
}
free_netdev(dev->netdev); free_netdev(dev->netdev);
} }
/*****************************************************************************/ /*****************************************************************************/
/** Creates a network socket.
*/
int ec_gen_device_create_socket(
ec_gen_device_t *dev,
struct net_device *real_netdev
)
{
int ret;
struct sockaddr_ll sa;
ret = sock_create_kern(PF_PACKET, SOCK_RAW, htons(ETH_P_ETHERCAT), &dev->socket);
if (ret) {
printk(KERN_ERR PFX "Failed to create socket.\n");
return ret;
}
printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n",
real_netdev->ifindex, real_netdev->name);
memset(&sa, 0x00, sizeof(sa));
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(ETH_P_ETHERCAT);
sa.sll_ifindex = real_netdev->ifindex;
ret = kernel_bind(dev->socket, (struct sockaddr *) &sa, sizeof(sa));
if (ret) {
printk(KERN_ERR PFX "Failed to bind() socket to interface.\n");
sock_release(dev->socket);
dev->socket = NULL;
return ret;
}
return 0;
}
/*****************************************************************************/
/** Offer generic device to master. /** Offer generic device to master.
*/ */
int ec_gen_device_offer( int ec_gen_device_offer(
ec_gen_device_t *dev ec_gen_device_t *dev,
struct net_device *real_netdev
) )
{ {
int ret = 0; int ret = 0;
dev->ecdev = ecdev_offer(dev->netdev, ec_gen_poll, THIS_MODULE); dev->ecdev = ecdev_offer(dev->netdev, ec_gen_poll, THIS_MODULE);
if (dev->ecdev) { if (dev->ecdev) {
if (ecdev_open(dev->ecdev)) { if (ec_gen_device_create_socket(dev, real_netdev)) {
ecdev_withdraw(dev->ecdev);
dev->ecdev = NULL;
} else if (ecdev_open(dev->ecdev)) {
ecdev_withdraw(dev->ecdev); ecdev_withdraw(dev->ecdev);
dev->ecdev = NULL; dev->ecdev = NULL;
} else { } else {
ecdev_set_link(dev->ecdev, 1); // FIXME
ret = 1; ret = 1;
} }
} }
...@@ -192,17 +234,7 @@ int ec_gen_device_open( ...@@ -192,17 +234,7 @@ int ec_gen_device_open(
ec_gen_device_t *dev ec_gen_device_t *dev
) )
{ {
int ret = 0; return 0;
#if 0
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
ret = dev->real_netdev->netdev_ops->ndo_open(dev->real_netdev);
#else
ret = dev->real_netdev->open(dev->real_netdev);
#endif
#endif
return ret;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -213,17 +245,7 @@ int ec_gen_device_stop( ...@@ -213,17 +245,7 @@ int ec_gen_device_stop(
ec_gen_device_t *dev ec_gen_device_t *dev
) )
{ {
int ret = 0; return 0;
#if 0
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
ret = dev->real_netdev->netdev_ops->ndo_stop(dev->real_netdev);
#else
ret = dev->real_netdev->stop(dev->real_netdev);
#endif
#endif
return ret;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -233,7 +255,18 @@ int ec_gen_device_start_xmit( ...@@ -233,7 +255,18 @@ int ec_gen_device_start_xmit(
struct sk_buff *skb struct sk_buff *skb
) )
{ {
return 0; struct msghdr msg;
struct kvec iov;
size_t len = skb->len;
int ret;
iov.iov_base = skb->data;
iov.iov_len = len;
memset(&msg, 0, sizeof(msg));
ret = kernel_sendmsg(dev->socket, &msg, &iov, 1, len);
return ret == len ? NETDEV_TX_OK : NETDEV_TX_BUSY;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -258,7 +291,7 @@ int offer_device( ...@@ -258,7 +291,7 @@ int offer_device(
return ret; return ret;
} }
if (ec_gen_device_offer(gendev)) { if (ec_gen_device_offer(gendev, netdev)) {
list_add_tail(&gendev->list, &generic_devices); list_add_tail(&gendev->list, &generic_devices);
} else { } else {
ec_gen_device_clear(gendev); ec_gen_device_clear(gendev);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment