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 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
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
00120 priv = netdev_priv(eoe->dev);
00121 *priv = eoe;
00122
00123
00124
00125
00126
00127 #if 0
00128 eoe->dev->mtu = slave->sii_rx_mailbox_size - ETH_HLEN - 10;
00129 #endif
00130
00131
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
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) {
00159 unregister_netdev(eoe->dev);
00160 free_netdev(eoe->dev);
00161 }
00162
00163
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
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);
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
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
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
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
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
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
00522
00523 ec_eoe_state_rx_start(eoe);
00524 return;
00525 }
00526
00527
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
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 {
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
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