From 27f4c209a28d2ee4a7b1269de6029f4f3821256f Mon Sep 17 00:00:00 2001
From: Florian Pose <fp@igh-essen.com>
Date: Tue, 1 Aug 2006 18:37:55 +0000
Subject: [PATCH] Improved EoE state machine.

---
 master/ethernet.c | 174 +++++++++++++++++++++++-----------------------
 1 file changed, 88 insertions(+), 86 deletions(-)

diff --git a/master/ethernet.c b/master/ethernet.c
index fcc85f2e..7763f86a 100644
--- a/master/ethernet.c
+++ b/master/ethernet.c
@@ -384,114 +384,116 @@ void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */)
 
     frame_type = EC_READ_U16(data) & 0x000F;
 
-    if (frame_type == 0x00) { // EoE Fragment Request
-        last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
-        time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
-        fragment_number = EC_READ_U16(data + 2) & 0x003F;
-        fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
-        frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
+    if (frame_type != 0x00) {
+#if EOE_DEBUG_LEVEL > 0
+        EC_DBG("other frame received.\n");
+#endif
+        eoe->stats.rx_dropped++;
+        eoe->state = ec_eoe_state_tx_start;
+        return;
+    }
+
+    // EoE Fragment Request received
+
+    last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
+    time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
+    fragment_number = EC_READ_U16(data + 2) & 0x003F;
+    fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
+    frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
 
 #if EOE_DEBUG_LEVEL > 0
-        EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
-               " %i octets\n", fragment_number, fragment_offset,
-               frame_number,
-               last_fragment ? ", last fragment" : "",
-               time_appended ? ", + timestamp" : "",
-               time_appended ? rec_size - 8 : rec_size - 4);
+    EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
+           " %i octets\n", fragment_number, fragment_offset,
+           frame_number,
+           last_fragment ? ", last fragment" : "",
+           time_appended ? ", + timestamp" : "",
+           time_appended ? rec_size - 8 : rec_size - 4);
 #endif
 
 #if EOE_DEBUG_LEVEL > 1
-        EC_DBG("");
-        for (i = 0; i < rec_size - 4; i++) {
-            printk("%02X ", data[i + 4]);
-            if ((i + 1) % 16 == 0) {
-                printk("\n");
-                EC_DBG("");
-            }
+    EC_DBG("");
+    for (i = 0; i < rec_size - 4; i++) {
+        printk("%02X ", data[i + 4]);
+        if ((i + 1) % 16 == 0) {
+            printk("\n");
+            EC_DBG("");
         }
-        printk("\n");
+    }
+    printk("\n");
 #endif
 
-        data_size = time_appended ? rec_size - 8 : rec_size - 4;
-
-        if (!fragment_number) {
-            if (eoe->rx_skb) {
-                EC_WARN("EoE RX freeing old socket buffer...\n");
-                dev_kfree_skb(eoe->rx_skb);
-            }
-
-            // new socket buffer
-            if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
-                if (printk_ratelimit())
-                    EC_WARN("EoE RX low on mem. frame dropped.\n");
-                eoe->stats.rx_dropped++;
-                eoe->state = ec_eoe_state_tx_start;
-                return;
-            }
-
-            eoe->rx_skb_offset = 0;
-            eoe->rx_skb_size = fragment_offset * 32;
-            eoe->rx_expected_fragment = 0;
-        }
-        else {
-            if (!eoe->rx_skb) {
-                eoe->stats.rx_dropped++;
-                eoe->state = ec_eoe_state_tx_start;
-                return;
-            }
-
-            offset = fragment_offset * 32;
-            if (offset != eoe->rx_skb_offset ||
-                offset + data_size > eoe->rx_skb_size ||
-                fragment_number != eoe->rx_expected_fragment) {
-                eoe->stats.rx_errors++;
-                eoe->state = ec_eoe_state_tx_start;
-                dev_kfree_skb(eoe->rx_skb);
-                eoe->rx_skb = NULL;
-                return;
-            }
-        }
+    data_size = time_appended ? rec_size - 8 : rec_size - 4;
 
-        // copy fragment into socket buffer
-        memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
-        eoe->rx_skb_offset += data_size;
+    if (!fragment_number) {
+        if (eoe->rx_skb) {
+            EC_WARN("EoE RX freeing old socket buffer...\n");
+            dev_kfree_skb(eoe->rx_skb);
+        }
 
-        if (last_fragment) {
-            // update statistics
-            eoe->stats.rx_packets++;
-            eoe->stats.rx_bytes += eoe->rx_skb->len;
+        // new socket buffer
+        if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
+            if (printk_ratelimit())
+                EC_WARN("EoE RX low on mem. frame dropped.\n");
+            eoe->stats.rx_dropped++;
+            eoe->state = ec_eoe_state_tx_start;
+            return;
+        }
 
-#if EOE_DEBUG_LEVEL > 0
-            EC_DBG("EoE RX frame completed with %u octets.\n",
-                   eoe->rx_skb->len);
-#endif
+        eoe->rx_skb_offset = 0;
+        eoe->rx_skb_size = fragment_offset * 32;
+        eoe->rx_expected_fragment = 0;
+    }
+    else {
+        if (!eoe->rx_skb) {
+            eoe->stats.rx_dropped++;
+            eoe->state = ec_eoe_state_tx_start;
+            return;
+        }
 
-            // pass socket buffer to network stack
-            eoe->rx_skb->dev = eoe->dev;
-            eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
-            eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
-            if (netif_rx(eoe->rx_skb)) {
-                EC_WARN("EoE RX netif_rx failed.\n");
-            }
+        offset = fragment_offset * 32;
+        if (offset != eoe->rx_skb_offset ||
+            offset + data_size > eoe->rx_skb_size ||
+            fragment_number != eoe->rx_expected_fragment) {
+            dev_kfree_skb(eoe->rx_skb);
             eoe->rx_skb = NULL;
-
+            eoe->stats.rx_errors++;
             eoe->state = ec_eoe_state_tx_start;
+            return;
         }
-        else {
-            eoe->rx_expected_fragment++;
+    }
+
+    // copy fragment into socket buffer
+    memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
+    eoe->rx_skb_offset += data_size;
+
+    if (last_fragment) {
+        // update statistics
+        eoe->stats.rx_packets++;
+        eoe->stats.rx_bytes += eoe->rx_skb->len;
+
 #if EOE_DEBUG_LEVEL > 0
-            EC_DBG("EoE RX expecting fragment %i\n",
-                   eoe->rx_expected_fragment);
+        EC_DBG("EoE RX frame completed with %u octets.\n",
+               eoe->rx_skb->len);
 #endif
-            eoe->state = ec_eoe_state_rx_start;
+
+        // pass socket buffer to network stack
+        eoe->rx_skb->dev = eoe->dev;
+        eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
+        eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
+        if (netif_rx(eoe->rx_skb)) {
+            EC_WARN("EoE RX netif_rx failed.\n");
         }
+        eoe->rx_skb = NULL;
+
+        eoe->state = ec_eoe_state_tx_start;
     }
     else {
+        eoe->rx_expected_fragment++;
 #if EOE_DEBUG_LEVEL > 0
-        EC_DBG("other frame received.\n");
+        EC_DBG("EoE RX expecting fragment %i\n",
+               eoe->rx_expected_fragment);
 #endif
-        eoe->stats.rx_dropped++;
-        eoe->state = ec_eoe_state_tx_start;
+        eoe->state = ec_eoe_state_rx_start;
     }
 }
 
-- 
GitLab