Jeff,

A few more for 2.6.24 -- mostly libertas.

Individual patches are available here:

        
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-2.6/upstream-jgarzik/

Thanks!

John

---

The following changes since commit e54cfa621f4cca9cca500019aa600c71d20f0592:
  Jeff Garzik (1):
        Merge branch 'upstream-jgarzik' of 
git://git.kernel.org/.../linville/wireless-2.6 into upstream

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git 
upstream-jgarzik

Andrew Morton (1):
      libertas: printk warning fixes

Brajesh Dave (1):
      libertas: advertise 11g ad-hoc rates

Dan Williams (4):
      libertas: fix inadvertant removal of bits from commit 
831441862956fffa17b9801db37e6ea1650b0f69
      libertas: reorganize and simplify init sequence
      libertas: don't stomp on interface-specific private data
      libertas: send reset command directly instead of calling 
libertas_reset_device

Jesper Juhl (1):
      net: Kill some unneeded allocation return value casts in libertas

Johannes Berg (1):
      rtl8187: remove IEEE80211_HW_DATA_NULLFUNC_ACK

John W. Linville (1):
      libertas: remove unused adhoc_rates_b definition

Marek VaĊĦut (1):
      libertas: region code values specified as 8bit

Pierre Ossman (1):
      libertas: properly end commands on hardware failure

 drivers/net/wireless/libertas/cmd.c     |    2 +
 drivers/net/wireless/libertas/cmdresp.c |    6 +-
 drivers/net/wireless/libertas/debugfs.c |    2 +-
 drivers/net/wireless/libertas/decl.h    |    3 +-
 drivers/net/wireless/libertas/dev.h     |    4 -
 drivers/net/wireless/libertas/ethtool.c |    3 +-
 drivers/net/wireless/libertas/if_cs.c   |   58 +----
 drivers/net/wireless/libertas/if_usb.c  |  371 +++++++++++++----------------
 drivers/net/wireless/libertas/if_usb.h  |    4 +-
 drivers/net/wireless/libertas/join.c    |    7 +-
 drivers/net/wireless/libertas/main.c    |  408 +++++++++++++------------------
 drivers/net/wireless/rtl8187_dev.c      |    3 +-
 12 files changed, 354 insertions(+), 517 deletions(-)

diff --git a/drivers/net/wireless/libertas/cmd.c 
b/drivers/net/wireless/libertas/cmd.c
index 98092b9..33dbed0 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1009,7 +1009,9 @@ static int DownloadcommandToStation(wlan_private * priv,
        if (ret != 0) {
                lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n");
                spin_lock_irqsave(&adapter->driver_lock, flags);
+               adapter->cur_cmd_retcode = ret;
                __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
+               adapter->nr_cmd_pending--;
                adapter->cur_cmd = NULL;
                spin_unlock_irqrestore(&adapter->driver_lock, flags);
                goto done;
diff --git a/drivers/net/wireless/libertas/cmdresp.c 
b/drivers/net/wireless/libertas/cmdresp.c
index 4c36e63..d64ad87 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -174,7 +174,11 @@ static int wlan_ret_get_hw_spec(wlan_private * priv,
        lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 
0x%04x\n",
               hwspec->hwifversion, hwspec->version);
 
-       adapter->regioncode = le16_to_cpu(hwspec->regioncode);
+       /* Clamp region code to 8-bit since FW spec indicates that it should
+        * only ever be 8-bit, even though the field size is 16-bit.  Some 
firmware
+        * returns non-zero high 8 bits here.
+        */
+       adapter->regioncode = le16_to_cpu(hwspec->regioncode) & 0xFF;
 
        for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
                /* use the region code to search for the index */
diff --git a/drivers/net/wireless/libertas/debugfs.c 
b/drivers/net/wireless/libertas/debugfs.c
index 6d95148..816f42e 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -1838,7 +1838,7 @@ static ssize_t wlan_debugfs_write(struct file *f, const 
char __user *buf,
        char *p2;
        struct debug_data *d = (struct debug_data *)f->private_data;
 
-       pdata = (char *)kmalloc(cnt, GFP_KERNEL);
+       pdata = kmalloc(cnt, GFP_KERNEL);
        if (pdata == NULL)
                return 0;
 
diff --git a/drivers/net/wireless/libertas/decl.h 
b/drivers/net/wireless/libertas/decl.h
index 095edf6..87fea9d 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -72,8 +72,9 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * 
str);
 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);
diff --git a/drivers/net/wireless/libertas/dev.h 
b/drivers/net/wireless/libertas/dev.h
index a3c94d7..1fb807a 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -143,7 +143,6 @@ struct _wlan_private {
           all other bits reserved 0 */
        u8 dnld_sent;
 
-       const struct firmware *firmware;
        struct device *hotplug_device;
 
        /** thread to service interrupts */
@@ -156,9 +155,6 @@ struct _wlan_private {
        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 *);
diff --git a/drivers/net/wireless/libertas/ethtool.c 
b/drivers/net/wireless/libertas/ethtool.c
index ec99cb8..d793d84 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -60,8 +60,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev,
 
 //      mutex_lock(&priv->mutex);
 
-       adapter->prdeeprom =
-                   (char *)kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
+       adapter->prdeeprom = kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
        if (!adapter->prdeeprom)
                return -ENOMEM;
        memcpy(adapter->prdeeprom, &regctrl, sizeof(regctrl));
diff --git a/drivers/net/wireless/libertas/if_cs.c 
b/drivers/net/wireless/libertas/if_cs.c
index 888f023..09c87df 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -459,7 +459,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
                ret = -ENODEV;
                goto done;
        }
-       lbs_deb_cs("helper size %d\n", fw->size);
+       lbs_deb_cs("helper size %td\n", fw->size);
 
        /* "Set the 5 bytes of the helper image to 0" */
        /* Not needed, this contains an ARM branch instruction */
@@ -535,7 +535,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
                ret = -ENODEV;
                goto done;
        }
