diff --git a/master/ethernet.c b/master/ethernet.c index fcc85f2e5b4f406676f6e3128e55b486e37ddeb2..7763f86a8199b479b98f61d6ec58d450282c4dbe 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; } }