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
00035
00036
00037 #include <linux/version.h>
00038 #include <linux/netdevice.h>
00039 #include <linux/etherdevice.h>
00040
00041 #include "globals.h"
00042 #include "master.h"
00043 #include "slave.h"
00044 #include "mailbox.h"
00045 #include "ethernet.h"
00046
00047
00048
00056 #define EOE_DEBUG_LEVEL 1
00057
00060 #define EC_EOE_TX_QUEUE_SIZE 100
00061
00064 #define EC_EOE_TRIES 100
00065
00066
00067
00068 void ec_eoe_flush(ec_eoe_t *);
00069
00070
00071 void ec_eoe_state_rx_start(ec_eoe_t *);
00072 void ec_eoe_state_rx_check(ec_eoe_t *);
00073 void ec_eoe_state_rx_fetch(ec_eoe_t *);
00074 void ec_eoe_state_tx_start(ec_eoe_t *);
00075 void ec_eoe_state_tx_sent(ec_eoe_t *);
00076
00077
00078 int ec_eoedev_open(struct net_device *);
00079 int ec_eoedev_stop(struct net_device *);
00080 int ec_eoedev_tx(struct sk_buff *, struct net_device *);
00081 struct net_device_stats *ec_eoedev_stats(struct net_device *);
00082
00083
00084
00085 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
00086
00088 static const struct net_device_ops ec_eoedev_ops = {
00089 .ndo_open = ec_eoedev_open,
00090 .ndo_stop = ec_eoedev_stop,
00091 .ndo_start_xmit = ec_eoedev_tx,
00092 .ndo_get_stats = ec_eoedev_stats,
00093 };
00094 #endif
00095
00096
00097
00104 int ec_eoe_init(
00105 ec_eoe_t *eoe,
00106 ec_slave_t *slave
00107 )
00108 {
00109 ec_eoe_t **priv;
00110 int i, ret = 0;
00111 char name[EC_DATAGRAM_NAME_SIZE];
00112
00113 eoe->slave = slave;
00114
00115 ec_datagram_init(&eoe->datagram);
00116 eoe->queue_datagram = 0;
00117 eoe->state = ec_eoe_state_rx_start;
00118 eoe->opened = 0;
00119 eoe->rx_skb = NULL;
00120 eoe->rx_expected_fragment = 0;
00121 INIT_LIST_HEAD(&eoe->tx_queue);
00122 eoe->tx_frame = NULL;
00123 eoe->tx_queue_active = 0;
00124 eoe->tx_queue_size = EC_EOE_TX_QUEUE_SIZE;
00125 eoe->tx_queued_frames = 0;
00126
00127 sema_init(&eoe->tx_queue_sem, 1);
00128 eoe->tx_frame_number = 0xFF;
00129 memset(&eoe->stats, 0, sizeof(struct net_device_stats));
00130
00131 eoe->rx_counter = 0;
00132 eoe->tx_counter = 0;
00133 eoe->rx_rate = 0;
00134 eoe->tx_rate = 0;
00135 eoe->rate_jiffies = 0;
00136 eoe->rx_idle = 1;
00137 eoe->tx_idle = 1;
00138
00139
00140
00141 if (slave->effective_alias) {
00142 snprintf(name, EC_DATAGRAM_NAME_SIZE,
00143 "eoe%ua%u", slave->master->index, slave->effective_alias);
00144 } else {
00145 snprintf(name, EC_DATAGRAM_NAME_SIZE,
00146 "eoe%us%u", slave->master->index, slave->ring_position);
00147 }
00148
00149 snprintf(eoe->datagram.name, EC_DATAGRAM_NAME_SIZE, name);
00150
00151 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
00152 eoe->dev = alloc_netdev(sizeof(ec_eoe_t *), name, NET_NAME_UNKNOWN,
00153 ether_setup);
00154 #else
00155 eoe->dev = alloc_netdev(sizeof(ec_eoe_t *), name, ether_setup);
00156 #endif
00157 if (!eoe->dev) {
00158 EC_SLAVE_ERR(slave, "Unable to allocate net_device %s"
00159 " for EoE handler!\n", name);
00160 ret = -ENODEV;
00161 goto out_return;
00162 }
00163
00164
00165 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
00166 eoe->dev->netdev_ops = &ec_eoedev_ops;
00167 #else
00168 eoe->dev->open = ec_eoedev_open;
00169 eoe->dev->stop = ec_eoedev_stop;
00170 eoe->dev->hard_start_xmit = ec_eoedev_tx;
00171 eoe->dev->get_stats = ec_eoedev_stats;
00172 #endif
00173
00174 for (i = 0; i < ETH_ALEN; i++)
00175 eoe->dev->dev_addr[i] = i | (i << 4);
00176
00177
00178 priv = netdev_priv(eoe->dev);
00179 *priv = eoe;
00180
00181
00182
00183
00184
00185 #if 0
00186 eoe->dev->mtu = slave->configured_rx_mailbox_size - ETH_HLEN - 10;
00187 #endif
00188
00189
00190 ret = register_netdev(eoe->dev);
00191 if (ret) {
00192 EC_SLAVE_ERR(slave, "Unable to register net_device:"
00193 " error %i\n", ret);
00194 goto out_free;
00195 }
00196
00197
00198 eoe->dev->dev_addr[ETH_ALEN - 1] = (uint8_t) eoe->dev->ifindex;
00199 return 0;
00200
00201 out_free:
00202 free_netdev(eoe->dev);
00203 eoe->dev = NULL;
00204 out_return:
00205 return ret;
00206 }
00207
00208
00209
00214 void ec_eoe_clear(ec_eoe_t *eoe )
00215 {
00216 unregister_netdev(eoe->dev);
00217
00218
00219 ec_eoe_flush(eoe);
00220
00221 if (eoe->tx_frame) {
00222 dev_kfree_skb(eoe->tx_frame->skb);
00223 kfree(eoe->tx_frame);
00224 }
00225
00226 if (eoe->rx_skb)
00227 dev_kfree_skb(eoe->rx_skb);
00228
00229 free_netdev(eoe->dev);
00230
00231 ec_datagram_clear(&eoe->datagram);
00232 }
00233
00234
00235
00238 void ec_eoe_flush(ec_eoe_t *eoe )
00239 {
00240 ec_eoe_frame_t *frame, *next;
00241
00242 down(&eoe->tx_queue_sem);
00243
00244 list_for_each_entry_safe(frame, next, &eoe->tx_queue, queue) {
00245 list_del(&frame->queue);
00246 dev_kfree_skb(frame->skb);
00247 kfree(frame);
00248 }
00249 eoe->tx_queued_frames = 0;
00250
00251 up(&eoe->tx_queue_sem);
00252 }
00253
00254
00255
00260 int ec_eoe_send(ec_eoe_t *eoe )
00261 {
00262 size_t remaining_size, current_size, complete_offset;
00263 unsigned int last_fragment;
00264 uint8_t *data;
00265 #if EOE_DEBUG_LEVEL >= 3
00266 unsigned int i;
00267 #endif
00268
00269 remaining_size = eoe->tx_frame->skb->len - eoe->tx_offset;
00270
00271 if (remaining_size <= eoe->slave->configured_tx_mailbox_size - 10) {
00272 current_size = remaining_size;
00273 last_fragment = 1;
00274 } else {
00275 current_size = ((eoe->slave->configured_tx_mailbox_size - 10) / 32) * 32;
00276 last_fragment = 0;
00277 }
00278
00279 if (eoe->tx_fragment_number) {
00280 complete_offset = eoe->tx_offset / 32;
00281 }
00282 else {
00283
00284 complete_offset = remaining_size / 32 + 1;
00285 }
00286
00287 #if EOE_DEBUG_LEVEL >= 2
00288 EC_SLAVE_DBG(slave, 0, "EoE %s TX sending fragment %u%s"
00289 " with %u octets (%u). %u frames queued.\n",
00290 eoe->dev->name, eoe->tx_fragment_number,
00291 last_fragment ? "" : "+", current_size, complete_offset,
00292 eoe->tx_queued_frames);
00293 #endif
00294
00295 #if EOE_DEBUG_LEVEL >= 3
00296 EC_SLAVE_DBG(master, 0, "");
00297 for (i = 0; i < current_size; i++) {
00298 printk("%02X ", eoe->tx_frame->skb->data[eoe->tx_offset + i]);
00299 if ((i + 1) % 16 == 0) {
00300 printk("\n");
00301 EC_SLAVE_DBG(master, 0, "");
00302 }
00303 }
00304 printk("\n");
00305 #endif
00306
00307 data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
00308 0x02, current_size + 4);
00309 if (IS_ERR(data))
00310 return PTR_ERR(data);
00311
00312 EC_WRITE_U8 (data, 0x00);
00313 EC_WRITE_U8 (data + 1, last_fragment);
00314 EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) |
00315 (complete_offset & 0x3F) << 6 |
00316 (eoe->tx_frame_number & 0x0F) << 12));
00317
00318 memcpy(data + 4, eoe->tx_frame->skb->data + eoe->tx_offset, current_size);
00319 eoe->queue_datagram = 1;
00320
00321 eoe->tx_offset += current_size;
00322 eoe->tx_fragment_number++;
00323 return 0;
00324 }
00325
00326
00327
00330 void ec_eoe_run(ec_eoe_t *eoe )
00331 {
00332 if (!eoe->opened)
00333 return;
00334
00335
00336 if (eoe->queue_datagram || eoe->datagram.state == EC_DATAGRAM_SENT)
00337 return;
00338
00339
00340 eoe->state(eoe);
00341
00342
00343 if (jiffies - eoe->rate_jiffies > HZ) {
00344 eoe->rx_rate = eoe->rx_counter;
00345 eoe->tx_rate = eoe->tx_counter;
00346 eoe->rx_counter = 0;
00347 eoe->tx_counter = 0;
00348 eoe->rate_jiffies = jiffies;
00349 }
00350
00351 ec_datagram_output_stats(&eoe->datagram);
00352 }
00353
00354
00355
00358 void ec_eoe_queue(ec_eoe_t *eoe )
00359 {
00360 if (eoe->queue_datagram) {
00361 ec_master_queue_datagram_ext(eoe->slave->master, &eoe->datagram);
00362 eoe->queue_datagram = 0;
00363 }
00364 }
00365
00366
00367
00372 int ec_eoe_is_open(const ec_eoe_t *eoe )
00373 {
00374 return eoe->opened;
00375 }
00376
00377
00378
00384 int ec_eoe_is_idle(const ec_eoe_t *eoe )
00385 {
00386 return eoe->rx_idle && eoe->tx_idle;
00387 }
00388
00389
00390
00391
00392
00400 void ec_eoe_state_rx_start(ec_eoe_t *eoe )
00401 {
00402 if (eoe->slave->error_flag ||
00403 !eoe->slave->master->devices[EC_DEVICE_MAIN].link_state) {
00404 eoe->rx_idle = 1;
00405 eoe->tx_idle = 1;
00406 return;
00407 }
00408
00409 ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
00410 eoe->queue_datagram = 1;
00411 eoe->state = ec_eoe_state_rx_check;
00412 }
00413
00414
00415
00421 void ec_eoe_state_rx_check(ec_eoe_t *eoe )
00422 {
00423 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
00424 eoe->stats.rx_errors++;
00425 #if EOE_DEBUG_LEVEL >= 1
00426 EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
00427 " check datagram for %s.\n", eoe->dev->name);
00428 #endif
00429 eoe->state = ec_eoe_state_tx_start;
00430 return;
00431 }
00432
00433 if (!ec_slave_mbox_check(&eoe->datagram)) {
00434 eoe->rx_idle = 1;
00435 eoe->state = ec_eoe_state_tx_start;
00436 return;
00437 }
00438
00439 eoe->rx_idle = 0;
00440 ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram);
00441 eoe->queue_datagram = 1;
00442 eoe->state = ec_eoe_state_rx_fetch;
00443 }
00444
00445
00446
00452 void ec_eoe_state_rx_fetch(ec_eoe_t *eoe )
00453 {
00454 size_t rec_size, data_size;
00455 uint8_t *data, frame_type, last_fragment, time_appended, mbox_prot;
00456 uint8_t fragment_offset, fragment_number;
00457 #if EOE_DEBUG_LEVEL >= 2
00458 uint8_t frame_number;
00459 #endif
00460 off_t offset;
00461 #if EOE_DEBUG_LEVEL >= 3
00462 unsigned int i;
00463 #endif
00464
00465 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
00466 eoe->stats.rx_errors++;
00467 #if EOE_DEBUG_LEVEL >= 1
00468 EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
00469 " fetch datagram for %s.\n", eoe->dev->name);
00470 #endif
00471 eoe->state = ec_eoe_state_tx_start;
00472 return;
00473 }
00474
00475 data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram,
00476 &mbox_prot, &rec_size);
00477 if (IS_ERR(data)) {
00478 eoe->stats.rx_errors++;
00479 #if EOE_DEBUG_LEVEL >= 1
00480 EC_SLAVE_WARN(eoe->slave, "Invalid mailbox response for %s.\n",
00481 eoe->dev->name);
00482 #endif
00483 eoe->state = ec_eoe_state_tx_start;
00484 return;
00485 }
00486
00487 if (mbox_prot != 0x02) {
00488 eoe->stats.rx_errors++;
00489 #if EOE_DEBUG_LEVEL >= 1
00490 EC_SLAVE_WARN(eoe->slave, "Other mailbox protocol response for %s.\n",
00491 eoe->dev->name);
00492 #endif
00493 eoe->state = ec_eoe_state_tx_start;
00494 return;
00495 }
00496
00497 frame_type = EC_READ_U16(data) & 0x000F;
00498
00499 if (frame_type != 0x00) {
00500 #if EOE_DEBUG_LEVEL >= 1
00501 EC_SLAVE_WARN(eoe->slave, "%s: Other frame received."
00502 " Dropping.\n", eoe->dev->name);
00503 #endif
00504 eoe->stats.rx_dropped++;
00505 eoe->state = ec_eoe_state_tx_start;
00506 return;
00507 }
00508
00509
00510
00511 last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
00512 time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
00513 fragment_number = EC_READ_U16(data + 2) & 0x003F;
00514 fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
00515 #if EOE_DEBUG_LEVEL >= 2
00516 frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
00517 #endif
00518
00519 #if EOE_DEBUG_LEVEL >= 2
00520 EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX fragment %u%s, offset %u,"
00521 " frame %u%s, %u octets\n", eoe->dev->name, fragment_number,
00522 last_fragment ? "" : "+", fragment_offset, frame_number,
00523 time_appended ? ", + timestamp" : "",
00524 time_appended ? rec_size - 8 : rec_size - 4);
00525 #endif
00526
00527 #if EOE_DEBUG_LEVEL >= 3
00528 EC_SLAVE_DBG(eoe->slave, 0, "");
00529 for (i = 0; i < rec_size - 4; i++) {
00530 printk("%02X ", data[i + 4]);
00531 if ((i + 1) % 16 == 0) {
00532 printk("\n");
00533 EC_SLAVE_DBG(eoe->slave, 0, "");
00534 }
00535 }
00536 printk("\n");
00537 #endif
00538
00539 data_size = time_appended ? rec_size - 8 : rec_size - 4;
00540
00541 if (!fragment_number) {
00542 if (eoe->rx_skb) {
00543 EC_SLAVE_WARN(eoe->slave, "EoE RX freeing old socket buffer.\n");
00544 dev_kfree_skb(eoe->rx_skb);
00545 }
00546
00547
00548 if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
00549 if (printk_ratelimit())
00550 EC_SLAVE_WARN(eoe->slave, "EoE RX low on mem,"
00551 " frame dropped.\n");
00552 eoe->stats.rx_dropped++;
00553 eoe->state = ec_eoe_state_tx_start;
00554 return;
00555 }
00556
00557 eoe->rx_skb_offset = 0;
00558 eoe->rx_skb_size = fragment_offset * 32;
00559 eoe->rx_expected_fragment = 0;
00560 }
00561 else {
00562 if (!eoe->rx_skb) {
00563 eoe->stats.rx_dropped++;
00564 eoe->state = ec_eoe_state_tx_start;
00565 return;
00566 }
00567
00568 offset = fragment_offset * 32;
00569 if (offset != eoe->rx_skb_offset ||
00570 offset + data_size > eoe->rx_skb_size ||
00571 fragment_number != eoe->rx_expected_fragment) {
00572 dev_kfree_skb(eoe->rx_skb);
00573 eoe->rx_skb = NULL;
00574 eoe->stats.rx_errors++;
00575 #if EOE_DEBUG_LEVEL >= 1
00576 EC_SLAVE_WARN(eoe->slave, "Fragmenting error at %s.\n",
00577 eoe->dev->name);
00578 #endif
00579 eoe->state = ec_eoe_state_tx_start;
00580 return;
00581 }
00582 }
00583
00584
00585 memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
00586 eoe->rx_skb_offset += data_size;
00587
00588 if (last_fragment) {
00589
00590 eoe->stats.rx_packets++;
00591 eoe->stats.rx_bytes += eoe->rx_skb->len;
00592 eoe->rx_counter += eoe->rx_skb->len;
00593
00594 #if EOE_DEBUG_LEVEL >= 2
00595 EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX frame completed"
00596 " with %u octets.\n", eoe->dev->name, eoe->rx_skb->len);
00597 #endif
00598
00599
00600 eoe->rx_skb->dev = eoe->dev;
00601 eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
00602 eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
00603 if (netif_rx(eoe->rx_skb)) {
00604 EC_SLAVE_WARN(eoe->slave, "EoE RX netif_rx failed.\n");
00605 }
00606 eoe->rx_skb = NULL;
00607
00608 eoe->state = ec_eoe_state_tx_start;
00609 }
00610 else {
00611 eoe->rx_expected_fragment++;
00612 #if EOE_DEBUG_LEVEL >= 2
00613 EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX expecting fragment %u\n",
00614 eoe->dev->name, eoe->rx_expected_fragment);
00615 #endif
00616 eoe->state = ec_eoe_state_rx_start;
00617 }
00618 }
00619
00620
00621
00629 void ec_eoe_state_tx_start(ec_eoe_t *eoe )
00630 {
00631 #if EOE_DEBUG_LEVEL >= 2
00632 unsigned int wakeup = 0;
00633 #endif
00634
00635 if (eoe->slave->error_flag ||
00636 !eoe->slave->master->devices[EC_DEVICE_MAIN].link_state) {
00637 eoe->rx_idle = 1;
00638 eoe->tx_idle = 1;
00639 return;
00640 }
00641
00642 down(&eoe->tx_queue_sem);
00643
00644 if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) {
00645 up(&eoe->tx_queue_sem);
00646 eoe->tx_idle = 1;
00647
00648
00649 ec_eoe_state_rx_start(eoe);
00650 return;
00651 }
00652
00653
00654 eoe->tx_frame = list_entry(eoe->tx_queue.next, ec_eoe_frame_t, queue);
00655 list_del(&eoe->tx_frame->queue);
00656 if (!eoe->tx_queue_active &&
00657 eoe->tx_queued_frames == eoe->tx_queue_size / 2) {
00658 netif_wake_queue(eoe->dev);
00659 eoe->tx_queue_active = 1;
00660 #if EOE_DEBUG_LEVEL >= 2
00661 wakeup = 1;
00662 #endif
00663 }
00664
00665 eoe->tx_queued_frames--;
00666 up(&eoe->tx_queue_sem);
00667
00668 eoe->tx_idle = 0;
00669
00670 eoe->tx_frame_number++;
00671 eoe->tx_frame_number %= 16;
00672 eoe->tx_fragment_number = 0;
00673 eoe->tx_offset = 0;
00674
00675 if (ec_eoe_send(eoe)) {
00676 dev_kfree_skb(eoe->tx_frame->skb);
00677 kfree(eoe->tx_frame);
00678 eoe->tx_frame = NULL;
00679 eoe->stats.tx_errors++;
00680 eoe->state = ec_eoe_state_rx_start;
00681 #if EOE_DEBUG_LEVEL >= 1
00682 EC_SLAVE_WARN(eoe->slave, "Send error at %s.\n", eoe->dev->name);
00683 #endif
00684 return;
00685 }
00686
00687 #if EOE_DEBUG_LEVEL >= 2
00688 if (wakeup)
00689 EC_SLAVE_DBG(eoe->slave, 0, "EoE %s waking up TX queue...\n",
00690 eoe->dev->name);
00691 #endif
00692
00693 eoe->tries = EC_EOE_TRIES;
00694 eoe->state = ec_eoe_state_tx_sent;
00695 }
00696
00697
00698
00704 void ec_eoe_state_tx_sent(ec_eoe_t *eoe )
00705 {
00706 if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
00707 if (eoe->tries) {
00708 eoe->tries--;
00709 eoe->queue_datagram = 1;
00710 } else {
00711 eoe->stats.tx_errors++;
00712 #if EOE_DEBUG_LEVEL >= 1
00713 EC_SLAVE_WARN(eoe->slave, "Failed to receive send"
00714 " datagram for %s after %u tries.\n",
00715 eoe->dev->name, EC_EOE_TRIES);
00716 #endif
00717 eoe->state = ec_eoe_state_rx_start;
00718 }
00719 return;
00720 }
00721
00722 if (eoe->datagram.working_counter != 1) {
00723 if (eoe->tries) {
00724 eoe->tries--;
00725 eoe->queue_datagram = 1;
00726 } else {
00727 eoe->stats.tx_errors++;
00728 #if EOE_DEBUG_LEVEL >= 1
00729 EC_SLAVE_WARN(eoe->slave, "No sending response"
00730 " for %s after %u tries.\n",
00731 eoe->dev->name, EC_EOE_TRIES);
00732 #endif
00733 eoe->state = ec_eoe_state_rx_start;
00734 }
00735 return;
00736 }
00737
00738
00739 if (eoe->tx_offset >= eoe->tx_frame->skb->len) {
00740 eoe->stats.tx_packets++;
00741 eoe->stats.tx_bytes += eoe->tx_frame->skb->len;
00742 eoe->tx_counter += eoe->tx_frame->skb->len;
00743 dev_kfree_skb(eoe->tx_frame->skb);
00744 kfree(eoe->tx_frame);
00745 eoe->tx_frame = NULL;
00746 eoe->state = ec_eoe_state_rx_start;
00747 }
00748 else {
00749 if (ec_eoe_send(eoe)) {
00750 dev_kfree_skb(eoe->tx_frame->skb);
00751 kfree(eoe->tx_frame);
00752 eoe->tx_frame = NULL;
00753 eoe->stats.tx_errors++;
00754 #if EOE_DEBUG_LEVEL >= 1
00755 EC_SLAVE_WARN(eoe->slave, "Send error at %s.\n", eoe->dev->name);
00756 #endif
00757 eoe->state = ec_eoe_state_rx_start;
00758 }
00759 }
00760 }
00761
00762
00763
00764
00765
00770 int ec_eoedev_open(struct net_device *dev )
00771 {
00772 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00773 ec_eoe_flush(eoe);
00774 eoe->opened = 1;
00775 eoe->rx_idle = 0;
00776 eoe->tx_idle = 0;
00777 netif_start_queue(dev);
00778 eoe->tx_queue_active = 1;
00779 #if EOE_DEBUG_LEVEL >= 2
00780 EC_SLAVE_DBG(eoe->slave, 0, "%s opened.\n", dev->name);
00781 #endif
00782 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
00783 return 0;
00784 }
00785
00786
00787
00792 int ec_eoedev_stop(struct net_device *dev )
00793 {
00794 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00795 netif_stop_queue(dev);
00796 eoe->rx_idle = 1;
00797 eoe->tx_idle = 1;
00798 eoe->tx_queue_active = 0;
00799 eoe->opened = 0;
00800 ec_eoe_flush(eoe);
00801 #if EOE_DEBUG_LEVEL >= 2
00802 EC_SLAVE_DBG(eoe->slave, 0, "%s stopped.\n", dev->name);
00803 #endif
00804 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_PREOP);
00805 return 0;
00806 }
00807
00808
00809
00814 int ec_eoedev_tx(struct sk_buff *skb,
00815 struct net_device *dev
00816 )
00817 {
00818 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00819 ec_eoe_frame_t *frame;
00820
00821 #if 0
00822 if (skb->len > eoe->slave->configured_tx_mailbox_size - 10) {
00823 EC_SLAVE_WARN(eoe->slave, "EoE TX frame (%u octets)"
00824 " exceeds MTU. dropping.\n", skb->len);
00825 dev_kfree_skb(skb);
00826 eoe->stats.tx_dropped++;
00827 return 0;
00828 }
00829 #endif
00830
00831 if (!(frame =
00832 (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) {
00833 if (printk_ratelimit())
00834 EC_SLAVE_WARN(eoe->slave, "EoE TX: low on mem. frame dropped.\n");
00835 return 1;
00836 }
00837
00838 frame->skb = skb;
00839
00840 down(&eoe->tx_queue_sem);
00841 list_add_tail(&frame->queue, &eoe->tx_queue);
00842 eoe->tx_queued_frames++;
00843 if (eoe->tx_queued_frames == eoe->tx_queue_size) {
00844 netif_stop_queue(dev);
00845 eoe->tx_queue_active = 0;
00846 }
00847 up(&eoe->tx_queue_sem);
00848
00849 #if EOE_DEBUG_LEVEL >= 2
00850 EC_SLAVE_DBG(eoe->slave, 0, "EoE %s TX queued frame"
00851 " with %u octets (%u frames queued).\n",
00852 eoe->dev->name, skb->len, eoe->tx_queued_frames);
00853 if (!eoe->tx_queue_active)
00854 EC_SLAVE_WARN(eoe->slave, "EoE TX queue is now full.\n");
00855 #endif
00856
00857 return 0;
00858 }
00859
00860
00861
00866 struct net_device_stats *ec_eoedev_stats(
00867 struct net_device *dev
00868 )
00869 {
00870 ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
00871 return &eoe->stats;
00872 }
00873
00874