struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
                                                             int *cfp_no);
 wlan_private *libertas_add_card(void *card, struct device *dmdev);
-int libertas_activate_card(wlan_private *priv);
 int libertas_remove_card(wlan_private *priv);
+int libertas_start_card(wlan_private *priv);
+int libertas_stop_card(wlan_private *priv);
 int libertas_add_mesh(wlan_private *priv, struct device *dev);
 void libertas_remove_mesh(wlan_private *priv);
 int libertas_reset_device(wlan_private *priv);
 
           all other bits reserved 0 */
        u8 dnld_sent;
 
-       const struct firmware *firmware;
        struct device *hotplug_device;
 
        /** thread to service interrupts */
        struct work_struct sync_channel;
 
        /** Hardware access */
-       int (*hw_register_dev) (wlan_private * priv);
-       int (*hw_unregister_dev) (wlan_private *);
-       int (*hw_prog_firmware) (wlan_private *);
        int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb);
        int (*hw_get_int_status) (wlan_private * priv, u8 *);
        int (*hw_read_event_cause) (wlan_private *);
 
 /* Callback functions for libertas.ko                               */
 /********************************************************************/
 
-static int if_cs_register_dev(wlan_private *priv)
-{
-       struct if_cs_card *card = (struct if_cs_card *)priv->card;
-
-       lbs_deb_enter(LBS_DEB_CS);
-
-       card->priv = priv;
-
-       return 0;
-}
-
-
-static int if_cs_unregister_dev(wlan_private *priv)
-{
-       lbs_deb_enter(LBS_DEB_CS);
-
-       /*
-        * Nothing special here. Because the device's power gets turned off
-        * anyway, there's no need to send a RESET command like in if_usb.c
-        */
-
-       return 0;
-}
-
-
-/*
- * This callback is a dummy. The reason is that the USB code needs
- * to have various things set up in order to be able to download the
- * firmware. That's not needed in our case.
- *
- * On the contrary, if libertas_add_card() has been called and we're
- * then later called via libertas_activate_card(), but without a valid
- * firmware, then it's quite tedious to tear down the half-installed
- * card. Therefore, we download the firmware before calling adding/
- * activating the card in the first place. If that doesn't work, we
- * won't call into libertas.ko at all.
- */
-
-static int if_cs_prog_firmware(wlan_private *priv)
-{
-       priv->adapter->fw_ready = 1;
-       return 0;
-}
-
-
 /* Send commands or data packets to the card */
 static int if_cs_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb)
 {
        }
 
        /* Store pointers to our call-back functions */
+       card->priv = priv;
        priv->card = card;
-       priv->hw_register_dev     = if_cs_register_dev;
-       priv->hw_unregister_dev   = if_cs_unregister_dev;
-       priv->hw_prog_firmware    = if_cs_prog_firmware;
        priv->hw_host_to_card     = if_cs_host_to_card;
        priv->hw_get_int_status   = if_cs_get_int_status;
        priv->hw_read_event_cause = if_cs_read_event_cause;
 
+       priv->adapter->fw_ready = 1;
+
        /* Now actually get the IRQ */
        ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt,
                IRQF_SHARED, DRV_NAME, card);
        }
 
        /* And finally bring the card up */
-       if (libertas_activate_card(priv) != 0) {
+       if (libertas_start_card(priv) != 0) {
                lbs_pr_err("could not activate card\n");
                goto out3;
        }
 
        lbs_deb_enter(LBS_DEB_CS);
 
+       libertas_stop_card(card->priv);
        libertas_remove_card(card->priv);
        if_cs_release(p_dev);
        kfree(card);
 
 
 static void if_usb_receive(struct urb *urb);
 static void if_usb_receive_fwload(struct urb *urb);
-static int if_usb_register_dev(wlan_private * priv);
-static int if_usb_unregister_dev(wlan_private *);
-static int if_usb_prog_firmware(wlan_private *);
+static int if_usb_prog_firmware(struct usb_card_rec *cardp);
 static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
 static int if_usb_get_int_status(wlan_private * priv, u8 *);
 static int if_usb_read_event_cause(wlan_private *);
-static int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb);
+static int usb_tx_block(struct usb_card_rec *cardp, u8 *payload, u16 nb);
 static void if_usb_free(struct usb_card_rec *cardp);
