aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/Kconfig12
-rw-r--r--drivers/net/wireless/b43legacy/dma.c66
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c4
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c65
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c117
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c8
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig8
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c23
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h40
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c107
-rw-r--r--drivers/net/wireless/rtl8187.h113
-rw-r--r--drivers/net/wireless/rtl8187_dev.c490
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.c229
-rw-r--r--drivers/net/wireless/rtl818x.h36
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c62
30 files changed, 1090 insertions, 395 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 865f2980c273..d5b006f5b86f 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -611,14 +611,20 @@ config RTL8180
611 Thanks to Realtek for their support! 611 Thanks to Realtek for their support!
612 612
613config RTL8187 613config RTL8187
614 tristate "Realtek 8187 USB support" 614 tristate "Realtek 8187 and 8187B USB support"
615 depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL 615 depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
616 select EEPROM_93CX6 616 select EEPROM_93CX6
617 ---help--- 617 ---help---
618 This is a driver for RTL8187 based cards. 618 This is a driver for RTL8187 and RTL8187B based cards.
619 These are USB based chips found in cards such as: 619 These are USB based chips found in devices such as:
620 620
621 Netgear WG111v2 621 Netgear WG111v2
622 Level 1 WNC-0301USB
623 Micronet SP907GK V5
624 Encore ENUWI-G2
625 Trendnet TEW-424UB
626 ASUS P5B Deluxe
627 Toshiba Satellite Pro series of laptops
622 628
623 Thanks to Realtek for their support! 629 Thanks to Realtek for their support!
624 630
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index eb0243a22691..fb6819e40f38 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -859,6 +859,18 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
859 return DMA_30BIT_MASK; 859 return DMA_30BIT_MASK;
860} 860}
861 861
862static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask)
863{
864 if (dmamask == DMA_30BIT_MASK)
865 return B43legacy_DMA_30BIT;
866 if (dmamask == DMA_32BIT_MASK)
867 return B43legacy_DMA_32BIT;
868 if (dmamask == DMA_64BIT_MASK)
869 return B43legacy_DMA_64BIT;
870 B43legacy_WARN_ON(1);
871 return B43legacy_DMA_30BIT;
872}
873
862/* Main initialization function. */ 874/* Main initialization function. */
863static 875static
864struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, 876struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
@@ -1018,6 +1030,43 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev)
1018 dma->tx_ring0 = NULL; 1030 dma->tx_ring0 = NULL;
1019} 1031}
1020 1032
1033static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask)
1034{
1035 u64 orig_mask = mask;
1036 bool fallback = 0;
1037 int err;
1038
1039 /* Try to set the DMA mask. If it fails, try falling back to a
1040 * lower mask, as we can always also support a lower one. */
1041 while (1) {
1042 err = ssb_dma_set_mask(dev->dev, mask);
1043 if (!err)
1044 break;
1045 if (mask == DMA_64BIT_MASK) {
1046 mask = DMA_32BIT_MASK;
1047 fallback = 1;
1048 continue;
1049 }
1050 if (mask == DMA_32BIT_MASK) {
1051 mask = DMA_30BIT_MASK;
1052 fallback = 1;
1053 continue;
1054 }
1055 b43legacyerr(dev->wl, "The machine/kernel does not support "
1056 "the required %u-bit DMA mask\n",
1057 (unsigned int)dma_mask_to_engine_type(orig_mask));
1058 return -EOPNOTSUPP;
1059 }
1060 if (fallback) {
1061 b43legacyinfo(dev->wl, "DMA mask fallback from %u-bit to %u-"
1062 "bit\n",
1063 (unsigned int)dma_mask_to_engine_type(orig_mask),
1064 (unsigned int)dma_mask_to_engine_type(mask));
1065 }
1066
1067 return 0;
1068}
1069
1021int b43legacy_dma_init(struct b43legacy_wldev *dev) 1070int b43legacy_dma_init(struct b43legacy_wldev *dev)
1022{ 1071{
1023 struct b43legacy_dma *dma = &dev->dma; 1072 struct b43legacy_dma *dma = &dev->dma;
@@ -1027,21 +1076,8 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
1027 enum b43legacy_dmatype type; 1076 enum b43legacy_dmatype type;
1028 1077
1029 dmamask = supported_dma_mask(dev); 1078 dmamask = supported_dma_mask(dev);
1030 switch (dmamask) { 1079 type = dma_mask_to_engine_type(dmamask);
1031 default: 1080 err = b43legacy_dma_set_mask(dev, dmamask);
1032 B43legacy_WARN_ON(1);
1033 case DMA_30BIT_MASK:
1034 type = B43legacy_DMA_30BIT;
1035 break;
1036 case DMA_32BIT_MASK:
1037 type = B43legacy_DMA_32BIT;
1038 break;
1039 case DMA_64BIT_MASK:
1040 type = B43legacy_DMA_64BIT;
1041 break;
1042 }
1043
1044 err = ssb_dma_set_mask(dev->dev, dmamask);
1045 if (err) { 1081 if (err) {
1046#ifdef CONFIG_B43LEGACY_PIO 1082#ifdef CONFIG_B43LEGACY_PIO
1047 b43legacywarn(dev->wl, "DMA for this device not supported. " 1083 b43legacywarn(dev->wl, "DMA for this device not supported. "
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 6c158a569485..09004a632ae7 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3417,7 +3417,7 @@ static void prism2_free_local_data(struct net_device *dev)
3417} 3417}
3418 3418
3419 3419
3420#ifndef PRISM2_PLX 3420#if (defined(PRISM2_PCI) && defined(CONFIG_PM)) || defined(PRISM2_PCCARD)
3421static void prism2_suspend(struct net_device *dev) 3421static void prism2_suspend(struct net_device *dev)
3422{ 3422{
3423 struct hostap_interface *iface; 3423 struct hostap_interface *iface;
@@ -3436,7 +3436,7 @@ static void prism2_suspend(struct net_device *dev)
3436 /* Disable hardware and firmware */ 3436 /* Disable hardware and firmware */
3437 prism2_hw_shutdown(dev, 0); 3437 prism2_hw_shutdown(dev, 0);
3438} 3438}
3439#endif /* PRISM2_PLX */ 3439#endif /* (PRISM2_PCI && CONFIG_PM) || PRISM2_PCCARD */
3440 3440
3441 3441
3442/* These might at some point be compiled separately and used as separate 3442/* These might at some point be compiled separately and used as separate
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b628a44057f7..82b66a3d3a5d 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -104,6 +104,7 @@ config IWL3945
104 select IWLWIFI 104 select IWLWIFI
105 select MAC80211_LEDS if IWL3945_LEDS 105 select MAC80211_LEDS if IWL3945_LEDS
106 select LEDS_CLASS if IWL3945_LEDS 106 select LEDS_CLASS if IWL3945_LEDS
107 select RFKILL if IWL3945_RFKILL
107 ---help--- 108 ---help---
108 Select to build the driver supporting the: 109 Select to build the driver supporting the:
109 110
@@ -126,6 +127,10 @@ config IWL3945
126 say M here and read <file:Documentation/kbuild/modules.txt>. The 127 say M here and read <file:Documentation/kbuild/modules.txt>. The
127 module will be called iwl3945.ko. 128 module will be called iwl3945.ko.
128 129
130config IWL3945_RFKILL
131 bool "Enable RF kill support in iwl3945 drivers"
132 depends on IWL3945
133
129config IWL3945_SPECTRUM_MEASUREMENT 134config IWL3945_SPECTRUM_MEASUREMENT
130 bool "Enable Spectrum Measurement in iwl3945 drivers" 135 bool "Enable Spectrum Measurement in iwl3945 drivers"
131 depends on IWL3945 136 depends on IWL3945
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index a77497809d97..9c0a09eaca6f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -690,14 +690,9 @@ enum {
690 690
691#endif 691#endif
692 692
693#ifdef CONFIG_IWLWIFI_RFKILL 693#ifdef CONFIG_IWL3945_RFKILL
694struct iwl3945_priv; 694struct iwl3945_priv;
695 695
696struct iwl3945_rfkill_mngr {
697 struct rfkill *rfkill;
698 struct input_dev *input_dev;
699};
700
701void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv); 696void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv);
702void iwl3945_rfkill_unregister(struct iwl3945_priv *priv); 697void iwl3945_rfkill_unregister(struct iwl3945_priv *priv);
703int iwl3945_rfkill_init(struct iwl3945_priv *priv); 698int iwl3945_rfkill_init(struct iwl3945_priv *priv);
@@ -800,8 +795,8 @@ struct iwl3945_priv {
800 struct iwl3945_init_alive_resp card_alive_init; 795 struct iwl3945_init_alive_resp card_alive_init;
801 struct iwl3945_alive_resp card_alive; 796 struct iwl3945_alive_resp card_alive;
802 797
803#ifdef CONFIG_IWLWIFI_RFKILL 798#ifdef CONFIG_IWL3945_RFKILL
804 struct iwl3945_rfkill_mngr rfkill_mngr; 799 struct rfkill *rfkill;
805#endif 800#endif
806 801
807#ifdef CONFIG_IWL3945_LEDS 802#ifdef CONFIG_IWL3945_LEDS
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 8c93f8d56a70..04365b39279c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2285,9 +2285,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2285 2285
2286 iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); 2286 iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
2287 2287
2288 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { 2288 /* check if BAR is needed */
2289 /* TODO: send BAR */ 2289 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
2290 } 2290 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
2291 2291
2292 if (txq->q.read_ptr != (scd_ssn & 0xff)) { 2292 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
2293 int freed, ampdu_q; 2293 int freed, ampdu_q;
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 7cc73e9a711c..717db0d5ffb3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1278,9 +1278,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1278 1278
1279 iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); 1279 iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
1280 1280
1281 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { 1281 /* check if BAR is needed */
1282 /* TODO: send BAR */ 1282 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
1283 } 1283 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1284 1284
1285 if (txq->q.read_ptr != (scd_ssn & 0xff)) { 1285 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
1286 int freed, ampdu_q; 1286 int freed, ampdu_q;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index eb4abe1ebbdb..dafd62c7dfd6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -356,10 +356,19 @@ static inline int iwl_is_init(struct iwl_priv *priv)
356 return test_bit(STATUS_INIT, &priv->status); 356 return test_bit(STATUS_INIT, &priv->status);
357} 357}
358 358
359static inline int iwl_is_rfkill_sw(struct iwl_priv *priv)
360{
361 return test_bit(STATUS_RF_KILL_SW, &priv->status);
362}
363
364static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
365{
366 return test_bit(STATUS_RF_KILL_HW, &priv->status);
367}
368
359static inline int iwl_is_rfkill(struct iwl_priv *priv) 369static inline int iwl_is_rfkill(struct iwl_priv *priv)
360{ 370{
361 return test_bit(STATUS_RF_KILL_HW, &priv->status) || 371 return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv);
362 test_bit(STATUS_RF_KILL_SW, &priv->status);
363} 372}
364 373
365static inline int iwl_is_ready_rf(struct iwl_priv *priv) 374static inline int iwl_is_ready_rf(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index d1289cfc213c..c8d3d97cf48d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -929,7 +929,7 @@ struct iwl_priv {
929 struct iwl_init_alive_resp card_alive_init; 929 struct iwl_init_alive_resp card_alive_init;
930 struct iwl_alive_resp card_alive; 930 struct iwl_alive_resp card_alive;
931#ifdef CONFIG_IWLWIFI_RFKILL 931#ifdef CONFIG_IWLWIFI_RFKILL
932 struct iwl_rfkill_mngr rfkill_mngr; 932 struct rfkill *rfkill;
933#endif 933#endif
934 934
935#ifdef CONFIG_IWLWIFI_LEDS 935#ifdef CONFIG_IWLWIFI_LEDS
@@ -1103,7 +1103,7 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
1103 clear_bit(txq_id, &priv->txq_ctx_active_msk); 1103 clear_bit(txq_id, &priv->txq_ctx_active_msk);
1104} 1104}
1105 1105
1106#ifdef CONFIG_IWLWIF_DEBUG 1106#ifdef CONFIG_IWLWIFI_DEBUG
1107const char *iwl_get_tx_fail_reason(u32 status); 1107const char *iwl_get_tx_fail_reason(u32 status);
1108#else 1108#else
1109static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; } 1109static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index aa9f31eadab2..e5e5846e9f25 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -44,7 +44,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
44 struct iwl_priv *priv = data; 44 struct iwl_priv *priv = data;
45 int err = 0; 45 int err = 0;
46 46
47 if (!priv->rfkill_mngr.rfkill) 47 if (!priv->rfkill)
48 return 0; 48 return 0;
49 49
50 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 50 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -55,20 +55,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
55 55
56 switch (state) { 56 switch (state) {
57 case RFKILL_STATE_UNBLOCKED: 57 case RFKILL_STATE_UNBLOCKED:
58 iwl_radio_kill_sw_enable_radio(priv); 58 if (iwl_is_rfkill_hw(priv)) {
59 /* if HW rf-kill is set dont allow ON state */
60 if (iwl_is_rfkill(priv))
61 err = -EBUSY; 59 err = -EBUSY;
60 goto out_unlock;
61 }
62 iwl_radio_kill_sw_enable_radio(priv);
62 break; 63 break;
63 case RFKILL_STATE_SOFT_BLOCKED: 64 case RFKILL_STATE_SOFT_BLOCKED:
64 iwl_radio_kill_sw_disable_radio(priv); 65 iwl_radio_kill_sw_disable_radio(priv);
65 if (!iwl_is_rfkill(priv))
66 err = -EBUSY;
67 break; 66 break;
68 default: 67 default:
69 IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); 68 IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
70 break; 69 break;
71 } 70 }
71out_unlock:
72 mutex_unlock(&priv->mutex); 72 mutex_unlock(&priv->mutex);
73 73
74 return err; 74 return err;
@@ -82,39 +82,35 @@ int iwl_rfkill_init(struct iwl_priv *priv)
82 BUG_ON(device == NULL); 82 BUG_ON(device == NULL);
83 83
84 IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); 84 IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
85 priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); 85 priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
86 if (!priv->rfkill_mngr.rfkill) { 86 if (!priv->rfkill) {
87 IWL_ERROR("Unable to allocate rfkill device.\n"); 87 IWL_ERROR("Unable to allocate rfkill device.\n");
88 ret = -ENOMEM; 88 ret = -ENOMEM;
89 goto error; 89 goto error;
90 } 90 }
91 91
92 priv->rfkill_mngr.rfkill->name = priv->cfg->name; 92 priv->rfkill->name = priv->cfg->name;
93 priv->rfkill_mngr.rfkill->data = priv; 93 priv->rfkill->data = priv;
94 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; 94 priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
95 priv->rfkill_mngr.rfkill->toggle_radio = iwl_rfkill_soft_rf_kill; 95 priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
96 priv->rfkill_mngr.rfkill->user_claim_unsupported = 1; 96 priv->rfkill->user_claim_unsupported = 1;
97 97
98 priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; 98 priv->rfkill->dev.class->suspend = NULL;
99 priv->rfkill_mngr.rfkill->dev.class->resume = NULL; 99 priv->rfkill->dev.class->resume = NULL;
100 100
101 ret = rfkill_register(priv->rfkill_mngr.rfkill); 101 ret = rfkill_register(priv->rfkill);
102 if (ret) { 102 if (ret) {
103 IWL_ERROR("Unable to register rfkill: %d\n", ret); 103 IWL_ERROR("Unable to register rfkill: %d\n", ret);
104 goto unregister_rfkill; 104 goto free_rfkill;
105 } 105 }
106 106
107 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); 107 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
108 return ret; 108 return ret;
109 109
110unregister_rfkill: 110free_rfkill:
111 rfkill_unregister(priv->rfkill_mngr.rfkill); 111 if (priv->rfkill != NULL)
112 priv->rfkill_mngr.rfkill = NULL; 112 rfkill_free(priv->rfkill);
113 113 priv->rfkill = NULL;
114freed_rfkill:
115 if (priv->rfkill_mngr.rfkill != NULL)
116 rfkill_free(priv->rfkill_mngr.rfkill);
117 priv->rfkill_mngr.rfkill = NULL;
118 114
119error: 115error:
120 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); 116 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
@@ -125,22 +121,27 @@ EXPORT_SYMBOL(iwl_rfkill_init);
125void iwl_rfkill_unregister(struct iwl_priv *priv) 121void iwl_rfkill_unregister(struct iwl_priv *priv)
126{ 122{
127 123
128 if (priv->rfkill_mngr.rfkill) 124 if (priv->rfkill)
129 rfkill_unregister(priv->rfkill_mngr.rfkill); 125 rfkill_unregister(priv->rfkill);
130 126
131 priv->rfkill_mngr.rfkill = NULL; 127 priv->rfkill = NULL;
132} 128}
133EXPORT_SYMBOL(iwl_rfkill_unregister); 129EXPORT_SYMBOL(iwl_rfkill_unregister);
134 130
135/* set rf-kill to the right state. */ 131/* set rf-kill to the right state. */
136void iwl_rfkill_set_hw_state(struct iwl_priv *priv) 132void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
137{ 133{
138 if (!priv->rfkill_mngr.rfkill) 134 if (!priv->rfkill)
139 return; 135 return;
140 136
141 if (!iwl_is_rfkill(priv)) 137 if (iwl_is_rfkill_hw(priv)) {
142 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; 138 rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
139 return;
140 }
141
142 if (!iwl_is_rfkill_sw(priv))
143 rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
143 else 144 else
144 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; 145 rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
145} 146}
146EXPORT_SYMBOL(iwl_rfkill_set_hw_state); 147EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
index 00692d2e9bd8..402fd4c781da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
@@ -33,9 +33,6 @@ struct iwl_priv;
33#include <linux/rfkill.h> 33#include <linux/rfkill.h>
34 34
35#ifdef CONFIG_IWLWIFI_RFKILL 35#ifdef CONFIG_IWLWIFI_RFKILL
36struct iwl_rfkill_mngr {
37 struct rfkill *rfkill;
38};
39 36
40void iwl_rfkill_set_hw_state(struct iwl_priv *priv); 37void iwl_rfkill_set_hw_state(struct iwl_priv *priv);
41void iwl_rfkill_unregister(struct iwl_priv *priv); 38void iwl_rfkill_unregister(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 032641d4c7d1..0be2a71990b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1493,7 +1493,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1493} 1493}
1494EXPORT_SYMBOL(iwl_rx_reply_compressed_ba); 1494EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);
1495 1495
1496#ifdef CONFIG_IWLWIF_DEBUG 1496#ifdef CONFIG_IWLWIFI_DEBUG
1497#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x 1497#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
1498 1498
1499const char *iwl_get_tx_fail_reason(u32 status) 1499const char *iwl_get_tx_fail_reason(u32 status)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index baa1abd5a14d..1a7d18fea89d 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -537,10 +537,20 @@ static inline int iwl3945_is_init(struct iwl3945_priv *priv)
537 return test_bit(STATUS_INIT, &priv->status); 537 return test_bit(STATUS_INIT, &priv->status);
538} 538}
539 539
540static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
541{
542 return test_bit(STATUS_RF_KILL_SW, &priv->status);
543}
544
545static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
546{
547 return test_bit(STATUS_RF_KILL_HW, &priv->status);
548}
549
540static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv) 550static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
541{ 551{
542 return test_bit(STATUS_RF_KILL_HW, &priv->status) || 552 return iwl3945_is_rfkill_hw(priv) ||
543 test_bit(STATUS_RF_KILL_SW, &priv->status); 553 iwl3945_is_rfkill_sw(priv);
544} 554}
545 555
546static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv) 556static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
@@ -6013,12 +6023,11 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
6013 else { 6023 else {
6014 set_bit(STATUS_RF_KILL_HW, &priv->status); 6024 set_bit(STATUS_RF_KILL_HW, &priv->status);
6015 if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { 6025 if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
6016 iwl3945_rfkill_set_hw_state(priv);
6017 IWL_WARNING("Radio disabled by HW RF Kill switch\n"); 6026 IWL_WARNING("Radio disabled by HW RF Kill switch\n");
6018 return -ENODEV; 6027 return -ENODEV;
6019 } 6028 }
6020 } 6029 }
6021 iwl3945_rfkill_set_hw_state(priv); 6030
6022 iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); 6031 iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
6023 6032
6024 rc = iwl3945_hw_nic_init(priv); 6033 rc = iwl3945_hw_nic_init(priv);
@@ -6143,8 +6152,8 @@ static void iwl3945_bg_rf_kill(struct work_struct *work)
6143 "wireless networking to work.\n"); 6152 "wireless networking to work.\n");
6144 } 6153 }
6145 6154
6146 iwl3945_rfkill_set_hw_state(priv);
6147 mutex_unlock(&priv->mutex); 6155 mutex_unlock(&priv->mutex);
6156 iwl3945_rfkill_set_hw_state(priv);
6148} 6157}
6149 6158
6150static void iwl3945_bg_set_monitor(struct work_struct *work) 6159static void iwl3945_bg_set_monitor(struct work_struct *work)
@@ -6398,6 +6407,7 @@ static void iwl3945_bg_up(struct work_struct *data)
6398 mutex_lock(&priv->mutex); 6407 mutex_lock(&priv->mutex);
6399 __iwl3945_up(priv); 6408 __iwl3945_up(priv);
6400 mutex_unlock(&priv->mutex); 6409 mutex_unlock(&priv->mutex);
6410 iwl3945_rfkill_set_hw_state(priv);
6401} 6411}
6402 6412
6403static void iwl3945_bg_restart(struct work_struct *data) 6413static void iwl3945_bg_restart(struct work_struct *data)
@@ -6618,6 +6628,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
6618 6628
6619 mutex_unlock(&priv->mutex); 6629 mutex_unlock(&priv->mutex);
6620 6630
6631 iwl3945_rfkill_set_hw_state(priv);
6632
6621 if (ret) 6633 if (ret)
6622 goto out_release_irq; 6634 goto out_release_irq;
6623 6635
@@ -8276,14 +8288,14 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
8276#endif /* CONFIG_PM */ 8288#endif /* CONFIG_PM */
8277 8289
8278/*************** RFKILL FUNCTIONS **********/ 8290/*************** RFKILL FUNCTIONS **********/
8279#ifdef CONFIG_IWLWIFI_RFKILL 8291#ifdef CONFIG_IWL3945_RFKILL
8280/* software rf-kill from user */ 8292/* software rf-kill from user */
8281static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state) 8293static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
8282{ 8294{
8283 struct iwl3945_priv *priv = data; 8295 struct iwl3945_priv *priv = data;
8284 int err = 0; 8296 int err = 0;
8285 8297
8286 if (!priv->rfkill_mngr.rfkill) 8298 if (!priv->rfkill)
8287 return 0; 8299 return 0;
8288 8300
8289 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 8301 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -8294,20 +8306,20 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
8294 8306
8295 switch (state) { 8307 switch (state) {
8296 case RFKILL_STATE_UNBLOCKED: 8308 case RFKILL_STATE_UNBLOCKED:
8297 iwl3945_radio_kill_sw(priv, 0); 8309 if (iwl3945_is_rfkill_hw(priv)) {
8298 /* if HW rf-kill is set dont allow ON state */
8299 if (iwl3945_is_rfkill(priv))
8300 err = -EBUSY; 8310 err = -EBUSY;
8311 goto out_unlock;
8312 }
8313 iwl3945_radio_kill_sw(priv, 0);
8301 break; 8314 break;
8302 case RFKILL_STATE_SOFT_BLOCKED: 8315 case RFKILL_STATE_SOFT_BLOCKED:
8303 iwl3945_radio_kill_sw(priv, 1); 8316 iwl3945_radio_kill_sw(priv, 1);
8304 if (!iwl3945_is_rfkill(priv))
8305 err = -EBUSY;
8306 break; 8317 break;
8307 default: 8318 default:
8308 IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); 8319 IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
8309 break; 8320 break;
8310 } 8321 }
8322out_unlock:
8311 mutex_unlock(&priv->mutex); 8323 mutex_unlock(&priv->mutex);
8312 8324
8313 return err; 8325 return err;
@@ -8321,64 +8333,35 @@ int iwl3945_rfkill_init(struct iwl3945_priv *priv)
8321 BUG_ON(device == NULL); 8333 BUG_ON(device == NULL);
8322 8334
8323 IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); 8335 IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
8324 priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); 8336 priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
8325 if (!priv->rfkill_mngr.rfkill) { 8337 if (!priv->rfkill) {
8326 IWL_ERROR("Unable to allocate rfkill device.\n"); 8338 IWL_ERROR("Unable to allocate rfkill device.\n");
8327 ret = -ENOMEM; 8339 ret = -ENOMEM;
8328 goto error; 8340 goto error;
8329 } 8341 }
8330 8342
8331 priv->rfkill_mngr.rfkill->name = priv->cfg->name; 8343 priv->rfkill->name = priv->cfg->name;
8332 priv->rfkill_mngr.rfkill->data = priv; 8344 priv->rfkill->data = priv;
8333 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; 8345 priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
8334 priv->rfkill_mngr.rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill; 8346 priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
8335 priv->rfkill_mngr.rfkill->user_claim_unsupported = 1; 8347 priv->rfkill->user_claim_unsupported = 1;
8336
8337 priv->rfkill_mngr.rfkill->dev.class->suspend = NULL;
8338 priv->rfkill_mngr.rfkill->dev.class->resume = NULL;
8339 8348
8340 priv->rfkill_mngr.input_dev = input_allocate_device(); 8349 priv->rfkill->dev.class->suspend = NULL;
8341 if (!priv->rfkill_mngr.input_dev) { 8350 priv->rfkill->dev.class->resume = NULL;
8342 IWL_ERROR("Unable to allocate rfkill input device.\n");
8343 ret = -ENOMEM;
8344 goto freed_rfkill;
8345 }
8346 8351
8347 priv->rfkill_mngr.input_dev->name = priv->cfg->name; 8352 ret = rfkill_register(priv->rfkill);
8348 priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy);
8349 priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST;
8350 priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor;
8351 priv->rfkill_mngr.input_dev->dev.parent = device;
8352 priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY);
8353 set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
8354
8355 ret = rfkill_register(priv->rfkill_mngr.rfkill);
8356 if (ret) { 8353 if (ret) {
8357 IWL_ERROR("Unable to register rfkill: %d\n", ret); 8354 IWL_ERROR("Unable to register rfkill: %d\n", ret);
8358 goto free_input_dev; 8355 goto freed_rfkill;
8359 }
8360
8361 ret = input_register_device(priv->rfkill_mngr.input_dev);
8362 if (ret) {
8363 IWL_ERROR("Unable to register rfkill input device: %d\n", ret);
8364 goto unregister_rfkill;
8365 } 8356 }
8366 8357
8367 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); 8358 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
8368 return ret; 8359 return ret;
8369 8360
8370unregister_rfkill:
8371 rfkill_unregister(priv->rfkill_mngr.rfkill);
8372 priv->rfkill_mngr.rfkill = NULL;
8373
8374free_input_dev:
8375 input_free_device(priv->rfkill_mngr.input_dev);
8376 priv->rfkill_mngr.input_dev = NULL;
8377
8378freed_rfkill: 8361freed_rfkill:
8379 if (priv->rfkill_mngr.rfkill != NULL) 8362 if (priv->rfkill != NULL)
8380 rfkill_free(priv->rfkill_mngr.rfkill); 8363 rfkill_free(priv->rfkill);
8381 priv->rfkill_mngr.rfkill = NULL; 8364 priv->rfkill = NULL;
8382 8365
8383error: 8366error:
8384 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); 8367 IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
@@ -8387,28 +8370,28 @@ error:
8387 8370
8388void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) 8371void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
8389{ 8372{
8373 if (priv->rfkill)
8374 rfkill_unregister(priv->rfkill);
8390 8375
8391 if (priv->rfkill_mngr.input_dev) 8376 priv->rfkill = NULL;
8392 input_unregister_device(priv->rfkill_mngr.input_dev);
8393
8394 if (priv->rfkill_mngr.rfkill)
8395 rfkill_unregister(priv->rfkill_mngr.rfkill);
8396
8397 priv->rfkill_mngr.input_dev = NULL;
8398 priv->rfkill_mngr.rfkill = NULL;
8399} 8377}
8400 8378
8401/* set rf-kill to the right state. */ 8379/* set rf-kill to the right state. */
8402void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) 8380void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
8403{ 8381{
8404 8382
8405 if (!priv->rfkill_mngr.rfkill) 8383 if (!priv->rfkill)
8384 return;
8385
8386 if (iwl3945_is_rfkill_hw(priv)) {
8387 rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
8406 return; 8388 return;
8389 }
8407 8390
8408 if (!iwl3945_is_rfkill(priv)) 8391 if (!iwl3945_is_rfkill_sw(priv))
8409 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; 8392 rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
8410 else 8393 else
8411 priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; 8394 rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
8412} 8395}
8413#endif 8396#endif
8414 8397
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 60b7a6498fe8..7f65d9123b2a 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -2187,13 +2187,11 @@ static int __iwl4965_up(struct iwl_priv *priv)
2187 2187
2188 if (!test_bit(STATUS_IN_SUSPEND, &priv->status) && 2188 if (!test_bit(STATUS_IN_SUSPEND, &priv->status) &&
2189 iwl_is_rfkill(priv)) { 2189 iwl_is_rfkill(priv)) {
2190 iwl_rfkill_set_hw_state(priv);
2191 IWL_WARNING("Radio disabled by %s RF Kill switch\n", 2190 IWL_WARNING("Radio disabled by %s RF Kill switch\n",
2192 test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); 2191 test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
2193 return -ENODEV; 2192 return -ENODEV;
2194 } 2193 }
2195 2194
2196 iwl_rfkill_set_hw_state(priv);
2197 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 2195 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2198 2196
2199 ret = priv->cfg->ops->lib->alloc_shared_mem(priv); 2197 ret = priv->cfg->ops->lib->alloc_shared_mem(priv);
@@ -2330,9 +2328,8 @@ static void iwl4965_bg_rf_kill(struct work_struct *work)
2330 "Kill switch must be turned off for " 2328 "Kill switch must be turned off for "
2331 "wireless networking to work.\n"); 2329 "wireless networking to work.\n");
2332 } 2330 }
2333 iwl_rfkill_set_hw_state(priv);
2334
2335 mutex_unlock(&priv->mutex); 2331 mutex_unlock(&priv->mutex);
2332 iwl_rfkill_set_hw_state(priv);
2336} 2333}
2337 2334
2338static void iwl4965_bg_set_monitor(struct work_struct *work) 2335static void iwl4965_bg_set_monitor(struct work_struct *work)
@@ -2390,6 +2387,7 @@ static void iwl4965_bg_up(struct work_struct *data)
2390 mutex_lock(&priv->mutex); 2387 mutex_lock(&priv->mutex);
2391 __iwl4965_up(priv); 2388 __iwl4965_up(priv);
2392 mutex_unlock(&priv->mutex); 2389 mutex_unlock(&priv->mutex);
2390 iwl_rfkill_set_hw_state(priv);
2393} 2391}
2394 2392
2395static void iwl4965_bg_restart(struct work_struct *data) 2393static void iwl4965_bg_restart(struct work_struct *data)
@@ -2604,6 +2602,8 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
2604 2602
2605 mutex_unlock(&priv->mutex); 2603 mutex_unlock(&priv->mutex);
2606 2604
2605 iwl_rfkill_set_hw_state(priv);
2606
2607 if (ret) 2607 if (ret)
2608 goto out_release_irq; 2608 goto out_release_irq;
2609 2609
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 3a9b1d72caf8..d485a86bba75 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -36,9 +36,7 @@ config RT2X00_LIB_FIRMWARE
36config RT2X00_LIB_RFKILL 36config RT2X00_LIB_RFKILL
37 boolean 37 boolean
38 depends on RT2X00_LIB 38 depends on RT2X00_LIB
39 depends on INPUT
40 select RFKILL 39 select RFKILL
41 select INPUT_POLLDEV
42 40
43config RT2X00_LIB_LEDS 41config RT2X00_LIB_LEDS
44 boolean 42 boolean
@@ -57,7 +55,7 @@ config RT2400PCI
57 55
58config RT2400PCI_RFKILL 56config RT2400PCI_RFKILL
59 bool "Ralink rt2400 rfkill support" 57 bool "Ralink rt2400 rfkill support"
60 depends on RT2400PCI && INPUT 58 depends on RT2400PCI
61 select RT2X00_LIB_RFKILL 59 select RT2X00_LIB_RFKILL
62 ---help--- 60 ---help---
63 This adds support for integrated rt2400 hardware that features a 61 This adds support for integrated rt2400 hardware that features a
@@ -85,7 +83,7 @@ config RT2500PCI
85 83
86config RT2500PCI_RFKILL 84config RT2500PCI_RFKILL
87 bool "Ralink rt2500 rfkill support" 85 bool "Ralink rt2500 rfkill support"
88 depends on RT2500PCI && INPUT 86 depends on RT2500PCI
89 select RT2X00_LIB_RFKILL 87 select RT2X00_LIB_RFKILL
90 ---help--- 88 ---help---
91 This adds support for integrated rt2500 hardware that features a 89 This adds support for integrated rt2500 hardware that features a
@@ -115,7 +113,7 @@ config RT61PCI
115 113
116config RT61PCI_RFKILL 114config RT61PCI_RFKILL
117 bool "Ralink rt2501/rt61 rfkill support" 115 bool "Ralink rt2501/rt61 rfkill support"
118 depends on RT61PCI && INPUT 116 depends on RT61PCI
119 select RT2X00_LIB_RFKILL 117 select RT2X00_LIB_RFKILL
120 ---help--- 118 ---help---
121 This adds support for integrated rt61 hardware that features a 119 This adds support for integrated rt61 hardware that features a
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index b3dffcfed835..ee953ca0c6a3 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1087,14 +1087,20 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
1087static void rt2400pci_fill_rxdone(struct queue_entry *entry, 1087static void rt2400pci_fill_rxdone(struct queue_entry *entry,
1088 struct rxdone_entry_desc *rxdesc) 1088 struct rxdone_entry_desc *rxdesc)
1089{ 1089{
1090 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1090 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1091 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1091 u32 word0; 1092 u32 word0;
1092 u32 word2; 1093 u32 word2;
1093 u32 word3; 1094 u32 word3;
1095 u32 word4;
1096 u64 tsf;
1097 u32 rx_low;
1098 u32 rx_high;
1094 1099
1095 rt2x00_desc_read(entry_priv->desc, 0, &word0); 1100 rt2x00_desc_read(entry_priv->desc, 0, &word0);
1096 rt2x00_desc_read(entry_priv->desc, 2, &word2); 1101 rt2x00_desc_read(entry_priv->desc, 2, &word2);
1097 rt2x00_desc_read(entry_priv->desc, 3, &word3); 1102 rt2x00_desc_read(entry_priv->desc, 3, &word3);
1103 rt2x00_desc_read(entry_priv->desc, 4, &word4);
1098 1104
1099 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) 1105 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
1100 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 1106 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
@@ -1102,10 +1108,27 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
1102 rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; 1108 rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
1103 1109
1104 /* 1110 /*
1111 * We only get the lower 32bits from the timestamp,
1112 * to get the full 64bits we must complement it with
1113 * the timestamp from get_tsf().
1114 * Note that when a wraparound of the lower 32bits
1115 * has occurred between the frame arrival and the get_tsf()
1116 * call, we must decrease the higher 32bits with 1 to get
1117 * to correct value.
1118 */
1119 tsf = rt2x00dev->ops->hw->get_tsf(rt2x00dev->hw);
1120 rx_low = rt2x00_get_field32(word4, RXD_W4_RX_END_TIME);
1121 rx_high = upper_32_bits(tsf);
1122
1123 if ((u32)tsf <= rx_low)
1124 rx_high--;
1125
1126 /*
1105 * Obtain the status about this packet. 1127 * Obtain the status about this packet.
1106 * The signal is the PLCP value, and needs to be stripped 1128 * The signal is the PLCP value, and needs to be stripped
1107 * of the preamble bit (0x08). 1129 * of the preamble bit (0x08).
1108 */ 1130 */
1131 rxdesc->timestamp = ((u64)rx_high << 32) | rx_low;
1109 rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; 1132 rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08;
1110 rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - 1133 rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) -
1111 entry->queue->rt2x00dev->rssi_offset; 1134 entry->queue->rt2x00dev->rssi_offset;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index cb648c30a5b3..42f376929ea9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -751,7 +751,7 @@
751#define LEDCSR_LED_DEFAULT FIELD32(0x00100000) 751#define LEDCSR_LED_DEFAULT FIELD32(0x00100000)
752 752
753/* 753/*
754 * AES control register. 754 * SECCSR3: AES control register.
755 */ 755 */
756#define SECCSR3 0x00fc 756#define SECCSR3 0x00fc
757 757
@@ -895,7 +895,7 @@
895#define ARTCSR2_ACK_CTS_54MBS FIELD32(0xff000000) 895#define ARTCSR2_ACK_CTS_54MBS FIELD32(0xff000000)
896 896
897/* 897/*
898 * SECCSR1_RT2509: WEP control register. 898 * SECCSR1: WEP control register.
899 * KICK_ENCRYPT: Kick encryption engine, self-clear. 899 * KICK_ENCRYPT: Kick encryption engine, self-clear.
900 * ONE_SHOT: 0: ring mode, 1: One shot only mode. 900 * ONE_SHOT: 0: ring mode, 1: One shot only mode.
901 * DESC_ADDRESS: Descriptor physical address of frame. 901 * DESC_ADDRESS: Descriptor physical address of frame.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 3e21fdf2b00f..4769ffeb4cc6 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -209,7 +209,7 @@
209#define MAC_CSR21_OFF_PERIOD FIELD16(0xff00) 209#define MAC_CSR21_OFF_PERIOD FIELD16(0xff00)
210 210
211/* 211/*
212 * Collision window control register. 212 * MAC_CSR22: Collision window control register.
213 */ 213 */
214#define MAC_CSR22 0x042c 214#define MAC_CSR22 0x042c
215 215
@@ -296,7 +296,7 @@
296#define TXRX_CSR7_BBP_ID1_VALID FIELD16(0x8000) 296#define TXRX_CSR7_BBP_ID1_VALID FIELD16(0x8000)
297 297
298/* 298/*
299 * TXRX_CSR5: OFDM TX BBP ID1. 299 * TXRX_CSR8: OFDM TX BBP ID1.
300 */ 300 */
301#define TXRX_CSR8 0x0450 301#define TXRX_CSR8 0x0450
302#define TXRX_CSR8_BBP_ID0 FIELD16(0x007f) 302#define TXRX_CSR8_BBP_ID0 FIELD16(0x007f)
@@ -370,7 +370,14 @@
370 */ 370 */
371 371
372/* 372/*
373 * SEC_CSR0-SEC_CSR7: Shared key 0, word 0-7 373 * SEC_CSR0: Shared key 0, word 0
374 * SEC_CSR1: Shared key 0, word 1
375 * SEC_CSR2: Shared key 0, word 2
376 * SEC_CSR3: Shared key 0, word 3
377 * SEC_CSR4: Shared key 0, word 4
378 * SEC_CSR5: Shared key 0, word 5
379 * SEC_CSR6: Shared key 0, word 6
380 * SEC_CSR7: Shared key 0, word 7
374 */ 381 */
375#define SEC_CSR0 0x0480 382#define SEC_CSR0 0x0480
376#define SEC_CSR1 0x0482 383#define SEC_CSR1 0x0482
@@ -382,7 +389,14 @@
382#define SEC_CSR7 0x048e 389#define SEC_CSR7 0x048e
383 390
384/* 391/*
385 * SEC_CSR8-SEC_CSR15: Shared key 1, word 0-7 392 * SEC_CSR8: Shared key 1, word 0
393 * SEC_CSR9: Shared key 1, word 1
394 * SEC_CSR10: Shared key 1, word 2
395 * SEC_CSR11: Shared key 1, word 3
396 * SEC_CSR12: Shared key 1, word 4
397 * SEC_CSR13: Shared key 1, word 5
398 * SEC_CSR14: Shared key 1, word 6
399 * SEC_CSR15: Shared key 1, word 7
386 */ 400 */
387#define SEC_CSR8 0x0490 401#define SEC_CSR8 0x0490
388#define SEC_CSR9 0x0492 402#define SEC_CSR9 0x0492
@@ -394,7 +408,14 @@
394#define SEC_CSR15 0x049e 408#define SEC_CSR15 0x049e
395 409
396/* 410/*
397 * SEC_CSR16-SEC_CSR23: Shared key 2, word 0-7 411 * SEC_CSR16: Shared key 2, word 0
412 * SEC_CSR17: Shared key 2, word 1
413 * SEC_CSR18: Shared key 2, word 2
414 * SEC_CSR19: Shared key 2, word 3
415 * SEC_CSR20: Shared key 2, word 4
416 * SEC_CSR21: Shared key 2, word 5
417 * SEC_CSR22: Shared key 2, word 6
418 * SEC_CSR23: Shared key 2, word 7
398 */ 419 */
399#define SEC_CSR16 0x04a0 420#define SEC_CSR16 0x04a0
400#define SEC_CSR17 0x04a2 421#define SEC_CSR17 0x04a2
@@ -406,7 +427,14 @@
406#define SEC_CSR23 0x04ae 427#define SEC_CSR23 0x04ae
407 428
408/* 429/*
409 * SEC_CSR24-SEC_CSR31: Shared key 3, word 0-7 430 * SEC_CSR24: Shared key 3, word 0
431 * SEC_CSR25: Shared key 3, word 1
432 * SEC_CSR26: Shared key 3, word 2
433 * SEC_CSR27: Shared key 3, word 3
434 * SEC_CSR28: Shared key 3, word 4
435 * SEC_CSR29: Shared key 3, word 5
436 * SEC_CSR30: Shared key 3, word 6
437 * SEC_CSR31: Shared key 3, word 7
410 */ 438 */
411#define SEC_CSR24 0x04b0 439#define SEC_CSR24 0x04b0
412#define SEC_CSR25 0x04b2 440#define SEC_CSR25 0x04b2
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 6842464dcf3e..c07d9ef383f0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -649,7 +649,7 @@ struct rt2x00_dev {
649#define RFKILL_STATE_ALLOCATED 1 649#define RFKILL_STATE_ALLOCATED 1
650#define RFKILL_STATE_REGISTERED 2 650#define RFKILL_STATE_REGISTERED 2
651 struct rfkill *rfkill; 651 struct rfkill *rfkill;
652 struct input_polled_dev *poll_dev; 652 struct delayed_work rfkill_work;
653#endif /* CONFIG_RT2X00_LIB_RFKILL */ 653#endif /* CONFIG_RT2X00_LIB_RFKILL */
654 654
655 /* 655 /*
@@ -787,8 +787,10 @@ struct rt2x00_dev {
787 787
788 /* 788 /*
789 * Scheduled work. 789 * Scheduled work.
790 * NOTE: intf_work will use ieee80211_iterate_active_interfaces()
791 * which means it cannot be placed on the hw->workqueue
792 * due to RTNL locking requirements.
790 */ 793 */
791 struct workqueue_struct *workqueue;
792 struct work_struct intf_work; 794 struct work_struct intf_work;
793 struct work_struct filter_work; 795 struct work_struct filter_work;
794 796
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index ae8ab71fe474..b48c04e80a38 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -74,7 +74,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
74 74
75 rt2x00lib_reset_link_tuner(rt2x00dev); 75 rt2x00lib_reset_link_tuner(rt2x00dev);
76 76
77 queue_delayed_work(rt2x00dev->workqueue, 77 queue_delayed_work(rt2x00dev->hw->workqueue,
78 &rt2x00dev->link.work, LINK_TUNE_INTERVAL); 78 &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
79} 79}
80 80
@@ -392,7 +392,7 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
392 * Increase tuner counter, and reschedule the next link tuner run. 392 * Increase tuner counter, and reschedule the next link tuner run.
393 */ 393 */
394 rt2x00dev->link.count++; 394 rt2x00dev->link.count++;
395 queue_delayed_work(rt2x00dev->workqueue, 395 queue_delayed_work(rt2x00dev->hw->workqueue,
396 &rt2x00dev->link.work, LINK_TUNE_INTERVAL); 396 &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
397} 397}
398 398
@@ -496,7 +496,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
496 rt2x00lib_beacondone_iter, 496 rt2x00lib_beacondone_iter,
497 rt2x00dev); 497 rt2x00dev);
498 498
499 queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); 499 schedule_work(&rt2x00dev->intf_work);
500} 500}
501EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); 501EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
502 502
@@ -664,6 +664,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
664 664
665 rt2x00dev->link.qual.rx_success++; 665 rt2x00dev->link.qual.rx_success++;
666 666
667 rx_status->mactime = rxdesc.timestamp;
667 rx_status->rate_idx = idx; 668 rx_status->rate_idx = idx;
668 rx_status->qual = 669 rx_status->qual =
669 rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi); 670 rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi);
@@ -1064,10 +1065,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1064 /* 1065 /*
1065 * Initialize configuration work. 1066 * Initialize configuration work.
1066 */ 1067 */
1067 rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib");
1068 if (!rt2x00dev->workqueue)
1069 goto exit;
1070
1071 INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); 1068 INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
1072 INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); 1069 INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
1073 INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); 1070 INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
@@ -1128,13 +1125,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1128 rt2x00leds_unregister(rt2x00dev); 1125 rt2x00leds_unregister(rt2x00dev);
1129 1126
1130 /* 1127 /*
1131 * Stop all queued work. Note that most tasks will already be halted
1132 * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize().
1133 */
1134 flush_workqueue(rt2x00dev->workqueue);
1135 destroy_workqueue(rt2x00dev->workqueue);
1136
1137 /*
1138 * Free ieee80211_hw memory. 1128 * Free ieee80211_hw memory.
1139 */ 1129 */
1140 rt2x00lib_remove_hw(rt2x00dev); 1130 rt2x00lib_remove_hw(rt2x00dev);
@@ -1179,7 +1169,6 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
1179 * Suspend/disable extra components. 1169 * Suspend/disable extra components.
1180 */ 1170 */
1181 rt2x00leds_suspend(rt2x00dev); 1171 rt2x00leds_suspend(rt2x00dev);
1182 rt2x00rfkill_suspend(rt2x00dev);
1183 rt2x00debug_deregister(rt2x00dev); 1172 rt2x00debug_deregister(rt2x00dev);
1184 1173
1185exit: 1174exit:
@@ -1235,7 +1224,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1235 * Restore/enable extra components. 1224 * Restore/enable extra components.
1236 */ 1225 */
1237 rt2x00debug_register(rt2x00dev); 1226 rt2x00debug_register(rt2x00dev);
1238 rt2x00rfkill_resume(rt2x00dev);
1239 rt2x00leds_resume(rt2x00dev); 1227 rt2x00leds_resume(rt2x00dev);
1240 1228
1241 /* 1229 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 1d1f0749375e..eae5ce1d4de3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -33,7 +33,7 @@
33 * Both the link tuner as the rfkill will be called once per second. 33 * Both the link tuner as the rfkill will be called once per second.
34 */ 34 */
35#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) ) 35#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) )
36#define RFKILL_POLL_INTERVAL ( 1000 ) 36#define RFKILL_POLL_INTERVAL ( round_jiffies_relative(HZ) )
37 37
38/* 38/*
39 * rt2x00_rate: Per rate device information 39 * rt2x00_rate: Per rate device information
@@ -204,8 +204,6 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev);
204void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev); 204void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev);
205void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev); 205void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev);
206void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev); 206void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev);
207void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev);
208void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev);
209#else 207#else
210static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) 208static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
211{ 209{
@@ -222,14 +220,6 @@ static inline void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
222static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) 220static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
223{ 221{
224} 222}
225
226static inline void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev)
227{
228}
229
230static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
231{
232}
233#endif /* CONFIG_RT2X00_LIB_RFKILL */ 223#endif /* CONFIG_RT2X00_LIB_RFKILL */
234 224
235/* 225/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 1253da89295b..3a1fb6d47e5d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -431,7 +431,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
431 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) 431 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
432 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); 432 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
433 else 433 else
434 queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work); 434 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
435} 435}
436EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); 436EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
437 437
@@ -512,7 +512,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
512 memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); 512 memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
513 if (delayed) { 513 if (delayed) {
514 intf->delayed_flags |= delayed; 514 intf->delayed_flags |= delayed;
515 queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); 515 schedule_work(&rt2x00dev->intf_work);
516 } 516 }
517 spin_unlock(&intf->lock); 517 spin_unlock(&intf->lock);
518} 518}
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 8e86611791f0..3ddce538ef4a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -45,10 +45,11 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
45 frame_size = entry->queue->data_size + entry->queue->desc_size; 45 frame_size = entry->queue->data_size + entry->queue->desc_size;
46 46
47 /* 47 /*
48 * Reserve a few bytes extra headroom to allow drivers some moving 48 * The payload should be aligned to a 4-byte boundary,
49 * space (e.g. for alignment), while keeping the skb aligned. 49 * this means we need at least 3 bytes for moving the frame
50 * into the correct offset.
50 */ 51 */
51 reserved_size = 8; 52 reserved_size = 4;
52 53
53 /* 54 /*
54 * Allocate skbuffer. 55 * Allocate skbuffer.
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 5dd9cca3c62c..8945945c892e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -146,6 +146,7 @@ enum rxdone_entry_desc_flags {
146 * 146 *
147 * Summary of information that has been read from the RX frame descriptor. 147 * Summary of information that has been read from the RX frame descriptor.
148 * 148 *
149 * @timestamp: RX Timestamp
149 * @signal: Signal of the received frame. 150 * @signal: Signal of the received frame.
150 * @rssi: RSSI of the received frame. 151 * @rssi: RSSI of the received frame.
151 * @size: Data size of the received frame. 152 * @size: Data size of the received frame.
@@ -154,6 +155,7 @@ enum rxdone_entry_desc_flags {
154 155
155 */ 156 */
156struct rxdone_entry_desc { 157struct rxdone_entry_desc {
158 u64 timestamp;
157 int signal; 159 int signal;
158 int rssi; 160 int rssi;
159 int size; 161 int size;
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index 207281cfa8b7..04b29716d356 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -23,7 +23,6 @@
23 Abstract: rt2x00 rfkill routines. 23 Abstract: rt2x00 rfkill routines.
24 */ 24 */
25 25
26#include <linux/input-polldev.h>
27#include <linux/kernel.h> 26#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/rfkill.h> 28#include <linux/rfkill.h>
@@ -61,15 +60,35 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
61 return retval; 60 return retval;
62} 61}
63 62
64static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) 63static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state)
65{ 64{
66 struct rt2x00_dev *rt2x00dev = poll_dev->private; 65 struct rt2x00_dev *rt2x00dev = data;
67 int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
68 66
69 if (rt2x00dev->rfkill->state != state) { 67 *state = rt2x00dev->rfkill->state;
70 input_report_key(poll_dev->input, KEY_WLAN, 1); 68
71 input_report_key(poll_dev->input, KEY_WLAN, 0); 69 return 0;
72 } 70}
71
72static void rt2x00rfkill_poll(struct work_struct *work)
73{
74 struct rt2x00_dev *rt2x00dev =
75 container_of(work, struct rt2x00_dev, rfkill_work.work);
76 int state;
77
78 if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
79 return;
80
81 /*
82 * rfkill_poll reports 1 when the key has been pressed and the
83 * radio should be blocked.
84 */
85 state = !rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
86 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
87
88 rfkill_force_state(rt2x00dev->rfkill, state);
89
90 queue_delayed_work(rt2x00dev->hw->workqueue,
91 &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL);
73} 92}
74 93
75void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) 94void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -83,12 +102,6 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
83 return; 102 return;
84 } 103 }
85 104
86 if (input_register_polled_device(rt2x00dev->poll_dev)) {
87 ERROR(rt2x00dev, "Failed to register polled device.\n");
88 rfkill_unregister(rt2x00dev->rfkill);
89 return;
90 }
91
92 __set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); 105 __set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
93 106
94 /* 107 /*
@@ -96,7 +109,7 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
96 * and correctly sends the signal to the rfkill layer about this 109 * and correctly sends the signal to the rfkill layer about this
97 * state. 110 * state.
98 */ 111 */
99 rt2x00rfkill_poll(rt2x00dev->poll_dev); 112 rt2x00rfkill_poll(&rt2x00dev->rfkill_work.work);
100} 113}
101 114
102void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) 115void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
@@ -105,38 +118,13 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
105 !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) 118 !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
106 return; 119 return;
107 120
108 input_unregister_polled_device(rt2x00dev->poll_dev); 121 cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
122
109 rfkill_unregister(rt2x00dev->rfkill); 123 rfkill_unregister(rt2x00dev->rfkill);
110 124
111 __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); 125 __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
112} 126}
113 127
114static struct input_polled_dev *
115rt2x00rfkill_allocate_polldev(struct rt2x00_dev *rt2x00dev)
116{
117 struct input_polled_dev *poll_dev;
118
119 poll_dev = input_allocate_polled_device();
120 if (!poll_dev)
121 return NULL;
122
123 poll_dev->private = rt2x00dev;
124 poll_dev->poll = rt2x00rfkill_poll;
125 poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
126
127 poll_dev->input->name = rt2x00dev->ops->name;
128 poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
129 poll_dev->input->id.bustype = BUS_HOST;
130 poll_dev->input->id.vendor = 0x1814;
131 poll_dev->input->id.product = rt2x00dev->chip.rt;
132 poll_dev->input->id.version = rt2x00dev->chip.rev;
133 poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
134 poll_dev->input->evbit[0] = BIT(EV_KEY);
135 set_bit(KEY_WLAN, poll_dev->input->keybit);
136
137 return poll_dev;
138}
139
140void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) 128void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
141{ 129{
142 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) 130 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
@@ -153,14 +141,9 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
153 rt2x00dev->rfkill->data = rt2x00dev; 141 rt2x00dev->rfkill->data = rt2x00dev;
154 rt2x00dev->rfkill->state = -1; 142 rt2x00dev->rfkill->state = -1;
155 rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; 143 rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
144 rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
156 145
157 rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev); 146 INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
158 if (!rt2x00dev->poll_dev) {
159 ERROR(rt2x00dev, "Failed to allocate polled device.\n");
160 rfkill_free(rt2x00dev->rfkill);
161 rt2x00dev->rfkill = NULL;
162 return;
163 }
164 147
165 return; 148 return;
166} 149}
@@ -171,32 +154,8 @@ void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
171 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) 154 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
172 return; 155 return;
173 156
174 input_free_polled_device(rt2x00dev->poll_dev); 157 cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
175 rt2x00dev->poll_dev = NULL;
176 158
177 rfkill_free(rt2x00dev->rfkill); 159 rfkill_free(rt2x00dev->rfkill);
178 rt2x00dev->rfkill = NULL; 160 rt2x00dev->rfkill = NULL;
179} 161}
180
181void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev)
182{
183 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
184 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
185 return;
186
187 input_free_polled_device(rt2x00dev->poll_dev);
188 rt2x00dev->poll_dev = NULL;
189}
190
191void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
192{
193 if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
194 !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
195 return;
196
197 rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev);
198 if (!rt2x00dev->poll_dev) {
199 ERROR(rt2x00dev, "Failed to allocate polled device.\n");
200 return;
201 }
202}
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
index a0cfb666de0e..3afb49f8866a 100644
--- a/drivers/net/wireless/rtl8187.h
+++ b/drivers/net/wireless/rtl8187.h
@@ -44,17 +44,48 @@ struct rtl8187_rx_hdr {
44 __le64 mac_time; 44 __le64 mac_time;
45} __attribute__((packed)); 45} __attribute__((packed));
46 46
47struct rtl8187_tx_hdr { 47struct rtl8187b_rx_hdr {
48 __le32 flags; 48 __le32 flags;
49 __le64 mac_time;
50 u8 noise;
51 u8 signal;
52 u8 agc;
53 u8 reserved;
54 __le32 unused;
55} __attribute__((packed));
56
57/* {rtl8187,rtl8187b}_tx_info is in skb */
58
59/* Tx flags are common between rtl8187 and rtl8187b */
49#define RTL8187_TX_FLAG_NO_ENCRYPT (1 << 15) 60#define RTL8187_TX_FLAG_NO_ENCRYPT (1 << 15)
50#define RTL8187_TX_FLAG_MORE_FRAG (1 << 17) 61#define RTL8187_TX_FLAG_MORE_FRAG (1 << 17)
51#define RTL8187_TX_FLAG_CTS (1 << 18) 62#define RTL8187_TX_FLAG_CTS (1 << 18)
52#define RTL8187_TX_FLAG_RTS (1 << 23) 63#define RTL8187_TX_FLAG_RTS (1 << 23)
64
65struct rtl8187_tx_hdr {
66 __le32 flags;
53 __le16 rts_duration; 67 __le16 rts_duration;
54 __le16 len; 68 __le16 len;
55 __le32 retry; 69 __le32 retry;
56} __attribute__((packed)); 70} __attribute__((packed));
57 71
72struct rtl8187b_tx_hdr {
73 __le32 flags;
74 __le16 rts_duration;
75 __le16 len;
76 __le32 unused_1;
77 __le16 unused_2;
78 __le16 tx_duration;
79 __le32 unused_3;
80 __le32 retry;
81 __le32 unused_4[2];
82} __attribute__((packed));
83
84enum {
85 DEVICE_RTL8187,
86 DEVICE_RTL8187B
87};
88
58struct rtl8187_priv { 89struct rtl8187_priv {
59 /* common between rtl818x drivers */ 90 /* common between rtl818x drivers */
60 struct rtl818x_csr *map; 91 struct rtl818x_csr *map;
@@ -70,70 +101,120 @@ struct rtl8187_priv {
70 u32 rx_conf; 101 u32 rx_conf;
71 u16 txpwr_base; 102 u16 txpwr_base;
72 u8 asic_rev; 103 u8 asic_rev;
104 u8 is_rtl8187b;
105 enum {
106 RTL8187BvB,
107 RTL8187BvD,
108 RTL8187BvE
109 } hw_rev;
73 struct sk_buff_head rx_queue; 110 struct sk_buff_head rx_queue;
111 u8 signal;
112 u8 quality;
113 u8 noise;
74}; 114};
75 115
76void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); 116void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
77 117
78static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr) 118static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv,
119 u8 *addr, u8 idx)
79{ 120{
80 u8 val; 121 u8 val;
81 122
82 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), 123 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
83 RTL8187_REQ_GET_REG, RTL8187_REQT_READ, 124 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
84 (unsigned long)addr, 0, &val, sizeof(val), HZ / 2); 125 (unsigned long)addr, idx & 0x03, &val,
126 sizeof(val), HZ / 2);
85 127
86 return val; 128 return val;
87} 129}
88 130
89static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr) 131static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
132{
133 return rtl818x_ioread8_idx(priv, addr, 0);
134}
135
136static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv,
137 __le16 *addr, u8 idx)
90{ 138{
91 __le16 val; 139 __le16 val;
92 140
93 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), 141 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
94 RTL8187_REQ_GET_REG, RTL8187_REQT_READ, 142 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
95 (unsigned long)addr, 0, &val, sizeof(val), HZ / 2); 143 (unsigned long)addr, idx & 0x03, &val,
144 sizeof(val), HZ / 2);
96 145
97 return le16_to_cpu(val); 146 return le16_to_cpu(val);
98} 147}
99 148
100static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr) 149static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
150{
151 return rtl818x_ioread16_idx(priv, addr, 0);
152}
153
154static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv,
155 __le32 *addr, u8 idx)
101{ 156{
102 __le32 val; 157 __le32 val;
103 158
104 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), 159 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
105 RTL8187_REQ_GET_REG, RTL8187_REQT_READ, 160 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
106 (unsigned long)addr, 0, &val, sizeof(val), HZ / 2); 161 (unsigned long)addr, idx & 0x03, &val,
162 sizeof(val), HZ / 2);
107 163
108 return le32_to_cpu(val); 164 return le32_to_cpu(val);
109} 165}
110 166
111static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, 167static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
112 u8 *addr, u8 val) 168{
169 return rtl818x_ioread32_idx(priv, addr, 0);
170}
171
172static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv,
173 u8 *addr, u8 val, u8 idx)
113{ 174{
114 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 175 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
115 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, 176 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
116 (unsigned long)addr, 0, &val, sizeof(val), HZ / 2); 177 (unsigned long)addr, idx & 0x03, &val,
178 sizeof(val), HZ / 2);
179}
180
181static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val)
182{
183 rtl818x_iowrite8_idx(priv, addr, val, 0);
117} 184}
118 185
119static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, 186static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv,
120 __le16 *addr, u16 val) 187 __le16 *addr, u16 val, u8 idx)
121{ 188{
122 __le16 buf = cpu_to_le16(val); 189 __le16 buf = cpu_to_le16(val);
123 190
124 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 191 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
125 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, 192 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
126 (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2); 193 (unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
194 HZ / 2);
127} 195}
128 196
129static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, 197static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr,
130 __le32 *addr, u32 val) 198 u16 val)
199{
200 rtl818x_iowrite16_idx(priv, addr, val, 0);
201}
202
203static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv,
204 __le32 *addr, u32 val, u8 idx)
131{ 205{
132 __le32 buf = cpu_to_le32(val); 206 __le32 buf = cpu_to_le32(val);
133 207
134 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), 208 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
135 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, 209 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
136 (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2); 210 (unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
211 HZ / 2);
212}
213
214static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr,
215 u32 val)
216{
217 rtl818x_iowrite32_idx(priv, addr, val, 0);
137} 218}
138 219
139#endif /* RTL8187_H */ 220#endif /* RTL8187_H */
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index bec96d762c6c..33527e58256f 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -27,19 +27,21 @@
27 27
28MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); 28MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
29MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); 29MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
30MODULE_DESCRIPTION("RTL8187 USB wireless driver"); 30MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32 32
33static struct usb_device_id rtl8187_table[] __devinitdata = { 33static struct usb_device_id rtl8187_table[] __devinitdata = {
34 /* Realtek */ 34 /* Realtek */
35 {USB_DEVICE(0x0bda, 0x8187)}, 35 {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
36 {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
37 {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
36 /* Netgear */ 38 /* Netgear */
37 {USB_DEVICE(0x0846, 0x6100)}, 39 {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
38 {USB_DEVICE(0x0846, 0x6a00)}, 40 {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
39 /* HP */ 41 /* HP */
40 {USB_DEVICE(0x03f0, 0xca02)}, 42 {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
41 /* Sitecom */ 43 /* Sitecom */
42 {USB_DEVICE(0x0df6, 0x000d)}, 44 {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
43 {} 45 {}
44}; 46};
45 47
@@ -153,9 +155,11 @@ static void rtl8187_tx_cb(struct urb *urb)
153 struct sk_buff *skb = (struct sk_buff *)urb->context; 155 struct sk_buff *skb = (struct sk_buff *)urb->context;
154 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 156 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
155 struct ieee80211_hw *hw = info->driver_data[0]; 157 struct ieee80211_hw *hw = info->driver_data[0];
158 struct rtl8187_priv *priv = hw->priv;
156 159
157 usb_free_urb(info->driver_data[1]); 160 usb_free_urb(info->driver_data[1]);
158 skb_pull(skb, sizeof(struct rtl8187_tx_hdr)); 161 skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
162 sizeof(struct rtl8187_tx_hdr));
159 memset(&info->status, 0, sizeof(info->status)); 163 memset(&info->status, 0, sizeof(info->status));
160 info->flags |= IEEE80211_TX_STAT_ACK; 164 info->flags |= IEEE80211_TX_STAT_ACK;
161 ieee80211_tx_status_irqsafe(hw, skb); 165 ieee80211_tx_status_irqsafe(hw, skb);
@@ -165,7 +169,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
165{ 169{
166 struct rtl8187_priv *priv = dev->priv; 170 struct rtl8187_priv *priv = dev->priv;
167 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 171 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
168 struct rtl8187_tx_hdr *hdr; 172 unsigned int ep;
173 void *buf;
169 struct urb *urb; 174 struct urb *urb;
170 __le16 rts_dur = 0; 175 __le16 rts_dur = 0;
171 u32 flags; 176 u32 flags;
@@ -193,16 +198,47 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
193 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; 198 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
194 } 199 }
195 200
196 hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); 201 if (!priv->is_rtl8187b) {
197 hdr->flags = cpu_to_le32(flags); 202 struct rtl8187_tx_hdr *hdr =
198 hdr->len = 0; 203 (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
199 hdr->rts_duration = rts_dur; 204 hdr->flags = cpu_to_le32(flags);
200 hdr->retry = cpu_to_le32(info->control.retry_limit << 8); 205 hdr->len = 0;
206 hdr->rts_duration = rts_dur;
207 hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
208 buf = hdr;
209
210 ep = 2;
211 } else {
212 /* fc needs to be calculated before skb_push() */
213 unsigned int epmap[4] = { 6, 7, 5, 4 };
214 struct ieee80211_hdr *tx_hdr =
215 (struct ieee80211_hdr *)(skb->data);
216 u16 fc = le16_to_cpu(tx_hdr->frame_control);
217
218 struct rtl8187b_tx_hdr *hdr =
219 (struct rtl8187b_tx_hdr *)skb_push(skb, sizeof(*hdr));
220 struct ieee80211_rate *txrate =
221 ieee80211_get_tx_rate(dev, info);
222 memset(hdr, 0, sizeof(*hdr));
223 hdr->flags = cpu_to_le32(flags);
224 hdr->rts_duration = rts_dur;
225 hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
226 hdr->tx_duration =
227 ieee80211_generic_frame_duration(dev, priv->vif,
228 skb->len, txrate);
229 buf = hdr;
230
231 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
232 ep = 12;
233 else
234 ep = epmap[skb_get_queue_mapping(skb)];
235 }
201 236
202 info->driver_data[0] = dev; 237 info->driver_data[0] = dev;
203 info->driver_data[1] = urb; 238 info->driver_data[1] = urb;
204 usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2), 239
205 hdr, skb->len, rtl8187_tx_cb, skb); 240 usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
241 buf, skb->len, rtl8187_tx_cb, skb);
206 rc = usb_submit_urb(urb, GFP_ATOMIC); 242 rc = usb_submit_urb(urb, GFP_ATOMIC);
207 if (rc < 0) { 243 if (rc < 0) {
208 usb_free_urb(urb); 244 usb_free_urb(urb);
@@ -218,7 +254,6 @@ static void rtl8187_rx_cb(struct urb *urb)
218 struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb; 254 struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb;
219 struct ieee80211_hw *dev = info->dev; 255 struct ieee80211_hw *dev = info->dev;
220 struct rtl8187_priv *priv = dev->priv; 256 struct rtl8187_priv *priv = dev->priv;
221 struct rtl8187_rx_hdr *hdr;
222 struct ieee80211_rx_status rx_status = { 0 }; 257 struct ieee80211_rx_status rx_status = { 0 };
223 int rate, signal; 258 int rate, signal;
224 u32 flags; 259 u32 flags;
@@ -239,11 +274,33 @@ static void rtl8187_rx_cb(struct urb *urb)
239 } 274 }
240 275
241 skb_put(skb, urb->actual_length); 276 skb_put(skb, urb->actual_length);
242 hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr)); 277 if (!priv->is_rtl8187b) {
243 flags = le32_to_cpu(hdr->flags); 278 struct rtl8187_rx_hdr *hdr =
244 skb_trim(skb, flags & 0x0FFF); 279 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
280 flags = le32_to_cpu(hdr->flags);
281 signal = hdr->signal & 0x7f;
282 rx_status.antenna = (hdr->signal >> 7) & 1;
283 rx_status.signal = signal;
284 rx_status.noise = hdr->noise;
285 rx_status.mactime = le64_to_cpu(hdr->mac_time);
286 priv->signal = signal;
287 priv->quality = signal;
288 priv->noise = hdr->noise;
289 } else {
290 struct rtl8187b_rx_hdr *hdr =
291 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
292 flags = le32_to_cpu(hdr->flags);
293 signal = hdr->agc >> 1;
294 rx_status.antenna = (hdr->signal >> 7) & 1;
295 rx_status.signal = 64 - min(hdr->noise, (u8)64);
296 rx_status.noise = hdr->noise;
297 rx_status.mactime = le64_to_cpu(hdr->mac_time);
298 priv->signal = hdr->signal;
299 priv->quality = hdr->agc >> 1;
300 priv->noise = hdr->noise;
301 }
245 302
246 signal = hdr->agc >> 1; 303 skb_trim(skb, flags & 0x0FFF);
247 rate = (flags >> 20) & 0xF; 304 rate = (flags >> 20) & 0xF;
248 if (rate > 3) { /* OFDM rate */ 305 if (rate > 3) { /* OFDM rate */
249 if (signal > 90) 306 if (signal > 90)
@@ -259,13 +316,11 @@ static void rtl8187_rx_cb(struct urb *urb)
259 signal = 95 - signal; 316 signal = 95 - signal;
260 } 317 }
261 318
262 rx_status.antenna = (hdr->signal >> 7) & 1; 319 rx_status.qual = priv->quality;
263 rx_status.qual = 64 - min(hdr->noise, (u8)64);
264 rx_status.signal = signal; 320 rx_status.signal = signal;
265 rx_status.rate_idx = rate; 321 rx_status.rate_idx = rate;
266 rx_status.freq = dev->conf.channel->center_freq; 322 rx_status.freq = dev->conf.channel->center_freq;
267 rx_status.band = dev->conf.channel->band; 323 rx_status.band = dev->conf.channel->band;
268 rx_status.mactime = le64_to_cpu(hdr->mac_time);
269 rx_status.flag |= RX_FLAG_TSFT; 324 rx_status.flag |= RX_FLAG_TSFT;
270 if (flags & (1 << 13)) 325 if (flags & (1 << 13))
271 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 326 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
@@ -305,7 +360,8 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
305 break; 360 break;
306 } 361 }
307 usb_fill_bulk_urb(entry, priv->udev, 362 usb_fill_bulk_urb(entry, priv->udev,
308 usb_rcvbulkpipe(priv->udev, 1), 363 usb_rcvbulkpipe(priv->udev,
364 priv->is_rtl8187b ? 3 : 1),
309 skb_tail_pointer(skb), 365 skb_tail_pointer(skb),
310 RTL8187_MAX_RX, rtl8187_rx_cb, skb); 366 RTL8187_MAX_RX, rtl8187_rx_cb, skb);
311 info = (struct rtl8187_rx_info *)skb->cb; 367 info = (struct rtl8187_rx_info *)skb->cb;
@@ -318,29 +374,12 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
318 return 0; 374 return 0;
319} 375}
320 376
321static int rtl8187_init_hw(struct ieee80211_hw *dev) 377static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
322{ 378{
323 struct rtl8187_priv *priv = dev->priv; 379 struct rtl8187_priv *priv = dev->priv;
324 u8 reg; 380 u8 reg;
325 int i; 381 int i;
326 382
327 /* reset */
328 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
329 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
330 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
331 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
332 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
333 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
334 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
335
336 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
337
338 msleep(200);
339 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
340 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
341 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
342 msleep(200);
343
344 reg = rtl818x_ioread8(priv, &priv->map->CMD); 383 reg = rtl818x_ioread8(priv, &priv->map->CMD);
345 reg &= (1 << 1); 384 reg &= (1 << 1);
346 reg |= RTL818X_CMD_RESET; 385 reg |= RTL818X_CMD_RESET;
@@ -376,12 +415,48 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
376 return -ETIMEDOUT; 415 return -ETIMEDOUT;
377 } 416 }
378 417
418 return 0;
419}
420
421static int rtl8187_init_hw(struct ieee80211_hw *dev)
422{
423 struct rtl8187_priv *priv = dev->priv;
424 u8 reg;
425 int res;
426
427 /* reset */
428 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
429 RTL818X_EEPROM_CMD_CONFIG);
430 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
431 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg |
432 RTL818X_CONFIG3_ANAPARAM_WRITE);
433 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
434 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
435 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg &
436 ~RTL818X_CONFIG3_ANAPARAM_WRITE);
437 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
438 RTL818X_EEPROM_CMD_NORMAL);
439
440 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
441
442 msleep(200);
443 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
444 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
445 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
446 msleep(200);
447
448 res = rtl8187_cmd_reset(dev);
449 if (res)
450 return res;
451
379 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 452 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
380 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 453 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
381 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 454 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
455 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
382 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON); 456 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
383 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); 457 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
384 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 458 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
459 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
385 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 460 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
386 461
387 /* setup card */ 462 /* setup card */
@@ -426,9 +501,11 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
426 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); 501 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
427 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); 502 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
428 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); 503 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
429 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 504 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
505 RTL818X_EEPROM_CMD_CONFIG);
430 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); 506 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
431 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 507 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
508 RTL818X_EEPROM_CMD_NORMAL);
432 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7); 509 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
433 msleep(100); 510 msleep(100);
434 511
@@ -445,16 +522,198 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
445 return 0; 522 return 0;
446} 523}
447 524
525static const u8 rtl8187b_reg_table[][3] = {
526 {0xF0, 0x32, 0}, {0xF1, 0x32, 0}, {0xF2, 0x00, 0}, {0xF3, 0x00, 0},
527 {0xF4, 0x32, 0}, {0xF5, 0x43, 0}, {0xF6, 0x00, 0}, {0xF7, 0x00, 0},
528 {0xF8, 0x46, 0}, {0xF9, 0xA4, 0}, {0xFA, 0x00, 0}, {0xFB, 0x00, 0},
529 {0xFC, 0x96, 0}, {0xFD, 0xA4, 0}, {0xFE, 0x00, 0}, {0xFF, 0x00, 0},
530
531 {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1},
532 {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1},
533 {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xE0, 0xFF, 1}, {0xE1, 0x0F, 1},
534 {0xE2, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, {0xF2, 0x02, 1},
535 {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, {0xF6, 0x06, 1},
536 {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
537
538 {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2},
539 {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2},
540 {0x27, 0x8D, 2}, {0x4D, 0x08, 2}, {0x50, 0x05, 2}, {0x51, 0xF5, 2},
541 {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2},
542 {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2},
543 {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2},
544 {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2},
545 {0x73, 0x9A, 2},
546
547 {0x34, 0xF0, 0}, {0x35, 0x0F, 0}, {0x5B, 0x40, 0}, {0x84, 0x88, 0},
548 {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
549 {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
550 {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
551 {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x91, 0x03, 0},
552
553 {0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0},
554 {0x8E, 0x08, 0}, {0x8F, 0x00, 0}
555};
556
557static int rtl8187b_init_hw(struct ieee80211_hw *dev)
558{
559 struct rtl8187_priv *priv = dev->priv;
560 int res, i;
561 u8 reg;
562
563 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
564 RTL818X_EEPROM_CMD_CONFIG);
565
566 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
567 reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT;
568 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
569 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, 0x727f3f52);
570 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, 0x45090658);
571 rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, 0);
572
573 rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
574 reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
575 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5));
576 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5));
577
578 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
579 reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
580 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
581
582 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
583 RTL818X_EEPROM_CMD_NORMAL);
584
585 res = rtl8187_cmd_reset(dev);
586 if (res)
587 return res;
588
589 rtl818x_iowrite16(priv, (__le16 *)0xFF2D, 0x0FFF);
590 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
591 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
592 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
593 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
594 reg |= RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT |
595 RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
596 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
597
598 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
599 reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
600 reg |= RTL818X_RATE_FALLBACK_ENABLE;
601 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);
602
603 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
604 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
605 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1);
606
607 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
608 RTL818X_EEPROM_CMD_CONFIG);
609 reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
610 rtl818x_iowrite8(priv, &priv->map->CONFIG1, (reg & 0x3F) | 0x80);
611 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
612 RTL818X_EEPROM_CMD_NORMAL);
613
614 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
615 for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) {
616 rtl818x_iowrite8_idx(priv,
617 (u8 *)(uintptr_t)
618 (rtl8187b_reg_table[i][0] | 0xFF00),
619 rtl8187b_reg_table[i][1],
620 rtl8187b_reg_table[i][2]);
621 }
622
623 rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50);
624 rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0);
625
626 rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF0, 0, 1);
627 rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF4, 0, 1);
628 rtl818x_iowrite8_idx(priv, (u8 *)0xFFF8, 0, 1);
629
630 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
631
632 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
633
634 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
635 RTL818X_EEPROM_CMD_CONFIG);
636 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
637 reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
638 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
639 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
640 RTL818X_EEPROM_CMD_NORMAL);
641
642 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
643 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
644 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
645 msleep(1100);
646
647 priv->rf->init(dev);
648
649 reg = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE;
650 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
651 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
652
653 rtl818x_iowrite8(priv, (u8 *)0xFE41, 0xF4);
654 rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x00);
655 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
656 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
657 rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x0F);
658 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
659 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
660
661 reg = rtl818x_ioread8(priv, (u8 *)0xFFDB);
662 rtl818x_iowrite8(priv, (u8 *)0xFFDB, reg | (1 << 2));
663 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x59FA, 3);
664 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF74, 0x59D2, 3);
665 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF76, 0x59D2, 3);
666 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF78, 0x19FA, 3);
667 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7A, 0x19FA, 3);
668 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7C, 0x00D0, 3);
669 rtl818x_iowrite8(priv, (u8 *)0xFF61, 0);
670 rtl818x_iowrite8_idx(priv, (u8 *)0xFF80, 0x0F, 1);
671 rtl818x_iowrite8_idx(priv, (u8 *)0xFF83, 0x03, 1);
672 rtl818x_iowrite8(priv, (u8 *)0xFFDA, 0x10);
673 rtl818x_iowrite8_idx(priv, (u8 *)0xFF4D, 0x08, 2);
674
675 rtl818x_iowrite32(priv, &priv->map->HSSI_PARA, 0x0600321B);
676
677 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1);
678
679 return 0;
680}
681
448static int rtl8187_start(struct ieee80211_hw *dev) 682static int rtl8187_start(struct ieee80211_hw *dev)
449{ 683{
450 struct rtl8187_priv *priv = dev->priv; 684 struct rtl8187_priv *priv = dev->priv;
451 u32 reg; 685 u32 reg;
452 int ret; 686 int ret;
453 687
454 ret = rtl8187_init_hw(dev); 688 ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) :
689 rtl8187b_init_hw(dev);
455 if (ret) 690 if (ret)
456 return ret; 691 return ret;
457 692
693 if (priv->is_rtl8187b) {
694 reg = RTL818X_RX_CONF_MGMT |
695 RTL818X_RX_CONF_DATA |
696 RTL818X_RX_CONF_BROADCAST |
697 RTL818X_RX_CONF_NICMAC |
698 RTL818X_RX_CONF_BSSID |
699 (7 << 13 /* RX FIFO threshold NONE */) |
700 (7 << 10 /* MAX RX DMA */) |
701 RTL818X_RX_CONF_RX_AUTORESETPHY |
702 RTL818X_RX_CONF_ONLYERLPKT |
703 RTL818X_RX_CONF_MULTICAST;
704 priv->rx_conf = reg;
705 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
706
707 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
708 RTL818X_TX_CONF_HW_SEQNUM |
709 RTL818X_TX_CONF_DISREQQSIZE |
710 (7 << 8 /* short retry limit */) |
711 (7 << 0 /* long retry limit */) |
712 (7 << 21 /* MAX TX DMA */));
713 rtl8187_init_urbs(dev);
714 return 0;
715 }
716
458 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); 717 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
459 718
460 rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); 719 rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
@@ -581,18 +840,20 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
581 msleep(10); 840 msleep(10);
582 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); 841 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
583 842
584 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); 843 if (!priv->is_rtl8187b) {
585 844 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
586 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { 845
587 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); 846 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
588 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); 847 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
589 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14); 848 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
590 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73); 849 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
591 } else { 850 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
592 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); 851 } else {
593 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); 852 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
594 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24); 853 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
595 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5); 854 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
855 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
856 }
596 } 857 }
597 858
598 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); 859 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
@@ -608,14 +869,20 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
608{ 869{
609 struct rtl8187_priv *priv = dev->priv; 870 struct rtl8187_priv *priv = dev->priv;
610 int i; 871 int i;
872 u8 reg;
611 873
612 for (i = 0; i < ETH_ALEN; i++) 874 for (i = 0; i < ETH_ALEN; i++)
613 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); 875 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
614 876
615 if (is_valid_ether_addr(conf->bssid)) 877 if (is_valid_ether_addr(conf->bssid)) {
616 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA); 878 reg = RTL818X_MSR_INFRA;
617 else 879 if (priv->is_rtl8187b)
618 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK); 880 reg |= RTL818X_MSR_ENEDCA;
881 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
882 } else {
883 reg = RTL818X_MSR_NO_LINK;
884 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
885 }
619 886
620 return 0; 887 return 0;
621} 888}
@@ -702,6 +969,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
702 struct rtl8187_priv *priv; 969 struct rtl8187_priv *priv;
703 struct eeprom_93cx6 eeprom; 970 struct eeprom_93cx6 eeprom;
704 struct ieee80211_channel *channel; 971 struct ieee80211_channel *channel;
972 const char *chip_name;
705 u16 txpwr, reg; 973 u16 txpwr, reg;
706 int err, i; 974 int err, i;
707 DECLARE_MAC_BUF(mac); 975 DECLARE_MAC_BUF(mac);
@@ -713,6 +981,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
713 } 981 }
714 982
715 priv = dev->priv; 983 priv = dev->priv;
984 priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B);
716 985
717 SET_IEEE80211_DEV(dev, &intf->dev); 986 SET_IEEE80211_DEV(dev, &intf->dev);
718 usb_set_intfdata(intf, dev); 987 usb_set_intfdata(intf, dev);
@@ -741,8 +1010,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
741 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1010 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
742 IEEE80211_HW_RX_INCLUDES_FCS | 1011 IEEE80211_HW_RX_INCLUDES_FCS |
743 IEEE80211_HW_SIGNAL_UNSPEC; 1012 IEEE80211_HW_SIGNAL_UNSPEC;
744 dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
745 dev->queues = 1;
746 dev->max_signal = 65; 1013 dev->max_signal = 65;
747 1014
748 eeprom.data = dev; 1015 eeprom.data = dev;
@@ -777,12 +1044,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
777 (*channel++).hw_value = txpwr & 0xFF; 1044 (*channel++).hw_value = txpwr & 0xFF;
778 (*channel++).hw_value = txpwr >> 8; 1045 (*channel++).hw_value = txpwr >> 8;
779 } 1046 }
780 for (i = 0; i < 2; i++) {
781 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i,
782 &txpwr);
783 (*channel++).hw_value = txpwr & 0xFF;
784 (*channel++).hw_value = txpwr >> 8;
785 }
786 1047
787 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, 1048 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
788 &priv->txpwr_base); 1049 &priv->txpwr_base);
@@ -796,7 +1057,90 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
796 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); 1057 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
797 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 1058 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
798 1059
1060 if (!priv->is_rtl8187b) {
1061 u32 reg32;
1062 reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF);
1063 reg32 &= RTL818X_TX_CONF_HWVER_MASK;
1064 switch (reg32) {
1065 case RTL818X_TX_CONF_R8187vD_B:
1066 /* Some RTL8187B devices have a USB ID of 0x8187
1067 * detect them here */
1068 chip_name = "RTL8187BvB(early)";
1069 priv->is_rtl8187b = 1;
1070 priv->hw_rev = RTL8187BvB;
1071 break;
1072 case RTL818X_TX_CONF_R8187vD:
1073 chip_name = "RTL8187vD";
1074 break;
1075 default:
1076 chip_name = "RTL8187vB (default)";
1077 }
1078 } else {
1079 /*
1080 * Force USB request to write radio registers for 8187B, Realtek
1081 * only uses it in their sources
1082 */
1083 /*if (priv->asic_rev == 0) {
1084 printk(KERN_WARNING "rtl8187: Forcing use of USB "
1085 "requests to write to radio registers\n");
1086 priv->asic_rev = 1;
1087 }*/
1088 switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) {
1089 case RTL818X_R8187B_B:
1090 chip_name = "RTL8187BvB";
1091 priv->hw_rev = RTL8187BvB;
1092 break;
1093 case RTL818X_R8187B_D:
1094 chip_name = "RTL8187BvD";
1095 priv->hw_rev = RTL8187BvD;
1096 break;
1097 case RTL818X_R8187B_E:
1098 chip_name = "RTL8187BvE";
1099 priv->hw_rev = RTL8187BvE;
1100 break;
1101 default:
1102 chip_name = "RTL8187BvB (default)";
1103 priv->hw_rev = RTL8187BvB;
1104 }
1105 }
1106
1107 if (!priv->is_rtl8187b) {
1108 for (i = 0; i < 2; i++) {
1109 eeprom_93cx6_read(&eeprom,
1110 RTL8187_EEPROM_TXPWR_CHAN_6 + i,
1111 &txpwr);
1112 (*channel++).hw_value = txpwr & 0xFF;
1113 (*channel++).hw_value = txpwr >> 8;
1114 }
1115 } else {
1116 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6,
1117 &txpwr);
1118 (*channel++).hw_value = txpwr & 0xFF;
1119
1120 eeprom_93cx6_read(&eeprom, 0x0A, &txpwr);
1121 (*channel++).hw_value = txpwr & 0xFF;
1122
1123 eeprom_93cx6_read(&eeprom, 0x1C, &txpwr);
1124 (*channel++).hw_value = txpwr & 0xFF;
1125 (*channel++).hw_value = txpwr >> 8;
1126 }
1127
1128 if (priv->is_rtl8187b)
1129 printk(KERN_WARNING "rtl8187: 8187B chip detected. Support "
1130 "is EXPERIMENTAL, and could damage your\n"
1131 " hardware, use at your own risk\n");
1132 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
1133 printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
1134 " info!\n");
1135
799 priv->rf = rtl8187_detect_rf(dev); 1136 priv->rf = rtl8187_detect_rf(dev);
1137 dev->extra_tx_headroom = (!priv->is_rtl8187b) ?
1138 sizeof(struct rtl8187_tx_hdr) :
1139 sizeof(struct rtl8187b_tx_hdr);
1140 if (!priv->is_rtl8187b)
1141 dev->queues = 1;
1142 else
1143 dev->queues = 4;
800 1144
801 err = ieee80211_register_hw(dev); 1145 err = ieee80211_register_hw(dev);
802 if (err) { 1146 if (err) {
@@ -804,9 +1148,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
804 goto err_free_dev; 1148 goto err_free_dev;
805 } 1149 }
806 1150
807 printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n", 1151 printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
808 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), 1152 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
809 priv->asic_rev, priv->rf->name); 1153 chip_name, priv->asic_rev, priv->rf->name);
810 1154
811 return 0; 1155 return 0;
812 1156
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index 9146387b4c5e..1e059de97116 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -305,9 +305,11 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
305 /* anaparam2 on */ 305 /* anaparam2 on */
306 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 306 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
307 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 307 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
308 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 308 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
309 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
309 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); 310 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
310 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 311 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
312 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
311 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 313 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
312 314
313 rtl8225_write_phy_ofdm(dev, 2, 0x42); 315 rtl8225_write_phy_ofdm(dev, 2, 0x42);
@@ -471,12 +473,42 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
471 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]); 473 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
472} 474}
473 475
476static const u8 rtl8225z2_agc[] = {
477 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f,
478 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
479 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f,
480 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
481 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
482 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
483 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28,
484 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
485 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30,
486 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
487 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
488};
489static const u8 rtl8225z2_ofdm[] = {
490 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
491 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
492 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
493 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
494 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
495 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
496 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
497 0x6d, 0x3c, 0xfb, 0x07
498};
499
474static const u8 rtl8225z2_tx_power_cck_ch14[] = { 500static const u8 rtl8225z2_tx_power_cck_ch14[] = {
475 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 501 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
502 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
503 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
504 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
476}; 505};
477 506
478static const u8 rtl8225z2_tx_power_cck[] = { 507static const u8 rtl8225z2_tx_power_cck[] = {
479 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 508 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
509 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
510 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
511 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
480}; 512};
481 513
482static const u8 rtl8225z2_tx_power_ofdm[] = { 514static const u8 rtl8225z2_tx_power_ofdm[] = {
@@ -526,9 +558,11 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
526 /* anaparam2 on */ 558 /* anaparam2 on */
527 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 559 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
528 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 560 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
529 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 561 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
562 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
530 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); 563 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
531 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 564 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
565 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
532 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 566 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
533 567
534 rtl8225_write_phy_ofdm(dev, 2, 0x42); 568 rtl8225_write_phy_ofdm(dev, 2, 0x42);
@@ -542,6 +576,85 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
542 msleep(1); 576 msleep(1);
543} 577}
544 578
579static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
580{
581 struct rtl8187_priv *priv = dev->priv;
582 u8 cck_power, ofdm_power;
583 const u8 *tmp;
584 int i;
585
586 cck_power = priv->channels[channel - 1].hw_value & 0xF;
587 ofdm_power = priv->channels[channel - 1].hw_value >> 4;
588
589 if (cck_power > 15)
590 cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22;
591 else
592 cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
593 cck_power += priv->txpwr_base & 0xF;
594 cck_power = min(cck_power, (u8)35);
595
596 if (ofdm_power > 15)
597 ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25;
598 else
599 ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10;
600 ofdm_power += (priv->txpwr_base >> 4) & 0xF;
601 ofdm_power = min(ofdm_power, (u8)35);
602
603 if (channel == 14)
604 tmp = rtl8225z2_tx_power_cck_ch14;
605 else
606 tmp = rtl8225z2_tx_power_cck;
607
608 if (priv->hw_rev == RTL8187BvB) {
609 if (cck_power <= 6)
610 ; /* do nothing */
611 else if (cck_power <= 11)
612 tmp += 8;
613 else
614 tmp += 16;
615 } else {
616 if (cck_power <= 5)
617 ; /* do nothing */
618 else if (cck_power <= 11)
619 tmp += 8;
620 else if (cck_power <= 17)
621 tmp += 16;
622 else
623 tmp += 24;
624 }
625
626 for (i = 0; i < 8; i++)
627 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
628
629 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
630 rtl8225z2_tx_gain_cck_ofdm[cck_power]);
631 msleep(1);
632
633 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
634 rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1);
635 if (priv->hw_rev == RTL8187BvB) {
636 if (ofdm_power <= 11) {
637 rtl8225_write_phy_ofdm(dev, 0x87, 0x60);
638 rtl8225_write_phy_ofdm(dev, 0x89, 0x60);
639 } else {
640 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
641 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
642 }
643 } else {
644 if (ofdm_power <= 11) {
645 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
646 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
647 } else if (ofdm_power <= 17) {
648 rtl8225_write_phy_ofdm(dev, 0x87, 0x54);
649 rtl8225_write_phy_ofdm(dev, 0x89, 0x54);
650 } else {
651 rtl8225_write_phy_ofdm(dev, 0x87, 0x50);
652 rtl8225_write_phy_ofdm(dev, 0x89, 0x50);
653 }
654 }
655 msleep(1);
656}
657
545static const u16 rtl8225z2_rxgain[] = { 658static const u16 rtl8225z2_rxgain[] = {
546 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, 659 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
547 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, 660 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
@@ -715,6 +828,81 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
715 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); 828 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
716} 829}
717 830
831static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
832{
833 struct rtl8187_priv *priv = dev->priv;
834 int i;
835
836 rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
837 rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
838 rtl8225_write(dev, 0x2, 0x44D); msleep(1);
839 rtl8225_write(dev, 0x3, 0x441); msleep(1);
840 rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
841 rtl8225_write(dev, 0x5, 0xC72); msleep(1);
842 rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
843 rtl8225_write(dev, 0x7, 0x82A); msleep(1);
844 rtl8225_write(dev, 0x8, 0x03F); msleep(1);
845 rtl8225_write(dev, 0x9, 0x335); msleep(1);
846 rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
847 rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
848 rtl8225_write(dev, 0xc, 0x850); msleep(1);
849 rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
850 rtl8225_write(dev, 0xe, 0x02B); msleep(1);
851 rtl8225_write(dev, 0xf, 0x114); msleep(1);
852
853 rtl8225_write(dev, 0x0, 0x1B7); msleep(1);
854
855 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
856 rtl8225_write(dev, 0x1, i + 1); msleep(1);
857 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); msleep(1);
858 }
859
860 rtl8225_write(dev, 0x3, 0x080); msleep(1);
861 rtl8225_write(dev, 0x5, 0x004); msleep(1);
862 rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
863 msleep(3000);
864
865 rtl8225_write(dev, 0x2, 0xC4D); msleep(1);
866 msleep(2000);
867
868 rtl8225_write(dev, 0x2, 0x44D); msleep(1);
869 rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
870
871 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
872 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
873 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
874
875 rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
876 for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
877 rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]);
878 rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i);
879 rtl8225_write_phy_ofdm(dev, 0xE, 0);
880 }
881 rtl8225_write_phy_ofdm(dev, 0x80, 0x10);
882
883 for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
884 rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
885
886 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
887 rtl818x_iowrite8(priv, &priv->map->SLOT, 9);
888 rtl818x_iowrite8(priv, (u8 *)0xFFF0, 28);
889 rtl818x_iowrite8(priv, (u8 *)0xFFF4, 28);
890 rtl818x_iowrite8(priv, (u8 *)0xFFF8, 28);
891 rtl818x_iowrite8(priv, (u8 *)0xFFFC, 28);
892 rtl818x_iowrite8(priv, (u8 *)0xFF2D, 0x5B);
893 rtl818x_iowrite8(priv, (u8 *)0xFF79, 0x5B);
894 rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
895 rtl818x_iowrite32(priv, (__le32 *)0xFFF4, (7 << 12) | (3 << 8) | 28);
896 rtl818x_iowrite32(priv, (__le32 *)0xFFF8, (7 << 12) | (3 << 8) | 28);
897 rtl818x_iowrite32(priv, (__le32 *)0xFFFC, (7 << 12) | (3 << 8) | 28);
898 rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
899
900 rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
901 rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); msleep(1);
902 rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); msleep(1);
903 rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
904}
905
718static void rtl8225_rf_stop(struct ieee80211_hw *dev) 906static void rtl8225_rf_stop(struct ieee80211_hw *dev)
719{ 907{
720 u8 reg; 908 u8 reg;
@@ -739,8 +927,10 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
739 927
740 if (priv->rf->init == rtl8225_rf_init) 928 if (priv->rf->init == rtl8225_rf_init)
741 rtl8225_rf_set_tx_power(dev, chan); 929 rtl8225_rf_set_tx_power(dev, chan);
742 else 930 else if (priv->rf->init == rtl8225z2_rf_init)
743 rtl8225z2_rf_set_tx_power(dev, chan); 931 rtl8225z2_rf_set_tx_power(dev, chan);
932 else
933 rtl8225z2_b_rf_set_tx_power(dev, chan);
744 934
745 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); 935 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
746 msleep(10); 936 msleep(10);
@@ -760,19 +950,30 @@ static const struct rtl818x_rf_ops rtl8225z2_ops = {
760 .set_chan = rtl8225_rf_set_channel 950 .set_chan = rtl8225_rf_set_channel
761}; 951};
762 952
953static const struct rtl818x_rf_ops rtl8225z2_b_ops = {
954 .name = "rtl8225z2",
955 .init = rtl8225z2_b_rf_init,
956 .stop = rtl8225_rf_stop,
957 .set_chan = rtl8225_rf_set_channel
958};
959
763const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) 960const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
764{ 961{
765 u16 reg8, reg9; 962 u16 reg8, reg9;
963 struct rtl8187_priv *priv = dev->priv;
766 964
767 rtl8225_write(dev, 0, 0x1B7); 965 if (!priv->is_rtl8187b) {
966 rtl8225_write(dev, 0, 0x1B7);
768 967
769 reg8 = rtl8225_read(dev, 8); 968 reg8 = rtl8225_read(dev, 8);
770 reg9 = rtl8225_read(dev, 9); 969 reg9 = rtl8225_read(dev, 9);
771 970
772 rtl8225_write(dev, 0, 0x0B7); 971 rtl8225_write(dev, 0, 0x0B7);
773 972
774 if (reg8 != 0x588 || reg9 != 0x700) 973 if (reg8 != 0x588 || reg9 != 0x700)
775 return &rtl8225_ops; 974 return &rtl8225_ops;
776 975
777 return &rtl8225z2_ops; 976 return &rtl8225z2_ops;
977 } else
978 return &rtl8225z2_b_ops;
778} 979}
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h
index 4f7d38f506eb..00900fe16fce 100644
--- a/drivers/net/wireless/rtl818x.h
+++ b/drivers/net/wireless/rtl818x.h
@@ -66,7 +66,10 @@ struct rtl818x_csr {
66#define RTL818X_TX_CONF_R8180_F (3 << 25) 66#define RTL818X_TX_CONF_R8180_F (3 << 25)
67#define RTL818X_TX_CONF_R8185_ABC (4 << 25) 67#define RTL818X_TX_CONF_R8185_ABC (4 << 25)
68#define RTL818X_TX_CONF_R8185_D (5 << 25) 68#define RTL818X_TX_CONF_R8185_D (5 << 25)
69#define RTL818X_TX_CONF_R8187vD (5 << 25)
70#define RTL818X_TX_CONF_R8187vD_B (6 << 25)
69#define RTL818X_TX_CONF_HWVER_MASK (7 << 25) 71#define RTL818X_TX_CONF_HWVER_MASK (7 << 25)
72#define RTL818X_TX_CONF_DISREQQSIZE (1 << 28)
70#define RTL818X_TX_CONF_PROBE_DTS (1 << 29) 73#define RTL818X_TX_CONF_PROBE_DTS (1 << 29)
71#define RTL818X_TX_CONF_HW_SEQNUM (1 << 30) 74#define RTL818X_TX_CONF_HW_SEQNUM (1 << 30)
72#define RTL818X_TX_CONF_CW_MIN (1 << 31) 75#define RTL818X_TX_CONF_CW_MIN (1 << 31)
@@ -106,8 +109,11 @@ struct rtl818x_csr {
106#define RTL818X_MSR_NO_LINK (0 << 2) 109#define RTL818X_MSR_NO_LINK (0 << 2)
107#define RTL818X_MSR_ADHOC (1 << 2) 110#define RTL818X_MSR_ADHOC (1 << 2)
108#define RTL818X_MSR_INFRA (2 << 2) 111#define RTL818X_MSR_INFRA (2 << 2)
112#define RTL818X_MSR_MASTER (3 << 2)
113#define RTL818X_MSR_ENEDCA (4 << 2)
109 u8 CONFIG3; 114 u8 CONFIG3;
110#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6) 115#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6)
116#define RTL818X_CONFIG3_GNT_SELECT (1 << 7)
111 u8 CONFIG4; 117 u8 CONFIG4;
112#define RTL818X_CONFIG4_POWEROFF (1 << 6) 118#define RTL818X_CONFIG4_POWEROFF (1 << 6)
113#define RTL818X_CONFIG4_VCOOFF (1 << 7) 119#define RTL818X_CONFIG4_VCOOFF (1 << 7)
@@ -133,7 +139,9 @@ struct rtl818x_csr {
133 __le32 RF_TIMING; 139 __le32 RF_TIMING;
134 u8 GP_ENABLE; 140 u8 GP_ENABLE;
135 u8 GPIO; 141 u8 GPIO;
136 u8 reserved_12[10]; 142 u8 reserved_12[2];
143 __le32 HSSI_PARA;
144 u8 reserved_13[4];
137 u8 TX_AGC_CTL; 145 u8 TX_AGC_CTL;
138#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT (1 << 0) 146#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT (1 << 0)
139#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT (1 << 1) 147#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT (1 << 1)
@@ -141,29 +149,39 @@ struct rtl818x_csr {
141 u8 TX_GAIN_CCK; 149 u8 TX_GAIN_CCK;
142 u8 TX_GAIN_OFDM; 150 u8 TX_GAIN_OFDM;
143 u8 TX_ANTENNA; 151 u8 TX_ANTENNA;
144 u8 reserved_13[16]; 152 u8 reserved_14[16];
145 u8 WPA_CONF; 153 u8 WPA_CONF;
146 u8 reserved_14[3]; 154 u8 reserved_15[3];
147 u8 SIFS; 155 u8 SIFS;
148 u8 DIFS; 156 u8 DIFS;
149 u8 SLOT; 157 u8 SLOT;
150 u8 reserved_15[5]; 158 u8 reserved_16[5];
151 u8 CW_CONF; 159 u8 CW_CONF;
152#define RTL818X_CW_CONF_PERPACKET_CW_SHIFT (1 << 0) 160#define RTL818X_CW_CONF_PERPACKET_CW_SHIFT (1 << 0)
153#define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT (1 << 1) 161#define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT (1 << 1)
154 u8 CW_VAL; 162 u8 CW_VAL;
155 u8 RATE_FALLBACK; 163 u8 RATE_FALLBACK;
156 u8 reserved_16[25]; 164#define RTL818X_RATE_FALLBACK_ENABLE (1 << 7)
165 u8 ACM_CONTROL;
166 u8 reserved_17[24];
157 u8 CONFIG5; 167 u8 CONFIG5;
158 u8 TX_DMA_POLLING; 168 u8 TX_DMA_POLLING;
159 u8 reserved_17[2]; 169 u8 reserved_18[2];
160 __le16 CWR; 170 __le16 CWR;
161 u8 RETRY_CTR; 171 u8 RETRY_CTR;
162 u8 reserved_18[5]; 172 u8 reserved_19[3];
173 __le16 INT_MIG;
174/* RTL818X_R8187B_*: magic numbers from ioregisters */
175#define RTL818X_R8187B_B 0
176#define RTL818X_R8187B_D 1
177#define RTL818X_R8187B_E 2
163 __le32 RDSAR; 178 __le32 RDSAR;
164 u8 reserved_19[12]; 179 __le16 TID_AC_MAP;
165 __le16 FEMR;
166 u8 reserved_20[4]; 180 u8 reserved_20[4];
181 u8 ANAPARAM3;
182 u8 reserved_21[5];
183 __le16 FEMR;
184 u8 reserved_22[4];
167 __le16 TALLY_CNT; 185 __le16 TALLY_CNT;
168 u8 TALLY_SEL; 186 u8 TALLY_SEL;
169} __attribute__((packed)); 187} __attribute__((packed));
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 317c5e24f80c..665f76af2fec 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -405,43 +405,66 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
405 /* FIXME: Management frame? */ 405 /* FIXME: Management frame? */
406} 406}
407 407
408void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) 408static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
409{ 409{
410 struct zd_mac *mac = zd_hw_mac(hw); 410 struct zd_mac *mac = zd_hw_mac(hw);
411 int r;
411 u32 tmp, j = 0; 412 u32 tmp, j = 0;
412 /* 4 more bytes for tail CRC */ 413 /* 4 more bytes for tail CRC */
413 u32 full_len = beacon->len + 4; 414 u32 full_len = beacon->len + 4;
414 zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0); 415
415 zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); 416 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
417 if (r < 0)
418 return r;
419 r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
420 if (r < 0)
421 return r;
422
416 while (tmp & 0x2) { 423 while (tmp & 0x2) {
417 zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); 424 r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
425 if (r < 0)
426 return r;
418 if ((++j % 100) == 0) { 427 if ((++j % 100) == 0) {
419 printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n"); 428 printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
420 if (j >= 500) { 429 if (j >= 500) {
421 printk(KERN_ERR "Giving up beacon config.\n"); 430 printk(KERN_ERR "Giving up beacon config.\n");
422 return; 431 return -ETIMEDOUT;
423 } 432 }
424 } 433 }
425 msleep(1); 434 msleep(1);
426 } 435 }
427 436
428 zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1); 437 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1);
429 if (zd_chip_is_zd1211b(&mac->chip)) 438 if (r < 0)
430 zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1); 439 return r;
440 if (zd_chip_is_zd1211b(&mac->chip)) {
441 r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
442 if (r < 0)
443 return r;
444 }
431 445
432 for (j = 0 ; j < beacon->len; j++) 446 for (j = 0 ; j < beacon->len; j++) {
433 zd_iowrite32(&mac->chip, CR_BCN_FIFO, 447 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO,
434 *((u8 *)(beacon->data + j))); 448 *((u8 *)(beacon->data + j)));
449 if (r < 0)
450 return r;
451 }
435 452
436 for (j = 0; j < 4; j++) 453 for (j = 0; j < 4; j++) {
437 zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0); 454 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
455 if (r < 0)
456 return r;
457 }
458
459 r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
460 if (r < 0)
461 return r;
438 462
439 zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
440 /* 802.11b/g 2.4G CCK 1Mb 463 /* 802.11b/g 2.4G CCK 1Mb
441 * 802.11a, not yet implemented, uses different values (see GPL vendor 464 * 802.11a, not yet implemented, uses different values (see GPL vendor
442 * driver) 465 * driver)
443 */ 466 */
444 zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 | 467 return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
445 (full_len << 19)); 468 (full_len << 19));
446} 469}
447 470
@@ -699,15 +722,20 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
699{ 722{
700 struct zd_mac *mac = zd_hw_mac(hw); 723 struct zd_mac *mac = zd_hw_mac(hw);
701 int associated; 724 int associated;
725 int r;
702 726
703 if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || 727 if (mac->type == IEEE80211_IF_TYPE_MESH_POINT ||
704 mac->type == IEEE80211_IF_TYPE_IBSS) { 728 mac->type == IEEE80211_IF_TYPE_IBSS) {
705 associated = true; 729 associated = true;
706 if (conf->beacon) { 730 if (conf->beacon) {
707 zd_mac_config_beacon(hw, conf->beacon); 731 r = zd_mac_config_beacon(hw, conf->beacon);
708 kfree_skb(conf->beacon); 732 if (r < 0)
709 zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | 733 return r;
734 r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
710 hw->conf.beacon_int); 735 hw->conf.beacon_int);
736 if (r < 0)
737 return r;
738 kfree_skb(conf->beacon);
711 } 739 }
712 } else 740 } else
713 associated = is_valid_ether_addr(conf->bssid); 741 associated = is_valid_ether_addr(conf->bssid);