ethernet.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  *  $Id: ethernet.c 490 2006-08-02 12:25:25Z fp $
00004  *
00005  *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
00006  *
00007  *  This file is part of the IgH EtherCAT Master.
00008  *
00009  *  The IgH EtherCAT Master is free software; you can redistribute it
00010  *  and/or modify it under the terms of the GNU General Public License
00011  *  as published by the Free Software Foundation; either version 2 of the
00012  *  License, or (at your option) any later version.
00013  *
00014  *  The IgH EtherCAT Master is distributed in the hope that it will be
00015  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with the IgH EtherCAT Master; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  *  The right to use EtherCAT Technology is granted and comes free of
00024  *  charge under condition of compatibility of product made by
00025  *  Licensee. People intending to distribute/sell products based on the
00026  *  code, have to sign an agreement to guarantee that products using
00027  *  software based on IgH EtherCAT master stay compatible with the actual
00028  *  EtherCAT specification (which are released themselves as an open
00029  *  standard) as the (only) precondition to have the right to use EtherCAT
00030  *  Technology, IP and trade marks.
00031  *
00032  *****************************************************************************/
00033 
00039 /*****************************************************************************/
00040 
00041 #include <linux/netdevice.h>
00042 #include <linux/etherdevice.h>
00043 
00044 #include "../include/ecrt.h"
00045 #include "globals.h"
00046 #include "master.h"
00047 #include "slave.h"
00048 #include "mailbox.h"
00049 #include "ethernet.h"
00050 
00059 #define EOE_DEBUG_LEVEL 0
00060 
00061 /*****************************************************************************/
00062 
00063 void ec_eoe_flush(ec_eoe_t *);
00064 
00065 // state functions
00066 void ec_eoe_state_rx_start(ec_eoe_t *);
00067 void ec_eoe_state_rx_check(ec_eoe_t *);
00068 void ec_eoe_state_rx_fetch(ec_eoe_t *);
00069 void ec_eoe_state_tx_start(ec_eoe_t *);
00070 void ec_eoe_state_tx_sent(ec_eoe_t *);
00071 
00072 // net_device functions
00073 int ec_eoedev_open(struct net_device *);
00074 int ec_eoedev_stop(struct net_device *);
00075 int ec_eoedev_tx(struct sk_buff *, struct net_device *);
00076 struct net_device_stats *ec_eoedev_stats(struct net_device *);
00077 
00078 /*****************************************************************************/
00079 
00085 int ec_eoe_init(ec_eoe_t *eoe )
00086 {
00087     ec_eoe_t **priv;
00088     int result, i;
00089 
00090     eoe->slave = NULL;
00091     ec_datagram_init(&eoe->datagram);
00092     eoe->state = ec_eoe_state_rx_start;
00093     eoe->opened = 0;
00094     eoe->rx_skb = NULL;
00095     eoe->rx_expected_fragment = 0;
00096     INIT_LIST_HEAD(&eoe->tx_queue);
00097     eoe->tx_frame = NULL;
00098     eoe->tx_queue_active = 0;
00099     eoe->tx_queued_frames = 0;
00100     eoe->tx_queue_lock = SPIN_LOCK_UNLOCKED;
00101     eoe->tx_frame_number = 0xFF;
00102     memset(&eoe->stats, 0, sizeof(struct net_device_stats));
00103 
00104     if (!(eoe->dev =
00105           alloc_netdev(sizeof(ec_eoe_t *), "eoe%d", ether_setup))) {
00106         EC_ERR("Unable to allocate net_device for EoE handler!\n");
00107         goto out_return;
00108     }
00109 
00110     // initialize net_device
00111     eoe->dev->open = ec_eoedev_open;
00112     eoe->dev->stop = ec_eoedev_stop;
00113     eoe->dev->hard_start_xmit = ec_eoedev_tx;
00114     eoe->dev->get_stats = ec_eoedev_stats;
00115 
00116     for (i = 0; i < ETH_ALEN; i++)
00117         eoe->dev->dev_addr[i] = i | (i << 4);
00118 
00119     // initialize private data
00120     priv = netdev_priv(eoe->dev);
00121     *priv = eoe;
00122 
00123     // Usually setting the MTU appropriately makes the upper layers
00124     // do the frame fragmenting. In some cases this doesn't work
00125     // so the MTU is left on the Ethernet standard value and fragmenting
00126     // is done "manually".
00127 #if 0
00128     eoe->dev->mtu = slave->sii_rx_mailbox_size - ETH_HLEN - 10;
00129 #endif
00130 
00131     // connect the net_device to the kernel
00132     if ((result = register_netdev(eoe->dev))) {
00133         EC_ERR("Unable to register net_device: error %i\n", result);
00134         goto out_free;
00135     }
00136 
00137     // make the last address octet unique
00138     eoe->dev->dev_addr[ETH_ALEN - 1] = (uint8_t) eoe->dev->ifindex;
00139 
00140     return 0;
00141 
00142  out_free:
00143     free_netdev(eoe->dev);
00144     eoe->dev = NULL;
00145  out_return:
00146     return -1;
00147 }
00148 
00149 /*****************************************************************************/
00150 
00156 void ec_eoe_clear(ec_eoe_t *eoe )
00157 {
00158     if (eoe->dev) { // TODO: dev never NULL?
00159         unregister_netdev(eoe->dev);
00160         free_netdev(eoe->dev);
00161     }
00162 
00163     // empty transmit queue
00164     ec_eoe_flush(eoe);
00165 
00166     if (eoe->tx_frame) {
00167         dev_kfree_skb(eoe->tx_frame->skb);
00168         kfree(eoe->tx_frame);
00169     }
00170 
00171     if (eoe->rx_skb) dev_kfree_skb(eoe->rx_skb);
00172 
00173     ec_datagram_clear(&eoe->datagram);
00174 }
00175 
00176 /*****************************************************************************/
00177 
00182 void ec_eoe_flush(ec_eoe_t *eoe )
00183 {
00184     ec_eoe_frame_t *frame, *next;
00185 
00186     spin_lock_bh(&eoe->tx_queue_lock);
00187 
00188     list_for_each_entry_safe(frame, next, &eoe->tx_queue, queue) {
00189         list_del(&frame->queue);
00190         dev_kfree_skb(frame->skb);
00191         kfree(frame);
00192     }
00193     eoe->tx_queued_frames = 0;
00194 
00195     spin_unlock_bh(&eoe->tx_queue_lock);
00196 }
00197 
00198 /*****************************************************************************/
00199 
00204 int ec_eoe_send(ec_eoe_t *eoe )
00205 {
00206     size_t remaining_size, current_size, complete_offset;
00207     unsigned int last_fragment;
00208     uint8_t *data;
00209 #if EOE_DEBUG_LEVEL > 1
00210     unsigned int i;
00211 #endif
00212 
00213     remaining_size = eoe->tx_frame->skb->len - eoe->tx_offset;
00214 
00215     if (remaining_size <= eoe->slave->sii_tx_mailbox_size - 10) {
00216         current_size = remaining_size;
00217         last_fragment = 1;
00218     }
00219     else {
00220         current_size = ((eoe->slave->sii_tx_mailbox_size - 10) / 32) * 32;
00221         last_fragment = 0;
00222     }
00223 
00224     if (eoe->tx_fragment_number) {
00225         complete_offset = eoe->tx_offset / 32;
00226     }
00227     else {
00228         // complete size in 32 bit blocks, rounded up.
00229         complete_offset = remaining_size / 32 + 1;
00230     }
00231 
00232 #if EOE_DEBUG_LEVEL > 0
00233     EC_DBG("EoE TX sending %sfragment %i with %i octets (%i)."
00234            " %i frames queued.\n", last_fragment ? "last " : "",
00235            eoe->tx_fragment_number, current_size, complete_offset,
00236            eoe->tx_queued_frames);
00237 #endif
00238 
00239 #if EOE_DEBUG_LEVEL > 1
00240     EC_DBG("");
00241     for (i = 0; i < current_size; i++) {
00242         printk("%02X ", frame->skb->data[eoe->tx_offset + i]);
00243         if ((i + 1) % 16 == 0) {
00244             printk("\n");
00245             EC_DBG("");
00246         }
00247     }
00248     printk("\n");
00249 #endif
00250 
00251     if (!(data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
00252                                             0x02, current_size + 4)))
00253         return -1;
00254 
00255     EC_WRITE_U8 (data,     0x00); // eoe fragment req.
00256     EC_WRITE_U8 (data + 1, last_fragment);
00257     EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) |
00258                             (complete_offset & 0x3F) << 6 |
00259                             (eoe->tx_frame_number & 0x0F) << 12));
00260 
00261     memcpy(data + 4, eoe->tx_frame->skb->data + eoe->tx_offset, current_size);
00262     ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
00263 
00264     eoe->tx_offset += current_size;
00265     eoe->tx_fragment_number++;
00266     return 0;
00267 }
00268 
00269 /*****************************************************************************/
00270 
00275 void ec_eoe_run(ec_eoe_t *eoe )
00276 {
00277     if (!eoe->opened) return;
00278 
00279     // call state function
00280     eoe->state(eoe);
00281 }
00282 
00283 /*****************************************************************************/
00284 
00290 unsigned int ec_eoe_active(const ec_eoe_t *eoe )
00291 {
00292     return eoe->slave && eoe->opened;
00293 }
00294 
00295 /*****************************************************************************/
00296 
00301 void ec_eoe_print(const ec_eoe_t *eoe )
00302 {
00303     EC_INFO("  EoE handler %s\n", eoe->dev->name);
00304     EC_INFO("    State: %s\n", eoe->opened ? "opened" : "closed");
00305     if (eoe->slave)
00306         EC_INFO("    Coupled to slave %i.\n", eoe->slave->ring_position);
00307     else
00308         EC_INFO("    Not coupled.\n");
00309 }
00310 
00311 /******************************************************************************
00312  *  STATE PROCESSING FUNCTIONS
00313  *****************************************************************************/
00314 
00321 void ec_eoe_state_rx_start(ec_eoe_t *eoe )
00322 {
00323     if (!eoe->slave->online || !eoe->slave->master->device->link_state)
00324         return;
00325 
00326     ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
00327     ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
00328     eoe->state = ec_eoe_state_rx_check;
00329 }
00330 
00331 /*****************************************************************************/
00332 
00339 void ec_eoe_state_rx_check(ec_eoe_t *eoe )
00340 {
00341     if (eoe->datagram.state != EC_CMD_RECEIVED) {
00342         eoe->stats.rx_errors++;
00343         eoe->state = ec_eoe_state_tx_start;
00344         return;
00345     }
00346 
00347     if (!ec_slave_mbox_check(&eoe->datagram)) {
00348         eoe->state = ec_eoe_state_tx_start;
00349         return;
00350     }
00351 
00352     ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram);
00353     ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
00354     eoe->state = ec_eoe_state_rx_fetch;
00355 }
00356 
00357 /*****************************************************************************/
00358 
00365 void ec_eoe_state_rx_fetch(ec_eoe_t *eoe )
00366 {
00367     size_t rec_size, data_size;
00368     uint8_t *data, frame_type, last_fragment, time_appended;
00369     uint8_t frame_number, fragment_offset, fragment_number;
00370     off_t offset;
00371 
00372     if (eoe->datagram.state != EC_CMD_RECEIVED) {
00373         eoe->stats.rx_errors++;
00374         eoe->state = ec_eoe_state_tx_start;
00375         return;
00376     }
00377 
00378     if (!(data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram,
00379                                      0x02, &rec_size))) {
00380         eoe->stats.rx_errors++;
00381         eoe->state = ec_eoe_state_tx_start;
00382         return;
00383     }
00384 
00385     frame_type = EC_READ_U16(data) & 0x000F;
00386 
00387     if (frame_type != 0x00) {
00388 #if EOE_DEBUG_LEVEL > 0
00389         EC_DBG("other frame received.\n");
00390 #endif
00391         eoe->stats.rx_dropped++;
00392         eoe->state = ec_eoe_state_tx_start;
00393         return;
00394     }
00395 
00396     // EoE Fragment Request received
00397 
00398     last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
00399     time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
00400     fragment_number = EC_READ_U16(data + 2) & 0x003F;
00401     fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
00402     frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
00403 
00404 #if EOE_DEBUG_LEVEL > 0
00405     EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
00406            " %i octets\n", fragment_number, fragment_offset,
00407            frame_number,
00408            last_fragment ? ", last fragment" : "",
00409            time_appended ? ", + timestamp" : "",
00410            time_appended ? rec_size - 8 : rec_size - 4);
00411 #endif
00412 
00413 #if EOE_DEBUG_LEVEL > 1
00414     EC_DBG("");
00415     for (i = 0; i < rec_size - 4; i++) {
00416         printk("%02X ", data[i + 4]);
00417         if ((i + 1) % 16 == 0) {
00418             printk("\n");
00419             EC_DBG("");
00420         }
00421     }
00422     printk("\n");
00423 #endif
00424 
00425     data_size = time_appended ? rec_size - 8 : rec_size - 4;
00426 
00427     if (!fragment_number) {
00428         if (eoe->rx_skb) {
00429             EC_WARN("EoE RX freeing old socket buffer...\n");
00430             dev_kfree_skb(eoe->rx_skb);
00431         }
00432 
00433         // new socket buffer
00434         if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
00435             if (printk_ratelimit())
00436                 EC_WARN("EoE RX low on mem. frame dropped.\n");
00437             eoe->stats.rx_dropped++;
00438             eoe->state = ec_eoe_state_tx_start;
00439             return;
00440         }
00441 
00442         eoe->rx_skb_offset = 0;
00443         eoe->rx_skb_size = fragment_offset * 32;
00444         eoe->rx_expected_fragment = 0;
00445     }
00446     else {
00447         if (!eoe->rx_skb) {
00448             eoe->stats.rx_dropped++;
00449             eoe->state = ec_eoe_state_tx_start;
00450             return;
00451         }
00452 
00453         offset = fragment_offset * 32;
00454         if (offset != eoe->rx_skb_offset ||
00455             offset + data_size > eoe->rx_skb_size ||
00456             fragment_number != eoe->rx_expected_fragment) {
00457             dev_kfree_skb(eoe->rx_skb);
00458             eoe->rx_skb = NULL;
00459             eoe->stats.rx_errors++;
00460             eoe->state = ec_eoe_state_tx_start;
00461             return;
00462         }
00463     }
00464 
00465     // copy fragment into socket buffer
00466     memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
00467     eoe->rx_skb_offset += data_size;
00468 
00469     if (last_fragment) {
00470         // update statistics
00471         eoe->stats.rx_packets++;
00472         eoe->stats.rx_bytes += eoe->rx_skb->len;
00473 
00474 #if EOE_DEBUG_LEVEL > 0
00475         EC_DBG("EoE RX frame completed with %u octets.\n",
00476                eoe->rx_skb->len);
00477 #endif
00478 
00479         // pass socket buffer to network stack
00480         eoe->rx_skb->dev = eoe->dev;
00481         eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
00482         eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
00483         if (netif_rx(eoe->rx_skb)) {
00484             EC_WARN("EoE RX netif_rx failed.\n");
00485         }
00486         eoe->rx_skb = NULL;
00487 
00488         eoe->state = ec_eoe_state_tx_start;
00489     }
00490     else {
00491         eoe->rx_expected_fragment++;
00492 #if EOE_DEBUG_LEVEL > 0
00493         EC_DBG("EoE RX expecting fragment %i\n",
00494                eoe->rx_expected_fragment);
00495 #endif
00496         eoe->state = ec_eoe_state_rx_start;
00497     }
00498 }
00499 
00500 /*****************************************************************************/
00501 
00508 void ec_eoe_state_tx_start(ec_eoe_t *eoe )
00509 {
00510 #if EOE_DEBUG_LEVEL > 0
00511     unsigned int wakeup;
00512 #endif
00513 
00514     if (!eoe->slave->online || !eoe->slave->master->device->link_state)
00515         return;
00516 
00517     spin_lock_bh(&eoe->tx_queue_lock);
00518 
00519     if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) {
00520         spin_unlock_bh(&eoe->tx_queue_lock);
00521         // no data available.
00522         // start a new receive immediately.
00523         ec_eoe_state_rx_start(eoe);
00524         return;
00525     }
00526 
00527     // take the first frame out of the queue
00528     eoe->tx_frame = list_entry(eoe->tx_queue.next, ec_eoe_frame_t, queue);
00529     list_del(&eoe->tx_frame->queue);
00530     if (!eoe->tx_queue_active &&
00531         eoe->tx_queued_frames == EC_EOE_TX_QUEUE_SIZE / 2) {
00532         netif_wake_queue(eoe->dev);
00533         eoe->tx_queue_active = 1;
00534 #if EOE_DEBUG_LEVEL > 0
00535         wakeup = 1;
00536 #endif
00537     }
00538 
00539     eoe->tx_queued_frames--;
00540     spin_unlock_bh(&eoe->tx_queue_lock);
00541 
00542     eoe->tx_frame_number++;
00543     eoe->tx_frame_number %= 16;
00544     eoe->tx_fragment_number = 0;
00545     eoe->tx_offset = 0;
00546 
00547     if (ec_eoe_send(eoe)) {
00548         dev_kfree_skb(eoe->tx_frame->skb);
00549         kfree(eoe->tx_frame);
00550         eoe->tx_frame = NULL;
00551         eoe->stats.tx_errors++;
00552         eoe->state = ec_eoe_state_rx_start;
00553         return;
00554     }
00555 
00556 #if EOE_DEBUG_LEVEL > 0
00557     if (wakeup) EC_DBG("waking up TX queue...\n");
00558 #endif
00559 
00560     eoe->state = ec_eoe_state_tx_sent;
00561 }
00562 
00563 /*****************************************************************************/
00564 
00571 void ec_eoe_state_tx_sent(ec_eoe_t *eoe )
00572 {
00573     if (eoe->datagram.state != EC_CMD_RECEIVED) {
00574         eoe->stats.tx_errors++;
00575         eoe->state = ec_eoe_state_rx_start;
00576         return;
00577     }
00578 
00579     if (eoe->datagram.working_counter != 1) {
00580         eoe->stats.tx_errors++;
00581         eoe->state = ec_eoe_state_rx_start;
00582         return;
00583     }
00584 
00585     // frame completely sent
00586     if (eoe->tx_offset >= eoe->tx_frame->skb->len) {
00587         eoe->stats.tx_packets++;
00588         eoe->stats.tx_bytes += eoe->tx_frame->skb->len;
00589         dev_kfree_skb(eoe->tx_frame->skb);
00590         kfree(eoe->tx_frame);
00591         eoe->tx_frame = NULL;
00592         eoe->state = ec_eoe_state_rx_start;
00593     }
00594     else { // send next fragment
00595         if (ec_eoe_send(eoe)) {
00596             dev_kfree_skb(eoe->tx_frame->skb);
00597             kfree(eoe->tx_frame);
00598             eoe->tx_frame = NULL;
00599             eoe->stats.tx_errors++;
00600             eoe->state = ec_eoe_state_rx_start;
00601         }
00602     }
00603 }
00604 
00605 /******************************************************************************
00606  *  NET_DEVICE functions
00607  *****************************************************************************/
00608 
00613 int ec_eoedev_open(struct net_device *dev )
00614 {
00615     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00616     ec_eoe_flush(eoe);
00617     eoe->opened = 1;
00618     netif_start_queue(dev);
00619     eoe->tx_queue_active = 1;
00620     EC_INFO("%s opened.\n", dev->name);
00621     if (!eoe->slave)
00622         EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
00623     else {
00624         eoe->slave->requested_state = EC_SLAVE_STATE_OP;
00625         eoe->slave->error_flag = 0;
00626     }
00627     return 0;
00628 }
00629 
00630 /*****************************************************************************/
00631 
00636 int ec_eoedev_stop(struct net_device *dev )
00637 {
00638     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00639     netif_stop_queue(dev);
00640     eoe->tx_queue_active = 0;
00641     eoe->opened = 0;
00642     ec_eoe_flush(eoe);
00643     EC_INFO("%s stopped.\n", dev->name);
00644     if (!eoe->slave)
00645         EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
00646     else {
00647         eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
00648         eoe->slave->error_flag = 0;
00649     }
00650     return 0;
00651 }
00652 
00653 /*****************************************************************************/
00654 
00659 int ec_eoedev_tx(struct sk_buff *skb, 
00660                  struct net_device *dev 
00661                 )
00662 {
00663     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00664     ec_eoe_frame_t *frame;
00665 
00666 #if 0
00667     if (skb->len > eoe->slave->sii_tx_mailbox_size - 10) {
00668         EC_WARN("EoE TX frame (%i octets) exceeds MTU. dropping.\n", skb->len);
00669         dev_kfree_skb(skb);
00670         eoe->stats.tx_dropped++;
00671         return 0;
00672     }
00673 #endif
00674 
00675     if (!(frame =
00676           (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) {
00677         if (printk_ratelimit())
00678             EC_WARN("EoE TX: low on mem. frame dropped.\n");
00679         return 1;
00680     }
00681 
00682     frame->skb = skb;
00683 
00684     spin_lock_bh(&eoe->tx_queue_lock);
00685     list_add_tail(&frame->queue, &eoe->tx_queue);
00686     eoe->tx_queued_frames++;
00687     if (eoe->tx_queued_frames == EC_EOE_TX_QUEUE_SIZE) {
00688         netif_stop_queue(dev);
00689         eoe->tx_queue_active = 0;
00690     }
00691     spin_unlock_bh(&eoe->tx_queue_lock);
00692 
00693 #if EOE_DEBUG_LEVEL > 0
00694     EC_DBG("EoE TX queued frame with %i octets (%i frames queued).\n",
00695            skb->len, eoe->tx_queued_frames);
00696     if (!eoe->tx_queue_active)
00697         EC_WARN("EoE TX queue is now full.\n");
00698 #endif
00699 
00700     return 0;
00701 }
00702 
00703 /*****************************************************************************/
00704 
00709 struct net_device_stats *ec_eoedev_stats(struct net_device *dev)
00711 {
00712     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00713     return &eoe->stats;
00714 }
00715 
00716 /*****************************************************************************/

Generated on Wed Aug 2 18:41:43 2006 for IgH EtherCAT master by  doxygen 1.4.6