+static int if_usb_submit_rx_urb(struct usb_card_rec *cardp);
+static int if_usb_reset_device(struct usb_card_rec *cardp);
 
 /**
  *  @brief  call back function to handle the status of the URB
  */
 static void if_usb_write_bulk_callback(struct urb *urb)
 {
-       wlan_private *priv = (wlan_private *) (urb->context);
-       wlan_adapter *adapter = priv->adapter;
-       struct net_device *dev = priv->dev;
+       struct usb_card_rec *cardp = (struct usb_card_rec *) urb->context;
 
        /* handle the transmission complete validations */
 
-       if (urb->status != 0) {
-               /* print the failure status number for debug */
-               lbs_pr_info("URB in failure status: %d\n", urb->status);
-       } else {
+       if (urb->status == 0) {
+               wlan_private *priv = cardp->priv;
+
                /*
                lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
                lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
                       urb->actual_length);
                */
-               priv->dnld_sent = DNLD_RES_RECEIVED;
-               /* Wake main thread if commands are pending */
-               if (!adapter->cur_cmd)
-                       wake_up_interruptible(&priv->waitq);
-               if ((adapter->connect_status == LIBERTAS_CONNECTED)) {
-                       netif_wake_queue(dev);
-                       netif_wake_queue(priv->mesh_dev);
+
+               /* Used for both firmware TX and regular TX.  priv isn't
+                * valid at firmware load time.
+                */
+               if (priv) {
+                       wlan_adapter *adapter = priv->adapter;
+                       struct net_device *dev = priv->dev;
+
+                       priv->dnld_sent = DNLD_RES_RECEIVED;
+
+                       /* Wake main thread if commands are pending */
+                       if (!adapter->cur_cmd)
+                               wake_up_interruptible(&priv->waitq);
+
+                       if ((adapter->connect_status == LIBERTAS_CONNECTED)) {
+                               netif_wake_queue(dev);
+                               netif_wake_queue(priv->mesh_dev);
+                       }
                }
+       } else {
+               /* print the failure status number for debug */
+               lbs_pr_info("URB in failure status: %d\n", urb->status);
        }
 
        return;
                }
        }
 
+       /* Upload firmware */
+       cardp->rinfo.cardp = cardp;
+       if (if_usb_prog_firmware(cardp)) {
+               lbs_deb_usbd(&udev->dev, "FW upload failed");
+               goto err_prog_firmware;
+       }
+
        if (!(priv = libertas_add_card(cardp, &udev->dev)))
-               goto dealloc;
+               goto err_prog_firmware;
 
-       udev->dev.driver_data = priv;
+       cardp->priv = priv;
 
        if (libertas_add_mesh(priv, &udev->dev))
                goto err_add_mesh;
 
-       priv->hw_register_dev = if_usb_register_dev;
-       priv->hw_unregister_dev = if_usb_unregister_dev;
-       priv->hw_prog_firmware = if_usb_prog_firmware;
+       cardp->eth_dev = priv->dev;
+
        priv->hw_host_to_card = if_usb_host_to_card;
        priv->hw_get_int_status = if_usb_get_int_status;
        priv->hw_read_event_cause = if_usb_read_event_cause;
        priv->boot2_version = udev->descriptor.bcdDevice;
 
-       if (libertas_activate_card(priv))
-               goto err_activate_card;
+       /* Delay 200 ms to waiting for the FW ready */
+       if_usb_submit_rx_urb(cardp);
+       msleep_interruptible(200);
+       priv->adapter->fw_ready = 1;
+
+       if (libertas_start_card(priv))
+               goto err_start_card;
 
        list_add_tail(&cardp->list, &usb_devices);
 
 
        return 0;
 
-err_activate_card:
+err_start_card:
        libertas_remove_mesh(priv);
 err_add_mesh:
-       free_netdev(priv->dev);
-       kfree(priv->adapter);
+       libertas_remove_card(priv);
+err_prog_firmware:
+       if_usb_reset_device(cardp);
 dealloc:
        if_usb_free(cardp);
 
 {
        struct usb_card_rec *cardp = usb_get_intfdata(intf);
        wlan_private *priv = (wlan_private *) cardp->priv;
-       wlan_adapter *adapter = NULL;
 
-       adapter = priv->adapter;
+       lbs_deb_enter(LBS_DEB_MAIN);
 
-       /*
-        * Update Surprise removed to TRUE
-        */
-       adapter->surpriseremoved = 1;
+       /* Update Surprise removed to TRUE */
+       cardp->surprise_removed = 1;
 
        list_del(&cardp->list);
 
-       /* card is removed and we can call wlan_remove_card */
-       lbs_deb_usbd(&cardp->udev->dev, "call remove card\n");
-       libertas_remove_mesh(priv);
-       libertas_remove_card(priv);
+       if (priv) {
+               wlan_adapter *adapter = priv->adapter;
+
+               adapter->surpriseremoved = 1;
+               libertas_stop_card(priv);
+               libertas_remove_mesh(priv);
+               libertas_remove_card(priv);
+       }
 
        /* Unlink and free urb */
        if_usb_free(cardp);
        usb_set_intfdata(intf, NULL);
        usb_put_dev(interface_to_usbdev(intf));
 
-       return;
+       lbs_deb_leave(LBS_DEB_MAIN);
 }
 
 /**
  *  @param priv                pointer to wlan_private
  *  @return            0
  */
-static int if_prog_firmware(wlan_private * priv)
+static int if_prog_firmware(struct usb_card_rec *cardp)
 {
-       struct usb_card_rec *cardp = priv->card;
        struct FWData *fwdata;
        struct fwheader *fwheader;
-       u8 *firmware = priv->firmware->data;
+       u8 *firmware = cardp->fw->data;
 
        fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);
 
                            cardp->totalbytes);
                */
                memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
