master/ethernet.c
branchstable-1.1
changeset 1715 e675450f2174
parent 294 feea8d850c65
child 1716 9440f4ff25c7
equal deleted inserted replaced
1714:f149465f4c63 1715:e675450f2174
   153    Unregisteres the net_device and frees allocated memory.
   153    Unregisteres the net_device and frees allocated memory.
   154 */
   154 */
   155 
   155 
   156 void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
   156 void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
   157 {
   157 {
   158     if (eoe->dev) {
   158     unregister_netdev(eoe->dev);
   159         unregister_netdev(eoe->dev);
   159     free_netdev(eoe->dev);
   160         free_netdev(eoe->dev);
       
   161     }
       
   162 
   160 
   163     // empty transmit queue
   161     // empty transmit queue
   164     ec_eoe_flush(eoe);
   162     ec_eoe_flush(eoe);
   165 
   163 
   166     if (eoe->tx_frame) {
   164     if (eoe->tx_frame) {
   223 
   221 
   224     if (eoe->tx_fragment_number) {
   222     if (eoe->tx_fragment_number) {
   225         complete_offset = eoe->tx_offset / 32;
   223         complete_offset = eoe->tx_offset / 32;
   226     }
   224     }
   227     else {
   225     else {
       
   226         // complete size in 32 bit blocks, rounded up.
   228         complete_offset = remaining_size / 32 + 1;
   227         complete_offset = remaining_size / 32 + 1;
   229     }
   228     }
   230 
   229 
   231 #if EOE_DEBUG_LEVEL > 0
   230 #if EOE_DEBUG_LEVEL > 0
   232     EC_DBG("EoE TX sending %sfragment %i with %i octets (%i)."
   231     EC_DBG("EoE TX sending %sfragment %i with %i octets (%i)."
   289 unsigned int ec_eoe_active(const ec_eoe_t *eoe /**< EoE handler */)
   288 unsigned int ec_eoe_active(const ec_eoe_t *eoe /**< EoE handler */)
   290 {
   289 {
   291     return eoe->slave && eoe->opened;
   290     return eoe->slave && eoe->opened;
   292 }
   291 }
   293 
   292 
   294 /*****************************************************************************/
       
   295 
       
   296 /**
       
   297    Prints EoE handler information.
       
   298 */
       
   299 
       
   300 void ec_eoe_print(const ec_eoe_t *eoe /**< EoE handler */)
       
   301 {
       
   302     EC_INFO("  EoE handler %s\n", eoe->dev->name);
       
   303     EC_INFO("    State: %s\n", eoe->opened ? "opened" : "closed");
       
   304     if (eoe->slave)
       
   305         EC_INFO("    Coupled to slave %i.\n", eoe->slave->ring_position);
       
   306     else
       
   307         EC_INFO("    Not coupled.\n");
       
   308 }
       
   309 
       
   310 /******************************************************************************
   293 /******************************************************************************
   311  *  STATE PROCESSING FUNCTIONS
   294  *  STATE PROCESSING FUNCTIONS
   312  *****************************************************************************/
   295  *****************************************************************************/
   313 
   296 
   314 /**
   297 /**
   335    datagram, if new data is available.
   318    datagram, if new data is available.
   336 */
   319 */
   337 
   320 
   338 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
   321 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
   339 {
   322 {
   340     if (eoe->datagram.state != EC_CMD_RECEIVED) {
   323     if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
   341         eoe->stats.rx_errors++;
   324         eoe->stats.rx_errors++;
   342         eoe->state = ec_eoe_state_tx_start;
   325         eoe->state = ec_eoe_state_tx_start;
   343         return;
   326         return;
   344     }
   327     }
   345 
   328 
   366     size_t rec_size, data_size;
   349     size_t rec_size, data_size;
   367     uint8_t *data, frame_type, last_fragment, time_appended;
   350     uint8_t *data, frame_type, last_fragment, time_appended;
   368     uint8_t frame_number, fragment_offset, fragment_number;
   351     uint8_t frame_number, fragment_offset, fragment_number;
   369     off_t offset;
   352     off_t offset;
   370 
   353 
   371     if (eoe->datagram.state != EC_CMD_RECEIVED) {
   354     if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
   372         eoe->stats.rx_errors++;
   355         eoe->stats.rx_errors++;
   373         eoe->state = ec_eoe_state_tx_start;
   356         eoe->state = ec_eoe_state_tx_start;
   374         return;
   357         return;
   375     }
   358     }
   376 
   359 
   381         return;
   364         return;
   382     }
   365     }
   383 
   366 
   384     frame_type = EC_READ_U16(data) & 0x000F;
   367     frame_type = EC_READ_U16(data) & 0x000F;
   385 
   368 
   386     if (frame_type == 0x00) { // EoE Fragment Request
   369     if (frame_type != 0x00) {
   387         last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
       
   388         time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
       
   389         fragment_number = EC_READ_U16(data + 2) & 0x003F;
       
   390         fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
       
   391         frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
       
   392 
       
   393 #if EOE_DEBUG_LEVEL > 0
       
   394         EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
       
   395                " %i octets\n", fragment_number, fragment_offset,
       
   396                frame_number,
       
   397                last_fragment ? ", last fragment" : "",
       
   398                time_appended ? ", + timestamp" : "",
       
   399                time_appended ? rec_size - 8 : rec_size - 4);
       
   400 #endif
       
   401 
       
   402 #if EOE_DEBUG_LEVEL > 1
       
   403         EC_DBG("");
       
   404         for (i = 0; i < rec_size - 4; i++) {
       
   405             printk("%02X ", data[i + 4]);
       
   406             if ((i + 1) % 16 == 0) {
       
   407                 printk("\n");
       
   408                 EC_DBG("");
       
   409             }
       
   410         }
       
   411         printk("\n");
       
   412 #endif
       
   413 
       
   414         data_size = time_appended ? rec_size - 8 : rec_size - 4;
       
   415 
       
   416         if (!fragment_number) {
       
   417             if (eoe->rx_skb) {
       
   418                 EC_WARN("EoE RX freeing old socket buffer...\n");
       
   419                 dev_kfree_skb(eoe->rx_skb);
       
   420             }
       
   421 
       
   422             // new socket buffer
       
   423             if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
       
   424                 if (printk_ratelimit())
       
   425                     EC_WARN("EoE RX low on mem. frame dropped.\n");
       
   426                 eoe->stats.rx_dropped++;
       
   427                 eoe->state = ec_eoe_state_tx_start;
       
   428                 return;
       
   429             }
       
   430 
       
   431             eoe->rx_skb_offset = 0;
       
   432             eoe->rx_skb_size = fragment_offset * 32;
       
   433             eoe->rx_expected_fragment = 0;
       
   434         }
       
   435         else {
       
   436             if (!eoe->rx_skb) {
       
   437                 eoe->stats.rx_dropped++;
       
   438                 eoe->state = ec_eoe_state_tx_start;
       
   439                 return;
       
   440             }
       
   441 
       
   442             offset = fragment_offset * 32;
       
   443             if (offset != eoe->rx_skb_offset ||
       
   444                 offset + data_size > eoe->rx_skb_size ||
       
   445                 fragment_number != eoe->rx_expected_fragment) {
       
   446                 eoe->stats.rx_errors++;
       
   447                 eoe->state = ec_eoe_state_tx_start;
       
   448                 dev_kfree_skb(eoe->rx_skb);
       
   449                 eoe->rx_skb = NULL;
       
   450                 return;
       
   451             }
       
   452         }
       
   453 
       
   454         // copy fragment into socket buffer
       
   455         memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
       
   456         eoe->rx_skb_offset += data_size;
       
   457 
       
   458         if (last_fragment) {
       
   459             // update statistics
       
   460             eoe->stats.rx_packets++;
       
   461             eoe->stats.rx_bytes += eoe->rx_skb->len;
       
   462 
       
   463 #if EOE_DEBUG_LEVEL > 0
       
   464             EC_DBG("EoE RX frame completed with %u octets.\n",
       
   465                    eoe->rx_skb->len);
       
   466 #endif
       
   467 
       
   468             // pass socket buffer to network stack
       
   469             eoe->rx_skb->dev = eoe->dev;
       
   470             eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
       
   471             eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
       
   472             if (netif_rx(eoe->rx_skb)) {
       
   473                 EC_WARN("EoE RX netif_rx failed.\n");
       
   474             }
       
   475             eoe->rx_skb = NULL;
       
   476 
       
   477             eoe->state = ec_eoe_state_tx_start;
       
   478         }
       
   479         else {
       
   480             eoe->rx_expected_fragment++;
       
   481 #if EOE_DEBUG_LEVEL > 0
       
   482             EC_DBG("EoE RX expecting fragment %i\n",
       
   483                    eoe->rx_expected_fragment);
       
   484 #endif
       
   485             eoe->state = ec_eoe_state_rx_start;
       
   486         }
       
   487     }
       
   488     else {
       
   489 #if EOE_DEBUG_LEVEL > 0
   370 #if EOE_DEBUG_LEVEL > 0
   490         EC_DBG("other frame received.\n");
   371         EC_DBG("other frame received.\n");
   491 #endif
   372 #endif
   492         eoe->stats.rx_dropped++;
   373         eoe->stats.rx_dropped++;
   493         eoe->state = ec_eoe_state_tx_start;
   374         eoe->state = ec_eoe_state_tx_start;
       
   375         return;
       
   376     }
       
   377 
       
   378     // EoE Fragment Request received
       
   379 
       
   380     last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
       
   381     time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
       
   382     fragment_number = EC_READ_U16(data + 2) & 0x003F;
       
   383     fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
       
   384     frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
       
   385 
       
   386 #if EOE_DEBUG_LEVEL > 0
       
   387     EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
       
   388            " %i octets\n", fragment_number, fragment_offset,
       
   389            frame_number,
       
   390            last_fragment ? ", last fragment" : "",
       
   391            time_appended ? ", + timestamp" : "",
       
   392            time_appended ? rec_size - 8 : rec_size - 4);
       
   393 #endif
       
   394 
       
   395 #if EOE_DEBUG_LEVEL > 1
       
   396     EC_DBG("");
       
   397     for (i = 0; i < rec_size - 4; i++) {
       
   398         printk("%02X ", data[i + 4]);
       
   399         if ((i + 1) % 16 == 0) {
       
   400             printk("\n");
       
   401             EC_DBG("");
       
   402         }
       
   403     }
       
   404     printk("\n");
       
   405 #endif
       
   406 
       
   407     data_size = time_appended ? rec_size - 8 : rec_size - 4;
       
   408 
       
   409     if (!fragment_number) {
       
   410         if (eoe->rx_skb) {
       
   411             EC_WARN("EoE RX freeing old socket buffer...\n");
       
   412             dev_kfree_skb(eoe->rx_skb);
       
   413         }
       
   414 
       
   415         // new socket buffer
       
   416         if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
       
   417             if (printk_ratelimit())
       
   418                 EC_WARN("EoE RX low on mem. frame dropped.\n");
       
   419             eoe->stats.rx_dropped++;
       
   420             eoe->state = ec_eoe_state_tx_start;
       
   421             return;
       
   422         }
       
   423 
       
   424         eoe->rx_skb_offset = 0;
       
   425         eoe->rx_skb_size = fragment_offset * 32;
       
   426         eoe->rx_expected_fragment = 0;
       
   427     }
       
   428     else {
       
   429         if (!eoe->rx_skb) {
       
   430             eoe->stats.rx_dropped++;
       
   431             eoe->state = ec_eoe_state_tx_start;
       
   432             return;
       
   433         }
       
   434 
       
   435         offset = fragment_offset * 32;
       
   436         if (offset != eoe->rx_skb_offset ||
       
   437             offset + data_size > eoe->rx_skb_size ||
       
   438             fragment_number != eoe->rx_expected_fragment) {
       
   439             dev_kfree_skb(eoe->rx_skb);
       
   440             eoe->rx_skb = NULL;
       
   441             eoe->stats.rx_errors++;
       
   442             eoe->state = ec_eoe_state_tx_start;
       
   443             return;
       
   444         }
       
   445     }
       
   446 
       
   447     // copy fragment into socket buffer
       
   448     memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
       
   449     eoe->rx_skb_offset += data_size;
       
   450 
       
   451     if (last_fragment) {
       
   452         // update statistics
       
   453         eoe->stats.rx_packets++;
       
   454         eoe->stats.rx_bytes += eoe->rx_skb->len;
       
   455 
       
   456 #if EOE_DEBUG_LEVEL > 0
       
   457         EC_DBG("EoE RX frame completed with %u octets.\n",
       
   458                eoe->rx_skb->len);
       
   459 #endif
       
   460 
       
   461         // pass socket buffer to network stack
       
   462         eoe->rx_skb->dev = eoe->dev;
       
   463         eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
       
   464         eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
       
   465         if (netif_rx(eoe->rx_skb)) {
       
   466             EC_WARN("EoE RX netif_rx failed.\n");
       
   467         }
       
   468         eoe->rx_skb = NULL;
       
   469 
       
   470         eoe->state = ec_eoe_state_tx_start;
       
   471     }
       
   472     else {
       
   473         eoe->rx_expected_fragment++;
       
   474 #if EOE_DEBUG_LEVEL > 0
       
   475         EC_DBG("EoE RX expecting fragment %i\n",
       
   476                eoe->rx_expected_fragment);
       
   477 #endif
       
   478         eoe->state = ec_eoe_state_rx_start;
   494     }
   479     }
   495 }
   480 }
   496 
   481 
   497 /*****************************************************************************/
   482 /*****************************************************************************/
   498 
   483 
   565    fragment, if necessary.
   550    fragment, if necessary.
   566 */
   551 */
   567 
   552 
   568 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
   553 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
   569 {
   554 {
   570     if (eoe->datagram.state != EC_CMD_RECEIVED) {
   555     if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
   571         eoe->stats.tx_errors++;
   556         eoe->stats.tx_errors++;
   572         eoe->state = ec_eoe_state_rx_start;
   557         eoe->state = ec_eoe_state_rx_start;
   573         return;
   558         return;
   574     }
   559     }
   575 
   560