43 #include "mailbox.h" |
43 #include "mailbox.h" |
44 #include "ethernet.h" |
44 #include "ethernet.h" |
45 |
45 |
46 /*****************************************************************************/ |
46 /*****************************************************************************/ |
47 |
47 |
48 /** |
48 /** Defines the debug level of EoE processing. |
49 * Defines the debug level of EoE processing. |
|
50 * |
49 * |
51 * 0 = No debug messages. |
50 * 0 = No debug messages. |
52 * 1 = Output actions. |
51 * 1 = Output warnings. |
53 * 2 = Output actions and frame data. |
52 * 2 = Output actions. |
|
53 * 3 = Output actions and frame data. |
54 */ |
54 */ |
55 |
|
56 #define EOE_DEBUG_LEVEL 0 |
55 #define EOE_DEBUG_LEVEL 0 |
57 |
56 |
58 /** size of the EoE tx queue */ |
57 /** Size of the EoE tx queue. |
|
58 */ |
59 #define EC_EOE_TX_QUEUE_SIZE 100 |
59 #define EC_EOE_TX_QUEUE_SIZE 100 |
|
60 |
|
61 /** Number of tries. |
|
62 */ |
|
63 #define EC_EOE_TRIES 10 |
60 |
64 |
61 /*****************************************************************************/ |
65 /*****************************************************************************/ |
62 |
66 |
63 void ec_eoe_flush(ec_eoe_t *); |
67 void ec_eoe_flush(ec_eoe_t *); |
64 |
68 |
227 int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */) |
231 int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */) |
228 { |
232 { |
229 size_t remaining_size, current_size, complete_offset; |
233 size_t remaining_size, current_size, complete_offset; |
230 unsigned int last_fragment; |
234 unsigned int last_fragment; |
231 uint8_t *data; |
235 uint8_t *data; |
232 #if EOE_DEBUG_LEVEL > 1 |
236 #if EOE_DEBUG_LEVEL >= 3 |
233 unsigned int i; |
237 unsigned int i; |
234 #endif |
238 #endif |
235 |
239 |
236 remaining_size = eoe->tx_frame->skb->len - eoe->tx_offset; |
240 remaining_size = eoe->tx_frame->skb->len - eoe->tx_offset; |
237 |
241 |
249 else { |
253 else { |
250 // complete size in 32 bit blocks, rounded up. |
254 // complete size in 32 bit blocks, rounded up. |
251 complete_offset = remaining_size / 32 + 1; |
255 complete_offset = remaining_size / 32 + 1; |
252 } |
256 } |
253 |
257 |
254 #if EOE_DEBUG_LEVEL > 0 |
258 #if EOE_DEBUG_LEVEL >= 2 |
255 EC_DBG("EoE %s TX sending fragment %u%s with %u octets (%u)." |
259 EC_DBG("EoE %s TX sending fragment %u%s with %u octets (%u)." |
256 " %u frames queued.\n", eoe->dev->name, eoe->tx_fragment_number, |
260 " %u frames queued.\n", eoe->dev->name, eoe->tx_fragment_number, |
257 last_fragment ? "" : "+", current_size, complete_offset, |
261 last_fragment ? "" : "+", current_size, complete_offset, |
258 eoe->tx_queued_frames); |
262 eoe->tx_queued_frames); |
259 #endif |
263 #endif |
260 |
264 |
261 #if EOE_DEBUG_LEVEL > 1 |
265 #if EOE_DEBUG_LEVEL >= 3 |
262 EC_DBG(""); |
266 EC_DBG(""); |
263 for (i = 0; i < current_size; i++) { |
267 for (i = 0; i < current_size; i++) { |
264 printk("%02X ", eoe->tx_frame->skb->data[eoe->tx_offset + i]); |
268 printk("%02X ", eoe->tx_frame->skb->data[eoe->tx_offset + i]); |
265 if ((i + 1) % 16 == 0) { |
269 if ((i + 1) % 16 == 0) { |
266 printk("\n"); |
270 printk("\n"); |
375 |
379 |
376 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */) |
380 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */) |
377 { |
381 { |
378 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { |
382 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { |
379 eoe->stats.rx_errors++; |
383 eoe->stats.rx_errors++; |
|
384 #if EOE_DEBUG_LEVEL >= 1 |
|
385 EC_WARN("Failed to receive mbox check datagram for %s.\n", |
|
386 eoe->dev->name); |
|
387 #endif |
380 eoe->state = ec_eoe_state_tx_start; |
388 eoe->state = ec_eoe_state_tx_start; |
381 return; |
389 return; |
382 } |
390 } |
383 |
391 |
384 if (!ec_slave_mbox_check(&eoe->datagram)) { |
392 if (!ec_slave_mbox_check(&eoe->datagram)) { |
403 { |
411 { |
404 size_t rec_size, data_size; |
412 size_t rec_size, data_size; |
405 uint8_t *data, frame_type, last_fragment, time_appended, mbox_prot; |
413 uint8_t *data, frame_type, last_fragment, time_appended, mbox_prot; |
406 uint8_t frame_number, fragment_offset, fragment_number; |
414 uint8_t frame_number, fragment_offset, fragment_number; |
407 off_t offset; |
415 off_t offset; |
408 #if EOE_DEBUG_LEVEL > 1 |
416 #if EOE_DEBUG_LEVEL >= 3 |
409 unsigned int i; |
417 unsigned int i; |
410 #endif |
418 #endif |
411 |
419 |
412 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { |
420 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { |
413 eoe->stats.rx_errors++; |
421 eoe->stats.rx_errors++; |
|
422 #if EOE_DEBUG_LEVEL >= 1 |
|
423 EC_WARN("Failed to receive mbox fetch datagram for %s.\n", |
|
424 eoe->dev->name); |
|
425 #endif |
414 eoe->state = ec_eoe_state_tx_start; |
426 eoe->state = ec_eoe_state_tx_start; |
415 return; |
427 return; |
416 } |
428 } |
417 |
429 |
418 data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram, |
430 data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram, |
419 &mbox_prot, &rec_size); |
431 &mbox_prot, &rec_size); |
420 if (IS_ERR(data)) { |
432 if (IS_ERR(data)) { |
421 eoe->stats.rx_errors++; |
433 eoe->stats.rx_errors++; |
|
434 #if EOE_DEBUG_LEVEL >= 1 |
|
435 EC_WARN("Invalid mailbox response for %s.\n", |
|
436 eoe->dev->name); |
|
437 #endif |
422 eoe->state = ec_eoe_state_tx_start; |
438 eoe->state = ec_eoe_state_tx_start; |
423 return; |
439 return; |
424 } |
440 } |
425 |
441 |
426 if (mbox_prot != 0x02) { // EoE FIXME mailbox handler necessary |
442 if (mbox_prot != 0x02) { // EoE FIXME mailbox handler necessary |
427 eoe->stats.rx_errors++; |
443 eoe->stats.rx_errors++; |
|
444 #if EOE_DEBUG_LEVEL >= 1 |
|
445 EC_WARN("Other mailbox protocol response for %s.\n", |
|
446 eoe->dev->name); |
|
447 #endif |
428 eoe->state = ec_eoe_state_tx_start; |
448 eoe->state = ec_eoe_state_tx_start; |
429 return; |
449 return; |
430 } |
450 } |
431 |
451 |
432 frame_type = EC_READ_U16(data) & 0x000F; |
452 frame_type = EC_READ_U16(data) & 0x000F; |
433 |
453 |
434 if (frame_type != 0x00) { |
454 if (frame_type != 0x00) { |
435 #if EOE_DEBUG_LEVEL > 0 |
455 #if EOE_DEBUG_LEVEL >= 1 |
436 EC_DBG("EoE %s: Other frame received.\n", eoe->dev->name); |
456 EC_WARN("%s: Other frame received. Dropping.\n", eoe->dev->name); |
437 #endif |
457 #endif |
438 eoe->stats.rx_dropped++; |
458 eoe->stats.rx_dropped++; |
439 eoe->state = ec_eoe_state_tx_start; |
459 eoe->state = ec_eoe_state_tx_start; |
440 return; |
460 return; |
441 } |
461 } |
446 time_appended = (EC_READ_U16(data) >> 9) & 0x0001; |
466 time_appended = (EC_READ_U16(data) >> 9) & 0x0001; |
447 fragment_number = EC_READ_U16(data + 2) & 0x003F; |
467 fragment_number = EC_READ_U16(data + 2) & 0x003F; |
448 fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F; |
468 fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F; |
449 frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F; |
469 frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F; |
450 |
470 |
451 #if EOE_DEBUG_LEVEL > 0 |
471 #if EOE_DEBUG_LEVEL >= 2 |
452 EC_DBG("EoE %s RX fragment %u%s, offset %u, frame %u%s," |
472 EC_DBG("EoE %s RX fragment %u%s, offset %u, frame %u%s," |
453 " %u octets\n", eoe->dev->name, fragment_number, |
473 " %u octets\n", eoe->dev->name, fragment_number, |
454 last_fragment ? "" : "+", fragment_offset, frame_number, |
474 last_fragment ? "" : "+", fragment_offset, frame_number, |
455 time_appended ? ", + timestamp" : "", |
475 time_appended ? ", + timestamp" : "", |
456 time_appended ? rec_size - 8 : rec_size - 4); |
476 time_appended ? rec_size - 8 : rec_size - 4); |
457 #endif |
477 #endif |
458 |
478 |
459 #if EOE_DEBUG_LEVEL > 1 |
479 #if EOE_DEBUG_LEVEL >= 3 |
460 EC_DBG(""); |
480 EC_DBG(""); |
461 for (i = 0; i < rec_size - 4; i++) { |
481 for (i = 0; i < rec_size - 4; i++) { |
462 printk("%02X ", data[i + 4]); |
482 printk("%02X ", data[i + 4]); |
463 if ((i + 1) % 16 == 0) { |
483 if ((i + 1) % 16 == 0) { |
464 printk("\n"); |
484 printk("\n"); |
501 offset + data_size > eoe->rx_skb_size || |
521 offset + data_size > eoe->rx_skb_size || |
502 fragment_number != eoe->rx_expected_fragment) { |
522 fragment_number != eoe->rx_expected_fragment) { |
503 dev_kfree_skb(eoe->rx_skb); |
523 dev_kfree_skb(eoe->rx_skb); |
504 eoe->rx_skb = NULL; |
524 eoe->rx_skb = NULL; |
505 eoe->stats.rx_errors++; |
525 eoe->stats.rx_errors++; |
|
526 #if EOE_DEBUG_LEVEL >= 1 |
|
527 EC_WARN("Fragmenting error at %s.\n", eoe->dev->name); |
|
528 #endif |
506 eoe->state = ec_eoe_state_tx_start; |
529 eoe->state = ec_eoe_state_tx_start; |
507 return; |
530 return; |
508 } |
531 } |
509 } |
532 } |
510 |
533 |
516 // update statistics |
539 // update statistics |
517 eoe->stats.rx_packets++; |
540 eoe->stats.rx_packets++; |
518 eoe->stats.rx_bytes += eoe->rx_skb->len; |
541 eoe->stats.rx_bytes += eoe->rx_skb->len; |
519 eoe->rx_counter += eoe->rx_skb->len; |
542 eoe->rx_counter += eoe->rx_skb->len; |
520 |
543 |
521 #if EOE_DEBUG_LEVEL > 0 |
544 #if EOE_DEBUG_LEVEL >= 2 |
522 EC_DBG("EoE %s RX frame completed with %u octets.\n", |
545 EC_DBG("EoE %s RX frame completed with %u octets.\n", |
523 eoe->dev->name, eoe->rx_skb->len); |
546 eoe->dev->name, eoe->rx_skb->len); |
524 #endif |
547 #endif |
525 |
548 |
526 // pass socket buffer to network stack |
549 // pass socket buffer to network stack |
534 |
557 |
535 eoe->state = ec_eoe_state_tx_start; |
558 eoe->state = ec_eoe_state_tx_start; |
536 } |
559 } |
537 else { |
560 else { |
538 eoe->rx_expected_fragment++; |
561 eoe->rx_expected_fragment++; |
539 #if EOE_DEBUG_LEVEL > 0 |
562 #if EOE_DEBUG_LEVEL >= 2 |
540 EC_DBG("EoE %s RX expecting fragment %u\n", |
563 EC_DBG("EoE %s RX expecting fragment %u\n", |
541 eoe->dev->name, eoe->rx_expected_fragment); |
564 eoe->dev->name, eoe->rx_expected_fragment); |
542 #endif |
565 #endif |
543 eoe->state = ec_eoe_state_rx_start; |
566 eoe->state = ec_eoe_state_rx_start; |
544 } |
567 } |
576 list_del(&eoe->tx_frame->queue); |
599 list_del(&eoe->tx_frame->queue); |
577 if (!eoe->tx_queue_active && |
600 if (!eoe->tx_queue_active && |
578 eoe->tx_queued_frames == eoe->tx_queue_size / 2) { |
601 eoe->tx_queued_frames == eoe->tx_queue_size / 2) { |
579 netif_wake_queue(eoe->dev); |
602 netif_wake_queue(eoe->dev); |
580 eoe->tx_queue_active = 1; |
603 eoe->tx_queue_active = 1; |
581 #if EOE_DEBUG_LEVEL > 0 |
604 #if EOE_DEBUG_LEVEL >= 2 |
582 wakeup = 1; |
605 wakeup = 1; |
583 #endif |
606 #endif |
584 } |
607 } |
585 |
608 |
586 eoe->tx_queued_frames--; |
609 eoe->tx_queued_frames--; |
595 dev_kfree_skb(eoe->tx_frame->skb); |
618 dev_kfree_skb(eoe->tx_frame->skb); |
596 kfree(eoe->tx_frame); |
619 kfree(eoe->tx_frame); |
597 eoe->tx_frame = NULL; |
620 eoe->tx_frame = NULL; |
598 eoe->stats.tx_errors++; |
621 eoe->stats.tx_errors++; |
599 eoe->state = ec_eoe_state_rx_start; |
622 eoe->state = ec_eoe_state_rx_start; |
600 return; |
623 #if EOE_DEBUG_LEVEL >= 1 |
601 } |
624 EC_WARN("Send error at %s.\n", eoe->dev->name); |
602 |
625 #endif |
603 #if EOE_DEBUG_LEVEL > 0 |
626 return; |
|
627 } |
|
628 |
|
629 #if EOE_DEBUG_LEVEL >= 2 |
604 if (wakeup) |
630 if (wakeup) |
605 EC_DBG("EoE %s waking up TX queue...\n", eoe->dev->name); |
631 EC_DBG("EoE %s waking up TX queue...\n", eoe->dev->name); |
606 #endif |
632 #endif |
607 |
633 |
|
634 eoe->tries = EC_EOE_TRIES; |
608 eoe->state = ec_eoe_state_tx_sent; |
635 eoe->state = ec_eoe_state_tx_sent; |
609 } |
636 } |
610 |
637 |
611 /*****************************************************************************/ |
638 /*****************************************************************************/ |
612 |
639 |
617 */ |
644 */ |
618 |
645 |
619 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */) |
646 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */) |
620 { |
647 { |
621 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { |
648 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { |
622 eoe->stats.tx_errors++; |
649 if (eoe->tries) { |
623 eoe->state = ec_eoe_state_rx_start; |
650 eoe->tries--; // try again |
|
651 eoe->queue_datagram = 1; |
|
652 #if EOE_DEBUG_LEVEL >= 1 |
|
653 EC_WARN("Failed to receive send datagram for %s. Retrying.\n", |
|
654 eoe->dev->name); |
|
655 #endif |
|
656 } else { |
|
657 eoe->stats.tx_errors++; |
|
658 #if EOE_DEBUG_LEVEL >= 1 |
|
659 EC_WARN("Failed to receive send datagram for %s. Giving up.\n", |
|
660 eoe->dev->name); |
|
661 #endif |
|
662 eoe->state = ec_eoe_state_rx_start; |
|
663 } |
624 return; |
664 return; |
625 } |
665 } |
626 |
666 |
627 if (eoe->datagram.working_counter != 1) { |
667 if (eoe->datagram.working_counter != 1) { |
628 eoe->stats.tx_errors++; |
668 if (eoe->tries) { |
629 eoe->state = ec_eoe_state_rx_start; |
669 eoe->tries--; // try again |
|
670 eoe->queue_datagram = 1; |
|
671 #if EOE_DEBUG_LEVEL >= 1 |
|
672 EC_WARN("No sending response for %s. Retrying.\n", eoe->dev->name); |
|
673 #endif |
|
674 } else { |
|
675 eoe->stats.tx_errors++; |
|
676 #if EOE_DEBUG_LEVEL >= 1 |
|
677 EC_WARN("No sending response for %s. Giving up.\n", eoe->dev->name); |
|
678 #endif |
|
679 eoe->state = ec_eoe_state_rx_start; |
|
680 } |
630 return; |
681 return; |
631 } |
682 } |
632 |
683 |
633 // frame completely sent |
684 // frame completely sent |
634 if (eoe->tx_offset >= eoe->tx_frame->skb->len) { |
685 if (eoe->tx_offset >= eoe->tx_frame->skb->len) { |
644 if (ec_eoe_send(eoe)) { |
695 if (ec_eoe_send(eoe)) { |
645 dev_kfree_skb(eoe->tx_frame->skb); |
696 dev_kfree_skb(eoe->tx_frame->skb); |
646 kfree(eoe->tx_frame); |
697 kfree(eoe->tx_frame); |
647 eoe->tx_frame = NULL; |
698 eoe->tx_frame = NULL; |
648 eoe->stats.tx_errors++; |
699 eoe->stats.tx_errors++; |
|
700 #if EOE_DEBUG_LEVEL >= 1 |
|
701 EC_WARN("Send error at %s.\n", eoe->dev->name); |
|
702 #endif |
649 eoe->state = ec_eoe_state_rx_start; |
703 eoe->state = ec_eoe_state_rx_start; |
650 } |
704 } |
651 } |
705 } |
652 } |
706 } |
653 |
707 |
727 netif_stop_queue(dev); |
781 netif_stop_queue(dev); |
728 eoe->tx_queue_active = 0; |
782 eoe->tx_queue_active = 0; |
729 } |
783 } |
730 spin_unlock_bh(&eoe->tx_queue_lock); |
784 spin_unlock_bh(&eoe->tx_queue_lock); |
731 |
785 |
732 #if EOE_DEBUG_LEVEL > 0 |
786 #if EOE_DEBUG_LEVEL >= 2 |
733 EC_DBG("EoE %s TX queued frame with %u octets (%u frames queued).\n", |
787 EC_DBG("EoE %s TX queued frame with %u octets (%u frames queued).\n", |
734 eoe->dev->name, skb->len, eoe->tx_queued_frames); |
788 eoe->dev->name, skb->len, eoe->tx_queued_frames); |
735 if (!eoe->tx_queue_active) |
789 if (!eoe->tx_queue_active) |
736 EC_WARN("EoE TX queue is now full.\n"); |
790 EC_WARN("EoE TX queue is now full.\n"); |
737 #endif |
791 #endif |