-               usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
+               usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
 
        } else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
                /*
                            "Donwloading FW JUMP BLOCK\n");
                */
                memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
-               usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
+               usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
                cardp->fwfinalblk = 1;
        }
 
        return 0;
 }
 
-static int if_usb_reset_device(wlan_private *priv)
+static int if_usb_reset_device(struct usb_card_rec *cardp)
 {
        int ret;
-       struct usb_card_rec *cardp = priv->card;
+       wlan_private * priv = cardp->priv;
 
        lbs_deb_enter(LBS_DEB_USB);
 
         * command to the firmware.
         */
        ret = usb_reset_device(cardp->udev);
-       if (!ret) {
+       if (!ret && priv) {
                msleep(10);
                ret = libertas_reset_device(priv);
                msleep(10);
  *  @param nb          data length
  *  @return            0 or -1
  */
-static int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
+static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb)
 {
-       /* pointer to card structure */
-       struct usb_card_rec *cardp = priv->card;
        int ret = -1;
 
        /* check if device is removed */
-       if (priv->adapter->surpriseremoved) {
+       if (cardp->surprise_removed) {
                lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
                goto tx_ret;
        }
        usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
                          usb_sndbulkpipe(cardp->udev,
                                          cardp->bulk_out_endpointAddr),
-                         payload, nb, if_usb_write_bulk_callback, priv);
+                         payload, nb, if_usb_write_bulk_callback, cardp);
 
        cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
 
        return ret;
 }
 
-static int __if_usb_submit_rx_urb(wlan_private * priv,
-                                 void (*callbackfn)
-                                 (struct urb *urb))
+static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
+                                 void (*callbackfn)(struct urb *urb))
 {
-       struct usb_card_rec *cardp = priv->card;
        struct sk_buff *skb;
        struct read_cb_info *rinfo = &cardp->rinfo;
        int ret = -1;
        return ret;
 }
 
-static inline int if_usb_submit_rx_urb_fwload(wlan_private * priv)
+static int if_usb_submit_rx_urb_fwload(struct usb_card_rec *cardp)
 {
-       return __if_usb_submit_rx_urb(priv, &if_usb_receive_fwload);
+       return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
 }
 
-static inline int if_usb_submit_rx_urb(wlan_private * priv)
+static int if_usb_submit_rx_urb(struct usb_card_rec *cardp)
 {
-       return __if_usb_submit_rx_urb(priv, &if_usb_receive);
+       return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
 }
 
 static void if_usb_receive_fwload(struct urb *urb)
 {
        struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
-       wlan_private *priv = rinfo->priv;
        struct sk_buff *skb = rinfo->skb;
-       struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
+       struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp;
        struct fwsyncheader *syncfwheader;
        struct bootcmdrespStr bootcmdresp;
 
                        sizeof(bootcmdresp));
                if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
                        kfree_skb(skb);
-                       if_usb_submit_rx_urb_fwload(priv);
+                       if_usb_submit_rx_urb_fwload(cardp);
                        cardp->bootcmdresp = 1;
                        lbs_deb_usbd(&cardp->udev->dev,
                                    "Received valid boot command response\n");
                                    "Received valid boot command response\n");
                }
                kfree_skb(skb);
-               if_usb_submit_rx_urb_fwload(priv);
+               if_usb_submit_rx_urb_fwload(cardp);
                return;
        }
 
                goto exit;
        }
 
-       if_prog_firmware(priv);
+       if_prog_firmware(cardp);
 
-       if_usb_submit_rx_urb_fwload(priv);
+       if_usb_submit_rx_urb_fwload(cardp);
 exit:
        kfree(syncfwheader);
 
 static void if_usb_receive(struct urb *urb)
 {
        struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
-       wlan_private *priv = rinfo->priv;
        struct sk_buff *skb = rinfo->skb;
-       struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
+       struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp;
+       wlan_private * priv = cardp->priv;
 
        int recvlength = urb->actual_length;
        u8 *recvbuff = NULL;
        }
 
 setup_for_next:
-       if_usb_submit_rx_urb(priv);
+       if_usb_submit_rx_urb(cardp);
 rx_exit:
        lbs_deb_leave(LBS_DEB_USB);
 }
 
        memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);
 
