master/ethernet.c
changeset 322 fceb7b6e0a06
parent 319 88f2e8c4face
child 325 7833cf70c4f2
equal deleted inserted replaced
321:64e20e6e9d0b 322:fceb7b6e0a06
   382         return;
   382         return;
   383     }
   383     }
   384 
   384 
   385     frame_type = EC_READ_U16(data) & 0x000F;
   385     frame_type = EC_READ_U16(data) & 0x000F;
   386 
   386 
   387     if (frame_type == 0x00) { // EoE Fragment Request
   387     if (frame_type != 0x00) {
   388         last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
       
   389         time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
       
   390         fragment_number = EC_READ_U16(data + 2) & 0x003F;
       
   391         fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
       
   392         frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
       
   393 
       
   394 #if EOE_DEBUG_LEVEL > 0
       
   395         EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
       
   396                " %i octets\n", fragment_number, fragment_offset,
       
   397                frame_number,
       
   398                last_fragment ? ", last fragment" : "",
       
   399                time_appended ? ", + timestamp" : "",
       
   400                time_appended ? rec_size - 8 : rec_size - 4);
       
   401 #endif
       
   402 
       
   403 #if EOE_DEBUG_LEVEL > 1
       
   404         EC_DBG("");
       
   405         for (i = 0; i < rec_size - 4; i++) {
       
   406             printk("%02X ", data[i + 4]);
       
   407             if ((i + 1) % 16 == 0) {
       
   408                 printk("\n");
       
   409                 EC_DBG("");
       
   410             }
       
   411         }
       
   412         printk("\n");
       
   413 #endif
       
   414 
       
   415         data_size = time_appended ? rec_size - 8 : rec_size - 4;
       
   416 
       
   417         if (!fragment_number) {
       
   418             if (eoe->rx_skb) {
       
   419                 EC_WARN("EoE RX freeing old socket buffer...\n");
       
   420                 dev_kfree_skb(eoe->rx_skb);
       
   421             }
       
   422 
       
   423             // new socket buffer
       
   424             if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
       
   425                 if (printk_ratelimit())
       
   426                     EC_WARN("EoE RX low on mem. frame dropped.\n");
       
   427                 eoe->stats.rx_dropped++;
       
   428                 eoe->state = ec_eoe_state_tx_start;
       
   429                 return;
       
   430             }
       
   431 
       
   432             eoe->rx_skb_offset = 0;
       
   433             eoe->rx_skb_size = fragment_offset * 32;
       
   434             eoe->rx_expected_fragment = 0;
       
   435         }
       
   436         else {
       
   437             if (!eoe->rx_skb) {
       
   438                 eoe->stats.rx_dropped++;
       
   439                 eoe->state = ec_eoe_state_tx_start;
       
   440                 return;
       
   441             }
       
   442 
       
   443             offset = fragment_offset * 32;
       
   444             if (offset != eoe->rx_skb_offset ||
       
   445                 offset + data_size > eoe->rx_skb_size ||
       
   446                 fragment_number != eoe->rx_expected_fragment) {
       
   447                 eoe->stats.rx_errors++;
       
   448                 eoe->state = ec_eoe_state_tx_start;
       
   449                 dev_kfree_skb(eoe->rx_skb);
       
   450                 eoe->rx_skb = NULL;
       
   451                 return;
       
   452             }
       
   453         }
       
   454 
       
   455         // copy fragment into socket buffer
       
   456         memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
       
   457         eoe->rx_skb_offset += data_size;
       
   458 
       
   459         if (last_fragment) {
       
   460             // update statistics
       
   461             eoe->stats.rx_packets++;
       
   462             eoe->stats.rx_bytes += eoe->rx_skb->len;
       
   463 
       
   464 #if EOE_DEBUG_LEVEL > 0
       
   465             EC_DBG("EoE RX frame completed with %u octets.\n",
       
   466                    eoe->rx_skb->len);
       
   467 #endif
       
   468 
       
   469             // pass socket buffer to network stack
       
   470             eoe->rx_skb->dev = eoe->dev;
       
   471             eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
       
   472             eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
       
   473             if (netif_rx(eoe->rx_skb)) {
       
   474                 EC_WARN("EoE RX netif_rx failed.\n");
       
   475             }
       
   476             eoe->rx_skb = NULL;
       
   477 
       
   478             eoe->state = ec_eoe_state_tx_start;
       
   479         }
       
   480         else {
       
   481             eoe->rx_expected_fragment++;
       
   482 #if EOE_DEBUG_LEVEL > 0
       
   483             EC_DBG("EoE RX expecting fragment %i\n",
       
   484                    eoe->rx_expected_fragment);
       
   485 #endif
       
   486             eoe->state = ec_eoe_state_rx_start;
       
   487         }
       
   488     }
       
   489     else {
       
   490 #if EOE_DEBUG_LEVEL > 0
   388 #if EOE_DEBUG_LEVEL > 0
   491         EC_DBG("other frame received.\n");
   389         EC_DBG("other frame received.\n");
   492 #endif
   390 #endif
   493         eoe->stats.rx_dropped++;
   391         eoe->stats.rx_dropped++;
   494         eoe->state = ec_eoe_state_tx_start;
   392         eoe->state = ec_eoe_state_tx_start;
       
   393         return;
       
   394     }
       
   395 
       
   396     // EoE Fragment Request received
       
   397 
       
   398     last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
       
   399     time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
       
   400     fragment_number = EC_READ_U16(data + 2) & 0x003F;
       
   401     fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
       
   402     frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
       
   403 
       
   404 #if EOE_DEBUG_LEVEL > 0
       
   405     EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
       
   406            " %i octets\n", fragment_number, fragment_offset,
       
   407            frame_number,
       
   408            last_fragment ? ", last fragment" : "",
       
   409            time_appended ? ", + timestamp" : "",
       
   410            time_appended ? rec_size - 8 : rec_size - 4);
       
   411 #endif
       
   412 
       
   413 #if EOE_DEBUG_LEVEL > 1
       
   414     EC_DBG("");
       
   415     for (i = 0; i < rec_size - 4; i++) {
       
   416         printk("%02X ", data[i + 4]);
       
   417         if ((i + 1) % 16 == 0) {
       
   418             printk("\n");
       
   419             EC_DBG("");
       
   420         }
       
   421     }
       
   422     printk("\n");
       
   423 #endif
       
   424 
       
   425     data_size = time_appended ? rec_size - 8 : rec_size - 4;
       
   426 
       
   427     if (!fragment_number) {
       
   428         if (eoe->rx_skb) {
       
   429             EC_WARN("EoE RX freeing old socket buffer...\n");
       
   430             dev_kfree_skb(eoe->rx_skb);
       
   431         }
       
   432 
       
   433         // new socket buffer
       
   434         if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
       
   435             if (printk_ratelimit())
       
   436                 EC_WARN("EoE RX low on mem. frame dropped.\n");
       
   437             eoe->stats.rx_dropped++;
       
   438             eoe->state = ec_eoe_state_tx_start;
       
   439             return;
       
   440         }
       
   441 
       
   442         eoe->rx_skb_offset = 0;
       
   443         eoe->rx_skb_size = fragment_offset * 32;
       
   444         eoe->rx_expected_fragment = 0;
       
   445     }
       
   446     else {
       
   447         if (!eoe->rx_skb) {
       
   448             eoe->stats.rx_dropped++;
       
   449             eoe->state = ec_eoe_state_tx_start;
       
   450             return;
       
   451         }
       
   452 
       
   453         offset = fragment_offset * 32;
       
   454         if (offset != eoe->rx_skb_offset ||
       
   455             offset + data_size > eoe->rx_skb_size ||
       
   456             fragment_number != eoe->rx_expected_fragment) {
       
   457             dev_kfree_skb(eoe->rx_skb);
       
   458             eoe->rx_skb = NULL;
       
   459             eoe->stats.rx_errors++;
       
   460             eoe->state = ec_eoe_state_tx_start;
       
   461             return;
       
   462         }
       
   463     }
       
   464 
       
   465     // copy fragment into socket buffer
       
   466     memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
       
   467     eoe->rx_skb_offset += data_size;
       
   468 
       
   469     if (last_fragment) {
       
   470         // update statistics
       
   471         eoe->stats.rx_packets++;
       
   472         eoe->stats.rx_bytes += eoe->rx_skb->len;
       
   473 
       
   474 #if EOE_DEBUG_LEVEL > 0
       
   475         EC_DBG("EoE RX frame completed with %u octets.\n",
       
   476                eoe->rx_skb->len);
       
   477 #endif
       
   478 
       
   479         // pass socket buffer to network stack
       
   480         eoe->rx_skb->dev = eoe->dev;
       
   481         eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
       
   482         eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
       
   483         if (netif_rx(eoe->rx_skb)) {
       
   484             EC_WARN("EoE RX netif_rx failed.\n");
       
   485         }
       
   486         eoe->rx_skb = NULL;
       
   487 
       
   488         eoe->state = ec_eoe_state_tx_start;
       
   489     }
       
   490     else {
       
   491         eoe->rx_expected_fragment++;
       
   492 #if EOE_DEBUG_LEVEL > 0
       
   493         EC_DBG("EoE RX expecting fragment %i\n",
       
   494                eoe->rx_expected_fragment);
       
   495 #endif
       
   496         eoe->state = ec_eoe_state_rx_start;
   495     }
   497     }
   496 }
   498 }
   497 
   499 
   498 /*****************************************************************************/
   500 /*****************************************************************************/
   499 
   501