devices/generic.c
changeset 1541 26ac1c611100
parent 1540 49430a3fe73d
child 1542 91ae9c95dd2e
equal deleted inserted replaced
1540:49430a3fe73d 1541:26ac1c611100
    43 #include "../globals.h"
    43 #include "../globals.h"
    44 #include "ecdev.h"
    44 #include "ecdev.h"
    45 
    45 
    46 #define PFX "ec_generic: "
    46 #define PFX "ec_generic: "
    47 
    47 
       
    48 #define ETH_P_ETHERCAT 0x88A4
       
    49 
    48 /*****************************************************************************/
    50 /*****************************************************************************/
    49 
    51 
    50 int __init ec_gen_init_module(void);
    52 int __init ec_gen_init_module(void);
    51 void __exit ec_gen_cleanup_module(void);
    53 void __exit ec_gen_cleanup_module(void);
    52 
    54 
    64 struct list_head generic_devices;
    66 struct list_head generic_devices;
    65 
    67 
    66 typedef struct {
    68 typedef struct {
    67     struct list_head list;
    69     struct list_head list;
    68     struct net_device *netdev;
    70     struct net_device *netdev;
    69 #if 0
    71     struct socket *socket;
    70     struct net_device *real_netdev;
       
    71 #endif
       
    72     ec_device_t *ecdev;
    72     ec_device_t *ecdev;
    73 } ec_gen_device_t;
    73 } ec_gen_device_t;
    74 
    74 
    75 int ec_gen_device_open(ec_gen_device_t *);
    75 int ec_gen_device_open(ec_gen_device_t *);
    76 int ec_gen_device_stop(ec_gen_device_t *);
    76 int ec_gen_device_stop(ec_gen_device_t *);
   128 {
   128 {
   129     ec_gen_device_t **priv;
   129     ec_gen_device_t **priv;
   130     char null = 0x00;
   130     char null = 0x00;
   131 
   131 
   132     dev->ecdev = NULL;
   132     dev->ecdev = NULL;
   133 #if 0
   133     dev->socket = NULL;
   134     dev->real_netdev = real_netdev;
       
   135 #endif
       
   136 
   134 
   137 	dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, ether_setup);
   135 	dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, ether_setup);
   138 	if (!dev->netdev) {
   136 	if (!dev->netdev) {
   139 		return -ENOMEM;
   137 		return -ENOMEM;
   140 	}
   138 	}
   156 {
   154 {
   157     if (dev->ecdev) {
   155     if (dev->ecdev) {
   158         ecdev_close(dev->ecdev);
   156         ecdev_close(dev->ecdev);
   159         ecdev_withdraw(dev->ecdev);
   157         ecdev_withdraw(dev->ecdev);
   160     }
   158     }
       
   159     if (dev->socket) {
       
   160         sock_release(dev->socket);
       
   161     }
   161     free_netdev(dev->netdev);
   162     free_netdev(dev->netdev);
   162 }
   163 }
   163 
   164 
   164 /*****************************************************************************/
   165 /*****************************************************************************/
   165 
   166 
       
   167 /** Creates a network socket.
       
   168  */
       
   169 int ec_gen_device_create_socket(
       
   170         ec_gen_device_t *dev,
       
   171         struct net_device *real_netdev
       
   172         )
       
   173 {
       
   174     int ret;
       
   175     struct sockaddr_ll sa;
       
   176 
       
   177     ret = sock_create_kern(PF_PACKET, SOCK_RAW, htons(ETH_P_ETHERCAT), &dev->socket);
       
   178     if (ret) {
       
   179         printk(KERN_ERR PFX "Failed to create socket.\n");
       
   180         return ret;
       
   181     }
       
   182 
       
   183     printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n",
       
   184             real_netdev->ifindex, real_netdev->name);
       
   185 
       
   186     memset(&sa, 0x00, sizeof(sa));
       
   187     sa.sll_family = AF_PACKET;
       
   188     sa.sll_protocol = htons(ETH_P_ETHERCAT);
       
   189     sa.sll_ifindex = real_netdev->ifindex;
       
   190     ret = kernel_bind(dev->socket, (struct sockaddr *) &sa, sizeof(sa));
       
   191     if (ret) {
       
   192         printk(KERN_ERR PFX "Failed to bind() socket to interface.\n");
       
   193         sock_release(dev->socket);
       
   194         dev->socket = NULL;
       
   195         return ret;
       
   196     }
       
   197 
       
   198     return 0;
       
   199 }
       
   200 
       
   201 /*****************************************************************************/
       
   202 
   166 /** Offer generic device to master.
   203 /** Offer generic device to master.
   167  */
   204  */
   168 int ec_gen_device_offer(
   205 int ec_gen_device_offer(
   169         ec_gen_device_t *dev
   206         ec_gen_device_t *dev,
       
   207         struct net_device *real_netdev
   170         )
   208         )
   171 {
   209 {
   172     int ret = 0;
   210     int ret = 0;
   173 
   211 
   174 	dev->ecdev = ecdev_offer(dev->netdev, ec_gen_poll, THIS_MODULE);
   212 	dev->ecdev = ecdev_offer(dev->netdev, ec_gen_poll, THIS_MODULE);
   175     if (dev->ecdev) {
   213     if (dev->ecdev) {
   176         if (ecdev_open(dev->ecdev)) {
   214         if (ec_gen_device_create_socket(dev, real_netdev)) {
       
   215             ecdev_withdraw(dev->ecdev);
       
   216             dev->ecdev = NULL;
       
   217         } else if (ecdev_open(dev->ecdev)) {
   177             ecdev_withdraw(dev->ecdev);
   218             ecdev_withdraw(dev->ecdev);
   178             dev->ecdev = NULL;
   219             dev->ecdev = NULL;
   179         } else {
   220         } else {
       
   221             ecdev_set_link(dev->ecdev, 1); // FIXME
   180             ret = 1;
   222             ret = 1;
   181         }
   223         }
   182     }
   224     }
   183 
   225 
   184     return ret;
   226     return ret;
   190  */
   232  */
   191 int ec_gen_device_open(
   233 int ec_gen_device_open(
   192         ec_gen_device_t *dev
   234         ec_gen_device_t *dev
   193         )
   235         )
   194 {
   236 {
   195     int ret = 0;
   237     return 0;
   196 
       
   197 #if 0
       
   198 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
       
   199     ret = dev->real_netdev->netdev_ops->ndo_open(dev->real_netdev);
       
   200 #else
       
   201     ret = dev->real_netdev->open(dev->real_netdev);
       
   202 #endif
       
   203 #endif
       
   204 
       
   205     return ret;
       
   206 }
   238 }
   207 
   239 
   208 /*****************************************************************************/
   240 /*****************************************************************************/
   209 
   241 
   210 /** Stop the device.
   242 /** Stop the device.
   211  */
   243  */
   212 int ec_gen_device_stop(
   244 int ec_gen_device_stop(
   213         ec_gen_device_t *dev
   245         ec_gen_device_t *dev
   214         )
   246         )
   215 {
   247 {
   216     int ret = 0;
   248     return 0;
   217 
       
   218 #if 0
       
   219 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
       
   220     ret = dev->real_netdev->netdev_ops->ndo_stop(dev->real_netdev);
       
   221 #else
       
   222     ret = dev->real_netdev->stop(dev->real_netdev);
       
   223 #endif
       
   224 #endif
       
   225 
       
   226     return ret;
       
   227 }
   249 }
   228 
   250 
   229 /*****************************************************************************/
   251 /*****************************************************************************/
   230 
   252 
   231 int ec_gen_device_start_xmit(
   253 int ec_gen_device_start_xmit(
   232         ec_gen_device_t *dev,
   254         ec_gen_device_t *dev,
   233         struct sk_buff *skb
   255         struct sk_buff *skb
   234         )
   256         )
   235 {
   257 {
   236     return 0;
   258     struct msghdr msg;
       
   259     struct kvec iov;
       
   260     size_t len = skb->len;
       
   261     int ret;
       
   262 
       
   263     iov.iov_base = skb->data;
       
   264     iov.iov_len = len;
       
   265     memset(&msg, 0, sizeof(msg));
       
   266 
       
   267     ret = kernel_sendmsg(dev->socket, &msg, &iov, 1, len);
       
   268 
       
   269     return ret == len ? NETDEV_TX_OK : NETDEV_TX_BUSY;
   237 }
   270 }
   238 
   271 
   239 /*****************************************************************************/
   272 /*****************************************************************************/
   240 
   273 
   241 /** Offer device.
   274 /** Offer device.
   256     if (ret) {
   289     if (ret) {
   257         kfree(gendev);
   290         kfree(gendev);
   258         return ret;
   291         return ret;
   259     }
   292     }
   260 
   293 
   261     if (ec_gen_device_offer(gendev)) {
   294     if (ec_gen_device_offer(gendev, netdev)) {
   262         list_add_tail(&gendev->list, &generic_devices);
   295         list_add_tail(&gendev->list, &generic_devices);
   263     } else {
   296     } else {
   264         ec_gen_device_clear(gendev);
   297         ec_gen_device_clear(gendev);
   265         kfree(gendev);
   298         kfree(gendev);
   266     }
   299     }