67 |
67 |
68 int ec_device_init(ec_device_t *device, /**< EtherCAT device */ |
68 int ec_device_init(ec_device_t *device, /**< EtherCAT device */ |
69 ec_master_t *master /**< master owning the device */ |
69 ec_master_t *master /**< master owning the device */ |
70 ) |
70 ) |
71 { |
71 { |
|
72 unsigned int i; |
|
73 struct ethhdr *eth; |
72 #ifdef EC_DEBUG_IF |
74 #ifdef EC_DEBUG_IF |
73 char ifname[10]; |
75 char ifname[10]; |
74 char mb = 'x'; |
76 char mb = 'x'; |
75 #endif |
77 #endif |
76 #ifdef EC_DEBUG_RING |
78 #ifdef EC_DEBUG_RING |
77 device->debug_frame_index = 0; |
79 device->debug_frame_index = 0; |
78 device->debug_frame_count = 0; |
80 device->debug_frame_count = 0; |
79 #endif |
81 #endif |
80 |
82 |
81 device->master = master; |
83 device->master = master; |
|
84 device->tx_ring_index = 0; |
82 |
85 |
83 #ifdef EC_DEBUG_IF |
86 #ifdef EC_DEBUG_IF |
84 if (device == &master->main_device) |
87 if (device == &master->main_device) |
85 mb = 'm'; |
88 mb = 'm'; |
86 else if (device == &master->backup_device) |
89 else if (device == &master->backup_device) |
92 EC_ERR("Failed to init debug device!\n"); |
95 EC_ERR("Failed to init debug device!\n"); |
93 goto out_return; |
96 goto out_return; |
94 } |
97 } |
95 #endif |
98 #endif |
96 |
99 |
97 if (!(device->tx_skb = dev_alloc_skb(ETH_FRAME_LEN))) { |
100 for (i = 0; i < EC_TX_RING_SIZE; i++) |
98 EC_ERR("Error allocating device socket buffer!\n"); |
101 device->tx_skb[i] = NULL; |
99 #ifdef EC_DEBUG_IF |
102 |
100 goto out_debug; |
103 for (i = 0; i < EC_TX_RING_SIZE; i++) { |
101 #else |
104 if (!(device->tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN))) { |
102 goto out_return; |
105 EC_ERR("Error allocating device socket buffer!\n"); |
103 #endif |
106 goto out_tx_ring; |
104 } |
107 } |
105 |
108 |
106 // add Ethernet-II-header |
109 // add Ethernet-II-header |
107 skb_reserve(device->tx_skb, ETH_HLEN); |
110 skb_reserve(device->tx_skb[i], ETH_HLEN); |
108 device->eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN); |
111 eth = (struct ethhdr *) skb_push(device->tx_skb[i], ETH_HLEN); |
109 device->eth->h_proto = htons(0x88A4); |
112 eth->h_proto = htons(0x88A4); |
110 memset(device->eth->h_dest, 0xFF, ETH_ALEN); |
113 memset(eth->h_dest, 0xFF, ETH_ALEN); |
|
114 } |
111 |
115 |
112 ec_device_detach(device); // resets remaining fields |
116 ec_device_detach(device); // resets remaining fields |
113 return 0; |
117 return 0; |
114 |
118 |
115 #ifdef EC_DEBUG_IF |
119 out_tx_ring: |
116 out_debug: |
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 |
117 ec_debug_clear(&device->dbg); |
124 ec_debug_clear(&device->dbg); |
118 #endif |
125 out_return: |
119 out_return: |
126 #endif |
120 return -1; |
127 return -1; |
121 } |
128 } |
122 |
129 |
123 /*****************************************************************************/ |
130 /*****************************************************************************/ |
124 |
131 |
126 EtherCAT device destuctor. |
133 EtherCAT device destuctor. |
127 */ |
134 */ |
128 |
135 |
129 void ec_device_clear(ec_device_t *device /**< EtherCAT device */) |
136 void ec_device_clear(ec_device_t *device /**< EtherCAT device */) |
130 { |
137 { |
|
138 unsigned int i; |
|
139 |
131 if (device->open) ec_device_close(device); |
140 if (device->open) ec_device_close(device); |
132 dev_kfree_skb(device->tx_skb); |
141 for (i = 0; i < EC_TX_RING_SIZE; i++) |
|
142 dev_kfree_skb(device->tx_skb[i]); |
133 #ifdef EC_DEBUG_IF |
143 #ifdef EC_DEBUG_IF |
134 ec_debug_clear(&device->dbg); |
144 ec_debug_clear(&device->dbg); |
135 #endif |
145 #endif |
136 } |
146 } |
137 |
147 |
145 struct net_device *net_dev, /**< net_device structure */ |
155 struct net_device *net_dev, /**< net_device structure */ |
146 ec_pollfunc_t poll, /**< pointer to device's poll function */ |
156 ec_pollfunc_t poll, /**< pointer to device's poll function */ |
147 struct module *module /**< the device's module */ |
157 struct module *module /**< the device's module */ |
148 ) |
158 ) |
149 { |
159 { |
|
160 unsigned int i; |
|
161 struct ethhdr *eth; |
|
162 |
150 ec_device_detach(device); // resets fields |
163 ec_device_detach(device); // resets fields |
151 |
164 |
152 device->dev = net_dev; |
165 device->dev = net_dev; |
153 device->poll = poll; |
166 device->poll = poll; |
154 device->module = module; |
167 device->module = module; |
155 |
168 |
156 device->tx_skb->dev = net_dev; |
169 for (i = 0; i < EC_TX_RING_SIZE; i++) { |
157 memcpy(device->eth->h_source, net_dev->dev_addr, ETH_ALEN); |
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 } |
158 } |
174 } |
159 |
175 |
160 /*****************************************************************************/ |
176 /*****************************************************************************/ |
161 |
177 |
162 /** |
178 /** |
163 Disconnect from net_device. |
179 Disconnect from net_device. |
164 */ |
180 */ |
165 |
181 |
166 void ec_device_detach(ec_device_t *device /**< EtherCAT device */) |
182 void ec_device_detach(ec_device_t *device /**< EtherCAT device */) |
167 { |
183 { |
|
184 unsigned int i; |
|
185 |
168 device->dev = NULL; |
186 device->dev = NULL; |
169 device->poll = NULL; |
187 device->poll = NULL; |
170 device->module = NULL; |
188 device->module = NULL; |
171 device->open = 0; |
189 device->open = 0; |
172 device->link_state = 0; // down |
190 device->link_state = 0; // down |
173 device->tx_count = 0; |
191 device->tx_count = 0; |
174 device->rx_count = 0; |
192 device->rx_count = 0; |
175 device->tx_skb->dev = NULL; |
193 for (i = 0; i < EC_TX_RING_SIZE; i++) |
|
194 device->tx_skb[i]->dev = NULL; |
176 } |
195 } |
177 |
196 |
178 /*****************************************************************************/ |
197 /*****************************************************************************/ |
179 |
198 |
180 /** |
199 /** |
234 \return pointer to the TX socket buffer |
253 \return pointer to the TX socket buffer |
235 */ |
254 */ |
236 |
255 |
237 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT device */) |
256 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT device */) |
238 { |
257 { |
239 return device->tx_skb->data + ETH_HLEN; |
258 /* cycle through socket buffers, because otherwise there is a race |
|
259 * condition, if multiple frames are sent and the DMA is not scheduled in |
|
260 * between. */ |
|
261 device->tx_ring_index++; |
|
262 device->tx_ring_index %= EC_TX_RING_SIZE; |
|
263 return device->tx_skb[device->tx_ring_index]->data + ETH_HLEN; |
240 } |
264 } |
241 |
265 |
242 /*****************************************************************************/ |
266 /*****************************************************************************/ |
243 |
267 |
244 /** |
268 /** |
249 |
273 |
250 void ec_device_send(ec_device_t *device, /**< EtherCAT device */ |
274 void ec_device_send(ec_device_t *device, /**< EtherCAT device */ |
251 size_t size /**< number of bytes to send */ |
275 size_t size /**< number of bytes to send */ |
252 ) |
276 ) |
253 { |
277 { |
|
278 struct sk_buff *skb = device->tx_skb[device->tx_ring_index]; |
|
279 |
254 if (unlikely(!device->link_state)) // Link down |
280 if (unlikely(!device->link_state)) // Link down |
255 return; |
281 return; |
256 |
282 |
257 // set the right length for the data |
283 // set the right length for the data |
258 device->tx_skb->len = ETH_HLEN + size; |
284 skb->len = ETH_HLEN + size; |
259 |
285 |
260 if (unlikely(device->master->debug_level > 1)) { |
286 if (unlikely(device->master->debug_level > 1)) { |
261 EC_DBG("sending frame:\n"); |
287 EC_DBG("sending frame:\n"); |
262 ec_print_data(device->tx_skb->data + ETH_HLEN, size); |
288 ec_print_data(skb->data + ETH_HLEN, size); |
263 } |
289 } |
264 |
290 |
265 #ifdef EC_DEBUG_IF |
291 #ifdef EC_DEBUG_IF |
266 ec_debug_send(&device->dbg, device->tx_skb->data, ETH_HLEN + size); |
292 ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size); |
267 #endif |
293 #endif |
268 #ifdef EC_DEBUG_RING |
294 #ifdef EC_DEBUG_RING |
269 ec_device_debug_ring_append( |
295 ec_device_debug_ring_append( |
270 device, TX, device->tx_skb->data + ETH_HLEN, size); |
296 device, TX, skb->data + ETH_HLEN, size); |
271 #endif |
297 #endif |
272 |
298 |
273 // start sending |
299 // start sending |
274 device->dev->hard_start_xmit(device->tx_skb, device->dev); |
300 device->dev->hard_start_xmit(skb, device->dev); |
275 device->tx_count++; |
301 device->tx_count++; |
276 } |
302 } |
277 |
303 |
278 /*****************************************************************************/ |
304 /*****************************************************************************/ |
279 |
305 |
387 size_t ec_size = size - ETH_HLEN; |
413 size_t ec_size = size - ETH_HLEN; |
388 device->rx_count++; |
414 device->rx_count++; |
389 |
415 |
390 if (unlikely(device->master->debug_level > 1)) { |
416 if (unlikely(device->master->debug_level > 1)) { |
391 EC_DBG("Received frame:\n"); |
417 EC_DBG("Received frame:\n"); |
392 ec_print_data_diff(device->tx_skb->data + ETH_HLEN, ec_data, ec_size); |
418 ec_print_data(ec_data, ec_size); |
393 } |
419 } |
394 |
420 |
395 #ifdef EC_DEBUG_IF |
421 #ifdef EC_DEBUG_IF |
396 ec_debug_send(&device->dbg, data, size); |
422 ec_debug_send(&device->dbg, data, size); |
397 #endif |
423 #endif |