master/ethernet.c
changeset 2068 3001f6523e63
parent 2045 ff2a13a4603c
child 2094 83e9160319ec
equal deleted inserted replaced
2067:19732da2cf86 2068:3001f6523e63
   109     char name[EC_DATAGRAM_NAME_SIZE];
   109     char name[EC_DATAGRAM_NAME_SIZE];
   110 
   110 
   111     eoe->slave = slave;
   111     eoe->slave = slave;
   112 
   112 
   113     ec_datagram_init(&eoe->datagram);
   113     ec_datagram_init(&eoe->datagram);
       
   114     ec_mbox_init(&eoe->mbox,&eoe->datagram);
   114     eoe->queue_datagram = 0;
   115     eoe->queue_datagram = 0;
   115     eoe->state = ec_eoe_state_rx_start;
   116     eoe->state = ec_eoe_state_rx_start;
   116     eoe->opened = 0;
   117     eoe->opened = 0;
   117     eoe->rx_skb = NULL;
   118     eoe->rx_skb = NULL;
   118     eoe->rx_expected_fragment = 0;
   119     eoe->rx_expected_fragment = 0;
   120     eoe->tx_frame = NULL;
   121     eoe->tx_frame = NULL;
   121     eoe->tx_queue_active = 0;
   122     eoe->tx_queue_active = 0;
   122     eoe->tx_queue_size = EC_EOE_TX_QUEUE_SIZE;
   123     eoe->tx_queue_size = EC_EOE_TX_QUEUE_SIZE;
   123     eoe->tx_queued_frames = 0;
   124     eoe->tx_queued_frames = 0;
   124 
   125 
   125     sema_init(&eoe->tx_queue_sem, 1);
   126     ec_mutex_init(&eoe->tx_queue_mutex);
   126     eoe->tx_frame_number = 0xFF;
   127     eoe->tx_frame_number = 0xFF;
   127     memset(&eoe->stats, 0, sizeof(struct net_device_stats));
   128     memset(&eoe->stats, 0, sizeof(struct net_device_stats));
   128 
   129 
   129     eoe->rx_counter = 0;
   130     eoe->rx_counter = 0;
   130     eoe->tx_counter = 0;
   131     eoe->tx_counter = 0;
   218     if (eoe->rx_skb)
   219     if (eoe->rx_skb)
   219         dev_kfree_skb(eoe->rx_skb);
   220         dev_kfree_skb(eoe->rx_skb);
   220 
   221 
   221     free_netdev(eoe->dev);
   222     free_netdev(eoe->dev);
   222 
   223 
       
   224     ec_mbox_clear(&eoe->mbox);
   223     ec_datagram_clear(&eoe->datagram);
   225     ec_datagram_clear(&eoe->datagram);
   224 }
   226 }
   225 
   227 
   226 /*****************************************************************************/
   228 /*****************************************************************************/
   227 
   229 
   229  */
   231  */
   230 void ec_eoe_flush(ec_eoe_t *eoe /**< EoE handler */)
   232 void ec_eoe_flush(ec_eoe_t *eoe /**< EoE handler */)
   231 {
   233 {
   232     ec_eoe_frame_t *frame, *next;
   234     ec_eoe_frame_t *frame, *next;
   233 
   235 
   234     down(&eoe->tx_queue_sem);
   236     ec_mutex_lock(&eoe->tx_queue_mutex);
   235 
   237 
   236     list_for_each_entry_safe(frame, next, &eoe->tx_queue, queue) {
   238     list_for_each_entry_safe(frame, next, &eoe->tx_queue, queue) {
   237         list_del(&frame->queue);
   239         list_del(&frame->queue);
   238         dev_kfree_skb(frame->skb);
   240         dev_kfree_skb(frame->skb);
   239         kfree(frame);
   241         kfree(frame);
   240     }
   242     }
   241     eoe->tx_queued_frames = 0;
   243     eoe->tx_queued_frames = 0;
   242 
   244 
   243     up(&eoe->tx_queue_sem);
   245     ec_mutex_unlock(&eoe->tx_queue_mutex);
   244 }
   246 }
   245 
   247 
   246 /*****************************************************************************/
   248 /*****************************************************************************/
   247 
   249 
   248 /** Sends a frame or the next fragment.
   250 /** Sends a frame or the next fragment.
   292         }
   294         }
   293     }
   295     }
   294     printk("\n");
   296     printk("\n");
   295 #endif
   297 #endif
   296 
   298 
   297     data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
   299     data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->mbox,
   298             0x02, current_size + 4);
   300             0x02, current_size + 4);
   299     if (IS_ERR(data))
   301     if (IS_ERR(data))
   300         return PTR_ERR(data);
   302         return PTR_ERR(data);
   301 
   303 
   302     EC_WRITE_U8 (data,     0x00); // eoe fragment req.
   304     EC_WRITE_U8 (data,     0x00); // eoe fragment req.
   321 {
   323 {
   322     if (!eoe->opened)
   324     if (!eoe->opened)
   323         return;
   325         return;
   324 
   326 
   325     // if the datagram was not sent, or is not yet received, skip this cycle
   327     // if the datagram was not sent, or is not yet received, skip this cycle
   326     if (eoe->queue_datagram || eoe->datagram.state == EC_DATAGRAM_SENT)
   328     if (eoe->queue_datagram ||
       
   329         ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_QUEUED) ||
       
   330         ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_SENT))
   327         return;
   331         return;
   328 
   332 
   329     // call state function
   333     // call state function
   330     eoe->state(eoe);
   334     eoe->state(eoe);
   331 
   335 
   346 /** Queues the datagram, if necessary.
   350 /** Queues the datagram, if necessary.
   347  */
   351  */
   348 void ec_eoe_queue(ec_eoe_t *eoe /**< EoE handler */)
   352 void ec_eoe_queue(ec_eoe_t *eoe /**< EoE handler */)
   349 {
   353 {
   350    if (eoe->queue_datagram) {
   354    if (eoe->queue_datagram) {
   351        ec_master_queue_datagram_ext(eoe->slave->master, &eoe->datagram);
   355        ec_master_mbox_queue_datagrams(eoe->slave->master, &eoe->mbox);
   352        eoe->queue_datagram = 0;
   356        eoe->queue_datagram = 0;
   353    }
   357    }
   354 }
   358 }
   355 
   359 
   356 /*****************************************************************************/
   360 /*****************************************************************************/
   392         eoe->rx_idle = 1;
   396         eoe->rx_idle = 1;
   393         eoe->tx_idle = 1;
   397         eoe->tx_idle = 1;
   394         return;
   398         return;
   395     }
   399     }
   396 
   400 
   397     ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
   401     ec_slave_mbox_prepare_check(eoe->slave, &eoe->mbox);
   398     eoe->queue_datagram = 1;
   402     eoe->queue_datagram = 1;
   399     eoe->state = ec_eoe_state_rx_check;
   403     eoe->state = ec_eoe_state_rx_check;
   400 }
   404 }
   401 
   405 
   402 /*****************************************************************************/
   406 /*****************************************************************************/
   406  * Processes the checking datagram sent in RX_START and issues a receive
   410  * Processes the checking datagram sent in RX_START and issues a receive
   407  * datagram, if new data is available.
   411  * datagram, if new data is available.
   408  */
   412  */
   409 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
   413 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
   410 {
   414 {
   411     if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
   415     if (!ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_RECEIVED)) {
   412         eoe->stats.rx_errors++;
   416         eoe->stats.rx_errors++;
   413 #if EOE_DEBUG_LEVEL >= 1
   417 #if EOE_DEBUG_LEVEL >= 1
   414         EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
   418         EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
   415                 " check datagram for %s.\n", eoe->dev->name);
   419                 " check datagram for %s.\n", eoe->dev->name);
   416 #endif
   420 #endif
   417         eoe->state = ec_eoe_state_tx_start;
   421         eoe->state = ec_eoe_state_tx_start;
   418         return;
   422         return;
   419     }
   423     }
   420 
   424 
   421     if (!ec_slave_mbox_check(&eoe->datagram)) {
   425     if (!ec_slave_mbox_check(&eoe->mbox)) {
   422         eoe->rx_idle = 1;
   426         eoe->rx_idle = 1;
   423         eoe->state = ec_eoe_state_tx_start;
   427         eoe->state = ec_eoe_state_tx_start;
   424         return;
   428         return;
   425     }
   429     }
   426 
   430 
   427     eoe->rx_idle = 0;
   431     eoe->rx_idle = 0;
   428     ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram);
   432     ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->mbox);
   429     eoe->queue_datagram = 1;
   433     eoe->queue_datagram = 1;
   430     eoe->state = ec_eoe_state_rx_fetch;
   434     eoe->state = ec_eoe_state_rx_fetch;
   431 }
   435 }
   432 
   436 
   433 /*****************************************************************************/
   437 /*****************************************************************************/
   445     off_t offset;
   449     off_t offset;
   446 #if EOE_DEBUG_LEVEL >= 3
   450 #if EOE_DEBUG_LEVEL >= 3
   447     unsigned int i;
   451     unsigned int i;
   448 #endif
   452 #endif
   449 
   453 
   450     if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
   454     if (!ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_RECEIVED)) {
   451         eoe->stats.rx_errors++;
   455         eoe->stats.rx_errors++;
   452 #if EOE_DEBUG_LEVEL >= 1
   456 #if EOE_DEBUG_LEVEL >= 1
   453         EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
   457         EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
   454                 " fetch datagram for %s.\n", eoe->dev->name);
   458                 " fetch datagram for %s.\n", eoe->dev->name);
   455 #endif
   459 #endif
   456         eoe->state = ec_eoe_state_tx_start;
   460         eoe->state = ec_eoe_state_tx_start;
   457         return;
   461         return;
   458     }
   462     }
   459 
   463 
   460     data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram,
   464     data = ec_slave_mbox_fetch(eoe->slave, &eoe->mbox,
   461             &mbox_prot, &rec_size);
   465             &mbox_prot, &rec_size);
   462     if (IS_ERR(data)) {
   466     if (IS_ERR(data)) {
   463         eoe->stats.rx_errors++;
   467         eoe->stats.rx_errors++;
   464 #if EOE_DEBUG_LEVEL >= 1
   468 #if EOE_DEBUG_LEVEL >= 1
   465         EC_SLAVE_WARN(eoe->slave, "Invalid mailbox response for %s.\n",
   469         EC_SLAVE_WARN(eoe->slave, "Invalid mailbox response for %s.\n",
   618         eoe->rx_idle = 1;
   622         eoe->rx_idle = 1;
   619         eoe->tx_idle = 1;
   623         eoe->tx_idle = 1;
   620         return;
   624         return;
   621     }
   625     }
   622 
   626 
   623     down(&eoe->tx_queue_sem);
   627     ec_mutex_lock(&eoe->tx_queue_mutex);
   624 
   628 
   625     if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) {
   629     if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) {
   626         up(&eoe->tx_queue_sem);
   630         ec_mutex_unlock(&eoe->tx_queue_mutex);
   627         eoe->tx_idle = 1;
   631         eoe->tx_idle = 1;
   628         // no data available.
   632         // no data available.
   629         // start a new receive immediately.
   633         // start a new receive immediately.
   630         ec_eoe_state_rx_start(eoe);
   634         ec_eoe_state_rx_start(eoe);
   631         return;
   635         return;
   642         wakeup = 1;
   646         wakeup = 1;
   643 #endif
   647 #endif
   644     }
   648     }
   645 
   649 
   646     eoe->tx_queued_frames--;
   650     eoe->tx_queued_frames--;
   647     up(&eoe->tx_queue_sem);
   651     ec_mutex_unlock(&eoe->tx_queue_mutex);
   648 
   652 
   649     eoe->tx_idle = 0;
   653     eoe->tx_idle = 0;
   650 
   654 
   651     eoe->tx_frame_number++;
   655     eoe->tx_frame_number++;
   652     eoe->tx_frame_number %= 16;
   656     eoe->tx_frame_number %= 16;
   682  * Checks is the previous transmit datagram succeded and sends the next
   686  * Checks is the previous transmit datagram succeded and sends the next
   683  * fragment, if necessary.
   687  * fragment, if necessary.
   684  */
   688  */
   685 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
   689 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
   686 {
   690 {
   687     if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
   691     if (!ec_mbox_is_datagram_state(&eoe->mbox,EC_DATAGRAM_RECEIVED)) {
   688         if (eoe->tries) {
   692         if (eoe->tries) {
   689             eoe->tries--; // try again
   693             eoe->tries--; // try again
   690             eoe->queue_datagram = 1;
   694             eoe->queue_datagram = 1;
   691         } else {
   695         } else {
   692             eoe->stats.tx_errors++;
   696             eoe->stats.tx_errors++;
   698             eoe->state = ec_eoe_state_rx_start;
   702             eoe->state = ec_eoe_state_rx_start;
   699         }
   703         }
   700         return;
   704         return;
   701     }
   705     }
   702 
   706 
   703     if (eoe->datagram.working_counter != 1) {
   707     if (!ec_mbox_is_datagram_wc(&eoe->mbox,1)) {
   704         if (eoe->tries) {
   708         if (eoe->tries) {
   705             eoe->tries--; // try again
   709             eoe->tries--; // try again
   706             eoe->queue_datagram = 1;
   710             eoe->queue_datagram = 1;
   707         } else {
   711         } else {
   708             eoe->stats.tx_errors++;
   712             eoe->stats.tx_errors++;
   810         return 1;
   814         return 1;
   811     }
   815     }
   812 
   816 
   813     frame->skb = skb;
   817     frame->skb = skb;
   814 
   818 
   815     down(&eoe->tx_queue_sem);
   819     ec_mutex_lock(&eoe->tx_queue_mutex);
   816     list_add_tail(&frame->queue, &eoe->tx_queue);
   820     list_add_tail(&frame->queue, &eoe->tx_queue);
   817     eoe->tx_queued_frames++;
   821     eoe->tx_queued_frames++;
   818     if (eoe->tx_queued_frames == eoe->tx_queue_size) {
   822     if (eoe->tx_queued_frames == eoe->tx_queue_size) {
   819         netif_stop_queue(dev);
   823         netif_stop_queue(dev);
   820         eoe->tx_queue_active = 0;
   824         eoe->tx_queue_active = 0;
   821     }
   825     }
   822     up(&eoe->tx_queue_sem);
   826     ec_mutex_unlock(&eoe->tx_queue_mutex);
   823 
   827 
   824 #if EOE_DEBUG_LEVEL >= 2
   828 #if EOE_DEBUG_LEVEL >= 2
   825     EC_SLAVE_DBG(eoe->slave, 0, "EoE %s TX queued frame"
   829     EC_SLAVE_DBG(eoe->slave, 0, "EoE %s TX queued frame"
   826             " with %u octets (%u frames queued).\n",
   830             " with %u octets (%u frames queued).\n",
   827             eoe->dev->name, skb->len, eoe->tx_queued_frames);
   831             eoe->dev->name, skb->len, eoe->tx_queued_frames);