1 /**************************************************************** |
1 /****************************************************************************** |
2 * |
2 * |
3 * e c _ d e v i c e . c |
3 * e c _ d e v i c e . c |
4 * |
4 * |
5 * Methoden für ein EtherCAT-Gerät. |
5 * Methoden für ein EtherCAT-Gerät. |
6 * |
6 * |
7 * $Date$ |
7 * $Id$ |
8 * $Author$ |
|
9 * |
8 * |
10 ***************************************************************/ |
9 *****************************************************************************/ |
11 |
10 |
12 #include <linux/module.h> |
11 #include <linux/module.h> |
13 #include <linux/skbuff.h> |
12 #include <linux/skbuff.h> |
14 #include <linux/if_ether.h> |
13 #include <linux/if_ether.h> |
15 #include <linux/netdevice.h> |
14 #include <linux/netdevice.h> |
16 #include <linux/delay.h> |
15 #include <linux/delay.h> |
17 |
16 |
18 #include "ec_device.h" |
17 #include "ec_device.h" |
19 |
18 |
20 /***************************************************************/ |
19 /*****************************************************************************/ |
21 |
20 |
22 /** |
21 /** |
23 EtherCAT-Geräte-Konstuktor. |
22 EtherCAT-Geräte-Konstuktor. |
24 |
23 |
25 Initialisiert ein EtherCAT-Gerät, indem es die Variablen |
24 Initialisiert ein EtherCAT-Gerät, indem es die Variablen |
88 */ |
86 */ |
89 |
87 |
90 int EtherCAT_device_assign(EtherCAT_device_t *ecd, |
88 int EtherCAT_device_assign(EtherCAT_device_t *ecd, |
91 struct net_device *dev) |
89 struct net_device *dev) |
92 { |
90 { |
93 if (!dev) |
91 if (!dev) { |
94 { |
|
95 printk("EtherCAT: Device is NULL!\n"); |
92 printk("EtherCAT: Device is NULL!\n"); |
96 return -1; |
93 return -1; |
97 } |
94 } |
98 |
95 |
99 if ((ecd->tx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) |
96 if ((ecd->tx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) { |
100 { |
|
101 printk(KERN_ERR "EtherCAT: Could not allocate device tx socket buffer!\n"); |
97 printk(KERN_ERR "EtherCAT: Could not allocate device tx socket buffer!\n"); |
102 return -1; |
98 return -1; |
103 } |
99 } |
104 |
100 |
105 if ((ecd->rx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) |
101 if ((ecd->rx_skb = dev_alloc_skb(ECAT_FRAME_BUFFER_SIZE)) == NULL) { |
106 { |
|
107 dev_kfree_skb(ecd->tx_skb); |
102 dev_kfree_skb(ecd->tx_skb); |
108 ecd->tx_skb = NULL; |
103 ecd->tx_skb = NULL; |
109 |
|
110 printk(KERN_ERR "EtherCAT: Could not allocate device rx socket buffer!\n"); |
104 printk(KERN_ERR "EtherCAT: Could not allocate device rx socket buffer!\n"); |
111 return -1; |
105 return -1; |
112 } |
106 } |
113 |
107 |
114 ecd->dev = dev; |
108 ecd->dev = dev; |
204 unsigned int length) |
195 unsigned int length) |
205 { |
196 { |
206 unsigned char *frame_data; |
197 unsigned char *frame_data; |
207 struct ethhdr *eth; |
198 struct ethhdr *eth; |
208 |
199 |
209 if (ecd->state == ECAT_DS_SENT) |
200 if (unlikely(ecd->state == ECAT_DS_SENT)) { |
210 { |
201 printk(KERN_WARNING "EtherCAT: Warning - Trying to send frame" |
211 printk(KERN_WARNING "EtherCAT: Trying to send frame while last was not received!\n"); |
202 " while last was not received!\n"); |
212 } |
203 } |
213 |
204 |
214 skb_trim(ecd->tx_skb, 0); // Clear transmit socket buffer |
205 // Clear transmit socket buffer and reserve |
215 skb_reserve(ecd->tx_skb, ETH_HLEN); // Reserve space for Ethernet-II header |
206 // space for Ethernet-II header |
|
207 skb_trim(ecd->tx_skb, 0); |
|
208 skb_reserve(ecd->tx_skb, ETH_HLEN); |
216 |
209 |
217 // Copy data to socket buffer |
210 // Copy data to socket buffer |
218 frame_data = skb_put(ecd->tx_skb, length); |
211 frame_data = skb_put(ecd->tx_skb, length); |
219 memcpy(frame_data, data, length); |
212 memcpy(frame_data, data, length); |
220 |
213 |
221 // Add Ethernet-II-Header |
214 // Add Ethernet-II-Header |
222 if ((eth = (struct ethhdr *) skb_push(ecd->tx_skb, ETH_HLEN)) == NULL) |
215 if (unlikely((eth = (struct ethhdr *) |
223 { |
216 skb_push(ecd->tx_skb, ETH_HLEN)) == NULL)) { |
224 printk(KERN_ERR "EtherCAT: device_send - Could not allocate Ethernet-II header!\n"); |
217 printk(KERN_ERR "EtherCAT: device_send -" |
225 return -1; |
218 " Could not allocate Ethernet-II header!\n"); |
226 } |
219 return -1; |
227 |
220 } |
228 eth->h_proto = htons(0x88A4); // Protocol type |
221 |
229 memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len); // Hardware address |
222 // Protocol type |
230 memset(eth->h_dest, 0xFF, ecd->dev->addr_len); // Broadcast address |
223 eth->h_proto = htons(0x88A4); |
|
224 // Hardware address |
|
225 memcpy(eth->h_source, ecd->dev->dev_addr, ecd->dev->addr_len); |
|
226 // Broadcast address |
|
227 memset(eth->h_dest, 0xFF, ecd->dev->addr_len); |
231 |
228 |
232 rdtscl(ecd->tx_time); // Get CPU cycles |
229 rdtscl(ecd->tx_time); // Get CPU cycles |
233 |
230 |
234 // Start sending of frame |
231 // Start sending of frame |
235 ecd->state = ECAT_DS_SENT; |
232 ecd->state = ECAT_DS_SENT; |
236 ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev); |
233 ecd->dev->hard_start_xmit(ecd->tx_skb, ecd->dev); |
237 |
234 |
238 return 0; |
235 return 0; |
239 } |
236 } |
240 |
237 |
241 /***************************************************************/ |
238 /*****************************************************************************/ |
242 |
239 |
243 /** |
240 /** |
244 Holt einen empfangenen Rahmen von der Netzwerkkarte. |
241 Holt einen empfangenen Rahmen von der Netzwerkkarte. |
245 |
242 |
246 Zuerst wird geprüft, ob überhaupt ein Rahmen empfangen |
243 Zuerst wird geprüft, ob überhaupt ein Rahmen empfangen |
247 wurde. Wenn ja, wird diesem mit Hilfe eines Spin-Locks |
244 wurde. Wenn ja, wird dieser in den angegebenen |
248 in den angegebenen Speicherbereich kopiert. |
245 Speicherbereich kopiert. |
249 |
246 |
250 @param ecd EtherCAT-Gerät |
247 @param ecd EtherCAT-Gerät |
251 @param data Zeiger auf den Speicherbereich, in den die |
248 @param data Zeiger auf den Speicherbereich, in den die |
252 empfangenen Daten kopiert werden sollen |
249 empfangenen Daten kopiert werden sollen |
253 |
250 |
255 */ |
252 */ |
256 |
253 |
257 int EtherCAT_device_receive(EtherCAT_device_t *ecd, |
254 int EtherCAT_device_receive(EtherCAT_device_t *ecd, |
258 unsigned char *data) |
255 unsigned char *data) |
259 { |
256 { |
260 if (ecd->state != ECAT_DS_RECEIVED) |
257 if (unlikely(ecd->state != ECAT_DS_RECEIVED)) { |
261 { |
258 if (likely(ecd->error_reported)) { |
262 printk(KERN_ERR "EtherCAT: receive - Nothing received!\n"); |
259 printk(KERN_ERR "EtherCAT: receive - Nothing received!\n"); |
263 return -1; |
260 ecd->error_reported = 1; |
264 } |
261 } |
265 |
262 return -1; |
266 if (ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE) |
263 } |
267 { |
264 |
268 printk(KERN_ERR "EtherCAT: receive - Reveived frame too long (%i Bytes)!\n", |
265 if (unlikely(ecd->rx_data_length > ECAT_FRAME_BUFFER_SIZE)) { |
269 ecd->rx_data_length); |
266 if (likely(ecd->error_reported)) { |
270 return -1; |
267 printk(KERN_ERR "EtherCAT: receive - " |
|
268 " Reveived frame too long (%i Bytes)!\n", |
|
269 ecd->rx_data_length); |
|
270 ecd->error_reported = 1; |
|
271 } |
|
272 return -1; |
|
273 } |
|
274 |
|
275 if (unlikely(ecd->error_reported)) { |
|
276 ecd->error_reported = 0; |
271 } |
277 } |
272 |
278 |
273 memcpy(data, ecd->rx_data, ecd->rx_data_length); |
279 memcpy(data, ecd->rx_data, ecd->rx_data_length); |
274 |
280 |
275 return ecd->rx_data_length; |
281 return ecd->rx_data_length; |
276 } |
282 } |
277 |
283 |
278 /***************************************************************/ |
284 /*****************************************************************************/ |
279 |
285 |
280 /** |
286 /** |
281 Ruft manuell die Interrupt-Routine der Netzwerkkarte auf. |
287 Ruft manuell die Interrupt-Routine der Netzwerkkarte auf. |
282 |
288 |
283 @param ecd EtherCAT-Gerät |
289 @param ecd EtherCAT-Gerät |
285 @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0 |
291 @return Anzahl der kopierten Bytes bei Erfolg, sonst < 0 |
286 */ |
292 */ |
287 |
293 |
288 void EtherCAT_device_call_isr(EtherCAT_device_t *ecd) |
294 void EtherCAT_device_call_isr(EtherCAT_device_t *ecd) |
289 { |
295 { |
290 if (ecd->isr) ecd->isr(0, ecd->dev, NULL); |
296 if (likely(ecd->isr)) ecd->isr(0, ecd->dev, NULL); |
291 } |
297 } |
292 |
298 |
293 /***************************************************************/ |
299 /*****************************************************************************/ |
294 |
300 |
295 /** |
301 /** |
296 Gibt alle Informationen über das Device-Objekt aus. |
302 Gibt alle Informationen über das Device-Objekt aus. |
297 |
303 |
298 @param ecd EtherCAT-Gerät |
304 @param ecd EtherCAT-Gerät |
302 { |
308 { |
303 printk(KERN_DEBUG "---EtherCAT device information begin---\n"); |
309 printk(KERN_DEBUG "---EtherCAT device information begin---\n"); |
304 |
310 |
305 if (ecd) |
311 if (ecd) |
306 { |
312 { |
307 printk(KERN_DEBUG "Assigned net_device: %X\n", (unsigned) ecd->dev); |
313 printk(KERN_DEBUG "Assigned net_device: %X\n", |
308 printk(KERN_DEBUG "Transmit socket buffer: %X\n", (unsigned) ecd->tx_skb); |
314 (unsigned) ecd->dev); |
309 printk(KERN_DEBUG "Receive socket buffer: %X\n", (unsigned) ecd->rx_skb); |
315 printk(KERN_DEBUG "Transmit socket buffer: %X\n", |
310 printk(KERN_DEBUG "Time of last transmission: %u\n", (unsigned) ecd->tx_time); |
316 (unsigned) ecd->tx_skb); |
311 printk(KERN_DEBUG "Time of last receive: %u\n", (unsigned) ecd->rx_time); |
317 printk(KERN_DEBUG "Receive socket buffer: %X\n", |
312 printk(KERN_DEBUG "Number of transmit interrupts: %u\n", (unsigned) ecd->tx_intr_cnt); |
318 (unsigned) ecd->rx_skb); |
313 printk(KERN_DEBUG "Number of receive interrupts: %u\n", (unsigned) ecd->rx_intr_cnt); |
319 printk(KERN_DEBUG "Time of last transmission: %u\n", |
314 printk(KERN_DEBUG "Total Number of interrupts: %u\n", (unsigned) ecd->intr_cnt); |
320 (unsigned) ecd->tx_time); |
315 printk(KERN_DEBUG "Actual device state: %i\n", (int) ecd->state); |
321 printk(KERN_DEBUG "Time of last receive: %u\n", |
316 printk(KERN_DEBUG "Receive buffer: %X\n", (unsigned) ecd->rx_data); |
322 (unsigned) ecd->rx_time); |
|
323 printk(KERN_DEBUG "Number of transmit interrupts: %u\n", |
|
324 (unsigned) ecd->tx_intr_cnt); |
|
325 printk(KERN_DEBUG "Number of receive interrupts: %u\n", |
|
326 (unsigned) ecd->rx_intr_cnt); |
|
327 printk(KERN_DEBUG "Total Number of interrupts: %u\n", |
|
328 (unsigned) ecd->intr_cnt); |
|
329 printk(KERN_DEBUG "Actual device state: %i\n", |
|
330 (int) ecd->state); |
|
331 printk(KERN_DEBUG "Receive buffer: %X\n", |
|
332 (unsigned) ecd->rx_data); |
317 printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n", |
333 printk(KERN_DEBUG "Receive buffer fill state: %u/%u\n", |
318 (unsigned) ecd->rx_data_length, ECAT_FRAME_BUFFER_SIZE); |
334 (unsigned) ecd->rx_data_length, ECAT_FRAME_BUFFER_SIZE); |
319 } |
335 } |
320 else |
336 else |
321 { |
337 { |
323 } |
339 } |
324 |
340 |
325 printk(KERN_DEBUG "---EtherCAT device information end---\n"); |
341 printk(KERN_DEBUG "---EtherCAT device information end---\n"); |
326 } |
342 } |
327 |
343 |
328 /***************************************************************/ |
344 /*****************************************************************************/ |
329 |
345 |
330 EXPORT_SYMBOL(EtherCAT_device_init); |
346 EXPORT_SYMBOL(EtherCAT_device_init); |
331 EXPORT_SYMBOL(EtherCAT_device_clear); |
347 EXPORT_SYMBOL(EtherCAT_device_clear); |
332 EXPORT_SYMBOL(EtherCAT_device_assign); |
348 EXPORT_SYMBOL(EtherCAT_device_assign); |
333 EXPORT_SYMBOL(EtherCAT_device_open); |
349 EXPORT_SYMBOL(EtherCAT_device_open); |
334 EXPORT_SYMBOL(EtherCAT_device_close); |
350 EXPORT_SYMBOL(EtherCAT_device_close); |
335 |
351 |
336 /***************************************************************/ |
352 /*****************************************************************************/ |