]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
authorJohn W. Linville <linville@tuxdriver.com>
Thu, 25 Jul 2013 20:48:01 +0000 (16:48 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 25 Jul 2013 20:48:01 +0000 (16:48 -0400)
1  2 
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/rt2x00/Kconfig

index e347d8ceb6826d50e1bea54ce44bc6469f5abd03,9279927326203d02f421233b9456f074cb92e5ec..52cd5219aba90f98b5b800f8370b14bbb6f2d49a
@@@ -146,6 -146,28 +146,28 @@@ static void ath_set_rates(struct ieee80
                               ARRAY_SIZE(bf->rates));
  }
  
+ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
+                            struct sk_buff *skb)
+ {
+       int q;
+       q = skb_get_queue_mapping(skb);
+       if (txq == sc->tx.uapsdq)
+               txq = sc->tx.txq_map[q];
+       if (txq != sc->tx.txq_map[q])
+               return;
+       if (WARN_ON(--txq->pending_frames < 0))
+               txq->pending_frames = 0;
+       if (txq->stopped &&
+           txq->pending_frames < sc->tx.txq_max_pending[q]) {
+               ieee80211_wake_queue(sc->hw, q);
+               txq->stopped = false;
+       }
+ }
  static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
  {
        struct ath_txq *txq = tid->ac->txq;
                if (!bf) {
                        bf = ath_tx_setup_buffer(sc, txq, tid, skb);
                        if (!bf) {
+                               ath_txq_skb_done(sc, txq, skb);
                                ieee80211_free_txskb(sc->hw, skb);
                                continue;
                        }
@@@ -811,6 -834,7 +834,7 @@@ ath_tx_get_tid_subframe(struct ath_soft
  
                if (!bf) {
                        __skb_unlink(skb, &tid->buf_q);
+                       ath_txq_skb_done(sc, txq, skb);
                        ieee80211_free_txskb(sc->hw, skb);
                        continue;
                }
@@@ -999,7 -1023,7 +1023,7 @@@ void ath_update_max_aggr_framelen(struc
  }
  
  static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
 -                           struct ath_tx_info *info, int len)
 +                           struct ath_tx_info *info, int len, bool rts)
  {
        struct ath_hw *ah = sc->sc_ah;
        struct sk_buff *skb;
        const struct ieee80211_rate *rate;
        struct ieee80211_hdr *hdr;
        struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
 +      u32 rts_thresh = sc->hw->wiphy->rts_threshold;
        int i;
        u8 rix = 0;
  
                rix = rates[i].idx;
                info->rates[i].Tries = rates[i].count;
  
 -                  if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
 +              /*
 +               * Handle RTS threshold for unaggregated HT frames.
 +               */
 +              if (bf_isampdu(bf) && !bf_isaggr(bf) &&
 +                  (rates[i].flags & IEEE80211_TX_RC_MCS) &&
 +                  unlikely(rts_thresh != (u32) -1)) {
 +                      if (!rts_thresh || (len > rts_thresh))
 +                              rts = true;
 +              }
 +
 +              if (rts || rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                        info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
                        info->flags |= ATH9K_TXDESC_RTSENA;
                } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
@@@ -1134,8 -1147,6 +1158,8 @@@ static void ath_tx_fill_desc(struct ath
        struct ath_hw *ah = sc->sc_ah;
        struct ath_buf *bf_first = NULL;
        struct ath_tx_info info;
 +      u32 rts_thresh = sc->hw->wiphy->rts_threshold;
 +      bool rts = false;
  
        memset(&info, 0, sizeof(info));
        info.is_first = true;
                                info.flags |= (u32) bf->bf_state.bfs_paprd <<
                                              ATH9K_TXDESC_PAPRD_S;
  
 -                      ath_buf_set_rate(sc, bf, &info, len);
 +                      /*
 +                       * mac80211 doesn't handle RTS threshold for HT because
 +                       * the decision has to be taken based on AMPDU length
 +                       * and aggregation is done entirely inside ath9k.
 +                       * Set the RTS/CTS flag for the first subframe based
 +                       * on the threshold.
 +                       */
 +                      if (aggr && (bf == bf_first) &&
 +                          unlikely(rts_thresh != (u32) -1)) {
 +                              /*
 +                               * "len" is the size of the entire AMPDU.
 +                               */
 +                              if (!rts_thresh || (len > rts_thresh))
 +                                      rts = true;
 +                      }
 +                      ath_buf_set_rate(sc, bf, &info, len, rts);
                }
  
                info.buf_addr[0] = bf->bf_buf_addr;
@@@ -1852,6 -1848,7 +1876,7 @@@ static void ath_tx_send_ampdu(struct at
  
        bf = ath_tx_setup_buffer(sc, txq, tid, skb);
        if (!bf) {
+               ath_txq_skb_done(sc, txq, skb);
                ieee80211_free_txskb(sc->hw, skb);
                return;
        }
@@@ -2118,6 -2115,7 +2143,7 @@@ int ath_tx_start(struct ieee80211_hw *h
  
        bf = ath_tx_setup_buffer(sc, txq, tid, skb);
        if (!bf) {
+               ath_txq_skb_done(sc, txq, skb);
                if (txctl->paprd)
                        dev_kfree_skb_any(skb);
                else
@@@ -2170,7 -2168,7 +2196,7 @@@ void ath_tx_cabq(struct ieee80211_hw *h
  
                bf->bf_lastbf = bf;
                ath_set_rates(vif, NULL, bf);
 -              ath_buf_set_rate(sc, bf, &info, fi->framelen);
 +              ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
                duration += info.rates[0].PktDuration;
                if (bf_tail)
                        bf_tail->bf_next = bf;
@@@ -2217,7 -2215,7 +2243,7 @@@ static void ath_tx_complete(struct ath_
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
-       int q, padpos, padsize;
+       int padpos, padsize;
        unsigned long flags;
  
        ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
  
        __skb_queue_tail(&txq->complete_q, skb);
-       q = skb_get_queue_mapping(skb);
-       if (txq == sc->tx.uapsdq)
-               txq = sc->tx.txq_map[q];
-       if (txq == sc->tx.txq_map[q]) {
-               if (WARN_ON(--txq->pending_frames < 0))
-                       txq->pending_frames = 0;
-               if (txq->stopped &&
-                   txq->pending_frames < sc->tx.txq_max_pending[q]) {
-                       ieee80211_wake_queue(sc->hw, q);
-                       txq->stopped = false;
-               }
-       }
+       ath_txq_skb_done(sc, txq, skb);
  }
  
  static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
index 971ce46a6b5f4511b4b02d2cab55917348ec7243,ab636767fbde098ce41bd952aa7d950b6932cb28..1caa31992a7e1ecc25b03d32d78aaf12894fcd78
@@@ -51,7 -51,7 +51,7 @@@ static void wil_print_vring(struct seq_
                        if ((i % 64) == 0 && (i != 0))
                                seq_printf(s, "\n");
                        seq_printf(s, "%s", (d->dma.status & BIT(0)) ?
 -                                      "S" : (vring->ctx[i] ? "H" : "h"));
 +                                      "S" : (vring->ctx[i].skb ? "H" : "h"));
                }
                seq_printf(s, "\n");
        }
@@@ -145,7 -145,7 +145,7 @@@ static void wil_print_ring(struct seq_f
                                   le16_to_cpu(hdr.type), hdr.flags);
                        if (len <= MAX_MBOXITEM_SIZE) {
                                int n = 0;
-                               unsigned char printbuf[16 * 3 + 2];
+                               char printbuf[16 * 3 + 2];
                                unsigned char databuf[MAX_MBOXITEM_SIZE];
                                void __iomem *src = wmi_buffer(wil, d.addr) +
                                        sizeof(struct wil6210_mbox_hdr);
@@@ -406,7 -406,7 +406,7 @@@ static int wil_txdesc_debugfs_show(stru
                volatile struct vring_tx_desc *d =
                                &(vring->va[dbg_txdesc_index].tx);
                volatile u32 *u = (volatile u32 *)d;
 -              struct sk_buff *skb = vring->ctx[dbg_txdesc_index];
 +              struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb;
  
                seq_printf(s, "Tx[%3d] = {\n", dbg_txdesc_index);
                seq_printf(s, "  MAC = 0x%08x 0x%08x 0x%08x 0x%08x\n",
                seq_printf(s, "  SKB = %p\n", skb);
  
                if (skb) {
-                       unsigned char printbuf[16 * 3 + 2];
+                       char printbuf[16 * 3 + 2];
                        int i = 0;
                        int len = le16_to_cpu(d->dma.length);
                        void *p = skb->data;
index e4c5ae34c6a8e73cd0b4ce687658681046283f03,2cf8b964e966c5dec94b37ca9a826799d73f4dee..e021a581a143872d231d6c77de60dad877bcfa2a
@@@ -135,7 -135,6 +135,7 @@@ int mwifiex_init_priv(struct mwifiex_pr
  
        priv->csa_chan = 0;
        priv->csa_expire_time = 0;
 +      priv->del_list_idx = 0;
  
        return mwifiex_add_bss_prio_tbl(priv);
  }
@@@ -378,11 -377,18 +378,11 @@@ static void mwifiex_free_lock_list(stru
  static void
  mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
  {
 -      int i;
 -
        if (!adapter) {
                pr_err("%s: adapter is NULL\n", __func__);
                return;
        }
  
 -      for (i = 0; i < adapter->priv_num; i++) {
 -              if (adapter->priv[i])
 -                      del_timer_sync(&adapter->priv[i]->scan_delay_timer);
 -      }
 -
        mwifiex_cancel_all_pending_cmd(adapter);
  
        /* Free lock variables */
        dev_dbg(adapter->dev, "info: free cmd buffer\n");
        mwifiex_free_cmd_buffer(adapter);
  
 -      del_timer(&adapter->cmd_timer);
 -
        dev_dbg(adapter->dev, "info: free scan table\n");
  
 -      if (adapter->if_ops.cleanup_if)
 -              adapter->if_ops.cleanup_if(adapter);
 -
        if (adapter->sleep_cfm)
                dev_kfree_skb_any(adapter->sleep_cfm);
  }
@@@ -682,7 -693,7 +682,7 @@@ int mwifiex_dnld_fw(struct mwifiex_adap
                if (!ret) {
                        dev_notice(adapter->dev,
                                   "WLAN FW already running! Skip FW dnld\n");
-                       goto done;
+                       return 0;
                }
  
                poll_num = MAX_FIRMWARE_POLL_TRIES;
                if (!adapter->winner) {
                        dev_notice(adapter->dev,
                                   "FW already running! Skip FW dnld\n");
 -                      poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
                        goto poll_fw;
                }
        }
  poll_fw:
        /* Check if the firmware is downloaded successfully or not */
        ret = adapter->if_ops.check_fw_status(adapter, poll_num);
-       if (ret) {
+       if (ret)
                dev_err(adapter->dev, "FW failed to be active in time\n");
-               return -1;
-       }
- done:
-       /* re-enable host interrupt for mwifiex after fw dnld is successful */
-       if (adapter->if_ops.enable_int)
-               adapter->if_ops.enable_int(adapter);
  
        return ret;
  }
index f26beb7ed022224b3a2ba4c5496a527aef2ed4b8,1753431de361b807890ec8bcb177760f457faa07..e64c369f30243183509a77a0950a0f6d193b3c1a
@@@ -191,16 -191,12 +191,16 @@@ static int mwifiex_unregister(struct mw
  {
        s32 i;
  
 +      if (adapter->if_ops.cleanup_if)
 +              adapter->if_ops.cleanup_if(adapter);
 +
        del_timer(&adapter->cmd_timer);
  
        /* Free private structures */
        for (i = 0; i < adapter->priv_num; i++) {
                if (adapter->priv[i]) {
                        mwifiex_free_curr_bcn(adapter->priv[i]);
 +                      del_timer_sync(&adapter->priv[i]->scan_delay_timer);
                        kfree(adapter->priv[i]);
                }
        }
@@@ -431,6 -427,10 +431,10 @@@ static void mwifiex_fw_dpc(const struc
                                "Cal data request_firmware() failed\n");
        }
  
+       /* enable host interrupt after fw dnld is successful */
+       if (adapter->if_ops.enable_int)
+               adapter->if_ops.enable_int(adapter);
        adapter->init_wait_q_woken = false;
        ret = mwifiex_init_fw(adapter);
        if (ret == -1) {
@@@ -482,6 -482,8 +486,8 @@@ err_add_intf
        mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
        rtnl_unlock();
  err_init_fw:
+       if (adapter->if_ops.disable_int)
+               adapter->if_ops.disable_int(adapter);
        pr_debug("info: %s: unregister device\n", __func__);
        adapter->if_ops.unregister_dev(adapter);
  done:
@@@ -859,7 -861,7 +865,7 @@@ mwifiex_add_card(void *card, struct sem
        INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
  
        /* Register the device. Fill up the private data structure with relevant
-          information from the card and request for the required IRQ. */
+          information from the card. */
        if (adapter->if_ops.register_dev(adapter)) {
                pr_err("%s: failed to register mwifiex device\n", __func__);
                goto err_registerdev;
@@@ -923,6 -925,11 +929,11 @@@ int mwifiex_remove_card(struct mwifiex_
        if (!adapter)
                goto exit_remove;
  
+       /* We can no longer handle interrupts once we start doing the teardown
+        * below. */
+       if (adapter->if_ops.disable_int)
+               adapter->if_ops.disable_int(adapter);
        adapter->surprise_removed = true;
  
        /* Stop data */
index 5db05435d412ed7070d2f94ae1d27f45c1467202,253e0bd38e25e22ce911e6e49b4d99261afe596d..bb28d3dc0164e8e8dfc2d84b4f10ec2079add965
@@@ -204,11 -204,11 +204,11 @@@ struct mwifiex_ra_list_tbl 
        struct list_head list;
        struct sk_buff_head skb_head;
        u8 ra[ETH_ALEN];
 -      u32 total_pkts_size;
        u32 is_11n_enabled;
        u16 max_amsdu;
 -      u16 pkt_count;
 +      u16 ba_pkt_count;
        u8 ba_packet_thr;
 +      u16 total_pkt_count;
  };
  
  struct mwifiex_tid_tbl {
@@@ -515,7 -515,6 +515,7 @@@ struct mwifiex_private 
        bool scan_aborting;
        u8 csa_chan;
        unsigned long csa_expire_time;
 +      u8 del_list_idx;
  };
  
  enum mwifiex_ba_status {
@@@ -602,6 -601,7 +602,7 @@@ struct mwifiex_if_ops 
        int (*register_dev) (struct mwifiex_adapter *);
        void (*unregister_dev) (struct mwifiex_adapter *);
        int (*enable_int) (struct mwifiex_adapter *);
+       void (*disable_int) (struct mwifiex_adapter *);
        int (*process_int_status) (struct mwifiex_adapter *);
        int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *,
                             struct mwifiex_tx_param *);
index 14ac51fd7d3c1aeda32615e74c73aae8c528e527,5ef49f2e375a13f768286dafcb143a540ac3a273..c32a735ca3aaca6bea67d3b297a8fc897c659e93
@@@ -51,6 -51,7 +51,7 @@@ static struct mwifiex_if_ops sdio_ops
  static struct semaphore add_remove_card_sem;
  
  static int mwifiex_sdio_resume(struct device *dev);
+ static void mwifiex_sdio_interrupt(struct sdio_func *func);
  
  /*
   * SDIO probe.
@@@ -296,6 -297,15 +297,15 @@@ static struct sdio_driver mwifiex_sdio 
        }
  };
  
+ /* Write data into SDIO card register. Caller claims SDIO device. */
+ static int
+ mwifiex_write_reg_locked(struct sdio_func *func, u32 reg, u8 data)
+ {
+       int ret = -1;
+       sdio_writeb(func, data, reg, &ret);
+       return ret;
+ }
  /*
   * This function writes data into SDIO card register.
   */
@@@ -303,10 -313,10 +313,10 @@@ static in
  mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
  {
        struct sdio_mmc_card *card = adapter->card;
-       int ret = -1;
+       int ret;
  
        sdio_claim_host(card->func);
-       sdio_writeb(card->func, data, reg, &ret);
+       ret = mwifiex_write_reg_locked(card->func, reg, data);
        sdio_release_host(card->func);
  
        return ret;
@@@ -685,23 -695,15 +695,15 @@@ mwifiex_sdio_read_fw_status(struct mwif
   * The host interrupt mask is read, the disable bit is reset and
   * written back to the card host interrupt mask register.
   */
- static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
+ static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
  {
-       u8 host_int_mask, host_int_disable = HOST_INT_DISABLE;
-       /* Read back the host_int_mask register */
-       if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
-               return -1;
-       /* Update with the mask and write back to the register */
-       host_int_mask &= ~host_int_disable;
-       if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
-               dev_err(adapter->dev, "disable host interrupt failed\n");
-               return -1;
-       }
+       struct sdio_mmc_card *card = adapter->card;
+       struct sdio_func *func = card->func;
  
-       return 0;
+       sdio_claim_host(func);
+       mwifiex_write_reg_locked(func, HOST_INT_MASK_REG, 0);
+       sdio_release_irq(func);
+       sdio_release_host(func);
  }
  
  /*
  static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)
  {
        struct sdio_mmc_card *card = adapter->card;
+       struct sdio_func *func = card->func;
+       int ret;
+       sdio_claim_host(func);
+       /* Request the SDIO IRQ */
+       ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
+       if (ret) {
+               dev_err(adapter->dev, "claim irq failed: ret=%d\n", ret);
+               goto out;
+       }
  
        /* Simply write the mask to the register */
-       if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG,
-                             card->reg->host_int_enable)) {
+       ret = mwifiex_write_reg_locked(func, HOST_INT_MASK_REG,
+                                      card->reg->host_int_enable);
+       if (ret) {
                dev_err(adapter->dev, "enable host interrupt failed\n");
-               return -1;
+               sdio_release_irq(func);
        }
-       return 0;
+ out:
+       sdio_release_host(func);
+       return ret;
  }
  
  /*
@@@ -927,7 -944,7 +944,7 @@@ static int mwifiex_check_fw_status(stru
                        ret = 0;
                        break;
                } else {
 -                      mdelay(100);
 +                      msleep(100);
                        ret = -1;
                }
        }
@@@ -997,9 -1014,6 +1014,6 @@@ mwifiex_sdio_interrupt(struct sdio_fun
        }
        adapter = card->adapter;
  
-       if (adapter->surprise_removed)
-               return;
        if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
                adapter->ps_state = PS_STATE_AWAKE;
  
@@@ -1728,9 -1742,7 +1742,7 @@@ mwifiex_unregister_dev(struct mwifiex_a
        struct sdio_mmc_card *card = adapter->card;
  
        if (adapter->card) {
-               /* Release the SDIO IRQ */
                sdio_claim_host(card->func);
-               sdio_release_irq(card->func);
                sdio_disable_func(card->func);
                sdio_release_host(card->func);
                sdio_set_drvdata(card->func, NULL);
   */
  static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
  {
-       int ret = 0;
+       int ret;
        struct sdio_mmc_card *card = adapter->card;
        struct sdio_func *func = card->func;
  
  
        sdio_claim_host(func);
  
-       /* Request the SDIO IRQ */
-       ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
-       if (ret) {
-               pr_err("claim irq failed: ret=%d\n", ret);
-               goto disable_func;
-       }
        /* Set block size */
        ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);
+       sdio_release_host(func);
        if (ret) {
                pr_err("cannot set SDIO block size\n");
-               ret = -1;
-               goto release_irq;
+               return ret;
        }
  
-       sdio_release_host(func);
        sdio_set_drvdata(func, card);
  
        adapter->dev = &func->dev;
        strcpy(adapter->fw_name, card->firmware);
  
        return 0;
- release_irq:
-       sdio_release_irq(func);
- disable_func:
-       sdio_disable_func(func);
-       sdio_release_host(func);
-       adapter->card = NULL;
-       return -1;
  }
  
  /*
@@@ -1813,9 -1808,6 +1808,6 @@@ static int mwifiex_init_sdio(struct mwi
         */
        mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg);
  
-       /* Disable host interrupt mask register for SDIO */
-       mwifiex_sdio_disable_host_int(adapter);
        /* Get SDIO ioport */
        mwifiex_init_sdio_ioport(adapter);
  
@@@ -1957,6 -1949,7 +1949,7 @@@ static struct mwifiex_if_ops sdio_ops 
        .register_dev = mwifiex_register_dev,
        .unregister_dev = mwifiex_unregister_dev,
        .enable_int = mwifiex_sdio_enable_host_int,
+       .disable_int = mwifiex_sdio_disable_host_int,
        .process_int_status = mwifiex_process_int_status,
        .host_to_card = mwifiex_sdio_host_to_card,
        .wakeup = mwifiex_pm_wakeup_card,
index c60d6e83a9502a7e97a9a39b9b89bb04d739cb55,3e60a31582f8b3b15f359a5325a8031de96f4427..68dbbb9c6d1259eb3d83d7c1458126f6fc69a2f2
@@@ -1,6 -1,6 +1,6 @@@
  menuconfig RT2X00
        tristate "Ralink driver support"
-       depends on MAC80211
+       depends on MAC80211 && HAS_DMA
        ---help---
          This will enable the support for the Ralink drivers,
          developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
@@@ -166,12 -166,6 +166,12 @@@ config RT2800USB_RT35X
          rt2800usb driver.
          Supported chips: RT3572
  
 +config RT2800USB_RT3573
 +      bool "rt2800usb - Include support for rt3573 devices (EXPERIMENTAL)"
 +      ---help---
 +        This enables support for RT3573 chipset based wireless USB devices
 +        in the rt2800usb driver.
 +
  config RT2800USB_RT53XX
         bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
         ---help---