-       return usb_tx_block(priv, cardp->bulk_out_buffer,
+       return usb_tx_block(cardp, cardp->bulk_out_buffer,
                            nb + MESSAGE_HEADER_LEN);
 }
 
 static int if_usb_read_event_cause(wlan_private * priv)
 {
        struct usb_card_rec *cardp = priv->card;
+
        priv->adapter->eventcause = cardp->usb_event_cause;
        /* Re-submit rx urb here to avoid event lost issue */
-       if_usb_submit_rx_urb(priv);
-       return 0;
-}
-
-static int if_usb_unregister_dev(wlan_private * priv)
-{
-       int ret = 0;
-
-       /* Need to send a Reset command to device before USB resources freed
-        * and wlan_remove_card() called, then device can handle FW download
-        * again.
-        */
-       if (priv)
-               libertas_reset_device(priv);
-
-       return ret;
-}
-
-
-/**
- *  @brief  This function register usb device and initialize parameter
- *  @param             priv pointer to wlan_private
- *  @return            0 or -1
- */
-static int if_usb_register_dev(wlan_private * priv)
-{
-       struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
-
-       lbs_deb_enter(LBS_DEB_USB);
-
-       cardp->priv = priv;
-       cardp->eth_dev = priv->dev;
-       priv->hotplug_device = &(cardp->udev->dev);
-
-       lbs_deb_usbd(&cardp->udev->dev, "udev pointer is at %p\n",
-                   cardp->udev);
-
-       lbs_deb_leave(LBS_DEB_USB);
+       if_usb_submit_rx_urb(cardp);
        return 0;
 }
 
  *                  2:Boot from FW in EEPROM
  *  @return            0
  */
-static int if_usb_issue_boot_command(wlan_private *priv, int ivalue)
+static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
 {
-       struct usb_card_rec     *cardp = priv->card;
-       struct bootcmdstr       sbootcmd;
+       struct bootcmdstr sbootcmd;
        int i;
 
        /* Prepare command */
        memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr));
 
        /* Issue command */
-       usb_tx_block(priv, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
+       usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
 
        return 0;
 }
 
 
-static int if_usb_do_prog_firmware(wlan_private * priv)
+/**
+ *  @brief This function checks the validity of Boot2/FW image.
+ *
+ *  @param data              pointer to image
+ *         len               image length
+ *  @return     0 or -1
+ */
+static int check_fwfile_format(u8 *data, u32 totlen)
+{
+       u32 bincmd, exit;
+       u32 blksize, offset, len;
+       int ret;
+
+       ret = 1;
+       exit = len = 0;
+
+       do {
+               struct fwheader *fwh = (void *)data;
+
+               bincmd = le32_to_cpu(fwh->dnldcmd);
+               blksize = le32_to_cpu(fwh->datalength);
+               switch (bincmd) {
+               case FW_HAS_DATA_TO_RECV:
+                       offset = sizeof(struct fwheader) + blksize;
+                       data += offset;
+                       len += offset;
+                       if (len >= totlen)
+                               exit = 1;
+                       break;
+               case FW_HAS_LAST_BLOCK:
+                       exit = 1;
+                       ret = 0;
+                       break;
+               default:
+                       exit = 1;
+                       break;
+               }
+       } while (!exit);
+
+       if (ret)
+               lbs_pr_err("firmware file format check FAIL\n");
+       else
+               lbs_deb_fw("firmware file format check PASS\n");
+
+       return ret;
+}
+
+
+static int if_usb_prog_firmware(struct usb_card_rec *cardp)
 {
-       struct usb_card_rec *cardp = priv->card;
        int i = 0;
        static int reset_count = 10;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_USB);
 
-       cardp->rinfo.priv = priv;
+       if ((ret = request_firmware(&cardp->fw, libertas_fw_name,
+                                   &cardp->udev->dev)) < 0) {
+               lbs_pr_err("request_firmware() failed with %#x\n", ret);
+               lbs_pr_err("firmware %s not found\n", libertas_fw_name);
+               goto done;
+       }
+
+       if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
+               goto release_fw;
 
 restart:
-       if (if_usb_submit_rx_urb_fwload(priv) < 0) {
+       if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
                lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
                ret = -1;
-               goto done;
+               goto release_fw;
        }
 
        cardp->bootcmdresp = 0;
                int j = 0;
                i++;
                /* Issue Boot command = 1, Boot from Download-FW */
-               if_usb_issue_boot_command(priv, BOOT_CMD_FW_BY_USB);
+               if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
                /* wait for command response */
                do {
                        j++;
 
        if (cardp->bootcmdresp == 0) {
                if (--reset_count >= 0) {
-                       if_usb_reset_device(priv);
+                       if_usb_reset_device(cardp);
                        goto restart;
                }
                return -1;
        }
 
        i = 0;
-       priv->adapter->fw_ready = 0;
 
        cardp->totalbytes = 0;
        cardp->fwlastblksent = 0;
        cardp->totalbytes = 0;
        cardp->fwfinalblk = 0;
 
-       if_prog_firmware(priv);
+       if_prog_firmware(cardp);
 
        do {
                lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
                i++;
                msleep_interruptible(100);
-               if (priv->adapter->surpriseremoved || i >= 20)
+               if (cardp->surprise_removed || i >= 20)
                        break;
        } while (!cardp->fwdnldover);
 
        if (!cardp->fwdnldover) {
                lbs_pr_info("failed to load fw, resetting device!\n");
                if (--reset_count >= 0) {
-                       if_usb_reset_device(priv);
+                       if_usb_reset_device(cardp);
                        goto restart;
                }
 
                lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
                ret = -1;
-               goto done;
+               goto release_fw;
        }
 
-       if_usb_submit_rx_urb(priv);
-
-       /* Delay 200 ms to waiting for the FW ready */
-       msleep_interruptible(200);
-
-       priv->adapter->fw_ready = 1;
+release_fw:
+       release_firmware(cardp->fw);
+       cardp->fw = NULL;
 
 done:
        lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
        return ret;
 }
 
