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, mbox_prot;
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 &mbox_prot, &rec_size))) {
00380 eoe->stats.rx_errors++;
00381 eoe->state = ec_eoe_state_tx_start;
00382 return;
00383 }
00384
00385 if (mbox_prot != 0x02) {
00386 eoe->stats.rx_errors++;
00387 eoe->state = ec_eoe_state_tx_start;
00388 return;
00389 }
00390
00391 frame_type = EC_READ_U16(data) & 0x000F;
00392
00393 if (frame_type != 0x00) {
00394 #if EOE_DEBUG_LEVEL > 0
00395 EC_DBG("other frame received.\n");
00396 #endif
00397 eoe->stats.rx_dropped++;
00398 eoe->state = ec_eoe_state_tx_start;
00399 return;
00400 }
00401
00402
00403
00404 last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
00405 time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
00406 fragment_number = EC_READ_U16(data + 2) & 0x003F;
00407 fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
00408 frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
00409
00410 #if EOE_DEBUG_LEVEL > 0
00411 EC_DBG("EoE RX fragment %i, offset %i, frame %i%s%s,"
00412 " %i octets\n", fragment_number, fragment_offset,
00413 frame_number,
00414 last_fragment ? ", last fragment" : "",
00415 time_appended ? ", + timestamp" : "",
00416 time_appended ? rec_size - 8 : rec_size - 4);
00417 #endif
00418
00419 #if EOE_DEBUG_LEVEL > 1
00420 EC_DBG("");
00421 for (i = 0; i < rec_size - 4; i++) {
00422 printk("%02X ", data[i + 4]);
00423 if ((i + 1) % 16 == 0) {
00424 printk("\n");
00425 EC_DBG("");
00426 }
00427 }
00428 printk("\n");
00429 #endif
00430
00431 data_size = time_appended ? rec_size - 8 : rec_size - 4;
00432
00433 if (!fragment_number) {
00434 if (eoe->rx_skb) {
00435 EC_WARN("EoE RX freeing old socket buffer...\n");
00436 dev_kfree_skb(eoe->rx_skb);
00437 }
00438
00439
00440 if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
00441 if (printk_ratelimit())
00442 EC_WARN("EoE RX low on mem. frame dropped.\n");
00443 eoe->stats.rx_dropped++;
00444 eoe->state = ec_eoe_state_tx_start;
00445 return;
00446 }
00447
00448 eoe->rx_skb_offset = 0;
00449 eoe->rx_skb_size = fragment_offset * 32;
00450 eoe->rx_expected_fragment = 0;
00451 }
00452 else {
00453 if (!eoe->rx_skb) {
00454 eoe->stats.rx_dropped++;
00455 eoe->state = ec_eoe_state_tx_start;
00456 return;
00457 }
00458
00459 offset = fragment_offset * 32;
00460 if (offset != eoe->rx_skb_offset ||
00461 offset + data_size > eoe->rx_skb_size ||
00462 fragment_number != eoe->rx_expected_fragment) {
00463 dev_kfree_skb(eoe->rx_skb);
00464 eoe->rx_skb = NULL;
00465 eoe->stats.rx_errors++;
00466 eoe->state = ec_eoe_state_tx_start;
00467 return;
00468 }
00469 }
00470
00471
00472 memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
00473 eoe->rx_skb_offset += data_size;
00474
00475 if (last_fragment) {
00476
00477 eoe->stats.rx_packets++;
00478 eoe->stats.rx_bytes += eoe->rx_skb->len;
00479 eoe->rx_counter += eoe->rx_skb->len;
00480
00481 #if EOE_DEBUG_LEVEL > 0
00482 EC_DBG("EoE RX frame completed with %u octets.\n",
00483 eoe->rx_skb->len);
00484 #endif
00485
00486
00487 eoe->rx_skb->dev = eoe->dev;
00488 eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
00489 eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
00490 if (netif_rx(eoe->rx_skb)) {
00491 EC_WARN("EoE RX netif_rx failed.\n");
00492 }
00493 eoe->rx_skb = NULL;
00494
00495 eoe->state = ec_eoe_state_tx_start;
00496 }
00497 else {
00498 eoe->rx_expected_fragment++;
00499 #if EOE_DEBUG_LEVEL > 0
00500 EC_DBG("EoE RX expecting fragment %i\n",
00501 eoe->rx_expected_fragment);
00502 #endif
00503 eoe->state = ec_eoe_state_rx_start;
00504 }
00505 }
00506
00507
00508
00515 void ec_eoe_state_tx_start(ec_eoe_t *eoe )
00516 {
00517 #if EOE_DEBUG_LEVEL > 0
00518 unsigned int wakeup = 0;
00519 #endif
00520
00521 if (!eoe->slave->online || !eoe->slave->master->device->link_state)
00522 return;
00523
00524 spin_lock_bh(&eoe->tx_queue_lock);
00525
00526 if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) {
00527 spin_unlock_bh(&eoe->tx_queue_lock);
00528
00529
00530 ec_eoe_state_rx_start(eoe);
00531 return;
00532 }
00533
00534
00535 eoe->tx_frame = list_entry(eoe->tx_queue.next, ec_eoe_frame_t, queue);
00536 list_del(&eoe->tx_frame->queue);
00537 if (!eoe->tx_queue_active &&
00538 eoe->tx_queued_frames == EC_EOE_TX_QUEUE_SIZE / 2) {
00539 netif_wake_queue(eoe->dev);
00540 eoe->tx_queue_active = 1;
00541 #if EOE_DEBUG_LEVEL > 0
00542 wakeup = 1;
00543 #endif
00544 }
00545
00546 eoe->tx_queued_frames--;
00547 spin_unlock_bh(&eoe->tx_queue_lock);
00548
00549 eoe->tx_frame_number++;
00550 eoe->tx_frame_number %= 16;
00551 eoe->tx_fragment_number = 0;
00552 eoe->tx_offset = 0;
00553
00554 if (ec_eoe_send(eoe)) {
00555 dev_kfree_skb(eoe->tx_frame->skb);
00556 kfree(eoe->tx_frame);
00557 eoe->tx_frame = NULL;
00558 eoe->stats.tx_errors++;
00559 eoe->state = ec_eoe_state_rx_start;
00560 return;
00561 }
00562
00563 #if EOE_DEBUG_LEVEL > 0
00564 if (wakeup) EC_DBG("waking up TX queue...\n");
00565 #endif
00566
00567 eoe->state = ec_eoe_state_tx_sent;
00568 }
00569
00570
00571
00578 void ec_eoe_state_tx_sent(ec_eoe_t *eoe )
00579 {
00580 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
00581 eoe->stats.tx_errors++;
00582 eoe->state = ec_eoe_state_rx_start;
00583 return;
00584 }
00585
00586 if (eoe->datagram.working_counter != 1) {
00587 eoe->stats.tx_errors++;
00588 eoe->state = ec_eoe_state_rx_start;
00589 return;
00590 }
00591
00592
00593 if (eoe->tx_offset >= eoe->tx_frame->skb->len) {
00594 eoe->stats.tx_packets++;
00595 eoe->stats.tx_bytes += eoe->tx_frame->skb->len;
00596 eoe->tx_counter += eoe->tx_frame->skb->len;
00597 dev_kfree_skb(eoe->tx_frame->skb);
00598 kfree(eoe->tx_frame);
00599 eoe->tx_frame = NULL;
00600 eoe->state = ec_eoe_state_rx_start;
00601 }
00602 else {
00603 if (ec_eoe_send(eoe)) {
00604 dev_kfree_skb(eoe->tx_frame->skb);
00605 kfree(eoe->tx_frame);
00606 eoe->tx_frame = NULL;
00607 eoe->stats.tx_errors++;
00608 eoe->state = ec_eoe_state_rx_start;
00609 }
00610 }
00611 }
00612
00613
00614
00615
00616
00621 int ec_eoedev_open(struct net_device *dev )
00622 {
00623 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00624 ec_eoe_flush(eoe);
00625 eoe->opened = 1;
00626 netif_start_queue(dev);
00627 eoe->tx_queue_active = 1;
00628 EC_INFO("%s opened.\n", dev->name);
00629 if (!eoe->slave)
00630 EC_WARN("Device %s is not coupled to any EoE slave!\n", dev->name);
00631 else {
00632 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
00633 }
00634 return 0;
00635 }
00636
00637
00638
00643 int ec_eoedev_stop(struct net_device *dev )
00644 {
00645 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00646 netif_stop_queue(dev);
00647 eoe->tx_queue_active = 0;
00648 eoe->opened = 0;
00649 ec_eoe_flush(eoe);
00650 EC_INFO("%s stopped.\n", dev->name);
00651 if (!eoe->slave)
00652 EC_WARN("Device %s is not coupled to any EoE slave!\n", dev->name);
00653 else {
00654 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_PREOP);
00655 }
00656 return 0;
00657 }
00658
00659
00660
00665 int ec_eoedev_tx(struct sk_buff *skb,
00666 struct net_device *dev
00667 )
00668 {
00669 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00670 ec_eoe_frame_t *frame;
00671
00672 #if 0
00673 if (skb->len > eoe->slave->sii_tx_mailbox_size - 10) {
00674 EC_WARN("EoE TX frame (%i octets) exceeds MTU. dropping.\n", skb->len);
00675 dev_kfree_skb(skb);
00676 eoe->stats.tx_dropped++;
00677 return 0;
00678 }
00679 #endif
00680
00681 if (!(frame =
00682 (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) {
00683 if (printk_ratelimit())
00684 EC_WARN("EoE TX: low on mem. frame dropped.\n");
00685 return 1;
00686 }
00687
00688 frame->skb = skb;
00689
00690 spin_lock_bh(&eoe->tx_queue_lock);
00691 list_add_tail(&frame->queue, &eoe->tx_queue);
00692 eoe->tx_queued_frames++;
00693 if (eoe->tx_queued_frames == EC_EOE_TX_QUEUE_SIZE) {
00694 netif_stop_queue(dev);
00695 eoe->tx_queue_active = 0;
00696 }
00697 spin_unlock_bh(&eoe->tx_queue_lock);
00698
00699 #if EOE_DEBUG_LEVEL > 0
00700 EC_DBG("EoE TX queued frame with %i octets (%i frames queued).\n",
00701 skb->len, eoe->tx_queued_frames);
00702 if (!eoe->tx_queue_active)
00703 EC_WARN("EoE TX queue is now full.\n");
00704 #endif
00705
00706 return 0;
00707 }
00708
00709
00710
00715 struct net_device_stats *ec_eoedev_stats(struct net_device *dev)
00717 {
00718 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00719 return &eoe->stats;
00720 }
00721
00722