00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
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
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 eoe->rx_counter = 0;
00105 eoe->tx_counter = 0;
00106 eoe->rx_rate = 0;
00107 eoe->tx_rate = 0;
00108 eoe->rate_jiffies = 0;
00109
00110 if (!(eoe->dev =
00111 alloc_netdev(sizeof(ec_eoe_t *), "eoe%d", ether_setup))) {
00112 EC_ERR("Unable to allocate net_device for EoE handler!\n");
00113 goto out_return;
00114 }
00115
00116
00117 eoe->dev->open = ec_eoedev_open;
00118 eoe->dev->stop = ec_eoedev_stop;
00119 eoe->dev->hard_start_xmit = ec_eoedev_tx;
00120 eoe->dev->get_stats = ec_eoedev_stats;
00121
00122 for (i = 0; i < ETH_ALEN; i++)
00123 eoe->dev->dev_addr[i] = i | (i << 4);
00124
00125
00126 priv = netdev_priv(eoe->dev);
00127 *priv = eoe;
00128
00129
00130
00131
00132
00133 #if 0
00134 eoe->dev->mtu = slave->sii_rx_mailbox_size - ETH_HLEN - 10;
00135 #endif
00136
00137
00138 if ((result = register_netdev(eoe->dev))) {
00139 EC_ERR("Unable to register net_device: error %i\n", result);
00140 goto out_free;
00141 }
00142
00143
00144 eoe->dev->dev_addr[ETH_ALEN - 1] = (uint8_t) eoe->dev->ifindex;
00145
00146 return 0;
00147
00148 out_free:
00149 free_netdev(eoe->dev);
00150 eoe->dev = NULL;
00151 out_return:
00152 return -1;
00153 }
00154
00155
00156
00162 void ec_eoe_clear(ec_eoe_t *eoe )
00163 {
00164 unregister_netdev(eoe->dev);
00165 free_netdev(eoe->dev);
00166
00167
00168 ec_eoe_flush(eoe);
00169
00170 if (eoe->tx_frame) {
00171 dev_kfree_skb(eoe->tx_frame->skb);
00172 kfree(eoe->tx_frame);
00173 }
00174
00175 if (eoe->rx_skb) dev_kfree_skb(eoe->rx_skb);
00176
00177 ec_datagram_clear(&eoe->datagram);
00178 }
00179
00180
00181
00186 void ec_eoe_flush(ec_eoe_t *eoe )
00187 {
00188 ec_eoe_frame_t *frame, *next;
00189
00190 spin_lock_bh(&eoe->tx_queue_lock);
00191
00192 list_for_each_entry_safe(frame, next, &eoe->tx_queue, queue) {
00193 list_del(&frame->queue);
00194 dev_kfree_skb(frame->skb);
00195 kfree(frame);
00196 }
00197 eoe->tx_queued_frames = 0;
00198
00199 spin_unlock_bh(&eoe->tx_queue_lock);
00200 }
00201
00202
00203
00208 int ec_eoe_send(ec_eoe_t *eoe )
00209 {
00210 size_t remaining_size, current_size, complete_offset;
00211 unsigned int last_fragment;
00212 uint8_t *data;
00213 #if EOE_DEBUG_LEVEL > 1
00214 unsigned int i;
00215 #endif
00216
00217 remaining_size = eoe->tx_frame->skb->len - eoe->tx_offset;
00218
00219 if (remaining_size <= eoe->slave->sii_tx_mailbox_size - 10) {
00220 current_size = remaining_size;
00221 last_fragment = 1;
00222 }
00223 else {
00224 current_size = ((eoe->slave->sii_tx_mailbox_size - 10) / 32) * 32;
00225 last_fragment = 0;
00226 }
00227
00228 if (eoe->tx_fragment_number) {
00229 complete_offset = eoe->tx_offset / 32;
00230 }
00231 else {
00232
00233 complete_offset = remaining_size / 32 + 1;
00234 }
00235
00236 #if EOE_DEBUG_LEVEL > 0
00237 EC_DBG("EoE TX sending %sfragment %i with %i octets (%i)."
00238 " %i frames queued.\n", last_fragment ? "last " : "",
00239 eoe->tx_fragment_number, current_size, complete_offset,
00240 eoe->tx_queued_frames);
00241 #endif
00242
00243 #if EOE_DEBUG_LEVEL > 1
00244 EC_DBG("");
00245 for (i = 0; i < current_size; i++) {
00246 printk("%02X ", eoe->tx_frame->skb->data[eoe->tx_offset + i]);
00247 if ((i + 1) % 16 == 0) {
00248 printk("\n");
00249 EC_DBG("");
00250 }
00251 }
00252 printk("\n");
00253 #endif
00254
00255 if (!(data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
00256 0x02, current_size + 4)))
00257 return -1;
00258
00259 EC_WRITE_U8 (data, 0x00);
00260 EC_WRITE_U8 (data + 1, last_fragment);
00261 EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) |
00262 (complete_offset & 0x3F) << 6 |
00263 (eoe->tx_frame_number & 0x0F) << 12));
00264
00265 memcpy(data + 4, eoe->tx_frame->skb->data + eoe->tx_offset, current_size);
00266 ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
00267
00268 eoe->tx_offset += current_size;
00269 eoe->tx_fragment_number++;
00270 return 0;
00271 }
00272
00273
00274
00279 void ec_eoe_run(ec_eoe_t *eoe )
00280 {
00281 if (!eoe->opened) return;
00282
00283
00284 eoe->state(eoe);
00285
00286
00287 if (jiffies - eoe->rate_jiffies > HZ) {
00288 eoe->rx_rate = eoe->rx_counter * 8;
00289 eoe->tx_rate = eoe->tx_counter * 8;
00290 eoe->rx_counter = 0;
00291 eoe->tx_counter = 0;
00292 eoe->rate_jiffies = jiffies;
00293 }
00294 }
00295
00296
00297
00303 int ec_eoe_active(const ec_eoe_t *eoe )
00304 {
00305 return eoe->slave && eoe->opened;
00306 }
00307
00308
00309
00310
00311
00318 void ec_eoe_state_rx_start(ec_eoe_t *eoe )
00319 {
00320 if (!eoe->slave->online || !eoe->slave->master->device->link_state)
00321 return;
00322
00323 ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
00324 ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
00325 eoe->state = ec_eoe_state_rx_check;
00326 }
00327
00328
00329
00336 void ec_eoe_state_rx_check(ec_eoe_t *eoe )
00337 {
00338 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
00339 eoe->stats.rx_errors++;
00340 eoe->state = ec_eoe_state_tx_start;
00341 return;
00342 }
00343
00344 if (!ec_slave_mbox_check(&eoe->datagram)) {
00345 eoe->state = ec_eoe_state_tx_start;
00346 return;
00347 }
00348
00349 ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram);
00350 ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
00351 eoe->state = ec_eoe_state_rx_fetch;
00352 }
00353
00354
00355
00362 void ec_eoe_state_rx_fetch(ec_eoe_t *eoe )
00363 {
00364 size_t rec_size, data_size;
00365 uint8_t *data, frame_type, last_fragment, time_appended;
00366 uint8_t frame_number, fragment_offset, fragment_number;
00367 off_t offset;
00368 #if EOE_DEBUG_LEVEL > 1
00369 unsigned int i;
00370 #endif
00371
00372 if (eoe->datagram.state != EC_DATAGRAM_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
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
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
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
00471 eoe->stats.rx_packets++;
00472 eoe->stats.rx_bytes += eoe->rx_skb->len;
00473 eoe->rx_counter += eoe->rx_skb->len;
00474
00475 #if EOE_DEBUG_LEVEL > 0
00476 EC_DBG("EoE RX frame completed with %u octets.\n",
00477 eoe->rx_skb->len);
00478 #endif
00479
00480
00481 eoe->rx_skb->dev = eoe->dev;
00482 eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
00483 eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
00484 if (netif_rx(eoe->rx_skb)) {
00485 EC_WARN("EoE RX netif_rx failed.\n");
00486 }
00487 eoe->rx_skb = NULL;
00488
00489 eoe->state = ec_eoe_state_tx_start;
00490 }
00491 else {
00492 eoe->rx_expected_fragment++;
00493 #if EOE_DEBUG_LEVEL > 0
00494 EC_DBG("EoE RX expecting fragment %i\n",
00495 eoe->rx_expected_fragment);
00496 #endif
00497 eoe->state = ec_eoe_state_rx_start;
00498 }
00499 }
00500
00501
00502
00509 void ec_eoe_state_tx_start(ec_eoe_t *eoe )
00510 {
00511 #if EOE_DEBUG_LEVEL > 0
00512 unsigned int wakeup = 0;
00513 #endif
00514
00515 if (!eoe->slave->online || !eoe->slave->master->device->link_state)
00516 return;
00517
00518 spin_lock_bh(&eoe->tx_queue_lock);
00519
00520 if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) {
00521 spin_unlock_bh(&eoe->tx_queue_lock);
00522
00523
00524 ec_eoe_state_rx_start(eoe);
00525 return;
00526 }
00527
00528
00529 eoe->tx_frame = list_entry(eoe->tx_queue.next, ec_eoe_frame_t, queue);
00530 list_del(&eoe->tx_frame->queue);
00531 if (!eoe->tx_queue_active &&
00532 eoe->tx_queued_frames == EC_EOE_TX_QUEUE_SIZE / 2) {
00533 netif_wake_queue(eoe->dev);
00534 eoe->tx_queue_active = 1;
00535 #if EOE_DEBUG_LEVEL > 0
00536 wakeup = 1;
00537 #endif
00538 }
00539
00540 eoe->tx_queued_frames--;
00541 spin_unlock_bh(&eoe->tx_queue_lock);
00542
00543 eoe->tx_frame_number++;
00544 eoe->tx_frame_number %= 16;
00545 eoe->tx_fragment_number = 0;
00546 eoe->tx_offset = 0;
00547
00548 if (ec_eoe_send(eoe)) {
00549 dev_kfree_skb(eoe->tx_frame->skb);
00550 kfree(eoe->tx_frame);
00551 eoe->tx_frame = NULL;
00552 eoe->stats.tx_errors++;
00553 eoe->state = ec_eoe_state_rx_start;
00554 return;
00555 }
00556
00557 #if EOE_DEBUG_LEVEL > 0
00558 if (wakeup) EC_DBG("waking up TX queue...\n");
00559 #endif
00560
00561 eoe->state = ec_eoe_state_tx_sent;
00562 }
00563
00564
00565
00572 void ec_eoe_state_tx_sent(ec_eoe_t *eoe )
00573 {
00574 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
00575 eoe->stats.tx_errors++;
00576 eoe->state = ec_eoe_state_rx_start;
00577 return;
00578 }
00579
00580 if (eoe->datagram.working_counter != 1) {
00581 eoe->stats.tx_errors++;
00582 eoe->state = ec_eoe_state_rx_start;
00583 return;
00584 }
00585
00586
00587 if (eoe->tx_offset >= eoe->tx_frame->skb->len) {
00588 eoe->stats.tx_packets++;
00589 eoe->stats.tx_bytes += eoe->tx_frame->skb->len;
00590 eoe->tx_counter += eoe->tx_frame->skb->len;
00591 dev_kfree_skb(eoe->tx_frame->skb);
00592 kfree(eoe->tx_frame);
00593 eoe->tx_frame = NULL;
00594 eoe->state = ec_eoe_state_rx_start;
00595 }
00596 else {
00597 if (ec_eoe_send(eoe)) {
00598 dev_kfree_skb(eoe->tx_frame->skb);
00599 kfree(eoe->tx_frame);
00600 eoe->tx_frame = NULL;
00601 eoe->stats.tx_errors++;
00602 eoe->state = ec_eoe_state_rx_start;
00603 }
00604 }
00605 }
00606
00607
00608
00609
00610
00615 int ec_eoedev_open(struct net_device *dev )
00616 {
00617 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00618 ec_eoe_flush(eoe);
00619 eoe->opened = 1;
00620 netif_start_queue(dev);
00621 eoe->tx_queue_active = 1;
00622 EC_INFO("%s opened.\n", dev->name);
00623 if (!eoe->slave)
00624 EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
00625 else {
00626 eoe->slave->requested_state = EC_SLAVE_STATE_OP;
00627 eoe->slave->error_flag = 0;
00628 }
00629 return 0;
00630 }
00631
00632
00633
00638 int ec_eoedev_stop(struct net_device *dev )
00639 {
00640 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00641 netif_stop_queue(dev);
00642 eoe->tx_queue_active = 0;
00643 eoe->opened = 0;
00644 ec_eoe_flush(eoe);
00645 EC_INFO("%s stopped.\n", dev->name);
00646 if (!eoe->slave)
00647 EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
00648 else {
00649 eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
00650 eoe->slave->error_flag = 0;
00651 }
00652 return 0;
00653 }
00654
00655
00656
00661 int ec_eoedev_tx(struct sk_buff *skb,
00662 struct net_device *dev
00663 )
00664 {
00665 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00666 ec_eoe_frame_t *frame;
00667
00668 #if 0
00669 if (skb->len > eoe->slave->sii_tx_mailbox_size - 10) {
00670 EC_WARN("EoE TX frame (%i octets) exceeds MTU. dropping.\n", skb->len);
00671 dev_kfree_skb(skb);
00672 eoe->stats.tx_dropped++;
00673 return 0;
00674 }
00675 #endif
00676
00677 if (!(frame =
00678 (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) {
00679 if (printk_ratelimit())
00680 EC_WARN("EoE TX: low on mem. frame dropped.\n");
00681 return 1;
00682 }
00683
00684 frame->skb = skb;
00685
00686 spin_lock_bh(&eoe->tx_queue_lock);
00687 list_add_tail(&frame->queue, &eoe->tx_queue);
00688 eoe->tx_queued_frames++;
00689 if (eoe->tx_queued_frames == EC_EOE_TX_QUEUE_SIZE) {
00690 netif_stop_queue(dev);
00691 eoe->tx_queue_active = 0;
00692 }
00693 spin_unlock_bh(&eoe->tx_queue_lock);
00694
00695 #if EOE_DEBUG_LEVEL > 0
00696 EC_DBG("EoE TX queued frame with %i octets (%i frames queued).\n",
00697 skb->len, eoe->tx_queued_frames);
00698 if (!eoe->tx_queue_active)
00699 EC_WARN("EoE TX queue is now full.\n");
00700 #endif
00701
00702 return 0;
00703 }
00704
00705
00706
00711 struct net_device_stats *ec_eoedev_stats(struct net_device *dev)
00713 {
00714 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00715 return &eoe->stats;
00716 }
00717
00718