aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c6
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c18
-rw-r--r--drivers/net/wireless/b43/Kconfig2
-rw-r--r--drivers/net/wireless/b43/main.c1
-rw-r--r--drivers/net/wireless/b43/xmit.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c5
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c1
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c1
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c1
-rw-r--r--drivers/net/wireless/mwifiex/main.c1
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c1
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c2
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c1
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c1
-rw-r--r--drivers/net/wireless/mwifiex/util.h43
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c55
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c24
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h1
22 files changed, 144 insertions, 44 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 82017f56e661..e6c56c5bb0f6 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -795,7 +795,11 @@ int ath10k_core_start(struct ath10k *ar)
795 if (status) 795 if (status)
796 goto err_htc_stop; 796 goto err_htc_stop;
797 797
798 ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; 798 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
799 ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1;
800 else
801 ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
802
799 INIT_LIST_HEAD(&ar->arvifs); 803 INIT_LIST_HEAD(&ar->arvifs);
800 804
801 if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) 805 if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 6c102b1312ff..eebc860c3655 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -312,7 +312,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
312 int msdu_len, msdu_chaining = 0; 312 int msdu_len, msdu_chaining = 0;
313 struct sk_buff *msdu; 313 struct sk_buff *msdu;
314 struct htt_rx_desc *rx_desc; 314 struct htt_rx_desc *rx_desc;
315 bool corrupted = false;
316 315
317 lockdep_assert_held(&htt->rx_ring.lock); 316 lockdep_assert_held(&htt->rx_ring.lock);
318 317
@@ -439,9 +438,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
439 last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) & 438 last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
440 RX_MSDU_END_INFO0_LAST_MSDU; 439 RX_MSDU_END_INFO0_LAST_MSDU;
441 440
442 if (msdu_chaining && !last_msdu)
443 corrupted = true;
444
445 if (last_msdu) { 441 if (last_msdu) {
446 msdu->next = NULL; 442 msdu->next = NULL;
447 break; 443 break;
@@ -457,20 +453,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
457 msdu_chaining = -1; 453 msdu_chaining = -1;
458 454
459 /* 455 /*
460 * Apparently FW sometimes reports weird chained MSDU sequences with
461 * more than one rx descriptor. This seems like a bug but needs more
462 * analyzing. For the time being fix it by dropping such sequences to
463 * avoid blowing up the host system.
464 */
465 if (corrupted) {
466 ath10k_warn("failed to pop chained msdus, dropping\n");
467 ath10k_htt_rx_free_msdu_chain(*head_msdu);
468 *head_msdu = NULL;
469 *tail_msdu = NULL;
470 msdu_chaining = -EINVAL;
471 }
472
473 /*
474 * Don't refill the ring yet. 456 * Don't refill the ring yet.
475 * 457 *
476 * First, the elements popped here are still in use - it is not 458 * First, the elements popped here are still in use - it is not
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 037a4e304d14..d4c6ae3a9210 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -36,7 +36,7 @@ config B43_SSB
36choice 36choice
37 prompt "Supported bus types" 37 prompt "Supported bus types"
38 depends on B43 38 depends on B43
39 default B43_BCMA_AND_SSB 39 default B43_BUSES_BCMA_AND_SSB
40 40
41config B43_BUSES_BCMA_AND_SSB 41config B43_BUSES_BCMA_AND_SSB
42 bool "BCMA and SSB" 42 bool "BCMA and SSB"
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index b2bc593a6513..15aaeb132a32 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -5250,6 +5250,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
5250 /* We don't support 5 GHz on some PHYs yet */ 5250 /* We don't support 5 GHz on some PHYs yet */
5251 switch (dev->phy.type) { 5251 switch (dev->phy.type) {
5252 case B43_PHYTYPE_A: 5252 case B43_PHYTYPE_A:
5253 case B43_PHYTYPE_G:
5253 case B43_PHYTYPE_N: 5254 case B43_PHYTYPE_N:
5254 case B43_PHYTYPE_LP: 5255 case B43_PHYTYPE_LP:
5255 case B43_PHYTYPE_HT: 5256 case B43_PHYTYPE_HT:
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 4f38f19b8e3d..6e6ef3fc2247 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -811,9 +811,13 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
811 break; 811 break;
812 case B43_PHYTYPE_G: 812 case B43_PHYTYPE_G:
813 status.band = IEEE80211_BAND_2GHZ; 813 status.band = IEEE80211_BAND_2GHZ;
814 /* chanid is the radio channel cookie value as used 814 /* Somewhere between 478.104 and 508.1084 firmware for G-PHY
815 * to tune the radio. */ 815 * has been modified to be compatible with N-PHY and others.
816 status.freq = chanid + 2400; 816 */
817 if (dev->fw.rev >= 508)
818 status.freq = ieee80211_channel_to_frequency(chanid, status.band);
819 else
820 status.freq = chanid + 2400;
817 break; 821 break;
818 case B43_PHYTYPE_N: 822 case B43_PHYTYPE_N:
819 case B43_PHYTYPE_LP: 823 case B43_PHYTYPE_LP:
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 839bcda9465a..b732a99e402c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -1183,8 +1183,6 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1183 bus->bus_priv.usb = bus_pub; 1183 bus->bus_priv.usb = bus_pub;
1184 dev_set_drvdata(dev, bus); 1184 dev_set_drvdata(dev, bus);
1185 bus->ops = &brcmf_usb_bus_ops; 1185 bus->ops = &brcmf_usb_bus_ops;
1186 bus->chip = bus_pub->devid;
1187 bus->chiprev = bus_pub->chiprev;
1188 bus->proto_type = BRCMF_PROTO_BCDC; 1186 bus->proto_type = BRCMF_PROTO_BCDC;
1189 bus->always_use_fws_queue = true; 1187 bus->always_use_fws_queue = true;
1190 1188
@@ -1193,6 +1191,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1193 if (ret) 1191 if (ret)
1194 goto fail; 1192 goto fail;
1195 } 1193 }
1194 bus->chip = bus_pub->devid;
1195 bus->chiprev = bus_pub->chiprev;
1196
1196 /* request firmware here */ 1197 /* request firmware here */
1197 brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL, 1198 brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
1198 brcmf_usb_probe_phase2); 1199 brcmf_usb_probe_phase2);
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index b4c14b0fd3cb..8720a3d3c755 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -185,6 +185,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
185 skb_reserve(skb_aggr, headroom + sizeof(struct txpd)); 185 skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
186 tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr); 186 tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
187 187
188 memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
188 tx_info_aggr->bss_type = tx_info_src->bss_type; 189 tx_info_aggr->bss_type = tx_info_src->bss_type;
189 tx_info_aggr->bss_num = tx_info_src->bss_num; 190 tx_info_aggr->bss_num = tx_info_src->bss_num;
190 191
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 15fa7b453372..6af135fa99f7 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -188,6 +188,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
188 } 188 }
189 189
190 tx_info = MWIFIEX_SKB_TXCB(skb); 190 tx_info = MWIFIEX_SKB_TXCB(skb);
191 memset(tx_info, 0, sizeof(*tx_info));
191 tx_info->bss_num = priv->bss_num; 192 tx_info->bss_num = priv->bss_num;
192 tx_info->bss_type = priv->bss_type; 193 tx_info->bss_type = priv->bss_type;
193 tx_info->pkt_len = pkt_len; 194 tx_info->pkt_len = pkt_len;
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index df42f066d70c..5899eee87fb1 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -462,6 +462,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
462 462
463 if (skb) { 463 if (skb) {
464 rx_info = MWIFIEX_SKB_RXCB(skb); 464 rx_info = MWIFIEX_SKB_RXCB(skb);
465 memset(rx_info, 0, sizeof(*rx_info));
465 rx_info->bss_num = priv->bss_num; 466 rx_info->bss_num = priv->bss_num;
466 rx_info->bss_type = priv->bss_type; 467 rx_info->bss_type = priv->bss_type;
467 } 468 }
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 657504c3c79d..3e5194fb0b0f 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -644,6 +644,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
644 } 644 }
645 645
646 tx_info = MWIFIEX_SKB_TXCB(skb); 646 tx_info = MWIFIEX_SKB_TXCB(skb);
647 memset(tx_info, 0, sizeof(*tx_info));
647 tx_info->bss_num = priv->bss_num; 648 tx_info->bss_num = priv->bss_num;
648 tx_info->bss_type = priv->bss_type; 649 tx_info->bss_type = priv->bss_type;
649 tx_info->pkt_len = skb->len; 650 tx_info->pkt_len = skb->len;
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 3c224a793b82..5f7afffdd34e 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -57,7 +57,7 @@ mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
57 return -1; 57 return -1;
58 } 58 }
59 mapping.len = size; 59 mapping.len = size;
60 memcpy(skb->cb, &mapping, sizeof(mapping)); 60 mwifiex_store_mapping(skb, &mapping);
61 return 0; 61 return 0;
62} 62}
63 63
@@ -67,7 +67,7 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
67 struct pcie_service_card *card = adapter->card; 67 struct pcie_service_card *card = adapter->card;
68 struct mwifiex_dma_mapping mapping; 68 struct mwifiex_dma_mapping mapping;
69 69
70 MWIFIEX_SKB_PACB(skb, &mapping); 70 mwifiex_get_mapping(skb, &mapping);
71 pci_unmap_single(card->dev, mapping.addr, mapping.len, flags); 71 pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
72} 72}
73 73
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index cf330ba951cd..dab7b33c54be 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -150,6 +150,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
150 return -1; 150 return -1;
151 151
152 tx_info = MWIFIEX_SKB_TXCB(skb); 152 tx_info = MWIFIEX_SKB_TXCB(skb);
153 memset(tx_info, 0, sizeof(*tx_info));
153 tx_info->bss_num = priv->bss_num; 154 tx_info->bss_num = priv->bss_num;
154 tx_info->bss_type = priv->bss_type; 155 tx_info->bss_type = priv->bss_type;
155 tx_info->pkt_len = data_len - (sizeof(struct txpd) + INTF_HEADER_LEN); 156 tx_info->pkt_len = data_len - (sizeof(struct txpd) + INTF_HEADER_LEN);
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index 3efbcbe7e891..a414161c6064 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -604,6 +604,7 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
604 } 604 }
605 605
606 tx_info = MWIFIEX_SKB_TXCB(skb); 606 tx_info = MWIFIEX_SKB_TXCB(skb);
607 memset(tx_info, 0, sizeof(*tx_info));
607 tx_info->bss_num = priv->bss_num; 608 tx_info->bss_num = priv->bss_num;
608 tx_info->bss_type = priv->bss_type; 609 tx_info->bss_type = priv->bss_type;
609 610
@@ -757,6 +758,7 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
757 skb->priority = MWIFIEX_PRIO_VI; 758 skb->priority = MWIFIEX_PRIO_VI;
758 759
759 tx_info = MWIFIEX_SKB_TXCB(skb); 760 tx_info = MWIFIEX_SKB_TXCB(skb);
761 memset(tx_info, 0, sizeof(*tx_info));
760 tx_info->bss_num = priv->bss_num; 762 tx_info->bss_num = priv->bss_num;
761 tx_info->bss_type = priv->bss_type; 763 tx_info->bss_type = priv->bss_type;
762 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; 764 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 08205683f877..96a2126cc44b 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -55,6 +55,7 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
55 return -1; 55 return -1;
56 } 56 }
57 57
58 memset(rx_info, 0, sizeof(*rx_info));
58 rx_info->bss_num = priv->bss_num; 59 rx_info->bss_num = priv->bss_num;
59 rx_info->bss_type = priv->bss_type; 60 rx_info->bss_type = priv->bss_type;
60 61
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index ddfc3c6c1e78..ec7309d096ab 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -174,6 +174,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
174 } 174 }
175 175
176 tx_info = MWIFIEX_SKB_TXCB(skb); 176 tx_info = MWIFIEX_SKB_TXCB(skb);
177 memset(tx_info, 0, sizeof(*tx_info));
177 tx_info->bss_num = priv->bss_num; 178 tx_info->bss_num = priv->bss_num;
178 tx_info->bss_type = priv->bss_type; 179 tx_info->bss_type = priv->bss_type;
179 tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT; 180 tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index 9a31215487dd..40296cb4a3f1 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -20,32 +20,55 @@
20#ifndef _MWIFIEX_UTIL_H_ 20#ifndef _MWIFIEX_UTIL_H_
21#define _MWIFIEX_UTIL_H_ 21#define _MWIFIEX_UTIL_H_
22 22
23struct mwifiex_dma_mapping {
24 dma_addr_t addr;
25 size_t len;
26};
27
28struct mwifiex_cb {
29 struct mwifiex_dma_mapping dma_mapping;
30 union {
31 struct mwifiex_rxinfo rx_info;
32 struct mwifiex_txinfo tx_info;
33 };
34};
35
23static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) 36static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
24{ 37{
25 return (struct mwifiex_rxinfo *)(skb->cb + sizeof(dma_addr_t)); 38 struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
39
40 BUILD_BUG_ON(sizeof(struct mwifiex_cb) > sizeof(skb->cb));
41 return &cb->rx_info;
26} 42}
27 43
28static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb) 44static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
29{ 45{
30 return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t)); 46 struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
47
48 return &cb->tx_info;
31} 49}
32 50
33struct mwifiex_dma_mapping { 51static inline void mwifiex_store_mapping(struct sk_buff *skb,
34 dma_addr_t addr; 52 struct mwifiex_dma_mapping *mapping)
35 size_t len; 53{
36}; 54 struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
55
56 memcpy(&cb->dma_mapping, mapping, sizeof(*mapping));
57}
37 58
38static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb, 59static inline void mwifiex_get_mapping(struct sk_buff *skb,
39 struct mwifiex_dma_mapping *mapping) 60 struct mwifiex_dma_mapping *mapping)
40{ 61{
41 memcpy(mapping, skb->cb, sizeof(*mapping)); 62 struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
63
64 memcpy(mapping, &cb->dma_mapping, sizeof(*mapping));
42} 65}
43 66
44static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb) 67static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb)
45{ 68{
46 struct mwifiex_dma_mapping mapping; 69 struct mwifiex_dma_mapping mapping;
47 70
48 MWIFIEX_SKB_PACB(skb, &mapping); 71 mwifiex_get_mapping(skb, &mapping);
49 72
50 return mapping.addr; 73 return mapping.addr;
51} 74}
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 2f1cd929c6f6..a511cccc9f01 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1681,8 +1681,13 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1681 /* 1681 /*
1682 * Detect if this device has an hardware controlled radio. 1682 * Detect if this device has an hardware controlled radio.
1683 */ 1683 */
1684 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) 1684 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) {
1685 __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); 1685 __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
1686 /*
1687 * On this device RFKILL initialized during probe does not work.
1688 */
1689 __set_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags);
1690 }
1686 1691
1687 /* 1692 /*
1688 * Check if the BBP tuning should be enabled. 1693 * Check if the BBP tuning should be enabled.
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index a49c3d73ea2c..832006b5aab1 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -229,6 +229,31 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
229/* 229/*
230 * Firmware functions 230 * Firmware functions
231 */ 231 */
232static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
233{
234 __le32 *reg;
235 u32 fw_mode;
236
237 reg = kmalloc(sizeof(*reg), GFP_KERNEL);
238 if (reg == NULL)
239 return -ENOMEM;
240 /* cannot use rt2x00usb_register_read here as it uses different
241 * mode (MULTI_READ vs. DEVICE_MODE) and does not pass the
242 * magic value USB_MODE_AUTORUN (0x11) to the device, thus the
243 * returned value would be invalid.
244 */
245 rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE,
246 USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN,
247 reg, sizeof(*reg), REGISTER_TIMEOUT_FIRMWARE);
248 fw_mode = le32_to_cpu(*reg);
249 kfree(reg);
250
251 if ((fw_mode & 0x00000003) == 2)
252 return 1;
253
254 return 0;
255}
256
232static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) 257static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
233{ 258{
234 return FIRMWARE_RT2870; 259 return FIRMWARE_RT2870;
@@ -240,6 +265,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
240 int status; 265 int status;
241 u32 offset; 266 u32 offset;
242 u32 length; 267 u32 length;
268 int retval;
243 269
244 /* 270 /*
245 * Check which section of the firmware we need. 271 * Check which section of the firmware we need.
@@ -257,8 +283,16 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
257 /* 283 /*
258 * Write firmware to device. 284 * Write firmware to device.
259 */ 285 */
260 rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, 286 retval = rt2800usb_autorun_detect(rt2x00dev);
261 data + offset, length); 287 if (retval < 0)
288 return retval;
289 if (retval) {
290 rt2x00_info(rt2x00dev,
291 "Firmware loading not required - NIC in AutoRun mode\n");
292 } else {
293 rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
294 data + offset, length);
295 }
262 296
263 rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); 297 rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
264 rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); 298 rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
@@ -735,11 +769,26 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
735/* 769/*
736 * Device probe functions. 770 * Device probe functions.
737 */ 771 */
772static int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev)
773{
774 int retval;
775
776 retval = rt2800usb_autorun_detect(rt2x00dev);
777 if (retval < 0)
778 return retval;
779 if (retval)
780 return 1;
781 return rt2800_efuse_detect(rt2x00dev);
782}
783
738static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev) 784static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
739{ 785{
740 int retval; 786 int retval;
741 787
742 if (rt2800_efuse_detect(rt2x00dev)) 788 retval = rt2800usb_efuse_detect(rt2x00dev);
789 if (retval < 0)
790 return retval;
791 if (retval)
743 retval = rt2800_read_eeprom_efuse(rt2x00dev); 792 retval = rt2800_read_eeprom_efuse(rt2x00dev);
744 else 793 else
745 retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, 794 retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 010b76505243..d13f25cd70d5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -693,6 +693,7 @@ enum rt2x00_capability_flags {
693 REQUIRE_SW_SEQNO, 693 REQUIRE_SW_SEQNO,
694 REQUIRE_HT_TX_DESC, 694 REQUIRE_HT_TX_DESC,
695 REQUIRE_PS_AUTOWAKE, 695 REQUIRE_PS_AUTOWAKE,
696 REQUIRE_DELAYED_RFKILL,
696 697
697 /* 698 /*
698 * Capabilities 699 * Capabilities
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index c6ae9a495b77..9967a1d9f0ec 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1129,9 +1129,10 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
1129 return; 1129 return;
1130 1130
1131 /* 1131 /*
1132 * Unregister extra components. 1132 * Stop rfkill polling.
1133 */ 1133 */
1134 rt2x00rfkill_unregister(rt2x00dev); 1134 if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
1135 rt2x00rfkill_unregister(rt2x00dev);
1135 1136
1136 /* 1137 /*
1137 * Allow the HW to uninitialize. 1138 * Allow the HW to uninitialize.
@@ -1169,6 +1170,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
1169 1170
1170 set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags); 1171 set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
1171 1172
1173 /*
1174 * Start rfkill polling.
1175 */
1176 if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
1177 rt2x00rfkill_register(rt2x00dev);
1178
1172 return 0; 1179 return 0;
1173} 1180}
1174 1181
@@ -1378,7 +1385,12 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1378 rt2x00link_register(rt2x00dev); 1385 rt2x00link_register(rt2x00dev);
1379 rt2x00leds_register(rt2x00dev); 1386 rt2x00leds_register(rt2x00dev);
1380 rt2x00debug_register(rt2x00dev); 1387 rt2x00debug_register(rt2x00dev);
1381 rt2x00rfkill_register(rt2x00dev); 1388
1389 /*
1390 * Start rfkill polling.
1391 */
1392 if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
1393 rt2x00rfkill_register(rt2x00dev);
1382 1394
1383 return 0; 1395 return 0;
1384 1396
@@ -1394,6 +1406,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1394 clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); 1406 clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
1395 1407
1396 /* 1408 /*
1409 * Stop rfkill polling.
1410 */
1411 if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
1412 rt2x00rfkill_unregister(rt2x00dev);
1413
1414 /*
1397 * Disable radio. 1415 * Disable radio.
1398 */ 1416 */
1399 rt2x00lib_disable_radio(rt2x00dev); 1417 rt2x00lib_disable_radio(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index e5935ea3719f..ad6e5a8d1e10 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -487,6 +487,8 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
487 crypto.cipher = rt2x00crypto_key_to_cipher(key); 487 crypto.cipher = rt2x00crypto_key_to_cipher(key);
488 if (crypto.cipher == CIPHER_NONE) 488 if (crypto.cipher == CIPHER_NONE)
489 return -EOPNOTSUPP; 489 return -EOPNOTSUPP;
490 if (crypto.cipher == CIPHER_TKIP && rt2x00_is_usb(rt2x00dev))
491 return -EOPNOTSUPP;
490 492
491 crypto.cmd = cmd; 493 crypto.cmd = cmd;
492 494
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index e7bcf62347d5..831b65f93feb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -93,6 +93,7 @@ enum rt2x00usb_mode_offset {
93 USB_MODE_SLEEP = 7, /* RT73USB */ 93 USB_MODE_SLEEP = 7, /* RT73USB */
94 USB_MODE_FIRMWARE = 8, /* RT73USB */ 94 USB_MODE_FIRMWARE = 8, /* RT73USB */
95 USB_MODE_WAKEUP = 9, /* RT73USB */ 95 USB_MODE_WAKEUP = 9, /* RT73USB */
96 USB_MODE_AUTORUN = 17, /* RT2800USB */
96}; 97};
97 98
98/** 99/**