diff -r 3fb343e3fac0 -r f77a1182b6f4 master/ethernet.c --- a/master/ethernet.c Mon Jun 29 14:27:06 2009 +0000 +++ b/master/ethernet.c Tue Jun 30 11:11:56 2009 +0000 @@ -52,7 +52,7 @@ * 2 = Output actions. * 3 = Output actions and frame data. */ -#define EOE_DEBUG_LEVEL 0 +#define EOE_DEBUG_LEVEL 1 /** Size of the EoE tx queue. */ @@ -60,7 +60,7 @@ /** Number of tries. */ -#define EC_EOE_TRIES 10 +#define EC_EOE_TRIES 100 /*****************************************************************************/ @@ -107,7 +107,7 @@ eoe->tx_queue_active = 0; eoe->tx_queue_size = EC_EOE_TX_QUEUE_SIZE; eoe->tx_queued_frames = 0; - eoe->tx_queue_lock = SPIN_LOCK_UNLOCKED; + init_MUTEX(&eoe->tx_queue_sem); eoe->tx_frame_number = 0xFF; memset(&eoe->stats, 0, sizeof(struct net_device_stats)); @@ -116,6 +116,8 @@ eoe->rx_rate = 0; eoe->tx_rate = 0; eoe->rate_jiffies = 0; + eoe->rx_idle = 1; + eoe->tx_idle = 1; /* device name eoe[as], because networking scripts don't * like hyphens etc. in interface names. */ @@ -206,7 +208,7 @@ { ec_eoe_frame_t *frame, *next; - spin_lock_bh(&eoe->tx_queue_lock); + down(&eoe->tx_queue_sem); list_for_each_entry_safe(frame, next, &eoe->tx_queue, queue) { list_del(&frame->queue); @@ -215,7 +217,7 @@ } eoe->tx_queued_frames = 0; - spin_unlock_bh(&eoe->tx_queue_lock); + up(&eoe->tx_queue_sem); } /*****************************************************************************/ @@ -338,6 +340,18 @@ return eoe->opened; } +/*****************************************************************************/ + +/** Returns the idle state. + * + * \retval 1 The device is idle. + * \retval 0 The device is busy. + */ +int ec_eoe_is_idle(const ec_eoe_t *eoe /**< EoE handler */) +{ + return eoe->rx_idle && eoe->tx_idle; +} + /****************************************************************************** * STATE PROCESSING FUNCTIONS *****************************************************************************/ @@ -349,8 +363,12 @@ */ void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */) { - if (eoe->slave->error_flag || !eoe->slave->master->main_device.link_state) - return; + if (eoe->slave->error_flag || + !eoe->slave->master->main_device.link_state) { + eoe->rx_idle = 1; + eoe->tx_idle = 1; + return; + } ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram); eoe->queue_datagram = 1; @@ -377,10 +395,12 @@ } if (!ec_slave_mbox_check(&eoe->datagram)) { + eoe->rx_idle = 1; eoe->state = ec_eoe_state_tx_start; return; } + eoe->rx_idle = 0; ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram); eoe->queue_datagram = 1; eoe->state = ec_eoe_state_rx_fetch; @@ -566,13 +586,18 @@ unsigned int wakeup = 0; #endif - if (eoe->slave->error_flag || !eoe->slave->master->main_device.link_state) - return; - - spin_lock_bh(&eoe->tx_queue_lock); + if (eoe->slave->error_flag || + !eoe->slave->master->main_device.link_state) { + eoe->rx_idle = 1; + eoe->tx_idle = 1; + return; + } + + down(&eoe->tx_queue_sem); if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) { - spin_unlock_bh(&eoe->tx_queue_lock); + up(&eoe->tx_queue_sem); + eoe->tx_idle = 1; // no data available. // start a new receive immediately. ec_eoe_state_rx_start(eoe); @@ -592,7 +617,9 @@ } eoe->tx_queued_frames--; - spin_unlock_bh(&eoe->tx_queue_lock); + up(&eoe->tx_queue_sem); + + eoe->tx_idle = 0; eoe->tx_frame_number++; eoe->tx_frame_number %= 16; @@ -633,15 +660,11 @@ if (eoe->tries) { eoe->tries--; // try again eoe->queue_datagram = 1; -#if EOE_DEBUG_LEVEL >= 1 - EC_WARN("Failed to receive send datagram for %s. Retrying.\n", - eoe->dev->name); -#endif } else { eoe->stats.tx_errors++; #if EOE_DEBUG_LEVEL >= 1 - EC_WARN("Failed to receive send datagram for %s. Giving up.\n", - eoe->dev->name); + EC_WARN("Failed to receive send datagram for %s after %u tries.\n", + eoe->dev->name, EC_EOE_TRIES); #endif eoe->state = ec_eoe_state_rx_start; } @@ -652,13 +675,11 @@ if (eoe->tries) { eoe->tries--; // try again eoe->queue_datagram = 1; -#if EOE_DEBUG_LEVEL >= 1 - EC_WARN("No sending response for %s. Retrying.\n", eoe->dev->name); -#endif } else { eoe->stats.tx_errors++; #if EOE_DEBUG_LEVEL >= 1 - EC_WARN("No sending response for %s. Giving up.\n", eoe->dev->name); + EC_WARN("No sending response for %s after %u tries.\n", + eoe->dev->name, EC_EOE_TRIES); #endif eoe->state = ec_eoe_state_rx_start; } @@ -700,6 +721,8 @@ ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev)); ec_eoe_flush(eoe); eoe->opened = 1; + eoe->rx_idle = 0; + eoe->tx_idle = 0; netif_start_queue(dev); eoe->tx_queue_active = 1; #if EOE_DEBUG_LEVEL >= 2 @@ -717,6 +740,8 @@ { ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev)); netif_stop_queue(dev); + eoe->rx_idle = 1; + eoe->tx_idle = 1; eoe->tx_queue_active = 0; eoe->opened = 0; ec_eoe_flush(eoe); @@ -756,14 +781,14 @@ frame->skb = skb; - spin_lock_bh(&eoe->tx_queue_lock); + down(&eoe->tx_queue_sem); list_add_tail(&frame->queue, &eoe->tx_queue); eoe->tx_queued_frames++; if (eoe->tx_queued_frames == eoe->tx_queue_size) { netif_stop_queue(dev); eoe->tx_queue_active = 0; } - spin_unlock_bh(&eoe->tx_queue_lock); + up(&eoe->tx_queue_sem); #if EOE_DEBUG_LEVEL >= 2 EC_DBG("EoE %s TX queued frame with %u octets (%u frames queued).\n",