mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
- netif_start_queue(dev);
+ if (dev->flags & IFF_UP)
+ /* Otherwise process may sleep forever */
+ netif_wake_queue(dev);
+ else
+ netif_start_queue(dev);
e100_start_ru(bdp);
if ((rc = request_irq(dev->irq, &e100intr, SA_SHIRQ,
goto exit2;
}
- if (!TCBS_AVAIL(bdp->tcb_pool) ||
+ /* tcb list may be empty temporarily during releasing resources */
+ if (!TCBS_AVAIL(bdp->tcb_pool) || (bdp->tcb_phys == 0) ||
(bdp->non_tx_command_state != E100_NON_TX_IDLE)) {
notify_stop = true;
rc = 1;
if ((ecmd.autoneg == AUTONEG_ENABLE)
&& (bdp->speed_duplex_caps & SUPPORTED_Autoneg)) {
bdp->params.e100_speed_duplex = E100_AUTONEG;
- e100_set_speed_duplex(bdp);
+ if (netif_running(dev)) {
+ spin_lock_bh(&dev->xmit_lock);
+ e100_close(dev);
+ spin_unlock_bh(&dev->xmit_lock);
+ e100_hw_init(bdp);
+ e100_open(dev);
+ }
} else {
if (ecmd.speed == SPEED_10) {
if (ecmd.duplex == DUPLEX_HALF) {
if (bdp->speed_duplex_caps & ethtool_new_speed_duplex) {
bdp->params.e100_speed_duplex =
e100_new_speed_duplex;
- e100_set_speed_duplex(bdp);
+ if (netif_running(dev)) {
+ spin_lock_bh(&dev->xmit_lock);
+ e100_close(dev);
+ spin_unlock_bh(&dev->xmit_lock);
+ e100_hw_init(bdp);
+ e100_open(dev);
+ }
} else {
return -EOPNOTSUPP;
}
if ((bdp->speed_duplex_caps & SUPPORTED_Autoneg) &&
(bdp->params.e100_speed_duplex == E100_AUTONEG)) {
- e100_set_speed_duplex(bdp);
+ if (netif_running(dev)) {
+ spin_lock_bh(&dev->xmit_lock);
+ e100_close(dev);
+ spin_unlock_bh(&dev->xmit_lock);
+ e100_hw_init(bdp);
+ e100_open(dev);
+ }
} else {
return -EFAULT;
}
bdp->params.e100_speed_duplex = E100_SPEED_10_FULL;
else
bdp->params.e100_speed_duplex = E100_SPEED_10_HALF;
- e100_set_speed_duplex(bdp);
+ if (netif_running(dev)) {
+ spin_lock_bh(&dev->xmit_lock);
+ e100_close(dev);
+ spin_unlock_bh(&dev->xmit_lock);
+ e100_hw_init(bdp);
+ e100_open(dev);
+ }
}
else
/* Only allows changing speed/duplex */