39 |
39 |
40 #define EOE_DEBUG_LEVEL 0 |
40 #define EOE_DEBUG_LEVEL 0 |
41 |
41 |
42 /*****************************************************************************/ |
42 /*****************************************************************************/ |
43 |
43 |
44 /** |
|
45 Queued frame structure. |
|
46 */ |
|
47 |
|
48 typedef struct |
|
49 { |
|
50 struct list_head queue; /**< list item */ |
|
51 struct sk_buff *skb; /**< socket buffer */ |
|
52 } |
|
53 ec_eoe_frame_t; |
|
54 |
|
55 /*****************************************************************************/ |
|
56 |
|
57 void ec_eoe_flush(ec_eoe_t *); |
44 void ec_eoe_flush(ec_eoe_t *); |
58 void ec_eoedev_init(struct net_device *); |
45 void ec_eoedev_init(struct net_device *); |
59 int ec_eoedev_open(struct net_device *); |
46 int ec_eoedev_open(struct net_device *); |
60 int ec_eoedev_stop(struct net_device *); |
47 int ec_eoedev_stop(struct net_device *); |
61 int ec_eoedev_tx(struct sk_buff *, struct net_device *); |
48 int ec_eoedev_tx(struct sk_buff *, struct net_device *); |
147 kfree(frame); |
134 kfree(frame); |
148 } |
135 } |
149 eoe->queued_frames = 0; |
136 eoe->queued_frames = 0; |
150 |
137 |
151 spin_unlock_bh(&eoe->tx_queue_lock); |
138 spin_unlock_bh(&eoe->tx_queue_lock); |
|
139 } |
|
140 |
|
141 /*****************************************************************************/ |
|
142 |
|
143 /** |
|
144 Sends a frame or the next fragment. |
|
145 */ |
|
146 |
|
147 int ec_eoe_send(ec_eoe_t *eoe) |
|
148 { |
|
149 ec_eoe_frame_t *frame = eoe->tx_frame; |
|
150 size_t remaining_size, current_size, complete_offset; |
|
151 unsigned int last_fragment; |
|
152 uint8_t *data; |
|
153 #if EOE_DEBUG_LEVEL > 1 |
|
154 unsigned int i; |
|
155 #endif |
|
156 |
|
157 remaining_size = frame->skb->len - eoe->tx_offset; |
|
158 |
|
159 if (remaining_size <= eoe->slave->sii_tx_mailbox_size - 10) { |
|
160 current_size = remaining_size; |
|
161 last_fragment = 1; |
|
162 } |
|
163 else { |
|
164 current_size = ((eoe->slave->sii_tx_mailbox_size - 10) / 32) * 32; |
|
165 last_fragment = 0; |
|
166 } |
|
167 |
|
168 if (eoe->tx_fragment_number) { |
|
169 complete_offset = eoe->tx_offset / 32; |
|
170 } |
|
171 else { |
|
172 complete_offset = remaining_size / 32 + 1; |
|
173 } |
|
174 |
|
175 #if EOE_DEBUG_LEVEL > 0 |
|
176 EC_DBG("EoE TX sending %sfragment %i with %i octets (%i)." |
|
177 " %i frames queued.\n", last_fragment ? "last " : "", |
|
178 eoe->tx_fragment_number, current_size, complete_offset, |
|
179 eoe->queued_frames); |
|
180 #endif |
|
181 |
|
182 #if EOE_DEBUG_LEVEL > 1 |
|
183 EC_DBG(""); |
|
184 for (i = 0; i < current_size; i++) { |
|
185 printk("%02X ", frame->skb->data[eoe->tx_offset + i]); |
|
186 if ((i + 1) % 16 == 0) { |
|
187 printk("\n"); |
|
188 EC_DBG(""); |
|
189 } |
|
190 } |
|
191 printk("\n"); |
|
192 #endif |
|
193 |
|
194 if (!(data = ec_slave_mbox_prepare_send(eoe->slave, 0x02, |
|
195 current_size + 4))) |
|
196 return -1; |
|
197 |
|
198 EC_WRITE_U8 (data, 0x00); // eoe fragment req. |
|
199 EC_WRITE_U8 (data + 1, last_fragment); |
|
200 EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) | |
|
201 (complete_offset & 0x3F) << 6 | |
|
202 (eoe->tx_frame_number & 0x0F) << 12)); |
|
203 |
|
204 memcpy(data + 4, frame->skb->data + eoe->tx_offset, current_size); |
|
205 ec_master_queue_command(eoe->slave->master, &eoe->slave->mbox_command); |
|
206 |
|
207 eoe->tx_offset += current_size; |
|
208 eoe->tx_fragment_number++; |
|
209 |
|
210 return 0; |
152 } |
211 } |
153 |
212 |
154 /*****************************************************************************/ |
213 /*****************************************************************************/ |
155 |
214 |
156 /** |
215 /** |
341 wakeup = 1; |
400 wakeup = 1; |
342 } |
401 } |
343 eoe->queued_frames--; |
402 eoe->queued_frames--; |
344 spin_unlock_bh(&eoe->tx_queue_lock); |
403 spin_unlock_bh(&eoe->tx_queue_lock); |
345 |
404 |
346 #if EOE_DEBUG_LEVEL > 0 |
405 eoe->tx_frame_number++; |
347 EC_DBG("EoE TX Sending frame with %i octets." |
406 eoe->tx_frame_number %= 16; |
348 " (%i frames queued).\n", |
407 eoe->tx_frame = frame; |
349 frame->skb->len, eoe->queued_frames); |
408 eoe->tx_fragment_number = 0; |
350 |
409 eoe->tx_offset = 0; |
351 #if EOE_DEBUG_LEVEL > 1 |
410 |
352 EC_DBG(""); |
411 if (ec_eoe_send(eoe)) { |
353 for (i = 0; i < frame->skb->len; i++) { |
|
354 printk("%02X ", frame->skb->data[i]); |
|
355 if ((i + 1) % 16 == 0) { |
|
356 printk("\n"); |
|
357 EC_DBG(""); |
|
358 } |
|
359 } |
|
360 printk("\n"); |
|
361 #endif |
|
362 |
|
363 if (wakeup) EC_DBG("waking up TX queue...\n"); |
|
364 #endif |
|
365 |
|
366 if (!(data = ec_slave_mbox_prepare_send(eoe->slave, 0x02, |
|
367 frame->skb->len + 4))) { |
|
368 dev_kfree_skb(frame->skb); |
412 dev_kfree_skb(frame->skb); |
369 kfree(frame); |
413 kfree(frame); |
370 eoe->stats.tx_errors++; |
414 eoe->stats.tx_errors++; |
371 eoe->state = EC_EOE_RX_START; |
415 eoe->state = EC_EOE_RX_START; |
372 break; |
416 break; |
373 } |
417 } |
374 |
418 |
375 eoe->tx_frame_number++; |
419 #if EOE_DEBUG_LEVEL > 0 |
376 eoe->tx_frame_number %= 16; |
420 if (wakeup) EC_DBG("waking up TX queue...\n"); |
377 |
421 #endif |
378 EC_WRITE_U16(data, 0x0100); // eoe fragment req. |
|
379 EC_WRITE_U16(data + 2, (eoe->tx_frame_number & 0x0F) << 12); |
|
380 |
|
381 memcpy(data + 4, frame->skb->data, frame->skb->len); |
|
382 ec_master_queue_command(master, &eoe->slave->mbox_command); |
|
383 |
|
384 eoe->last_tx_bytes = frame->skb->len; |
|
385 dev_kfree_skb(frame->skb); |
|
386 kfree(frame); |
|
387 |
422 |
388 eoe->state = EC_EOE_TX_SENT; |
423 eoe->state = EC_EOE_TX_SENT; |
389 break; |
424 break; |
390 |
425 |
391 case EC_EOE_TX_SENT: |
426 case EC_EOE_TX_SENT: |
398 eoe->stats.tx_errors++; |
433 eoe->stats.tx_errors++; |
399 eoe->state = EC_EOE_RX_START; |
434 eoe->state = EC_EOE_RX_START; |
400 break; |
435 break; |
401 } |
436 } |
402 |
437 |
403 eoe->stats.tx_packets++; |
438 // frame completely sent |
404 eoe->stats.tx_bytes += eoe->last_tx_bytes; |
439 if (eoe->tx_offset >= eoe->tx_frame->skb->len) { |
405 eoe->state = EC_EOE_RX_START; |
440 eoe->stats.tx_packets++; |
|
441 eoe->stats.tx_bytes += eoe->tx_frame->skb->len; |
|
442 dev_kfree_skb(eoe->tx_frame->skb); |
|
443 kfree(eoe->tx_frame); |
|
444 eoe->state = EC_EOE_RX_START; |
|
445 } |
|
446 else { // send next fragment |
|
447 if (ec_eoe_send(eoe)) { |
|
448 dev_kfree_skb(eoe->tx_frame->skb); |
|
449 kfree(eoe->tx_frame); |
|
450 eoe->stats.tx_errors++; |
|
451 eoe->state = EC_EOE_RX_START; |
|
452 break; |
|
453 } |
|
454 } |
|
455 |
406 break; |
456 break; |
407 |
457 |
408 default: |
458 default: |
409 break; |
459 break; |
410 } |
460 } |
495 ) |
545 ) |
496 { |
546 { |
497 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev)); |
547 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev)); |
498 ec_eoe_frame_t *frame; |
548 ec_eoe_frame_t *frame; |
499 |
549 |
500 if (skb->len + 10 > eoe->slave->sii_tx_mailbox_size) { |
550 #if 0 |
|
551 if (skb->len > eoe->slave->sii_tx_mailbox_size - 10) { |
501 EC_WARN("EoE TX frame (%i octets) exceeds MTU. dropping.\n", skb->len); |
552 EC_WARN("EoE TX frame (%i octets) exceeds MTU. dropping.\n", skb->len); |
502 dev_kfree_skb(skb); |
553 dev_kfree_skb(skb); |
503 eoe->stats.tx_dropped++; |
554 eoe->stats.tx_dropped++; |
504 return 0; |
555 return 0; |
505 } |
556 } |
|
557 #endif |
506 |
558 |
507 if (!(frame = |
559 if (!(frame = |
508 (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) { |
560 (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) { |
509 if (printk_ratelimit()) |
561 if (printk_ratelimit()) |
510 EC_WARN("EoE TX: low on mem. frame dropped.\n"); |
562 EC_WARN("EoE TX: low on mem. frame dropped.\n"); |