53 void ec_eoedev_init(struct net_device *); |
55 void ec_eoedev_init(struct net_device *); |
54 int ec_eoedev_open(struct net_device *); |
56 int ec_eoedev_open(struct net_device *); |
55 int ec_eoedev_stop(struct net_device *); |
57 int ec_eoedev_stop(struct net_device *); |
56 int ec_eoedev_tx(struct sk_buff *, struct net_device *); |
58 int ec_eoedev_tx(struct sk_buff *, struct net_device *); |
57 struct net_device_stats *ec_eoedev_stats(struct net_device *); |
59 struct net_device_stats *ec_eoedev_stats(struct net_device *); |
|
60 void ec_eoedev_rx(struct net_device *, const uint8_t *, size_t); |
58 |
61 |
59 /*****************************************************************************/ |
62 /*****************************************************************************/ |
60 |
63 |
61 /** |
64 /** |
62 EoE constructor. |
65 EoE constructor. |
67 ec_eoedev_priv_t *priv; |
70 ec_eoedev_priv_t *priv; |
68 int result; |
71 int result; |
69 |
72 |
70 eoe->slave = slave; |
73 eoe->slave = slave; |
71 eoe->rx_state = EC_EOE_IDLE; |
74 eoe->rx_state = EC_EOE_IDLE; |
|
75 eoe->opened = 0; |
72 |
76 |
73 if (!(eoe->dev = |
77 if (!(eoe->dev = |
74 alloc_netdev(sizeof(ec_eoedev_priv_t), "eoe%d", ec_eoedev_init))) { |
78 alloc_netdev(sizeof(ec_eoedev_priv_t), "eoe%d", ec_eoedev_init))) { |
75 EC_ERR("Unable to allocate net_device for EoE object!\n"); |
79 EC_ERR("Unable to allocate net_device for EoE object!\n"); |
76 goto out_return; |
80 goto out_return; |
118 void ec_eoe_run(ec_eoe_t *eoe) |
122 void ec_eoe_run(ec_eoe_t *eoe) |
119 { |
123 { |
120 uint8_t *data; |
124 uint8_t *data; |
121 ec_master_t *master; |
125 ec_master_t *master; |
122 size_t rec_size; |
126 size_t rec_size; |
123 unsigned int i; |
127 uint8_t fragment_number, frame_number, last_fragment, time_appended; |
124 uint8_t fragment_number; |
128 uint8_t fragment_offset, frame_type; |
125 uint8_t complete_size; |
129 |
126 uint8_t frame_number; |
130 if (!eoe->opened) return; |
127 uint8_t last_fragment; |
|
128 |
131 |
129 master = eoe->slave->master; |
132 master = eoe->slave->master; |
130 |
133 |
131 if (eoe->rx_state == EC_EOE_IDLE) { |
134 if (eoe->rx_state == EC_EOE_IDLE) { |
132 ec_slave_mbox_prepare_check(eoe->slave); |
135 ec_slave_mbox_prepare_check(eoe->slave); |
161 master->stats.eoe_errors++; |
164 master->stats.eoe_errors++; |
162 eoe->rx_state = EC_EOE_IDLE; |
165 eoe->rx_state = EC_EOE_IDLE; |
163 return; |
166 return; |
164 } |
167 } |
165 |
168 |
166 fragment_number = EC_READ_U16(data + 2) & 0x003F; |
169 frame_type = EC_READ_U16(data) & 0x000F; |
167 complete_size = (EC_READ_U16(data + 2) >> 6) & 0x003F; |
170 |
168 frame_number = (EC_READ_U16(data + 2) >> 12) & 0x0003; |
171 if (frame_type == 0x00) { // EoE Fragment Request |
169 last_fragment = (EC_READ_U16(data + 2) >> 15) & 0x0001; |
172 last_fragment = (EC_READ_U16(data) >> 8) & 0x0001; |
170 |
173 time_appended = (EC_READ_U16(data) >> 9) & 0x0001; |
171 EC_DBG("EOE %s received, fragment: %i, complete size: %i (0x%02X)," |
174 fragment_number = EC_READ_U16(data + 2) & 0x003F; |
172 " frame %i%s\n", |
175 fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F; |
173 fragment_number ? "fragment" : "initiate", fragment_number, |
176 frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F; |
174 (complete_size - 31) / 32, complete_size, frame_number, |
177 |
175 last_fragment ? ", last fragment" : ""); |
178 #if 0 |
176 EC_DBG(""); |
179 EC_DBG("EOE fragment req received, fragment: %i, offset: %i," |
177 for (i = 0; i < rec_size - 2; i++) { |
180 " frame %i%s%s, %i bytes\n", fragment_number, |
178 printk("%02X ", data[i + 2]); |
181 fragment_offset, frame_number, |
179 if ((i + 1) % 16 == 0) { |
182 last_fragment ? ", last fragment" : "", |
180 printk("\n"); |
183 time_appended ? ", + timestamp" : "", |
181 EC_DBG(""); |
184 time_appended ? rec_size - 8 : rec_size - 4); |
|
185 |
|
186 #if 0 |
|
187 EC_DBG(""); |
|
188 for (i = 0; i < rec_size - 4; i++) { |
|
189 printk("%02X ", data[i + 4]); |
|
190 if ((i + 1) % 16 == 0) { |
|
191 printk("\n"); |
|
192 EC_DBG(""); |
|
193 } |
182 } |
194 } |
183 } |
195 printk("\n"); |
184 printk("\n"); |
196 #endif |
|
197 #endif |
|
198 |
|
199 ec_eoedev_rx(eoe->dev, data + 4, |
|
200 time_appended ? rec_size - 8 : rec_size - 4); |
|
201 } |
|
202 else { |
|
203 #if 1 |
|
204 EC_DBG("other frame received.\n"); |
|
205 #endif |
|
206 } |
185 |
207 |
186 eoe->rx_state = EC_EOE_IDLE; |
208 eoe->rx_state = EC_EOE_IDLE; |
187 return; |
209 return; |
188 } |
210 } |
189 } |
211 } |
196 |
218 |
197 void ec_eoe_print(const ec_eoe_t *eoe) |
219 void ec_eoe_print(const ec_eoe_t *eoe) |
198 { |
220 { |
199 EC_INFO(" EoE slave %i\n", eoe->slave->ring_position); |
221 EC_INFO(" EoE slave %i\n", eoe->slave->ring_position); |
200 EC_INFO(" RX State %i\n", eoe->rx_state); |
222 EC_INFO(" RX State %i\n", eoe->rx_state); |
|
223 EC_INFO(" Assigned device: %s (%s)\n", eoe->dev->name, |
|
224 eoe->opened ? "opened" : "closed"); |
201 } |
225 } |
202 |
226 |
203 /*****************************************************************************/ |
227 /*****************************************************************************/ |
204 |
228 |
205 /** |
229 /** |
207 */ |
231 */ |
208 |
232 |
209 void ec_eoedev_init(struct net_device *dev /**< pointer to the net_device */) |
233 void ec_eoedev_init(struct net_device *dev /**< pointer to the net_device */) |
210 { |
234 { |
211 ec_eoedev_priv_t *priv; |
235 ec_eoedev_priv_t *priv; |
|
236 unsigned int i; |
212 |
237 |
213 // initialize net_device |
238 // initialize net_device |
214 ether_setup(dev); |
239 ether_setup(dev); |
215 dev->open = ec_eoedev_open; |
240 dev->open = ec_eoedev_open; |
216 dev->stop = ec_eoedev_stop; |
241 dev->stop = ec_eoedev_stop; |
217 dev->hard_start_xmit = ec_eoedev_tx; |
242 dev->hard_start_xmit = ec_eoedev_tx; |
218 dev->get_stats = ec_eoedev_stats; |
243 dev->get_stats = ec_eoedev_stats; |
219 |
244 |
|
245 for (i = 0; i < 6; i++) dev->dev_addr[i] = (i + 1) | (i + 1) << 4; |
|
246 |
220 // initialize private data |
247 // initialize private data |
221 priv = netdev_priv(dev); |
248 priv = netdev_priv(dev); |
222 memset(priv, 0, sizeof(ec_eoedev_priv_t)); |
249 memset(priv, 0, sizeof(ec_eoedev_priv_t)); |
223 } |
250 } |
224 |
251 |
229 */ |
256 */ |
230 |
257 |
231 int ec_eoedev_open(struct net_device *dev /**< EoE net_device */) |
258 int ec_eoedev_open(struct net_device *dev /**< EoE net_device */) |
232 { |
259 { |
233 ec_eoedev_priv_t *priv = netdev_priv(dev); |
260 ec_eoedev_priv_t *priv = netdev_priv(dev); |
|
261 priv->eoe->opened = 1; |
234 netif_start_queue(dev); |
262 netif_start_queue(dev); |
235 EC_INFO("%s (slave %i) opened.\n", dev->name, |
263 EC_INFO("%s (slave %i) opened.\n", dev->name, |
236 priv->eoe->slave->ring_position); |
264 priv->eoe->slave->ring_position); |
237 return 0; |
265 return 0; |
238 } |
266 } |
245 |
273 |
246 int ec_eoedev_stop(struct net_device *dev /**< EoE net_device */) |
274 int ec_eoedev_stop(struct net_device *dev /**< EoE net_device */) |
247 { |
275 { |
248 ec_eoedev_priv_t *priv = netdev_priv(dev); |
276 ec_eoedev_priv_t *priv = netdev_priv(dev); |
249 netif_stop_queue(dev); |
277 netif_stop_queue(dev); |
|
278 priv->eoe->opened = 0; |
250 EC_INFO("%s (slave %i) stopped.\n", dev->name, |
279 EC_INFO("%s (slave %i) stopped.\n", dev->name, |
251 priv->eoe->slave->ring_position); |
280 priv->eoe->slave->ring_position); |
252 return 0; |
281 return 0; |
253 } |
282 } |
254 |
283 |
270 } |
299 } |
271 |
300 |
272 /*****************************************************************************/ |
301 /*****************************************************************************/ |
273 |
302 |
274 /** |
303 /** |
|
304 Receives data from the bus and passes it to the network stack. |
|
305 */ |
|
306 |
|
307 void ec_eoedev_rx(struct net_device *dev, /**< EoE net_device */ |
|
308 const uint8_t *data, /**< pointer to the data */ |
|
309 size_t size /**< size of the received data */ |
|
310 ) |
|
311 { |
|
312 ec_eoedev_priv_t *priv = netdev_priv(dev); |
|
313 struct sk_buff *skb; |
|
314 |
|
315 // allocate socket buffer |
|
316 if (!(skb = dev_alloc_skb(size + 2))) { |
|
317 if (printk_ratelimit()) |
|
318 EC_WARN("EoE RX: low on mem. frame dropped.\n"); |
|
319 priv->stats.rx_dropped++; |
|
320 return; |
|
321 } |
|
322 |
|
323 // copy received data to socket buffer |
|
324 memcpy(skb_put(skb, size), data, size); |
|
325 |
|
326 // set socket buffer fields |
|
327 skb->dev = dev; |
|
328 skb->protocol = eth_type_trans(skb, dev); |
|
329 skb->ip_summed = CHECKSUM_UNNECESSARY; |
|
330 |
|
331 // update statistics |
|
332 priv->stats.rx_packets++; |
|
333 priv->stats.rx_bytes += size; |
|
334 |
|
335 // pass socket buffer to network stack |
|
336 netif_rx(skb); |
|
337 } |
|
338 |
|
339 /*****************************************************************************/ |
|
340 |
|
341 /** |
275 Gets statistics about the virtual network device. |
342 Gets statistics about the virtual network device. |
276 */ |
343 */ |
277 |
344 |
278 struct net_device_stats *ec_eoedev_stats(struct net_device *dev |
345 struct net_device_stats *ec_eoedev_stats(struct net_device *dev |
279 /**< EoE net_device */) |
346 /**< EoE net_device */) |