69 struct list_head list; |
69 struct list_head list; |
70 struct net_device *netdev; |
70 struct net_device *netdev; |
71 struct socket *socket; |
71 struct socket *socket; |
72 ec_device_t *ecdev; |
72 ec_device_t *ecdev; |
73 } ec_gen_device_t; |
73 } ec_gen_device_t; |
|
74 |
|
75 typedef struct { |
|
76 struct list_head list; |
|
77 char name[IFNAMSIZ]; |
|
78 int ifindex; |
|
79 uint8_t dev_addr[ETH_ALEN]; |
|
80 } ec_gen_interface_desc_t; |
74 |
81 |
75 int ec_gen_device_open(ec_gen_device_t *); |
82 int ec_gen_device_open(ec_gen_device_t *); |
76 int ec_gen_device_stop(ec_gen_device_t *); |
83 int ec_gen_device_stop(ec_gen_device_t *); |
77 int ec_gen_device_start_xmit(ec_gen_device_t *, struct sk_buff *); |
84 int ec_gen_device_start_xmit(ec_gen_device_t *, struct sk_buff *); |
78 void ec_gen_device_poll(ec_gen_device_t *); |
85 void ec_gen_device_poll(ec_gen_device_t *); |
125 /*****************************************************************************/ |
132 /*****************************************************************************/ |
126 |
133 |
127 /** Init generic device. |
134 /** Init generic device. |
128 */ |
135 */ |
129 int ec_gen_device_init( |
136 int ec_gen_device_init( |
130 ec_gen_device_t *dev, |
137 ec_gen_device_t *dev |
131 struct net_device *real_netdev |
|
132 ) |
138 ) |
133 { |
139 { |
134 ec_gen_device_t **priv; |
140 ec_gen_device_t **priv; |
135 char null = 0x00; |
141 char null = 0x00; |
136 |
142 |
139 |
145 |
140 dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, ether_setup); |
146 dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, ether_setup); |
141 if (!dev->netdev) { |
147 if (!dev->netdev) { |
142 return -ENOMEM; |
148 return -ENOMEM; |
143 } |
149 } |
144 memcpy(dev->netdev->dev_addr, real_netdev->dev_addr, ETH_ALEN); |
|
145 |
150 |
146 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) |
151 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) |
147 dev->netdev->netdev_ops = &ec_gen_netdev_ops; |
152 dev->netdev->netdev_ops = &ec_gen_netdev_ops; |
148 #else |
153 #else |
149 dev->netdev->open = ec_gen_netdev_open; |
154 dev->netdev->open = ec_gen_netdev_open; |
179 |
184 |
180 /** Creates a network socket. |
185 /** Creates a network socket. |
181 */ |
186 */ |
182 int ec_gen_device_create_socket( |
187 int ec_gen_device_create_socket( |
183 ec_gen_device_t *dev, |
188 ec_gen_device_t *dev, |
184 struct net_device *real_netdev |
189 ec_gen_interface_desc_t *desc |
185 ) |
190 ) |
186 { |
191 { |
187 int ret; |
192 int ret; |
188 struct sockaddr_ll sa; |
193 struct sockaddr_ll sa; |
189 |
194 |
192 printk(KERN_ERR PFX "Failed to create socket.\n"); |
197 printk(KERN_ERR PFX "Failed to create socket.\n"); |
193 return ret; |
198 return ret; |
194 } |
199 } |
195 |
200 |
196 printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n", |
201 printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n", |
197 real_netdev->ifindex, real_netdev->name); |
202 desc->ifindex, desc->name); |
198 |
203 |
199 memset(&sa, 0x00, sizeof(sa)); |
204 memset(&sa, 0x00, sizeof(sa)); |
200 sa.sll_family = AF_PACKET; |
205 sa.sll_family = AF_PACKET; |
201 sa.sll_protocol = htons(ETH_P_ETHERCAT); |
206 sa.sll_protocol = htons(ETH_P_ETHERCAT); |
202 sa.sll_ifindex = real_netdev->ifindex; |
207 sa.sll_ifindex = desc->ifindex; |
203 ret = kernel_bind(dev->socket, (struct sockaddr *) &sa, sizeof(sa)); |
208 ret = kernel_bind(dev->socket, (struct sockaddr *) &sa, sizeof(sa)); |
204 if (ret) { |
209 if (ret) { |
205 printk(KERN_ERR PFX "Failed to bind() socket to interface.\n"); |
210 printk(KERN_ERR PFX "Failed to bind() socket to interface.\n"); |
206 sock_release(dev->socket); |
211 sock_release(dev->socket); |
207 dev->socket = NULL; |
212 dev->socket = NULL; |
215 |
220 |
216 /** Offer generic device to master. |
221 /** Offer generic device to master. |
217 */ |
222 */ |
218 int ec_gen_device_offer( |
223 int ec_gen_device_offer( |
219 ec_gen_device_t *dev, |
224 ec_gen_device_t *dev, |
220 struct net_device *real_netdev |
225 ec_gen_interface_desc_t *desc |
221 ) |
226 ) |
222 { |
227 { |
223 int ret = 0; |
228 int ret = 0; |
|
229 |
|
230 memcpy(dev->netdev->dev_addr, desc->dev_addr, ETH_ALEN); |
224 |
231 |
225 dev->ecdev = ecdev_offer(dev->netdev, ec_gen_poll, THIS_MODULE); |
232 dev->ecdev = ecdev_offer(dev->netdev, ec_gen_poll, THIS_MODULE); |
226 if (dev->ecdev) { |
233 if (dev->ecdev) { |
227 if (ec_gen_device_create_socket(dev, real_netdev)) { |
234 if (ec_gen_device_create_socket(dev, desc)) { |
228 ecdev_withdraw(dev->ecdev); |
235 ecdev_withdraw(dev->ecdev); |
229 dev->ecdev = NULL; |
236 dev->ecdev = NULL; |
230 } else if (ecdev_open(dev->ecdev)) { |
237 } else if (ecdev_open(dev->ecdev)) { |
231 ecdev_withdraw(dev->ecdev); |
238 ecdev_withdraw(dev->ecdev); |
232 dev->ecdev = NULL; |
239 dev->ecdev = NULL; |
314 /*****************************************************************************/ |
321 /*****************************************************************************/ |
315 |
322 |
316 /** Offer device. |
323 /** Offer device. |
317 */ |
324 */ |
318 int offer_device( |
325 int offer_device( |
319 struct net_device *netdev |
326 ec_gen_interface_desc_t *desc |
320 ) |
327 ) |
321 { |
328 { |
322 ec_gen_device_t *gendev; |
329 ec_gen_device_t *gendev; |
323 int ret = 0; |
330 int ret = 0; |
324 |
331 |
325 gendev = kmalloc(sizeof(ec_gen_device_t), GFP_KERNEL); |
332 gendev = kmalloc(sizeof(ec_gen_device_t), GFP_KERNEL); |
326 if (!gendev) { |
333 if (!gendev) { |
327 return -ENOMEM; |
334 return -ENOMEM; |
328 } |
335 } |
329 |
336 |
330 ret = ec_gen_device_init(gendev, netdev); |
337 ret = ec_gen_device_init(gendev); |
331 if (ret) { |
338 if (ret) { |
332 kfree(gendev); |
339 kfree(gendev); |
333 return ret; |
340 return ret; |
334 } |
341 } |
335 |
342 |
336 if (ec_gen_device_offer(gendev, netdev)) { |
343 if (ec_gen_device_offer(gendev, desc)) { |
337 list_add_tail(&gendev->list, &generic_devices); |
344 list_add_tail(&gendev->list, &generic_devices); |
338 } else { |
345 } else { |
339 ec_gen_device_clear(gendev); |
346 ec_gen_device_clear(gendev); |
340 kfree(gendev); |
347 kfree(gendev); |
341 } |
348 } |
366 * \return 0 on success, else < 0 |
373 * \return 0 on success, else < 0 |
367 */ |
374 */ |
368 int __init ec_gen_init_module(void) |
375 int __init ec_gen_init_module(void) |
369 { |
376 { |
370 int ret = 0; |
377 int ret = 0; |
|
378 struct list_head descs; |
371 struct net_device *netdev; |
379 struct net_device *netdev; |
|
380 ec_gen_interface_desc_t *desc, *next; |
372 |
381 |
373 printk(KERN_INFO PFX "EtherCAT master generic Ethernet device module %s\n", |
382 printk(KERN_INFO PFX "EtherCAT master generic Ethernet device module %s\n", |
374 EC_MASTER_VERSION); |
383 EC_MASTER_VERSION); |
375 |
384 |
376 INIT_LIST_HEAD(&generic_devices); |
385 INIT_LIST_HEAD(&generic_devices); |
|
386 INIT_LIST_HEAD(&descs); |
377 |
387 |
378 read_lock(&dev_base_lock); |
388 read_lock(&dev_base_lock); |
379 for_each_netdev(&init_net, netdev) { |
389 for_each_netdev(&init_net, netdev) { |
380 if (netdev->type != ARPHRD_ETHER) |
390 if (netdev->type != ARPHRD_ETHER) |
381 continue; |
391 continue; |
382 ret = offer_device(netdev); |
392 desc = kmalloc(sizeof(ec_gen_interface_desc_t), GFP_KERNEL); |
383 if (ret) { |
393 if (!desc) { |
|
394 ret = -ENOMEM; |
384 read_unlock(&dev_base_lock); |
395 read_unlock(&dev_base_lock); |
385 goto out_err; |
396 goto out_err; |
386 } |
397 } |
|
398 strncpy(desc->name, netdev->name, IFNAMSIZ); |
|
399 desc->ifindex = netdev->ifindex; |
|
400 memcpy(desc->dev_addr, netdev->dev_addr, ETH_ALEN); |
|
401 list_add_tail(&desc->list, &descs); |
387 } |
402 } |
388 read_unlock(&dev_base_lock); |
403 read_unlock(&dev_base_lock); |
|
404 |
|
405 list_for_each_entry_safe(desc, next, &descs, list) { |
|
406 ret = offer_device(desc); |
|
407 if (ret) { |
|
408 goto out_err; |
|
409 } |
|
410 kfree(desc); |
|
411 } |
389 return ret; |
412 return ret; |
390 |
413 |
391 out_err: |
414 out_err: |
|
415 list_for_each_entry_safe(desc, next, &descs, list) { |
|
416 list_del(&desc->list); |
|
417 kfree(desc); |
|
418 } |
392 clear_devices(); |
419 clear_devices(); |
393 return ret; |
420 return ret; |
394 } |
421 } |
395 |
422 |
396 /*****************************************************************************/ |
423 /*****************************************************************************/ |