/* this lock protects this structure */
        spinlock_t lock;
 
+       struct workqueue_struct *wq;
+
        u8 running; /* SoftMAC started? */
        u8 scanning;
 
 
        /* Set a timer for timeout */
        /* FIXME: make timeout configurable */
        if (likely(mac->running))
-               schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);
+               queue_delayed_work(mac->wq, &mac->associnfo.timeout, 5 * HZ);
        spin_unlock_irqrestore(&mac->lock, flags);
 }
 
                                network->authenticated = 0;
                                /* we don't want to do this more than once ... */
                                network->auth_desynced_once = 1;
-                               schedule_delayed_work(&mac->associnfo.work, 0);
+                               queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
                                break;
                        }
                default:
 
        spin_lock_irqsave(&mac->lock, flags);
        mac->associnfo.associating = 1;
-       schedule_delayed_work(&mac->associnfo.work, 0);
+       queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
        spin_unlock_irqrestore(&mac->lock, flags);
 }
 
                dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
                return 0;
        }
-       schedule_delayed_work(&mac->associnfo.work, 0);
+       queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
 
        return 0;
 }
 
 
        /* add to list */
        list_add_tail(&auth->list, &mac->auth_queue);
-       schedule_delayed_work(&auth->work, 0);
+       queue_delayed_work(mac->wq, &auth->work, 0);
        spin_unlock_irqrestore(&mac->lock, flags);
 
        return 0;
                }
                net->authenticated = 0;
                /* add a timeout call so we eventually give up waiting for an auth reply */
-               schedule_delayed_work(&auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT);
+               queue_delayed_work(mac->wq, &auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT);
                auth->retry--;
                spin_unlock_irqrestore(&mac->lock, flags);
                if (ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state))
                         * request. */
                        cancel_delayed_work(&aq->work);
                        INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response);
-                       schedule_delayed_work(&aq->work, 0);
+                       queue_delayed_work(mac->wq, &aq->work, 0);
                        spin_unlock_irqrestore(&mac->lock, flags);
                        return 0;
                case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
        ieee80211softmac_deauth_from_net(mac, net);
 
        /* let's try to re-associate */
-       schedule_delayed_work(&mac->associnfo.work, 0);
+       queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
        return 0;
 }
 
                                /* User may have subscribed to ANY event, so
                                 * we tell them which event triggered it. */
                                eventptr->event_type = event;
-                               schedule_delayed_work(&eventptr->work, 0);
+                               queue_delayed_work(mac->wq, &eventptr->work, 0);
                        }
                }
 }
 
        dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv);
        if (!dev)
                return NULL;
-
        softmac = ieee80211_priv(dev);
+       softmac->wq = create_freezeable_workqueue("softmac");
+       if (!softmac->wq) {
+               free_ieee80211(dev);
+               return NULL;
+       }
+
        softmac->dev = dev;
        softmac->ieee = netdev_priv(dev);
        spin_lock_init(&softmac->lock);
                cancel_delayed_work(&eventptr->work);
 
        spin_unlock_irqrestore(&sm->lock, flags);
-       flush_scheduled_work();
+       flush_workqueue(sm->wq);
 
        /* now we should be save and no longer need locking... */
        spin_lock_irqsave(&sm->lock, flags);
        ieee80211softmac_clear_pending_work(sm);
        kfree(sm->scaninfo);
        kfree(sm->wpa.IE);
+       destroy_workqueue(sm->wq);
        free_ieee80211(dev);
 }
 EXPORT_SYMBOL_GPL(free_ieee80211softmac);
 
                                spin_unlock_irqrestore(&sm->lock, flags);
                                break;
                        }
-                       schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
+                       queue_delayed_work(sm->wq, &si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
                        spin_unlock_irqrestore(&sm->lock, flags);
                        return;
                } else {
        sm->scaninfo->started = 1;
        sm->scaninfo->stop = 0;
        INIT_COMPLETION(sm->scaninfo->finished);
-       schedule_delayed_work(&sm->scaninfo->softmac_scan, 0);
+       queue_delayed_work(sm->wq, &sm->scaninfo->softmac_scan, 0);
        spin_unlock_irqrestore(&sm->lock, flags);
        return 0;
 }
 
                /* We must unlock to avoid deadlocks with the assoc workqueue
                 * on the associnfo.mutex */
                mutex_unlock(&sm->associnfo.mutex);
-               flush_scheduled_work();
+               flush_workqueue(sm->wq);
                /* Avoid race! Check assoc status again. Maybe someone started an
                 * association while we flushed. */
                goto check_assoc_again;
 
        sm->associnfo.associating = 1;
        /* queue lower level code to do work (if necessary) */
-       schedule_delayed_work(&sm->associnfo.work, 0);
+       queue_delayed_work(sm->wq, &sm->associnfo.work, 0);
 
        mutex_unlock(&sm->associnfo.mutex);
 
                /* force reassociation */
                mac->associnfo.bssvalid = 0;
                if (mac->associnfo.associated)
-                       schedule_delayed_work(&mac->associnfo.work, 0);
+                       queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
        } else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
                /* the bssid we have is no longer fixed */
                mac->associnfo.bssfixed = 0;
                /* tell the other code that this bssid should be used no matter what */
                mac->associnfo.bssfixed = 1;
                /* queue associate if new bssid or (old one again and not associated) */
-               schedule_delayed_work(&mac->associnfo.work, 0);
+               queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
        }
 
  out: