diff -r f149465f4c63 -r e675450f2174 master/ethernet.c --- a/master/ethernet.c Thu Jul 13 13:10:57 2006 +0000 +++ b/master/ethernet.c Thu Aug 03 12:59:01 2006 +0000 @@ -155,10 +155,8 @@ void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */) { - if (eoe->dev) { - unregister_netdev(eoe->dev); - free_netdev(eoe->dev); - } + unregister_netdev(eoe->dev); + free_netdev(eoe->dev); // empty transmit queue ec_eoe_flush(eoe); @@ -225,6 +223,7 @@ complete_offset = eoe->tx_offset / 32; } else { + // complete size in 32 bit blocks, rounded up. complete_offset = remaining_size / 32 + 1; } @@ -291,22 +290,6 @@ return eoe->slave && eoe->opened; } -/*****************************************************************************/ - -/** - Prints EoE handler information. -*/ - -void ec_eoe_print(const ec_eoe_t *eoe /**< EoE handler */) -{ - EC_INFO(" EoE handler %s\n", eoe->dev->name); - EC_INFO(" State: %s\n", eoe->opened ? "opened" : "closed"); - if (eoe->slave) - EC_INFO(" Coupled to slave %i.\n", eoe->slave->ring_position); - else - EC_INFO(" Not coupled.\n"); -} - /****************************************************************************** * STATE PROCESSING FUNCTIONS *****************************************************************************/ @@ -337,7 +320,7 @@ void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */) { - if (eoe->datagram.state != EC_CMD_RECEIVED) { + if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { eoe->stats.rx_errors++; eoe->state = ec_eoe_state_tx_start; return; @@ -368,7 +351,7 @@ uint8_t frame_number, fragment_offset, fragment_number; off_t offset; - if (eoe->datagram.state != EC_CMD_RECEIVED) { + if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { eoe->stats.rx_errors++; eoe->state = ec_eoe_state_tx_start; return; @@ -383,114 +366,116 @@ 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 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); -#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(""); - } - } - 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; - } - } - - // 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 frame completed with %u octets.\n", - eoe->rx_skb->len); -#endif - - // 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("EoE RX expecting fragment %i\n", - eoe->rx_expected_fragment); -#endif - eoe->state = ec_eoe_state_rx_start; - } - } - else { + 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); +#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(""); + } + } + 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) { + dev_kfree_skb(eoe->rx_skb); + eoe->rx_skb = NULL; + eoe->stats.rx_errors++; + eoe->state = ec_eoe_state_tx_start; + return; + } + } + + // 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 frame completed with %u octets.\n", + eoe->rx_skb->len); +#endif + + // 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("EoE RX expecting fragment %i\n", + eoe->rx_expected_fragment); +#endif + eoe->state = ec_eoe_state_rx_start; } } @@ -567,7 +552,7 @@ void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */) { - if (eoe->datagram.state != EC_CMD_RECEIVED) { + if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) { eoe->stats.tx_errors++; eoe->state = ec_eoe_state_rx_start; return;