40 |
40 |
41 #include <linux/module.h> |
41 #include <linux/module.h> |
42 #include <linux/skbuff.h> |
42 #include <linux/skbuff.h> |
43 #include <linux/if_ether.h> |
43 #include <linux/if_ether.h> |
44 #include <linux/netdevice.h> |
44 #include <linux/netdevice.h> |
45 #include <linux/delay.h> |
|
46 |
45 |
47 #include "device.h" |
46 #include "device.h" |
48 #include "master.h" |
47 #include "master.h" |
49 |
48 |
|
49 #ifdef EC_DEBUG_RING |
|
50 #define timersub(a, b, result) \ |
|
51 do { \ |
|
52 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ |
|
53 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ |
|
54 if ((result)->tv_usec < 0) { \ |
|
55 --(result)->tv_sec; \ |
|
56 (result)->tv_usec += 1000000; \ |
|
57 } \ |
|
58 } while (0) |
|
59 #endif |
|
60 |
50 /*****************************************************************************/ |
61 /*****************************************************************************/ |
51 |
62 |
52 /** |
63 /** |
53 Device constructor. |
64 Device constructor. |
54 \return 0 in case of success, else < 0 |
65 \return 0 in case of success, else < 0 |
55 */ |
66 */ |
56 |
67 |
57 int ec_device_init(ec_device_t *device, /**< EtherCAT device */ |
68 int ec_device_init(ec_device_t *device, /**< EtherCAT device */ |
58 ec_master_t *master, /**< master owning the device */ |
69 ec_master_t *master /**< master owning the device */ |
59 struct net_device *net_dev, /**< net_device structure */ |
70 ) |
60 ec_pollfunc_t poll, /**< pointer to device's poll function */ |
71 { |
61 struct module *module /**< the device's module */ |
72 unsigned int i; |
62 ) |
|
63 { |
|
64 struct ethhdr *eth; |
73 struct ethhdr *eth; |
|
74 #ifdef EC_DEBUG_IF |
|
75 char ifname[10]; |
|
76 char mb = 'x'; |
|
77 #endif |
|
78 #ifdef EC_DEBUG_RING |
|
79 device->debug_frame_index = 0; |
|
80 device->debug_frame_count = 0; |
|
81 #endif |
65 |
82 |
66 device->master = master; |
83 device->master = master; |
|
84 device->tx_ring_index = 0; |
|
85 |
|
86 #ifdef EC_DEBUG_IF |
|
87 if (device == &master->main_device) |
|
88 mb = 'm'; |
|
89 else if (device == &master->backup_device) |
|
90 mb = 'b'; |
|
91 |
|
92 sprintf(ifname, "ecdbg%c%u", mb, master->index); |
|
93 |
|
94 if (ec_debug_init(&device->dbg, ifname)) { |
|
95 EC_ERR("Failed to init debug device!\n"); |
|
96 goto out_return; |
|
97 } |
|
98 #endif |
|
99 |
|
100 for (i = 0; i < EC_TX_RING_SIZE; i++) |
|
101 device->tx_skb[i] = NULL; |
|
102 |
|
103 for (i = 0; i < EC_TX_RING_SIZE; i++) { |
|
104 if (!(device->tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN))) { |
|
105 EC_ERR("Error allocating device socket buffer!\n"); |
|
106 goto out_tx_ring; |
|
107 } |
|
108 |
|
109 // add Ethernet-II-header |
|
110 skb_reserve(device->tx_skb[i], ETH_HLEN); |
|
111 eth = (struct ethhdr *) skb_push(device->tx_skb[i], ETH_HLEN); |
|
112 eth->h_proto = htons(0x88A4); |
|
113 memset(eth->h_dest, 0xFF, ETH_ALEN); |
|
114 } |
|
115 |
|
116 ec_device_detach(device); // resets remaining fields |
|
117 return 0; |
|
118 |
|
119 out_tx_ring: |
|
120 for (i = 0; i < EC_TX_RING_SIZE; i++) |
|
121 if (device->tx_skb[i]) |
|
122 dev_kfree_skb(device->tx_skb[i]); |
|
123 #ifdef EC_DEBUG_IF |
|
124 ec_debug_clear(&device->dbg); |
|
125 out_return: |
|
126 #endif |
|
127 return -1; |
|
128 } |
|
129 |
|
130 /*****************************************************************************/ |
|
131 |
|
132 /** |
|
133 EtherCAT device destuctor. |
|
134 */ |
|
135 |
|
136 void ec_device_clear(ec_device_t *device /**< EtherCAT device */) |
|
137 { |
|
138 unsigned int i; |
|
139 |
|
140 if (device->open) ec_device_close(device); |
|
141 for (i = 0; i < EC_TX_RING_SIZE; i++) |
|
142 dev_kfree_skb(device->tx_skb[i]); |
|
143 #ifdef EC_DEBUG_IF |
|
144 ec_debug_clear(&device->dbg); |
|
145 #endif |
|
146 } |
|
147 |
|
148 /*****************************************************************************/ |
|
149 |
|
150 /** |
|
151 Associate with net_device. |
|
152 */ |
|
153 |
|
154 void ec_device_attach(ec_device_t *device, /**< EtherCAT device */ |
|
155 struct net_device *net_dev, /**< net_device structure */ |
|
156 ec_pollfunc_t poll, /**< pointer to device's poll function */ |
|
157 struct module *module /**< the device's module */ |
|
158 ) |
|
159 { |
|
160 unsigned int i; |
|
161 struct ethhdr *eth; |
|
162 |
|
163 ec_device_detach(device); // resets fields |
|
164 |
67 device->dev = net_dev; |
165 device->dev = net_dev; |
68 device->poll = poll; |
166 device->poll = poll; |
69 device->module = module; |
167 device->module = module; |
70 |
168 |
|
169 for (i = 0; i < EC_TX_RING_SIZE; i++) { |
|
170 device->tx_skb[i]->dev = net_dev; |
|
171 eth = (struct ethhdr *) (device->tx_skb[i]->data + ETH_HLEN); |
|
172 memcpy(eth->h_source, net_dev->dev_addr, ETH_ALEN); |
|
173 } |
|
174 } |
|
175 |
|
176 /*****************************************************************************/ |
|
177 |
|
178 /** |
|
179 Disconnect from net_device. |
|
180 */ |
|
181 |
|
182 void ec_device_detach(ec_device_t *device /**< EtherCAT device */) |
|
183 { |
|
184 unsigned int i; |
|
185 |
|
186 device->dev = NULL; |
|
187 device->poll = NULL; |
|
188 device->module = NULL; |
71 device->open = 0; |
189 device->open = 0; |
72 device->link_state = 0; // down |
190 device->link_state = 0; // down |
73 |
|
74 device->tx_count = 0; |
191 device->tx_count = 0; |
75 device->rx_count = 0; |
192 device->rx_count = 0; |
76 |
193 for (i = 0; i < EC_TX_RING_SIZE; i++) |
77 #ifdef EC_DBG_IF |
194 device->tx_skb[i]->dev = NULL; |
78 if (ec_debug_init(&device->dbg)) { |
|
79 EC_ERR("Failed to init debug device!\n"); |
|
80 goto out_return; |
|
81 } |
|
82 #endif |
|
83 |
|
84 if (!(device->tx_skb = dev_alloc_skb(ETH_FRAME_LEN))) { |
|
85 EC_ERR("Error allocating device socket buffer!\n"); |
|
86 #ifdef EC_DBG_IF |
|
87 goto out_debug; |
|
88 #else |
|
89 goto out_return; |
|
90 #endif |
|
91 } |
|
92 |
|
93 device->tx_skb->dev = net_dev; |
|
94 |
|
95 // add Ethernet-II-header |
|
96 skb_reserve(device->tx_skb, ETH_HLEN); |
|
97 eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN); |
|
98 eth->h_proto = htons(0x88A4); |
|
99 memcpy(eth->h_source, net_dev->dev_addr, net_dev->addr_len); |
|
100 memset(eth->h_dest, 0xFF, net_dev->addr_len); |
|
101 |
|
102 return 0; |
|
103 |
|
104 #ifdef EC_DBG_IF |
|
105 out_debug: |
|
106 ec_debug_clear(&device->dbg); |
|
107 #endif |
|
108 out_return: |
|
109 return -1; |
|
110 } |
|
111 |
|
112 /*****************************************************************************/ |
|
113 |
|
114 /** |
|
115 EtherCAT device destuctor. |
|
116 */ |
|
117 |
|
118 void ec_device_clear(ec_device_t *device /**< EtherCAT device */) |
|
119 { |
|
120 if (device->open) ec_device_close(device); |
|
121 if (device->tx_skb) dev_kfree_skb(device->tx_skb); |
|
122 #ifdef EC_DBG_IF |
|
123 ec_debug_clear(&device->dbg); |
|
124 #endif |
|
125 } |
195 } |
126 |
196 |
127 /*****************************************************************************/ |
197 /*****************************************************************************/ |
128 |
198 |
129 /** |
199 /** |
203 |
273 |
204 void ec_device_send(ec_device_t *device, /**< EtherCAT device */ |
274 void ec_device_send(ec_device_t *device, /**< EtherCAT device */ |
205 size_t size /**< number of bytes to send */ |
275 size_t size /**< number of bytes to send */ |
206 ) |
276 ) |
207 { |
277 { |
|
278 struct sk_buff *skb = device->tx_skb[device->tx_ring_index]; |
|
279 |
208 if (unlikely(!device->link_state)) // Link down |
280 if (unlikely(!device->link_state)) // Link down |
209 return; |
281 return; |
210 |
282 |
211 // set the right length for the data |
283 // set the right length for the data |
212 device->tx_skb->len = ETH_HLEN + size; |
284 skb->len = ETH_HLEN + size; |
213 |
285 |
214 if (unlikely(device->master->debug_level > 1)) { |
286 if (unlikely(device->master->debug_level > 1)) { |
215 EC_DBG("sending frame:\n"); |
287 EC_DBG("sending frame:\n"); |
216 ec_print_data(device->tx_skb->data + ETH_HLEN, size); |
288 ec_print_data(skb->data + ETH_HLEN, size); |
217 } |
289 } |
218 |
290 |
219 #ifdef EC_DBG_IF |
291 #ifdef EC_DEBUG_IF |
220 ec_debug_send(&device->dbg, device->tx_skb->data, ETH_HLEN + size); |
292 ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size); |
|
293 #endif |
|
294 #ifdef EC_DEBUG_RING |
|
295 ec_device_debug_ring_append( |
|
296 device, TX, skb->data + ETH_HLEN, size); |
221 #endif |
297 #endif |
222 |
298 |
223 // start sending |
299 // start sending |
224 device->dev->hard_start_xmit(device->tx_skb, device->dev); |
300 device->dev->hard_start_xmit(skb, device->dev); |
225 device->tx_count++; |
301 device->tx_count++; |
226 } |
302 } |
|
303 |
|
304 /*****************************************************************************/ |
|
305 |
|
306 #ifdef EC_DEBUG_RING |
|
307 /** |
|
308 * Appends frame data to the debug ring. |
|
309 */ |
|
310 |
|
311 void ec_device_debug_ring_append( |
|
312 ec_device_t *device, /**< EtherCAT device */ |
|
313 ec_debug_frame_dir_t dir, /**< direction */ |
|
314 const void *data, /**< frame data */ |
|
315 size_t size /**< data size */ |
|
316 ) |
|
317 { |
|
318 ec_debug_frame_t *df = &device->debug_frames[device->debug_frame_index]; |
|
319 |
|
320 df->dir = dir; |
|
321 if (dir == TX) |
|
322 do_gettimeofday(&df->t); |
|
323 else |
|
324 df->t = device->timeval_poll; |
|
325 memcpy(df->data, data, size); |
|
326 df->data_size = size; |
|
327 |
|
328 device->debug_frame_index++; |
|
329 device->debug_frame_index %= EC_DEBUG_RING_SIZE; |
|
330 if (unlikely(device->debug_frame_count < EC_DEBUG_RING_SIZE)) |
|
331 device->debug_frame_count++; |
|
332 } |
|
333 |
|
334 /*****************************************************************************/ |
|
335 |
|
336 /** |
|
337 * Outputs the debug ring. |
|
338 */ |
|
339 |
|
340 void ec_device_debug_ring_print( |
|
341 const ec_device_t *device /**< EtherCAT device */ |
|
342 ) |
|
343 { |
|
344 int i; |
|
345 unsigned int ring_index; |
|
346 const ec_debug_frame_t *df; |
|
347 struct timeval t0, diff; |
|
348 |
|
349 // calculate index of the newest frame in the ring to get its time |
|
350 ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE - 1) |
|
351 % EC_DEBUG_RING_SIZE; |
|
352 t0 = device->debug_frames[ring_index].t; |
|
353 |
|
354 EC_DBG("Debug ring %i:\n", ring_index); |
|
355 |
|
356 // calculate index of the oldest frame in the ring |
|
357 ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE |
|
358 - device->debug_frame_count) % EC_DEBUG_RING_SIZE; |
|
359 |
|
360 for (i = 0; i < device->debug_frame_count; i++) { |
|
361 df = &device->debug_frames[ring_index]; |
|
362 timersub(&t0, &df->t, &diff); |
|
363 |
|
364 EC_DBG("Frame %i, dt=%u.%06u s, %s:\n", |
|
365 i + 1 - device->debug_frame_count, |
|
366 (unsigned int) diff.tv_sec, |
|
367 (unsigned int) diff.tv_usec, |
|
368 (df->dir == TX) ? "TX" : "RX"); |
|
369 ec_print_data(df->data, df->data_size); |
|
370 |
|
371 ring_index++; |
|
372 ring_index %= EC_DEBUG_RING_SIZE; |
|
373 } |
|
374 } |
|
375 #endif |
227 |
376 |
228 /*****************************************************************************/ |
377 /*****************************************************************************/ |
229 |
378 |
230 /** |
379 /** |
231 Calls the poll function of the assigned net_device. |
380 Calls the poll function of the assigned net_device. |
255 void ecdev_receive(ec_device_t *device, /**< EtherCAT device */ |
407 void ecdev_receive(ec_device_t *device, /**< EtherCAT device */ |
256 const void *data, /**< pointer to received data */ |
408 const void *data, /**< pointer to received data */ |
257 size_t size /**< number of bytes received */ |
409 size_t size /**< number of bytes received */ |
258 ) |
410 ) |
259 { |
411 { |
|
412 const void *ec_data = data + ETH_HLEN; |
|
413 size_t ec_size = size - ETH_HLEN; |
260 device->rx_count++; |
414 device->rx_count++; |
261 |
415 |
262 if (unlikely(device->master->debug_level > 1)) { |
416 if (unlikely(device->master->debug_level > 1)) { |
263 EC_DBG("Received frame:\n"); |
417 EC_DBG("Received frame:\n"); |
264 ec_print_data_diff(device->tx_skb->data + ETH_HLEN, |
418 ec_print_data(ec_data, ec_size); |
265 data + ETH_HLEN, size - ETH_HLEN); |
419 } |
266 } |
420 |
267 |
421 #ifdef EC_DEBUG_IF |
268 #ifdef EC_DBG_IF |
|
269 ec_debug_send(&device->dbg, data, size); |
422 ec_debug_send(&device->dbg, data, size); |
270 #endif |
423 #endif |
271 |
424 #ifdef EC_DEBUG_RING |
272 ec_master_receive_datagrams(device->master, |
425 ec_device_debug_ring_append(device, RX, ec_data, ec_size); |
273 data + ETH_HLEN, |
426 #endif |
274 size - ETH_HLEN); |
427 |
|
428 ec_master_receive_datagrams(device->master, ec_data, ec_size); |
275 } |
429 } |
276 |
430 |
277 /*****************************************************************************/ |
431 /*****************************************************************************/ |
278 |
432 |
279 /** |
433 /** |