46 #include "master.h" |
46 #include "master.h" |
47 #include "device.h" |
47 #include "device.h" |
48 |
48 |
49 /*****************************************************************************/ |
49 /*****************************************************************************/ |
50 |
50 |
|
51 #define MAX_MASTERS 5 /**< maximum number of masters */ |
|
52 |
|
53 /*****************************************************************************/ |
|
54 |
51 int __init ec_init_module(void); |
55 int __init ec_init_module(void); |
52 void __exit ec_cleanup_module(void); |
56 void __exit ec_cleanup_module(void); |
53 |
57 |
54 /*****************************************************************************/ |
58 static int ec_mac_parse(uint8_t *, const char *, int); |
55 |
59 |
56 static int ec_master_count = 1; /**< parameter value, number of masters */ |
60 /*****************************************************************************/ |
57 static int ec_eoeif_count = 0; /**< parameter value, number of EoE interf. */ |
61 |
58 static struct list_head ec_masters; /**< list of masters */ |
62 struct kobject kobj; /**< kobject for master module */ |
|
63 |
|
64 static char *main[MAX_MASTERS]; /**< main devices parameter */ |
|
65 static char *backup[MAX_MASTERS]; /**< backup devices parameter */ |
|
66 |
|
67 static ec_master_t *masters; /**< master array */ |
|
68 static struct semaphore master_sem; /**< master semaphore */ |
|
69 static unsigned int master_count; /**< number of masters */ |
|
70 static unsigned int backup_count; /**< number of backup devices */ |
|
71 |
|
72 static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses */ |
59 |
73 |
60 char *ec_master_version_str = EC_MASTER_VERSION; |
74 char *ec_master_version_str = EC_MASTER_VERSION; |
61 |
75 |
62 /*****************************************************************************/ |
76 /*****************************************************************************/ |
63 |
77 |
64 /** \cond */ |
78 /** \cond */ |
65 |
|
66 module_param(ec_master_count, int, S_IRUGO); |
|
67 module_param(ec_eoeif_count, int, S_IRUGO); |
|
68 |
79 |
69 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>"); |
80 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>"); |
70 MODULE_DESCRIPTION("EtherCAT master driver module"); |
81 MODULE_DESCRIPTION("EtherCAT master driver module"); |
71 MODULE_LICENSE("GPL"); |
82 MODULE_LICENSE("GPL"); |
72 MODULE_VERSION(EC_MASTER_VERSION); |
83 MODULE_VERSION(EC_MASTER_VERSION); |
73 MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize"); |
84 |
74 MODULE_PARM_DESC(ec_eoeif_count, "number of EoE interfaces per master"); |
85 module_param_array(main, charp, &master_count, S_IRUGO); |
|
86 MODULE_PARM_DESC(main, "MAC addresses of main devices"); |
|
87 module_param_array(backup, charp, &backup_count, S_IRUGO); |
|
88 MODULE_PARM_DESC(backup, "MAC addresses of backup devices"); |
75 |
89 |
76 /** \endcond */ |
90 /** \endcond */ |
77 |
91 |
78 /*****************************************************************************/ |
92 /*****************************************************************************/ |
79 |
93 |
80 /** |
94 /** |
81 Module initialization. |
95 * Module initialization. |
82 Initializes \a ec_master_count masters. |
96 * Initializes \a ec_master_count masters. |
83 \return 0 on success, else < 0 |
97 * \return 0 on success, else < 0 |
84 */ |
98 */ |
85 |
99 |
86 int __init ec_init_module(void) |
100 int __init ec_init_module(void) |
87 { |
101 { |
88 unsigned int i; |
102 int i, ret = 0; |
89 ec_master_t *master, *next; |
|
90 |
103 |
91 EC_INFO("Master driver %s\n", EC_MASTER_VERSION); |
104 EC_INFO("Master driver %s\n", EC_MASTER_VERSION); |
92 |
105 |
93 if (ec_master_count < 1) { |
106 init_MUTEX(&master_sem); |
94 EC_ERR("Error - Invalid ec_master_count: %i\n", ec_master_count); |
107 |
95 goto out_return; |
108 // init kobject and add it to the hierarchy |
96 } |
109 memset(&kobj, 0x00, sizeof(struct kobject)); |
97 |
110 kobject_init(&kobj); // no ktype |
98 EC_INFO("Initializing %i EtherCAT master(s)...\n", ec_master_count); |
111 |
99 |
112 if (kobject_set_name(&kobj, "ethercat")) { |
100 INIT_LIST_HEAD(&ec_masters); |
113 EC_ERR("Failed to set module kobject name.\n"); |
101 |
114 ret = -ENOMEM; |
102 for (i = 0; i < ec_master_count; i++) { |
115 goto out_put; |
103 if (!(master = |
116 } |
104 (ec_master_t *) kmalloc(sizeof(ec_master_t), GFP_KERNEL))) { |
117 |
105 EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", i); |
118 if (kobject_add(&kobj)) { |
106 goto out_free; |
119 EC_ERR("Failed to add module kobject.\n"); |
107 } |
120 ret = -EEXIST; |
108 |
121 goto out_put; |
109 if (ec_master_init(master, i, ec_eoeif_count)) |
122 } |
110 goto out_free; |
123 |
111 |
124 // zero MAC addresses |
112 list_add_tail(&master->list, &ec_masters); |
125 memset(macs, 0x00, sizeof(uint8_t) * MAX_MASTERS * 2 * ETH_ALEN); |
113 } |
126 |
114 |
127 // process MAC parameters |
115 EC_INFO("Master driver initialized.\n"); |
128 for (i = 0; i < master_count; i++) { |
116 return 0; |
129 if (ec_mac_parse(macs[i][0], main[i], 0)) { |
117 |
130 ret = -EINVAL; |
118 out_free: |
131 goto out_del; |
119 list_for_each_entry_safe(master, next, &ec_masters, list) { |
132 } |
120 list_del(&master->list); |
133 |
121 kobject_del(&master->kobj); |
134 if (i < backup_count && ec_mac_parse(macs[i][1], backup[i], 1)) { |
122 kobject_put(&master->kobj); |
135 ret = -EINVAL; |
123 } |
136 goto out_del; |
124 out_return: |
137 } |
125 return -1; |
138 } |
|
139 |
|
140 if (master_count) { |
|
141 if (!(masters = kmalloc(sizeof(ec_master_t) * master_count, |
|
142 GFP_KERNEL))) { |
|
143 EC_ERR("Failed to allocate memory for EtherCAT masters.\n"); |
|
144 ret = -ENOMEM; |
|
145 goto out_del; |
|
146 } |
|
147 } |
|
148 |
|
149 for (i = 0; i < master_count; i++) { |
|
150 if (ec_master_init(&masters[i], &kobj, i, macs[i][0], macs[i][1])) { |
|
151 ret = -EIO; |
|
152 goto out_free_masters; |
|
153 } |
|
154 } |
|
155 |
|
156 EC_INFO("%u master%s waiting for devices.\n", |
|
157 master_count, (master_count == 1 ? "" : "s")); |
|
158 return ret; |
|
159 |
|
160 out_free_masters: |
|
161 for (i--; i >= 0; i--) ec_master_clear(&masters[i]); |
|
162 kfree(masters); |
|
163 out_del: |
|
164 kobject_del(&kobj); |
|
165 out_put: |
|
166 kobject_put(&kobj); |
|
167 return ret; |
126 } |
168 } |
127 |
169 |
128 /*****************************************************************************/ |
170 /*****************************************************************************/ |
129 |
171 |
130 /** |
172 /** |
132 Clears all master instances. |
174 Clears all master instances. |
133 */ |
175 */ |
134 |
176 |
135 void __exit ec_cleanup_module(void) |
177 void __exit ec_cleanup_module(void) |
136 { |
178 { |
137 ec_master_t *master, *next; |
179 unsigned int i; |
138 |
180 |
139 EC_INFO("Cleaning up master driver...\n"); |
181 for (i = 0; i < master_count; i++) { |
140 |
182 ec_master_clear(&masters[i]); |
141 list_for_each_entry_safe(master, next, &ec_masters, list) { |
183 } |
142 list_del(&master->list); |
184 if (master_count) |
143 ec_master_destroy(master); |
185 kfree(masters); |
144 } |
186 |
145 |
187 kobject_del(&kobj); |
146 EC_INFO("Master driver cleaned up.\n"); |
188 kobject_put(&kobj); |
147 } |
189 |
148 |
190 EC_INFO("Master module cleaned up.\n"); |
149 /*****************************************************************************/ |
191 } |
150 |
192 |
151 /** |
193 /***************************************************************************** |
152 Gets a handle to a certain master. |
194 * MAC address functions |
153 \returns pointer to master |
195 ****************************************************************************/ |
154 */ |
196 |
155 |
197 int ec_mac_equal(const uint8_t *mac1, const uint8_t *mac2) |
156 ec_master_t *ec_find_master(unsigned int master_index /**< master index */) |
198 { |
157 { |
199 unsigned int i; |
158 ec_master_t *master; |
200 |
159 |
201 for (i = 0; i < ETH_ALEN; i++) |
160 list_for_each_entry(master, &ec_masters, list) { |
202 if (mac1[i] != mac2[i]) |
161 if (master->index == master_index) return master; |
203 return 0; |
162 } |
204 |
163 |
205 return 1; |
164 EC_ERR("Master %i does not exist!\n", master_index); |
206 } |
165 return NULL; |
207 |
|
208 /*****************************************************************************/ |
|
209 |
|
210 ssize_t ec_mac_print(const uint8_t *mac, char *buffer) |
|
211 { |
|
212 off_t off = 0; |
|
213 unsigned int i; |
|
214 |
|
215 for (i = 0; i < ETH_ALEN; i++) { |
|
216 off += sprintf(buffer + off, "%02X", mac[i]); |
|
217 if (i < ETH_ALEN - 1) off += sprintf(buffer + off, ":"); |
|
218 } |
|
219 |
|
220 return off; |
|
221 } |
|
222 |
|
223 /*****************************************************************************/ |
|
224 |
|
225 int ec_mac_is_zero(const uint8_t *mac) |
|
226 { |
|
227 unsigned int i; |
|
228 |
|
229 for (i = 0; i < ETH_ALEN; i++) |
|
230 if (mac[i]) |
|
231 return 0; |
|
232 |
|
233 return 1; |
|
234 } |
|
235 |
|
236 /*****************************************************************************/ |
|
237 |
|
238 int ec_mac_is_broadcast(const uint8_t *mac) |
|
239 { |
|
240 unsigned int i; |
|
241 |
|
242 for (i = 0; i < ETH_ALEN; i++) |
|
243 if (mac[i] != 0xff) |
|
244 return 0; |
|
245 |
|
246 return 1; |
|
247 } |
|
248 |
|
249 /*****************************************************************************/ |
|
250 |
|
251 static int ec_mac_parse(uint8_t *mac, const char *src, int allow_empty) |
|
252 { |
|
253 unsigned int i, value; |
|
254 const char *orig = src; |
|
255 char *rem; |
|
256 |
|
257 if (!strlen(src)) { |
|
258 if (allow_empty){ |
|
259 return 0; |
|
260 } |
|
261 else { |
|
262 EC_ERR("MAC address may not be empty.\n"); |
|
263 return -EINVAL; |
|
264 } |
|
265 } |
|
266 |
|
267 for (i = 0; i < ETH_ALEN; i++) { |
|
268 value = simple_strtoul(src, &rem, 16); |
|
269 if (rem != src + 2 |
|
270 || value > 0xFF |
|
271 || (i < ETH_ALEN - 1 && *rem != ':')) { |
|
272 EC_ERR("Invalid MAC address \"%s\".\n", orig); |
|
273 return -EINVAL; |
|
274 } |
|
275 mac[i] = value; |
|
276 if (i < ETH_ALEN - 1) |
|
277 src = rem + 1; // skip colon |
|
278 } |
|
279 |
|
280 return 0; |
166 } |
281 } |
167 |
282 |
168 /*****************************************************************************/ |
283 /*****************************************************************************/ |
169 |
284 |
170 /** |
285 /** |
261 /****************************************************************************** |
376 /****************************************************************************** |
262 * Device interface |
377 * Device interface |
263 *****************************************************************************/ |
378 *****************************************************************************/ |
264 |
379 |
265 /** |
380 /** |
266 Connects an EtherCAT device to a certain master. |
381 Offers an EtherCAT device to a certain master. |
267 The master will use the device for sending and receiving frames. It is |
382 The master decides, if it wants to use the device for EtherCAT operation, |
268 required that no other instance (for example the kernel IP stack) uses |
383 or not. It is important, that the offered net_device is not used by |
269 the device. |
384 the kernel IP stack. If the master, accepted the offer, the address of |
|
385 the newly created EtherCAT device is written to the ecdev pointer, else |
|
386 the pointer is written to zero. |
270 \return 0 on success, else < 0 |
387 \return 0 on success, else < 0 |
271 \ingroup DeviceInterface |
388 \ingroup DeviceInterface |
272 */ |
389 */ |
273 |
390 |
274 ec_device_t *ecdev_register(unsigned int master_index, /**< master index */ |
391 int ecdev_offer(struct net_device *net_dev, /**< net_device to offer */ |
275 struct net_device *net_dev, /**< net_device of |
392 ec_pollfunc_t poll, /**< device poll function */ |
276 the device */ |
393 struct module *module, /**< pointer to the module */ |
277 ec_pollfunc_t poll, /**< device poll function */ |
394 ec_device_t **ecdev /**< pointer to store a device on success */ |
278 struct module *module /**< pointer to the module */ |
395 ) |
279 ) |
|
280 { |
396 { |
281 ec_master_t *master; |
397 ec_master_t *master; |
282 |
398 char str[20]; |
283 if (!(master = ec_find_master(master_index))) return NULL; |
399 unsigned int i; |
284 |
400 |
285 if (down_interruptible(&master->device_sem)) { |
401 for (i = 0; i < master_count; i++) { |
286 EC_ERR("Interrupted while waiting for device!\n"); |
402 master = &masters[i]; |
287 goto out_return; |
403 |
288 } |
404 down(&master->device_sem); |
289 |
405 if (master->main_device.dev) { // master already has a device |
290 if (master->device) { |
406 up(&master->device_sem); |
291 EC_ERR("Master %i already has a device!\n", master_index); |
407 continue; |
292 goto out_up; |
408 } |
293 } |
409 |
294 |
410 if (ec_mac_equal(master->main_mac, net_dev->dev_addr) |
295 if (!(master->device = |
411 || ec_mac_is_broadcast(master->main_mac)) { |
296 (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) { |
412 ec_mac_print(net_dev->dev_addr, str); |
297 EC_ERR("Failed to allocate device!\n"); |
413 EC_INFO("Accepting device %s for master %u.\n", |
298 goto out_up; |
414 str, master->index); |
299 } |
415 |
300 |
416 ec_device_attach(&master->main_device, net_dev, poll, module); |
301 if (ec_device_init(master->device, master, net_dev, poll, module)) { |
417 up(&master->device_sem); |
302 EC_ERR("Failed to init device!\n"); |
418 |
303 goto out_free; |
419 sprintf(net_dev->name, "ec%u", master->index); |
304 } |
420 *ecdev = &master->main_device; // offer accepted |
305 |
421 return 0; // no error |
306 up(&master->device_sem); |
422 } |
307 return master->device; |
423 else { |
308 |
424 up(&master->device_sem); |
309 out_free: |
425 |
310 kfree(master->device); |
426 if (master->debug_level) { |
311 master->device = NULL; |
427 ec_mac_print(net_dev->dev_addr, str); |
312 out_up: |
428 EC_DBG("Master %u declined device %s.\n", master->index, str); |
313 up(&master->device_sem); |
429 } |
314 out_return: |
430 } |
315 return NULL; |
431 } |
316 } |
432 |
317 |
433 *ecdev = NULL; // offer declined |
318 /*****************************************************************************/ |
434 return 0; // no error |
319 |
435 } |
320 /** |
436 |
321 Disconnect an EtherCAT device from the master. |
437 /*****************************************************************************/ |
|
438 |
|
439 /** |
|
440 Withdraws an EtherCAT device from the master. |
322 The device is disconnected from the master and all device ressources |
441 The device is disconnected from the master and all device ressources |
323 are freed. |
442 are freed. |
324 \attention Before calling this function, the ecdev_stop() function has |
443 \attention Before calling this function, the ecdev_stop() function has |
325 to be called, to be sure that the master does not use the device any more. |
444 to be called, to be sure that the master does not use the device any more. |
326 \ingroup DeviceInterface |
445 \ingroup DeviceInterface |
327 */ |
446 */ |
328 |
447 |
329 void ecdev_unregister(unsigned int master_index, /**< master index */ |
448 void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */) |
330 ec_device_t *device /**< EtherCAT device */ |
449 { |
331 ) |
450 ec_master_t *master = device->master; |
332 { |
451 char str[20]; |
333 ec_master_t *master; |
452 |
334 |
453 ec_mac_print(device->dev->dev_addr, str); |
335 if (!(master = ec_find_master(master_index))) return; |
454 EC_INFO("Master %u releasing main device %s.\n", master->index, str); |
336 |
455 |
337 down(&master->device_sem); |
456 down(&master->device_sem); |
338 |
457 ec_device_detach(device); |
339 if (!master->device || master->device != device) { |
|
340 up(&master->device_sem); |
|
341 EC_WARN("Unable to unregister device!\n"); |
|
342 return; |
|
343 } |
|
344 |
|
345 ec_device_clear(master->device); |
|
346 kfree(master->device); |
|
347 master->device = NULL; |
|
348 |
|
349 up(&master->device_sem); |
458 up(&master->device_sem); |
350 } |
459 } |
351 |
460 |
352 /*****************************************************************************/ |
461 /*****************************************************************************/ |
353 |
462 |
415 /**< master index */ |
524 /**< master index */ |
416 ) |
525 ) |
417 { |
526 { |
418 ec_master_t *master; |
527 ec_master_t *master; |
419 |
528 |
420 EC_INFO("Requesting master %i...\n", master_index); |
529 EC_INFO("Requesting master %u...\n", master_index); |
421 |
530 |
422 if (!(master = ec_find_master(master_index))) goto out_return; |
531 if (master_index >= master_count) { |
423 |
532 EC_ERR("Invalid master index %u.\n", master_index); |
424 if (!atomic_dec_and_test(&master->available)) { |
|
425 atomic_inc(&master->available); |
|
426 EC_ERR("Master %i is already in use!\n", master_index); |
|
427 goto out_return; |
533 goto out_return; |
428 } |
534 } |
429 |
535 master = &masters[master_index]; |
430 if (down_interruptible(&master->device_sem)) { |
536 |
431 EC_ERR("Interrupted while waiting for device!\n"); |
537 down(&master_sem); |
|
538 if (master->reserved) { |
|
539 up(&master_sem); |
|
540 EC_ERR("Master %u is already in use!\n", master_index); |
|
541 goto out_return; |
|
542 } |
|
543 master->reserved = 1; |
|
544 up(&master_sem); |
|
545 |
|
546 down(&master->device_sem); |
|
547 |
|
548 if (master->mode != EC_MASTER_MODE_IDLE) { |
|
549 up(&master->device_sem); |
|
550 EC_ERR("Master %u still waiting for devices!\n", master_index); |
432 goto out_release; |
551 goto out_release; |
433 } |
552 } |
434 |
553 |
435 if (!master->device) { |
554 if (!try_module_get(master->main_device.module)) { |
436 up(&master->device_sem); |
|
437 EC_ERR("Master %i has no assigned device!\n", master_index); |
|
438 goto out_release; |
|
439 } |
|
440 |
|
441 if (!try_module_get(master->device->module)) { |
|
442 up(&master->device_sem); |
555 up(&master->device_sem); |
443 EC_ERR("Device module is unloading!\n"); |
556 EC_ERR("Device module is unloading!\n"); |
444 goto out_release; |
557 goto out_release; |
445 } |
558 } |
446 |
559 |
447 up(&master->device_sem); |
560 up(&master->device_sem); |
448 |
561 |
449 if (!master->device->link_state) { |
562 if (!master->main_device.link_state) { |
450 EC_ERR("Link is DOWN.\n"); |
563 EC_ERR("Link is DOWN.\n"); |
451 goto out_module_put; |
564 goto out_module_put; |
452 } |
565 } |
453 |
566 |
454 if (ec_master_enter_operation_mode(master)) { |
567 if (ec_master_enter_operation_mode(master)) { |
455 EC_ERR("Failed to enter OPERATION mode!\n"); |
568 EC_ERR("Failed to enter OPERATION mode!\n"); |
456 goto out_module_put; |
569 goto out_module_put; |
457 } |
570 } |
458 |
571 |
459 EC_INFO("Successfully requested master %i.\n", master_index); |
572 EC_INFO("Successfully requested master %u.\n", master_index); |
460 return master; |
573 return master; |
461 |
574 |
462 out_module_put: |
575 out_module_put: |
463 module_put(master->device->module); |
576 module_put(master->main_device.module); |
464 out_release: |
577 out_release: |
465 atomic_inc(&master->available); |
578 master->reserved = 0; |
466 out_return: |
579 out_return: |
467 return NULL; |
580 return NULL; |
468 } |
581 } |
469 |
582 |
470 /*****************************************************************************/ |
583 /*****************************************************************************/ |
474 \ingroup RealtimeInterface |
587 \ingroup RealtimeInterface |
475 */ |
588 */ |
476 |
589 |
477 void ecrt_release_master(ec_master_t *master /**< EtherCAT master */) |
590 void ecrt_release_master(ec_master_t *master /**< EtherCAT master */) |
478 { |
591 { |
479 EC_INFO("Releasing master %i...\n", master->index); |
592 EC_INFO("Releasing master %u...\n", master->index); |
480 |
593 |
481 if (master->mode != EC_MASTER_MODE_OPERATION) { |
594 if (master->mode != EC_MASTER_MODE_OPERATION) { |
482 EC_WARN("Master %i was was not requested!\n", master->index); |
595 EC_WARN("Master %u was was not requested!\n", master->index); |
483 return; |
596 return; |
484 } |
597 } |
485 |
598 |
486 ec_master_leave_operation_mode(master); |
599 ec_master_leave_operation_mode(master); |
487 |
600 |
488 module_put(master->device->module); |
601 module_put(master->main_device.module); |
489 atomic_inc(&master->available); |
602 master->reserved = 0; |
490 |
603 |
491 EC_INFO("Released master %i.\n", master->index); |
604 EC_INFO("Released master %u.\n", master->index); |
492 } |
605 } |
493 |
606 |
494 /*****************************************************************************/ |
607 /*****************************************************************************/ |
495 |
608 |
496 /** \cond */ |
609 /** \cond */ |
497 |
610 |
498 module_init(ec_init_module); |
611 module_init(ec_init_module); |
499 module_exit(ec_cleanup_module); |
612 module_exit(ec_cleanup_module); |
500 |
613 |
501 EXPORT_SYMBOL(ecdev_register); |
614 EXPORT_SYMBOL(ecdev_offer); |
502 EXPORT_SYMBOL(ecdev_unregister); |
615 EXPORT_SYMBOL(ecdev_withdraw); |
503 EXPORT_SYMBOL(ecdev_open); |
616 EXPORT_SYMBOL(ecdev_open); |
504 EXPORT_SYMBOL(ecdev_close); |
617 EXPORT_SYMBOL(ecdev_close); |
505 EXPORT_SYMBOL(ecrt_request_master); |
618 EXPORT_SYMBOL(ecrt_request_master); |
506 EXPORT_SYMBOL(ecrt_release_master); |
619 EXPORT_SYMBOL(ecrt_release_master); |
507 EXPORT_SYMBOL(ecrt_version_magic); |
620 EXPORT_SYMBOL(ecrt_version_magic); |