-/**
- *  @brief This function checks the validity of Boot2/FW image.
- *
- *  @param data              pointer to image
- *         len               image length
- *  @return     0 or -1
- */
-static int check_fwfile_format(u8 *data, u32 totlen)
-{
-       u32 bincmd, exit;
-       u32 blksize, offset, len;
-       int ret;
-
-       ret = 1;
-       exit = len = 0;
-
-       do {
-               struct fwheader *fwh = (void *)data;
-
-               bincmd = le32_to_cpu(fwh->dnldcmd);
-               blksize = le32_to_cpu(fwh->datalength);
-               switch (bincmd) {
-               case FW_HAS_DATA_TO_RECV:
-                       offset = sizeof(struct fwheader) + blksize;
-                       data += offset;
-                       len += offset;
-                       if (len >= totlen)
-                               exit = 1;
-                       break;
-               case FW_HAS_LAST_BLOCK:
-                       exit = 1;
-                       ret = 0;
-                       break;
-               default:
-                       exit = 1;
-                       break;
-               }
-       } while (!exit);
-
-       if (ret)
-               lbs_pr_err("firmware file format check FAIL\n");
-       else
-               lbs_deb_fw("firmware file format check PASS\n");
-
-       return ret;
-}
-
-
-static int if_usb_prog_firmware(wlan_private *priv)
-{
-       int ret = -1;
-
-       lbs_deb_enter(LBS_DEB_FW);
-
-       if ((ret = request_firmware(&priv->firmware, libertas_fw_name,
-                                   priv->hotplug_device)) < 0) {
-               lbs_pr_err("request_firmware() failed with %#x\n", ret);
-               lbs_pr_err("firmware %s not found\n", libertas_fw_name);
-               goto done;
-       }
-
-       if (check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
-               release_firmware(priv->firmware);
-               goto done;
-       }
-
-       ret = if_usb_do_prog_firmware(priv);
-
-       release_firmware(priv->firmware);
-done:
-       return ret;
-}
-
 
 #ifdef CONFIG_PM
 static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 
 
 /* read callback private data */
 struct read_cb_info {
-        wlan_private *priv;
+        struct usb_card_rec *cardp;
         struct sk_buff *skb;
 };
 
        int bulk_out_size;
        u8 bulk_out_endpointAddr;
 
+       const struct firmware *fw;
        u8 CRC_OK;
        u32 fwseqnum;
        u32 lastseqnum;
        u32 fwlastblksent;
        u8 fwdnldover;
        u8 fwfinalblk;
+       u8 surprise_removed;
 
        u32 usb_event_cause;
        u8 usb_int_cause;
 
                } else
                        spin_unlock_irq(&adapter->driver_lock);
 
-
                lbs_deb_thread(
                       "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
                       "dnld_sent=%d\n", adapter->intcounter,
  *  @param priv    A pointer to wlan_private structure
  *  @return       0 or -1
  */
-static int wlan_setup_station_hw(wlan_private * priv)
+static int wlan_setup_firmware(wlan_private * priv)
 {
        int ret = -1;
        wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_FW);
 
-       ret = priv->hw_prog_firmware(priv);
-
-       if (ret) {
-               lbs_deb_fw("bootloader in invalid state\n");
-               ret = -1;
-               goto done;
-       }
-
        /*
         * Read MAC address from HW
         */
        return ret;
 }
 