-       lbs_deb_cs("fw size %d\n", fw->size);
+       lbs_deb_cs("fw size %td\n", fw->size);
 
        ret = if_cs_poll_while_fw_download(card, IF_CS_C_SQ_READ_LOW, 
IF_CS_C_SQ_HELPER_OK);
        if (ret < 0) {
@@ -608,51 +608,6 @@ done:
 /* 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)
 {
@@ -902,14 +857,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
        }
 
        /* 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);
@@ -919,7 +874,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
        }
 
        /* 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;
        }
@@ -951,6 +906,7 @@ static void if_cs_detach(struct pcmcia_device *p_dev)
 
        lbs_deb_enter(LBS_DEB_CS);
 
+       libertas_stop_card(card->priv);
        libertas_remove_card(card->priv);
        if_cs_release(p_dev);
        kfree(card);
diff --git a/drivers/net/wireless/libertas/if_usb.c 
b/drivers/net/wireless/libertas/if_usb.c
index 364eae3..8a3c70e 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -45,14 +45,14 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
 
 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
@@ -61,29 +61,40 @@ static void if_usb_free(struct usb_card_rec *cardp);
  */
 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;
@@ -205,24 +216,35 @@ static int if_usb_probe(struct usb_interface *intf,
                }
        }
 
+       /* 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);
 
@@ -231,11 +253,12 @@ static int if_usb_probe(struct usb_interface *intf,
 
        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);
 
@@ -252,21 +275,22 @@ static void if_usb_disconnect(struct usb_interface *intf)
 {
        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);
@@ -274,7 +298,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
        usb_set_intfdata(intf, NULL);
        usb_put_dev(interface_to_usbdev(intf));
 
-       return;
+       lbs_deb_leave(LBS_DEB_MAIN);
 }
 
 /**
@@ -282,12 +306,11 @@ static void if_usb_disconnect(struct usb_interface *intf)
  *  @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);
 
@@ -335,7 +358,7 @@ static int if_prog_firmware(wlan_private * priv)
                            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)) {
                /*
@@ -345,7 +368,7 @@ static int if_prog_firmware(wlan_private * priv)
                            "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;
        }
 
@@ -360,10 +383,10 @@ static int if_prog_firmware(wlan_private * priv)
        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);
 
@@ -371,7 +394,7 @@ static int if_usb_reset_device(wlan_private *priv)
         * command to the firmware.
         */
        ret = usb_reset_device(cardp->udev);
