master/ethernet.c
branchstable-1.0
changeset 1624 9dc190591c0f
parent 1623 05622513f627
equal deleted inserted replaced
1623:05622513f627 1624:9dc190591c0f
    36    Ethernet-over-EtherCAT (EoE).
    36    Ethernet-over-EtherCAT (EoE).
    37 */
    37 */
    38 
    38 
    39 /*****************************************************************************/
    39 /*****************************************************************************/
    40 
    40 
       
    41 #include <linux/netdevice.h>
    41 #include <linux/etherdevice.h>
    42 #include <linux/etherdevice.h>
    42 
    43 
    43 #include "../include/ecrt.h"
    44 #include "../include/ecrt.h"
    44 #include "globals.h"
    45 #include "globals.h"
    45 #include "master.h"
    46 #include "master.h"
    85 {
    86 {
    86     ec_eoe_t **priv;
    87     ec_eoe_t **priv;
    87     int result, i;
    88     int result, i;
    88 
    89 
    89     eoe->slave = NULL;
    90     eoe->slave = NULL;
    90     ec_command_init(&eoe->command);
    91     ec_datagram_init(&eoe->datagram);
    91     eoe->state = ec_eoe_state_rx_start;
    92     eoe->state = ec_eoe_state_rx_start;
    92     eoe->opened = 0;
    93     eoe->opened = 0;
    93     eoe->rx_skb = NULL;
    94     eoe->rx_skb = NULL;
    94     eoe->rx_expected_fragment = 0;
    95     eoe->rx_expected_fragment = 0;
    95     INIT_LIST_HEAD(&eoe->tx_queue);
    96     INIT_LIST_HEAD(&eoe->tx_queue);
   152    Unregisteres the net_device and frees allocated memory.
   153    Unregisteres the net_device and frees allocated memory.
   153 */
   154 */
   154 
   155 
   155 void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
   156 void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
   156 {
   157 {
   157     if (eoe->dev) {
   158     if (eoe->dev) { // TODO: dev never NULL?
   158         unregister_netdev(eoe->dev);
   159         unregister_netdev(eoe->dev);
   159         free_netdev(eoe->dev);
   160         free_netdev(eoe->dev);
   160     }
   161     }
   161 
   162 
   162     // empty transmit queue
   163     // empty transmit queue
   167         kfree(eoe->tx_frame);
   168         kfree(eoe->tx_frame);
   168     }
   169     }
   169 
   170 
   170     if (eoe->rx_skb) dev_kfree_skb(eoe->rx_skb);
   171     if (eoe->rx_skb) dev_kfree_skb(eoe->rx_skb);
   171 
   172 
   172     ec_command_clear(&eoe->command);
   173     ec_datagram_clear(&eoe->datagram);
   173 }
   174 }
   174 
   175 
   175 /*****************************************************************************/
   176 /*****************************************************************************/
   176 
   177 
   177 /**
   178 /**
   222 
   223 
   223     if (eoe->tx_fragment_number) {
   224     if (eoe->tx_fragment_number) {
   224         complete_offset = eoe->tx_offset / 32;
   225         complete_offset = eoe->tx_offset / 32;
   225     }
   226     }
   226     else {
   227     else {
       
   228         // complete size in 32 bit blocks, rounded up.
   227         complete_offset = remaining_size / 32 + 1;
   229         complete_offset = remaining_size / 32 + 1;
   228     }
   230     }
   229 
   231 
   230 #if EOE_DEBUG_LEVEL > 0
   232 #if EOE_DEBUG_LEVEL > 0
   231     EC_DBG("EoE TX sending %sfragment %i with %i octets (%i)."
   233     EC_DBG("EoE TX sending %sfragment %i with %i octets (%i)."
   244         }
   246         }
   245     }
   247     }
   246     printk("\n");
   248     printk("\n");
   247 #endif
   249 #endif
   248 
   250 
   249     if (!(data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->command,
   251     if (!(data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
   250                                             0x02, current_size + 4)))
   252                                             0x02, current_size + 4)))
   251         return -1;
   253         return -1;
   252 
   254 
   253     EC_WRITE_U8 (data,     0x00); // eoe fragment req.
   255     EC_WRITE_U8 (data,     0x00); // eoe fragment req.
   254     EC_WRITE_U8 (data + 1, last_fragment);
   256     EC_WRITE_U8 (data + 1, last_fragment);
   255     EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) |
   257     EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) |
   256                             (complete_offset & 0x3F) << 6 |
   258                             (complete_offset & 0x3F) << 6 |
   257                             (eoe->tx_frame_number & 0x0F) << 12));
   259                             (eoe->tx_frame_number & 0x0F) << 12));
   258 
   260 
   259     memcpy(data + 4, eoe->tx_frame->skb->data + eoe->tx_offset, current_size);
   261     memcpy(data + 4, eoe->tx_frame->skb->data + eoe->tx_offset, current_size);
   260     ec_master_queue_command(eoe->slave->master, &eoe->command);
   262     ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
   261 
   263 
   262     eoe->tx_offset += current_size;
   264     eoe->tx_offset += current_size;
   263     eoe->tx_fragment_number++;
   265     eoe->tx_fragment_number++;
   264     return 0;
   266     return 0;
   265 }
   267 }
   310  *  STATE PROCESSING FUNCTIONS
   312  *  STATE PROCESSING FUNCTIONS
   311  *****************************************************************************/
   313  *****************************************************************************/
   312 
   314 
   313 /**
   315 /**
   314    State: RX_START.
   316    State: RX_START.
   315    Starts a new receiving sequence by queueing a command that checks the
   317    Starts a new receiving sequence by queueing a datagram that checks the
   316    slave's mailbox for a new EoE command.
   318    slave's mailbox for a new EoE datagram.
   317 */
   319 */
   318 
   320 
   319 void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
   321 void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
   320 {
   322 {
   321     if (!eoe->slave->online || !eoe->slave->master->device->link_state)
   323     if (!eoe->slave->online || !eoe->slave->master->device->link_state)
   322         return;
   324         return;
   323 
   325 
   324     ec_slave_mbox_prepare_check(eoe->slave, &eoe->command);
   326     ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
   325     ec_master_queue_command(eoe->slave->master, &eoe->command);
   327     ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
   326     eoe->state = ec_eoe_state_rx_check;
   328     eoe->state = ec_eoe_state_rx_check;
   327 }
   329 }
   328 
   330 
   329 /*****************************************************************************/
   331 /*****************************************************************************/
   330 
   332 
   331 /**
   333 /**
   332    State: RX_CHECK.
   334    State: RX_CHECK.
   333    Processes the checking command sent in RX_START and issues a receive
   335    Processes the checking datagram sent in RX_START and issues a receive
   334    command, if new data is available.
   336    datagram, if new data is available.
   335 */
   337 */
   336 
   338 
   337 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
   339 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
   338 {
   340 {
   339     if (eoe->command.state != EC_CMD_RECEIVED) {
   341     if (eoe->datagram.state != EC_CMD_RECEIVED) {
   340         eoe->stats.rx_errors++;
   342         eoe->stats.rx_errors++;
   341         eoe->state = ec_eoe_state_tx_start;
   343         eoe->state = ec_eoe_state_tx_start;
   342         return;
   344         return;
   343     }
   345     }
   344 
   346 
   345     if (!ec_slave_mbox_check(&eoe->command)) {
   347     if (!ec_slave_mbox_check(&eoe->datagram)) {
   346         eoe->state = ec_eoe_state_tx_start;
   348         eoe->state = ec_eoe_state_tx_start;
   347         return;
   349         return;
   348     }
   350     }
   349 
   351 
   350     ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->command);
   352     ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram);
   351     ec_master_queue_command(eoe->slave->master, &eoe->command);
   353     ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
   352     eoe->state = ec_eoe_state_rx_fetch;
   354     eoe->state = ec_eoe_state_rx_fetch;
   353 }
   355 }
   354 
   356 
   355 /*****************************************************************************/
   357 /*****************************************************************************/
   356 
   358 
   357 /**
   359 /**
   358    State: RX_FETCH.
   360    State: RX_FETCH.
   359    Checks if the requested data of RX_CHECK was received and processes the
   361    Checks if the requested data of RX_CHECK was received and processes the
   360    EoE command.
   362    EoE datagram.
   361 */
   363 */
   362 
   364 
   363 void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */)
   365 void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */)
   364 {
   366 {
   365     size_t rec_size, data_size;
   367     size_t rec_size, data_size;
   366     uint8_t *data, frame_type, last_fragment, time_appended;
   368     uint8_t *data, frame_type, last_fragment, time_appended;
   367     uint8_t frame_number, fragment_offset, fragment_number;
   369     uint8_t frame_number, fragment_offset, fragment_number;
   368     off_t offset;
   370     off_t offset;
   369 
   371 
   370     if (eoe->command.state != EC_CMD_RECEIVED) {
   372     if (eoe->datagram.state != EC_CMD_RECEIVED) {
   371         eoe->stats.rx_errors++;
   373         eoe->stats.rx_errors++;
   372         eoe->state = ec_eoe_state_tx_start;
   374         eoe->state = ec_eoe_state_tx_start;
   373         return;
   375         return;
   374     }
   376     }
   375 
   377 
   376     if (!(data = ec_slave_mbox_fetch(eoe->slave, &eoe->command,
   378     if (!(data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram,
   377                                      0x02, &rec_size))) {
   379                                      0x02, &rec_size))) {
   378         eoe->stats.rx_errors++;
   380         eoe->stats.rx_errors++;
   379         eoe->state = ec_eoe_state_tx_start;
   381         eoe->state = ec_eoe_state_tx_start;
   380         return;
   382         return;
   381     }
   383     }
   382 
   384 
   383     frame_type = EC_READ_U16(data) & 0x000F;
   385     frame_type = EC_READ_U16(data) & 0x000F;
   384 
   386 
   385     if (frame_type == 0x00) { // EoE Fragment Request
   387     if (frame_type != 0x00) {
   386         last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
       
   387         time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
       
   388         fragment_number = EC_READ_U16(data + 2) & 0x003F;
       
   389         fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
       
   390         frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
       
   391 
       
   392 #if EOE_DEBUG_LEVEL > 0
       
   393         EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
       
   394                " %i octets\n", fragment_number, fragment_offset,
       
   395                frame_number,
       
   396                last_fragment ? ", last fragment" : "",
       
   397                time_appended ? ", + timestamp" : "",
       
   398                time_appended ? rec_size - 8 : rec_size - 4);
       
   399 #endif
       
   400 
       
   401 #if EOE_DEBUG_LEVEL > 1
       
   402         EC_DBG("");
       
   403         for (i = 0; i < rec_size - 4; i++) {
       
   404             printk("%02X ", data[i + 4]);
       
   405             if ((i + 1) % 16 == 0) {
       
   406                 printk("\n");
       
   407                 EC_DBG("");
       
   408             }
       
   409         }
       
   410         printk("\n");
       
   411 #endif
       
   412 
       
   413         data_size = time_appended ? rec_size - 8 : rec_size - 4;
       
   414 
       
   415         if (!fragment_number) {
       
   416             if (eoe->rx_skb) {
       
   417                 EC_WARN("EoE RX freeing old socket buffer...\n");
       
   418                 dev_kfree_skb(eoe->rx_skb);
       
   419             }
       
   420 
       
   421             // new socket buffer
       
   422             if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
       
   423                 if (printk_ratelimit())
       
   424                     EC_WARN("EoE RX low on mem. frame dropped.\n");
       
   425                 eoe->stats.rx_dropped++;
       
   426                 eoe->state = ec_eoe_state_tx_start;
       
   427                 return;
       
   428             }
       
   429 
       
   430             eoe->rx_skb_offset = 0;
       
   431             eoe->rx_skb_size = fragment_offset * 32;
       
   432             eoe->rx_expected_fragment = 0;
       
   433         }
       
   434         else {
       
   435             if (!eoe->rx_skb) {
       
   436                 eoe->stats.rx_dropped++;
       
   437                 eoe->state = ec_eoe_state_tx_start;
       
   438                 return;
       
   439             }
       
   440 
       
   441             offset = fragment_offset * 32;
       
   442             if (offset != eoe->rx_skb_offset ||
       
   443                 offset + data_size > eoe->rx_skb_size ||
       
   444                 fragment_number != eoe->rx_expected_fragment) {
       
   445                 eoe->stats.rx_errors++;
       
   446                 eoe->state = ec_eoe_state_tx_start;
       
   447                 dev_kfree_skb(eoe->rx_skb);
       
   448                 eoe->rx_skb = NULL;
       
   449                 return;
       
   450             }
       
   451         }
       
   452 
       
   453         // copy fragment into socket buffer
       
   454         memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
       
   455         eoe->rx_skb_offset += data_size;
       
   456 
       
   457         if (last_fragment) {
       
   458             // update statistics
       
   459             eoe->stats.rx_packets++;
       
   460             eoe->stats.rx_bytes += eoe->rx_skb->len;
       
   461 
       
   462 #if EOE_DEBUG_LEVEL > 0
       
   463             EC_DBG("EoE RX frame completed with %u octets.\n",
       
   464                    eoe->rx_skb->len);
       
   465 #endif
       
   466 
       
   467             // pass socket buffer to network stack
       
   468             eoe->rx_skb->dev = eoe->dev;
       
   469             eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
       
   470             eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
       
   471             if (netif_rx(eoe->rx_skb)) {
       
   472                 EC_WARN("EoE RX netif_rx failed.\n");
       
   473             }
       
   474             eoe->rx_skb = NULL;
       
   475 
       
   476             eoe->state = ec_eoe_state_tx_start;
       
   477         }
       
   478         else {
       
   479             eoe->rx_expected_fragment++;
       
   480 #if EOE_DEBUG_LEVEL > 0
       
   481             EC_DBG("EoE RX expecting fragment %i\n",
       
   482                    eoe->rx_expected_fragment);
       
   483 #endif
       
   484             eoe->state = ec_eoe_state_rx_start;
       
   485         }
       
   486     }
       
   487     else {
       
   488 #if EOE_DEBUG_LEVEL > 0
   388 #if EOE_DEBUG_LEVEL > 0
   489         EC_DBG("other frame received.\n");
   389         EC_DBG("other frame received.\n");
   490 #endif
   390 #endif
   491         eoe->stats.rx_dropped++;
   391         eoe->stats.rx_dropped++;
   492         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;
   493     }
   497     }
   494 }
   498 }
   495 
   499 
   496 /*****************************************************************************/
   500 /*****************************************************************************/
   497 
   501 
   558 
   562 
   559 /*****************************************************************************/
   563 /*****************************************************************************/
   560 
   564 
   561 /**
   565 /**
   562    State: TX SENT.
   566    State: TX SENT.
   563    Checks is the previous transmit command succeded and sends the next
   567    Checks is the previous transmit datagram succeded and sends the next
   564    fragment, if necessary.
   568    fragment, if necessary.
   565 */
   569 */
   566 
   570 
   567 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
   571 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
   568 {
   572 {
   569     if (eoe->command.state != EC_CMD_RECEIVED) {
   573     if (eoe->datagram.state != EC_CMD_RECEIVED) {
   570         eoe->stats.tx_errors++;
   574         eoe->stats.tx_errors++;
   571         eoe->state = ec_eoe_state_rx_start;
   575         eoe->state = ec_eoe_state_rx_start;
   572         return;
   576         return;
   573     }
   577     }
   574 
   578 
   575     if (eoe->command.working_counter != 1) {
   579     if (eoe->datagram.working_counter != 1) {
   576         eoe->stats.tx_errors++;
   580         eoe->stats.tx_errors++;
   577         eoe->state = ec_eoe_state_rx_start;
   581         eoe->state = ec_eoe_state_rx_start;
   578         return;
   582         return;
   579     }
   583     }
   580 
   584 
   616     EC_INFO("%s opened.\n", dev->name);
   620     EC_INFO("%s opened.\n", dev->name);
   617     if (!eoe->slave)
   621     if (!eoe->slave)
   618         EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
   622         EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
   619     else {
   623     else {
   620         eoe->slave->requested_state = EC_SLAVE_STATE_OP;
   624         eoe->slave->requested_state = EC_SLAVE_STATE_OP;
   621         eoe->slave->state_error = 0;
   625         eoe->slave->error_flag = 0;
   622     }
   626     }
   623     return 0;
   627     return 0;
   624 }
   628 }
   625 
   629 
   626 /*****************************************************************************/
   630 /*****************************************************************************/
   639     EC_INFO("%s stopped.\n", dev->name);
   643     EC_INFO("%s stopped.\n", dev->name);
   640     if (!eoe->slave)
   644     if (!eoe->slave)
   641         EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
   645         EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
   642     else {
   646     else {
   643         eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
   647         eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
   644         eoe->slave->state_error = 0;
   648         eoe->slave->error_flag = 0;
   645     }
   649     }
   646     return 0;
   650     return 0;
   647 }
   651 }
   648 
   652 
   649 /*****************************************************************************/
   653 /*****************************************************************************/