-static void command_timer_fn(unsigned long data);
-
 /**
  *  This function handles the timeout of command sending.
  *  It will re-send the same command again.
        return;
 }
 
-static void libertas_free_adapter(wlan_private * priv)
+static int libertas_init_adapter(wlan_private * priv)
 {
        wlan_adapter *adapter = priv->adapter;
-
-       if (!adapter) {
-               lbs_deb_fw("why double free adapter?\n");
-               return;
-       }
-
-       lbs_deb_fw("free command buffer\n");
-       libertas_free_cmd_buffer(priv);
-
-       lbs_deb_fw("free command_timer\n");
-       del_timer(&adapter->command_timer);
-
-       lbs_deb_fw("free scan results table\n");
-       kfree(adapter->networks);
-       adapter->networks = NULL;
-
-       /* Free the adapter object itself */
-       lbs_deb_fw("free adapter\n");
-       kfree(adapter);
-       priv->adapter = NULL;
-}
-
-static int wlan_allocate_adapter(wlan_private * priv)
-{
        size_t bufsize;
-       wlan_adapter *adapter = priv->adapter;
+       int i, ret = 0;
 
        /* Allocate buffer to store the BSSID list */
        bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
        adapter->networks = kzalloc(bufsize, GFP_KERNEL);
        if (!adapter->networks) {
                lbs_pr_err("Out of memory allocating beacons\n");
-               libertas_free_adapter(priv);
-               return -ENOMEM;
+               ret = -1;
+               goto out;
        }
 
-       /* Allocate the command buffers */
-       libertas_allocate_cmd_buffer(priv);
+       /* Initialize scan result lists */
+       INIT_LIST_HEAD(&adapter->network_free_list);
+       INIT_LIST_HEAD(&adapter->network_list);
+       for (i = 0; i < MAX_NETWORK_COUNT; i++) {
+               list_add_tail(&adapter->networks[i].list,
+                             &adapter->network_free_list);
+       }
 
-       memset(&adapter->libertas_ps_confirm_sleep, 0, sizeof(struct PS_CMD_ConfirmSleep));
        adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum);
        adapter->libertas_ps_confirm_sleep.command =
            cpu_to_le16(CMD_802_11_PS_MODE);
        adapter->libertas_ps_confirm_sleep.size =
            cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
-       adapter->libertas_ps_confirm_sleep.result = 0;
        adapter->libertas_ps_confirm_sleep.action =
            cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
 
-       return 0;
-}
-
-static void wlan_init_adapter(wlan_private * priv)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int i;
-
-       adapter->connect_status = LIBERTAS_DISCONNECTED;
        memset(adapter->current_addr, 0xff, ETH_ALEN);
 
-       /* 802.11 specific */
-       adapter->secinfo.wep_enabled = 0;
-       for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]);
-            i++)
-               memset(&adapter->wep_keys[i], 0, sizeof(struct enc_key));
-       adapter->wep_tx_keyidx = 0;
+       adapter->connect_status = LIBERTAS_DISCONNECTED;
        adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
        adapter->mode = IW_MODE_INFRA;
-
-       adapter->pending_assoc_req = NULL;
-       adapter->in_progress_assoc_req = NULL;
-
-       /* Initialize scan result lists */
-       INIT_LIST_HEAD(&adapter->network_free_list);
-       INIT_LIST_HEAD(&adapter->network_list);
-       for (i = 0; i < MAX_NETWORK_COUNT; i++) {
-               list_add_tail(&adapter->networks[i].list,
-                             &adapter->network_free_list);
-       }
-
-       mutex_init(&adapter->lock);
-
-       memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
        adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
-
-       /* PnP and power profile */
-       adapter->surpriseremoved = 0;
-
-       adapter->currentpacketfilter =
-           CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
-
+       adapter->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
        adapter->radioon = RADIO_ON;
-
        adapter->auto_rate = 1;
-       adapter->cur_rate = 0;
-
-       // set default capabilities
        adapter->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
-
        adapter->psmode = WLAN802_11POWERMODECAM;
-
        adapter->psstate = PS_STATE_FULL_POWER;
-       adapter->needtowakeup = 0;
 
-       adapter->intcounter = 0;
-
-       adapter->currenttxskb = NULL;
+       mutex_init(&adapter->lock);
 
        memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*));
        adapter->tx_queue_idx = 0;
        spin_lock_init(&adapter->txqueue_lock);
 
-       return;
-}
+       setup_timer(&adapter->command_timer, command_timer_fn,
+                   (unsigned long)priv);
 
-static int libertas_init_fw(wlan_private * priv)
-{
-       int ret = -1;
-       wlan_adapter *adapter = priv->adapter;
+       INIT_LIST_HEAD(&adapter->cmdfreeq);
+       INIT_LIST_HEAD(&adapter->cmdpendingq);
 
-       lbs_deb_enter(LBS_DEB_FW);
+       spin_lock_init(&adapter->driver_lock);
+       init_waitqueue_head(&adapter->cmd_pending);
+       adapter->nr_cmd_pending = 0;
 
-       /* Allocate adapter structure */
-       if ((ret = wlan_allocate_adapter(priv)) != 0)
-               goto done;
+       /* Allocate the command buffers */
+       if (libertas_allocate_cmd_buffer(priv)) {
+               lbs_pr_err("Out of memory allocating command buffers\n");
+               ret = -1;
+       }
 
-       /* init adapter structure */
-       wlan_init_adapter(priv);
+out:
+       return ret;
+}
 