-       if (!ret) {
+       if (!ret && priv) {
                msleep(10);
                ret = libertas_reset_device(priv);
                msleep(10);
@@ -389,14 +412,12 @@ static int if_usb_reset_device(wlan_private *priv)
  *  @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;
        }
@@ -404,7 +425,7 @@ static int usb_tx_block(wlan_private * priv, u8 * payload, 
u16 nb)
        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;
 
@@ -421,11 +442,9 @@ tx_ret:
        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;
@@ -461,22 +480,21 @@ rx_ret:
        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;
 
@@ -492,7 +510,7 @@ static void if_usb_receive_fwload(struct urb *urb)
                        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");
@@ -516,7 +534,7 @@ static void if_usb_receive_fwload(struct urb *urb)
                                    "Received valid boot command response\n");
                }
                kfree_skb(skb);
-               if_usb_submit_rx_urb_fwload(priv);
+               if_usb_submit_rx_urb_fwload(cardp);
                return;
        }
 
@@ -552,9 +570,9 @@ static void if_usb_receive_fwload(struct urb *urb)
                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);
 
@@ -633,9 +651,9 @@ static inline void process_cmdrequest(int recvlength, u8 
*recvbuff,
 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;
@@ -696,7 +714,7 @@ static void if_usb_receive(struct urb *urb)
        }
 
 setup_for_next:
-       if_usb_submit_rx_urb(priv);
+       if_usb_submit_rx_urb(cardp);
 rx_exit:
        lbs_deb_leave(LBS_DEB_USB);
 }
@@ -731,7 +749,7 @@ static int if_usb_host_to_card(wlan_private * priv, u8 
type, u8 * payload, u16 n
 
        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);
 }
 
@@ -751,46 +769,10 @@ static int if_usb_get_int_status(wlan_private * priv, u8 
* ireg)
 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;
 }
 
@@ -800,10 +782,9 @@ static int if_usb_register_dev(wlan_private * priv)
  *                  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 */
@@ -814,28 +795,83 @@ static int if_usb_issue_boot_command(wlan_private *priv, 
int ivalue)
        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;
@@ -843,7 +879,7 @@ restart:
                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++;
@@ -853,14 +889,13 @@ restart:
 
        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;
@@ -870,113 +905,37 @@ restart:
        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)
@@ -1085,8 +1044,10 @@ static void if_usb_exit_module(void)
 
        lbs_deb_enter(LBS_DEB_MAIN);
 
-       list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list)
-               libertas_reset_device((wlan_private *) cardp->priv);
+       list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list) {
+               libertas_prepare_and_send_command(cardp->priv, CMD_802_11_RESET,
+                                                 CMD_ACT_HALT, 0, 0, NULL);
+       }
 
        /* API unregisters the driver from USB subsystem */
        usb_deregister(&if_usb_driver);
diff --git a/drivers/net/wireless/libertas/if_usb.h 
b/drivers/net/wireless/libertas/if_usb.h
index 8b3b4f1..e07a10e 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -38,7 +38,7 @@ struct bootcmdrespStr
 
 /* read callback private data */
 struct read_cb_info {
-        wlan_private *priv;
+        struct usb_card_rec *cardp;
         struct sk_buff *skb;
 };
 
