--- linux-2.6.18.noarch/drivers/net/wireless/ipw3945.c.orig 2006-10-06 14:38:48.000000000 -0400 +++ linux-2.6.18.noarch/drivers/net/wireless/ipw3945.c 2006-10-06 14:55:44.000000000 -0400 @@ -4558,6 +4558,9 @@ static void ipw_bg_calibrated_work(void priv->status |= STATUS_CALIBRATE; if (!priv->netdev_registered) { + /* unlock priv->mutex to avoid rtnl_mutex contention */ + mutex_unlock(&priv->mutex); + rc = register_netdev(priv->net_dev); if (rc) { IPW_ERROR("Failed to register network " @@ -4565,12 +4568,13 @@ static void ipw_bg_calibrated_work(void "in 5 seconds.\n", rc); queue_delayed_work(priv->workqueue, &priv->down, 5 * HZ); - mutex_unlock(&priv->mutex); return; } #ifdef CONFIG_IPW3945_PROMISCUOUS if (rtap_iface) { + dev_hold(&priv->net_dev); rc = ipw_prom_alloc(priv); + dev_put(&priv->net_dev); if (rc) { IPW_ERROR ("Failed to register promiscuous network " @@ -4578,12 +4582,12 @@ static void ipw_bg_calibrated_work(void "in 5 seconds.\n", rc); queue_delayed_work(priv->workqueue, &priv->down, 5 * HZ); - mutex_unlock(&priv->mutex); unregister_netdev(priv->net_dev); return; } } #endif + mutex_lock(&priv->mutex); priv->netdev_registered = 1; /* For some reason, this card comes up with IFF_RUNNING set.