-       /* init timer etc. */
-       setup_timer(&adapter->command_timer, command_timer_fn,
-                       (unsigned long)priv);
+static void libertas_free_adapter(wlan_private * priv)
+{
+       wlan_adapter *adapter = priv->adapter;
 
-       /* download fimrware etc. */
-       if ((ret = wlan_setup_station_hw(priv)) != 0) {
-               del_timer_sync(&adapter->command_timer);
-               goto done;
+       if (!adapter) {
+               lbs_deb_fw("why double free adapter?\n");
+               return;
        }
 
-       /* init 802.11d */
-       libertas_init_11d(priv);
+       lbs_deb_fw("free command buffer\n");
+       libertas_free_cmd_buffer(priv);
 
-       ret = 0;
-done:
-       lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
-       return ret;
+       lbs_deb_fw("free command_timer\n");
+       del_timer(&adapter->command_timer);
+
+       lbs_deb_fw("free scan results table\n");
+       kfree(adapter->networks);
+       adapter->networks = NULL;
+
+       /* Free the adapter object itself */
+       lbs_deb_fw("free adapter\n");
+       kfree(adapter);
+       priv->adapter = NULL;
 }
 
 /**
        /* Allocate an Ethernet device and register it */
        if (!(dev = alloc_etherdev(sizeof(wlan_private)))) {
                lbs_pr_err("init ethX device failed\n");
-               return NULL;
+               goto done;
        }
-       priv = dev->priv;
+       dmdev->driver_data = priv = dev->priv;
 
        /* allocate buffer for wlan_adapter */
        if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
                goto err_kzalloc;
        }
 
+       if (libertas_init_adapter(priv)) {
+               lbs_pr_err("failed to initialize adapter structure.\n");
+               goto err_init_adapter;
+       }
+
        priv->dev = dev;
        priv->card = card;
        priv->mesh_open = 0;
        priv->infra_open = 0;
+       priv->hotplug_device = dmdev;
 
        SET_MODULE_OWNER(dev);
 
 
        SET_NETDEV_DEV(dev, dmdev);
 
-       INIT_LIST_HEAD(&priv->adapter->cmdfreeq);
-       INIT_LIST_HEAD(&priv->adapter->cmdpendingq);
-
-       spin_lock_init(&priv->adapter->driver_lock);
-       init_waitqueue_head(&priv->adapter->cmd_pending);
-       priv->adapter->nr_cmd_pending = 0;
        priv->rtap_net_dev = NULL;
        if (device_create_file(dmdev, &dev_attr_libertas_rtap))
-               goto err_kzalloc;
+               goto err_init_adapter;
+
+       lbs_deb_thread("Starting main thread...\n");
+       init_waitqueue_head(&priv->waitq);
+       priv->main_thread = kthread_run(libertas_thread, dev, "libertas_main");
+       if (IS_ERR(priv->main_thread)) {
+               lbs_deb_thread("Error creating main thread.\n");
+               goto err_kthread_run;
+       }
+
+       priv->work_thread = create_singlethread_workqueue("libertas_worker");
+       INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker);
+       INIT_DELAYED_WORK(&priv->scan_work, libertas_scan_worker);
+       INIT_WORK(&priv->sync_channel, libertas_sync_channel);
+
        goto done;
 
+err_kthread_run:
+       device_remove_file(dmdev, &dev_attr_libertas_rtap);
+
+err_init_adapter:
+       libertas_free_adapter(priv);
+
 err_kzalloc:
        free_netdev(dev);
        priv = NULL;
+
 done:
        lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
        return priv;
 }
 EXPORT_SYMBOL_GPL(libertas_add_card);
 
-int libertas_activate_card(wlan_private *priv)
+
+int libertas_remove_card(wlan_private *priv)
 {
+       wlan_adapter *adapter = priv->adapter;
        struct net_device *dev = priv->dev;
-       int ret = -1;
+       union iwreq_data wrqu;
 
        lbs_deb_enter(LBS_DEB_MAIN);
 
-       lbs_deb_thread("Starting main thread...\n");
-       init_waitqueue_head(&priv->waitq);
-       priv->main_thread = kthread_run(libertas_thread, dev, "libertas_main");
-       if (IS_ERR(priv->main_thread)) {
-               lbs_deb_thread("Error creating main thread.\n");
-               goto done;
-       }
+       libertas_remove_rtap(priv);
 
-       priv->work_thread = create_singlethread_workqueue("libertas_worker");
-       INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker);
-       INIT_DELAYED_WORK(&priv->scan_work, libertas_scan_worker);
+       dev = priv->dev;
+       device_remove_file(priv->hotplug_device, &dev_attr_libertas_rtap);
 
-       INIT_WORK(&priv->sync_channel, libertas_sync_channel);
+       cancel_delayed_work(&priv->scan_work);
+       cancel_delayed_work(&priv->assoc_work);
+       destroy_workqueue(priv->work_thread);
 
-       /*
-        * Register the device. Fillup the private data structure with
-        * relevant information from the card and request for the required
-        * IRQ.
-        */
-       if (priv->hw_register_dev(priv) < 0) {
-               lbs_pr_err("failed to register WLAN device\n");
-               goto err_registerdev;
+       if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) {
+               adapter->psmode = WLAN802_11POWERMODECAM;
+               libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
        }
 