@@ -58,6 +58,7 @@ struct usb_card_rec {
        int bulk_out_size;
        u8 bulk_out_endpointAddr;
 
+       const struct firmware *fw;
        u8 CRC_OK;
        u32 fwseqnum;
        u32 lastseqnum;
@@ -65,6 +66,7 @@ struct usb_card_rec {
        u32 fwlastblksent;
        u8 fwdnldover;
        u8 fwfinalblk;
+       u8 surprise_removed;
 
        u32 usb_event_cause;
        u8 usb_int_cause;
diff --git a/drivers/net/wireless/libertas/join.c 
b/drivers/net/wireless/libertas/join.c
index ce49d3f..0ad1362 100644
--- a/drivers/net/wireless/libertas/join.c
+++ b/drivers/net/wireless/libertas/join.c
@@ -17,9 +17,6 @@
 #include "dev.h"
 #include "assoc.h"
 
-/* Supported rates for ad-hoc B mode */
-static u8 adhoc_rates_b[5] = { 0x02, 0x04, 0x0b, 0x16, 0x00 };
-
 /* The firmware needs certain bits masked out of the beacon-derviced capability
  * field when associating/joining to BSSs.
  */
@@ -550,8 +547,8 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
        adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
 
        memset(adhs->rates, 0, sizeof(adhs->rates));
-       ratesize = min(sizeof(adhs->rates), sizeof(adhoc_rates_b));
-       memcpy(adhs->rates, adhoc_rates_b, ratesize);
+       ratesize = min(sizeof(adhs->rates), sizeof(libertas_bg_rates));
+       memcpy(adhs->rates, libertas_bg_rates, ratesize);
 
        /* Copy the ad-hoc creating rates into Current BSS state structure */
        memset(&adapter->curbssparams.rates, 0, 
sizeof(adapter->curbssparams.rates));
diff --git a/drivers/net/wireless/libertas/main.c 
b/drivers/net/wireless/libertas/main.c
index f0213ec..3feddcc 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -256,7 +256,7 @@ void libertas_remove_rtap(wlan_private *priv);
 static ssize_t libertas_rtap_get(struct device * dev,
                struct device_attribute *attr, char * buf)
 {
-       wlan_private *priv = (wlan_private *) dev->driver_data;
+       wlan_private *priv = (wlan_private *) (to_net_dev(dev))->priv;
        wlan_adapter *adapter = priv->adapter;
        return snprintf(buf, 5, "0x%X\n", adapter->monitormode);
 }
@@ -268,7 +268,7 @@ static ssize_t libertas_rtap_set(struct device * dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
        int monitor_mode;
-       wlan_private *priv = (wlan_private *) dev->driver_data;
+       wlan_private *priv = (wlan_private *) (to_net_dev(dev))->priv;
        wlan_adapter *adapter = priv->adapter;
 
        sscanf(buf, "%x", &monitor_mode);
@@ -768,6 +768,7 @@ static int libertas_thread(void *data)
 
        init_waitqueue_entry(&wait, current);
 
+       set_freezable();
        for (;;) {
                lbs_deb_thread( "main-thread 111: intcounter=%d "
                       "currenttxskb=%p dnld_sent=%d\n",
@@ -790,7 +791,6 @@ static int libertas_thread(void *data)
                } 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,
@@ -925,7 +925,7 @@ static int libertas_thread(void *data)
  *  @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;
@@ -933,14 +933,6 @@ static int wlan_setup_station_hw(wlan_private * priv)
 
        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
         */
@@ -991,8 +983,6 @@ done:
        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.
@@ -1034,155 +1024,99 @@ static void command_timer_fn(unsigned long data)
        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;
 }
 
 /**
@@ -1202,7 +1136,7 @@ wlan_private *libertas_add_card(void *card, struct device 
*dmdev)
        /* 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;
 
@@ -1212,10 +1146,16 @@ wlan_private *libertas_add_card(void *card, struct 
device *dmdev)
                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);
 
@@ -1238,87 +1178,144 @@ wlan_private *libertas_add_card(void *card, struct 
device *dmdev)
 
        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);
 
 
 /**
@@ -1388,89 +1385,12 @@ done:
 }
 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;
@@ -1487,7 +1407,7 @@ void libertas_remove_mesh(wlan_private *priv)
        free_netdev(mesh_dev);
 
 out:
-       lbs_deb_leave(LBS_DEB_NET);
+       lbs_deb_leave(LBS_DEB_MAIN);
 }
 EXPORT_SYMBOL_GPL(libertas_remove_mesh);
 
diff --git a/drivers/net/wireless/rtl8187_dev.c 
b/drivers/net/wireless/rtl8187_dev.c
index e61c6d5..d52e487 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -604,8 +604,7 @@ static int __devinit rtl8187_probe(struct usb_interface 
*intf,
        priv->mode = IEEE80211_IF_TYPE_MGMT;
        dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
                     IEEE80211_HW_RX_INCLUDES_FCS |
-                    IEEE80211_HW_WEP_INCLUDE_IV |
-                    IEEE80211_HW_DATA_NULLFUNC_ACK;
+                    IEEE80211_HW_WEP_INCLUDE_IV;
        dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
        dev->queues = 1;
        dev->max_rssi = 65;
-- 
John W. Linville
[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to