-       /* init FW and HW */
-       if (libertas_init_fw(priv)) {
-               lbs_pr_err("firmware init failed\n");
-               goto err_registerdev;
-       }
+       memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
+       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+       wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+
+       /* Stop the thread servicing the interrupts */
+       adapter->surpriseremoved = 1;
+       kthread_stop(priv->main_thread);
+
+       libertas_free_adapter(priv);
+
+       priv->dev = NULL;
+       free_netdev(dev);
+
+       lbs_deb_leave(LBS_DEB_MAIN);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(libertas_remove_card);
+
+
+int libertas_start_card(wlan_private *priv)
+{
+       struct net_device *dev = priv->dev;
+       int ret = -1;
+
+       lbs_deb_enter(LBS_DEB_MAIN);
+
+       /* poke the firmware */
+       ret = wlan_setup_firmware(priv);
+       if (ret)
+               goto done;
+
+       /* init 802.11d */
+       libertas_init_11d(priv);
 
        if (register_netdev(dev)) {
                lbs_pr_err("cannot register ethX device\n");
-               goto err_init_fw;
+               goto done;
        }
 
-       lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
-
        libertas_debugfs_init_one(priv, dev);
 
+       lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
+
        ret = 0;
-       goto done;
 
-err_init_fw:
-       priv->hw_unregister_dev(priv);
-err_registerdev:
-       destroy_workqueue(priv->work_thread);
-       /* Stop the thread servicing the interrupts */
-       wake_up_interruptible(&priv->waitq);
-       kthread_stop(priv->main_thread);
 done:
-       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(libertas_activate_card);
+EXPORT_SYMBOL_GPL(libertas_start_card);
+
+
+int libertas_stop_card(wlan_private *priv)
+{
+       struct net_device *dev = priv->dev;
+       int ret = -1;
+       struct cmd_ctrl_node *cmdnode;
+       unsigned long flags;
+
+       lbs_deb_enter(LBS_DEB_MAIN);
+
+       netif_stop_queue(priv->dev);
+       netif_carrier_off(priv->dev);
+
+       libertas_debugfs_remove_one(priv);
+
+       /* Flush pending command nodes */
+       spin_lock_irqsave(&priv->adapter->driver_lock, flags);
+       list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
+               cmdnode->cmdwaitqwoken = 1;
+               wake_up_interruptible(&cmdnode->cmdwait_q);
+       }
+       spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
+
+       unregister_netdev(dev);
+
+       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(libertas_stop_card);
 
 
 /**
 }
 EXPORT_SYMBOL_GPL(libertas_add_mesh);
 
-static void wake_pending_cmdnodes(wlan_private *priv)
-{
-       struct cmd_ctrl_node *cmdnode;
-       unsigned long flags;
-
-       lbs_deb_enter(LBS_DEB_HOST);
-
-       spin_lock_irqsave(&priv->adapter->driver_lock, flags);
-       list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
-               cmdnode->cmdwaitqwoken = 1;
-               wake_up_interruptible(&cmdnode->cmdwait_q);
-       }
-       spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
-}
-
-
-int libertas_remove_card(wlan_private *priv)
-{
-       wlan_adapter *adapter;
-       struct net_device *dev;
-       union iwreq_data wrqu;
-
-       lbs_deb_enter(LBS_DEB_NET);
-
-       libertas_remove_rtap(priv);
-       if (!priv)
-               goto out;
-
-       adapter = priv->adapter;
-
-       if (!adapter)
-               goto out;
-
-       dev = priv->dev;
-       device_remove_file(priv->hotplug_device, &dev_attr_libertas_rtap);
-
-       netif_stop_queue(priv->dev);
-       netif_carrier_off(priv->dev);
-
-       wake_pending_cmdnodes(priv);
-
-       unregister_netdev(dev);
-
-       cancel_delayed_work(&priv->scan_work);
-       cancel_delayed_work(&priv->assoc_work);
-       destroy_workqueue(priv->work_thread);
-
-       if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) {
-               adapter->psmode = WLAN802_11POWERMODECAM;
-               libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
-       }
-
-       memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
-       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-       wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
-
-       adapter->surpriseremoved = 1;
-
-       /* Stop the thread servicing the interrupts */
-       kthread_stop(priv->main_thread);
-
-       libertas_debugfs_remove_one(priv);
-
-       lbs_deb_net("free adapter\n");
-       libertas_free_adapter(priv);
-
-       lbs_deb_net("unregister finish\n");
-
-       priv->dev = NULL;
-       free_netdev(dev);
-
-out:
-       lbs_deb_leave(LBS_DEB_NET);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(libertas_remove_card);
-
 
 void libertas_remove_mesh(wlan_private *priv)
 {
        struct net_device *mesh_dev;
 
-       lbs_deb_enter(LBS_DEB_NET);
+       lbs_deb_enter(LBS_DEB_MAIN);
 
        if (!priv)
                goto out;
        free_netdev(mesh_dev);
 
 out:
-       lbs_deb_leave(LBS_DEB_NET);
+       lbs_deb_leave(LBS_DEB_MAIN);
 }
 EXPORT_SYMBOL_GPL(libertas_remove_mesh);