diff options
185 files changed, 7517 insertions, 3611 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 12a75ab3dd23..4228736de0e8 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -13,8 +13,8 @@ | |||
13 | struct bcma_bus; | 13 | struct bcma_bus; |
14 | 14 | ||
15 | /* main.c */ | 15 | /* main.c */ |
16 | extern int bcma_bus_register(struct bcma_bus *bus); | 16 | int bcma_bus_register(struct bcma_bus *bus); |
17 | extern void bcma_bus_unregister(struct bcma_bus *bus); | 17 | void bcma_bus_unregister(struct bcma_bus *bus); |
18 | 18 | ||
19 | /* scan.c */ | 19 | /* scan.c */ |
20 | int bcma_bus_scan(struct bcma_bus *bus); | 20 | int bcma_bus_scan(struct bcma_bus *bus); |
diff --git a/drivers/bcma/core.c b/drivers/bcma/core.c index ced379f7b371..1ec7d4528dd0 100644 --- a/drivers/bcma/core.c +++ b/drivers/bcma/core.c | |||
@@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_device *core) | |||
19 | } | 19 | } |
20 | EXPORT_SYMBOL_GPL(bcma_core_is_enabled); | 20 | EXPORT_SYMBOL_GPL(bcma_core_is_enabled); |
21 | 21 | ||
22 | static void bcma_core_disable(struct bcma_device *core, u32 flags) | 22 | void bcma_core_disable(struct bcma_device *core, u32 flags) |
23 | { | 23 | { |
24 | if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) | 24 | if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) |
25 | return; | 25 | return; |
@@ -31,6 +31,7 @@ static void bcma_core_disable(struct bcma_device *core, u32 flags) | |||
31 | bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET); | 31 | bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET); |
32 | udelay(1); | 32 | udelay(1); |
33 | } | 33 | } |
34 | EXPORT_SYMBOL_GPL(bcma_core_disable); | ||
34 | 35 | ||
35 | int bcma_core_enable(struct bcma_device *core, u32 flags) | 36 | int bcma_core_enable(struct bcma_device *core, u32 flags) |
36 | { | 37 | { |
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index f44177a644c7..dd5846bef029 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c | |||
@@ -53,6 +53,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) | |||
53 | max_msk = 0xFFFF; | 53 | max_msk = 0xFFFF; |
54 | break; | 54 | break; |
55 | case 43224: | 55 | case 43224: |
56 | case 43225: | ||
56 | break; | 57 | break; |
57 | default: | 58 | default: |
58 | pr_err("PMU resource config unknown for device 0x%04X\n", | 59 | pr_err("PMU resource config unknown for device 0x%04X\n", |
@@ -74,6 +75,7 @@ void bcma_pmu_swreg_init(struct bcma_drv_cc *cc) | |||
74 | case 0x4313: | 75 | case 0x4313: |
75 | case 0x4331: | 76 | case 0x4331: |
76 | case 43224: | 77 | case 43224: |
78 | case 43225: | ||
77 | break; | 79 | break; |
78 | default: | 80 | default: |
79 | pr_err("PMU switch/regulators init unknown for device " | 81 | pr_err("PMU switch/regulators init unknown for device " |
@@ -96,11 +98,13 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc) | |||
96 | if (bus->chipinfo.rev == 0) { | 98 | if (bus->chipinfo.rev == 0) { |
97 | pr_err("Workarounds for 43224 rev 0 not fully " | 99 | pr_err("Workarounds for 43224 rev 0 not fully " |
98 | "implemented\n"); | 100 | "implemented\n"); |
99 | bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); | 101 | bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0); |
100 | } else { | 102 | } else { |
101 | bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); | 103 | bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); |
102 | } | 104 | } |
103 | break; | 105 | break; |
106 | case 43225: | ||
107 | break; | ||
104 | default: | 108 | default: |
105 | pr_err("Workarounds unknown for device 0x%04X\n", | 109 | pr_err("Workarounds unknown for device 0x%04X\n", |
106 | bus->chipinfo.id); | 110 | bus->chipinfo.id); |
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index 789d68b4858b..b0c19ede0d2e 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c | |||
@@ -184,3 +184,4 @@ int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, | |||
184 | out: | 184 | out: |
185 | return err; | 185 | return err; |
186 | } | 186 | } |
187 | EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl); | ||
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 2a526bc3342f..ac4bc626c149 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -227,6 +227,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { | |||
227 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, | 227 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, |
228 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, | 228 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, |
229 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, | 229 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, |
230 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, | ||
230 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, | 231 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, |
231 | { 0, }, | 232 | { 0, }, |
232 | }; | 233 | }; |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 11e96dc6011a..ba15105cc23a 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -160,13 +160,11 @@ int bcma_bus_register(struct bcma_bus *bus) | |||
160 | 160 | ||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | EXPORT_SYMBOL_GPL(bcma_bus_register); | ||
164 | 163 | ||
165 | void bcma_bus_unregister(struct bcma_bus *bus) | 164 | void bcma_bus_unregister(struct bcma_bus *bus) |
166 | { | 165 | { |
167 | bcma_unregister_cores(bus); | 166 | bcma_unregister_cores(bus); |
168 | } | 167 | } |
169 | EXPORT_SYMBOL_GPL(bcma_bus_unregister); | ||
170 | 168 | ||
171 | int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) | 169 | int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) |
172 | { | 170 | { |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 085560e1d17a..cced4fd31fe2 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -2336,7 +2336,7 @@ static struct ssb_driver b44_ssb_driver = { | |||
2336 | .resume = b44_resume, | 2336 | .resume = b44_resume, |
2337 | }; | 2337 | }; |
2338 | 2338 | ||
2339 | static inline int b44_pci_init(void) | 2339 | static inline int __init b44_pci_init(void) |
2340 | { | 2340 | { |
2341 | int err = 0; | 2341 | int err = 0; |
2342 | #ifdef CONFIG_B44_PCI | 2342 | #ifdef CONFIG_B44_PCI |
@@ -2345,7 +2345,7 @@ static inline int b44_pci_init(void) | |||
2345 | return err; | 2345 | return err; |
2346 | } | 2346 | } |
2347 | 2347 | ||
2348 | static inline void b44_pci_exit(void) | 2348 | static inline void __exit b44_pci_exit(void) |
2349 | { | 2349 | { |
2350 | #ifdef CONFIG_B44_PCI | 2350 | #ifdef CONFIG_B44_PCI |
2351 | ssb_pcihost_unregister(&b44_pci_driver); | 2351 | ssb_pcihost_unregister(&b44_pci_driver); |
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index ea9982781559..c38e9e848995 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
@@ -219,6 +219,7 @@ static int ath_ahb_remove(struct platform_device *pdev) | |||
219 | 219 | ||
220 | ath5k_deinit_softc(sc); | 220 | ath5k_deinit_softc(sc); |
221 | platform_set_drvdata(pdev, NULL); | 221 | platform_set_drvdata(pdev, NULL); |
222 | ieee80211_free_hw(hw); | ||
222 | 223 | ||
223 | return 0; | 224 | return 0; |
224 | } | 225 | } |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index bb50700436fe..c4c02d5145c2 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -767,6 +767,7 @@ struct ath5k_athchan_2ghz { | |||
767 | */ | 767 | */ |
768 | 768 | ||
769 | #define AR5K_KEYCACHE_SIZE 8 | 769 | #define AR5K_KEYCACHE_SIZE 8 |
770 | extern int ath5k_modparam_nohwcrypt; | ||
770 | 771 | ||
771 | /***********************\ | 772 | /***********************\ |
772 | HW RELATED DEFINITIONS | 773 | HW RELATED DEFINITIONS |
@@ -1180,8 +1181,8 @@ void ath5k_sysfs_unregister(struct ath5k_softc *sc); | |||
1180 | struct ath5k_buf; | 1181 | struct ath5k_buf; |
1181 | struct ath5k_txq; | 1182 | struct ath5k_txq; |
1182 | 1183 | ||
1183 | void set_beacon_filter(struct ieee80211_hw *hw, bool enable); | 1184 | void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable); |
1184 | bool ath_any_vif_assoc(struct ath5k_softc *sc); | 1185 | bool ath5k_any_vif_assoc(struct ath5k_softc *sc); |
1185 | void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | 1186 | void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, |
1186 | struct ath5k_txq *txq); | 1187 | struct ath5k_txq *txq); |
1187 | int ath5k_init_hw(struct ath5k_softc *sc); | 1188 | int ath5k_init_hw(struct ath5k_softc *sc); |
@@ -1253,7 +1254,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | |||
1253 | int len, struct ieee80211_rate *rate, bool shortpre); | 1254 | int len, struct ieee80211_rate *rate, bool shortpre); |
1254 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); | 1255 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); |
1255 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); | 1256 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); |
1256 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); | 1257 | int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); |
1257 | void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); | 1258 | void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); |
1258 | /* RX filter control*/ | 1259 | /* RX filter control*/ |
1259 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); | 1260 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 779a1d270243..fb05bf89b8e3 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -88,8 +88,6 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
88 | static int ath5k_init(struct ieee80211_hw *hw); | 88 | static int ath5k_init(struct ieee80211_hw *hw); |
89 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, | 89 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, |
90 | bool skip_pcu); | 90 | bool skip_pcu); |
91 | int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | ||
92 | void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); | ||
93 | 91 | ||
94 | /* Known SREVs */ | 92 | /* Known SREVs */ |
95 | static const struct ath5k_srev_name srev_names[] = { | 93 | static const struct ath5k_srev_name srev_names[] = { |
@@ -2162,7 +2160,7 @@ ath5k_schedule_tx(struct ath5k_softc *sc) | |||
2162 | tasklet_schedule(&sc->txtq); | 2160 | tasklet_schedule(&sc->txtq); |
2163 | } | 2161 | } |
2164 | 2162 | ||
2165 | irqreturn_t | 2163 | static irqreturn_t |
2166 | ath5k_intr(int irq, void *dev_id) | 2164 | ath5k_intr(int irq, void *dev_id) |
2167 | { | 2165 | { |
2168 | struct ath5k_softc *sc = dev_id; | 2166 | struct ath5k_softc *sc = dev_id; |
@@ -2616,7 +2614,7 @@ done: | |||
2616 | return ret; | 2614 | return ret; |
2617 | } | 2615 | } |
2618 | 2616 | ||
2619 | static void stop_tasklets(struct ath5k_softc *sc) | 2617 | static void ath5k_stop_tasklets(struct ath5k_softc *sc) |
2620 | { | 2618 | { |
2621 | sc->rx_pending = false; | 2619 | sc->rx_pending = false; |
2622 | sc->tx_pending = false; | 2620 | sc->tx_pending = false; |
@@ -2670,7 +2668,7 @@ ath5k_stop_hw(struct ath5k_softc *sc) | |||
2670 | mmiowb(); | 2668 | mmiowb(); |
2671 | mutex_unlock(&sc->lock); | 2669 | mutex_unlock(&sc->lock); |
2672 | 2670 | ||
2673 | stop_tasklets(sc); | 2671 | ath5k_stop_tasklets(sc); |
2674 | 2672 | ||
2675 | cancel_delayed_work_sync(&sc->tx_complete_work); | 2673 | cancel_delayed_work_sync(&sc->tx_complete_work); |
2676 | 2674 | ||
@@ -2698,7 +2696,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, | |||
2698 | 2696 | ||
2699 | ath5k_hw_set_imr(ah, 0); | 2697 | ath5k_hw_set_imr(ah, 0); |
2700 | synchronize_irq(sc->irq); | 2698 | synchronize_irq(sc->irq); |
2701 | stop_tasklets(sc); | 2699 | ath5k_stop_tasklets(sc); |
2702 | 2700 | ||
2703 | /* Save ani mode and disable ANI during | 2701 | /* Save ani mode and disable ANI during |
2704 | * reset. If we don't we might get false | 2702 | * reset. If we don't we might get false |
@@ -2963,11 +2961,12 @@ ath5k_deinit_softc(struct ath5k_softc *sc) | |||
2963 | * state and potentially want to use them. | 2961 | * state and potentially want to use them. |
2964 | */ | 2962 | */ |
2965 | ath5k_hw_deinit(sc->ah); | 2963 | ath5k_hw_deinit(sc->ah); |
2964 | kfree(sc->ah); | ||
2966 | free_irq(sc->irq, sc); | 2965 | free_irq(sc->irq, sc); |
2967 | } | 2966 | } |
2968 | 2967 | ||
2969 | bool | 2968 | bool |
2970 | ath_any_vif_assoc(struct ath5k_softc *sc) | 2969 | ath5k_any_vif_assoc(struct ath5k_softc *sc) |
2971 | { | 2970 | { |
2972 | struct ath5k_vif_iter_data iter_data; | 2971 | struct ath5k_vif_iter_data iter_data; |
2973 | iter_data.hw_macaddr = NULL; | 2972 | iter_data.hw_macaddr = NULL; |
@@ -2981,7 +2980,7 @@ ath_any_vif_assoc(struct ath5k_softc *sc) | |||
2981 | } | 2980 | } |
2982 | 2981 | ||
2983 | void | 2982 | void |
2984 | set_beacon_filter(struct ieee80211_hw *hw, bool enable) | 2983 | ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable) |
2985 | { | 2984 | { |
2986 | struct ath5k_softc *sc = hw->priv; | 2985 | struct ath5k_softc *sc = hw->priv; |
2987 | struct ath5k_hw *ah = sc->ah; | 2986 | struct ath5k_hw *ah = sc->ah; |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 807bd6440169..493908299bb4 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -46,8 +46,6 @@ | |||
46 | #include "base.h" | 46 | #include "base.h" |
47 | #include "reg.h" | 47 | #include "reg.h" |
48 | 48 | ||
49 | extern int ath5k_modparam_nohwcrypt; | ||
50 | |||
51 | /********************\ | 49 | /********************\ |
52 | * Mac80211 functions * | 50 | * Mac80211 functions * |
53 | \********************/ | 51 | \********************/ |
@@ -296,10 +294,10 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
296 | if (bss_conf->assoc) | 294 | if (bss_conf->assoc) |
297 | sc->assoc = bss_conf->assoc; | 295 | sc->assoc = bss_conf->assoc; |
298 | else | 296 | else |
299 | sc->assoc = ath_any_vif_assoc(sc); | 297 | sc->assoc = ath5k_any_vif_assoc(sc); |
300 | 298 | ||
301 | if (sc->opmode == NL80211_IFTYPE_STATION) | 299 | if (sc->opmode == NL80211_IFTYPE_STATION) |
302 | set_beacon_filter(hw, sc->assoc); | 300 | ath5k_set_beacon_filter(hw, sc->assoc); |
303 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? | 301 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? |
304 | AR5K_LED_ASSOC : AR5K_LED_INIT); | 302 | AR5K_LED_ASSOC : AR5K_LED_INIT); |
305 | if (bss_conf->assoc) { | 303 | if (bss_conf->assoc) { |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 126a4eab35f3..1676a3e3dc3d 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -375,19 +375,19 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) | |||
375 | static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags) | 375 | static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags) |
376 | { | 376 | { |
377 | u32 mask = flags ? flags : ~0U; | 377 | u32 mask = flags ? flags : ~0U; |
378 | volatile u32 *reg; | 378 | volatile __iomem u32 *reg; |
379 | u32 regval; | 379 | u32 regval; |
380 | u32 val = 0; | 380 | u32 val = 0; |
381 | 381 | ||
382 | /* ah->ah_mac_srev is not available at this point yet */ | 382 | /* ah->ah_mac_srev is not available at this point yet */ |
383 | if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) { | 383 | if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) { |
384 | reg = (u32 *) AR5K_AR2315_RESET; | 384 | reg = (u32 __iomem *) AR5K_AR2315_RESET; |
385 | if (mask & AR5K_RESET_CTL_PCU) | 385 | if (mask & AR5K_RESET_CTL_PCU) |
386 | val |= AR5K_AR2315_RESET_WMAC; | 386 | val |= AR5K_AR2315_RESET_WMAC; |
387 | if (mask & AR5K_RESET_CTL_BASEBAND) | 387 | if (mask & AR5K_RESET_CTL_BASEBAND) |
388 | val |= AR5K_AR2315_RESET_BB_WARM; | 388 | val |= AR5K_AR2315_RESET_BB_WARM; |
389 | } else { | 389 | } else { |
390 | reg = (u32 *) AR5K_AR5312_RESET; | 390 | reg = (u32 __iomem *) AR5K_AR5312_RESET; |
391 | if (to_platform_device(ah->ah_sc->dev)->id == 0) { | 391 | if (to_platform_device(ah->ah_sc->dev)->id == 0) { |
392 | if (mask & AR5K_RESET_CTL_PCU) | 392 | if (mask & AR5K_RESET_CTL_PCU) |
393 | val |= AR5K_AR5312_RESET_WMAC0; | 393 | val |= AR5K_AR5312_RESET_WMAC0; |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 5b49cd03bfdf..0b36fcf8a280 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -27,6 +27,10 @@ static const struct platform_device_id ath9k_platform_id_table[] = { | |||
27 | .driver_data = AR5416_AR9100_DEVID, | 27 | .driver_data = AR5416_AR9100_DEVID, |
28 | }, | 28 | }, |
29 | { | 29 | { |
30 | .name = "ar933x_wmac", | ||
31 | .driver_data = AR9300_DEVID_AR9330, | ||
32 | }, | ||
33 | { | ||
30 | .name = "ar934x_wmac", | 34 | .name = "ar934x_wmac", |
31 | .driver_data = AR9300_DEVID_AR9340, | 35 | .driver_data = AR9300_DEVID_AR9340, |
32 | }, | 36 | }, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index ff8150e46f0e..1d09f22fee4d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -1461,7 +1461,7 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1461 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, | 1461 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
1462 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, | 1462 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
1463 | 1463 | ||
1464 | { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, | 1464 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, |
1465 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, | 1465 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
1466 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, | 1466 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
1467 | 1467 | ||
@@ -2616,7 +2616,7 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2616 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, | 2616 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
2617 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, | 2617 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
2618 | 2618 | ||
2619 | { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, | 2619 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, |
2620 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, | 2620 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
2621 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, | 2621 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
2622 | 2622 | ||
@@ -3324,6 +3324,8 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, | |||
3324 | read = ar9300_read_eeprom; | 3324 | read = ar9300_read_eeprom; |
3325 | if (AR_SREV_9485(ah)) | 3325 | if (AR_SREV_9485(ah)) |
3326 | cptr = AR9300_BASE_ADDR_4K; | 3326 | cptr = AR9300_BASE_ADDR_4K; |
3327 | else if (AR_SREV_9330(ah)) | ||
3328 | cptr = AR9300_BASE_ADDR_512; | ||
3327 | else | 3329 | else |
3328 | cptr = AR9300_BASE_ADDR; | 3330 | cptr = AR9300_BASE_ADDR; |
3329 | ath_dbg(common, ATH_DBG_EEPROM, | 3331 | ath_dbg(common, ATH_DBG_EEPROM, |
@@ -3442,7 +3444,7 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) | |||
3442 | { | 3444 | { |
3443 | int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); | 3445 | int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); |
3444 | 3446 | ||
3445 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | 3447 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) |
3446 | REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); | 3448 | REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); |
3447 | else { | 3449 | else { |
3448 | REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); | 3450 | REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); |
@@ -3523,7 +3525,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | |||
3523 | } | 3525 | } |
3524 | } | 3526 | } |
3525 | 3527 | ||
3526 | if (AR_SREV_9485(ah)) { | 3528 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { |
3527 | value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1); | 3529 | value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1); |
3528 | /* | 3530 | /* |
3529 | * main_lnaconf, alt_lnaconf, main_tb, alt_tb | 3531 | * main_lnaconf, alt_lnaconf, main_tb, alt_tb |
@@ -3710,7 +3712,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | |||
3710 | ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); | 3712 | ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); |
3711 | 3713 | ||
3712 | if (internal_regulator) { | 3714 | if (internal_regulator) { |
3713 | if (AR_SREV_9485(ah)) { | 3715 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { |
3714 | int reg_pmu_set; | 3716 | int reg_pmu_set; |
3715 | 3717 | ||
3716 | reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM; | 3718 | reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM; |
@@ -3718,9 +3720,24 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | |||
3718 | if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) | 3720 | if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) |
3719 | return; | 3721 | return; |
3720 | 3722 | ||
3721 | reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) | | 3723 | if (AR_SREV_9330(ah)) { |
3722 | (2 << 14) | (6 << 17) | (1 << 20) | | 3724 | if (ah->is_clk_25mhz) { |
3723 | (3 << 24) | (1 << 28); | 3725 | reg_pmu_set = (3 << 1) | (8 << 4) | |
3726 | (3 << 8) | (1 << 14) | | ||
3727 | (6 << 17) | (1 << 20) | | ||
3728 | (3 << 24); | ||
3729 | } else { | ||
3730 | reg_pmu_set = (4 << 1) | (7 << 4) | | ||
3731 | (3 << 8) | (1 << 14) | | ||
3732 | (6 << 17) | (1 << 20) | | ||
3733 | (3 << 24); | ||
3734 | } | ||
3735 | } else { | ||
3736 | reg_pmu_set = (5 << 1) | (7 << 4) | | ||
3737 | (1 << 8) | (2 << 14) | | ||
3738 | (6 << 17) | (1 << 20) | | ||
3739 | (3 << 24) | (1 << 28); | ||
3740 | } | ||
3724 | 3741 | ||
3725 | REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set); | 3742 | REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set); |
3726 | if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set)) | 3743 | if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set)) |
@@ -3751,7 +3768,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | |||
3751 | AR_RTC_REG_CONTROL1_SWREG_PROGRAM); | 3768 | AR_RTC_REG_CONTROL1_SWREG_PROGRAM); |
3752 | } | 3769 | } |
3753 | } else { | 3770 | } else { |
3754 | if (AR_SREV_9485(ah)) { | 3771 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { |
3755 | REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0); | 3772 | REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0); |
3756 | while (REG_READ_FIELD(ah, AR_PHY_PMU2, | 3773 | while (REG_READ_FIELD(ah, AR_PHY_PMU2, |
3757 | AR_PHY_PMU2_PGM)) | 3774 | AR_PHY_PMU2_PGM)) |
@@ -3795,9 +3812,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | |||
3795 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | 3812 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); |
3796 | ar9003_hw_drive_strength_apply(ah); | 3813 | ar9003_hw_drive_strength_apply(ah); |
3797 | ar9003_hw_atten_apply(ah, chan); | 3814 | ar9003_hw_atten_apply(ah, chan); |
3798 | if (!AR_SREV_9340(ah)) | 3815 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) |
3799 | ar9003_hw_internal_regulator_apply(ah); | 3816 | ar9003_hw_internal_regulator_apply(ah); |
3800 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | 3817 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) |
3801 | ar9003_hw_apply_tuning_caps(ah); | 3818 | ar9003_hw_apply_tuning_caps(ah); |
3802 | } | 3819 | } |
3803 | 3820 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 392bf0f8ff16..8efdec247c02 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include "ar9003_2p2_initvals.h" | 19 | #include "ar9003_2p2_initvals.h" |
20 | #include "ar9485_initvals.h" | 20 | #include "ar9485_initvals.h" |
21 | #include "ar9340_initvals.h" | 21 | #include "ar9340_initvals.h" |
22 | #include "ar9330_1p1_initvals.h" | ||
23 | #include "ar9330_1p2_initvals.h" | ||
22 | 24 | ||
23 | /* General hardware code for the AR9003 hadware family */ | 25 | /* General hardware code for the AR9003 hadware family */ |
24 | 26 | ||
@@ -29,7 +31,113 @@ | |||
29 | */ | 31 | */ |
30 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | 32 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) |
31 | { | 33 | { |
32 | if (AR_SREV_9340(ah)) { | 34 | if (AR_SREV_9330_11(ah)) { |
35 | /* mac */ | ||
36 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
37 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||
38 | ar9331_1p1_mac_core, | ||
39 | ARRAY_SIZE(ar9331_1p1_mac_core), 2); | ||
40 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | ||
41 | ar9331_1p1_mac_postamble, | ||
42 | ARRAY_SIZE(ar9331_1p1_mac_postamble), 5); | ||
43 | |||
44 | /* bb */ | ||
45 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
46 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | ||
47 | ar9331_1p1_baseband_core, | ||
48 | ARRAY_SIZE(ar9331_1p1_baseband_core), 2); | ||
49 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | ||
50 | ar9331_1p1_baseband_postamble, | ||
51 | ARRAY_SIZE(ar9331_1p1_baseband_postamble), 5); | ||
52 | |||
53 | /* radio */ | ||
54 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
55 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | ||
56 | ar9331_1p1_radio_core, | ||
57 | ARRAY_SIZE(ar9331_1p1_radio_core), 2); | ||
58 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0); | ||
59 | |||
60 | /* soc */ | ||
61 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | ||
62 | ar9331_1p1_soc_preamble, | ||
63 | ARRAY_SIZE(ar9331_1p1_soc_preamble), 2); | ||
64 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
65 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | ||
66 | ar9331_1p1_soc_postamble, | ||
67 | ARRAY_SIZE(ar9331_1p1_soc_postamble), 2); | ||
68 | |||
69 | /* rx/tx gain */ | ||
70 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
71 | ar9331_common_rx_gain_1p1, | ||
72 | ARRAY_SIZE(ar9331_common_rx_gain_1p1), 2); | ||
73 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
74 | ar9331_modes_lowest_ob_db_tx_gain_1p1, | ||
75 | ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1), | ||
76 | 5); | ||
77 | |||
78 | /* additional clock settings */ | ||
79 | if (ah->is_clk_25mhz) | ||
80 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
81 | ar9331_1p1_xtal_25M, | ||
82 | ARRAY_SIZE(ar9331_1p1_xtal_25M), 2); | ||
83 | else | ||
84 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
85 | ar9331_1p1_xtal_40M, | ||
86 | ARRAY_SIZE(ar9331_1p1_xtal_40M), 2); | ||
87 | } else if (AR_SREV_9330_12(ah)) { | ||
88 | /* mac */ | ||
89 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
90 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||
91 | ar9331_1p2_mac_core, | ||
92 | ARRAY_SIZE(ar9331_1p2_mac_core), 2); | ||
93 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | ||
94 | ar9331_1p2_mac_postamble, | ||
95 | ARRAY_SIZE(ar9331_1p2_mac_postamble), 5); | ||
96 | |||
97 | /* bb */ | ||
98 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
99 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | ||
100 | ar9331_1p2_baseband_core, | ||
101 | ARRAY_SIZE(ar9331_1p2_baseband_core), 2); | ||
102 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | ||
103 | ar9331_1p2_baseband_postamble, | ||
104 | ARRAY_SIZE(ar9331_1p2_baseband_postamble), 5); | ||
105 | |||
106 | /* radio */ | ||
107 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
108 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | ||
109 | ar9331_1p2_radio_core, | ||
110 | ARRAY_SIZE(ar9331_1p2_radio_core), 2); | ||
111 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0); | ||
112 | |||
113 | /* soc */ | ||
114 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | ||
115 | ar9331_1p2_soc_preamble, | ||
116 | ARRAY_SIZE(ar9331_1p2_soc_preamble), 2); | ||
117 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
118 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | ||
119 | ar9331_1p2_soc_postamble, | ||
120 | ARRAY_SIZE(ar9331_1p2_soc_postamble), 2); | ||
121 | |||
122 | /* rx/tx gain */ | ||
123 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
124 | ar9331_common_rx_gain_1p2, | ||
125 | ARRAY_SIZE(ar9331_common_rx_gain_1p2), 2); | ||
126 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
127 | ar9331_modes_lowest_ob_db_tx_gain_1p2, | ||
128 | ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2), | ||
129 | 5); | ||
130 | |||
131 | /* additional clock settings */ | ||
132 | if (ah->is_clk_25mhz) | ||
133 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
134 | ar9331_1p2_xtal_25M, | ||
135 | ARRAY_SIZE(ar9331_1p2_xtal_25M), 2); | ||
136 | else | ||
137 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
138 | ar9331_1p2_xtal_40M, | ||
139 | ARRAY_SIZE(ar9331_1p2_xtal_40M), 2); | ||
140 | } else if (AR_SREV_9340(ah)) { | ||
33 | /* mac */ | 141 | /* mac */ |
34 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | 142 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); |
35 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 143 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
@@ -220,7 +328,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
220 | switch (ar9003_hw_get_tx_gain_idx(ah)) { | 328 | switch (ar9003_hw_get_tx_gain_idx(ah)) { |
221 | case 0: | 329 | case 0: |
222 | default: | 330 | default: |
223 | if (AR_SREV_9340(ah)) | 331 | if (AR_SREV_9330_12(ah)) |
332 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
333 | ar9331_modes_lowest_ob_db_tx_gain_1p2, | ||
334 | ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2), | ||
335 | 5); | ||
336 | else if (AR_SREV_9330_11(ah)) | ||
337 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
338 | ar9331_modes_lowest_ob_db_tx_gain_1p1, | ||
339 | ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1), | ||
340 | 5); | ||
341 | else if (AR_SREV_9340(ah)) | ||
224 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 342 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
225 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | 343 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, |
226 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | 344 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), |
@@ -237,7 +355,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
237 | 5); | 355 | 5); |
238 | break; | 356 | break; |
239 | case 1: | 357 | case 1: |
240 | if (AR_SREV_9340(ah)) | 358 | if (AR_SREV_9330_12(ah)) |
359 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
360 | ar9331_modes_high_ob_db_tx_gain_1p2, | ||
361 | ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2), | ||
362 | 5); | ||
363 | else if (AR_SREV_9330_11(ah)) | ||
364 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
365 | ar9331_modes_high_ob_db_tx_gain_1p1, | ||
366 | ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1), | ||
367 | 5); | ||
368 | else if (AR_SREV_9340(ah)) | ||
241 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 369 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
242 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | 370 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, |
243 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | 371 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), |
@@ -254,7 +382,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
254 | 5); | 382 | 5); |
255 | break; | 383 | break; |
256 | case 2: | 384 | case 2: |
257 | if (AR_SREV_9340(ah)) | 385 | if (AR_SREV_9330_12(ah)) |
386 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
387 | ar9331_modes_low_ob_db_tx_gain_1p2, | ||
388 | ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2), | ||
389 | 5); | ||
390 | else if (AR_SREV_9330_11(ah)) | ||
391 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
392 | ar9331_modes_low_ob_db_tx_gain_1p1, | ||
393 | ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1), | ||
394 | 5); | ||
395 | else if (AR_SREV_9340(ah)) | ||
258 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 396 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
259 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | 397 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, |
260 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | 398 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), |
@@ -271,7 +409,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
271 | 5); | 409 | 5); |
272 | break; | 410 | break; |
273 | case 3: | 411 | case 3: |
274 | if (AR_SREV_9340(ah)) | 412 | if (AR_SREV_9330_12(ah)) |
413 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
414 | ar9331_modes_high_power_tx_gain_1p2, | ||
415 | ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2), | ||
416 | 5); | ||
417 | else if (AR_SREV_9330_11(ah)) | ||
418 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
419 | ar9331_modes_high_power_tx_gain_1p1, | ||
420 | ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1), | ||
421 | 5); | ||
422 | else if (AR_SREV_9340(ah)) | ||
275 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 423 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
276 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | 424 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, |
277 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | 425 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), |
@@ -295,7 +443,17 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
295 | switch (ar9003_hw_get_rx_gain_idx(ah)) { | 443 | switch (ar9003_hw_get_rx_gain_idx(ah)) { |
296 | case 0: | 444 | case 0: |
297 | default: | 445 | default: |
298 | if (AR_SREV_9340(ah)) | 446 | if (AR_SREV_9330_12(ah)) |
447 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
448 | ar9331_common_rx_gain_1p2, | ||
449 | ARRAY_SIZE(ar9331_common_rx_gain_1p2), | ||
450 | 2); | ||
451 | else if (AR_SREV_9330_11(ah)) | ||
452 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
453 | ar9331_common_rx_gain_1p1, | ||
454 | ARRAY_SIZE(ar9331_common_rx_gain_1p1), | ||
455 | 2); | ||
456 | else if (AR_SREV_9340(ah)) | ||
299 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 457 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
300 | ar9340Common_rx_gain_table_1p0, | 458 | ar9340Common_rx_gain_table_1p0, |
301 | ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), | 459 | ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), |
@@ -312,7 +470,17 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
312 | 2); | 470 | 2); |
313 | break; | 471 | break; |
314 | case 1: | 472 | case 1: |
315 | if (AR_SREV_9340(ah)) | 473 | if (AR_SREV_9330_12(ah)) |
474 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
475 | ar9331_common_wo_xlna_rx_gain_1p2, | ||
476 | ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2), | ||
477 | 2); | ||
478 | else if (AR_SREV_9330_11(ah)) | ||
479 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
480 | ar9331_common_wo_xlna_rx_gain_1p1, | ||
481 | ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1), | ||
482 | 2); | ||
483 | else if (AR_SREV_9340(ah)) | ||
316 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 484 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
317 | ar9340Common_wo_xlna_rx_gain_table_1p0, | 485 | ar9340Common_wo_xlna_rx_gain_table_1p0, |
318 | ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), | 486 | ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2e7f0f2567eb..8f6d11dfa371 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
@@ -83,7 +83,23 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah) | |||
83 | if (delta > scale) | 83 | if (delta > scale) |
84 | return -1; | 84 | return -1; |
85 | 85 | ||
86 | power += 2 * get_streams(common->tx_chainmask); | 86 | switch (get_streams(common->tx_chainmask)) { |
87 | case 1: | ||
88 | delta = 6; | ||
89 | break; | ||
90 | case 2: | ||
91 | delta = 4; | ||
92 | break; | ||
93 | case 3: | ||
94 | delta = 2; | ||
95 | break; | ||
96 | default: | ||
97 | delta = 0; | ||
98 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
99 | "Invalid tx-chainmask: %u\n", common->tx_chainmask); | ||
100 | } | ||
101 | |||
102 | power += delta; | ||
87 | return power; | 103 | return power; |
88 | } | 104 | } |
89 | 105 | ||
@@ -785,7 +801,26 @@ EXPORT_SYMBOL(ar9003_paprd_init_table); | |||
785 | 801 | ||
786 | bool ar9003_paprd_is_done(struct ath_hw *ah) | 802 | bool ar9003_paprd_is_done(struct ath_hw *ah) |
787 | { | 803 | { |
788 | return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 804 | int paprd_done, agc2_pwr; |
805 | paprd_done = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, | ||
789 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); | 806 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); |
807 | |||
808 | if (paprd_done == 0x1) { | ||
809 | agc2_pwr = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, | ||
810 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR); | ||
811 | |||
812 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
813 | "AGC2_PWR = 0x%x training done = 0x%x\n", | ||
814 | agc2_pwr, paprd_done); | ||
815 | /* | ||
816 | * agc2_pwr range should not be less than 'IDEAL_AGC2_PWR_CHANGE' | ||
817 | * when the training is completely done, otherwise retraining is | ||
818 | * done to make sure the value is in ideal range | ||
819 | */ | ||
820 | if (agc2_pwr <= PAPRD_IDEAL_AGC2_PWR_RANGE) | ||
821 | paprd_done = 0; | ||
822 | } | ||
823 | |||
824 | return !!paprd_done; | ||
790 | } | 825 | } |
791 | EXPORT_SYMBOL(ar9003_paprd_is_done); | 826 | EXPORT_SYMBOL(ar9003_paprd_is_done); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 892c48b15434..1baca8e4715d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -75,7 +75,19 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
75 | freq = centers.synth_center; | 75 | freq = centers.synth_center; |
76 | 76 | ||
77 | if (freq < 4800) { /* 2 GHz, fractional mode */ | 77 | if (freq < 4800) { /* 2 GHz, fractional mode */ |
78 | if (AR_SREV_9485(ah)) { | 78 | if (AR_SREV_9330(ah)) { |
79 | u32 chan_frac; | ||
80 | u32 div; | ||
81 | |||
82 | if (ah->is_clk_25mhz) | ||
83 | div = 75; | ||
84 | else | ||
85 | div = 120; | ||
86 | |||
87 | channelSel = (freq * 4) / div; | ||
88 | chan_frac = (((freq * 4) % div) * 0x20000) / div; | ||
89 | channelSel = (channelSel << 17) | chan_frac; | ||
90 | } else if (AR_SREV_9485(ah)) { | ||
79 | u32 chan_frac; | 91 | u32 chan_frac; |
80 | 92 | ||
81 | /* | 93 | /* |
@@ -104,7 +116,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
104 | u32 chan_frac; | 116 | u32 chan_frac; |
105 | 117 | ||
106 | channelSel = (freq * 2) / 75; | 118 | channelSel = (freq * 2) / 75; |
107 | chan_frac = ((freq % 75) * 0x20000) / 75; | 119 | chan_frac = (((freq * 2) % 75) * 0x20000) / 75; |
108 | channelSel = (channelSel << 17) | chan_frac; | 120 | channelSel = (channelSel << 17) | chan_frac; |
109 | } else { | 121 | } else { |
110 | channelSel = CHANSEL_5G(freq); | 122 | channelSel = CHANSEL_5G(freq); |
@@ -168,7 +180,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
168 | * is out-of-band and can be ignored. | 180 | * is out-of-band and can be ignored. |
169 | */ | 181 | */ |
170 | 182 | ||
171 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) { | 183 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) { |
172 | spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, | 184 | spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, |
173 | IS_CHAN_2GHZ(chan)); | 185 | IS_CHAN_2GHZ(chan)); |
174 | if (spur_fbin_ptr[0] == 0) /* No spur */ | 186 | if (spur_fbin_ptr[0] == 0) /* No spur */ |
@@ -193,7 +205,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
193 | 205 | ||
194 | for (i = 0; i < max_spur_cnts; i++) { | 206 | for (i = 0; i < max_spur_cnts; i++) { |
195 | negative = 0; | 207 | negative = 0; |
196 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | 208 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) |
197 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], | 209 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], |
198 | IS_CHAN_2GHZ(chan)) - synth_freq; | 210 | IS_CHAN_2GHZ(chan)) - synth_freq; |
199 | else | 211 | else |
@@ -659,6 +671,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
659 | REG_WRITE_ARRAY(&ah->iniModesAdditional, | 671 | REG_WRITE_ARRAY(&ah->iniModesAdditional, |
660 | modesIndex, regWrites); | 672 | modesIndex, regWrites); |
661 | 673 | ||
674 | if (AR_SREV_9300(ah)) | ||
675 | REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); | ||
676 | |||
662 | if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) | 677 | if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) |
663 | REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); | 678 | REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); |
664 | 679 | ||
@@ -1074,7 +1089,10 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah) | |||
1074 | { | 1089 | { |
1075 | ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; | 1090 | ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; |
1076 | ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; | 1091 | ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; |
1077 | ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ; | 1092 | if (AR_SREV_9330(ah)) |
1093 | ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ; | ||
1094 | else | ||
1095 | ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ; | ||
1078 | ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; | 1096 | ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; |
1079 | ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; | 1097 | ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; |
1080 | ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ; | 1098 | ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ; |
@@ -1196,8 +1214,17 @@ static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, | |||
1196 | AR_PHY_9485_ANT_DIV_ALT_LNACONF_S; | 1214 | AR_PHY_9485_ANT_DIV_ALT_LNACONF_S; |
1197 | antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >> | 1215 | antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >> |
1198 | AR_PHY_9485_ANT_FAST_DIV_BIAS_S; | 1216 | AR_PHY_9485_ANT_FAST_DIV_BIAS_S; |
1199 | antconf->lna1_lna2_delta = -9; | 1217 | |
1200 | antconf->div_group = 2; | 1218 | if (AR_SREV_9330_11(ah)) { |
1219 | antconf->lna1_lna2_delta = -9; | ||
1220 | antconf->div_group = 1; | ||
1221 | } else if (AR_SREV_9485(ah)) { | ||
1222 | antconf->lna1_lna2_delta = -9; | ||
1223 | antconf->div_group = 2; | ||
1224 | } else { | ||
1225 | antconf->lna1_lna2_delta = -3; | ||
1226 | antconf->div_group = 0; | ||
1227 | } | ||
1201 | } | 1228 | } |
1202 | 1229 | ||
1203 | static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah, | 1230 | static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 443090d278e3..9eb3aa211688 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -332,6 +332,8 @@ | |||
332 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95 | 332 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95 |
333 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100 | 333 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100 |
334 | 334 | ||
335 | #define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118 | ||
336 | |||
335 | /* | 337 | /* |
336 | * AGC Field Definitions | 338 | * AGC Field Definitions |
337 | */ | 339 | */ |
@@ -623,11 +625,11 @@ | |||
623 | #define AR_PHY_65NM_CH2_RXTX1 0x16900 | 625 | #define AR_PHY_65NM_CH2_RXTX1 0x16900 |
624 | #define AR_PHY_65NM_CH2_RXTX2 0x16904 | 626 | #define AR_PHY_65NM_CH2_RXTX2 0x16904 |
625 | 627 | ||
626 | #define AR_CH0_TOP2 (AR_SREV_9485(ah) ? 0x00016284 : 0x0001628c) | 628 | #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : 0x16284) |
627 | #define AR_CH0_TOP2_XPABIASLVL 0xf000 | 629 | #define AR_CH0_TOP2_XPABIASLVL 0xf000 |
628 | #define AR_CH0_TOP2_XPABIASLVL_S 12 | 630 | #define AR_CH0_TOP2_XPABIASLVL_S 12 |
629 | 631 | ||
630 | #define AR_CH0_XTAL (AR_SREV_9485(ah) ? 0x16290 : 0x16294) | 632 | #define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : 0x16290) |
631 | #define AR_CH0_XTAL_CAPINDAC 0x7f000000 | 633 | #define AR_CH0_XTAL_CAPINDAC 0x7f000000 |
632 | #define AR_CH0_XTAL_CAPINDAC_S 24 | 634 | #define AR_CH0_XTAL_CAPINDAC_S 24 |
633 | #define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 | 635 | #define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h new file mode 100644 index 000000000000..f11d9b2677fd --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h | |||
@@ -0,0 +1,1147 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef INITVALS_9330_1P1_H | ||
18 | #define INITVALS_9330_1P1_H | ||
19 | |||
20 | static const u32 ar9331_1p1_baseband_postamble[][5] = { | ||
21 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
22 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, | ||
23 | {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, | ||
24 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | ||
25 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | ||
26 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
27 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, | ||
28 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, | ||
29 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, | ||
30 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, | ||
31 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | ||
32 | {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, | ||
33 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | ||
34 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
35 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
36 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
37 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00003221, 0x00003221}, | ||
38 | {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222}, | ||
39 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, | ||
40 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, | ||
41 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
42 | {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, | ||
43 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
44 | {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, | ||
45 | {0x0000a234, 0x00000fff, 0x00000fff, 0x10000fff, 0x00000fff}, | ||
46 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, | ||
47 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
48 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
49 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
50 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | ||
51 | {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, | ||
52 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | ||
53 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
54 | {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
55 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
56 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
57 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
58 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, | ||
59 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | ||
60 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
61 | {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, | ||
62 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
63 | }; | ||
64 | |||
65 | static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p1[][5] = { | ||
66 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
67 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, | ||
68 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, | ||
69 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, | ||
70 | {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000}, | ||
71 | {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, | ||
72 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d0, 0x000050d0}, | ||
73 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
74 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
75 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
76 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
77 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
78 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
79 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
80 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
81 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, | ||
82 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, | ||
83 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, | ||
84 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2d000a20, 0x2d000a20}, | ||
85 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000a22, 0x31000a22}, | ||
86 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000a24, 0x35000a24}, | ||
87 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000a43, 0x38000a43}, | ||
88 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3b000e42, 0x3b000e42}, | ||
89 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x3f000e44, 0x3f000e44}, | ||
90 | {0x0000a544, 0x6502feca, 0x6502feca, 0x42000e64, 0x42000e64}, | ||
91 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46000e66, 0x46000e66}, | ||
92 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x4a000ea6, 0x4a000ea6}, | ||
93 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4a000ea6, 0x4a000ea6}, | ||
94 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4a000ea6, 0x4a000ea6}, | ||
95 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x4a000ea6, 0x4a000ea6}, | ||
96 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x4a000ea6, 0x4a000ea6}, | ||
97 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
98 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x4a000ea6, 0x4a000ea6}, | ||
99 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
100 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
101 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
102 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
103 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
104 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
105 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
106 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
107 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
108 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, | ||
109 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, | ||
110 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, | ||
111 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, | ||
112 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, | ||
113 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, | ||
114 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, | ||
115 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, | ||
116 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, | ||
117 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, | ||
118 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, | ||
119 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, | ||
120 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, | ||
121 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, | ||
122 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, | ||
123 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, | ||
124 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, | ||
125 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, | ||
126 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, | ||
127 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, | ||
128 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, | ||
129 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, | ||
130 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, | ||
131 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
132 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
133 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
134 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
135 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
136 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
137 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
138 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
139 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
140 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
141 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
142 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
143 | {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, | ||
144 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, | ||
145 | {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802}, | ||
146 | {0x0000a624, 0x03010a03, 0x03010a03, 0x03010a03, 0x03010a03}, | ||
147 | {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
148 | {0x0000a62c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
149 | {0x0000a630, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
150 | {0x0000a634, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
151 | {0x0000a638, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
152 | {0x0000a63c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
153 | {0x00016044, 0x034922db, 0x034922db, 0x034922db, 0x034922db}, | ||
154 | {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, | ||
155 | }; | ||
156 | |||
157 | static const u32 ar9331_modes_high_ob_db_tx_gain_1p1[][5] = { | ||
158 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
159 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, | ||
160 | {0x0000a2dc, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52, 0xffaa9a52}, | ||
161 | {0x0000a2e0, 0xffb31c84, 0xffb31c84, 0xffb31c84, 0xffb31c84}, | ||
162 | {0x0000a2e4, 0xff43e000, 0xff43e000, 0xff43e000, 0xff43e000}, | ||
163 | {0x0000a2e8, 0xfffc0000, 0xfffc0000, 0xfffc0000, 0xfffc0000}, | ||
164 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, | ||
165 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
166 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
167 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
168 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
169 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
170 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
171 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
172 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
173 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, | ||
174 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, | ||
175 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, | ||
176 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x3d001620, 0x3d001620}, | ||
177 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x3f001621, 0x3f001621}, | ||
178 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x42001640, 0x42001640}, | ||
179 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x44001641, 0x44001641}, | ||
180 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x46001642, 0x46001642}, | ||
181 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49001644, 0x49001644}, | ||
182 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4c001a81, 0x4c001a81}, | ||
183 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4f001a83, 0x4f001a83}, | ||
184 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x52001c84, 0x52001c84}, | ||
185 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001ce3, 0x55001ce3}, | ||
186 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x59001ce5, 0x59001ce5}, | ||
187 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5d001ce9, 0x5d001ce9}, | ||
188 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x64001eec, 0x64001eec}, | ||
189 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x64001eec, 0x64001eec}, | ||
190 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x64001eec, 0x64001eec}, | ||
191 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, | ||
192 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, | ||
193 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, | ||
194 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, | ||
195 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, | ||
196 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x64001eec, 0x64001eec}, | ||
197 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
198 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
199 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
200 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, | ||
201 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, | ||
202 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, | ||
203 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, | ||
204 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, | ||
205 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, | ||
206 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, | ||
207 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, | ||
208 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, | ||
209 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, | ||
210 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, | ||
211 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, | ||
212 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, | ||
213 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, | ||
214 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, | ||
215 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, | ||
216 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, | ||
217 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, | ||
218 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, | ||
219 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, | ||
220 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, | ||
221 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, | ||
222 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, | ||
223 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
224 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
225 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
226 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
227 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
228 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
229 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
230 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
231 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
232 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
233 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
234 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
235 | {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, | ||
236 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, | ||
237 | {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802}, | ||
238 | {0x0000a624, 0x0280ca03, 0x0280ca03, 0x0280ca03, 0x0280ca03}, | ||
239 | {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
240 | {0x0000a62c, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, | ||
241 | {0x0000a630, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, | ||
242 | {0x0000a634, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, | ||
243 | {0x0000a638, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, | ||
244 | {0x0000a63c, 0x04015005, 0x04015005, 0x04015005, 0x04015005}, | ||
245 | }; | ||
246 | |||
247 | static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { | ||
248 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
249 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, | ||
250 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, | ||
251 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, | ||
252 | {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000}, | ||
253 | {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, | ||
254 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d0, 0x000050d0}, | ||
255 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
256 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
257 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
258 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
259 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
260 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
261 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
262 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
263 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, | ||
264 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, | ||
265 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, | ||
266 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2d000a20, 0x2d000a20}, | ||
267 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000a22, 0x31000a22}, | ||
268 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000a24, 0x35000a24}, | ||
269 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000a43, 0x38000a43}, | ||
270 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3b000e42, 0x3b000e42}, | ||
271 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x3f000e44, 0x3f000e44}, | ||
272 | {0x0000a544, 0x6502feca, 0x6502feca, 0x42000e64, 0x42000e64}, | ||
273 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46000e66, 0x46000e66}, | ||
274 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x4a000ea6, 0x4a000ea6}, | ||
275 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4a000ea6, 0x4a000ea6}, | ||
276 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4a000ea6, 0x4a000ea6}, | ||
277 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x4a000ea6, 0x4a000ea6}, | ||
278 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x4a000ea6, 0x4a000ea6}, | ||
279 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
280 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x4a000ea6, 0x4a000ea6}, | ||
281 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
282 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
283 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
284 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
285 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
286 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
287 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
288 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
289 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
290 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, | ||
291 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, | ||
292 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, | ||
293 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, | ||
294 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, | ||
295 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, | ||
296 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, | ||
297 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, | ||
298 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, | ||
299 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, | ||
300 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, | ||
301 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, | ||
302 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, | ||
303 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, | ||
304 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, | ||
305 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, | ||
306 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, | ||
307 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, | ||
308 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, | ||
309 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, | ||
310 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, | ||
311 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, | ||
312 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, | ||
313 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
314 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
315 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
316 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
317 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
318 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
319 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
320 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
321 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
322 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
323 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
324 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
325 | {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, | ||
326 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, | ||
327 | {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802}, | ||
328 | {0x0000a624, 0x03010a03, 0x03010a03, 0x03010a03, 0x03010a03}, | ||
329 | {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
330 | {0x0000a62c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
331 | {0x0000a630, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
332 | {0x0000a634, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
333 | {0x0000a638, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
334 | {0x0000a63c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
335 | {0x00016044, 0x034922db, 0x034922db, 0x034922db, 0x034922db}, | ||
336 | {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, | ||
337 | }; | ||
338 | |||
339 | static const u32 ar9331_1p1_baseband_core_txfir_coeff_japan_2484[][2] = { | ||
340 | /* Addr allmodes */ | ||
341 | {0x0000a398, 0x00000000}, | ||
342 | {0x0000a39c, 0x6f7f0301}, | ||
343 | {0x0000a3a0, 0xca9228ee}, | ||
344 | }; | ||
345 | |||
346 | static const u32 ar9331_1p1_xtal_25M[][2] = { | ||
347 | /* Addr allmodes */ | ||
348 | {0x00007038, 0x000002f8}, | ||
349 | {0x00008244, 0x0010f3d7}, | ||
350 | {0x0000824c, 0x0001e7ae}, | ||
351 | {0x0001609c, 0x0f508f29}, | ||
352 | }; | ||
353 | |||
354 | static const u32 ar9331_1p1_radio_core[][2] = { | ||
355 | /* Addr allmodes */ | ||
356 | {0x00016000, 0x36db6db6}, | ||
357 | {0x00016004, 0x6db6db40}, | ||
358 | {0x00016008, 0x73800000}, | ||
359 | {0x0001600c, 0x00000000}, | ||
360 | {0x00016040, 0x7f80fff8}, | ||
361 | {0x00016044, 0x03db62db}, | ||
362 | {0x00016048, 0x6c924268}, | ||
363 | {0x0001604c, 0x000f0278}, | ||
364 | {0x00016050, 0x4db6db8c}, | ||
365 | {0x00016054, 0x6db60000}, | ||
366 | {0x00016080, 0x00080000}, | ||
367 | {0x00016084, 0x0e48048c}, | ||
368 | {0x00016088, 0x14214514}, | ||
369 | {0x0001608c, 0x119f081c}, | ||
370 | {0x00016090, 0x24926490}, | ||
371 | {0x00016098, 0xd411eb84}, | ||
372 | {0x000160a0, 0xc2108ffe}, | ||
373 | {0x000160a4, 0x812fc370}, | ||
374 | {0x000160a8, 0x423c8000}, | ||
375 | {0x000160ac, 0x24651800}, | ||
376 | {0x000160b0, 0x03284f3e}, | ||
377 | {0x000160b4, 0x92480040}, | ||
378 | {0x000160c0, 0x006db6db}, | ||
379 | {0x000160c4, 0x0186db60}, | ||
380 | {0x000160c8, 0x6db6db6c}, | ||
381 | {0x000160cc, 0x6de6c300}, | ||
382 | {0x000160d0, 0x14500820}, | ||
383 | {0x00016100, 0x04cb0001}, | ||
384 | {0x00016104, 0xfff80015}, | ||
385 | {0x00016108, 0x00080010}, | ||
386 | {0x0001610c, 0x00170000}, | ||
387 | {0x00016140, 0x10804000}, | ||
388 | {0x00016144, 0x01884080}, | ||
389 | {0x00016148, 0x000080c0}, | ||
390 | {0x00016280, 0x01000015}, | ||
391 | {0x00016284, 0x14d20000}, | ||
392 | {0x00016288, 0x00318000}, | ||
393 | {0x0001628c, 0x50000000}, | ||
394 | {0x00016290, 0x4b96210f}, | ||
395 | {0x00016380, 0x00000000}, | ||
396 | {0x00016384, 0x00000000}, | ||
397 | {0x00016388, 0x00800700}, | ||
398 | {0x0001638c, 0x00800700}, | ||
399 | {0x00016390, 0x00800700}, | ||
400 | {0x00016394, 0x00000000}, | ||
401 | {0x00016398, 0x00000000}, | ||
402 | {0x0001639c, 0x00000000}, | ||
403 | {0x000163a0, 0x00000001}, | ||
404 | {0x000163a4, 0x00000001}, | ||
405 | {0x000163a8, 0x00000000}, | ||
406 | {0x000163ac, 0x00000000}, | ||
407 | {0x000163b0, 0x00000000}, | ||
408 | {0x000163b4, 0x00000000}, | ||
409 | {0x000163b8, 0x00000000}, | ||
410 | {0x000163bc, 0x00000000}, | ||
411 | {0x000163c0, 0x000000a0}, | ||
412 | {0x000163c4, 0x000c0000}, | ||
413 | {0x000163c8, 0x14021402}, | ||
414 | {0x000163cc, 0x00001402}, | ||
415 | {0x000163d0, 0x00000000}, | ||
416 | {0x000163d4, 0x00000000}, | ||
417 | }; | ||
418 | |||
419 | static const u32 ar9331_1p1_soc_postamble[][5] = { | ||
420 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
421 | {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, | ||
422 | }; | ||
423 | |||
424 | static const u32 ar9331_common_wo_xlna_rx_gain_1p1[][2] = { | ||
425 | /* Addr allmodes */ | ||
426 | {0x0000a000, 0x00060005}, | ||
427 | {0x0000a004, 0x00810080}, | ||
428 | {0x0000a008, 0x00830082}, | ||
429 | {0x0000a00c, 0x00850084}, | ||
430 | {0x0000a010, 0x01820181}, | ||
431 | {0x0000a014, 0x01840183}, | ||
432 | {0x0000a018, 0x01880185}, | ||
433 | {0x0000a01c, 0x018a0189}, | ||
434 | {0x0000a020, 0x02850284}, | ||
435 | {0x0000a024, 0x02890288}, | ||
436 | {0x0000a028, 0x028b028a}, | ||
437 | {0x0000a02c, 0x03850384}, | ||
438 | {0x0000a030, 0x03890388}, | ||
439 | {0x0000a034, 0x038b038a}, | ||
440 | {0x0000a038, 0x038d038c}, | ||
441 | {0x0000a03c, 0x03910390}, | ||
442 | {0x0000a040, 0x03930392}, | ||
443 | {0x0000a044, 0x03950394}, | ||
444 | {0x0000a048, 0x00000396}, | ||
445 | {0x0000a04c, 0x00000000}, | ||
446 | {0x0000a050, 0x00000000}, | ||
447 | {0x0000a054, 0x00000000}, | ||
448 | {0x0000a058, 0x00000000}, | ||
449 | {0x0000a05c, 0x00000000}, | ||
450 | {0x0000a060, 0x00000000}, | ||
451 | {0x0000a064, 0x00000000}, | ||
452 | {0x0000a068, 0x00000000}, | ||
453 | {0x0000a06c, 0x00000000}, | ||
454 | {0x0000a070, 0x00000000}, | ||
455 | {0x0000a074, 0x00000000}, | ||
456 | {0x0000a078, 0x00000000}, | ||
457 | {0x0000a07c, 0x00000000}, | ||
458 | {0x0000a080, 0x28282828}, | ||
459 | {0x0000a084, 0x28282828}, | ||
460 | {0x0000a088, 0x28282828}, | ||
461 | {0x0000a08c, 0x28282828}, | ||
462 | {0x0000a090, 0x28282828}, | ||
463 | {0x0000a094, 0x24242428}, | ||
464 | {0x0000a098, 0x171e1e1e}, | ||
465 | {0x0000a09c, 0x02020b0b}, | ||
466 | {0x0000a0a0, 0x02020202}, | ||
467 | {0x0000a0a4, 0x00000000}, | ||
468 | {0x0000a0a8, 0x00000000}, | ||
469 | {0x0000a0ac, 0x00000000}, | ||
470 | {0x0000a0b0, 0x00000000}, | ||
471 | {0x0000a0b4, 0x00000000}, | ||
472 | {0x0000a0b8, 0x00000000}, | ||
473 | {0x0000a0bc, 0x00000000}, | ||
474 | {0x0000a0c0, 0x22072208}, | ||
475 | {0x0000a0c4, 0x22052206}, | ||
476 | {0x0000a0c8, 0x22032204}, | ||
477 | {0x0000a0cc, 0x22012202}, | ||
478 | {0x0000a0d0, 0x221f2200}, | ||
479 | {0x0000a0d4, 0x221d221e}, | ||
480 | {0x0000a0d8, 0x33023303}, | ||
481 | {0x0000a0dc, 0x33003301}, | ||
482 | {0x0000a0e0, 0x331e331f}, | ||
483 | {0x0000a0e4, 0x4402331d}, | ||
484 | {0x0000a0e8, 0x44004401}, | ||
485 | {0x0000a0ec, 0x441e441f}, | ||
486 | {0x0000a0f0, 0x55025503}, | ||
487 | {0x0000a0f4, 0x55005501}, | ||
488 | {0x0000a0f8, 0x551e551f}, | ||
489 | {0x0000a0fc, 0x6602551d}, | ||
490 | {0x0000a100, 0x66006601}, | ||
491 | {0x0000a104, 0x661e661f}, | ||
492 | {0x0000a108, 0x7703661d}, | ||
493 | {0x0000a10c, 0x77017702}, | ||
494 | {0x0000a110, 0x00007700}, | ||
495 | {0x0000a114, 0x00000000}, | ||
496 | {0x0000a118, 0x00000000}, | ||
497 | {0x0000a11c, 0x00000000}, | ||
498 | {0x0000a120, 0x00000000}, | ||
499 | {0x0000a124, 0x00000000}, | ||
500 | {0x0000a128, 0x00000000}, | ||
501 | {0x0000a12c, 0x00000000}, | ||
502 | {0x0000a130, 0x00000000}, | ||
503 | {0x0000a134, 0x00000000}, | ||
504 | {0x0000a138, 0x00000000}, | ||
505 | {0x0000a13c, 0x00000000}, | ||
506 | {0x0000a140, 0x001f0000}, | ||
507 | {0x0000a144, 0x111f1100}, | ||
508 | {0x0000a148, 0x111d111e}, | ||
509 | {0x0000a14c, 0x111b111c}, | ||
510 | {0x0000a150, 0x22032204}, | ||
511 | {0x0000a154, 0x22012202}, | ||
512 | {0x0000a158, 0x221f2200}, | ||
513 | {0x0000a15c, 0x221d221e}, | ||
514 | {0x0000a160, 0x33013302}, | ||
515 | {0x0000a164, 0x331f3300}, | ||
516 | {0x0000a168, 0x4402331e}, | ||
517 | {0x0000a16c, 0x44004401}, | ||
518 | {0x0000a170, 0x441e441f}, | ||
519 | {0x0000a174, 0x55015502}, | ||
520 | {0x0000a178, 0x551f5500}, | ||
521 | {0x0000a17c, 0x6602551e}, | ||
522 | {0x0000a180, 0x66006601}, | ||
523 | {0x0000a184, 0x661e661f}, | ||
524 | {0x0000a188, 0x7703661d}, | ||
525 | {0x0000a18c, 0x77017702}, | ||
526 | {0x0000a190, 0x00007700}, | ||
527 | {0x0000a194, 0x00000000}, | ||
528 | {0x0000a198, 0x00000000}, | ||
529 | {0x0000a19c, 0x00000000}, | ||
530 | {0x0000a1a0, 0x00000000}, | ||
531 | {0x0000a1a4, 0x00000000}, | ||
532 | {0x0000a1a8, 0x00000000}, | ||
533 | {0x0000a1ac, 0x00000000}, | ||
534 | {0x0000a1b0, 0x00000000}, | ||
535 | {0x0000a1b4, 0x00000000}, | ||
536 | {0x0000a1b8, 0x00000000}, | ||
537 | {0x0000a1bc, 0x00000000}, | ||
538 | {0x0000a1c0, 0x00000000}, | ||
539 | {0x0000a1c4, 0x00000000}, | ||
540 | {0x0000a1c8, 0x00000000}, | ||
541 | {0x0000a1cc, 0x00000000}, | ||
542 | {0x0000a1d0, 0x00000000}, | ||
543 | {0x0000a1d4, 0x00000000}, | ||
544 | {0x0000a1d8, 0x00000000}, | ||
545 | {0x0000a1dc, 0x00000000}, | ||
546 | {0x0000a1e0, 0x00000000}, | ||
547 | {0x0000a1e4, 0x00000000}, | ||
548 | {0x0000a1e8, 0x00000000}, | ||
549 | {0x0000a1ec, 0x00000000}, | ||
550 | {0x0000a1f0, 0x00000396}, | ||
551 | {0x0000a1f4, 0x00000396}, | ||
552 | {0x0000a1f8, 0x00000396}, | ||
553 | {0x0000a1fc, 0x00000296}, | ||
554 | }; | ||
555 | |||
556 | static const u32 ar9331_1p1_baseband_core[][2] = { | ||
557 | /* Addr allmodes */ | ||
558 | {0x00009800, 0xafe68e30}, | ||
559 | {0x00009804, 0xfd14e000}, | ||
560 | {0x00009808, 0x9c0a8f6b}, | ||
561 | {0x0000980c, 0x04800000}, | ||
562 | {0x00009814, 0x9280c00a}, | ||
563 | {0x00009818, 0x00000000}, | ||
564 | {0x0000981c, 0x00020028}, | ||
565 | {0x00009834, 0x5f3ca3de}, | ||
566 | {0x00009838, 0x0108ecff}, | ||
567 | {0x0000983c, 0x14750600}, | ||
568 | {0x00009880, 0x201fff00}, | ||
569 | {0x00009884, 0x00001042}, | ||
570 | {0x000098a4, 0x00200400}, | ||
571 | {0x000098b0, 0x32840bbe}, | ||
572 | {0x000098d0, 0x004b6a8e}, | ||
573 | {0x000098d4, 0x00000820}, | ||
574 | {0x000098dc, 0x00000000}, | ||
575 | {0x000098f0, 0x00000000}, | ||
576 | {0x000098f4, 0x00000000}, | ||
577 | {0x00009c04, 0x00000000}, | ||
578 | {0x00009c08, 0x03200000}, | ||
579 | {0x00009c0c, 0x00000000}, | ||
580 | {0x00009c10, 0x00000000}, | ||
581 | {0x00009c14, 0x00046384}, | ||
582 | {0x00009c18, 0x05b6b440}, | ||
583 | {0x00009c1c, 0x00b6b440}, | ||
584 | {0x00009d00, 0xc080a333}, | ||
585 | {0x00009d04, 0x40206c10}, | ||
586 | {0x00009d08, 0x009c4060}, | ||
587 | {0x00009d0c, 0x1883800a}, | ||
588 | {0x00009d10, 0x01834061}, | ||
589 | {0x00009d14, 0x00c00400}, | ||
590 | {0x00009d18, 0x00000000}, | ||
591 | {0x00009e08, 0x0038233c}, | ||
592 | {0x00009e24, 0x9927b515}, | ||
593 | {0x00009e28, 0x12ef0200}, | ||
594 | {0x00009e30, 0x06336f77}, | ||
595 | {0x00009e34, 0x6af6532f}, | ||
596 | {0x00009e38, 0x0cc80c00}, | ||
597 | {0x00009e40, 0x0d261820}, | ||
598 | {0x00009e4c, 0x00001004}, | ||
599 | {0x00009e50, 0x00ff03f1}, | ||
600 | {0x00009fc0, 0x803e4788}, | ||
601 | {0x00009fc4, 0x0001efb5}, | ||
602 | {0x00009fcc, 0x40000014}, | ||
603 | {0x0000a20c, 0x00000000}, | ||
604 | {0x0000a220, 0x00000000}, | ||
605 | {0x0000a224, 0x00000000}, | ||
606 | {0x0000a228, 0x10002310}, | ||
607 | {0x0000a23c, 0x00000000}, | ||
608 | {0x0000a244, 0x0c000000}, | ||
609 | {0x0000a2a0, 0x00000001}, | ||
610 | {0x0000a2c0, 0x00000001}, | ||
611 | {0x0000a2c8, 0x00000000}, | ||
612 | {0x0000a2cc, 0x18c43433}, | ||
613 | {0x0000a2d4, 0x00000000}, | ||
614 | {0x0000a2dc, 0x00000000}, | ||
615 | {0x0000a2e0, 0x00000000}, | ||
616 | {0x0000a2e4, 0x00000000}, | ||
617 | {0x0000a2e8, 0x00000000}, | ||
618 | {0x0000a2ec, 0x00000000}, | ||
619 | {0x0000a2f0, 0x00000000}, | ||
620 | {0x0000a2f4, 0x00000000}, | ||
621 | {0x0000a2f8, 0x00000000}, | ||
622 | {0x0000a344, 0x00000000}, | ||
623 | {0x0000a34c, 0x00000000}, | ||
624 | {0x0000a350, 0x0000a000}, | ||
625 | {0x0000a364, 0x00000000}, | ||
626 | {0x0000a370, 0x00000000}, | ||
627 | {0x0000a390, 0x00000001}, | ||
628 | {0x0000a394, 0x00000444}, | ||
629 | {0x0000a398, 0x001f0e0f}, | ||
630 | {0x0000a39c, 0x0075393f}, | ||
631 | {0x0000a3a0, 0xb79f6427}, | ||
632 | {0x0000a3a4, 0x00000000}, | ||
633 | {0x0000a3a8, 0xaaaaaaaa}, | ||
634 | {0x0000a3ac, 0x3c466478}, | ||
635 | {0x0000a3c0, 0x20202020}, | ||
636 | {0x0000a3c4, 0x22222220}, | ||
637 | {0x0000a3c8, 0x20200020}, | ||
638 | {0x0000a3cc, 0x20202020}, | ||
639 | {0x0000a3d0, 0x20202020}, | ||
640 | {0x0000a3d4, 0x20202020}, | ||
641 | {0x0000a3d8, 0x20202020}, | ||
642 | {0x0000a3dc, 0x20202020}, | ||
643 | {0x0000a3e0, 0x20202020}, | ||
644 | {0x0000a3e4, 0x20202020}, | ||
645 | {0x0000a3e8, 0x20202020}, | ||
646 | {0x0000a3ec, 0x20202020}, | ||
647 | {0x0000a3f0, 0x00000000}, | ||
648 | {0x0000a3f4, 0x00000006}, | ||
649 | {0x0000a3f8, 0x0cdbd380}, | ||
650 | {0x0000a3fc, 0x000f0f01}, | ||
651 | {0x0000a400, 0x8fa91f01}, | ||
652 | {0x0000a404, 0x00000000}, | ||
653 | {0x0000a408, 0x0e79e5c6}, | ||
654 | {0x0000a40c, 0x00820820}, | ||
655 | {0x0000a414, 0x1ce739ce}, | ||
656 | {0x0000a418, 0x2d001dce}, | ||
657 | {0x0000a41c, 0x1ce739ce}, | ||
658 | {0x0000a420, 0x000001ce}, | ||
659 | {0x0000a424, 0x1ce739ce}, | ||
660 | {0x0000a428, 0x000001ce}, | ||
661 | {0x0000a42c, 0x1ce739ce}, | ||
662 | {0x0000a430, 0x1ce739ce}, | ||
663 | {0x0000a434, 0x00000000}, | ||
664 | {0x0000a438, 0x00001801}, | ||
665 | {0x0000a43c, 0x00000000}, | ||
666 | {0x0000a440, 0x00000000}, | ||
667 | {0x0000a444, 0x00000000}, | ||
668 | {0x0000a448, 0x04000000}, | ||
669 | {0x0000a44c, 0x00000001}, | ||
670 | {0x0000a450, 0x00010000}, | ||
671 | {0x0000a458, 0x00000000}, | ||
672 | {0x0000a640, 0x00000000}, | ||
673 | {0x0000a644, 0x3fad9d74}, | ||
674 | {0x0000a648, 0x0048060a}, | ||
675 | {0x0000a64c, 0x00003c37}, | ||
676 | {0x0000a670, 0x03020100}, | ||
677 | {0x0000a674, 0x09080504}, | ||
678 | {0x0000a678, 0x0d0c0b0a}, | ||
679 | {0x0000a67c, 0x13121110}, | ||
680 | {0x0000a680, 0x31301514}, | ||
681 | {0x0000a684, 0x35343332}, | ||
682 | {0x0000a688, 0x00000036}, | ||
683 | {0x0000a690, 0x00000838}, | ||
684 | {0x0000a7c0, 0x00000000}, | ||
685 | {0x0000a7c4, 0xfffffffc}, | ||
686 | {0x0000a7c8, 0x00000000}, | ||
687 | {0x0000a7cc, 0x00000000}, | ||
688 | {0x0000a7d0, 0x00000000}, | ||
689 | {0x0000a7d4, 0x00000004}, | ||
690 | {0x0000a7dc, 0x00000001}, | ||
691 | }; | ||
692 | |||
693 | static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { | ||
694 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
695 | {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, | ||
696 | {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, | ||
697 | {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, | ||
698 | {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000}, | ||
699 | {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, | ||
700 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d0, 0x000050d0}, | ||
701 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
702 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
703 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
704 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
705 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
706 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
707 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
708 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
709 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, | ||
710 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, | ||
711 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, | ||
712 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2d000a20, 0x2d000a20}, | ||
713 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000a22, 0x31000a22}, | ||
714 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000a24, 0x35000a24}, | ||
715 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000a43, 0x38000a43}, | ||
716 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3b000e42, 0x3b000e42}, | ||
717 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x3f000e44, 0x3f000e44}, | ||
718 | {0x0000a544, 0x6502feca, 0x6502feca, 0x42000e64, 0x42000e64}, | ||
719 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46000e66, 0x46000e66}, | ||
720 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x4a000ea6, 0x4a000ea6}, | ||
721 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4a000ea6, 0x4a000ea6}, | ||
722 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4a000ea6, 0x4a000ea6}, | ||
723 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x4a000ea6, 0x4a000ea6}, | ||
724 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x4a000ea6, 0x4a000ea6}, | ||
725 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
726 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x4a000ea6, 0x4a000ea6}, | ||
727 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
728 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
729 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
730 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
731 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
732 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6}, | ||
733 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
734 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
735 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
736 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, | ||
737 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, | ||
738 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, | ||
739 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, | ||
740 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, | ||
741 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, | ||
742 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, | ||
743 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, | ||
744 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, | ||
745 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, | ||
746 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, | ||
747 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, | ||
748 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, | ||
749 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, | ||
750 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, | ||
751 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, | ||
752 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, | ||
753 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, | ||
754 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, | ||
755 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, | ||
756 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, | ||
757 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, | ||
758 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, | ||
759 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
760 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
761 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
762 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
763 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
764 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
765 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
766 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
767 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
768 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
769 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
770 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
771 | {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, | ||
772 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, | ||
773 | {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802}, | ||
774 | {0x0000a624, 0x03010a03, 0x03010a03, 0x03010a03, 0x03010a03}, | ||
775 | {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
776 | {0x0000a62c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
777 | {0x0000a630, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
778 | {0x0000a634, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
779 | {0x0000a638, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
780 | {0x0000a63c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04}, | ||
781 | {0x00016044, 0x034922db, 0x034922db, 0x034922db, 0x034922db}, | ||
782 | {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, | ||
783 | }; | ||
784 | |||
785 | static const u32 ar9331_1p1_mac_postamble[][5] = { | ||
786 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
787 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | ||
788 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | ||
789 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | ||
790 | {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, | ||
791 | {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, | ||
792 | {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, | ||
793 | {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, | ||
794 | {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, | ||
795 | }; | ||
796 | |||
797 | static const u32 ar9331_1p1_soc_preamble[][2] = { | ||
798 | /* Addr allmodes */ | ||
799 | {0x00007020, 0x00000000}, | ||
800 | {0x00007034, 0x00000002}, | ||
801 | {0x00007038, 0x000002f8}, | ||
802 | }; | ||
803 | |||
804 | static const u32 ar9331_1p1_xtal_40M[][2] = { | ||
805 | /* Addr allmodes */ | ||
806 | {0x00007038, 0x000004c2}, | ||
807 | {0x00008244, 0x0010f400}, | ||
808 | {0x0000824c, 0x0001e800}, | ||
809 | {0x0001609c, 0x0b283f31}, | ||
810 | }; | ||
811 | |||
812 | static const u32 ar9331_1p1_mac_core[][2] = { | ||
813 | /* Addr allmodes */ | ||
814 | {0x00000008, 0x00000000}, | ||
815 | {0x00000030, 0x00020085}, | ||
816 | {0x00000034, 0x00000005}, | ||
817 | {0x00000040, 0x00000000}, | ||
818 | {0x00000044, 0x00000000}, | ||
819 | {0x00000048, 0x00000008}, | ||
820 | {0x0000004c, 0x00000010}, | ||
821 | {0x00000050, 0x00000000}, | ||
822 | {0x00001040, 0x002ffc0f}, | ||
823 | {0x00001044, 0x002ffc0f}, | ||
824 | {0x00001048, 0x002ffc0f}, | ||
825 | {0x0000104c, 0x002ffc0f}, | ||
826 | {0x00001050, 0x002ffc0f}, | ||
827 | {0x00001054, 0x002ffc0f}, | ||
828 | {0x00001058, 0x002ffc0f}, | ||
829 | {0x0000105c, 0x002ffc0f}, | ||
830 | {0x00001060, 0x002ffc0f}, | ||
831 | {0x00001064, 0x002ffc0f}, | ||
832 | {0x000010f0, 0x00000100}, | ||
833 | {0x00001270, 0x00000000}, | ||
834 | {0x000012b0, 0x00000000}, | ||
835 | {0x000012f0, 0x00000000}, | ||
836 | {0x0000143c, 0x00000000}, | ||
837 | {0x0000147c, 0x00000000}, | ||
838 | {0x00008000, 0x00000000}, | ||
839 | {0x00008004, 0x00000000}, | ||
840 | {0x00008008, 0x00000000}, | ||
841 | {0x0000800c, 0x00000000}, | ||
842 | {0x00008018, 0x00000000}, | ||
843 | {0x00008020, 0x00000000}, | ||
844 | {0x00008038, 0x00000000}, | ||
845 | {0x0000803c, 0x00000000}, | ||
846 | {0x00008040, 0x00000000}, | ||
847 | {0x00008044, 0x00000000}, | ||
848 | {0x00008048, 0x00000000}, | ||
849 | {0x0000804c, 0xffffffff}, | ||
850 | {0x00008054, 0x00000000}, | ||
851 | {0x00008058, 0x00000000}, | ||
852 | {0x0000805c, 0x000fc78f}, | ||
853 | {0x00008060, 0x0000000f}, | ||
854 | {0x00008064, 0x00000000}, | ||
855 | {0x00008070, 0x00000310}, | ||
856 | {0x00008074, 0x00000020}, | ||
857 | {0x00008078, 0x00000000}, | ||
858 | {0x0000809c, 0x0000000f}, | ||
859 | {0x000080a0, 0x00000000}, | ||
860 | {0x000080a4, 0x02ff0000}, | ||
861 | {0x000080a8, 0x0e070605}, | ||
862 | {0x000080ac, 0x0000000d}, | ||
863 | {0x000080b0, 0x00000000}, | ||
864 | {0x000080b4, 0x00000000}, | ||
865 | {0x000080b8, 0x00000000}, | ||
866 | {0x000080bc, 0x00000000}, | ||
867 | {0x000080c0, 0x2a800000}, | ||
868 | {0x000080c4, 0x06900168}, | ||
869 | {0x000080c8, 0x13881c20}, | ||
870 | {0x000080cc, 0x01f40000}, | ||
871 | {0x000080d0, 0x00252500}, | ||
872 | {0x000080d4, 0x00a00000}, | ||
873 | {0x000080d8, 0x00400000}, | ||
874 | {0x000080dc, 0x00000000}, | ||
875 | {0x000080e0, 0xffffffff}, | ||
876 | {0x000080e4, 0x0000ffff}, | ||
877 | {0x000080e8, 0x3f3f3f3f}, | ||
878 | {0x000080ec, 0x00000000}, | ||
879 | {0x000080f0, 0x00000000}, | ||
880 | {0x000080f4, 0x00000000}, | ||
881 | {0x000080fc, 0x00020000}, | ||
882 | {0x00008100, 0x00000000}, | ||
883 | {0x00008108, 0x00000052}, | ||
884 | {0x0000810c, 0x00000000}, | ||
885 | {0x00008110, 0x00000000}, | ||
886 | {0x00008114, 0x000007ff}, | ||
887 | {0x00008118, 0x000000aa}, | ||
888 | {0x0000811c, 0x00003210}, | ||
889 | {0x00008124, 0x00000000}, | ||
890 | {0x00008128, 0x00000000}, | ||
891 | {0x0000812c, 0x00000000}, | ||
892 | {0x00008130, 0x00000000}, | ||
893 | {0x00008134, 0x00000000}, | ||
894 | {0x00008138, 0x00000000}, | ||
895 | {0x0000813c, 0x0000ffff}, | ||
896 | {0x00008144, 0xffffffff}, | ||
897 | {0x00008168, 0x00000000}, | ||
898 | {0x0000816c, 0x00000000}, | ||
899 | {0x00008170, 0x18486200}, | ||
900 | {0x00008174, 0x33332210}, | ||
901 | {0x00008178, 0x00000000}, | ||
902 | {0x0000817c, 0x00020000}, | ||
903 | {0x000081c0, 0x00000000}, | ||
904 | {0x000081c4, 0x33332210}, | ||
905 | {0x000081c8, 0x00000000}, | ||
906 | {0x000081cc, 0x00000000}, | ||
907 | {0x000081d4, 0x00000000}, | ||
908 | {0x000081ec, 0x00000000}, | ||
909 | {0x000081f0, 0x00000000}, | ||
910 | {0x000081f4, 0x00000000}, | ||
911 | {0x000081f8, 0x00000000}, | ||
912 | {0x000081fc, 0x00000000}, | ||
913 | {0x00008240, 0x00100000}, | ||
914 | {0x00008248, 0x00000800}, | ||
915 | {0x00008250, 0x00000000}, | ||
916 | {0x00008254, 0x00000000}, | ||
917 | {0x00008258, 0x00000000}, | ||
918 | {0x0000825c, 0x40000000}, | ||
919 | {0x00008260, 0x00080922}, | ||
920 | {0x00008264, 0x9d400010}, | ||
921 | {0x00008268, 0xffffffff}, | ||
922 | {0x0000826c, 0x0000ffff}, | ||
923 | {0x00008270, 0x00000000}, | ||
924 | {0x00008274, 0x40000000}, | ||
925 | {0x00008278, 0x003e4180}, | ||
926 | {0x0000827c, 0x00000004}, | ||
927 | {0x00008284, 0x0000002c}, | ||
928 | {0x00008288, 0x0000002c}, | ||
929 | {0x0000828c, 0x000000ff}, | ||
930 | {0x00008294, 0x00000000}, | ||
931 | {0x00008298, 0x00000000}, | ||
932 | {0x0000829c, 0x00000000}, | ||
933 | {0x00008300, 0x00000140}, | ||
934 | {0x00008314, 0x00000000}, | ||
935 | {0x0000831c, 0x0000010d}, | ||
936 | {0x00008328, 0x00000000}, | ||
937 | {0x0000832c, 0x00000007}, | ||
938 | {0x00008330, 0x00000302}, | ||
939 | {0x00008334, 0x00000700}, | ||
940 | {0x00008338, 0x00ff0000}, | ||
941 | {0x0000833c, 0x02400000}, | ||
942 | {0x00008340, 0x000107ff}, | ||
943 | {0x00008344, 0xaa48105b}, | ||
944 | {0x00008348, 0x008f0000}, | ||
945 | {0x0000835c, 0x00000000}, | ||
946 | {0x00008360, 0xffffffff}, | ||
947 | {0x00008364, 0xffffffff}, | ||
948 | {0x00008368, 0x00000000}, | ||
949 | {0x00008370, 0x00000000}, | ||
950 | {0x00008374, 0x000000ff}, | ||
951 | {0x00008378, 0x00000000}, | ||
952 | {0x0000837c, 0x00000000}, | ||
953 | {0x00008380, 0xffffffff}, | ||
954 | {0x00008384, 0xffffffff}, | ||
955 | {0x00008390, 0xffffffff}, | ||
956 | {0x00008394, 0xffffffff}, | ||
957 | {0x00008398, 0x00000000}, | ||
958 | {0x0000839c, 0x00000000}, | ||
959 | {0x000083a0, 0x00000000}, | ||
960 | {0x000083a4, 0x0000fa14}, | ||
961 | {0x000083a8, 0x000f0c00}, | ||
962 | {0x000083ac, 0x33332210}, | ||
963 | {0x000083b0, 0x33332210}, | ||
964 | {0x000083b4, 0x33332210}, | ||
965 | {0x000083b8, 0x33332210}, | ||
966 | {0x000083bc, 0x00000000}, | ||
967 | {0x000083c0, 0x00000000}, | ||
968 | {0x000083c4, 0x00000000}, | ||
969 | {0x000083c8, 0x00000000}, | ||
970 | {0x000083cc, 0x00000200}, | ||
971 | {0x000083d0, 0x000301ff}, | ||
972 | }; | ||
973 | |||
974 | static const u32 ar9331_common_rx_gain_1p1[][2] = { | ||
975 | /* Addr allmodes */ | ||
976 | {0x0000a000, 0x00010000}, | ||
977 | {0x0000a004, 0x00030002}, | ||
978 | {0x0000a008, 0x00050004}, | ||
979 | {0x0000a00c, 0x00810080}, | ||
980 | {0x0000a010, 0x00830082}, | ||
981 | {0x0000a014, 0x01810180}, | ||
982 | {0x0000a018, 0x01830182}, | ||
983 | {0x0000a01c, 0x01850184}, | ||
984 | {0x0000a020, 0x01890188}, | ||
985 | {0x0000a024, 0x018b018a}, | ||
986 | {0x0000a028, 0x018d018c}, | ||
987 | {0x0000a02c, 0x01910190}, | ||
988 | {0x0000a030, 0x01930192}, | ||
989 | {0x0000a034, 0x01950194}, | ||
990 | {0x0000a038, 0x038a0196}, | ||
991 | {0x0000a03c, 0x038c038b}, | ||
992 | {0x0000a040, 0x0390038d}, | ||
993 | {0x0000a044, 0x03920391}, | ||
994 | {0x0000a048, 0x03940393}, | ||
995 | {0x0000a04c, 0x03960395}, | ||
996 | {0x0000a050, 0x00000000}, | ||
997 | {0x0000a054, 0x00000000}, | ||
998 | {0x0000a058, 0x00000000}, | ||
999 | {0x0000a05c, 0x00000000}, | ||
1000 | {0x0000a060, 0x00000000}, | ||
1001 | {0x0000a064, 0x00000000}, | ||
1002 | {0x0000a068, 0x00000000}, | ||
1003 | {0x0000a06c, 0x00000000}, | ||
1004 | {0x0000a070, 0x00000000}, | ||
1005 | {0x0000a074, 0x00000000}, | ||
1006 | {0x0000a078, 0x00000000}, | ||
1007 | {0x0000a07c, 0x00000000}, | ||
1008 | {0x0000a080, 0x22222229}, | ||
1009 | {0x0000a084, 0x1d1d1d1d}, | ||
1010 | {0x0000a088, 0x1d1d1d1d}, | ||
1011 | {0x0000a08c, 0x1d1d1d1d}, | ||
1012 | {0x0000a090, 0x171d1d1d}, | ||
1013 | {0x0000a094, 0x11111717}, | ||
1014 | {0x0000a098, 0x00030311}, | ||
1015 | {0x0000a09c, 0x00000000}, | ||
1016 | {0x0000a0a0, 0x00000000}, | ||
1017 | {0x0000a0a4, 0x00000000}, | ||
1018 | {0x0000a0a8, 0x00000000}, | ||
1019 | {0x0000a0ac, 0x00000000}, | ||
1020 | {0x0000a0b0, 0x00000000}, | ||
1021 | {0x0000a0b4, 0x00000000}, | ||
1022 | {0x0000a0b8, 0x00000000}, | ||
1023 | {0x0000a0bc, 0x00000000}, | ||
1024 | {0x0000a0c0, 0x001f0000}, | ||
1025 | {0x0000a0c4, 0x01000101}, | ||
1026 | {0x0000a0c8, 0x011e011f}, | ||
1027 | {0x0000a0cc, 0x011c011d}, | ||
1028 | {0x0000a0d0, 0x02030204}, | ||
1029 | {0x0000a0d4, 0x02010202}, | ||
1030 | {0x0000a0d8, 0x021f0200}, | ||
1031 | {0x0000a0dc, 0x0302021e}, | ||
1032 | {0x0000a0e0, 0x03000301}, | ||
1033 | {0x0000a0e4, 0x031e031f}, | ||
1034 | {0x0000a0e8, 0x0402031d}, | ||
1035 | {0x0000a0ec, 0x04000401}, | ||
1036 | {0x0000a0f0, 0x041e041f}, | ||
1037 | {0x0000a0f4, 0x0502041d}, | ||
1038 | {0x0000a0f8, 0x05000501}, | ||
1039 | {0x0000a0fc, 0x051e051f}, | ||
1040 | {0x0000a100, 0x06010602}, | ||
1041 | {0x0000a104, 0x061f0600}, | ||
1042 | {0x0000a108, 0x061d061e}, | ||
1043 | {0x0000a10c, 0x07020703}, | ||
1044 | {0x0000a110, 0x07000701}, | ||
1045 | {0x0000a114, 0x00000000}, | ||
1046 | {0x0000a118, 0x00000000}, | ||
1047 | {0x0000a11c, 0x00000000}, | ||
1048 | {0x0000a120, 0x00000000}, | ||
1049 | {0x0000a124, 0x00000000}, | ||
1050 | {0x0000a128, 0x00000000}, | ||
1051 | {0x0000a12c, 0x00000000}, | ||
1052 | {0x0000a130, 0x00000000}, | ||
1053 | {0x0000a134, 0x00000000}, | ||
1054 | {0x0000a138, 0x00000000}, | ||
1055 | {0x0000a13c, 0x00000000}, | ||
1056 | {0x0000a140, 0x001f0000}, | ||
1057 | {0x0000a144, 0x01000101}, | ||
1058 | {0x0000a148, 0x011e011f}, | ||
1059 | {0x0000a14c, 0x011c011d}, | ||
1060 | {0x0000a150, 0x02030204}, | ||
1061 | {0x0000a154, 0x02010202}, | ||
1062 | {0x0000a158, 0x021f0200}, | ||
1063 | {0x0000a15c, 0x0302021e}, | ||
1064 | {0x0000a160, 0x03000301}, | ||
1065 | {0x0000a164, 0x031e031f}, | ||
1066 | {0x0000a168, 0x0402031d}, | ||
1067 | {0x0000a16c, 0x04000401}, | ||
1068 | {0x0000a170, 0x041e041f}, | ||
1069 | {0x0000a174, 0x0502041d}, | ||
1070 | {0x0000a178, 0x05000501}, | ||
1071 | {0x0000a17c, 0x051e051f}, | ||
1072 | {0x0000a180, 0x06010602}, | ||
1073 | {0x0000a184, 0x061f0600}, | ||
1074 | {0x0000a188, 0x061d061e}, | ||
1075 | {0x0000a18c, 0x07020703}, | ||
1076 | {0x0000a190, 0x07000701}, | ||
1077 | {0x0000a194, 0x00000000}, | ||
1078 | {0x0000a198, 0x00000000}, | ||
1079 | {0x0000a19c, 0x00000000}, | ||
1080 | {0x0000a1a0, 0x00000000}, | ||
1081 | {0x0000a1a4, 0x00000000}, | ||
1082 | {0x0000a1a8, 0x00000000}, | ||
1083 | {0x0000a1ac, 0x00000000}, | ||
1084 | {0x0000a1b0, 0x00000000}, | ||
1085 | {0x0000a1b4, 0x00000000}, | ||
1086 | {0x0000a1b8, 0x00000000}, | ||
1087 | {0x0000a1bc, 0x00000000}, | ||
1088 | {0x0000a1c0, 0x00000000}, | ||
1089 | {0x0000a1c4, 0x00000000}, | ||
1090 | {0x0000a1c8, 0x00000000}, | ||
1091 | {0x0000a1cc, 0x00000000}, | ||
1092 | {0x0000a1d0, 0x00000000}, | ||
1093 | {0x0000a1d4, 0x00000000}, | ||
1094 | {0x0000a1d8, 0x00000000}, | ||
1095 | {0x0000a1dc, 0x00000000}, | ||
1096 | {0x0000a1e0, 0x00000000}, | ||
1097 | {0x0000a1e4, 0x00000000}, | ||
1098 | {0x0000a1e8, 0x00000000}, | ||
1099 | {0x0000a1ec, 0x00000000}, | ||
1100 | {0x0000a1f0, 0x00000396}, | ||
1101 | {0x0000a1f4, 0x00000396}, | ||
1102 | {0x0000a1f8, 0x00000396}, | ||
1103 | {0x0000a1fc, 0x00000196}, | ||
1104 | }; | ||
1105 | |||
1106 | static const u32 ar9331_common_tx_gain_offset1_1[][1] = { | ||
1107 | {0}, | ||
1108 | {3}, | ||
1109 | {0}, | ||
1110 | {0}, | ||
1111 | }; | ||
1112 | |||
1113 | static const u32 ar9331_1p1_chansel_xtal_25M[] = { | ||
1114 | 0x0101479e, | ||
1115 | 0x0101d027, | ||
1116 | 0x010258af, | ||
1117 | 0x0102e138, | ||
1118 | 0x010369c0, | ||
1119 | 0x0103f249, | ||
1120 | 0x01047ad1, | ||
1121 | 0x0105035a, | ||
1122 | 0x01058be2, | ||
1123 | 0x0106146b, | ||
1124 | 0x01069cf3, | ||
1125 | 0x0107257c, | ||
1126 | 0x0107ae04, | ||
1127 | 0x0108f5b2, | ||
1128 | }; | ||
1129 | |||
1130 | static const u32 ar9331_1p1_chansel_xtal_40M[] = { | ||
1131 | 0x00a0ccbe, | ||
1132 | 0x00a12213, | ||
1133 | 0x00a17769, | ||
1134 | 0x00a1ccbe, | ||
1135 | 0x00a22213, | ||
1136 | 0x00a27769, | ||
1137 | 0x00a2ccbe, | ||
1138 | 0x00a32213, | ||
1139 | 0x00a37769, | ||
1140 | 0x00a3ccbe, | ||
1141 | 0x00a42213, | ||
1142 | 0x00a47769, | ||
1143 | 0x00a4ccbe, | ||
1144 | 0x00a5998b, | ||
1145 | }; | ||
1146 | |||
1147 | #endif /* INITVALS_9330_1P1_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h new file mode 100644 index 000000000000..0e6ca0834b34 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h | |||
@@ -0,0 +1,1080 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef INITVALS_9330_1P2_H | ||
18 | #define INITVALS_9330_1P2_H | ||
19 | |||
20 | static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p2[][5] = { | ||
21 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
22 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, | ||
23 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
24 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
25 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
26 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
27 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
28 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
29 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
30 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
31 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, | ||
32 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, | ||
33 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, | ||
34 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, | ||
35 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, | ||
36 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, | ||
37 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, | ||
38 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, | ||
39 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, | ||
40 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, | ||
41 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, | ||
42 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, | ||
43 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, | ||
44 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, | ||
45 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, | ||
46 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, | ||
47 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, | ||
48 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, | ||
49 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
50 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
51 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
52 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
53 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
54 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
55 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
56 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
57 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
58 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, | ||
59 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, | ||
60 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, | ||
61 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, | ||
62 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, | ||
63 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, | ||
64 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, | ||
65 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, | ||
66 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, | ||
67 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, | ||
68 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, | ||
69 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, | ||
70 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, | ||
71 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, | ||
72 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, | ||
73 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, | ||
74 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, | ||
75 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, | ||
76 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, | ||
77 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, | ||
78 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, | ||
79 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, | ||
80 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, | ||
81 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
82 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
83 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
84 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
85 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
86 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
87 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
88 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
89 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
90 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
91 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
92 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
93 | {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, | ||
94 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, | ||
95 | {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, | ||
96 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, | ||
97 | {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
98 | {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
99 | {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
100 | {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
101 | {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
102 | {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
103 | }; | ||
104 | |||
105 | static const u32 ar9331_1p2_baseband_postamble[][5] = { | ||
106 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
107 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, | ||
108 | {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, | ||
109 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | ||
110 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | ||
111 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
112 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, | ||
113 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, | ||
114 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4}, | ||
115 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, | ||
116 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | ||
117 | {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e}, | ||
118 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | ||
119 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
120 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
121 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
122 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00003221, 0x00003221}, | ||
123 | {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222}, | ||
124 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, | ||
125 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, | ||
126 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
127 | {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, | ||
128 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
129 | {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, | ||
130 | {0x0000a234, 0x00000fff, 0x00000fff, 0x10000fff, 0x00000fff}, | ||
131 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, | ||
132 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
133 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
134 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
135 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | ||
136 | {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, | ||
137 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | ||
138 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
139 | {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
140 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
141 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
142 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
143 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981}, | ||
144 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | ||
145 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
146 | {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, | ||
147 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
148 | }; | ||
149 | |||
150 | static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { | ||
151 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
152 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, | ||
153 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
154 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
155 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
156 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
157 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
158 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
159 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
160 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
161 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, | ||
162 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, | ||
163 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, | ||
164 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, | ||
165 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, | ||
166 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, | ||
167 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, | ||
168 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, | ||
169 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, | ||
170 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, | ||
171 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, | ||
172 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, | ||
173 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, | ||
174 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, | ||
175 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, | ||
176 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, | ||
177 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, | ||
178 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, | ||
179 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
180 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
181 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
182 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
183 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
184 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
185 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
186 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
187 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
188 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, | ||
189 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, | ||
190 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, | ||
191 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, | ||
192 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, | ||
193 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, | ||
194 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, | ||
195 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, | ||
196 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, | ||
197 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, | ||
198 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, | ||
199 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, | ||
200 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, | ||
201 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, | ||
202 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, | ||
203 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, | ||
204 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, | ||
205 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, | ||
206 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, | ||
207 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, | ||
208 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, | ||
209 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, | ||
210 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, | ||
211 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
212 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
213 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
214 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
215 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
216 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
217 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
218 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
219 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
220 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
221 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
222 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
223 | {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, | ||
224 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, | ||
225 | {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, | ||
226 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, | ||
227 | {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
228 | {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
229 | {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
230 | {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
231 | {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
232 | {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
233 | }; | ||
234 | |||
235 | static const u32 ar9331_modes_low_ob_db_tx_gain_1p2[][5] = { | ||
236 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
237 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, | ||
238 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
239 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
240 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
241 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
242 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
243 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
244 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
245 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
246 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, | ||
247 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, | ||
248 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, | ||
249 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, | ||
250 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, | ||
251 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, | ||
252 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, | ||
253 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, | ||
254 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, | ||
255 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, | ||
256 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, | ||
257 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, | ||
258 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, | ||
259 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, | ||
260 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, | ||
261 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, | ||
262 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, | ||
263 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, | ||
264 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
265 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
266 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
267 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
268 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
269 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
270 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
271 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
272 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
273 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, | ||
274 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, | ||
275 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, | ||
276 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, | ||
277 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, | ||
278 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, | ||
279 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, | ||
280 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, | ||
281 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, | ||
282 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, | ||
283 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, | ||
284 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, | ||
285 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, | ||
286 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, | ||
287 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, | ||
288 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, | ||
289 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, | ||
290 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, | ||
291 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, | ||
292 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, | ||
293 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, | ||
294 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, | ||
295 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, | ||
296 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
297 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
298 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
299 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
300 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
301 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
302 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
303 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
304 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
305 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
306 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
307 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
308 | {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, | ||
309 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, | ||
310 | {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, | ||
311 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, | ||
312 | {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
313 | {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
314 | {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
315 | {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
316 | {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
317 | {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
318 | }; | ||
319 | |||
320 | static const u32 ar9331_1p2_baseband_core_txfir_coeff_japan_2484[][2] = { | ||
321 | /* Addr allmodes */ | ||
322 | {0x0000a398, 0x00000000}, | ||
323 | {0x0000a39c, 0x6f7f0301}, | ||
324 | {0x0000a3a0, 0xca9228ee}, | ||
325 | }; | ||
326 | |||
327 | static const u32 ar9331_1p2_xtal_25M[][2] = { | ||
328 | /* Addr allmodes */ | ||
329 | {0x00007038, 0x000002f8}, | ||
330 | {0x00008244, 0x0010f3d7}, | ||
331 | {0x0000824c, 0x0001e7ae}, | ||
332 | {0x0001609c, 0x0f508f29}, | ||
333 | }; | ||
334 | |||
335 | static const u32 ar9331_1p2_radio_core[][2] = { | ||
336 | /* Addr allmodes */ | ||
337 | {0x00016000, 0x36db6db6}, | ||
338 | {0x00016004, 0x6db6db40}, | ||
339 | {0x00016008, 0x73800000}, | ||
340 | {0x0001600c, 0x00000000}, | ||
341 | {0x00016040, 0x7f80fff8}, | ||
342 | {0x00016044, 0x03d6d2db}, | ||
343 | {0x00016048, 0x6c924268}, | ||
344 | {0x0001604c, 0x000f0278}, | ||
345 | {0x00016050, 0x4db6db8c}, | ||
346 | {0x00016054, 0x6db60000}, | ||
347 | {0x00016080, 0x00080000}, | ||
348 | {0x00016084, 0x0e48048c}, | ||
349 | {0x00016088, 0x14214514}, | ||
350 | {0x0001608c, 0x119f081c}, | ||
351 | {0x00016090, 0x24926490}, | ||
352 | {0x00016098, 0xd411eb84}, | ||
353 | {0x000160a0, 0xc2108ffe}, | ||
354 | {0x000160a4, 0x812fc370}, | ||
355 | {0x000160a8, 0x423c8000}, | ||
356 | {0x000160ac, 0x24651800}, | ||
357 | {0x000160b0, 0x03284f3e}, | ||
358 | {0x000160b4, 0x92480040}, | ||
359 | {0x000160c0, 0x006db6db}, | ||
360 | {0x000160c4, 0x0186db60}, | ||
361 | {0x000160c8, 0x6db6db6c}, | ||
362 | {0x000160cc, 0x6de6c300}, | ||
363 | {0x000160d0, 0x14500820}, | ||
364 | {0x00016100, 0x04cb0001}, | ||
365 | {0x00016104, 0xfff80015}, | ||
366 | {0x00016108, 0x00080010}, | ||
367 | {0x0001610c, 0x00170000}, | ||
368 | {0x00016140, 0x10804000}, | ||
369 | {0x00016144, 0x01884080}, | ||
370 | {0x00016148, 0x000080c0}, | ||
371 | {0x00016280, 0x01000015}, | ||
372 | {0x00016284, 0x14d20000}, | ||
373 | {0x00016288, 0x00318000}, | ||
374 | {0x0001628c, 0x50000000}, | ||
375 | {0x00016290, 0x4b96210f}, | ||
376 | {0x00016380, 0x00000000}, | ||
377 | {0x00016384, 0x00000000}, | ||
378 | {0x00016388, 0x00800700}, | ||
379 | {0x0001638c, 0x00800700}, | ||
380 | {0x00016390, 0x00800700}, | ||
381 | {0x00016394, 0x00000000}, | ||
382 | {0x00016398, 0x00000000}, | ||
383 | {0x0001639c, 0x00000000}, | ||
384 | {0x000163a0, 0x00000001}, | ||
385 | {0x000163a4, 0x00000001}, | ||
386 | {0x000163a8, 0x00000000}, | ||
387 | {0x000163ac, 0x00000000}, | ||
388 | {0x000163b0, 0x00000000}, | ||
389 | {0x000163b4, 0x00000000}, | ||
390 | {0x000163b8, 0x00000000}, | ||
391 | {0x000163bc, 0x00000000}, | ||
392 | {0x000163c0, 0x000000a0}, | ||
393 | {0x000163c4, 0x000c0000}, | ||
394 | {0x000163c8, 0x14021402}, | ||
395 | {0x000163cc, 0x00001402}, | ||
396 | {0x000163d0, 0x00000000}, | ||
397 | {0x000163d4, 0x00000000}, | ||
398 | }; | ||
399 | |||
400 | static const u32 ar9331_1p2_soc_postamble[][5] = { | ||
401 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
402 | {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, | ||
403 | }; | ||
404 | |||
405 | static const u32 ar9331_common_wo_xlna_rx_gain_1p2[][2] = { | ||
406 | /* Addr allmodes */ | ||
407 | {0x0000a000, 0x00060005}, | ||
408 | {0x0000a004, 0x00810080}, | ||
409 | {0x0000a008, 0x00830082}, | ||
410 | {0x0000a00c, 0x00850084}, | ||
411 | {0x0000a010, 0x01820181}, | ||
412 | {0x0000a014, 0x01840183}, | ||
413 | {0x0000a018, 0x01880185}, | ||
414 | {0x0000a01c, 0x018a0189}, | ||
415 | {0x0000a020, 0x02850284}, | ||
416 | {0x0000a024, 0x02890288}, | ||
417 | {0x0000a028, 0x028b028a}, | ||
418 | {0x0000a02c, 0x03850384}, | ||
419 | {0x0000a030, 0x03890388}, | ||
420 | {0x0000a034, 0x038b038a}, | ||
421 | {0x0000a038, 0x038d038c}, | ||
422 | {0x0000a03c, 0x03910390}, | ||
423 | {0x0000a040, 0x03930392}, | ||
424 | {0x0000a044, 0x03950394}, | ||
425 | {0x0000a048, 0x00000396}, | ||
426 | {0x0000a04c, 0x00000000}, | ||
427 | {0x0000a050, 0x00000000}, | ||
428 | {0x0000a054, 0x00000000}, | ||
429 | {0x0000a058, 0x00000000}, | ||
430 | {0x0000a05c, 0x00000000}, | ||
431 | {0x0000a060, 0x00000000}, | ||
432 | {0x0000a064, 0x00000000}, | ||
433 | {0x0000a068, 0x00000000}, | ||
434 | {0x0000a06c, 0x00000000}, | ||
435 | {0x0000a070, 0x00000000}, | ||
436 | {0x0000a074, 0x00000000}, | ||
437 | {0x0000a078, 0x00000000}, | ||
438 | {0x0000a07c, 0x00000000}, | ||
439 | {0x0000a080, 0x28282828}, | ||
440 | {0x0000a084, 0x28282828}, | ||
441 | {0x0000a088, 0x28282828}, | ||
442 | {0x0000a08c, 0x28282828}, | ||
443 | {0x0000a090, 0x28282828}, | ||
444 | {0x0000a094, 0x24242428}, | ||
445 | {0x0000a098, 0x171e1e1e}, | ||
446 | {0x0000a09c, 0x02020b0b}, | ||
447 | {0x0000a0a0, 0x02020202}, | ||
448 | {0x0000a0a4, 0x00000000}, | ||
449 | {0x0000a0a8, 0x00000000}, | ||
450 | {0x0000a0ac, 0x00000000}, | ||
451 | {0x0000a0b0, 0x00000000}, | ||
452 | {0x0000a0b4, 0x00000000}, | ||
453 | {0x0000a0b8, 0x00000000}, | ||
454 | {0x0000a0bc, 0x00000000}, | ||
455 | {0x0000a0c0, 0x22072208}, | ||
456 | {0x0000a0c4, 0x22052206}, | ||
457 | {0x0000a0c8, 0x22032204}, | ||
458 | {0x0000a0cc, 0x22012202}, | ||
459 | {0x0000a0d0, 0x221f2200}, | ||
460 | {0x0000a0d4, 0x221d221e}, | ||
461 | {0x0000a0d8, 0x33023303}, | ||
462 | {0x0000a0dc, 0x33003301}, | ||
463 | {0x0000a0e0, 0x331e331f}, | ||
464 | {0x0000a0e4, 0x4402331d}, | ||
465 | {0x0000a0e8, 0x44004401}, | ||
466 | {0x0000a0ec, 0x441e441f}, | ||
467 | {0x0000a0f0, 0x55025503}, | ||
468 | {0x0000a0f4, 0x55005501}, | ||
469 | {0x0000a0f8, 0x551e551f}, | ||
470 | {0x0000a0fc, 0x6602551d}, | ||
471 | {0x0000a100, 0x66006601}, | ||
472 | {0x0000a104, 0x661e661f}, | ||
473 | {0x0000a108, 0x7703661d}, | ||
474 | {0x0000a10c, 0x77017702}, | ||
475 | {0x0000a110, 0x00007700}, | ||
476 | {0x0000a114, 0x00000000}, | ||
477 | {0x0000a118, 0x00000000}, | ||
478 | {0x0000a11c, 0x00000000}, | ||
479 | {0x0000a120, 0x00000000}, | ||
480 | {0x0000a124, 0x00000000}, | ||
481 | {0x0000a128, 0x00000000}, | ||
482 | {0x0000a12c, 0x00000000}, | ||
483 | {0x0000a130, 0x00000000}, | ||
484 | {0x0000a134, 0x00000000}, | ||
485 | {0x0000a138, 0x00000000}, | ||
486 | {0x0000a13c, 0x00000000}, | ||
487 | {0x0000a140, 0x001f0000}, | ||
488 | {0x0000a144, 0x111f1100}, | ||
489 | {0x0000a148, 0x111d111e}, | ||
490 | {0x0000a14c, 0x111b111c}, | ||
491 | {0x0000a150, 0x22032204}, | ||
492 | {0x0000a154, 0x22012202}, | ||
493 | {0x0000a158, 0x221f2200}, | ||
494 | {0x0000a15c, 0x221d221e}, | ||
495 | {0x0000a160, 0x33013302}, | ||
496 | {0x0000a164, 0x331f3300}, | ||
497 | {0x0000a168, 0x4402331e}, | ||
498 | {0x0000a16c, 0x44004401}, | ||
499 | {0x0000a170, 0x441e441f}, | ||
500 | {0x0000a174, 0x55015502}, | ||
501 | {0x0000a178, 0x551f5500}, | ||
502 | {0x0000a17c, 0x6602551e}, | ||
503 | {0x0000a180, 0x66006601}, | ||
504 | {0x0000a184, 0x661e661f}, | ||
505 | {0x0000a188, 0x7703661d}, | ||
506 | {0x0000a18c, 0x77017702}, | ||
507 | {0x0000a190, 0x00007700}, | ||
508 | {0x0000a194, 0x00000000}, | ||
509 | {0x0000a198, 0x00000000}, | ||
510 | {0x0000a19c, 0x00000000}, | ||
511 | {0x0000a1a0, 0x00000000}, | ||
512 | {0x0000a1a4, 0x00000000}, | ||
513 | {0x0000a1a8, 0x00000000}, | ||
514 | {0x0000a1ac, 0x00000000}, | ||
515 | {0x0000a1b0, 0x00000000}, | ||
516 | {0x0000a1b4, 0x00000000}, | ||
517 | {0x0000a1b8, 0x00000000}, | ||
518 | {0x0000a1bc, 0x00000000}, | ||
519 | {0x0000a1c0, 0x00000000}, | ||
520 | {0x0000a1c4, 0x00000000}, | ||
521 | {0x0000a1c8, 0x00000000}, | ||
522 | {0x0000a1cc, 0x00000000}, | ||
523 | {0x0000a1d0, 0x00000000}, | ||
524 | {0x0000a1d4, 0x00000000}, | ||
525 | {0x0000a1d8, 0x00000000}, | ||
526 | {0x0000a1dc, 0x00000000}, | ||
527 | {0x0000a1e0, 0x00000000}, | ||
528 | {0x0000a1e4, 0x00000000}, | ||
529 | {0x0000a1e8, 0x00000000}, | ||
530 | {0x0000a1ec, 0x00000000}, | ||
531 | {0x0000a1f0, 0x00000396}, | ||
532 | {0x0000a1f4, 0x00000396}, | ||
533 | {0x0000a1f8, 0x00000396}, | ||
534 | {0x0000a1fc, 0x00000296}, | ||
535 | }; | ||
536 | |||
537 | static const u32 ar9331_1p2_baseband_core[][2] = { | ||
538 | /* Addr allmodes */ | ||
539 | {0x00009800, 0xafe68e30}, | ||
540 | {0x00009804, 0xfd14e000}, | ||
541 | {0x00009808, 0x9c0a8f6b}, | ||
542 | {0x0000980c, 0x04800000}, | ||
543 | {0x00009814, 0x9280c00a}, | ||
544 | {0x00009818, 0x00000000}, | ||
545 | {0x0000981c, 0x00020028}, | ||
546 | {0x00009834, 0x5f3ca3de}, | ||
547 | {0x00009838, 0x0108ecff}, | ||
548 | {0x0000983c, 0x14750600}, | ||
549 | {0x00009880, 0x201fff00}, | ||
550 | {0x00009884, 0x00001042}, | ||
551 | {0x000098a4, 0x00200400}, | ||
552 | {0x000098b0, 0x32840bbe}, | ||
553 | {0x000098d0, 0x004b6a8e}, | ||
554 | {0x000098d4, 0x00000820}, | ||
555 | {0x000098dc, 0x00000000}, | ||
556 | {0x000098f0, 0x00000000}, | ||
557 | {0x000098f4, 0x00000000}, | ||
558 | {0x00009c04, 0x00000000}, | ||
559 | {0x00009c08, 0x03200000}, | ||
560 | {0x00009c0c, 0x00000000}, | ||
561 | {0x00009c10, 0x00000000}, | ||
562 | {0x00009c14, 0x00046384}, | ||
563 | {0x00009c18, 0x05b6b440}, | ||
564 | {0x00009c1c, 0x00b6b440}, | ||
565 | {0x00009d00, 0xc080a333}, | ||
566 | {0x00009d04, 0x40206c10}, | ||
567 | {0x00009d08, 0x009c4060}, | ||
568 | {0x00009d0c, 0x1883800a}, | ||
569 | {0x00009d10, 0x01834061}, | ||
570 | {0x00009d14, 0x00c00400}, | ||
571 | {0x00009d18, 0x00000000}, | ||
572 | {0x00009e08, 0x0038233c}, | ||
573 | {0x00009e24, 0x9927b515}, | ||
574 | {0x00009e28, 0x12ef0200}, | ||
575 | {0x00009e30, 0x06336f77}, | ||
576 | {0x00009e34, 0x6af6532f}, | ||
577 | {0x00009e38, 0x0cc80c00}, | ||
578 | {0x00009e40, 0x0d261820}, | ||
579 | {0x00009e4c, 0x00001004}, | ||
580 | {0x00009e50, 0x00ff03f1}, | ||
581 | {0x00009fc0, 0x803e4788}, | ||
582 | {0x00009fc4, 0x0001efb5}, | ||
583 | {0x00009fcc, 0x40000014}, | ||
584 | {0x0000a20c, 0x00000000}, | ||
585 | {0x0000a220, 0x00000000}, | ||
586 | {0x0000a224, 0x00000000}, | ||
587 | {0x0000a228, 0x10002310}, | ||
588 | {0x0000a23c, 0x00000000}, | ||
589 | {0x0000a244, 0x0c000000}, | ||
590 | {0x0000a2a0, 0x00000001}, | ||
591 | {0x0000a2c0, 0x00000001}, | ||
592 | {0x0000a2c8, 0x00000000}, | ||
593 | {0x0000a2cc, 0x18c43433}, | ||
594 | {0x0000a2d4, 0x00000000}, | ||
595 | {0x0000a2dc, 0x00000000}, | ||
596 | {0x0000a2e0, 0x00000000}, | ||
597 | {0x0000a2e4, 0x00000000}, | ||
598 | {0x0000a2e8, 0x00000000}, | ||
599 | {0x0000a2ec, 0x00000000}, | ||
600 | {0x0000a2f0, 0x00000000}, | ||
601 | {0x0000a2f4, 0x00000000}, | ||
602 | {0x0000a2f8, 0x00000000}, | ||
603 | {0x0000a344, 0x00000000}, | ||
604 | {0x0000a34c, 0x00000000}, | ||
605 | {0x0000a350, 0x0000a000}, | ||
606 | {0x0000a364, 0x00000000}, | ||
607 | {0x0000a370, 0x00000000}, | ||
608 | {0x0000a390, 0x00000001}, | ||
609 | {0x0000a394, 0x00000444}, | ||
610 | {0x0000a398, 0x001f0e0f}, | ||
611 | {0x0000a39c, 0x0075393f}, | ||
612 | {0x0000a3a0, 0xb79f6427}, | ||
613 | {0x0000a3a4, 0x00000000}, | ||
614 | {0x0000a3a8, 0xaaaaaaaa}, | ||
615 | {0x0000a3ac, 0x3c466478}, | ||
616 | {0x0000a3c0, 0x20202020}, | ||
617 | {0x0000a3c4, 0x22222220}, | ||
618 | {0x0000a3c8, 0x20200020}, | ||
619 | {0x0000a3cc, 0x20202020}, | ||
620 | {0x0000a3d0, 0x20202020}, | ||
621 | {0x0000a3d4, 0x20202020}, | ||
622 | {0x0000a3d8, 0x20202020}, | ||
623 | {0x0000a3dc, 0x20202020}, | ||
624 | {0x0000a3e0, 0x20202020}, | ||
625 | {0x0000a3e4, 0x20202020}, | ||
626 | {0x0000a3e8, 0x20202020}, | ||
627 | {0x0000a3ec, 0x20202020}, | ||
628 | {0x0000a3f0, 0x00000000}, | ||
629 | {0x0000a3f4, 0x00000006}, | ||
630 | {0x0000a3f8, 0x0cdbd380}, | ||
631 | {0x0000a3fc, 0x000f0f01}, | ||
632 | {0x0000a400, 0x8fa91f01}, | ||
633 | {0x0000a404, 0x00000000}, | ||
634 | {0x0000a408, 0x0e79e5c6}, | ||
635 | {0x0000a40c, 0x00820820}, | ||
636 | {0x0000a414, 0x1ce739ce}, | ||
637 | {0x0000a418, 0x2d001dce}, | ||
638 | {0x0000a41c, 0x1ce739ce}, | ||
639 | {0x0000a420, 0x000001ce}, | ||
640 | {0x0000a424, 0x1ce739ce}, | ||
641 | {0x0000a428, 0x000001ce}, | ||
642 | {0x0000a42c, 0x1ce739ce}, | ||
643 | {0x0000a430, 0x1ce739ce}, | ||
644 | {0x0000a434, 0x00000000}, | ||
645 | {0x0000a438, 0x00001801}, | ||
646 | {0x0000a43c, 0x00000000}, | ||
647 | {0x0000a440, 0x00000000}, | ||
648 | {0x0000a444, 0x00000000}, | ||
649 | {0x0000a448, 0x04000000}, | ||
650 | {0x0000a44c, 0x00000001}, | ||
651 | {0x0000a450, 0x00010000}, | ||
652 | {0x0000a458, 0x00000000}, | ||
653 | {0x0000a640, 0x00000000}, | ||
654 | {0x0000a644, 0x3fad9d74}, | ||
655 | {0x0000a648, 0x0048060a}, | ||
656 | {0x0000a64c, 0x00003c37}, | ||
657 | {0x0000a670, 0x03020100}, | ||
658 | {0x0000a674, 0x09080504}, | ||
659 | {0x0000a678, 0x0d0c0b0a}, | ||
660 | {0x0000a67c, 0x13121110}, | ||
661 | {0x0000a680, 0x31301514}, | ||
662 | {0x0000a684, 0x35343332}, | ||
663 | {0x0000a688, 0x00000036}, | ||
664 | {0x0000a690, 0x00000838}, | ||
665 | {0x0000a7c0, 0x00000000}, | ||
666 | {0x0000a7c4, 0xfffffffc}, | ||
667 | {0x0000a7c8, 0x00000000}, | ||
668 | {0x0000a7cc, 0x00000000}, | ||
669 | {0x0000a7d0, 0x00000000}, | ||
670 | {0x0000a7d4, 0x00000004}, | ||
671 | {0x0000a7dc, 0x00000001}, | ||
672 | }; | ||
673 | |||
674 | static const u32 ar9331_modes_high_power_tx_gain_1p2[][5] = { | ||
675 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
676 | {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, | ||
677 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
678 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
679 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
680 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
681 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
682 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
683 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
684 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
685 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00}, | ||
686 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, | ||
687 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, | ||
688 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, | ||
689 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, | ||
690 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, | ||
691 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, | ||
692 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, | ||
693 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, | ||
694 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, | ||
695 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, | ||
696 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, | ||
697 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, | ||
698 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, | ||
699 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, | ||
700 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, | ||
701 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, | ||
702 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, | ||
703 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
704 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
705 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
706 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
707 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
708 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, | ||
709 | {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
710 | {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
711 | {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
712 | {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, | ||
713 | {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, | ||
714 | {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, | ||
715 | {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, | ||
716 | {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, | ||
717 | {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, | ||
718 | {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, | ||
719 | {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, | ||
720 | {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, | ||
721 | {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, | ||
722 | {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, | ||
723 | {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, | ||
724 | {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, | ||
725 | {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, | ||
726 | {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, | ||
727 | {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, | ||
728 | {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, | ||
729 | {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, | ||
730 | {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, | ||
731 | {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, | ||
732 | {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, | ||
733 | {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, | ||
734 | {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, | ||
735 | {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
736 | {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
737 | {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
738 | {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
739 | {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
740 | {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, | ||
741 | {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
742 | {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
743 | {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
744 | {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
745 | {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
746 | {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, | ||
747 | {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, | ||
748 | {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, | ||
749 | {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, | ||
750 | {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, | ||
751 | {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
752 | {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
753 | {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
754 | {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
755 | {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
756 | {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, | ||
757 | }; | ||
758 | |||
759 | static const u32 ar9331_1p2_mac_postamble[][5] = { | ||
760 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
761 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | ||
762 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | ||
763 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | ||
764 | {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, | ||
765 | {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, | ||
766 | {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, | ||
767 | {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, | ||
768 | {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, | ||
769 | }; | ||
770 | |||
771 | static const u32 ar9331_1p2_soc_preamble[][2] = { | ||
772 | /* Addr allmodes */ | ||
773 | {0x00007020, 0x00000000}, | ||
774 | {0x00007034, 0x00000002}, | ||
775 | {0x00007038, 0x000002f8}, | ||
776 | }; | ||
777 | |||
778 | static const u32 ar9331_1p2_xtal_40M[][2] = { | ||
779 | /* Addr allmodes */ | ||
780 | {0x00007038, 0x000004c2}, | ||
781 | {0x00008244, 0x0010f400}, | ||
782 | {0x0000824c, 0x0001e800}, | ||
783 | {0x0001609c, 0x0b283f31}, | ||
784 | }; | ||
785 | |||
786 | static const u32 ar9331_1p2_mac_core[][2] = { | ||
787 | /* Addr allmodes */ | ||
788 | {0x00000008, 0x00000000}, | ||
789 | {0x00000030, 0x00020085}, | ||
790 | {0x00000034, 0x00000005}, | ||
791 | {0x00000040, 0x00000000}, | ||
792 | {0x00000044, 0x00000000}, | ||
793 | {0x00000048, 0x00000008}, | ||
794 | {0x0000004c, 0x00000010}, | ||
795 | {0x00000050, 0x00000000}, | ||
796 | {0x00001040, 0x002ffc0f}, | ||
797 | {0x00001044, 0x002ffc0f}, | ||
798 | {0x00001048, 0x002ffc0f}, | ||
799 | {0x0000104c, 0x002ffc0f}, | ||
800 | {0x00001050, 0x002ffc0f}, | ||
801 | {0x00001054, 0x002ffc0f}, | ||
802 | {0x00001058, 0x002ffc0f}, | ||
803 | {0x0000105c, 0x002ffc0f}, | ||
804 | {0x00001060, 0x002ffc0f}, | ||
805 | {0x00001064, 0x002ffc0f}, | ||
806 | {0x000010f0, 0x00000100}, | ||
807 | {0x00001270, 0x00000000}, | ||
808 | {0x000012b0, 0x00000000}, | ||
809 | {0x000012f0, 0x00000000}, | ||
810 | {0x0000143c, 0x00000000}, | ||
811 | {0x0000147c, 0x00000000}, | ||
812 | {0x00008000, 0x00000000}, | ||
813 | {0x00008004, 0x00000000}, | ||
814 | {0x00008008, 0x00000000}, | ||
815 | {0x0000800c, 0x00000000}, | ||
816 | {0x00008018, 0x00000000}, | ||
817 | {0x00008020, 0x00000000}, | ||
818 | {0x00008038, 0x00000000}, | ||
819 | {0x0000803c, 0x00000000}, | ||
820 | {0x00008040, 0x00000000}, | ||
821 | {0x00008044, 0x00000000}, | ||
822 | {0x00008048, 0x00000000}, | ||
823 | {0x0000804c, 0xffffffff}, | ||
824 | {0x00008054, 0x00000000}, | ||
825 | {0x00008058, 0x00000000}, | ||
826 | {0x0000805c, 0x000fc78f}, | ||
827 | {0x00008060, 0x0000000f}, | ||
828 | {0x00008064, 0x00000000}, | ||
829 | {0x00008070, 0x00000310}, | ||
830 | {0x00008074, 0x00000020}, | ||
831 | {0x00008078, 0x00000000}, | ||
832 | {0x0000809c, 0x0000000f}, | ||
833 | {0x000080a0, 0x00000000}, | ||
834 | {0x000080a4, 0x02ff0000}, | ||
835 | {0x000080a8, 0x0e070605}, | ||
836 | {0x000080ac, 0x0000000d}, | ||
837 | {0x000080b0, 0x00000000}, | ||
838 | {0x000080b4, 0x00000000}, | ||
839 | {0x000080b8, 0x00000000}, | ||
840 | {0x000080bc, 0x00000000}, | ||
841 | {0x000080c0, 0x2a800000}, | ||
842 | {0x000080c4, 0x06900168}, | ||
843 | {0x000080c8, 0x13881c20}, | ||
844 | {0x000080cc, 0x01f40000}, | ||
845 | {0x000080d0, 0x00252500}, | ||
846 | {0x000080d4, 0x00a00000}, | ||
847 | {0x000080d8, 0x00400000}, | ||
848 | {0x000080dc, 0x00000000}, | ||
849 | {0x000080e0, 0xffffffff}, | ||
850 | {0x000080e4, 0x0000ffff}, | ||
851 | {0x000080e8, 0x3f3f3f3f}, | ||
852 | {0x000080ec, 0x00000000}, | ||
853 | {0x000080f0, 0x00000000}, | ||
854 | {0x000080f4, 0x00000000}, | ||
855 | {0x000080fc, 0x00020000}, | ||
856 | {0x00008100, 0x00000000}, | ||
857 | {0x00008108, 0x00000052}, | ||
858 | {0x0000810c, 0x00000000}, | ||
859 | {0x00008110, 0x00000000}, | ||
860 | {0x00008114, 0x000007ff}, | ||
861 | {0x00008118, 0x000000aa}, | ||
862 | {0x0000811c, 0x00003210}, | ||
863 | {0x00008124, 0x00000000}, | ||
864 | {0x00008128, 0x00000000}, | ||
865 | {0x0000812c, 0x00000000}, | ||
866 | {0x00008130, 0x00000000}, | ||
867 | {0x00008134, 0x00000000}, | ||
868 | {0x00008138, 0x00000000}, | ||
869 | {0x0000813c, 0x0000ffff}, | ||
870 | {0x00008144, 0xffffffff}, | ||
871 | {0x00008168, 0x00000000}, | ||
872 | {0x0000816c, 0x00000000}, | ||
873 | {0x00008170, 0x18486200}, | ||
874 | {0x00008174, 0x33332210}, | ||
875 | {0x00008178, 0x00000000}, | ||
876 | {0x0000817c, 0x00020000}, | ||
877 | {0x000081c0, 0x00000000}, | ||
878 | {0x000081c4, 0x33332210}, | ||
879 | {0x000081c8, 0x00000000}, | ||
880 | {0x000081cc, 0x00000000}, | ||
881 | {0x000081d4, 0x00000000}, | ||
882 | {0x000081ec, 0x00000000}, | ||
883 | {0x000081f0, 0x00000000}, | ||
884 | {0x000081f4, 0x00000000}, | ||
885 | {0x000081f8, 0x00000000}, | ||
886 | {0x000081fc, 0x00000000}, | ||
887 | {0x00008240, 0x00100000}, | ||
888 | {0x00008248, 0x00000800}, | ||
889 | {0x00008250, 0x00000000}, | ||
890 | {0x00008254, 0x00000000}, | ||
891 | {0x00008258, 0x00000000}, | ||
892 | {0x0000825c, 0x40000000}, | ||
893 | {0x00008260, 0x00080922}, | ||
894 | {0x00008264, 0x9d400010}, | ||
895 | {0x00008268, 0xffffffff}, | ||
896 | {0x0000826c, 0x0000ffff}, | ||
897 | {0x00008270, 0x00000000}, | ||
898 | {0x00008274, 0x40000000}, | ||
899 | {0x00008278, 0x003e4180}, | ||
900 | {0x0000827c, 0x00000004}, | ||
901 | {0x00008284, 0x0000002c}, | ||
902 | {0x00008288, 0x0000002c}, | ||
903 | {0x0000828c, 0x000000ff}, | ||
904 | {0x00008294, 0x00000000}, | ||
905 | {0x00008298, 0x00000000}, | ||
906 | {0x0000829c, 0x00000000}, | ||
907 | {0x00008300, 0x00000140}, | ||
908 | {0x00008314, 0x00000000}, | ||
909 | {0x0000831c, 0x0000010d}, | ||
910 | {0x00008328, 0x00000000}, | ||
911 | {0x0000832c, 0x00000007}, | ||
912 | {0x00008330, 0x00000302}, | ||
913 | {0x00008334, 0x00000700}, | ||
914 | {0x00008338, 0x00ff0000}, | ||
915 | {0x0000833c, 0x02400000}, | ||
916 | {0x00008340, 0x000107ff}, | ||
917 | {0x00008344, 0xaa48105b}, | ||
918 | {0x00008348, 0x008f0000}, | ||
919 | {0x0000835c, 0x00000000}, | ||
920 | {0x00008360, 0xffffffff}, | ||
921 | {0x00008364, 0xffffffff}, | ||
922 | {0x00008368, 0x00000000}, | ||
923 | {0x00008370, 0x00000000}, | ||
924 | {0x00008374, 0x000000ff}, | ||
925 | {0x00008378, 0x00000000}, | ||
926 | {0x0000837c, 0x00000000}, | ||
927 | {0x00008380, 0xffffffff}, | ||
928 | {0x00008384, 0xffffffff}, | ||
929 | {0x00008390, 0xffffffff}, | ||
930 | {0x00008394, 0xffffffff}, | ||
931 | {0x00008398, 0x00000000}, | ||
932 | {0x0000839c, 0x00000000}, | ||
933 | {0x000083a0, 0x00000000}, | ||
934 | {0x000083a4, 0x0000fa14}, | ||
935 | {0x000083a8, 0x000f0c00}, | ||
936 | {0x000083ac, 0x33332210}, | ||
937 | {0x000083b0, 0x33332210}, | ||
938 | {0x000083b4, 0x33332210}, | ||
939 | {0x000083b8, 0x33332210}, | ||
940 | {0x000083bc, 0x00000000}, | ||
941 | {0x000083c0, 0x00000000}, | ||
942 | {0x000083c4, 0x00000000}, | ||
943 | {0x000083c8, 0x00000000}, | ||
944 | {0x000083cc, 0x00000200}, | ||
945 | {0x000083d0, 0x000301ff}, | ||
946 | }; | ||
947 | |||
948 | static const u32 ar9331_common_rx_gain_1p2[][2] = { | ||
949 | /* Addr allmodes */ | ||
950 | {0x0000a000, 0x00010000}, | ||
951 | {0x0000a004, 0x00030002}, | ||
952 | {0x0000a008, 0x00050004}, | ||
953 | {0x0000a00c, 0x00810080}, | ||
954 | {0x0000a010, 0x01800082}, | ||
955 | {0x0000a014, 0x01820181}, | ||
956 | {0x0000a018, 0x01840183}, | ||
957 | {0x0000a01c, 0x01880185}, | ||
958 | {0x0000a020, 0x018a0189}, | ||
959 | {0x0000a024, 0x02850284}, | ||
960 | {0x0000a028, 0x02890288}, | ||
961 | {0x0000a02c, 0x03850384}, | ||
962 | {0x0000a030, 0x03890388}, | ||
963 | {0x0000a034, 0x038b038a}, | ||
964 | {0x0000a038, 0x038d038c}, | ||
965 | {0x0000a03c, 0x03910390}, | ||
966 | {0x0000a040, 0x03930392}, | ||
967 | {0x0000a044, 0x03950394}, | ||
968 | {0x0000a048, 0x00000396}, | ||
969 | {0x0000a04c, 0x00000000}, | ||
970 | {0x0000a050, 0x00000000}, | ||
971 | {0x0000a054, 0x00000000}, | ||
972 | {0x0000a058, 0x00000000}, | ||
973 | {0x0000a05c, 0x00000000}, | ||
974 | {0x0000a060, 0x00000000}, | ||
975 | {0x0000a064, 0x00000000}, | ||
976 | {0x0000a068, 0x00000000}, | ||
977 | {0x0000a06c, 0x00000000}, | ||
978 | {0x0000a070, 0x00000000}, | ||
979 | {0x0000a074, 0x00000000}, | ||
980 | {0x0000a078, 0x00000000}, | ||
981 | {0x0000a07c, 0x00000000}, | ||
982 | {0x0000a080, 0x28282828}, | ||
983 | {0x0000a084, 0x28282828}, | ||
984 | {0x0000a088, 0x28282828}, | ||
985 | {0x0000a08c, 0x28282828}, | ||
986 | {0x0000a090, 0x28282828}, | ||
987 | {0x0000a094, 0x21212128}, | ||
988 | {0x0000a098, 0x171c1c1c}, | ||
989 | {0x0000a09c, 0x02020212}, | ||
990 | {0x0000a0a0, 0x00000202}, | ||
991 | {0x0000a0a4, 0x00000000}, | ||
992 | {0x0000a0a8, 0x00000000}, | ||
993 | {0x0000a0ac, 0x00000000}, | ||
994 | {0x0000a0b0, 0x00000000}, | ||
995 | {0x0000a0b4, 0x00000000}, | ||
996 | {0x0000a0b8, 0x00000000}, | ||
997 | {0x0000a0bc, 0x00000000}, | ||
998 | {0x0000a0c0, 0x001f0000}, | ||
999 | {0x0000a0c4, 0x111f1100}, | ||
1000 | {0x0000a0c8, 0x111d111e}, | ||
1001 | {0x0000a0cc, 0x111b111c}, | ||
1002 | {0x0000a0d0, 0x22032204}, | ||
1003 | {0x0000a0d4, 0x22012202}, | ||
1004 | {0x0000a0d8, 0x221f2200}, | ||
1005 | {0x0000a0dc, 0x221d221e}, | ||
1006 | {0x0000a0e0, 0x33013302}, | ||
1007 | {0x0000a0e4, 0x331f3300}, | ||
1008 | {0x0000a0e8, 0x4402331e}, | ||
1009 | {0x0000a0ec, 0x44004401}, | ||
1010 | {0x0000a0f0, 0x441e441f}, | ||
1011 | {0x0000a0f4, 0x55015502}, | ||
1012 | {0x0000a0f8, 0x551f5500}, | ||
1013 | {0x0000a0fc, 0x6602551e}, | ||
1014 | {0x0000a100, 0x66006601}, | ||
1015 | {0x0000a104, 0x661e661f}, | ||
1016 | {0x0000a108, 0x7703661d}, | ||
1017 | {0x0000a10c, 0x77017702}, | ||
1018 | {0x0000a110, 0x00007700}, | ||
1019 | {0x0000a114, 0x00000000}, | ||
1020 | {0x0000a118, 0x00000000}, | ||
1021 | {0x0000a11c, 0x00000000}, | ||
1022 | {0x0000a120, 0x00000000}, | ||
1023 | {0x0000a124, 0x00000000}, | ||
1024 | {0x0000a128, 0x00000000}, | ||
1025 | {0x0000a12c, 0x00000000}, | ||
1026 | {0x0000a130, 0x00000000}, | ||
1027 | {0x0000a134, 0x00000000}, | ||
1028 | {0x0000a138, 0x00000000}, | ||
1029 | {0x0000a13c, 0x00000000}, | ||
1030 | {0x0000a140, 0x001f0000}, | ||
1031 | {0x0000a144, 0x111f1100}, | ||
1032 | {0x0000a148, 0x111d111e}, | ||
1033 | {0x0000a14c, 0x111b111c}, | ||
1034 | {0x0000a150, 0x22032204}, | ||
1035 | {0x0000a154, 0x22012202}, | ||
1036 | {0x0000a158, 0x221f2200}, | ||
1037 | {0x0000a15c, 0x221d221e}, | ||
1038 | {0x0000a160, 0x33013302}, | ||
1039 | {0x0000a164, 0x331f3300}, | ||
1040 | {0x0000a168, 0x4402331e}, | ||
1041 | {0x0000a16c, 0x44004401}, | ||
1042 | {0x0000a170, 0x441e441f}, | ||
1043 | {0x0000a174, 0x55015502}, | ||
1044 | {0x0000a178, 0x551f5500}, | ||
1045 | {0x0000a17c, 0x6602551e}, | ||
1046 | {0x0000a180, 0x66006601}, | ||
1047 | {0x0000a184, 0x661e661f}, | ||
1048 | {0x0000a188, 0x7703661d}, | ||
1049 | {0x0000a18c, 0x77017702}, | ||
1050 | {0x0000a190, 0x00007700}, | ||
1051 | {0x0000a194, 0x00000000}, | ||
1052 | {0x0000a198, 0x00000000}, | ||
1053 | {0x0000a19c, 0x00000000}, | ||
1054 | {0x0000a1a0, 0x00000000}, | ||
1055 | {0x0000a1a4, 0x00000000}, | ||
1056 | {0x0000a1a8, 0x00000000}, | ||
1057 | {0x0000a1ac, 0x00000000}, | ||
1058 | {0x0000a1b0, 0x00000000}, | ||
1059 | {0x0000a1b4, 0x00000000}, | ||
1060 | {0x0000a1b8, 0x00000000}, | ||
1061 | {0x0000a1bc, 0x00000000}, | ||
1062 | {0x0000a1c0, 0x00000000}, | ||
1063 | {0x0000a1c4, 0x00000000}, | ||
1064 | {0x0000a1c8, 0x00000000}, | ||
1065 | {0x0000a1cc, 0x00000000}, | ||
1066 | {0x0000a1d0, 0x00000000}, | ||
1067 | {0x0000a1d4, 0x00000000}, | ||
1068 | {0x0000a1d8, 0x00000000}, | ||
1069 | {0x0000a1dc, 0x00000000}, | ||
1070 | {0x0000a1e0, 0x00000000}, | ||
1071 | {0x0000a1e4, 0x00000000}, | ||
1072 | {0x0000a1e8, 0x00000000}, | ||
1073 | {0x0000a1ec, 0x00000000}, | ||
1074 | {0x0000a1f0, 0x00000396}, | ||
1075 | {0x0000a1f4, 0x00000396}, | ||
1076 | {0x0000a1f8, 0x00000396}, | ||
1077 | {0x0000a1fc, 0x00000296}, | ||
1078 | }; | ||
1079 | |||
1080 | #endif /* INITVALS_9330_1P2_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 57933db57633..359576ff86dc 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -55,8 +55,6 @@ struct ath_node; | |||
55 | (_l) &= ((_sz) - 1); \ | 55 | (_l) &= ((_sz) - 1); \ |
56 | } while (0) | 56 | } while (0) |
57 | 57 | ||
58 | #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
59 | |||
60 | #define TSF_TO_TU(_h,_l) \ | 58 | #define TSF_TO_TU(_h,_l) \ |
61 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) | 59 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) |
62 | 60 | ||
@@ -580,7 +578,7 @@ struct ath9k_vif_iter_data { | |||
580 | int naps; /* number of AP vifs */ | 578 | int naps; /* number of AP vifs */ |
581 | int nmeshes; /* number of mesh vifs */ | 579 | int nmeshes; /* number of mesh vifs */ |
582 | int nstations; /* number of station vifs */ | 580 | int nstations; /* number of station vifs */ |
583 | int nwds; /* number of nwd vifs */ | 581 | int nwds; /* number of WDS vifs */ |
584 | int nadhocs; /* number of adhoc vifs */ | 582 | int nadhocs; /* number of adhoc vifs */ |
585 | int nothers; /* number of vifs not specified above. */ | 583 | int nothers; /* number of vifs not specified above. */ |
586 | }; | 584 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6de2655e07dd..07827b55e84b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -251,6 +251,15 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
251 | case AR5416_AR9100_DEVID: | 251 | case AR5416_AR9100_DEVID: |
252 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | 252 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; |
253 | break; | 253 | break; |
254 | case AR9300_DEVID_AR9330: | ||
255 | ah->hw_version.macVersion = AR_SREV_VERSION_9330; | ||
256 | if (ah->get_mac_revision) { | ||
257 | ah->hw_version.macRev = ah->get_mac_revision(); | ||
258 | } else { | ||
259 | val = REG_READ(ah, AR_SREV); | ||
260 | ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); | ||
261 | } | ||
262 | return; | ||
254 | case AR9300_DEVID_AR9340: | 263 | case AR9300_DEVID_AR9340: |
255 | ah->hw_version.macVersion = AR_SREV_VERSION_9340; | 264 | ah->hw_version.macVersion = AR_SREV_VERSION_9340; |
256 | val = REG_READ(ah, AR_SREV); | 265 | val = REG_READ(ah, AR_SREV); |
@@ -551,6 +560,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
551 | case AR_SREV_VERSION_9287: | 560 | case AR_SREV_VERSION_9287: |
552 | case AR_SREV_VERSION_9271: | 561 | case AR_SREV_VERSION_9271: |
553 | case AR_SREV_VERSION_9300: | 562 | case AR_SREV_VERSION_9300: |
563 | case AR_SREV_VERSION_9330: | ||
554 | case AR_SREV_VERSION_9485: | 564 | case AR_SREV_VERSION_9485: |
555 | case AR_SREV_VERSION_9340: | 565 | case AR_SREV_VERSION_9340: |
556 | break; | 566 | break; |
@@ -561,7 +571,8 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
561 | return -EOPNOTSUPP; | 571 | return -EOPNOTSUPP; |
562 | } | 572 | } |
563 | 573 | ||
564 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah)) | 574 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) || |
575 | AR_SREV_9330(ah)) | ||
565 | ah->is_pciexpress = false; | 576 | ah->is_pciexpress = false; |
566 | 577 | ||
567 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | 578 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); |
@@ -604,7 +615,10 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
604 | else | 615 | else |
605 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); | 616 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); |
606 | 617 | ||
607 | ah->bb_watchdog_timeout_ms = 25; | 618 | if (AR_SREV_9330(ah)) |
619 | ah->bb_watchdog_timeout_ms = 85; | ||
620 | else | ||
621 | ah->bb_watchdog_timeout_ms = 25; | ||
608 | 622 | ||
609 | common->state = ATH_HW_INITIALIZED; | 623 | common->state = ATH_HW_INITIALIZED; |
610 | 624 | ||
@@ -630,6 +644,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
630 | case AR2427_DEVID_PCIE: | 644 | case AR2427_DEVID_PCIE: |
631 | case AR9300_DEVID_PCIE: | 645 | case AR9300_DEVID_PCIE: |
632 | case AR9300_DEVID_AR9485_PCIE: | 646 | case AR9300_DEVID_AR9485_PCIE: |
647 | case AR9300_DEVID_AR9330: | ||
633 | case AR9300_DEVID_AR9340: | 648 | case AR9300_DEVID_AR9340: |
634 | break; | 649 | break; |
635 | default: | 650 | default: |
@@ -722,6 +737,39 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
722 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 737 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
723 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); | 738 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); |
724 | udelay(1000); | 739 | udelay(1000); |
740 | } else if (AR_SREV_9330(ah)) { | ||
741 | u32 ddr_dpll2, pll_control2, kd; | ||
742 | |||
743 | if (ah->is_clk_25mhz) { | ||
744 | ddr_dpll2 = 0x18e82f01; | ||
745 | pll_control2 = 0xe04a3d; | ||
746 | kd = 0x1d; | ||
747 | } else { | ||
748 | ddr_dpll2 = 0x19e82f01; | ||
749 | pll_control2 = 0x886666; | ||
750 | kd = 0x3d; | ||
751 | } | ||
752 | |||
753 | /* program DDR PLL ki and kd value */ | ||
754 | REG_WRITE(ah, AR_CH0_DDR_DPLL2, ddr_dpll2); | ||
755 | |||
756 | /* program DDR PLL phase_shift */ | ||
757 | REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, | ||
758 | AR_CH0_DPLL3_PHASE_SHIFT, 0x1); | ||
759 | |||
760 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | ||
761 | udelay(1000); | ||
762 | |||
763 | /* program refdiv, nint, frac to RTC register */ | ||
764 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, pll_control2); | ||
765 | |||
766 | /* program BB PLL kd and ki value */ | ||
767 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_DPLL2_KD, kd); | ||
768 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_DPLL2_KI, 0x06); | ||
769 | |||
770 | /* program BB PLL phase_shift */ | ||
771 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | ||
772 | AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1); | ||
725 | } else if (AR_SREV_9340(ah)) { | 773 | } else if (AR_SREV_9340(ah)) { |
726 | u32 regval, pll2_divint, pll2_divfrac, refdiv; | 774 | u32 regval, pll2_divint, pll2_divfrac, refdiv; |
727 | 775 | ||
@@ -763,7 +811,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
763 | 811 | ||
764 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 812 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
765 | 813 | ||
766 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | 814 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) |
767 | udelay(1000); | 815 | udelay(1000); |
768 | 816 | ||
769 | /* Switch the core clock for ar9271 to 117Mhz */ | 817 | /* Switch the core clock for ar9271 to 117Mhz */ |
@@ -1114,6 +1162,41 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1114 | rst_flags |= AR_RTC_RC_MAC_COLD; | 1162 | rst_flags |= AR_RTC_RC_MAC_COLD; |
1115 | } | 1163 | } |
1116 | 1164 | ||
1165 | if (AR_SREV_9330(ah)) { | ||
1166 | int npend = 0; | ||
1167 | int i; | ||
1168 | |||
1169 | /* AR9330 WAR: | ||
1170 | * call external reset function to reset WMAC if: | ||
1171 | * - doing a cold reset | ||
1172 | * - we have pending frames in the TX queues | ||
1173 | */ | ||
1174 | |||
1175 | for (i = 0; i < AR_NUM_QCU; i++) { | ||
1176 | npend = ath9k_hw_numtxpending(ah, i); | ||
1177 | if (npend) | ||
1178 | break; | ||
1179 | } | ||
1180 | |||
1181 | if (ah->external_reset && | ||
1182 | (npend || type == ATH9K_RESET_COLD)) { | ||
1183 | int reset_err = 0; | ||
1184 | |||
1185 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, | ||
1186 | "reset MAC via external reset\n"); | ||
1187 | |||
1188 | reset_err = ah->external_reset(); | ||
1189 | if (reset_err) { | ||
1190 | ath_err(ath9k_hw_common(ah), | ||
1191 | "External reset failed, err=%d\n", | ||
1192 | reset_err); | ||
1193 | return false; | ||
1194 | } | ||
1195 | |||
1196 | REG_WRITE(ah, AR_RTC_RESET, 1); | ||
1197 | } | ||
1198 | } | ||
1199 | |||
1117 | REG_WRITE(ah, AR_RTC_RC, rst_flags); | 1200 | REG_WRITE(ah, AR_RTC_RC, rst_flags); |
1118 | 1201 | ||
1119 | REGWRITE_BUFFER_FLUSH(ah); | 1202 | REGWRITE_BUFFER_FLUSH(ah); |
@@ -1545,7 +1628,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1545 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1628 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
1546 | } | 1629 | } |
1547 | #ifdef __BIG_ENDIAN | 1630 | #ifdef __BIG_ENDIAN |
1548 | else if (AR_SREV_9340(ah)) | 1631 | else if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) |
1549 | REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); | 1632 | REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); |
1550 | else | 1633 | else |
1551 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1634 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
@@ -1983,7 +2066,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1983 | 2066 | ||
1984 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 2067 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
1985 | pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; | 2068 | pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; |
1986 | if (!AR_SREV_9485(ah)) | 2069 | if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah)) |
1987 | pCap->hw_caps |= ATH9K_HW_CAP_LDPC; | 2070 | pCap->hw_caps |= ATH9K_HW_CAP_LDPC; |
1988 | 2071 | ||
1989 | pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; | 2072 | pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; |
@@ -2025,7 +2108,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2025 | } | 2108 | } |
2026 | 2109 | ||
2027 | 2110 | ||
2028 | if (AR_SREV_9485(ah)) { | 2111 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { |
2029 | ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); | 2112 | ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); |
2030 | /* | 2113 | /* |
2031 | * enable the diversity-combining algorithm only when | 2114 | * enable the diversity-combining algorithm only when |
@@ -2574,6 +2657,7 @@ static struct { | |||
2574 | { AR_SREV_VERSION_9287, "9287" }, | 2657 | { AR_SREV_VERSION_9287, "9287" }, |
2575 | { AR_SREV_VERSION_9271, "9271" }, | 2658 | { AR_SREV_VERSION_9271, "9271" }, |
2576 | { AR_SREV_VERSION_9300, "9300" }, | 2659 | { AR_SREV_VERSION_9300, "9300" }, |
2660 | { AR_SREV_VERSION_9330, "9330" }, | ||
2577 | { AR_SREV_VERSION_9485, "9485" }, | 2661 | { AR_SREV_VERSION_9485, "9485" }, |
2578 | }; | 2662 | }; |
2579 | 2663 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 6a6fb5439831..818acdd1ba90 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define AR9300_DEVID_PCIE 0x0030 | 45 | #define AR9300_DEVID_PCIE 0x0030 |
46 | #define AR9300_DEVID_AR9340 0x0031 | 46 | #define AR9300_DEVID_AR9340 0x0031 |
47 | #define AR9300_DEVID_AR9485_PCIE 0x0032 | 47 | #define AR9300_DEVID_AR9485_PCIE 0x0032 |
48 | #define AR9300_DEVID_AR9330 0x0035 | ||
48 | 49 | ||
49 | #define AR5416_AR9100_DEVID 0x000b | 50 | #define AR5416_AR9100_DEVID 0x000b |
50 | 51 | ||
@@ -157,8 +158,9 @@ | |||
157 | #define ATH9K_HW_RX_HP_QDEPTH 16 | 158 | #define ATH9K_HW_RX_HP_QDEPTH 16 |
158 | #define ATH9K_HW_RX_LP_QDEPTH 128 | 159 | #define ATH9K_HW_RX_LP_QDEPTH 128 |
159 | 160 | ||
160 | #define PAPRD_GAIN_TABLE_ENTRIES 32 | 161 | #define PAPRD_GAIN_TABLE_ENTRIES 32 |
161 | #define PAPRD_TABLE_SZ 24 | 162 | #define PAPRD_TABLE_SZ 24 |
163 | #define PAPRD_IDEAL_AGC2_PWR_RANGE 0xe0 | ||
162 | 164 | ||
163 | enum ath_hw_txq_subtype { | 165 | enum ath_hw_txq_subtype { |
164 | ATH_TXQ_AC_BE = 0, | 166 | ATH_TXQ_AC_BE = 0, |
@@ -860,6 +862,8 @@ struct ath_hw { | |||
860 | u32 ent_mode; | 862 | u32 ent_mode; |
861 | 863 | ||
862 | bool is_clk_25mhz; | 864 | bool is_clk_25mhz; |
865 | int (*get_mac_revision)(void); | ||
866 | int (*external_reset)(void); | ||
863 | }; | 867 | }; |
864 | 868 | ||
865 | struct ath_bus_ops { | 869 | struct ath_bus_ops { |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 1202bb0a5534..616e30b2001a 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -246,7 +246,7 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
246 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | 246 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
247 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | 247 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; |
248 | 248 | ||
249 | if (AR_SREV_9485(ah)) | 249 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) |
250 | max_streams = 1; | 250 | max_streams = 1; |
251 | else if (AR_SREV_9300_20_OR_LATER(ah)) | 251 | else if (AR_SREV_9300_20_OR_LATER(ah)) |
252 | max_streams = 3; | 252 | max_streams = 3; |
@@ -575,6 +575,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
575 | sc->sc_ah->gpio_val = pdata->gpio_val; | 575 | sc->sc_ah->gpio_val = pdata->gpio_val; |
576 | sc->sc_ah->led_pin = pdata->led_pin; | 576 | sc->sc_ah->led_pin = pdata->led_pin; |
577 | ah->is_clk_25mhz = pdata->is_clk_25mhz; | 577 | ah->is_clk_25mhz = pdata->is_clk_25mhz; |
578 | ah->get_mac_revision = pdata->get_mac_revision; | ||
579 | ah->external_reset = pdata->external_reset; | ||
578 | } | 580 | } |
579 | 581 | ||
580 | common = ath9k_hw_common(ah); | 582 | common = ath9k_hw_common(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 7f945333e2d8..5ae303b11e68 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -360,7 +360,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
360 | txctl.paprd = BIT(chain); | 360 | txctl.paprd = BIT(chain); |
361 | 361 | ||
362 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 362 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
363 | ath_dbg(common, ATH_DBG_XMIT, "PAPRD TX failed\n"); | 363 | ath_dbg(common, ATH_DBG_CALIBRATE, "PAPRD TX failed\n"); |
364 | dev_kfree_skb_any(skb); | 364 | dev_kfree_skb_any(skb); |
365 | return false; | 365 | return false; |
366 | } | 366 | } |
@@ -369,7 +369,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
369 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | 369 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); |
370 | 370 | ||
371 | if (!time_left) | 371 | if (!time_left) |
372 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, | 372 | ath_dbg(common, ATH_DBG_CALIBRATE, |
373 | "Timeout waiting for paprd training on TX chain %d\n", | 373 | "Timeout waiting for paprd training on TX chain %d\n", |
374 | chain); | 374 | chain); |
375 | 375 | ||
@@ -431,11 +431,18 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
431 | if (!ath_paprd_send_frame(sc, skb, chain)) | 431 | if (!ath_paprd_send_frame(sc, skb, chain)) |
432 | goto fail_paprd; | 432 | goto fail_paprd; |
433 | 433 | ||
434 | if (!ar9003_paprd_is_done(ah)) | 434 | if (!ar9003_paprd_is_done(ah)) { |
435 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
436 | "PAPRD not yet done on chain %d\n", chain); | ||
435 | break; | 437 | break; |
438 | } | ||
436 | 439 | ||
437 | if (ar9003_paprd_create_curve(ah, caldata, chain) != 0) | 440 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { |
441 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
442 | "PAPRD create curve failed on chain %d\n", | ||
443 | chain); | ||
438 | break; | 444 | break; |
445 | } | ||
439 | 446 | ||
440 | chain_ok = 1; | 447 | chain_ok = 1; |
441 | } | 448 | } |
@@ -1259,7 +1266,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1259 | 1266 | ||
1260 | /* disable HAL and put h/w to sleep */ | 1267 | /* disable HAL and put h/w to sleep */ |
1261 | ath9k_hw_disable(ah); | 1268 | ath9k_hw_disable(ah); |
1262 | ath9k_hw_configpcipowersave(ah, 1, 1); | ||
1263 | 1269 | ||
1264 | spin_unlock_bh(&sc->sc_pcu_lock); | 1270 | spin_unlock_bh(&sc->sc_pcu_lock); |
1265 | 1271 | ||
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index ba7f36ab0a74..e7fe4d9aee79 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -533,7 +533,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, | |||
533 | [valid_rate_count] = j; | 533 | [valid_rate_count] = j; |
534 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; | 534 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; |
535 | ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); | 535 | ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); |
536 | hi = A_MAX(hi, j); | 536 | hi = max(hi, j); |
537 | } | 537 | } |
538 | } | 538 | } |
539 | } | 539 | } |
@@ -569,7 +569,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, | |||
569 | [ath_rc_priv->valid_phy_ratecnt[phy]] = j; | 569 | [ath_rc_priv->valid_phy_ratecnt[phy]] = j; |
570 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; | 570 | ath_rc_priv->valid_phy_ratecnt[phy] += 1; |
571 | ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); | 571 | ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); |
572 | hi = A_MAX(hi, j); | 572 | hi = max(hi, j); |
573 | } | 573 | } |
574 | } | 574 | } |
575 | 575 | ||
@@ -1228,7 +1228,7 @@ static void ath_rc_init(struct ath_softc *sc, | |||
1228 | ht_mcs, | 1228 | ht_mcs, |
1229 | ath_rc_priv->ht_cap); | 1229 | ath_rc_priv->ht_cap); |
1230 | } | 1230 | } |
1231 | hi = A_MAX(hi, hthi); | 1231 | hi = max(hi, hthi); |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | ath_rc_priv->rate_table_size = hi + 1; | 1234 | ath_rc_priv->rate_table_size = hi + 1; |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c4c5d9f455bb..70dc8ecdad4d 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -40,6 +40,7 @@ static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, | |||
40 | result = true; | 40 | result = true; |
41 | break; | 41 | break; |
42 | case 1: | 42 | case 1: |
43 | case 2: | ||
43 | if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && | 44 | if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && |
44 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && | 45 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && |
45 | (alt_rssi_avg >= (main_rssi_avg - 5))) || | 46 | (alt_rssi_avg >= (main_rssi_avg - 5))) || |
@@ -1076,39 +1077,39 @@ static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, | |||
1076 | antcomb->rssi_lna1 = main_rssi_avg; | 1077 | antcomb->rssi_lna1 = main_rssi_avg; |
1077 | 1078 | ||
1078 | switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { | 1079 | switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { |
1079 | case (0x10): /* LNA2 A-B */ | 1080 | case 0x10: /* LNA2 A-B */ |
1080 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | 1081 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; |
1081 | antcomb->first_quick_scan_conf = | 1082 | antcomb->first_quick_scan_conf = |
1082 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | 1083 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; |
1083 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | 1084 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; |
1084 | break; | 1085 | break; |
1085 | case (0x20): /* LNA1 A-B */ | 1086 | case 0x20: /* LNA1 A-B */ |
1086 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | 1087 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; |
1087 | antcomb->first_quick_scan_conf = | 1088 | antcomb->first_quick_scan_conf = |
1088 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | 1089 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; |
1089 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | 1090 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; |
1090 | break; | 1091 | break; |
1091 | case (0x21): /* LNA1 LNA2 */ | 1092 | case 0x21: /* LNA1 LNA2 */ |
1092 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; | 1093 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; |
1093 | antcomb->first_quick_scan_conf = | 1094 | antcomb->first_quick_scan_conf = |
1094 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | 1095 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; |
1095 | antcomb->second_quick_scan_conf = | 1096 | antcomb->second_quick_scan_conf = |
1096 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | 1097 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; |
1097 | break; | 1098 | break; |
1098 | case (0x12): /* LNA2 LNA1 */ | 1099 | case 0x12: /* LNA2 LNA1 */ |
1099 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; | 1100 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; |
1100 | antcomb->first_quick_scan_conf = | 1101 | antcomb->first_quick_scan_conf = |
1101 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | 1102 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; |
1102 | antcomb->second_quick_scan_conf = | 1103 | antcomb->second_quick_scan_conf = |
1103 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | 1104 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; |
1104 | break; | 1105 | break; |
1105 | case (0x13): /* LNA2 A+B */ | 1106 | case 0x13: /* LNA2 A+B */ |
1106 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | 1107 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; |
1107 | antcomb->first_quick_scan_conf = | 1108 | antcomb->first_quick_scan_conf = |
1108 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | 1109 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; |
1109 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | 1110 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; |
1110 | break; | 1111 | break; |
1111 | case (0x23): /* LNA1 A+B */ | 1112 | case 0x23: /* LNA1 A+B */ |
1112 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | 1113 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; |
1113 | antcomb->first_quick_scan_conf = | 1114 | antcomb->first_quick_scan_conf = |
1114 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | 1115 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; |
@@ -1325,65 +1326,148 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | |||
1325 | /* Adjust the fast_div_bias based on main and alt lna conf */ | 1326 | /* Adjust the fast_div_bias based on main and alt lna conf */ |
1326 | switch ((ant_conf->main_lna_conf << 4) | | 1327 | switch ((ant_conf->main_lna_conf << 4) | |
1327 | ant_conf->alt_lna_conf) { | 1328 | ant_conf->alt_lna_conf) { |
1328 | case (0x01): /* A-B LNA2 */ | 1329 | case 0x01: /* A-B LNA2 */ |
1329 | ant_conf->fast_div_bias = 0x3b; | 1330 | ant_conf->fast_div_bias = 0x3b; |
1330 | break; | 1331 | break; |
1331 | case (0x02): /* A-B LNA1 */ | 1332 | case 0x02: /* A-B LNA1 */ |
1332 | ant_conf->fast_div_bias = 0x3d; | 1333 | ant_conf->fast_div_bias = 0x3d; |
1333 | break; | 1334 | break; |
1334 | case (0x03): /* A-B A+B */ | 1335 | case 0x03: /* A-B A+B */ |
1335 | ant_conf->fast_div_bias = 0x1; | 1336 | ant_conf->fast_div_bias = 0x1; |
1336 | break; | 1337 | break; |
1337 | case (0x10): /* LNA2 A-B */ | 1338 | case 0x10: /* LNA2 A-B */ |
1338 | ant_conf->fast_div_bias = 0x7; | 1339 | ant_conf->fast_div_bias = 0x7; |
1339 | break; | 1340 | break; |
1340 | case (0x12): /* LNA2 LNA1 */ | 1341 | case 0x12: /* LNA2 LNA1 */ |
1341 | ant_conf->fast_div_bias = 0x2; | 1342 | ant_conf->fast_div_bias = 0x2; |
1342 | break; | 1343 | break; |
1343 | case (0x13): /* LNA2 A+B */ | 1344 | case 0x13: /* LNA2 A+B */ |
1344 | ant_conf->fast_div_bias = 0x7; | 1345 | ant_conf->fast_div_bias = 0x7; |
1345 | break; | 1346 | break; |
1346 | case (0x20): /* LNA1 A-B */ | 1347 | case 0x20: /* LNA1 A-B */ |
1347 | ant_conf->fast_div_bias = 0x6; | 1348 | ant_conf->fast_div_bias = 0x6; |
1348 | break; | 1349 | break; |
1349 | case (0x21): /* LNA1 LNA2 */ | 1350 | case 0x21: /* LNA1 LNA2 */ |
1350 | ant_conf->fast_div_bias = 0x0; | 1351 | ant_conf->fast_div_bias = 0x0; |
1351 | break; | 1352 | break; |
1352 | case (0x23): /* LNA1 A+B */ | 1353 | case 0x23: /* LNA1 A+B */ |
1353 | ant_conf->fast_div_bias = 0x6; | 1354 | ant_conf->fast_div_bias = 0x6; |
1354 | break; | 1355 | break; |
1355 | case (0x30): /* A+B A-B */ | 1356 | case 0x30: /* A+B A-B */ |
1356 | ant_conf->fast_div_bias = 0x1; | 1357 | ant_conf->fast_div_bias = 0x1; |
1357 | break; | 1358 | break; |
1358 | case (0x31): /* A+B LNA2 */ | 1359 | case 0x31: /* A+B LNA2 */ |
1359 | ant_conf->fast_div_bias = 0x3b; | 1360 | ant_conf->fast_div_bias = 0x3b; |
1360 | break; | 1361 | break; |
1361 | case (0x32): /* A+B LNA1 */ | 1362 | case 0x32: /* A+B LNA1 */ |
1362 | ant_conf->fast_div_bias = 0x3d; | 1363 | ant_conf->fast_div_bias = 0x3d; |
1363 | break; | 1364 | break; |
1364 | default: | 1365 | default: |
1365 | break; | 1366 | break; |
1366 | } | 1367 | } |
1368 | } else if (ant_conf->div_group == 1) { | ||
1369 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
1370 | switch ((ant_conf->main_lna_conf << 4) | | ||
1371 | ant_conf->alt_lna_conf) { | ||
1372 | case 0x01: /* A-B LNA2 */ | ||
1373 | ant_conf->fast_div_bias = 0x1; | ||
1374 | ant_conf->main_gaintb = 0; | ||
1375 | ant_conf->alt_gaintb = 0; | ||
1376 | break; | ||
1377 | case 0x02: /* A-B LNA1 */ | ||
1378 | ant_conf->fast_div_bias = 0x1; | ||
1379 | ant_conf->main_gaintb = 0; | ||
1380 | ant_conf->alt_gaintb = 0; | ||
1381 | break; | ||
1382 | case 0x03: /* A-B A+B */ | ||
1383 | ant_conf->fast_div_bias = 0x1; | ||
1384 | ant_conf->main_gaintb = 0; | ||
1385 | ant_conf->alt_gaintb = 0; | ||
1386 | break; | ||
1387 | case 0x10: /* LNA2 A-B */ | ||
1388 | if (!(antcomb->scan) && | ||
1389 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1390 | ant_conf->fast_div_bias = 0x3f; | ||
1391 | else | ||
1392 | ant_conf->fast_div_bias = 0x1; | ||
1393 | ant_conf->main_gaintb = 0; | ||
1394 | ant_conf->alt_gaintb = 0; | ||
1395 | break; | ||
1396 | case 0x12: /* LNA2 LNA1 */ | ||
1397 | ant_conf->fast_div_bias = 0x1; | ||
1398 | ant_conf->main_gaintb = 0; | ||
1399 | ant_conf->alt_gaintb = 0; | ||
1400 | break; | ||
1401 | case 0x13: /* LNA2 A+B */ | ||
1402 | if (!(antcomb->scan) && | ||
1403 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1404 | ant_conf->fast_div_bias = 0x3f; | ||
1405 | else | ||
1406 | ant_conf->fast_div_bias = 0x1; | ||
1407 | ant_conf->main_gaintb = 0; | ||
1408 | ant_conf->alt_gaintb = 0; | ||
1409 | break; | ||
1410 | case 0x20: /* LNA1 A-B */ | ||
1411 | if (!(antcomb->scan) && | ||
1412 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1413 | ant_conf->fast_div_bias = 0x3f; | ||
1414 | else | ||
1415 | ant_conf->fast_div_bias = 0x1; | ||
1416 | ant_conf->main_gaintb = 0; | ||
1417 | ant_conf->alt_gaintb = 0; | ||
1418 | break; | ||
1419 | case 0x21: /* LNA1 LNA2 */ | ||
1420 | ant_conf->fast_div_bias = 0x1; | ||
1421 | ant_conf->main_gaintb = 0; | ||
1422 | ant_conf->alt_gaintb = 0; | ||
1423 | break; | ||
1424 | case 0x23: /* LNA1 A+B */ | ||
1425 | if (!(antcomb->scan) && | ||
1426 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1427 | ant_conf->fast_div_bias = 0x3f; | ||
1428 | else | ||
1429 | ant_conf->fast_div_bias = 0x1; | ||
1430 | ant_conf->main_gaintb = 0; | ||
1431 | ant_conf->alt_gaintb = 0; | ||
1432 | break; | ||
1433 | case 0x30: /* A+B A-B */ | ||
1434 | ant_conf->fast_div_bias = 0x1; | ||
1435 | ant_conf->main_gaintb = 0; | ||
1436 | ant_conf->alt_gaintb = 0; | ||
1437 | break; | ||
1438 | case 0x31: /* A+B LNA2 */ | ||
1439 | ant_conf->fast_div_bias = 0x1; | ||
1440 | ant_conf->main_gaintb = 0; | ||
1441 | ant_conf->alt_gaintb = 0; | ||
1442 | break; | ||
1443 | case 0x32: /* A+B LNA1 */ | ||
1444 | ant_conf->fast_div_bias = 0x1; | ||
1445 | ant_conf->main_gaintb = 0; | ||
1446 | ant_conf->alt_gaintb = 0; | ||
1447 | break; | ||
1448 | default: | ||
1449 | break; | ||
1450 | } | ||
1367 | } else if (ant_conf->div_group == 2) { | 1451 | } else if (ant_conf->div_group == 2) { |
1368 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | 1452 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ |
1369 | switch ((ant_conf->main_lna_conf << 4) | | 1453 | switch ((ant_conf->main_lna_conf << 4) | |
1370 | ant_conf->alt_lna_conf) { | 1454 | ant_conf->alt_lna_conf) { |
1371 | case (0x01): /* A-B LNA2 */ | 1455 | case 0x01: /* A-B LNA2 */ |
1372 | ant_conf->fast_div_bias = 0x1; | 1456 | ant_conf->fast_div_bias = 0x1; |
1373 | ant_conf->main_gaintb = 0; | 1457 | ant_conf->main_gaintb = 0; |
1374 | ant_conf->alt_gaintb = 0; | 1458 | ant_conf->alt_gaintb = 0; |
1375 | break; | 1459 | break; |
1376 | case (0x02): /* A-B LNA1 */ | 1460 | case 0x02: /* A-B LNA1 */ |
1377 | ant_conf->fast_div_bias = 0x1; | 1461 | ant_conf->fast_div_bias = 0x1; |
1378 | ant_conf->main_gaintb = 0; | 1462 | ant_conf->main_gaintb = 0; |
1379 | ant_conf->alt_gaintb = 0; | 1463 | ant_conf->alt_gaintb = 0; |
1380 | break; | 1464 | break; |
1381 | case (0x03): /* A-B A+B */ | 1465 | case 0x03: /* A-B A+B */ |
1382 | ant_conf->fast_div_bias = 0x1; | 1466 | ant_conf->fast_div_bias = 0x1; |
1383 | ant_conf->main_gaintb = 0; | 1467 | ant_conf->main_gaintb = 0; |
1384 | ant_conf->alt_gaintb = 0; | 1468 | ant_conf->alt_gaintb = 0; |
1385 | break; | 1469 | break; |
1386 | case (0x10): /* LNA2 A-B */ | 1470 | case 0x10: /* LNA2 A-B */ |
1387 | if (!(antcomb->scan) && | 1471 | if (!(antcomb->scan) && |
1388 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | 1472 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) |
1389 | ant_conf->fast_div_bias = 0x1; | 1473 | ant_conf->fast_div_bias = 0x1; |
@@ -1392,12 +1476,12 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | |||
1392 | ant_conf->main_gaintb = 0; | 1476 | ant_conf->main_gaintb = 0; |
1393 | ant_conf->alt_gaintb = 0; | 1477 | ant_conf->alt_gaintb = 0; |
1394 | break; | 1478 | break; |
1395 | case (0x12): /* LNA2 LNA1 */ | 1479 | case 0x12: /* LNA2 LNA1 */ |
1396 | ant_conf->fast_div_bias = 0x1; | 1480 | ant_conf->fast_div_bias = 0x1; |
1397 | ant_conf->main_gaintb = 0; | 1481 | ant_conf->main_gaintb = 0; |
1398 | ant_conf->alt_gaintb = 0; | 1482 | ant_conf->alt_gaintb = 0; |
1399 | break; | 1483 | break; |
1400 | case (0x13): /* LNA2 A+B */ | 1484 | case 0x13: /* LNA2 A+B */ |
1401 | if (!(antcomb->scan) && | 1485 | if (!(antcomb->scan) && |
1402 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | 1486 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) |
1403 | ant_conf->fast_div_bias = 0x1; | 1487 | ant_conf->fast_div_bias = 0x1; |
@@ -1406,7 +1490,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | |||
1406 | ant_conf->main_gaintb = 0; | 1490 | ant_conf->main_gaintb = 0; |
1407 | ant_conf->alt_gaintb = 0; | 1491 | ant_conf->alt_gaintb = 0; |
1408 | break; | 1492 | break; |
1409 | case (0x20): /* LNA1 A-B */ | 1493 | case 0x20: /* LNA1 A-B */ |
1410 | if (!(antcomb->scan) && | 1494 | if (!(antcomb->scan) && |
1411 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | 1495 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) |
1412 | ant_conf->fast_div_bias = 0x1; | 1496 | ant_conf->fast_div_bias = 0x1; |
@@ -1415,12 +1499,12 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | |||
1415 | ant_conf->main_gaintb = 0; | 1499 | ant_conf->main_gaintb = 0; |
1416 | ant_conf->alt_gaintb = 0; | 1500 | ant_conf->alt_gaintb = 0; |
1417 | break; | 1501 | break; |
1418 | case (0x21): /* LNA1 LNA2 */ | 1502 | case 0x21: /* LNA1 LNA2 */ |
1419 | ant_conf->fast_div_bias = 0x1; | 1503 | ant_conf->fast_div_bias = 0x1; |
1420 | ant_conf->main_gaintb = 0; | 1504 | ant_conf->main_gaintb = 0; |
1421 | ant_conf->alt_gaintb = 0; | 1505 | ant_conf->alt_gaintb = 0; |
1422 | break; | 1506 | break; |
1423 | case (0x23): /* LNA1 A+B */ | 1507 | case 0x23: /* LNA1 A+B */ |
1424 | if (!(antcomb->scan) && | 1508 | if (!(antcomb->scan) && |
1425 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | 1509 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) |
1426 | ant_conf->fast_div_bias = 0x1; | 1510 | ant_conf->fast_div_bias = 0x1; |
@@ -1429,17 +1513,17 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | |||
1429 | ant_conf->main_gaintb = 0; | 1513 | ant_conf->main_gaintb = 0; |
1430 | ant_conf->alt_gaintb = 0; | 1514 | ant_conf->alt_gaintb = 0; |
1431 | break; | 1515 | break; |
1432 | case (0x30): /* A+B A-B */ | 1516 | case 0x30: /* A+B A-B */ |
1433 | ant_conf->fast_div_bias = 0x1; | 1517 | ant_conf->fast_div_bias = 0x1; |
1434 | ant_conf->main_gaintb = 0; | 1518 | ant_conf->main_gaintb = 0; |
1435 | ant_conf->alt_gaintb = 0; | 1519 | ant_conf->alt_gaintb = 0; |
1436 | break; | 1520 | break; |
1437 | case (0x31): /* A+B LNA2 */ | 1521 | case 0x31: /* A+B LNA2 */ |
1438 | ant_conf->fast_div_bias = 0x1; | 1522 | ant_conf->fast_div_bias = 0x1; |
1439 | ant_conf->main_gaintb = 0; | 1523 | ant_conf->main_gaintb = 0; |
1440 | ant_conf->alt_gaintb = 0; | 1524 | ant_conf->alt_gaintb = 0; |
1441 | break; | 1525 | break; |
1442 | case (0x32): /* A+B LNA1 */ | 1526 | case 0x32: /* A+B LNA1 */ |
1443 | ant_conf->fast_div_bias = 0x1; | 1527 | ant_conf->fast_div_bias = 0x1; |
1444 | ant_conf->main_gaintb = 0; | 1528 | ant_conf->main_gaintb = 0; |
1445 | ant_conf->alt_gaintb = 0; | 1529 | ant_conf->alt_gaintb = 0; |
@@ -1447,9 +1531,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | |||
1447 | default: | 1531 | default: |
1448 | break; | 1532 | break; |
1449 | } | 1533 | } |
1450 | |||
1451 | } | 1534 | } |
1452 | |||
1453 | } | 1535 | } |
1454 | 1536 | ||
1455 | /* Antenna diversity and combining */ | 1537 | /* Antenna diversity and combining */ |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index c18ee9921fb1..a4833880accd 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -788,6 +788,10 @@ | |||
788 | #define AR_SREV_REVISION_9271_11 1 | 788 | #define AR_SREV_REVISION_9271_11 1 |
789 | #define AR_SREV_VERSION_9300 0x1c0 | 789 | #define AR_SREV_VERSION_9300 0x1c0 |
790 | #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ | 790 | #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ |
791 | #define AR_SREV_VERSION_9330 0x200 | ||
792 | #define AR_SREV_REVISION_9330_10 0 | ||
793 | #define AR_SREV_REVISION_9330_11 1 | ||
794 | #define AR_SREV_REVISION_9330_12 2 | ||
791 | #define AR_SREV_VERSION_9485 0x240 | 795 | #define AR_SREV_VERSION_9485 0x240 |
792 | #define AR_SREV_REVISION_9485_10 0 | 796 | #define AR_SREV_REVISION_9485_10 0 |
793 | #define AR_SREV_REVISION_9485_11 1 | 797 | #define AR_SREV_REVISION_9485_11 1 |
@@ -862,6 +866,18 @@ | |||
862 | #define AR_SREV_9300_20_OR_LATER(_ah) \ | 866 | #define AR_SREV_9300_20_OR_LATER(_ah) \ |
863 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) | 867 | ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) |
864 | 868 | ||
869 | #define AR_SREV_9330(_ah) \ | ||
870 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330)) | ||
871 | #define AR_SREV_9330_10(_ah) \ | ||
872 | (AR_SREV_9330((_ah)) && \ | ||
873 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_10)) | ||
874 | #define AR_SREV_9330_11(_ah) \ | ||
875 | (AR_SREV_9330((_ah)) && \ | ||
876 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_11)) | ||
877 | #define AR_SREV_9330_12(_ah) \ | ||
878 | (AR_SREV_9330((_ah)) && \ | ||
879 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_12)) | ||
880 | |||
865 | #define AR_SREV_9485(_ah) \ | 881 | #define AR_SREV_9485(_ah) \ |
866 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) | 882 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) |
867 | #define AR_SREV_9485_10(_ah) \ | 883 | #define AR_SREV_9485_10(_ah) \ |
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index fe26bf448fdb..d5add69aac8f 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -31,6 +31,11 @@ config B43_BCMA | |||
31 | depends on B43 && BCMA && BROKEN | 31 | depends on B43 && BCMA && BROKEN |
32 | default y | 32 | default y |
33 | 33 | ||
34 | config B43_SSB | ||
35 | bool | ||
36 | depends on B43 && SSB | ||
37 | default y | ||
38 | |||
34 | # Auto-select SSB PCI-HOST support, if possible | 39 | # Auto-select SSB PCI-HOST support, if possible |
35 | config B43_PCI_AUTOSELECT | 40 | config B43_PCI_AUTOSELECT |
36 | bool | 41 | bool |
@@ -112,6 +117,14 @@ config B43_PHY_LP | |||
112 | and embedded devices. It supports 802.11a/g | 117 | and embedded devices. It supports 802.11a/g |
113 | (802.11a support is optional, and currently disabled). | 118 | (802.11a support is optional, and currently disabled). |
114 | 119 | ||
120 | config B43_PHY_HT | ||
121 | bool "Support for HT-PHY devices (BROKEN)" | ||
122 | depends on B43 && BROKEN | ||
123 | ---help--- | ||
124 | Support for the HT-PHY. | ||
125 | |||
126 | Say N, this is BROKEN and crashes driver. | ||
127 | |||
115 | # This config option automatically enables b43 LEDS support, | 128 | # This config option automatically enables b43 LEDS support, |
116 | # if it's possible. | 129 | # if it's possible. |
117 | config B43_LEDS | 130 | config B43_LEDS |
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 95f7c001fda1..900dc9c8c688 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile | |||
@@ -10,6 +10,8 @@ b43-y += phy_a.o | |||
10 | b43-$(CONFIG_B43_PHY_N) += phy_n.o | 10 | b43-$(CONFIG_B43_PHY_N) += phy_n.o |
11 | b43-$(CONFIG_B43_PHY_LP) += phy_lp.o | 11 | b43-$(CONFIG_B43_PHY_LP) += phy_lp.o |
12 | b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o | 12 | b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o |
13 | b43-$(CONFIG_B43_PHY_HT) += phy_ht.o | ||
14 | b43-$(CONFIG_B43_PHY_HT) += radio_2059.o | ||
13 | b43-y += sysfs.o | 15 | b43-y += sysfs.o |
14 | b43-y += xmit.o | 16 | b43-y += xmit.o |
15 | b43-y += lo.o | 17 | b43-y += lo.o |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 1cb2ddee9dcf..666515e348b5 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -92,6 +92,8 @@ | |||
92 | #define B43_MMIO_PIO11_BASE4 0x300 | 92 | #define B43_MMIO_PIO11_BASE4 0x300 |
93 | #define B43_MMIO_PIO11_BASE5 0x340 | 93 | #define B43_MMIO_PIO11_BASE5 0x340 |
94 | 94 | ||
95 | #define B43_MMIO_RADIO24_CONTROL 0x3D8 /* core rev >= 24 only */ | ||
96 | #define B43_MMIO_RADIO24_DATA 0x3DA /* core rev >= 24 only */ | ||
95 | #define B43_MMIO_PHY_VER 0x3E0 | 97 | #define B43_MMIO_PHY_VER 0x3E0 |
96 | #define B43_MMIO_PHY_RADIO 0x3E2 | 98 | #define B43_MMIO_PHY_RADIO 0x3E2 |
97 | #define B43_MMIO_PHY0 0x3E6 | 99 | #define B43_MMIO_PHY0 0x3E6 |
@@ -363,6 +365,10 @@ enum { | |||
363 | #define B43_PHYTYPE_G 0x02 | 365 | #define B43_PHYTYPE_G 0x02 |
364 | #define B43_PHYTYPE_N 0x04 | 366 | #define B43_PHYTYPE_N 0x04 |
365 | #define B43_PHYTYPE_LP 0x05 | 367 | #define B43_PHYTYPE_LP 0x05 |
368 | #define B43_PHYTYPE_SSLPN 0x06 | ||
369 | #define B43_PHYTYPE_HT 0x07 | ||
370 | #define B43_PHYTYPE_LCN 0x08 | ||
371 | #define B43_PHYTYPE_LCNXN 0x09 | ||
366 | 372 | ||
367 | /* PHYRegisters */ | 373 | /* PHYRegisters */ |
368 | #define B43_PHY_ILT_A_CTRL 0x0072 | 374 | #define B43_PHY_ILT_A_CTRL 0x0072 |
diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index 6c63aecd6ab4..4200713eb597 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | 26 | ||
27 | /* SSB */ | 27 | /* SSB */ |
28 | 28 | #ifdef CONFIG_B43_SSB | |
29 | static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev) | 29 | static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev) |
30 | { | 30 | { |
31 | return ssb_bus_may_powerdown(dev->sdev->bus); | 31 | return ssb_bus_may_powerdown(dev->sdev->bus); |
@@ -83,7 +83,11 @@ void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer, | |||
83 | 83 | ||
84 | struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) | 84 | struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) |
85 | { | 85 | { |
86 | struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 86 | struct b43_bus_dev *dev; |
87 | |||
88 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
89 | if (!dev) | ||
90 | return NULL; | ||
87 | 91 | ||
88 | dev->bus_type = B43_BUS_SSB; | 92 | dev->bus_type = B43_BUS_SSB; |
89 | dev->sdev = sdev; | 93 | dev->sdev = sdev; |
@@ -120,3 +124,4 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) | |||
120 | 124 | ||
121 | return dev; | 125 | return dev; |
122 | } | 126 | } |
127 | #endif /* CONFIG_B43_SSB */ | ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index cae31463ead9..e9a01e3eede7 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -123,6 +123,7 @@ static const struct bcma_device_id b43_bcma_tbl[] = { | |||
123 | MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); | 123 | MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); |
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | #ifdef CONFIG_B43_SSB | ||
126 | static const struct ssb_device_id b43_ssb_tbl[] = { | 127 | static const struct ssb_device_id b43_ssb_tbl[] = { |
127 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), | 128 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), |
128 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), | 129 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), |
@@ -136,8 +137,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = { | |||
136 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), | 137 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), |
137 | SSB_DEVTABLE_END | 138 | SSB_DEVTABLE_END |
138 | }; | 139 | }; |
139 | |||
140 | MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); | 140 | MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); |
141 | #endif | ||
141 | 142 | ||
142 | /* Channel and ratetables are shared for all devices. | 143 | /* Channel and ratetables are shared for all devices. |
143 | * They can't be const, because ieee80211 puts some precalculated | 144 | * They can't be const, because ieee80211 puts some precalculated |
@@ -4097,6 +4098,12 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4097 | unsupported = 1; | 4098 | unsupported = 1; |
4098 | break; | 4099 | break; |
4099 | #endif | 4100 | #endif |
4101 | #ifdef CONFIG_B43_PHY_HT | ||
4102 | case B43_PHYTYPE_HT: | ||
4103 | if (phy_rev > 1) | ||
4104 | unsupported = 1; | ||
4105 | break; | ||
4106 | #endif | ||
4100 | default: | 4107 | default: |
4101 | unsupported = 1; | 4108 | unsupported = 1; |
4102 | } | 4109 | } |
@@ -4153,6 +4160,10 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4153 | if (radio_ver != 0x2062 && radio_ver != 0x2063) | 4160 | if (radio_ver != 0x2062 && radio_ver != 0x2063) |
4154 | unsupported = 1; | 4161 | unsupported = 1; |
4155 | break; | 4162 | break; |
4163 | case B43_PHYTYPE_HT: | ||
4164 | if (radio_ver != 0x2059) | ||
4165 | unsupported = 1; | ||
4166 | break; | ||
4156 | default: | 4167 | default: |
4157 | B43_WARN_ON(1); | 4168 | B43_WARN_ON(1); |
4158 | } | 4169 | } |
@@ -5016,6 +5027,7 @@ static struct bcma_driver b43_bcma_driver = { | |||
5016 | }; | 5027 | }; |
5017 | #endif | 5028 | #endif |
5018 | 5029 | ||
5030 | #ifdef CONFIG_B43_SSB | ||
5019 | static | 5031 | static |
5020 | int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) | 5032 | int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) |
5021 | { | 5033 | { |
@@ -5025,6 +5037,8 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) | |||
5025 | int first = 0; | 5037 | int first = 0; |
5026 | 5038 | ||
5027 | dev = b43_bus_dev_ssb_init(sdev); | 5039 | dev = b43_bus_dev_ssb_init(sdev); |
5040 | if (!dev) | ||
5041 | return -ENOMEM; | ||
5028 | 5042 | ||
5029 | wl = ssb_get_devtypedata(sdev); | 5043 | wl = ssb_get_devtypedata(sdev); |
5030 | if (!wl) { | 5044 | if (!wl) { |
@@ -5091,6 +5105,14 @@ static void b43_ssb_remove(struct ssb_device *sdev) | |||
5091 | } | 5105 | } |
5092 | } | 5106 | } |
5093 | 5107 | ||
5108 | static struct ssb_driver b43_ssb_driver = { | ||
5109 | .name = KBUILD_MODNAME, | ||
5110 | .id_table = b43_ssb_tbl, | ||
5111 | .probe = b43_ssb_probe, | ||
5112 | .remove = b43_ssb_remove, | ||
5113 | }; | ||
5114 | #endif /* CONFIG_B43_SSB */ | ||
5115 | |||
5094 | /* Perform a hardware reset. This can be called from any context. */ | 5116 | /* Perform a hardware reset. This can be called from any context. */ |
5095 | void b43_controller_restart(struct b43_wldev *dev, const char *reason) | 5117 | void b43_controller_restart(struct b43_wldev *dev, const char *reason) |
5096 | { | 5118 | { |
@@ -5101,13 +5123,6 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason) | |||
5101 | ieee80211_queue_work(dev->wl->hw, &dev->restart_work); | 5123 | ieee80211_queue_work(dev->wl->hw, &dev->restart_work); |
5102 | } | 5124 | } |
5103 | 5125 | ||
5104 | static struct ssb_driver b43_ssb_driver = { | ||
5105 | .name = KBUILD_MODNAME, | ||
5106 | .id_table = b43_ssb_tbl, | ||
5107 | .probe = b43_ssb_probe, | ||
5108 | .remove = b43_ssb_remove, | ||
5109 | }; | ||
5110 | |||
5111 | static void b43_print_driverinfo(void) | 5126 | static void b43_print_driverinfo(void) |
5112 | { | 5127 | { |
5113 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", | 5128 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", |
@@ -5151,14 +5166,18 @@ static int __init b43_init(void) | |||
5151 | if (err) | 5166 | if (err) |
5152 | goto err_sdio_exit; | 5167 | goto err_sdio_exit; |
5153 | #endif | 5168 | #endif |
5169 | #ifdef CONFIG_B43_SSB | ||
5154 | err = ssb_driver_register(&b43_ssb_driver); | 5170 | err = ssb_driver_register(&b43_ssb_driver); |
5155 | if (err) | 5171 | if (err) |
5156 | goto err_bcma_driver_exit; | 5172 | goto err_bcma_driver_exit; |
5173 | #endif | ||
5157 | b43_print_driverinfo(); | 5174 | b43_print_driverinfo(); |
5158 | 5175 | ||
5159 | return err; | 5176 | return err; |
5160 | 5177 | ||
5178 | #ifdef CONFIG_B43_SSB | ||
5161 | err_bcma_driver_exit: | 5179 | err_bcma_driver_exit: |
5180 | #endif | ||
5162 | #ifdef CONFIG_B43_BCMA | 5181 | #ifdef CONFIG_B43_BCMA |
5163 | bcma_driver_unregister(&b43_bcma_driver); | 5182 | bcma_driver_unregister(&b43_bcma_driver); |
5164 | err_sdio_exit: | 5183 | err_sdio_exit: |
@@ -5173,7 +5192,9 @@ err_dfs_exit: | |||
5173 | 5192 | ||
5174 | static void __exit b43_exit(void) | 5193 | static void __exit b43_exit(void) |
5175 | { | 5194 | { |
5195 | #ifdef CONFIG_B43_SSB | ||
5176 | ssb_driver_unregister(&b43_ssb_driver); | 5196 | ssb_driver_unregister(&b43_ssb_driver); |
5197 | #endif | ||
5177 | #ifdef CONFIG_B43_BCMA | 5198 | #ifdef CONFIG_B43_BCMA |
5178 | bcma_driver_unregister(&b43_bcma_driver); | 5199 | bcma_driver_unregister(&b43_bcma_driver); |
5179 | #endif | 5200 | #endif |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 425af28ea4e5..9705950f059a 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "phy_a.h" | 31 | #include "phy_a.h" |
32 | #include "phy_n.h" | 32 | #include "phy_n.h" |
33 | #include "phy_lp.h" | 33 | #include "phy_lp.h" |
34 | #include "phy_ht.h" | ||
34 | #include "b43.h" | 35 | #include "b43.h" |
35 | #include "main.h" | 36 | #include "main.h" |
36 | 37 | ||
@@ -59,6 +60,11 @@ int b43_phy_allocate(struct b43_wldev *dev) | |||
59 | phy->ops = &b43_phyops_lp; | 60 | phy->ops = &b43_phyops_lp; |
60 | #endif | 61 | #endif |
61 | break; | 62 | break; |
63 | case B43_PHYTYPE_HT: | ||
64 | #ifdef CONFIG_B43_PHY_HT | ||
65 | phy->ops = &b43_phyops_ht; | ||
66 | #endif | ||
67 | break; | ||
62 | } | 68 | } |
63 | if (B43_WARN_ON(!phy->ops)) | 69 | if (B43_WARN_ON(!phy->ops)) |
64 | return -ENODEV; | 70 | return -ENODEV; |
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 2401bee8b081..47dcb800a3c3 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h | |||
@@ -194,6 +194,7 @@ struct b43_phy_a; | |||
194 | struct b43_phy_g; | 194 | struct b43_phy_g; |
195 | struct b43_phy_n; | 195 | struct b43_phy_n; |
196 | struct b43_phy_lp; | 196 | struct b43_phy_lp; |
197 | struct b43_phy_ht; | ||
197 | 198 | ||
198 | struct b43_phy { | 199 | struct b43_phy { |
199 | /* Hardware operation callbacks. */ | 200 | /* Hardware operation callbacks. */ |
@@ -216,6 +217,8 @@ struct b43_phy { | |||
216 | struct b43_phy_n *n; | 217 | struct b43_phy_n *n; |
217 | /* LP-PHY specific information */ | 218 | /* LP-PHY specific information */ |
218 | struct b43_phy_lp *lp; | 219 | struct b43_phy_lp *lp; |
220 | /* HT-PHY specific information */ | ||
221 | struct b43_phy_ht *ht; | ||
219 | }; | 222 | }; |
220 | 223 | ||
221 | /* Band support flags. */ | 224 | /* Band support flags. */ |
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c new file mode 100644 index 000000000000..72f01ce8b42c --- /dev/null +++ b/drivers/net/wireless/b43/phy_ht.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | |||
3 | Broadcom B43 wireless driver | ||
4 | IEEE 802.11n HT-PHY support | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; see the file COPYING. If not, write to | ||
18 | the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, | ||
19 | Boston, MA 02110-1301, USA. | ||
20 | |||
21 | */ | ||
22 | |||
23 | #include <linux/slab.h> | ||
24 | |||
25 | #include "b43.h" | ||
26 | #include "phy_ht.h" | ||
27 | #include "radio_2059.h" | ||
28 | #include "main.h" | ||
29 | |||
30 | static void b43_radio_2059_channel_setup(struct b43_wldev *dev, | ||
31 | const struct b43_phy_ht_channeltab_e_radio2059 *e) | ||
32 | { | ||
33 | u8 i; | ||
34 | u16 routing; | ||
35 | |||
36 | b43_radio_write(dev, 0x16, e->radio_syn16); | ||
37 | b43_radio_write(dev, 0x17, e->radio_syn17); | ||
38 | b43_radio_write(dev, 0x22, e->radio_syn22); | ||
39 | b43_radio_write(dev, 0x25, e->radio_syn25); | ||
40 | b43_radio_write(dev, 0x27, e->radio_syn27); | ||
41 | b43_radio_write(dev, 0x28, e->radio_syn28); | ||
42 | b43_radio_write(dev, 0x29, e->radio_syn29); | ||
43 | b43_radio_write(dev, 0x2c, e->radio_syn2c); | ||
44 | b43_radio_write(dev, 0x2d, e->radio_syn2d); | ||
45 | b43_radio_write(dev, 0x37, e->radio_syn37); | ||
46 | b43_radio_write(dev, 0x41, e->radio_syn41); | ||
47 | b43_radio_write(dev, 0x43, e->radio_syn43); | ||
48 | b43_radio_write(dev, 0x47, e->radio_syn47); | ||
49 | b43_radio_write(dev, 0x4a, e->radio_syn4a); | ||
50 | b43_radio_write(dev, 0x58, e->radio_syn58); | ||
51 | b43_radio_write(dev, 0x5a, e->radio_syn5a); | ||
52 | b43_radio_write(dev, 0x6a, e->radio_syn6a); | ||
53 | b43_radio_write(dev, 0x6d, e->radio_syn6d); | ||
54 | b43_radio_write(dev, 0x6e, e->radio_syn6e); | ||
55 | b43_radio_write(dev, 0x92, e->radio_syn92); | ||
56 | b43_radio_write(dev, 0x98, e->radio_syn98); | ||
57 | |||
58 | for (i = 0; i < 2; i++) { | ||
59 | routing = i ? 0x800 : 0x400; | ||
60 | b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a); | ||
61 | b43_radio_write(dev, routing | 0x58, e->radio_rxtx58); | ||
62 | b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a); | ||
63 | b43_radio_write(dev, routing | 0x6a, e->radio_rxtx6a); | ||
64 | b43_radio_write(dev, routing | 0x6d, e->radio_rxtx6d); | ||
65 | b43_radio_write(dev, routing | 0x6e, e->radio_rxtx6e); | ||
66 | b43_radio_write(dev, routing | 0x92, e->radio_rxtx92); | ||
67 | b43_radio_write(dev, routing | 0x98, e->radio_rxtx98); | ||
68 | } | ||
69 | |||
70 | udelay(50); | ||
71 | |||
72 | /* Calibration */ | ||
73 | b43_radio_mask(dev, 0x2b, ~0x1); | ||
74 | b43_radio_mask(dev, 0x2e, ~0x4); | ||
75 | b43_radio_set(dev, 0x2e, 0x4); | ||
76 | b43_radio_set(dev, 0x2b, 0x1); | ||
77 | |||
78 | udelay(300); | ||
79 | } | ||
80 | |||
81 | static void b43_phy_ht_channel_setup(struct b43_wldev *dev, | ||
82 | const struct b43_phy_ht_channeltab_e_phy *e, | ||
83 | struct ieee80211_channel *new_channel) | ||
84 | { | ||
85 | /* TODO */ | ||
86 | } | ||
87 | |||
88 | static int b43_phy_ht_set_channel(struct b43_wldev *dev, | ||
89 | struct ieee80211_channel *channel, | ||
90 | enum nl80211_channel_type channel_type) | ||
91 | { | ||
92 | struct b43_phy *phy = &dev->phy; | ||
93 | |||
94 | const struct b43_phy_ht_channeltab_e_radio2059 *chent_r2059 = NULL; | ||
95 | |||
96 | if (phy->radio_ver == 0x2059) { | ||
97 | chent_r2059 = b43_phy_ht_get_channeltab_e_r2059(dev, | ||
98 | channel->center_freq); | ||
99 | if (!chent_r2059) | ||
100 | return -ESRCH; | ||
101 | } else { | ||
102 | return -ESRCH; | ||
103 | } | ||
104 | |||
105 | /* TODO: In case of N-PHY some bandwidth switching goes here */ | ||
106 | |||
107 | if (phy->radio_ver == 0x2059) { | ||
108 | b43_radio_2059_channel_setup(dev, chent_r2059); | ||
109 | b43_phy_ht_channel_setup(dev, &(chent_r2059->phy_regs), | ||
110 | channel); | ||
111 | } else { | ||
112 | return -ESRCH; | ||
113 | } | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | /************************************************** | ||
119 | * Basic PHY ops. | ||
120 | **************************************************/ | ||
121 | |||
122 | static int b43_phy_ht_op_allocate(struct b43_wldev *dev) | ||
123 | { | ||
124 | struct b43_phy_ht *phy_ht; | ||
125 | |||
126 | phy_ht = kzalloc(sizeof(*phy_ht), GFP_KERNEL); | ||
127 | if (!phy_ht) | ||
128 | return -ENOMEM; | ||
129 | dev->phy.ht = phy_ht; | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev) | ||
135 | { | ||
136 | struct b43_phy *phy = &dev->phy; | ||
137 | struct b43_phy_ht *phy_ht = phy->ht; | ||
138 | |||
139 | memset(phy_ht, 0, sizeof(*phy_ht)); | ||
140 | } | ||
141 | |||
142 | static void b43_phy_ht_op_free(struct b43_wldev *dev) | ||
143 | { | ||
144 | struct b43_phy *phy = &dev->phy; | ||
145 | struct b43_phy_ht *phy_ht = phy->ht; | ||
146 | |||
147 | kfree(phy_ht); | ||
148 | phy->ht = NULL; | ||
149 | } | ||
150 | |||
151 | /* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */ | ||
152 | static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev, | ||
153 | bool blocked) | ||
154 | { | ||
155 | if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) | ||
156 | b43err(dev->wl, "MAC not suspended\n"); | ||
157 | |||
158 | if (blocked) { | ||
159 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); | ||
160 | } else { | ||
161 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); | ||
162 | b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x1); | ||
163 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0); | ||
164 | b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x2); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) | ||
169 | { | ||
170 | if (on) { | ||
171 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd); | ||
172 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000); | ||
173 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd); | ||
174 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000); | ||
175 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd); | ||
176 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000); | ||
177 | } else { | ||
178 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff); | ||
179 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd); | ||
180 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff); | ||
181 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd); | ||
182 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff); | ||
183 | b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev, | ||
188 | unsigned int new_channel) | ||
189 | { | ||
190 | struct ieee80211_channel *channel = dev->wl->hw->conf.channel; | ||
191 | enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; | ||
192 | |||
193 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
194 | if ((new_channel < 1) || (new_channel > 14)) | ||
195 | return -EINVAL; | ||
196 | } else { | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | |||
200 | return b43_phy_ht_set_channel(dev, channel, channel_type); | ||
201 | } | ||
202 | |||
203 | static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev) | ||
204 | { | ||
205 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
206 | return 1; | ||
207 | return 36; | ||
208 | } | ||
209 | |||
210 | /************************************************** | ||
211 | * R/W ops. | ||
212 | **************************************************/ | ||
213 | |||
214 | static u16 b43_phy_ht_op_read(struct b43_wldev *dev, u16 reg) | ||
215 | { | ||
216 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
217 | return b43_read16(dev, B43_MMIO_PHY_DATA); | ||
218 | } | ||
219 | |||
220 | static void b43_phy_ht_op_write(struct b43_wldev *dev, u16 reg, u16 value) | ||
221 | { | ||
222 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
223 | b43_write16(dev, B43_MMIO_PHY_DATA, value); | ||
224 | } | ||
225 | |||
226 | static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, | ||
227 | u16 set) | ||
228 | { | ||
229 | b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); | ||
230 | b43_write16(dev, B43_MMIO_PHY_DATA, | ||
231 | (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); | ||
232 | } | ||
233 | |||
234 | static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg) | ||
235 | { | ||
236 | /* HT-PHY needs 0x200 for read access */ | ||
237 | reg |= 0x200; | ||
238 | |||
239 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); | ||
240 | return b43_read16(dev, B43_MMIO_RADIO24_DATA); | ||
241 | } | ||
242 | |||
243 | static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg, | ||
244 | u16 value) | ||
245 | { | ||
246 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); | ||
247 | b43_write16(dev, B43_MMIO_RADIO24_DATA, value); | ||
248 | } | ||
249 | |||
250 | /************************************************** | ||
251 | * PHY ops struct. | ||
252 | **************************************************/ | ||
253 | |||
254 | const struct b43_phy_operations b43_phyops_ht = { | ||
255 | .allocate = b43_phy_ht_op_allocate, | ||
256 | .free = b43_phy_ht_op_free, | ||
257 | .prepare_structs = b43_phy_ht_op_prepare_structs, | ||
258 | /* | ||
259 | .init = b43_phy_ht_op_init, | ||
260 | */ | ||
261 | .phy_read = b43_phy_ht_op_read, | ||
262 | .phy_write = b43_phy_ht_op_write, | ||
263 | .phy_maskset = b43_phy_ht_op_maskset, | ||
264 | .radio_read = b43_phy_ht_op_radio_read, | ||
265 | .radio_write = b43_phy_ht_op_radio_write, | ||
266 | .software_rfkill = b43_phy_ht_op_software_rfkill, | ||
267 | .switch_analog = b43_phy_ht_op_switch_analog, | ||
268 | .switch_channel = b43_phy_ht_op_switch_channel, | ||
269 | .get_default_chan = b43_phy_ht_op_get_default_chan, | ||
270 | /* | ||
271 | .recalc_txpower = b43_phy_ht_op_recalc_txpower, | ||
272 | .adjust_txpower = b43_phy_ht_op_adjust_txpower, | ||
273 | */ | ||
274 | }; | ||
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h new file mode 100644 index 000000000000..afa448d6571e --- /dev/null +++ b/drivers/net/wireless/b43/phy_ht.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef B43_PHY_HT_H_ | ||
2 | #define B43_PHY_HT_H_ | ||
3 | |||
4 | #include "phy_common.h" | ||
5 | |||
6 | |||
7 | #define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */ | ||
8 | #define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ | ||
9 | #define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ | ||
10 | |||
11 | #define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) | ||
12 | |||
13 | #define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110) | ||
14 | #define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111) | ||
15 | #define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114) | ||
16 | #define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115) | ||
17 | #define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118) | ||
18 | #define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119) | ||
19 | |||
20 | |||
21 | /* Values for PHY registers used on channel switching */ | ||
22 | struct b43_phy_ht_channeltab_e_phy { | ||
23 | /* TODO */ | ||
24 | }; | ||
25 | |||
26 | |||
27 | struct b43_phy_ht { | ||
28 | }; | ||
29 | |||
30 | |||
31 | struct b43_phy_operations; | ||
32 | extern const struct b43_phy_operations b43_phyops_ht; | ||
33 | |||
34 | #endif /* B43_PHY_HT_H_ */ | ||
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index ad14f3b428c5..e7dfdac9e4d7 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -4025,11 +4025,24 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, | |||
4025 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */ | 4025 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */ |
4026 | static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) | 4026 | static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) |
4027 | { | 4027 | { |
4028 | u16 val = on ? 0 : 0x7FFF; | 4028 | u16 override = on ? 0x0 : 0x7FFF; |
4029 | u16 core = on ? 0xD : 0x00FD; | ||
4029 | 4030 | ||
4030 | if (dev->phy.rev >= 3) | 4031 | if (dev->phy.rev >= 3) { |
4031 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, val); | 4032 | if (on) { |
4032 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, val); | 4033 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, core); |
4034 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override); | ||
4035 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, core); | ||
4036 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); | ||
4037 | } else { | ||
4038 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override); | ||
4039 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, core); | ||
4040 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); | ||
4041 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, core); | ||
4042 | } | ||
4043 | } else { | ||
4044 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override); | ||
4045 | } | ||
4033 | } | 4046 | } |
4034 | 4047 | ||
4035 | static int b43_nphy_op_switch_channel(struct b43_wldev *dev, | 4048 | static int b43_nphy_op_switch_channel(struct b43_wldev *dev, |
diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h index d9bfa0f21b72..67f96122f8d8 100644 --- a/drivers/net/wireless/b43/radio_2055.h +++ b/drivers/net/wireless/b43/radio_2055.h | |||
@@ -251,4 +251,9 @@ struct b43_nphy_channeltab_entry_rev2 { | |||
251 | void b2055_upload_inittab(struct b43_wldev *dev, | 251 | void b2055_upload_inittab(struct b43_wldev *dev, |
252 | bool ghz5, bool ignore_uploadflag); | 252 | bool ghz5, bool ignore_uploadflag); |
253 | 253 | ||
254 | /* Get the NPHY Channel Switch Table entry for a channel. | ||
255 | * Returns NULL on failure to find an entry. */ | ||
256 | const struct b43_nphy_channeltab_entry_rev2 * | ||
257 | b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); | ||
258 | |||
254 | #endif /* B43_RADIO_2055_H_ */ | 259 | #endif /* B43_RADIO_2055_H_ */ |
diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h index d601f6e7e313..d52df6be705a 100644 --- a/drivers/net/wireless/b43/radio_2056.h +++ b/drivers/net/wireless/b43/radio_2056.h | |||
@@ -1117,4 +1117,9 @@ struct b43_nphy_channeltab_entry_rev3 { | |||
1117 | void b2056_upload_inittabs(struct b43_wldev *dev, | 1117 | void b2056_upload_inittabs(struct b43_wldev *dev, |
1118 | bool ghz5, bool ignore_uploadflag); | 1118 | bool ghz5, bool ignore_uploadflag); |
1119 | 1119 | ||
1120 | /* Get the NPHY Channel Switch Table entry for a channel. | ||
1121 | * Returns NULL on failure to find an entry. */ | ||
1122 | const struct b43_nphy_channeltab_entry_rev3 * | ||
1123 | b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); | ||
1124 | |||
1120 | #endif /* B43_RADIO_2056_H_ */ | 1125 | #endif /* B43_RADIO_2056_H_ */ |
diff --git a/drivers/net/wireless/b43/radio_2059.c b/drivers/net/wireless/b43/radio_2059.c new file mode 100644 index 000000000000..55d7da74f15a --- /dev/null +++ b/drivers/net/wireless/b43/radio_2059.c | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | |||
3 | Broadcom B43 wireless driver | ||
4 | IEEE 802.11n 2059 radio device data tables | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; see the file COPYING. If not, write to | ||
18 | the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, | ||
19 | Boston, MA 02110-1301, USA. | ||
20 | |||
21 | */ | ||
22 | |||
23 | #include "b43.h" | ||
24 | #include "radio_2059.h" | ||
25 | |||
26 | const struct b43_phy_ht_channeltab_e_radio2059 | ||
27 | *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq) | ||
28 | { | ||
29 | return NULL; | ||
30 | } | ||
diff --git a/drivers/net/wireless/b43/radio_2059.h b/drivers/net/wireless/b43/radio_2059.h new file mode 100644 index 000000000000..c2874b145266 --- /dev/null +++ b/drivers/net/wireless/b43/radio_2059.h | |||
@@ -0,0 +1,49 @@ | |||
1 | #ifndef B43_RADIO_2059_H_ | ||
2 | #define B43_RADIO_2059_H_ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | #include "phy_ht.h" | ||
7 | |||
8 | /* Values for various registers uploaded on channel switching */ | ||
9 | struct b43_phy_ht_channeltab_e_radio2059 { | ||
10 | /* The channel frequency in MHz */ | ||
11 | u16 freq; | ||
12 | /* Values for radio registers */ | ||
13 | u8 radio_syn16; | ||
14 | u8 radio_syn17; | ||
15 | u8 radio_syn22; | ||
16 | u8 radio_syn25; | ||
17 | u8 radio_syn27; | ||
18 | u8 radio_syn28; | ||
19 | u8 radio_syn29; | ||
20 | u8 radio_syn2c; | ||
21 | u8 radio_syn2d; | ||
22 | u8 radio_syn37; | ||
23 | u8 radio_syn41; | ||
24 | u8 radio_syn43; | ||
25 | u8 radio_syn47; | ||
26 | u8 radio_syn4a; | ||
27 | u8 radio_syn58; | ||
28 | u8 radio_syn5a; | ||
29 | u8 radio_syn6a; | ||
30 | u8 radio_syn6d; | ||
31 | u8 radio_syn6e; | ||
32 | u8 radio_syn92; | ||
33 | u8 radio_syn98; | ||
34 | u8 radio_rxtx4a; | ||
35 | u8 radio_rxtx58; | ||
36 | u8 radio_rxtx5a; | ||
37 | u8 radio_rxtx6a; | ||
38 | u8 radio_rxtx6d; | ||
39 | u8 radio_rxtx6e; | ||
40 | u8 radio_rxtx92; | ||
41 | u8 radio_rxtx98; | ||
42 | /* Values for PHY registers */ | ||
43 | struct b43_phy_ht_channeltab_e_phy phy_regs; | ||
44 | }; | ||
45 | |||
46 | const struct b43_phy_ht_channeltab_e_radio2059 | ||
47 | *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq); | ||
48 | |||
49 | #endif /* B43_RADIO_2059_H_ */ | ||
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index e6c733d37c94..4fd6775b8c33 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c | |||
@@ -93,8 +93,8 @@ void b43_sdio_free_irq(struct b43_wldev *dev) | |||
93 | sdio->irq_handler = NULL; | 93 | sdio->irq_handler = NULL; |
94 | } | 94 | } |
95 | 95 | ||
96 | static int b43_sdio_probe(struct sdio_func *func, | 96 | static int __devinit b43_sdio_probe(struct sdio_func *func, |
97 | const struct sdio_device_id *id) | 97 | const struct sdio_device_id *id) |
98 | { | 98 | { |
99 | struct b43_sdio *sdio; | 99 | struct b43_sdio *sdio; |
100 | struct sdio_func_tuple *tuple; | 100 | struct sdio_func_tuple *tuple; |
@@ -171,7 +171,7 @@ out: | |||
171 | return error; | 171 | return error; |
172 | } | 172 | } |
173 | 173 | ||
174 | static void b43_sdio_remove(struct sdio_func *func) | 174 | static void __devexit b43_sdio_remove(struct sdio_func *func) |
175 | { | 175 | { |
176 | struct b43_sdio *sdio = sdio_get_drvdata(func); | 176 | struct b43_sdio *sdio = sdio_get_drvdata(func); |
177 | 177 | ||
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 18569367ce43..a81696bff0ed 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h | |||
@@ -60,16 +60,8 @@ struct nphy_gain_ctl_workaround_entry { | |||
60 | struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( | 60 | struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( |
61 | struct b43_wldev *dev, bool ghz5, bool ext_lna); | 61 | struct b43_wldev *dev, bool ghz5, bool ext_lna); |
62 | 62 | ||
63 | /* Get the NPHY Channel Switch Table entry for a channel. | ||
64 | * Returns NULL on failure to find an entry. */ | ||
65 | const struct b43_nphy_channeltab_entry_rev2 * | ||
66 | b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); | ||
67 | const struct b43_nphy_channeltab_entry_rev3 * | ||
68 | b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); | ||
69 | |||
70 | 63 | ||
71 | /* The N-PHY tables. */ | 64 | /* The N-PHY tables. */ |
72 | |||
73 | #define B43_NTAB_TYPEMASK 0xF0000000 | 65 | #define B43_NTAB_TYPEMASK 0xF0000000 |
74 | #define B43_NTAB_8BIT 0x10000000 | 66 | #define B43_NTAB_8BIT 0x10000000 |
75 | #define B43_NTAB_16BIT 0x20000000 | 67 | #define B43_NTAB_16BIT 0x20000000 |
diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c index d096dc28204d..dab67a12d73b 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945.c | |||
@@ -408,7 +408,6 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | |||
408 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS | 408 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS |
409 | iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); | 409 | iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); |
410 | #endif | 410 | #endif |
411 | iwl_legacy_recover_from_statistics(priv, pkt); | ||
412 | 411 | ||
413 | memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); | 412 | memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); |
414 | } | 413 | } |
@@ -2640,7 +2639,6 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
2640 | .txq_free_tfd = iwl3945_hw_txq_free_tfd, | 2639 | .txq_free_tfd = iwl3945_hw_txq_free_tfd, |
2641 | .txq_init = iwl3945_hw_tx_queue_init, | 2640 | .txq_init = iwl3945_hw_tx_queue_init, |
2642 | .load_ucode = iwl3945_load_bsm, | 2641 | .load_ucode = iwl3945_load_bsm, |
2643 | .dump_nic_event_log = iwl3945_dump_nic_event_log, | ||
2644 | .dump_nic_error_log = iwl3945_dump_nic_error_log, | 2642 | .dump_nic_error_log = iwl3945_dump_nic_error_log, |
2645 | .apm_ops = { | 2643 | .apm_ops = { |
2646 | .init = iwl3945_apm_init, | 2644 | .init = iwl3945_apm_init, |
@@ -2698,9 +2696,7 @@ static struct iwl_base_params iwl3945_base_params = { | |||
2698 | .set_l0s = false, | 2696 | .set_l0s = false, |
2699 | .use_bsm = true, | 2697 | .use_bsm = true, |
2700 | .led_compensation = 64, | 2698 | .led_compensation = 64, |
2701 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | ||
2702 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 2699 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
2703 | .max_event_log_size = 512, | ||
2704 | }; | 2700 | }; |
2705 | 2701 | ||
2706 | static struct iwl_cfg iwl3945_bg_cfg = { | 2702 | static struct iwl_cfg iwl3945_bg_cfg = { |
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index a7a4739880dc..2be6d9e3b019 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c | |||
@@ -694,47 +694,6 @@ void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, | |||
694 | sizeof(struct iwl_rx_phy_res)); | 694 | sizeof(struct iwl_rx_phy_res)); |
695 | } | 695 | } |
696 | 696 | ||
697 | static int iwl4965_get_single_channel_for_scan(struct iwl_priv *priv, | ||
698 | struct ieee80211_vif *vif, | ||
699 | enum ieee80211_band band, | ||
700 | struct iwl_scan_channel *scan_ch) | ||
701 | { | ||
702 | const struct ieee80211_supported_band *sband; | ||
703 | u16 passive_dwell = 0; | ||
704 | u16 active_dwell = 0; | ||
705 | int added = 0; | ||
706 | u16 channel = 0; | ||
707 | |||
708 | sband = iwl_get_hw_mode(priv, band); | ||
709 | if (!sband) { | ||
710 | IWL_ERR(priv, "invalid band\n"); | ||
711 | return added; | ||
712 | } | ||
713 | |||
714 | active_dwell = iwl_legacy_get_active_dwell_time(priv, band, 0); | ||
715 | passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); | ||
716 | |||
717 | if (passive_dwell <= active_dwell) | ||
718 | passive_dwell = active_dwell + 1; | ||
719 | |||
720 | channel = iwl_legacy_get_single_channel_number(priv, band); | ||
721 | if (channel) { | ||
722 | scan_ch->channel = cpu_to_le16(channel); | ||
723 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; | ||
724 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | ||
725 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | ||
726 | /* Set txpower levels to defaults */ | ||
727 | scan_ch->dsp_atten = 110; | ||
728 | if (band == IEEE80211_BAND_5GHZ) | ||
729 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; | ||
730 | else | ||
731 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); | ||
732 | added++; | ||
733 | } else | ||
734 | IWL_ERR(priv, "no valid channel found\n"); | ||
735 | return added; | ||
736 | } | ||
737 | |||
738 | static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, | 697 | static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, |
739 | struct ieee80211_vif *vif, | 698 | struct ieee80211_vif *vif, |
740 | enum ieee80211_band band, | 699 | enum ieee80211_band band, |
@@ -858,16 +817,13 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
858 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; | 817 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; |
859 | 818 | ||
860 | if (iwl_legacy_is_any_associated(priv)) { | 819 | if (iwl_legacy_is_any_associated(priv)) { |
861 | u16 interval = 0; | 820 | u16 interval; |
862 | u32 extra; | 821 | u32 extra; |
863 | u32 suspend_time = 100; | 822 | u32 suspend_time = 100; |
864 | u32 scan_suspend_time = 100; | 823 | u32 scan_suspend_time = 100; |
865 | 824 | ||
866 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); | 825 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); |
867 | if (priv->is_internal_short_scan) | 826 | interval = vif->bss_conf.beacon_int; |
868 | interval = 0; | ||
869 | else | ||
870 | interval = vif->bss_conf.beacon_int; | ||
871 | 827 | ||
872 | scan->suspend_time = 0; | 828 | scan->suspend_time = 0; |
873 | scan->max_out_time = cpu_to_le32(200 * 1024); | 829 | scan->max_out_time = cpu_to_le32(200 * 1024); |
@@ -882,9 +838,7 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
882 | scan_suspend_time, interval); | 838 | scan_suspend_time, interval); |
883 | } | 839 | } |
884 | 840 | ||
885 | if (priv->is_internal_short_scan) { | 841 | if (priv->scan_request->n_ssids) { |
886 | IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); | ||
887 | } else if (priv->scan_request->n_ssids) { | ||
888 | int i, p = 0; | 842 | int i, p = 0; |
889 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); | 843 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); |
890 | for (i = 0; i < priv->scan_request->n_ssids; i++) { | 844 | for (i = 0; i < priv->scan_request->n_ssids; i++) { |
@@ -981,38 +935,21 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
981 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; | 935 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; |
982 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; | 936 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; |
983 | scan->rx_chain = cpu_to_le16(rx_chain); | 937 | scan->rx_chain = cpu_to_le16(rx_chain); |
984 | if (!priv->is_internal_short_scan) { | 938 | |
985 | cmd_len = iwl_legacy_fill_probe_req(priv, | 939 | cmd_len = iwl_legacy_fill_probe_req(priv, |
986 | (struct ieee80211_mgmt *)scan->data, | 940 | (struct ieee80211_mgmt *)scan->data, |
987 | vif->addr, | 941 | vif->addr, |
988 | priv->scan_request->ie, | 942 | priv->scan_request->ie, |
989 | priv->scan_request->ie_len, | 943 | priv->scan_request->ie_len, |
990 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | 944 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); |
991 | } else { | ||
992 | /* use bcast addr, will not be transmitted but must be valid */ | ||
993 | cmd_len = iwl_legacy_fill_probe_req(priv, | ||
994 | (struct ieee80211_mgmt *)scan->data, | ||
995 | iwlegacy_bcast_addr, NULL, 0, | ||
996 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | ||
997 | |||
998 | } | ||
999 | scan->tx_cmd.len = cpu_to_le16(cmd_len); | 945 | scan->tx_cmd.len = cpu_to_le16(cmd_len); |
1000 | 946 | ||
1001 | scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | | 947 | scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | |
1002 | RXON_FILTER_BCON_AWARE_MSK); | 948 | RXON_FILTER_BCON_AWARE_MSK); |
1003 | 949 | ||
1004 | if (priv->is_internal_short_scan) { | 950 | scan->channel_count = iwl4965_get_channels_for_scan(priv, vif, band, |
1005 | scan->channel_count = | 951 | is_active, n_probes, |
1006 | iwl4965_get_single_channel_for_scan(priv, vif, band, | 952 | (void *)&scan->data[cmd_len]); |
1007 | (void *)&scan->data[le16_to_cpu( | ||
1008 | scan->tx_cmd.len)]); | ||
1009 | } else { | ||
1010 | scan->channel_count = | ||
1011 | iwl4965_get_channels_for_scan(priv, vif, band, | ||
1012 | is_active, n_probes, | ||
1013 | (void *)&scan->data[le16_to_cpu( | ||
1014 | scan->tx_cmd.len)]); | ||
1015 | } | ||
1016 | if (scan->channel_count == 0) { | 953 | if (scan->channel_count == 0) { |
1017 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); | 954 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); |
1018 | return -EIO; | 955 | return -EIO; |
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rx.c b/drivers/net/wireless/iwlegacy/iwl-4965-rx.c index b9fa2f6411a7..2b144bbfc3c5 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rx.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rx.c | |||
@@ -151,81 +151,6 @@ static void iwl4965_accumulative_statistics(struct iwl_priv *priv, | |||
151 | 151 | ||
152 | #define REG_RECALIB_PERIOD (60) | 152 | #define REG_RECALIB_PERIOD (60) |
153 | 153 | ||
154 | /** | ||
155 | * iwl4965_good_plcp_health - checks for plcp error. | ||
156 | * | ||
157 | * When the plcp error is exceeding the thresholds, reset the radio | ||
158 | * to improve the throughput. | ||
159 | */ | ||
160 | bool iwl4965_good_plcp_health(struct iwl_priv *priv, | ||
161 | struct iwl_rx_packet *pkt) | ||
162 | { | ||
163 | bool rc = true; | ||
164 | int combined_plcp_delta; | ||
165 | unsigned int plcp_msec; | ||
166 | unsigned long plcp_received_jiffies; | ||
167 | |||
168 | if (priv->cfg->base_params->plcp_delta_threshold == | ||
169 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | ||
170 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | ||
171 | return rc; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * check for plcp_err and trigger radio reset if it exceeds | ||
176 | * the plcp error threshold plcp_delta. | ||
177 | */ | ||
178 | plcp_received_jiffies = jiffies; | ||
179 | plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - | ||
180 | (long) priv->plcp_jiffies); | ||
181 | priv->plcp_jiffies = plcp_received_jiffies; | ||
182 | /* | ||
183 | * check to make sure plcp_msec is not 0 to prevent division | ||
184 | * by zero. | ||
185 | */ | ||
186 | if (plcp_msec) { | ||
187 | struct statistics_rx_phy *ofdm; | ||
188 | struct statistics_rx_ht_phy *ofdm_ht; | ||
189 | |||
190 | ofdm = &pkt->u.stats.rx.ofdm; | ||
191 | ofdm_ht = &pkt->u.stats.rx.ofdm_ht; | ||
192 | combined_plcp_delta = | ||
193 | (le32_to_cpu(ofdm->plcp_err) - | ||
194 | le32_to_cpu(priv->_4965.statistics. | ||
195 | rx.ofdm.plcp_err)) + | ||
196 | (le32_to_cpu(ofdm_ht->plcp_err) - | ||
197 | le32_to_cpu(priv->_4965.statistics. | ||
198 | rx.ofdm_ht.plcp_err)); | ||
199 | |||
200 | if ((combined_plcp_delta > 0) && | ||
201 | ((combined_plcp_delta * 100) / plcp_msec) > | ||
202 | priv->cfg->base_params->plcp_delta_threshold) { | ||
203 | /* | ||
204 | * if plcp_err exceed the threshold, | ||
205 | * the following data is printed in csv format: | ||
206 | * Text: plcp_err exceeded %d, | ||
207 | * Received ofdm.plcp_err, | ||
208 | * Current ofdm.plcp_err, | ||
209 | * Received ofdm_ht.plcp_err, | ||
210 | * Current ofdm_ht.plcp_err, | ||
211 | * combined_plcp_delta, | ||
212 | * plcp_msec | ||
213 | */ | ||
214 | IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " | ||
215 | "%u, %u, %u, %u, %d, %u mSecs\n", | ||
216 | priv->cfg->base_params->plcp_delta_threshold, | ||
217 | le32_to_cpu(ofdm->plcp_err), | ||
218 | le32_to_cpu(ofdm->plcp_err), | ||
219 | le32_to_cpu(ofdm_ht->plcp_err), | ||
220 | le32_to_cpu(ofdm_ht->plcp_err), | ||
221 | combined_plcp_delta, plcp_msec); | ||
222 | |||
223 | rc = false; | ||
224 | } | ||
225 | } | ||
226 | return rc; | ||
227 | } | ||
228 | |||
229 | void iwl4965_rx_statistics(struct iwl_priv *priv, | 154 | void iwl4965_rx_statistics(struct iwl_priv *priv, |
230 | struct iwl_rx_mem_buffer *rxb) | 155 | struct iwl_rx_mem_buffer *rxb) |
231 | { | 156 | { |
@@ -248,8 +173,7 @@ void iwl4965_rx_statistics(struct iwl_priv *priv, | |||
248 | iwl4965_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); | 173 | iwl4965_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); |
249 | #endif | 174 | #endif |
250 | 175 | ||
251 | iwl_legacy_recover_from_statistics(priv, pkt); | 176 | /* TODO: reading some of statistics is unneeded */ |
252 | |||
253 | memcpy(&priv->_4965.statistics, &pkt->u.stats, | 177 | memcpy(&priv->_4965.statistics, &pkt->u.stats, |
254 | sizeof(priv->_4965.statistics)); | 178 | sizeof(priv->_4965.statistics)); |
255 | 179 | ||
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index 9cf96cb51712..bd4b000733f7 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c | |||
@@ -2069,7 +2069,6 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
2069 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, | 2069 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, |
2070 | .init_alive_start = iwl4965_init_alive_start, | 2070 | .init_alive_start = iwl4965_init_alive_start, |
2071 | .load_ucode = iwl4965_load_bsm, | 2071 | .load_ucode = iwl4965_load_bsm, |
2072 | .dump_nic_event_log = iwl4965_dump_nic_event_log, | ||
2073 | .dump_nic_error_log = iwl4965_dump_nic_error_log, | 2072 | .dump_nic_error_log = iwl4965_dump_nic_error_log, |
2074 | .dump_fh = iwl4965_dump_fh, | 2073 | .dump_fh = iwl4965_dump_fh, |
2075 | .set_channel_switch = iwl4965_hw_channel_switch, | 2074 | .set_channel_switch = iwl4965_hw_channel_switch, |
@@ -2100,7 +2099,6 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
2100 | .tx_stats_read = iwl4965_ucode_tx_stats_read, | 2099 | .tx_stats_read = iwl4965_ucode_tx_stats_read, |
2101 | .general_stats_read = iwl4965_ucode_general_stats_read, | 2100 | .general_stats_read = iwl4965_ucode_general_stats_read, |
2102 | }, | 2101 | }, |
2103 | .check_plcp_health = iwl4965_good_plcp_health, | ||
2104 | }; | 2102 | }; |
2105 | 2103 | ||
2106 | static const struct iwl_legacy_ops iwl4965_legacy_ops = { | 2104 | static const struct iwl_legacy_ops iwl4965_legacy_ops = { |
@@ -2150,10 +2148,8 @@ static struct iwl_base_params iwl4965_base_params = { | |||
2150 | .use_bsm = true, | 2148 | .use_bsm = true, |
2151 | .led_compensation = 61, | 2149 | .led_compensation = 61, |
2152 | .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, | 2150 | .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, |
2153 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | ||
2154 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 2151 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
2155 | .temperature_kelvin = true, | 2152 | .temperature_kelvin = true, |
2156 | .max_event_log_size = 512, | ||
2157 | .ucode_tracing = true, | 2153 | .ucode_tracing = true, |
2158 | .sensitivity_calib_by_driver = true, | 2154 | .sensitivity_calib_by_driver = true, |
2159 | .chain_noise_calib_by_driver = true, | 2155 | .chain_noise_calib_by_driver = true, |
diff --git a/drivers/net/wireless/iwlegacy/iwl-commands.h b/drivers/net/wireless/iwlegacy/iwl-commands.h index 17a1d504348e..ee21210bea9c 100644 --- a/drivers/net/wireless/iwlegacy/iwl-commands.h +++ b/drivers/net/wireless/iwlegacy/iwl-commands.h | |||
@@ -2297,14 +2297,7 @@ struct iwl_spectrum_notification { | |||
2297 | #define IWL_POWER_VEC_SIZE 5 | 2297 | #define IWL_POWER_VEC_SIZE 5 |
2298 | 2298 | ||
2299 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) | 2299 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) |
2300 | #define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0)) | ||
2301 | #define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1)) | ||
2302 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) | ||
2303 | #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) | 2300 | #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) |
2304 | #define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) | ||
2305 | #define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5)) | ||
2306 | #define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6)) | ||
2307 | #define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7)) | ||
2308 | 2301 | ||
2309 | struct iwl3945_powertable_cmd { | 2302 | struct iwl3945_powertable_cmd { |
2310 | __le16 flags; | 2303 | __le16 flags; |
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index 3be76bd5499a..35cd2537e7fd 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c | |||
@@ -931,7 +931,6 @@ void iwl_legacy_irq_handle_error(struct iwl_priv *priv) | |||
931 | priv->cfg->ops->lib->dump_nic_error_log(priv); | 931 | priv->cfg->ops->lib->dump_nic_error_log(priv); |
932 | if (priv->cfg->ops->lib->dump_fh) | 932 | if (priv->cfg->ops->lib->dump_fh) |
933 | priv->cfg->ops->lib->dump_fh(priv, NULL, false); | 933 | priv->cfg->ops->lib->dump_fh(priv, NULL, false); |
934 | priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); | ||
935 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | 934 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG |
936 | if (iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) | 935 | if (iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) |
937 | iwl_legacy_print_rx_config_cmd(priv, | 936 | iwl_legacy_print_rx_config_cmd(priv, |
@@ -1707,41 +1706,14 @@ iwl_legacy_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | |||
1707 | EXPORT_SYMBOL(iwl_legacy_update_stats); | 1706 | EXPORT_SYMBOL(iwl_legacy_update_stats); |
1708 | #endif | 1707 | #endif |
1709 | 1708 | ||
1710 | static void _iwl_legacy_force_rf_reset(struct iwl_priv *priv) | 1709 | int iwl_legacy_force_reset(struct iwl_priv *priv, bool external) |
1711 | { | ||
1712 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
1713 | return; | ||
1714 | |||
1715 | if (!iwl_legacy_is_any_associated(priv)) { | ||
1716 | IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); | ||
1717 | return; | ||
1718 | } | ||
1719 | /* | ||
1720 | * There is no easy and better way to force reset the radio, | ||
1721 | * the only known method is switching channel which will force to | ||
1722 | * reset and tune the radio. | ||
1723 | * Use internal short scan (single channel) operation to should | ||
1724 | * achieve this objective. | ||
1725 | * Driver should reset the radio when number of consecutive missed | ||
1726 | * beacon, or any other uCode error condition detected. | ||
1727 | */ | ||
1728 | IWL_DEBUG_INFO(priv, "perform radio reset.\n"); | ||
1729 | iwl_legacy_internal_short_hw_scan(priv); | ||
1730 | } | ||
1731 | |||
1732 | |||
1733 | int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external) | ||
1734 | { | 1710 | { |
1735 | struct iwl_force_reset *force_reset; | 1711 | struct iwl_force_reset *force_reset; |
1736 | 1712 | ||
1737 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 1713 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1738 | return -EINVAL; | 1714 | return -EINVAL; |
1739 | 1715 | ||
1740 | if (mode >= IWL_MAX_FORCE_RESET) { | 1716 | force_reset = &priv->force_reset; |
1741 | IWL_DEBUG_INFO(priv, "invalid reset request.\n"); | ||
1742 | return -EINVAL; | ||
1743 | } | ||
1744 | force_reset = &priv->force_reset[mode]; | ||
1745 | force_reset->reset_request_count++; | 1717 | force_reset->reset_request_count++; |
1746 | if (!external) { | 1718 | if (!external) { |
1747 | if (force_reset->last_force_reset_jiffies && | 1719 | if (force_reset->last_force_reset_jiffies && |
@@ -1754,37 +1726,34 @@ int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
1754 | } | 1726 | } |
1755 | force_reset->reset_success_count++; | 1727 | force_reset->reset_success_count++; |
1756 | force_reset->last_force_reset_jiffies = jiffies; | 1728 | force_reset->last_force_reset_jiffies = jiffies; |
1757 | IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode); | 1729 | |
1758 | switch (mode) { | 1730 | /* |
1759 | case IWL_RF_RESET: | 1731 | * if the request is from external(ex: debugfs), |
1760 | _iwl_legacy_force_rf_reset(priv); | 1732 | * then always perform the request in regardless the module |
1761 | break; | 1733 | * parameter setting |
1762 | case IWL_FW_RESET: | 1734 | * if the request is from internal (uCode error or driver |
1763 | /* | 1735 | * detect failure), then fw_restart module parameter |
1764 | * if the request is from external(ex: debugfs), | 1736 | * need to be check before performing firmware reload |
1765 | * then always perform the request in regardless the module | 1737 | */ |
1766 | * parameter setting | 1738 | |
1767 | * if the request is from internal (uCode error or driver | 1739 | if (!external && !priv->cfg->mod_params->restart_fw) { |
1768 | * detect failure), then fw_restart module parameter | 1740 | IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " |
1769 | * need to be check before performing firmware reload | 1741 | "module parameter setting\n"); |
1770 | */ | 1742 | return 0; |
1771 | if (!external && !priv->cfg->mod_params->restart_fw) { | ||
1772 | IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " | ||
1773 | "module parameter setting\n"); | ||
1774 | break; | ||
1775 | } | ||
1776 | IWL_ERR(priv, "On demand firmware reload\n"); | ||
1777 | /* Set the FW error flag -- cleared on iwl_down */ | ||
1778 | set_bit(STATUS_FW_ERROR, &priv->status); | ||
1779 | wake_up_interruptible(&priv->wait_command_queue); | ||
1780 | /* | ||
1781 | * Keep the restart process from trying to send host | ||
1782 | * commands by clearing the INIT status bit | ||
1783 | */ | ||
1784 | clear_bit(STATUS_READY, &priv->status); | ||
1785 | queue_work(priv->workqueue, &priv->restart); | ||
1786 | break; | ||
1787 | } | 1743 | } |
1744 | |||
1745 | IWL_ERR(priv, "On demand firmware reload\n"); | ||
1746 | |||
1747 | /* Set the FW error flag -- cleared on iwl_down */ | ||
1748 | set_bit(STATUS_FW_ERROR, &priv->status); | ||
1749 | wake_up_interruptible(&priv->wait_command_queue); | ||
1750 | /* | ||
1751 | * Keep the restart process from trying to send host | ||
1752 | * commands by clearing the INIT status bit | ||
1753 | */ | ||
1754 | clear_bit(STATUS_READY, &priv->status); | ||
1755 | queue_work(priv->workqueue, &priv->restart); | ||
1756 | |||
1788 | return 0; | 1757 | return 0; |
1789 | } | 1758 | } |
1790 | 1759 | ||
@@ -1879,7 +1848,7 @@ static int iwl_legacy_check_stuck_queue(struct iwl_priv *priv, int cnt) | |||
1879 | if (time_after(jiffies, timeout)) { | 1848 | if (time_after(jiffies, timeout)) { |
1880 | IWL_ERR(priv, "Queue %d stuck for %u ms.\n", | 1849 | IWL_ERR(priv, "Queue %d stuck for %u ms.\n", |
1881 | q->id, priv->cfg->base_params->wd_timeout); | 1850 | q->id, priv->cfg->base_params->wd_timeout); |
1882 | ret = iwl_legacy_force_reset(priv, IWL_FW_RESET, false); | 1851 | ret = iwl_legacy_force_reset(priv, false); |
1883 | return (ret == -EAGAIN) ? 0 : 1; | 1852 | return (ret == -EAGAIN) ? 0 : 1; |
1884 | } | 1853 | } |
1885 | 1854 | ||
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index c5fbda0760de..a2de7e991706 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h | |||
@@ -143,8 +143,7 @@ struct iwl_lib_ops { | |||
143 | int (*is_valid_rtc_data_addr)(u32 addr); | 143 | int (*is_valid_rtc_data_addr)(u32 addr); |
144 | /* 1st ucode load */ | 144 | /* 1st ucode load */ |
145 | int (*load_ucode)(struct iwl_priv *priv); | 145 | int (*load_ucode)(struct iwl_priv *priv); |
146 | int (*dump_nic_event_log)(struct iwl_priv *priv, | 146 | |
147 | bool full_log, char **buf, bool display); | ||
148 | void (*dump_nic_error_log)(struct iwl_priv *priv); | 147 | void (*dump_nic_error_log)(struct iwl_priv *priv); |
149 | int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); | 148 | int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); |
150 | int (*set_channel_switch)(struct iwl_priv *priv, | 149 | int (*set_channel_switch)(struct iwl_priv *priv, |
@@ -161,9 +160,6 @@ struct iwl_lib_ops { | |||
161 | 160 | ||
162 | /* temperature */ | 161 | /* temperature */ |
163 | struct iwl_temp_ops temp_ops; | 162 | struct iwl_temp_ops temp_ops; |
164 | /* check for plcp health */ | ||
165 | bool (*check_plcp_health)(struct iwl_priv *priv, | ||
166 | struct iwl_rx_packet *pkt); | ||
167 | 163 | ||
168 | struct iwl_debugfs_ops debugfs_ops; | 164 | struct iwl_debugfs_ops debugfs_ops; |
169 | 165 | ||
@@ -207,11 +203,8 @@ struct iwl_mod_params { | |||
207 | * to the deviation to achieve the desired led frequency. | 203 | * to the deviation to achieve the desired led frequency. |
208 | * The detail algorithm is described in iwl-led.c | 204 | * The detail algorithm is described in iwl-led.c |
209 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | 205 | * @chain_noise_num_beacons: number of beacons used to compute chain noise |
210 | * @plcp_delta_threshold: plcp error rate threshold used to trigger | ||
211 | * radio tuning when there is a high receiving plcp error rate | ||
212 | * @wd_timeout: TX queues watchdog timeout | 206 | * @wd_timeout: TX queues watchdog timeout |
213 | * @temperature_kelvin: temperature report by uCode in kelvin | 207 | * @temperature_kelvin: temperature report by uCode in kelvin |
214 | * @max_event_log_size: size of event log buffer size for ucode event logging | ||
215 | * @ucode_tracing: support ucode continuous tracing | 208 | * @ucode_tracing: support ucode continuous tracing |
216 | * @sensitivity_calib_by_driver: driver has the capability to perform | 209 | * @sensitivity_calib_by_driver: driver has the capability to perform |
217 | * sensitivity calibration operation | 210 | * sensitivity calibration operation |
@@ -229,10 +222,8 @@ struct iwl_base_params { | |||
229 | 222 | ||
230 | u16 led_compensation; | 223 | u16 led_compensation; |
231 | int chain_noise_num_beacons; | 224 | int chain_noise_num_beacons; |
232 | u8 plcp_delta_threshold; | ||
233 | unsigned int wd_timeout; | 225 | unsigned int wd_timeout; |
234 | bool temperature_kelvin; | 226 | bool temperature_kelvin; |
235 | u32 max_event_log_size; | ||
236 | const bool ucode_tracing; | 227 | const bool ucode_tracing; |
237 | const bool sensitivity_calib_by_driver; | 228 | const bool sensitivity_calib_by_driver; |
238 | const bool chain_noise_calib_by_driver; | 229 | const bool chain_noise_calib_by_driver; |
@@ -441,7 +432,7 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, | |||
441 | struct ieee80211_vif *vif, | 432 | struct ieee80211_vif *vif, |
442 | struct cfg80211_scan_request *req); | 433 | struct cfg80211_scan_request *req); |
443 | void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv); | 434 | void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv); |
444 | int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external); | 435 | int iwl_legacy_force_reset(struct iwl_priv *priv, bool external); |
445 | u16 iwl_legacy_fill_probe_req(struct iwl_priv *priv, | 436 | u16 iwl_legacy_fill_probe_req(struct iwl_priv *priv, |
446 | struct ieee80211_mgmt *frame, | 437 | struct ieee80211_mgmt *frame, |
447 | const u8 *ta, const u8 *ie, int ie_len, int left); | 438 | const u8 *ta, const u8 *ie, int ie_len, int left); |
@@ -521,8 +512,6 @@ extern const struct dev_pm_ops iwl_legacy_pm_ops; | |||
521 | * Error Handling Debugging | 512 | * Error Handling Debugging |
522 | ******************************************************/ | 513 | ******************************************************/ |
523 | void iwl4965_dump_nic_error_log(struct iwl_priv *priv); | 514 | void iwl4965_dump_nic_error_log(struct iwl_priv *priv); |
524 | int iwl4965_dump_nic_event_log(struct iwl_priv *priv, | ||
525 | bool full_log, char **buf, bool display); | ||
526 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | 515 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG |
527 | void iwl_legacy_print_rx_config_cmd(struct iwl_priv *priv, | 516 | void iwl_legacy_print_rx_config_cmd(struct iwl_priv *priv, |
528 | struct iwl_rxon_context *ctx); | 517 | struct iwl_rxon_context *ctx); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-debugfs.c b/drivers/net/wireless/iwlegacy/iwl-debugfs.c index 2d32438b4cb8..996996a71657 100644 --- a/drivers/net/wireless/iwlegacy/iwl-debugfs.c +++ b/drivers/net/wireless/iwlegacy/iwl-debugfs.c | |||
@@ -391,48 +391,6 @@ static ssize_t iwl_legacy_dbgfs_nvm_read(struct file *file, | |||
391 | return ret; | 391 | return ret; |
392 | } | 392 | } |
393 | 393 | ||
394 | static ssize_t iwl_legacy_dbgfs_log_event_read(struct file *file, | ||
395 | char __user *user_buf, | ||
396 | size_t count, loff_t *ppos) | ||
397 | { | ||
398 | struct iwl_priv *priv = file->private_data; | ||
399 | char *buf; | ||
400 | int pos = 0; | ||
401 | ssize_t ret = -ENOMEM; | ||
402 | |||
403 | ret = pos = priv->cfg->ops->lib->dump_nic_event_log( | ||
404 | priv, true, &buf, true); | ||
405 | if (buf) { | ||
406 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
407 | kfree(buf); | ||
408 | } | ||
409 | return ret; | ||
410 | } | ||
411 | |||
412 | static ssize_t iwl_legacy_dbgfs_log_event_write(struct file *file, | ||
413 | const char __user *user_buf, | ||
414 | size_t count, loff_t *ppos) | ||
415 | { | ||
416 | struct iwl_priv *priv = file->private_data; | ||
417 | u32 event_log_flag; | ||
418 | char buf[8]; | ||
419 | int buf_size; | ||
420 | |||
421 | memset(buf, 0, sizeof(buf)); | ||
422 | buf_size = min(count, sizeof(buf) - 1); | ||
423 | if (copy_from_user(buf, user_buf, buf_size)) | ||
424 | return -EFAULT; | ||
425 | if (sscanf(buf, "%d", &event_log_flag) != 1) | ||
426 | return -EFAULT; | ||
427 | if (event_log_flag == 1) | ||
428 | priv->cfg->ops->lib->dump_nic_event_log(priv, true, | ||
429 | NULL, false); | ||
430 | |||
431 | return count; | ||
432 | } | ||
433 | |||
434 | |||
435 | |||
436 | static ssize_t | 394 | static ssize_t |
437 | iwl_legacy_dbgfs_channels_read(struct file *file, char __user *user_buf, | 395 | iwl_legacy_dbgfs_channels_read(struct file *file, char __user *user_buf, |
438 | size_t count, loff_t *ppos) | 396 | size_t count, loff_t *ppos) |
@@ -706,7 +664,6 @@ static ssize_t iwl_legacy_dbgfs_disable_ht40_read(struct file *file, | |||
706 | } | 664 | } |
707 | 665 | ||
708 | DEBUGFS_READ_WRITE_FILE_OPS(sram); | 666 | DEBUGFS_READ_WRITE_FILE_OPS(sram); |
709 | DEBUGFS_READ_WRITE_FILE_OPS(log_event); | ||
710 | DEBUGFS_READ_FILE_OPS(nvm); | 667 | DEBUGFS_READ_FILE_OPS(nvm); |
711 | DEBUGFS_READ_FILE_OPS(stations); | 668 | DEBUGFS_READ_FILE_OPS(stations); |
712 | DEBUGFS_READ_FILE_OPS(channels); | 669 | DEBUGFS_READ_FILE_OPS(channels); |
@@ -1098,56 +1055,6 @@ static ssize_t iwl_legacy_dbgfs_clear_ucode_statistics_write(struct file *file, | |||
1098 | return count; | 1055 | return count; |
1099 | } | 1056 | } |
1100 | 1057 | ||
1101 | static ssize_t iwl_legacy_dbgfs_ucode_tracing_read(struct file *file, | ||
1102 | char __user *user_buf, | ||
1103 | size_t count, loff_t *ppos) { | ||
1104 | |||
1105 | struct iwl_priv *priv = file->private_data; | ||
1106 | int pos = 0; | ||
1107 | char buf[128]; | ||
1108 | const size_t bufsz = sizeof(buf); | ||
1109 | |||
1110 | pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", | ||
1111 | priv->event_log.ucode_trace ? "On" : "Off"); | ||
1112 | pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n", | ||
1113 | priv->event_log.non_wraps_count); | ||
1114 | pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n", | ||
1115 | priv->event_log.wraps_once_count); | ||
1116 | pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", | ||
1117 | priv->event_log.wraps_more_count); | ||
1118 | |||
1119 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1120 | } | ||
1121 | |||
1122 | static ssize_t iwl_legacy_dbgfs_ucode_tracing_write(struct file *file, | ||
1123 | const char __user *user_buf, | ||
1124 | size_t count, loff_t *ppos) | ||
1125 | { | ||
1126 | struct iwl_priv *priv = file->private_data; | ||
1127 | char buf[8]; | ||
1128 | int buf_size; | ||
1129 | int trace; | ||
1130 | |||
1131 | memset(buf, 0, sizeof(buf)); | ||
1132 | buf_size = min(count, sizeof(buf) - 1); | ||
1133 | if (copy_from_user(buf, user_buf, buf_size)) | ||
1134 | return -EFAULT; | ||
1135 | if (sscanf(buf, "%d", &trace) != 1) | ||
1136 | return -EFAULT; | ||
1137 | |||
1138 | if (trace) { | ||
1139 | priv->event_log.ucode_trace = true; | ||
1140 | /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ | ||
1141 | mod_timer(&priv->ucode_trace, | ||
1142 | jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); | ||
1143 | } else { | ||
1144 | priv->event_log.ucode_trace = false; | ||
1145 | del_timer_sync(&priv->ucode_trace); | ||
1146 | } | ||
1147 | |||
1148 | return count; | ||
1149 | } | ||
1150 | |||
1151 | static ssize_t iwl_legacy_dbgfs_rxon_flags_read(struct file *file, | 1058 | static ssize_t iwl_legacy_dbgfs_rxon_flags_read(struct file *file, |
1152 | char __user *user_buf, | 1059 | char __user *user_buf, |
1153 | size_t count, loff_t *ppos) { | 1060 | size_t count, loff_t *ppos) { |
@@ -1236,72 +1143,31 @@ static ssize_t iwl_legacy_dbgfs_missed_beacon_write(struct file *file, | |||
1236 | return count; | 1143 | return count; |
1237 | } | 1144 | } |
1238 | 1145 | ||
1239 | static ssize_t iwl_legacy_dbgfs_plcp_delta_read(struct file *file, | ||
1240 | char __user *user_buf, | ||
1241 | size_t count, loff_t *ppos) { | ||
1242 | |||
1243 | struct iwl_priv *priv = file->private_data; | ||
1244 | int pos = 0; | ||
1245 | char buf[12]; | ||
1246 | const size_t bufsz = sizeof(buf); | ||
1247 | |||
1248 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", | ||
1249 | priv->cfg->base_params->plcp_delta_threshold); | ||
1250 | |||
1251 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1252 | } | ||
1253 | |||
1254 | static ssize_t iwl_legacy_dbgfs_plcp_delta_write(struct file *file, | ||
1255 | const char __user *user_buf, | ||
1256 | size_t count, loff_t *ppos) { | ||
1257 | |||
1258 | struct iwl_priv *priv = file->private_data; | ||
1259 | char buf[8]; | ||
1260 | int buf_size; | ||
1261 | int plcp; | ||
1262 | |||
1263 | memset(buf, 0, sizeof(buf)); | ||
1264 | buf_size = min(count, sizeof(buf) - 1); | ||
1265 | if (copy_from_user(buf, user_buf, buf_size)) | ||
1266 | return -EFAULT; | ||
1267 | if (sscanf(buf, "%d", &plcp) != 1) | ||
1268 | return -EINVAL; | ||
1269 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || | ||
1270 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) | ||
1271 | priv->cfg->base_params->plcp_delta_threshold = | ||
1272 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; | ||
1273 | else | ||
1274 | priv->cfg->base_params->plcp_delta_threshold = plcp; | ||
1275 | return count; | ||
1276 | } | ||
1277 | |||
1278 | static ssize_t iwl_legacy_dbgfs_force_reset_read(struct file *file, | 1146 | static ssize_t iwl_legacy_dbgfs_force_reset_read(struct file *file, |
1279 | char __user *user_buf, | 1147 | char __user *user_buf, |
1280 | size_t count, loff_t *ppos) { | 1148 | size_t count, loff_t *ppos) { |
1281 | 1149 | ||
1282 | struct iwl_priv *priv = file->private_data; | 1150 | struct iwl_priv *priv = file->private_data; |
1283 | int i, pos = 0; | 1151 | int pos = 0; |
1284 | char buf[300]; | 1152 | char buf[300]; |
1285 | const size_t bufsz = sizeof(buf); | 1153 | const size_t bufsz = sizeof(buf); |
1286 | struct iwl_force_reset *force_reset; | 1154 | struct iwl_force_reset *force_reset; |
1287 | 1155 | ||
1288 | for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { | 1156 | force_reset = &priv->force_reset; |
1289 | force_reset = &priv->force_reset[i]; | 1157 | |
1290 | pos += scnprintf(buf + pos, bufsz - pos, | 1158 | pos += scnprintf(buf + pos, bufsz - pos, |
1291 | "Force reset method %d\n", i); | 1159 | "\tnumber of reset request: %d\n", |
1292 | pos += scnprintf(buf + pos, bufsz - pos, | 1160 | force_reset->reset_request_count); |
1293 | "\tnumber of reset request: %d\n", | 1161 | pos += scnprintf(buf + pos, bufsz - pos, |
1294 | force_reset->reset_request_count); | 1162 | "\tnumber of reset request success: %d\n", |
1295 | pos += scnprintf(buf + pos, bufsz - pos, | 1163 | force_reset->reset_success_count); |
1296 | "\tnumber of reset request success: %d\n", | 1164 | pos += scnprintf(buf + pos, bufsz - pos, |
1297 | force_reset->reset_success_count); | 1165 | "\tnumber of reset request reject: %d\n", |
1298 | pos += scnprintf(buf + pos, bufsz - pos, | 1166 | force_reset->reset_reject_count); |
1299 | "\tnumber of reset request reject: %d\n", | 1167 | pos += scnprintf(buf + pos, bufsz - pos, |
1300 | force_reset->reset_reject_count); | 1168 | "\treset duration: %lu\n", |
1301 | pos += scnprintf(buf + pos, bufsz - pos, | 1169 | force_reset->reset_duration); |
1302 | "\treset duration: %lu\n", | 1170 | |
1303 | force_reset->reset_duration); | ||
1304 | } | ||
1305 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1171 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1306 | } | 1172 | } |
1307 | 1173 | ||
@@ -1309,25 +1175,11 @@ static ssize_t iwl_legacy_dbgfs_force_reset_write(struct file *file, | |||
1309 | const char __user *user_buf, | 1175 | const char __user *user_buf, |
1310 | size_t count, loff_t *ppos) { | 1176 | size_t count, loff_t *ppos) { |
1311 | 1177 | ||
1178 | int ret; | ||
1312 | struct iwl_priv *priv = file->private_data; | 1179 | struct iwl_priv *priv = file->private_data; |
1313 | char buf[8]; | ||
1314 | int buf_size; | ||
1315 | int reset, ret; | ||
1316 | 1180 | ||
1317 | memset(buf, 0, sizeof(buf)); | 1181 | ret = iwl_legacy_force_reset(priv, true); |
1318 | buf_size = min(count, sizeof(buf) - 1); | 1182 | |
1319 | if (copy_from_user(buf, user_buf, buf_size)) | ||
1320 | return -EFAULT; | ||
1321 | if (sscanf(buf, "%d", &reset) != 1) | ||
1322 | return -EINVAL; | ||
1323 | switch (reset) { | ||
1324 | case IWL_RF_RESET: | ||
1325 | case IWL_FW_RESET: | ||
1326 | ret = iwl_legacy_force_reset(priv, reset, true); | ||
1327 | break; | ||
1328 | default: | ||
1329 | return -EINVAL; | ||
1330 | } | ||
1331 | return ret ? ret : count; | 1183 | return ret ? ret : count; |
1332 | } | 1184 | } |
1333 | 1185 | ||
@@ -1367,10 +1219,8 @@ DEBUGFS_READ_FILE_OPS(chain_noise); | |||
1367 | DEBUGFS_READ_FILE_OPS(power_save_status); | 1219 | DEBUGFS_READ_FILE_OPS(power_save_status); |
1368 | DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); | 1220 | DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); |
1369 | DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); | 1221 | DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); |
1370 | DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); | ||
1371 | DEBUGFS_READ_FILE_OPS(fh_reg); | 1222 | DEBUGFS_READ_FILE_OPS(fh_reg); |
1372 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); | 1223 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); |
1373 | DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); | ||
1374 | DEBUGFS_READ_WRITE_FILE_OPS(force_reset); | 1224 | DEBUGFS_READ_WRITE_FILE_OPS(force_reset); |
1375 | DEBUGFS_READ_FILE_OPS(rxon_flags); | 1225 | DEBUGFS_READ_FILE_OPS(rxon_flags); |
1376 | DEBUGFS_READ_FILE_OPS(rxon_filter_flags); | 1226 | DEBUGFS_READ_FILE_OPS(rxon_filter_flags); |
@@ -1403,7 +1253,6 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1403 | 1253 | ||
1404 | DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); | 1254 | DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); |
1405 | DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); | 1255 | DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); |
1406 | DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); | ||
1407 | DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); | 1256 | DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); |
1408 | DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); | 1257 | DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); |
1409 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); | 1258 | DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); |
@@ -1420,7 +1269,6 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1420 | DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); | 1269 | DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); |
1421 | DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); | 1270 | DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); |
1422 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); | 1271 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); |
1423 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); | ||
1424 | DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); | 1272 | DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); |
1425 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); | 1273 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); |
1426 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); | 1274 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); |
@@ -1430,8 +1278,6 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1430 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); | 1278 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); |
1431 | if (priv->cfg->base_params->chain_noise_calib_by_driver) | 1279 | if (priv->cfg->base_params->chain_noise_calib_by_driver) |
1432 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); | 1280 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); |
1433 | if (priv->cfg->base_params->ucode_tracing) | ||
1434 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); | ||
1435 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | 1281 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); |
1436 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | 1282 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); |
1437 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); | 1283 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index 0a8d07fdc0e7..9c786edf56fd 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h | |||
@@ -856,32 +856,6 @@ struct traffic_stats { | |||
856 | }; | 856 | }; |
857 | 857 | ||
858 | /* | 858 | /* |
859 | * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds | ||
860 | * to perform continuous uCode event logging operation if enabled | ||
861 | */ | ||
862 | #define UCODE_TRACE_PERIOD (100) | ||
863 | |||
864 | /* | ||
865 | * iwl_event_log: current uCode event log position | ||
866 | * | ||
867 | * @ucode_trace: enable/disable ucode continuous trace timer | ||
868 | * @num_wraps: how many times the event buffer wraps | ||
869 | * @next_entry: the entry just before the next one that uCode would fill | ||
870 | * @non_wraps_count: counter for no wrap detected when dump ucode events | ||
871 | * @wraps_once_count: counter for wrap once detected when dump ucode events | ||
872 | * @wraps_more_count: counter for wrap more than once detected | ||
873 | * when dump ucode events | ||
874 | */ | ||
875 | struct iwl_event_log { | ||
876 | bool ucode_trace; | ||
877 | u32 num_wraps; | ||
878 | u32 next_entry; | ||
879 | int non_wraps_count; | ||
880 | int wraps_once_count; | ||
881 | int wraps_more_count; | ||
882 | }; | ||
883 | |||
884 | /* | ||
885 | * host interrupt timeout value | 859 | * host interrupt timeout value |
886 | * used with setting interrupt coalescing timer | 860 | * used with setting interrupt coalescing timer |
887 | * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit | 861 | * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit |
@@ -896,18 +870,6 @@ struct iwl_event_log { | |||
896 | #define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) | 870 | #define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) |
897 | #define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) | 871 | #define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) |
898 | 872 | ||
899 | /* | ||
900 | * This is the threshold value of plcp error rate per 100mSecs. It is | ||
901 | * used to set and check for the validity of plcp_delta. | ||
902 | */ | ||
903 | #define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (1) | ||
904 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) | ||
905 | #define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) | ||
906 | #define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200) | ||
907 | #define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) | ||
908 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) | ||
909 | |||
910 | #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) | ||
911 | #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) | 873 | #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) |
912 | 874 | ||
913 | /* TX queue watchdog timeouts in mSecs */ | 875 | /* TX queue watchdog timeouts in mSecs */ |
@@ -915,12 +877,6 @@ struct iwl_event_log { | |||
915 | #define IWL_LONG_WD_TIMEOUT (10000) | 877 | #define IWL_LONG_WD_TIMEOUT (10000) |
916 | #define IWL_MAX_WD_TIMEOUT (120000) | 878 | #define IWL_MAX_WD_TIMEOUT (120000) |
917 | 879 | ||
918 | enum iwl_reset { | ||
919 | IWL_RF_RESET = 0, | ||
920 | IWL_FW_RESET, | ||
921 | IWL_MAX_FORCE_RESET, | ||
922 | }; | ||
923 | |||
924 | struct iwl_force_reset { | 880 | struct iwl_force_reset { |
925 | int reset_request_count; | 881 | int reset_request_count; |
926 | int reset_success_count; | 882 | int reset_success_count; |
@@ -1033,11 +989,8 @@ struct iwl_priv { | |||
1033 | /* track IBSS manager (last beacon) status */ | 989 | /* track IBSS manager (last beacon) status */ |
1034 | u32 ibss_manager; | 990 | u32 ibss_manager; |
1035 | 991 | ||
1036 | /* storing the jiffies when the plcp error rate is received */ | ||
1037 | unsigned long plcp_jiffies; | ||
1038 | |||
1039 | /* force reset */ | 992 | /* force reset */ |
1040 | struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; | 993 | struct iwl_force_reset force_reset; |
1041 | 994 | ||
1042 | /* we allocate array of iwl_channel_info for NIC's valid channels. | 995 | /* we allocate array of iwl_channel_info for NIC's valid channels. |
1043 | * Access via channel # using indirect index array */ | 996 | * Access via channel # using indirect index array */ |
@@ -1058,7 +1011,6 @@ struct iwl_priv { | |||
1058 | enum ieee80211_band scan_band; | 1011 | enum ieee80211_band scan_band; |
1059 | struct cfg80211_scan_request *scan_request; | 1012 | struct cfg80211_scan_request *scan_request; |
1060 | struct ieee80211_vif *scan_vif; | 1013 | struct ieee80211_vif *scan_vif; |
1061 | bool is_internal_short_scan; | ||
1062 | u8 scan_tx_ant[IEEE80211_NUM_BANDS]; | 1014 | u8 scan_tx_ant[IEEE80211_NUM_BANDS]; |
1063 | u8 mgmt_tx_ant; | 1015 | u8 mgmt_tx_ant; |
1064 | 1016 | ||
@@ -1213,12 +1165,6 @@ struct iwl_priv { | |||
1213 | #endif | 1165 | #endif |
1214 | #if defined(CONFIG_IWL4965) || defined(CONFIG_IWL4965_MODULE) | 1166 | #if defined(CONFIG_IWL4965) || defined(CONFIG_IWL4965_MODULE) |
1215 | struct { | 1167 | struct { |
1216 | /* | ||
1217 | * reporting the number of tids has AGG on. 0 means | ||
1218 | * no AGGREGATION | ||
1219 | */ | ||
1220 | u8 agg_tids_count; | ||
1221 | |||
1222 | struct iwl_rx_phy_res last_phy_res; | 1168 | struct iwl_rx_phy_res last_phy_res; |
1223 | bool last_phy_res_valid; | 1169 | bool last_phy_res_valid; |
1224 | 1170 | ||
@@ -1257,7 +1203,6 @@ struct iwl_priv { | |||
1257 | struct iwl_rxon_context *beacon_ctx; | 1203 | struct iwl_rxon_context *beacon_ctx; |
1258 | struct sk_buff *beacon_skb; | 1204 | struct sk_buff *beacon_skb; |
1259 | 1205 | ||
1260 | struct work_struct start_internal_scan; | ||
1261 | struct work_struct tx_flush; | 1206 | struct work_struct tx_flush; |
1262 | 1207 | ||
1263 | struct tasklet_struct irq_tasklet; | 1208 | struct tasklet_struct irq_tasklet; |
@@ -1294,12 +1239,9 @@ struct iwl_priv { | |||
1294 | u32 disable_tx_power_cal; | 1239 | u32 disable_tx_power_cal; |
1295 | struct work_struct run_time_calib_work; | 1240 | struct work_struct run_time_calib_work; |
1296 | struct timer_list statistics_periodic; | 1241 | struct timer_list statistics_periodic; |
1297 | struct timer_list ucode_trace; | ||
1298 | struct timer_list watchdog; | 1242 | struct timer_list watchdog; |
1299 | bool hw_ready; | 1243 | bool hw_ready; |
1300 | 1244 | ||
1301 | struct iwl_event_log event_log; | ||
1302 | |||
1303 | struct led_classdev led; | 1245 | struct led_classdev led; |
1304 | unsigned long blink_on, blink_off; | 1246 | unsigned long blink_on, blink_off; |
1305 | bool led_registered; | 1247 | bool led_registered; |
diff --git a/drivers/net/wireless/iwlegacy/iwl-devtrace.c b/drivers/net/wireless/iwlegacy/iwl-devtrace.c index 080b852b33bd..acec99197ce0 100644 --- a/drivers/net/wireless/iwlegacy/iwl-devtrace.c +++ b/drivers/net/wireless/iwlegacy/iwl-devtrace.c | |||
@@ -38,8 +38,5 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ioread32); | |||
38 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite32); | 38 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite32); |
39 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_rx); | 39 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_rx); |
40 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_tx); | 40 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_tx); |
41 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_event); | ||
42 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_error); | 41 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_error); |
43 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_cont_event); | ||
44 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_wrap_event); | ||
45 | #endif | 42 | #endif |
diff --git a/drivers/net/wireless/iwlegacy/iwl-devtrace.h b/drivers/net/wireless/iwlegacy/iwl-devtrace.h index 9612aa0f6ec4..a443725ba6be 100644 --- a/drivers/net/wireless/iwlegacy/iwl-devtrace.h +++ b/drivers/net/wireless/iwlegacy/iwl-devtrace.h | |||
@@ -96,47 +96,6 @@ TRACE_EVENT(iwlwifi_legacy_dev_iowrite32, | |||
96 | #undef TRACE_SYSTEM | 96 | #undef TRACE_SYSTEM |
97 | #define TRACE_SYSTEM iwlwifi_legacy_ucode | 97 | #define TRACE_SYSTEM iwlwifi_legacy_ucode |
98 | 98 | ||
99 | TRACE_EVENT(iwlwifi_legacy_dev_ucode_cont_event, | ||
100 | TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), | ||
101 | TP_ARGS(priv, time, data, ev), | ||
102 | TP_STRUCT__entry( | ||
103 | PRIV_ENTRY | ||
104 | |||
105 | __field(u32, time) | ||
106 | __field(u32, data) | ||
107 | __field(u32, ev) | ||
108 | ), | ||
109 | TP_fast_assign( | ||
110 | PRIV_ASSIGN; | ||
111 | __entry->time = time; | ||
112 | __entry->data = data; | ||
113 | __entry->ev = ev; | ||
114 | ), | ||
115 | TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", | ||
116 | __entry->priv, __entry->time, __entry->data, __entry->ev) | ||
117 | ); | ||
118 | |||
119 | TRACE_EVENT(iwlwifi_legacy_dev_ucode_wrap_event, | ||
120 | TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry), | ||
121 | TP_ARGS(priv, wraps, n_entry, p_entry), | ||
122 | TP_STRUCT__entry( | ||
123 | PRIV_ENTRY | ||
124 | |||
125 | __field(u32, wraps) | ||
126 | __field(u32, n_entry) | ||
127 | __field(u32, p_entry) | ||
128 | ), | ||
129 | TP_fast_assign( | ||
130 | PRIV_ASSIGN; | ||
131 | __entry->wraps = wraps; | ||
132 | __entry->n_entry = n_entry; | ||
133 | __entry->p_entry = p_entry; | ||
134 | ), | ||
135 | TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X", | ||
136 | __entry->priv, __entry->wraps, __entry->n_entry, | ||
137 | __entry->p_entry) | ||
138 | ); | ||
139 | |||
140 | #undef TRACE_SYSTEM | 99 | #undef TRACE_SYSTEM |
141 | #define TRACE_SYSTEM iwlwifi | 100 | #define TRACE_SYSTEM iwlwifi |
142 | 101 | ||
@@ -242,25 +201,6 @@ TRACE_EVENT(iwlwifi_legacy_dev_ucode_error, | |||
242 | __entry->blink2, __entry->ilink1, __entry->ilink2) | 201 | __entry->blink2, __entry->ilink1, __entry->ilink2) |
243 | ); | 202 | ); |
244 | 203 | ||
245 | TRACE_EVENT(iwlwifi_legacy_dev_ucode_event, | ||
246 | TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), | ||
247 | TP_ARGS(priv, time, data, ev), | ||
248 | TP_STRUCT__entry( | ||
249 | PRIV_ENTRY | ||
250 | |||
251 | __field(u32, time) | ||
252 | __field(u32, data) | ||
253 | __field(u32, ev) | ||
254 | ), | ||
255 | TP_fast_assign( | ||
256 | PRIV_ASSIGN; | ||
257 | __entry->time = time; | ||
258 | __entry->data = data; | ||
259 | __entry->ev = ev; | ||
260 | ), | ||
261 | TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", | ||
262 | __entry->priv, __entry->time, __entry->data, __entry->ev) | ||
263 | ); | ||
264 | #endif /* __IWLWIFI_DEVICE_TRACE */ | 204 | #endif /* __IWLWIFI_DEVICE_TRACE */ |
265 | 205 | ||
266 | #undef TRACE_INCLUDE_PATH | 206 | #undef TRACE_INCLUDE_PATH |
diff --git a/drivers/net/wireless/iwlegacy/iwl-helpers.h b/drivers/net/wireless/iwlegacy/iwl-helpers.h index a6effdae63f9..5cf23eaecbbb 100644 --- a/drivers/net/wireless/iwlegacy/iwl-helpers.h +++ b/drivers/net/wireless/iwlegacy/iwl-helpers.h | |||
@@ -132,7 +132,16 @@ static inline void iwl_legacy_stop_queue(struct iwl_priv *priv, | |||
132 | ieee80211_stop_queue(priv->hw, ac); | 132 | ieee80211_stop_queue(priv->hw, ac); |
133 | } | 133 | } |
134 | 134 | ||
135 | #ifdef ieee80211_stop_queue | ||
136 | #undef ieee80211_stop_queue | ||
137 | #endif | ||
138 | |||
135 | #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue | 139 | #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue |
140 | |||
141 | #ifdef ieee80211_wake_queue | ||
142 | #undef ieee80211_wake_queue | ||
143 | #endif | ||
144 | |||
136 | #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue | 145 | #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue |
137 | 146 | ||
138 | static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv) | 147 | static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlegacy/iwl-rx.c b/drivers/net/wireless/iwlegacy/iwl-rx.c index 654cf233a384..9b5d0abe8be9 100644 --- a/drivers/net/wireless/iwlegacy/iwl-rx.c +++ b/drivers/net/wireless/iwlegacy/iwl-rx.c | |||
@@ -227,27 +227,6 @@ void iwl_legacy_rx_spectrum_measure_notif(struct iwl_priv *priv, | |||
227 | } | 227 | } |
228 | EXPORT_SYMBOL(iwl_legacy_rx_spectrum_measure_notif); | 228 | EXPORT_SYMBOL(iwl_legacy_rx_spectrum_measure_notif); |
229 | 229 | ||
230 | void iwl_legacy_recover_from_statistics(struct iwl_priv *priv, | ||
231 | struct iwl_rx_packet *pkt) | ||
232 | { | ||
233 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
234 | return; | ||
235 | if (iwl_legacy_is_any_associated(priv)) { | ||
236 | if (priv->cfg->ops->lib->check_plcp_health) { | ||
237 | if (!priv->cfg->ops->lib->check_plcp_health( | ||
238 | priv, pkt)) { | ||
239 | /* | ||
240 | * high plcp error detected | ||
241 | * reset Radio | ||
242 | */ | ||
243 | iwl_legacy_force_reset(priv, | ||
244 | IWL_RF_RESET, false); | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | EXPORT_SYMBOL(iwl_legacy_recover_from_statistics); | ||
250 | |||
251 | /* | 230 | /* |
252 | * returns non-zero if packet should be dropped | 231 | * returns non-zero if packet should be dropped |
253 | */ | 232 | */ |
diff --git a/drivers/net/wireless/iwlegacy/iwl-scan.c b/drivers/net/wireless/iwlegacy/iwl-scan.c index 353234a02c6d..a6b5222fc59e 100644 --- a/drivers/net/wireless/iwlegacy/iwl-scan.c +++ b/drivers/net/wireless/iwlegacy/iwl-scan.c | |||
@@ -101,7 +101,6 @@ static void iwl_legacy_complete_scan(struct iwl_priv *priv, bool aborted) | |||
101 | ieee80211_scan_completed(priv->hw, aborted); | 101 | ieee80211_scan_completed(priv->hw, aborted); |
102 | } | 102 | } |
103 | 103 | ||
104 | priv->is_internal_short_scan = false; | ||
105 | priv->scan_vif = NULL; | 104 | priv->scan_vif = NULL; |
106 | priv->scan_request = NULL; | 105 | priv->scan_request = NULL; |
107 | } | 106 | } |
@@ -329,10 +328,8 @@ void iwl_legacy_init_scan_params(struct iwl_priv *priv) | |||
329 | } | 328 | } |
330 | EXPORT_SYMBOL(iwl_legacy_init_scan_params); | 329 | EXPORT_SYMBOL(iwl_legacy_init_scan_params); |
331 | 330 | ||
332 | static int __must_check iwl_legacy_scan_initiate(struct iwl_priv *priv, | 331 | static int iwl_legacy_scan_initiate(struct iwl_priv *priv, |
333 | struct ieee80211_vif *vif, | 332 | struct ieee80211_vif *vif) |
334 | bool internal, | ||
335 | enum ieee80211_band band) | ||
336 | { | 333 | { |
337 | int ret; | 334 | int ret; |
338 | 335 | ||
@@ -359,18 +356,14 @@ static int __must_check iwl_legacy_scan_initiate(struct iwl_priv *priv, | |||
359 | return -EBUSY; | 356 | return -EBUSY; |
360 | } | 357 | } |
361 | 358 | ||
362 | IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", | 359 | IWL_DEBUG_SCAN(priv, "Starting scan...\n"); |
363 | internal ? "internal short " : ""); | ||
364 | 360 | ||
365 | set_bit(STATUS_SCANNING, &priv->status); | 361 | set_bit(STATUS_SCANNING, &priv->status); |
366 | priv->is_internal_short_scan = internal; | ||
367 | priv->scan_start = jiffies; | 362 | priv->scan_start = jiffies; |
368 | priv->scan_band = band; | ||
369 | 363 | ||
370 | ret = priv->cfg->ops->utils->request_scan(priv, vif); | 364 | ret = priv->cfg->ops->utils->request_scan(priv, vif); |
371 | if (ret) { | 365 | if (ret) { |
372 | clear_bit(STATUS_SCANNING, &priv->status); | 366 | clear_bit(STATUS_SCANNING, &priv->status); |
373 | priv->is_internal_short_scan = false; | ||
374 | return ret; | 367 | return ret; |
375 | } | 368 | } |
376 | 369 | ||
@@ -394,8 +387,7 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, | |||
394 | 387 | ||
395 | mutex_lock(&priv->mutex); | 388 | mutex_lock(&priv->mutex); |
396 | 389 | ||
397 | if (test_bit(STATUS_SCANNING, &priv->status) && | 390 | if (test_bit(STATUS_SCANNING, &priv->status)) { |
398 | !priv->is_internal_short_scan) { | ||
399 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); | 391 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); |
400 | ret = -EAGAIN; | 392 | ret = -EAGAIN; |
401 | goto out_unlock; | 393 | goto out_unlock; |
@@ -404,17 +396,9 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, | |||
404 | /* mac80211 will only ask for one band at a time */ | 396 | /* mac80211 will only ask for one band at a time */ |
405 | priv->scan_request = req; | 397 | priv->scan_request = req; |
406 | priv->scan_vif = vif; | 398 | priv->scan_vif = vif; |
399 | priv->scan_band = req->channels[0]->band; | ||
407 | 400 | ||
408 | /* | 401 | ret = iwl_legacy_scan_initiate(priv, vif); |
409 | * If an internal scan is in progress, just set | ||
410 | * up the scan_request as per above. | ||
411 | */ | ||
412 | if (priv->is_internal_short_scan) { | ||
413 | IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); | ||
414 | ret = 0; | ||
415 | } else | ||
416 | ret = iwl_legacy_scan_initiate(priv, vif, false, | ||
417 | req->channels[0]->band); | ||
418 | 402 | ||
419 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 403 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
420 | 404 | ||
@@ -425,40 +409,6 @@ out_unlock: | |||
425 | } | 409 | } |
426 | EXPORT_SYMBOL(iwl_legacy_mac_hw_scan); | 410 | EXPORT_SYMBOL(iwl_legacy_mac_hw_scan); |
427 | 411 | ||
428 | /* | ||
429 | * internal short scan, this function should only been called while associated. | ||
430 | * It will reset and tune the radio to prevent possible RF related problem | ||
431 | */ | ||
432 | void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv) | ||
433 | { | ||
434 | queue_work(priv->workqueue, &priv->start_internal_scan); | ||
435 | } | ||
436 | |||
437 | static void iwl_legacy_bg_start_internal_scan(struct work_struct *work) | ||
438 | { | ||
439 | struct iwl_priv *priv = | ||
440 | container_of(work, struct iwl_priv, start_internal_scan); | ||
441 | |||
442 | IWL_DEBUG_SCAN(priv, "Start internal scan\n"); | ||
443 | |||
444 | mutex_lock(&priv->mutex); | ||
445 | |||
446 | if (priv->is_internal_short_scan == true) { | ||
447 | IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); | ||
448 | goto unlock; | ||
449 | } | ||
450 | |||
451 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
452 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); | ||
453 | goto unlock; | ||
454 | } | ||
455 | |||
456 | if (iwl_legacy_scan_initiate(priv, NULL, true, priv->band)) | ||
457 | IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); | ||
458 | unlock: | ||
459 | mutex_unlock(&priv->mutex); | ||
460 | } | ||
461 | |||
462 | static void iwl_legacy_bg_scan_check(struct work_struct *data) | 412 | static void iwl_legacy_bg_scan_check(struct work_struct *data) |
463 | { | 413 | { |
464 | struct iwl_priv *priv = | 414 | struct iwl_priv *priv = |
@@ -542,8 +492,7 @@ static void iwl_legacy_bg_scan_completed(struct work_struct *work) | |||
542 | container_of(work, struct iwl_priv, scan_completed); | 492 | container_of(work, struct iwl_priv, scan_completed); |
543 | bool aborted; | 493 | bool aborted; |
544 | 494 | ||
545 | IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", | 495 | IWL_DEBUG_SCAN(priv, "Completed scan.\n"); |
546 | priv->is_internal_short_scan ? "internal short " : ""); | ||
547 | 496 | ||
548 | cancel_delayed_work(&priv->scan_check); | 497 | cancel_delayed_work(&priv->scan_check); |
549 | 498 | ||
@@ -558,27 +507,6 @@ static void iwl_legacy_bg_scan_completed(struct work_struct *work) | |||
558 | goto out_settings; | 507 | goto out_settings; |
559 | } | 508 | } |
560 | 509 | ||
561 | if (priv->is_internal_short_scan && !aborted) { | ||
562 | int err; | ||
563 | |||
564 | /* Check if mac80211 requested scan during our internal scan */ | ||
565 | if (priv->scan_request == NULL) | ||
566 | goto out_complete; | ||
567 | |||
568 | /* If so request a new scan */ | ||
569 | err = iwl_legacy_scan_initiate(priv, priv->scan_vif, false, | ||
570 | priv->scan_request->channels[0]->band); | ||
571 | if (err) { | ||
572 | IWL_DEBUG_SCAN(priv, | ||
573 | "failed to initiate pending scan: %d\n", err); | ||
574 | aborted = true; | ||
575 | goto out_complete; | ||
576 | } | ||
577 | |||
578 | goto out; | ||
579 | } | ||
580 | |||
581 | out_complete: | ||
582 | iwl_legacy_complete_scan(priv, aborted); | 510 | iwl_legacy_complete_scan(priv, aborted); |
583 | 511 | ||
584 | out_settings: | 512 | out_settings: |
@@ -590,8 +518,7 @@ out_settings: | |||
590 | * We do not commit power settings while scan is pending, | 518 | * We do not commit power settings while scan is pending, |
591 | * do it now if the settings changed. | 519 | * do it now if the settings changed. |
592 | */ | 520 | */ |
593 | iwl_legacy_power_set_mode(priv, &priv->power_data.sleep_cmd_next, | 521 | iwl_legacy_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false); |
594 | false); | ||
595 | iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); | 522 | iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); |
596 | 523 | ||
597 | priv->cfg->ops->utils->post_scan(priv); | 524 | priv->cfg->ops->utils->post_scan(priv); |
@@ -604,15 +531,12 @@ void iwl_legacy_setup_scan_deferred_work(struct iwl_priv *priv) | |||
604 | { | 531 | { |
605 | INIT_WORK(&priv->scan_completed, iwl_legacy_bg_scan_completed); | 532 | INIT_WORK(&priv->scan_completed, iwl_legacy_bg_scan_completed); |
606 | INIT_WORK(&priv->abort_scan, iwl_legacy_bg_abort_scan); | 533 | INIT_WORK(&priv->abort_scan, iwl_legacy_bg_abort_scan); |
607 | INIT_WORK(&priv->start_internal_scan, | ||
608 | iwl_legacy_bg_start_internal_scan); | ||
609 | INIT_DELAYED_WORK(&priv->scan_check, iwl_legacy_bg_scan_check); | 534 | INIT_DELAYED_WORK(&priv->scan_check, iwl_legacy_bg_scan_check); |
610 | } | 535 | } |
611 | EXPORT_SYMBOL(iwl_legacy_setup_scan_deferred_work); | 536 | EXPORT_SYMBOL(iwl_legacy_setup_scan_deferred_work); |
612 | 537 | ||
613 | void iwl_legacy_cancel_scan_deferred_work(struct iwl_priv *priv) | 538 | void iwl_legacy_cancel_scan_deferred_work(struct iwl_priv *priv) |
614 | { | 539 | { |
615 | cancel_work_sync(&priv->start_internal_scan); | ||
616 | cancel_work_sync(&priv->abort_scan); | 540 | cancel_work_sync(&priv->abort_scan); |
617 | cancel_work_sync(&priv->scan_completed); | 541 | cancel_work_sync(&priv->scan_completed); |
618 | 542 | ||
diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index 0ee6be6a9c5d..795826a014ed 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c | |||
@@ -1409,212 +1409,6 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv) | |||
1409 | } | 1409 | } |
1410 | } | 1410 | } |
1411 | 1411 | ||
1412 | #define EVENT_START_OFFSET (6 * sizeof(u32)) | ||
1413 | |||
1414 | /** | ||
1415 | * iwl3945_print_event_log - Dump error event log to syslog | ||
1416 | * | ||
1417 | */ | ||
1418 | static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | ||
1419 | u32 num_events, u32 mode, | ||
1420 | int pos, char **buf, size_t bufsz) | ||
1421 | { | ||
1422 | u32 i; | ||
1423 | u32 base; /* SRAM byte address of event log header */ | ||
1424 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ | ||
1425 | u32 ptr; /* SRAM byte address of log data */ | ||
1426 | u32 ev, time, data; /* event log data */ | ||
1427 | unsigned long reg_flags; | ||
1428 | |||
1429 | if (num_events == 0) | ||
1430 | return pos; | ||
1431 | |||
1432 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | ||
1433 | |||
1434 | if (mode == 0) | ||
1435 | event_size = 2 * sizeof(u32); | ||
1436 | else | ||
1437 | event_size = 3 * sizeof(u32); | ||
1438 | |||
1439 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); | ||
1440 | |||
1441 | /* Make sure device is powered up for SRAM reads */ | ||
1442 | spin_lock_irqsave(&priv->reg_lock, reg_flags); | ||
1443 | iwl_grab_nic_access(priv); | ||
1444 | |||
1445 | /* Set starting address; reads will auto-increment */ | ||
1446 | _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); | ||
1447 | rmb(); | ||
1448 | |||
1449 | /* "time" is actually "data" for mode 0 (no timestamp). | ||
1450 | * place event id # at far right for easier visual parsing. */ | ||
1451 | for (i = 0; i < num_events; i++) { | ||
1452 | ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
1453 | time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
1454 | if (mode == 0) { | ||
1455 | /* data, ev */ | ||
1456 | if (bufsz) { | ||
1457 | pos += scnprintf(*buf + pos, bufsz - pos, | ||
1458 | "0x%08x:%04u\n", | ||
1459 | time, ev); | ||
1460 | } else { | ||
1461 | IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); | ||
1462 | trace_iwlwifi_legacy_dev_ucode_event(priv, 0, | ||
1463 | time, ev); | ||
1464 | } | ||
1465 | } else { | ||
1466 | data = _iwl_legacy_read_direct32(priv, | ||
1467 | HBUS_TARG_MEM_RDAT); | ||
1468 | if (bufsz) { | ||
1469 | pos += scnprintf(*buf + pos, bufsz - pos, | ||
1470 | "%010u:0x%08x:%04u\n", | ||
1471 | time, data, ev); | ||
1472 | } else { | ||
1473 | IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", | ||
1474 | time, data, ev); | ||
1475 | trace_iwlwifi_legacy_dev_ucode_event(priv, time, | ||
1476 | data, ev); | ||
1477 | } | ||
1478 | } | ||
1479 | } | ||
1480 | |||
1481 | /* Allow device to power down */ | ||
1482 | iwl_release_nic_access(priv); | ||
1483 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
1484 | return pos; | ||
1485 | } | ||
1486 | |||
1487 | /** | ||
1488 | * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog | ||
1489 | */ | ||
1490 | static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | ||
1491 | u32 num_wraps, u32 next_entry, | ||
1492 | u32 size, u32 mode, | ||
1493 | int pos, char **buf, size_t bufsz) | ||
1494 | { | ||
1495 | /* | ||
1496 | * display the newest DEFAULT_LOG_ENTRIES entries | ||
1497 | * i.e the entries just before the next ont that uCode would fill. | ||
1498 | */ | ||
1499 | if (num_wraps) { | ||
1500 | if (next_entry < size) { | ||
1501 | pos = iwl3945_print_event_log(priv, | ||
1502 | capacity - (size - next_entry), | ||
1503 | size - next_entry, mode, | ||
1504 | pos, buf, bufsz); | ||
1505 | pos = iwl3945_print_event_log(priv, 0, | ||
1506 | next_entry, mode, | ||
1507 | pos, buf, bufsz); | ||
1508 | } else | ||
1509 | pos = iwl3945_print_event_log(priv, next_entry - size, | ||
1510 | size, mode, | ||
1511 | pos, buf, bufsz); | ||
1512 | } else { | ||
1513 | if (next_entry < size) | ||
1514 | pos = iwl3945_print_event_log(priv, 0, | ||
1515 | next_entry, mode, | ||
1516 | pos, buf, bufsz); | ||
1517 | else | ||
1518 | pos = iwl3945_print_event_log(priv, next_entry - size, | ||
1519 | size, mode, | ||
1520 | pos, buf, bufsz); | ||
1521 | } | ||
1522 | return pos; | ||
1523 | } | ||
1524 | |||
1525 | #define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) | ||
1526 | |||
1527 | int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | ||
1528 | char **buf, bool display) | ||
1529 | { | ||
1530 | u32 base; /* SRAM byte address of event log header */ | ||
1531 | u32 capacity; /* event log capacity in # entries */ | ||
1532 | u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ | ||
1533 | u32 num_wraps; /* # times uCode wrapped to top of log */ | ||
1534 | u32 next_entry; /* index of next entry to be written by uCode */ | ||
1535 | u32 size; /* # entries that we'll print */ | ||
1536 | int pos = 0; | ||
1537 | size_t bufsz = 0; | ||
1538 | |||
1539 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | ||
1540 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { | ||
1541 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); | ||
1542 | return -EINVAL; | ||
1543 | } | ||
1544 | |||
1545 | /* event log header */ | ||
1546 | capacity = iwl_legacy_read_targ_mem(priv, base); | ||
1547 | mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); | ||
1548 | num_wraps = iwl_legacy_read_targ_mem(priv, base + (2 * sizeof(u32))); | ||
1549 | next_entry = iwl_legacy_read_targ_mem(priv, base + (3 * sizeof(u32))); | ||
1550 | |||
1551 | if (capacity > priv->cfg->base_params->max_event_log_size) { | ||
1552 | IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", | ||
1553 | capacity, priv->cfg->base_params->max_event_log_size); | ||
1554 | capacity = priv->cfg->base_params->max_event_log_size; | ||
1555 | } | ||
1556 | |||
1557 | if (next_entry > priv->cfg->base_params->max_event_log_size) { | ||
1558 | IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", | ||
1559 | next_entry, priv->cfg->base_params->max_event_log_size); | ||
1560 | next_entry = priv->cfg->base_params->max_event_log_size; | ||
1561 | } | ||
1562 | |||
1563 | size = num_wraps ? capacity : next_entry; | ||
1564 | |||
1565 | /* bail out if nothing in log */ | ||
1566 | if (size == 0) { | ||
1567 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); | ||
1568 | return pos; | ||
1569 | } | ||
1570 | |||
1571 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | ||
1572 | if (!(iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) | ||
1573 | size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) | ||
1574 | ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; | ||
1575 | #else | ||
1576 | size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) | ||
1577 | ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; | ||
1578 | #endif | ||
1579 | |||
1580 | IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", | ||
1581 | size); | ||
1582 | |||
1583 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | ||
1584 | if (display) { | ||
1585 | if (full_log) | ||
1586 | bufsz = capacity * 48; | ||
1587 | else | ||
1588 | bufsz = size * 48; | ||
1589 | *buf = kmalloc(bufsz, GFP_KERNEL); | ||
1590 | if (!*buf) | ||
1591 | return -ENOMEM; | ||
1592 | } | ||
1593 | if ((iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { | ||
1594 | /* if uCode has wrapped back to top of log, | ||
1595 | * start at the oldest entry, | ||
1596 | * i.e the next one that uCode would fill. | ||
1597 | */ | ||
1598 | if (num_wraps) | ||
1599 | pos = iwl3945_print_event_log(priv, next_entry, | ||
1600 | capacity - next_entry, mode, | ||
1601 | pos, buf, bufsz); | ||
1602 | |||
1603 | /* (then/else) start at top of log */ | ||
1604 | pos = iwl3945_print_event_log(priv, 0, next_entry, mode, | ||
1605 | pos, buf, bufsz); | ||
1606 | } else | ||
1607 | pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, | ||
1608 | next_entry, size, mode, | ||
1609 | pos, buf, bufsz); | ||
1610 | #else | ||
1611 | pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, | ||
1612 | next_entry, size, mode, | ||
1613 | pos, buf, bufsz); | ||
1614 | #endif | ||
1615 | return pos; | ||
1616 | } | ||
1617 | |||
1618 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) | 1412 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) |
1619 | { | 1413 | { |
1620 | u32 inta, handled = 0; | 1414 | u32 inta, handled = 0; |
@@ -1762,49 +1556,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
1762 | #endif | 1556 | #endif |
1763 | } | 1557 | } |
1764 | 1558 | ||
1765 | static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, | ||
1766 | struct ieee80211_vif *vif, | ||
1767 | enum ieee80211_band band, | ||
1768 | struct iwl3945_scan_channel *scan_ch) | ||
1769 | { | ||
1770 | const struct ieee80211_supported_band *sband; | ||
1771 | u16 passive_dwell = 0; | ||
1772 | u16 active_dwell = 0; | ||
1773 | int added = 0; | ||
1774 | u8 channel = 0; | ||
1775 | |||
1776 | sband = iwl_get_hw_mode(priv, band); | ||
1777 | if (!sband) { | ||
1778 | IWL_ERR(priv, "invalid band\n"); | ||
1779 | return added; | ||
1780 | } | ||
1781 | |||
1782 | active_dwell = iwl_legacy_get_active_dwell_time(priv, band, 0); | ||
1783 | passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); | ||
1784 | |||
1785 | if (passive_dwell <= active_dwell) | ||
1786 | passive_dwell = active_dwell + 1; | ||
1787 | |||
1788 | |||
1789 | channel = iwl_legacy_get_single_channel_number(priv, band); | ||
1790 | |||
1791 | if (channel) { | ||
1792 | scan_ch->channel = channel; | ||
1793 | scan_ch->type = 0; /* passive */ | ||
1794 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | ||
1795 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | ||
1796 | /* Set txpower levels to defaults */ | ||
1797 | scan_ch->tpc.dsp_atten = 110; | ||
1798 | if (band == IEEE80211_BAND_5GHZ) | ||
1799 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | ||
1800 | else | ||
1801 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | ||
1802 | added++; | ||
1803 | } else | ||
1804 | IWL_ERR(priv, "no valid channel found\n"); | ||
1805 | return added; | ||
1806 | } | ||
1807 | |||
1808 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, | 1559 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, |
1809 | enum ieee80211_band band, | 1560 | enum ieee80211_band band, |
1810 | u8 is_active, u8 n_probes, | 1561 | u8 is_active, u8 n_probes, |
@@ -2816,6 +2567,7 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
2816 | enum ieee80211_band band; | 2567 | enum ieee80211_band band; |
2817 | bool is_active = false; | 2568 | bool is_active = false; |
2818 | int ret; | 2569 | int ret; |
2570 | u16 len; | ||
2819 | 2571 | ||
2820 | lockdep_assert_held(&priv->mutex); | 2572 | lockdep_assert_held(&priv->mutex); |
2821 | 2573 | ||
@@ -2834,17 +2586,14 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
2834 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; | 2586 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; |
2835 | 2587 | ||
2836 | if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) { | 2588 | if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) { |
2837 | u16 interval = 0; | 2589 | u16 interval; |
2838 | u32 extra; | 2590 | u32 extra; |
2839 | u32 suspend_time = 100; | 2591 | u32 suspend_time = 100; |
2840 | u32 scan_suspend_time = 100; | 2592 | u32 scan_suspend_time = 100; |
2841 | 2593 | ||
2842 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); | 2594 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); |
2843 | 2595 | ||
2844 | if (priv->is_internal_short_scan) | 2596 | interval = vif->bss_conf.beacon_int; |
2845 | interval = 0; | ||
2846 | else | ||
2847 | interval = vif->bss_conf.beacon_int; | ||
2848 | 2597 | ||
2849 | scan->suspend_time = 0; | 2598 | scan->suspend_time = 0; |
2850 | scan->max_out_time = cpu_to_le32(200 * 1024); | 2599 | scan->max_out_time = cpu_to_le32(200 * 1024); |
@@ -2866,9 +2615,7 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
2866 | scan_suspend_time, interval); | 2615 | scan_suspend_time, interval); |
2867 | } | 2616 | } |
2868 | 2617 | ||
2869 | if (priv->is_internal_short_scan) { | 2618 | if (priv->scan_request->n_ssids) { |
2870 | IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); | ||
2871 | } else if (priv->scan_request->n_ssids) { | ||
2872 | int i, p = 0; | 2619 | int i, p = 0; |
2873 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); | 2620 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); |
2874 | for (i = 0; i < priv->scan_request->n_ssids; i++) { | 2621 | for (i = 0; i < priv->scan_request->n_ssids; i++) { |
@@ -2919,36 +2666,17 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
2919 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : | 2666 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : |
2920 | IWL_GOOD_CRC_TH_DISABLED; | 2667 | IWL_GOOD_CRC_TH_DISABLED; |
2921 | 2668 | ||
2922 | if (!priv->is_internal_short_scan) { | 2669 | len = iwl_legacy_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, |
2923 | scan->tx_cmd.len = cpu_to_le16( | 2670 | vif->addr, priv->scan_request->ie, |
2924 | iwl_legacy_fill_probe_req(priv, | 2671 | priv->scan_request->ie_len, |
2925 | (struct ieee80211_mgmt *)scan->data, | 2672 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); |
2926 | vif->addr, | 2673 | scan->tx_cmd.len = cpu_to_le16(len); |
2927 | priv->scan_request->ie, | 2674 | |
2928 | priv->scan_request->ie_len, | ||
2929 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); | ||
2930 | } else { | ||
2931 | /* use bcast addr, will not be transmitted but must be valid */ | ||
2932 | scan->tx_cmd.len = cpu_to_le16( | ||
2933 | iwl_legacy_fill_probe_req(priv, | ||
2934 | (struct ieee80211_mgmt *)scan->data, | ||
2935 | iwlegacy_bcast_addr, NULL, 0, | ||
2936 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); | ||
2937 | } | ||
2938 | /* select Rx antennas */ | 2675 | /* select Rx antennas */ |
2939 | scan->flags |= iwl3945_get_antenna_flags(priv); | 2676 | scan->flags |= iwl3945_get_antenna_flags(priv); |
2940 | 2677 | ||
2941 | if (priv->is_internal_short_scan) { | 2678 | scan->channel_count = iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, |
2942 | scan->channel_count = | 2679 | (void *)&scan->data[len], vif); |
2943 | iwl3945_get_single_channel_for_scan(priv, vif, band, | ||
2944 | (void *)&scan->data[le16_to_cpu( | ||
2945 | scan->tx_cmd.len)]); | ||
2946 | } else { | ||
2947 | scan->channel_count = | ||
2948 | iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, | ||
2949 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); | ||
2950 | } | ||
2951 | |||
2952 | if (scan->channel_count == 0) { | 2680 | if (scan->channel_count == 0) { |
2953 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); | 2681 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); |
2954 | return -EIO; | 2682 | return -EIO; |
@@ -3824,10 +3552,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
3824 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; | 3552 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; |
3825 | 3553 | ||
3826 | /* initialize force reset */ | 3554 | /* initialize force reset */ |
3827 | priv->force_reset[IWL_RF_RESET].reset_duration = | 3555 | priv->force_reset.reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD; |
3828 | IWL_DELAY_NEXT_FORCE_RF_RESET; | ||
3829 | priv->force_reset[IWL_FW_RESET].reset_duration = | ||
3830 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; | ||
3831 | 3556 | ||
3832 | if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { | 3557 | if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { |
3833 | IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", | 3558 | IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", |
diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index 7157ba529680..46242d2aa5ad 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c | |||
@@ -488,134 +488,6 @@ static void iwl4965_bg_statistics_periodic(unsigned long data) | |||
488 | iwl_legacy_send_statistics_request(priv, CMD_ASYNC, false); | 488 | iwl_legacy_send_statistics_request(priv, CMD_ASYNC, false); |
489 | } | 489 | } |
490 | 490 | ||
491 | |||
492 | static void iwl4965_print_cont_event_trace(struct iwl_priv *priv, u32 base, | ||
493 | u32 start_idx, u32 num_events, | ||
494 | u32 mode) | ||
495 | { | ||
496 | u32 i; | ||
497 | u32 ptr; /* SRAM byte address of log data */ | ||
498 | u32 ev, time, data; /* event log data */ | ||
499 | unsigned long reg_flags; | ||
500 | |||
501 | if (mode == 0) | ||
502 | ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32)); | ||
503 | else | ||
504 | ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); | ||
505 | |||
506 | /* Make sure device is powered up for SRAM reads */ | ||
507 | spin_lock_irqsave(&priv->reg_lock, reg_flags); | ||
508 | if (iwl_grab_nic_access(priv)) { | ||
509 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
510 | return; | ||
511 | } | ||
512 | |||
513 | /* Set starting address; reads will auto-increment */ | ||
514 | _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); | ||
515 | rmb(); | ||
516 | |||
517 | /* | ||
518 | * "time" is actually "data" for mode 0 (no timestamp). | ||
519 | * place event id # at far right for easier visual parsing. | ||
520 | */ | ||
521 | for (i = 0; i < num_events; i++) { | ||
522 | ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
523 | time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
524 | if (mode == 0) { | ||
525 | trace_iwlwifi_legacy_dev_ucode_cont_event(priv, | ||
526 | 0, time, ev); | ||
527 | } else { | ||
528 | data = _iwl_legacy_read_direct32(priv, | ||
529 | HBUS_TARG_MEM_RDAT); | ||
530 | trace_iwlwifi_legacy_dev_ucode_cont_event(priv, | ||
531 | time, data, ev); | ||
532 | } | ||
533 | } | ||
534 | /* Allow device to power down */ | ||
535 | iwl_release_nic_access(priv); | ||
536 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
537 | } | ||
538 | |||
539 | static void iwl4965_continuous_event_trace(struct iwl_priv *priv) | ||
540 | { | ||
541 | u32 capacity; /* event log capacity in # entries */ | ||
542 | u32 base; /* SRAM byte address of event log header */ | ||
543 | u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ | ||
544 | u32 num_wraps; /* # times uCode wrapped to top of log */ | ||
545 | u32 next_entry; /* index of next entry to be written by uCode */ | ||
546 | |||
547 | if (priv->ucode_type == UCODE_INIT) | ||
548 | base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); | ||
549 | else | ||
550 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | ||
551 | if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | ||
552 | capacity = iwl_legacy_read_targ_mem(priv, base); | ||
553 | num_wraps = iwl_legacy_read_targ_mem(priv, | ||
554 | base + (2 * sizeof(u32))); | ||
555 | mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); | ||
556 | next_entry = iwl_legacy_read_targ_mem(priv, | ||
557 | base + (3 * sizeof(u32))); | ||
558 | } else | ||
559 | return; | ||
560 | |||
561 | if (num_wraps == priv->event_log.num_wraps) { | ||
562 | iwl4965_print_cont_event_trace(priv, | ||
563 | base, priv->event_log.next_entry, | ||
564 | next_entry - priv->event_log.next_entry, | ||
565 | mode); | ||
566 | priv->event_log.non_wraps_count++; | ||
567 | } else { | ||
568 | if ((num_wraps - priv->event_log.num_wraps) > 1) | ||
569 | priv->event_log.wraps_more_count++; | ||
570 | else | ||
571 | priv->event_log.wraps_once_count++; | ||
572 | trace_iwlwifi_legacy_dev_ucode_wrap_event(priv, | ||
573 | num_wraps - priv->event_log.num_wraps, | ||
574 | next_entry, priv->event_log.next_entry); | ||
575 | if (next_entry < priv->event_log.next_entry) { | ||
576 | iwl4965_print_cont_event_trace(priv, base, | ||
577 | priv->event_log.next_entry, | ||
578 | capacity - priv->event_log.next_entry, | ||
579 | mode); | ||
580 | |||
581 | iwl4965_print_cont_event_trace(priv, base, 0, | ||
582 | next_entry, mode); | ||
583 | } else { | ||
584 | iwl4965_print_cont_event_trace(priv, base, | ||
585 | next_entry, capacity - next_entry, | ||
586 | mode); | ||
587 | |||
588 | iwl4965_print_cont_event_trace(priv, base, 0, | ||
589 | next_entry, mode); | ||
590 | } | ||
591 | } | ||
592 | priv->event_log.num_wraps = num_wraps; | ||
593 | priv->event_log.next_entry = next_entry; | ||
594 | } | ||
595 | |||
596 | /** | ||
597 | * iwl4965_bg_ucode_trace - Timer callback to log ucode event | ||
598 | * | ||
599 | * The timer is continually set to execute every | ||
600 | * UCODE_TRACE_PERIOD milliseconds after the last timer expired | ||
601 | * this function is to perform continuous uCode event logging operation | ||
602 | * if enabled | ||
603 | */ | ||
604 | static void iwl4965_bg_ucode_trace(unsigned long data) | ||
605 | { | ||
606 | struct iwl_priv *priv = (struct iwl_priv *)data; | ||
607 | |||
608 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
609 | return; | ||
610 | |||
611 | if (priv->event_log.ucode_trace) { | ||
612 | iwl4965_continuous_event_trace(priv); | ||
613 | /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */ | ||
614 | mod_timer(&priv->ucode_trace, | ||
615 | jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); | ||
616 | } | ||
617 | } | ||
618 | |||
619 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, | 491 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, |
620 | struct iwl_rx_mem_buffer *rxb) | 492 | struct iwl_rx_mem_buffer *rxb) |
621 | { | 493 | { |
@@ -1711,209 +1583,6 @@ void iwl4965_dump_nic_error_log(struct iwl_priv *priv) | |||
1711 | pc, blink1, blink2, ilink1, ilink2, hcmd); | 1583 | pc, blink1, blink2, ilink1, ilink2, hcmd); |
1712 | } | 1584 | } |
1713 | 1585 | ||
1714 | #define EVENT_START_OFFSET (4 * sizeof(u32)) | ||
1715 | |||
1716 | /** | ||
1717 | * iwl4965_print_event_log - Dump error event log to syslog | ||
1718 | * | ||
1719 | */ | ||
1720 | static int iwl4965_print_event_log(struct iwl_priv *priv, u32 start_idx, | ||
1721 | u32 num_events, u32 mode, | ||
1722 | int pos, char **buf, size_t bufsz) | ||
1723 | { | ||
1724 | u32 i; | ||
1725 | u32 base; /* SRAM byte address of event log header */ | ||
1726 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ | ||
1727 | u32 ptr; /* SRAM byte address of log data */ | ||
1728 | u32 ev, time, data; /* event log data */ | ||
1729 | unsigned long reg_flags; | ||
1730 | |||
1731 | if (num_events == 0) | ||
1732 | return pos; | ||
1733 | |||
1734 | if (priv->ucode_type == UCODE_INIT) { | ||
1735 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); | ||
1736 | } else { | ||
1737 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | ||
1738 | } | ||
1739 | |||
1740 | if (mode == 0) | ||
1741 | event_size = 2 * sizeof(u32); | ||
1742 | else | ||
1743 | event_size = 3 * sizeof(u32); | ||
1744 | |||
1745 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); | ||
1746 | |||
1747 | /* Make sure device is powered up for SRAM reads */ | ||
1748 | spin_lock_irqsave(&priv->reg_lock, reg_flags); | ||
1749 | iwl_grab_nic_access(priv); | ||
1750 | |||
1751 | /* Set starting address; reads will auto-increment */ | ||
1752 | _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); | ||
1753 | rmb(); | ||
1754 | |||
1755 | /* "time" is actually "data" for mode 0 (no timestamp). | ||
1756 | * place event id # at far right for easier visual parsing. */ | ||
1757 | for (i = 0; i < num_events; i++) { | ||
1758 | ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
1759 | time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
1760 | if (mode == 0) { | ||
1761 | /* data, ev */ | ||
1762 | if (bufsz) { | ||
1763 | pos += scnprintf(*buf + pos, bufsz - pos, | ||
1764 | "EVT_LOG:0x%08x:%04u\n", | ||
1765 | time, ev); | ||
1766 | } else { | ||
1767 | trace_iwlwifi_legacy_dev_ucode_event(priv, 0, | ||
1768 | time, ev); | ||
1769 | IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", | ||
1770 | time, ev); | ||
1771 | } | ||
1772 | } else { | ||
1773 | data = _iwl_legacy_read_direct32(priv, | ||
1774 | HBUS_TARG_MEM_RDAT); | ||
1775 | if (bufsz) { | ||
1776 | pos += scnprintf(*buf + pos, bufsz - pos, | ||
1777 | "EVT_LOGT:%010u:0x%08x:%04u\n", | ||
1778 | time, data, ev); | ||
1779 | } else { | ||
1780 | IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", | ||
1781 | time, data, ev); | ||
1782 | trace_iwlwifi_legacy_dev_ucode_event(priv, time, | ||
1783 | data, ev); | ||
1784 | } | ||
1785 | } | ||
1786 | } | ||
1787 | |||
1788 | /* Allow device to power down */ | ||
1789 | iwl_release_nic_access(priv); | ||
1790 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
1791 | return pos; | ||
1792 | } | ||
1793 | |||
1794 | /** | ||
1795 | * iwl4965_print_last_event_logs - Dump the newest # of event log to syslog | ||
1796 | */ | ||
1797 | static int iwl4965_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | ||
1798 | u32 num_wraps, u32 next_entry, | ||
1799 | u32 size, u32 mode, | ||
1800 | int pos, char **buf, size_t bufsz) | ||
1801 | { | ||
1802 | /* | ||
1803 | * display the newest DEFAULT_LOG_ENTRIES entries | ||
1804 | * i.e the entries just before the next ont that uCode would fill. | ||
1805 | */ | ||
1806 | if (num_wraps) { | ||
1807 | if (next_entry < size) { | ||
1808 | pos = iwl4965_print_event_log(priv, | ||
1809 | capacity - (size - next_entry), | ||
1810 | size - next_entry, mode, | ||
1811 | pos, buf, bufsz); | ||
1812 | pos = iwl4965_print_event_log(priv, 0, | ||
1813 | next_entry, mode, | ||
1814 | pos, buf, bufsz); | ||
1815 | } else | ||
1816 | pos = iwl4965_print_event_log(priv, next_entry - size, | ||
1817 | size, mode, pos, buf, bufsz); | ||
1818 | } else { | ||
1819 | if (next_entry < size) { | ||
1820 | pos = iwl4965_print_event_log(priv, 0, next_entry, | ||
1821 | mode, pos, buf, bufsz); | ||
1822 | } else { | ||
1823 | pos = iwl4965_print_event_log(priv, next_entry - size, | ||
1824 | size, mode, pos, buf, bufsz); | ||
1825 | } | ||
1826 | } | ||
1827 | return pos; | ||
1828 | } | ||
1829 | |||
1830 | #define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) | ||
1831 | |||
1832 | int iwl4965_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | ||
1833 | char **buf, bool display) | ||
1834 | { | ||
1835 | u32 base; /* SRAM byte address of event log header */ | ||
1836 | u32 capacity; /* event log capacity in # entries */ | ||
1837 | u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ | ||
1838 | u32 num_wraps; /* # times uCode wrapped to top of log */ | ||
1839 | u32 next_entry; /* index of next entry to be written by uCode */ | ||
1840 | u32 size; /* # entries that we'll print */ | ||
1841 | int pos = 0; | ||
1842 | size_t bufsz = 0; | ||
1843 | |||
1844 | if (priv->ucode_type == UCODE_INIT) { | ||
1845 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); | ||
1846 | } else { | ||
1847 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | ||
1848 | } | ||
1849 | |||
1850 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | ||
1851 | IWL_ERR(priv, | ||
1852 | "Invalid event log pointer 0x%08X for %s uCode\n", | ||
1853 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | ||
1854 | return -EINVAL; | ||
1855 | } | ||
1856 | |||
1857 | /* event log header */ | ||
1858 | capacity = iwl_legacy_read_targ_mem(priv, base); | ||
1859 | mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); | ||
1860 | num_wraps = iwl_legacy_read_targ_mem(priv, base + (2 * sizeof(u32))); | ||
1861 | next_entry = iwl_legacy_read_targ_mem(priv, base + (3 * sizeof(u32))); | ||
1862 | |||
1863 | size = num_wraps ? capacity : next_entry; | ||
1864 | |||
1865 | /* bail out if nothing in log */ | ||
1866 | if (size == 0) { | ||
1867 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); | ||
1868 | return pos; | ||
1869 | } | ||
1870 | |||
1871 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | ||
1872 | if (!(iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) | ||
1873 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | ||
1874 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; | ||
1875 | #else | ||
1876 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | ||
1877 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; | ||
1878 | #endif | ||
1879 | IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", | ||
1880 | size); | ||
1881 | |||
1882 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | ||
1883 | if (display) { | ||
1884 | if (full_log) | ||
1885 | bufsz = capacity * 48; | ||
1886 | else | ||
1887 | bufsz = size * 48; | ||
1888 | *buf = kmalloc(bufsz, GFP_KERNEL); | ||
1889 | if (!*buf) | ||
1890 | return -ENOMEM; | ||
1891 | } | ||
1892 | if ((iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { | ||
1893 | /* | ||
1894 | * if uCode has wrapped back to top of log, | ||
1895 | * start at the oldest entry, | ||
1896 | * i.e the next one that uCode would fill. | ||
1897 | */ | ||
1898 | if (num_wraps) | ||
1899 | pos = iwl4965_print_event_log(priv, next_entry, | ||
1900 | capacity - next_entry, mode, | ||
1901 | pos, buf, bufsz); | ||
1902 | /* (then/else) start at top of log */ | ||
1903 | pos = iwl4965_print_event_log(priv, 0, | ||
1904 | next_entry, mode, pos, buf, bufsz); | ||
1905 | } else | ||
1906 | pos = iwl4965_print_last_event_logs(priv, capacity, num_wraps, | ||
1907 | next_entry, size, mode, | ||
1908 | pos, buf, bufsz); | ||
1909 | #else | ||
1910 | pos = iwl4965_print_last_event_logs(priv, capacity, num_wraps, | ||
1911 | next_entry, size, mode, | ||
1912 | pos, buf, bufsz); | ||
1913 | #endif | ||
1914 | return pos; | ||
1915 | } | ||
1916 | |||
1917 | static void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) | 1586 | static void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) |
1918 | { | 1587 | { |
1919 | struct iwl_ct_kill_config cmd; | 1588 | struct iwl_ct_kill_config cmd; |
@@ -2773,20 +2442,10 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | |||
2773 | case IEEE80211_AMPDU_TX_START: | 2442 | case IEEE80211_AMPDU_TX_START: |
2774 | IWL_DEBUG_HT(priv, "start Tx\n"); | 2443 | IWL_DEBUG_HT(priv, "start Tx\n"); |
2775 | ret = iwl4965_tx_agg_start(priv, vif, sta, tid, ssn); | 2444 | ret = iwl4965_tx_agg_start(priv, vif, sta, tid, ssn); |
2776 | if (ret == 0) { | ||
2777 | priv->_4965.agg_tids_count++; | ||
2778 | IWL_DEBUG_HT(priv, "priv->_4965.agg_tids_count = %u\n", | ||
2779 | priv->_4965.agg_tids_count); | ||
2780 | } | ||
2781 | break; | 2445 | break; |
2782 | case IEEE80211_AMPDU_TX_STOP: | 2446 | case IEEE80211_AMPDU_TX_STOP: |
2783 | IWL_DEBUG_HT(priv, "stop Tx\n"); | 2447 | IWL_DEBUG_HT(priv, "stop Tx\n"); |
2784 | ret = iwl4965_tx_agg_stop(priv, vif, sta, tid); | 2448 | ret = iwl4965_tx_agg_stop(priv, vif, sta, tid); |
2785 | if ((ret == 0) && (priv->_4965.agg_tids_count > 0)) { | ||
2786 | priv->_4965.agg_tids_count--; | ||
2787 | IWL_DEBUG_HT(priv, "priv->_4965.agg_tids_count = %u\n", | ||
2788 | priv->_4965.agg_tids_count); | ||
2789 | } | ||
2790 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2449 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2791 | ret = 0; | 2450 | ret = 0; |
2792 | break; | 2451 | break; |
@@ -2851,7 +2510,6 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
2851 | 2510 | ||
2852 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 2511 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
2853 | u16 ch; | 2512 | u16 ch; |
2854 | unsigned long flags = 0; | ||
2855 | 2513 | ||
2856 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2514 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
2857 | 2515 | ||
@@ -2868,64 +2526,64 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
2868 | if (!iwl_legacy_is_associated_ctx(ctx)) | 2526 | if (!iwl_legacy_is_associated_ctx(ctx)) |
2869 | goto out; | 2527 | goto out; |
2870 | 2528 | ||
2871 | if (priv->cfg->ops->lib->set_channel_switch) { | 2529 | if (!priv->cfg->ops->lib->set_channel_switch) |
2530 | goto out; | ||
2872 | 2531 | ||
2873 | ch = channel->hw_value; | 2532 | ch = channel->hw_value; |
2874 | if (le16_to_cpu(ctx->active.channel) != ch) { | 2533 | if (le16_to_cpu(ctx->active.channel) == ch) |
2875 | ch_info = iwl_legacy_get_channel_info(priv, | 2534 | goto out; |
2876 | channel->band, | 2535 | |
2877 | ch); | 2536 | ch_info = iwl_legacy_get_channel_info(priv, channel->band, ch); |
2878 | if (!iwl_legacy_is_channel_valid(ch_info)) { | 2537 | if (!iwl_legacy_is_channel_valid(ch_info)) { |
2879 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); | 2538 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); |
2880 | goto out; | 2539 | goto out; |
2881 | } | 2540 | } |
2882 | spin_lock_irqsave(&priv->lock, flags); | 2541 | |
2883 | 2542 | spin_lock_irq(&priv->lock); | |
2884 | priv->current_ht_config.smps = conf->smps_mode; | 2543 | |
2885 | 2544 | priv->current_ht_config.smps = conf->smps_mode; | |
2886 | /* Configure HT40 channels */ | 2545 | |
2887 | ctx->ht.enabled = conf_is_ht(conf); | 2546 | /* Configure HT40 channels */ |
2888 | if (ctx->ht.enabled) { | 2547 | ctx->ht.enabled = conf_is_ht(conf); |
2889 | if (conf_is_ht40_minus(conf)) { | 2548 | if (ctx->ht.enabled) { |
2890 | ctx->ht.extension_chan_offset = | 2549 | if (conf_is_ht40_minus(conf)) { |
2891 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | 2550 | ctx->ht.extension_chan_offset = |
2892 | ctx->ht.is_40mhz = true; | 2551 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; |
2893 | } else if (conf_is_ht40_plus(conf)) { | 2552 | ctx->ht.is_40mhz = true; |
2894 | ctx->ht.extension_chan_offset = | 2553 | } else if (conf_is_ht40_plus(conf)) { |
2895 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | 2554 | ctx->ht.extension_chan_offset = |
2896 | ctx->ht.is_40mhz = true; | 2555 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; |
2897 | } else { | 2556 | ctx->ht.is_40mhz = true; |
2898 | ctx->ht.extension_chan_offset = | 2557 | } else { |
2899 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | 2558 | ctx->ht.extension_chan_offset = |
2900 | ctx->ht.is_40mhz = false; | 2559 | IEEE80211_HT_PARAM_CHA_SEC_NONE; |
2901 | } | 2560 | ctx->ht.is_40mhz = false; |
2902 | } else | ||
2903 | ctx->ht.is_40mhz = false; | ||
2904 | |||
2905 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | ||
2906 | ctx->staging.flags = 0; | ||
2907 | |||
2908 | iwl_legacy_set_rxon_channel(priv, channel, ctx); | ||
2909 | iwl_legacy_set_rxon_ht(priv, ht_conf); | ||
2910 | iwl_legacy_set_flags_for_band(priv, ctx, channel->band, | ||
2911 | ctx->vif); | ||
2912 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2913 | |||
2914 | iwl_legacy_set_rate(priv); | ||
2915 | /* | ||
2916 | * at this point, staging_rxon has the | ||
2917 | * configuration for channel switch | ||
2918 | */ | ||
2919 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); | ||
2920 | priv->switch_channel = cpu_to_le16(ch); | ||
2921 | if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) { | ||
2922 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, | ||
2923 | &priv->status); | ||
2924 | priv->switch_channel = 0; | ||
2925 | ieee80211_chswitch_done(ctx->vif, false); | ||
2926 | } | ||
2927 | } | 2561 | } |
2562 | } else | ||
2563 | ctx->ht.is_40mhz = false; | ||
2564 | |||
2565 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | ||
2566 | ctx->staging.flags = 0; | ||
2567 | |||
2568 | iwl_legacy_set_rxon_channel(priv, channel, ctx); | ||
2569 | iwl_legacy_set_rxon_ht(priv, ht_conf); | ||
2570 | iwl_legacy_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | ||
2571 | |||
2572 | spin_unlock_irq(&priv->lock); | ||
2573 | |||
2574 | iwl_legacy_set_rate(priv); | ||
2575 | /* | ||
2576 | * at this point, staging_rxon has the | ||
2577 | * configuration for channel switch | ||
2578 | */ | ||
2579 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); | ||
2580 | priv->switch_channel = cpu_to_le16(ch); | ||
2581 | if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) { | ||
2582 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); | ||
2583 | priv->switch_channel = 0; | ||
2584 | ieee80211_chswitch_done(ctx->vif, false); | ||
2928 | } | 2585 | } |
2586 | |||
2929 | out: | 2587 | out: |
2930 | mutex_unlock(&priv->mutex); | 2588 | mutex_unlock(&priv->mutex); |
2931 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2589 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
@@ -3034,10 +2692,6 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv) | |||
3034 | priv->statistics_periodic.data = (unsigned long)priv; | 2692 | priv->statistics_periodic.data = (unsigned long)priv; |
3035 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; | 2693 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; |
3036 | 2694 | ||
3037 | init_timer(&priv->ucode_trace); | ||
3038 | priv->ucode_trace.data = (unsigned long)priv; | ||
3039 | priv->ucode_trace.function = iwl4965_bg_ucode_trace; | ||
3040 | |||
3041 | init_timer(&priv->watchdog); | 2695 | init_timer(&priv->watchdog); |
3042 | priv->watchdog.data = (unsigned long)priv; | 2696 | priv->watchdog.data = (unsigned long)priv; |
3043 | priv->watchdog.function = iwl_legacy_bg_watchdog; | 2697 | priv->watchdog.function = iwl_legacy_bg_watchdog; |
@@ -3056,7 +2710,6 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) | |||
3056 | iwl_legacy_cancel_scan_deferred_work(priv); | 2710 | iwl_legacy_cancel_scan_deferred_work(priv); |
3057 | 2711 | ||
3058 | del_timer_sync(&priv->statistics_periodic); | 2712 | del_timer_sync(&priv->statistics_periodic); |
3059 | del_timer_sync(&priv->ucode_trace); | ||
3060 | } | 2713 | } |
3061 | 2714 | ||
3062 | static void iwl4965_init_hw_rates(struct iwl_priv *priv, | 2715 | static void iwl4965_init_hw_rates(struct iwl_priv *priv, |
@@ -3132,13 +2785,9 @@ static int iwl4965_init_drv(struct iwl_priv *priv) | |||
3132 | priv->iw_mode = NL80211_IFTYPE_STATION; | 2785 | priv->iw_mode = NL80211_IFTYPE_STATION; |
3133 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; | 2786 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; |
3134 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; | 2787 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; |
3135 | priv->_4965.agg_tids_count = 0; | ||
3136 | 2788 | ||
3137 | /* initialize force reset */ | 2789 | /* initialize force reset */ |
3138 | priv->force_reset[IWL_RF_RESET].reset_duration = | 2790 | priv->force_reset.reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD; |
3139 | IWL_DELAY_NEXT_FORCE_RF_RESET; | ||
3140 | priv->force_reset[IWL_FW_RESET].reset_duration = | ||
3141 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; | ||
3142 | 2791 | ||
3143 | /* Choose which receivers/antennas to use */ | 2792 | /* Choose which receivers/antennas to use */ |
3144 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 2793 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 822660483f9f..9a56ce546715 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -13,6 +13,7 @@ iwlagn-objs += iwl-5000.o | |||
13 | iwlagn-objs += iwl-6000.o | 13 | iwlagn-objs += iwl-6000.o |
14 | iwlagn-objs += iwl-1000.o | 14 | iwlagn-objs += iwl-1000.o |
15 | iwlagn-objs += iwl-2000.o | 15 | iwlagn-objs += iwl-2000.o |
16 | iwlagn-objs += iwl-pci.o | ||
16 | 17 | ||
17 | iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 18 | iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
18 | iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 19 | iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 7aa240e6ba1c..2daca80f086f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/pci.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
33 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
34 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
@@ -194,8 +192,6 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
194 | .temp_ops = { | 192 | .temp_ops = { |
195 | .temperature = iwlagn_temperature, | 193 | .temperature = iwlagn_temperature, |
196 | }, | 194 | }, |
197 | .txfifo_flush = iwlagn_txfifo_flush, | ||
198 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||
199 | }; | 195 | }; |
200 | 196 | ||
201 | static const struct iwl_ops iwl1000_ops = { | 197 | static const struct iwl_ops iwl1000_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 5484ab712da8..1c1330035ca9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/pci.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
33 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
34 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
@@ -76,21 +74,7 @@ static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | |||
76 | /* NIC configuration for 2000 series */ | 74 | /* NIC configuration for 2000 series */ |
77 | static void iwl2000_nic_config(struct iwl_priv *priv) | 75 | static void iwl2000_nic_config(struct iwl_priv *priv) |
78 | { | 76 | { |
79 | u16 radio_cfg; | 77 | iwl_rf_config(priv); |
80 | |||
81 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | ||
82 | |||
83 | /* write radio config values to register */ | ||
84 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) | ||
85 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
86 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | | ||
87 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | | ||
88 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
89 | |||
90 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
91 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
92 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
93 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
94 | 78 | ||
95 | if (priv->cfg->iq_invert) | 79 | if (priv->cfg->iq_invert) |
96 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, | 80 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, |
@@ -204,8 +188,6 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
204 | .temp_ops = { | 188 | .temp_ops = { |
205 | .temperature = iwlagn_temperature, | 189 | .temperature = iwlagn_temperature, |
206 | }, | 190 | }, |
207 | .txfifo_flush = iwlagn_txfifo_flush, | ||
208 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||
209 | }; | 191 | }; |
210 | 192 | ||
211 | static const struct iwl_ops iwl2000_ops = { | 193 | static const struct iwl_ops iwl2000_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 05ad47628b63..f9630a3c79fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h | |||
@@ -75,7 +75,7 @@ static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) | |||
75 | { | 75 | { |
76 | u16 temperature, voltage; | 76 | u16 temperature, voltage; |
77 | __le16 *temp_calib = | 77 | __le16 *temp_calib = |
78 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); | 78 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); |
79 | 79 | ||
80 | temperature = le16_to_cpu(temp_calib[0]); | 80 | temperature = le16_to_cpu(temp_calib[0]); |
81 | voltage = le16_to_cpu(temp_calib[1]); | 81 | voltage = le16_to_cpu(temp_calib[1]); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 4353a658de25..937a8f12afa7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/pci.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
33 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
34 | #include <linux/skbuff.h> | 32 | #include <linux/skbuff.h> |
@@ -66,23 +64,10 @@ | |||
66 | static void iwl5000_nic_config(struct iwl_priv *priv) | 64 | static void iwl5000_nic_config(struct iwl_priv *priv) |
67 | { | 65 | { |
68 | unsigned long flags; | 66 | unsigned long flags; |
69 | u16 radio_cfg; | ||
70 | 67 | ||
71 | spin_lock_irqsave(&priv->lock, flags); | 68 | iwl_rf_config(priv); |
72 | |||
73 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | ||
74 | 69 | ||
75 | /* write radio config values to register */ | 70 | spin_lock_irqsave(&priv->lock, flags); |
76 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_RF_CONFIG_TYPE_MAX) | ||
77 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
78 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | | ||
79 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | | ||
80 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
81 | |||
82 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
83 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
84 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
85 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
86 | 71 | ||
87 | /* W/A : NIC is stuck in a reset state after Early PCIe power off | 72 | /* W/A : NIC is stuck in a reset state after Early PCIe power off |
88 | * (PCIe power is lost before PERST# is asserted), | 73 | * (PCIe power is lost before PERST# is asserted), |
@@ -361,8 +346,6 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
361 | .temp_ops = { | 346 | .temp_ops = { |
362 | .temperature = iwlagn_temperature, | 347 | .temperature = iwlagn_temperature, |
363 | }, | 348 | }, |
364 | .txfifo_flush = iwlagn_txfifo_flush, | ||
365 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||
366 | }; | 349 | }; |
367 | 350 | ||
368 | static struct iwl_lib_ops iwl5150_lib = { | 351 | static struct iwl_lib_ops iwl5150_lib = { |
@@ -391,8 +374,6 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
391 | .temp_ops = { | 374 | .temp_ops = { |
392 | .temperature = iwl5150_temperature, | 375 | .temperature = iwl5150_temperature, |
393 | }, | 376 | }, |
394 | .txfifo_flush = iwlagn_txfifo_flush, | ||
395 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||
396 | }; | 377 | }; |
397 | 378 | ||
398 | static const struct iwl_ops iwl5000_ops = { | 379 | static const struct iwl_ops iwl5000_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 6e5ce4478490..3fcc0925d542 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/pci.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
33 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
34 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
@@ -97,21 +95,7 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) | |||
97 | /* NIC configuration for 6000 series */ | 95 | /* NIC configuration for 6000 series */ |
98 | static void iwl6000_nic_config(struct iwl_priv *priv) | 96 | static void iwl6000_nic_config(struct iwl_priv *priv) |
99 | { | 97 | { |
100 | u16 radio_cfg; | 98 | iwl_rf_config(priv); |
101 | |||
102 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | ||
103 | |||
104 | /* write radio config values to register */ | ||
105 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) | ||
106 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
107 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | | ||
108 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | | ||
109 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
110 | |||
111 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
112 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
113 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
114 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
115 | 99 | ||
116 | /* no locking required for register write */ | 100 | /* no locking required for register write */ |
117 | if (priv->cfg->pa_type == IWL_PA_INTERNAL) { | 101 | if (priv->cfg->pa_type == IWL_PA_INTERNAL) { |
@@ -301,8 +285,6 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
301 | .temp_ops = { | 285 | .temp_ops = { |
302 | .temperature = iwlagn_temperature, | 286 | .temperature = iwlagn_temperature, |
303 | }, | 287 | }, |
304 | .txfifo_flush = iwlagn_txfifo_flush, | ||
305 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||
306 | }; | 288 | }; |
307 | 289 | ||
308 | static struct iwl_lib_ops iwl6030_lib = { | 290 | static struct iwl_lib_ops iwl6030_lib = { |
@@ -333,8 +315,6 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
333 | .temp_ops = { | 315 | .temp_ops = { |
334 | .temperature = iwlagn_temperature, | 316 | .temperature = iwlagn_temperature, |
335 | }, | 317 | }, |
336 | .txfifo_flush = iwlagn_txfifo_flush, | ||
337 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||
338 | }; | 318 | }; |
339 | 319 | ||
340 | static struct iwl_nic_ops iwl6050_nic_ops = { | 320 | static struct iwl_nic_ops iwl6050_nic_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 2ef9448b1c20..7745816eaff4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | |||
@@ -108,18 +108,16 @@ err: | |||
108 | 108 | ||
109 | int iwl_eeprom_check_sku(struct iwl_priv *priv) | 109 | int iwl_eeprom_check_sku(struct iwl_priv *priv) |
110 | { | 110 | { |
111 | u16 eeprom_sku; | ||
112 | u16 radio_cfg; | 111 | u16 radio_cfg; |
113 | 112 | ||
114 | eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); | ||
115 | |||
116 | if (!priv->cfg->sku) { | 113 | if (!priv->cfg->sku) { |
117 | /* not using sku overwrite */ | 114 | /* not using sku overwrite */ |
118 | priv->cfg->sku = | 115 | priv->cfg->sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); |
119 | ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >> | 116 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE && |
120 | EEPROM_SKU_CAP_BAND_POS); | 117 | !priv->cfg->ht_params) { |
121 | if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE) | 118 | IWL_ERR(priv, "Invalid 11n configuration\n"); |
122 | priv->cfg->sku |= IWL_SKU_N; | 119 | return -EINVAL; |
120 | } | ||
123 | } | 121 | } |
124 | if (!priv->cfg->sku) { | 122 | if (!priv->cfg->sku) { |
125 | IWL_ERR(priv, "Invalid device sku\n"); | 123 | IWL_ERR(priv, "Invalid device sku\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 23eee0ca5b35..ba7ed9157c92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | |||
@@ -111,10 +111,8 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, | |||
111 | 111 | ||
112 | memset(&cmd, 0, sizeof(cmd)); | 112 | memset(&cmd, 0, sizeof(cmd)); |
113 | 113 | ||
114 | cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_gain_cmd; | 114 | iwl_set_calib_hdr(&cmd.hdr, |
115 | cmd.hdr.first_group = 0; | 115 | priv->_agn.phy_calib_chain_noise_gain_cmd); |
116 | cmd.hdr.groups_num = 1; | ||
117 | cmd.hdr.data_valid = 1; | ||
118 | cmd.delta_gain_1 = data->delta_gain_code[1]; | 116 | cmd.delta_gain_1 = data->delta_gain_code[1]; |
119 | cmd.delta_gain_2 = data->delta_gain_code[2]; | 117 | cmd.delta_gain_2 = data->delta_gain_code[2]; |
120 | iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, | 118 | iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, |
@@ -144,10 +142,8 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) | |||
144 | data->beacon_count = 0; | 142 | data->beacon_count = 0; |
145 | 143 | ||
146 | memset(&cmd, 0, sizeof(cmd)); | 144 | memset(&cmd, 0, sizeof(cmd)); |
147 | cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_reset_cmd; | 145 | iwl_set_calib_hdr(&cmd.hdr, |
148 | cmd.hdr.first_group = 0; | 146 | priv->_agn.phy_calib_chain_noise_reset_cmd); |
149 | cmd.hdr.groups_num = 1; | ||
150 | cmd.hdr.data_valid = 1; | ||
151 | ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, | 147 | ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, |
152 | sizeof(cmd), &cmd); | 148 | sizeof(cmd), &cmd); |
153 | if (ret) | 149 | if (ret) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index 7bd19f4e66de..0e5b842529c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h | |||
@@ -81,13 +81,6 @@ | |||
81 | /* RSSI to dBm */ | 81 | /* RSSI to dBm */ |
82 | #define IWLAGN_RSSI_OFFSET 44 | 82 | #define IWLAGN_RSSI_OFFSET 44 |
83 | 83 | ||
84 | /* PCI registers */ | ||
85 | #define PCI_CFG_RETRY_TIMEOUT 0x041 | ||
86 | |||
87 | /* PCI register values */ | ||
88 | #define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 | ||
89 | #define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 | ||
90 | |||
91 | #define IWLAGN_DEFAULT_TX_RETRY 15 | 84 | #define IWLAGN_DEFAULT_TX_RETRY 15 |
92 | 85 | ||
93 | /* Limit range of txpower output target to be between these values */ | 86 | /* Limit range of txpower output target to be between these values */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index 0d5fda44c3a3..f1b40ec1c873 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c | |||
@@ -44,7 +44,7 @@ | |||
44 | void iwl_free_isr_ict(struct iwl_priv *priv) | 44 | void iwl_free_isr_ict(struct iwl_priv *priv) |
45 | { | 45 | { |
46 | if (priv->_agn.ict_tbl_vir) { | 46 | if (priv->_agn.ict_tbl_vir) { |
47 | dma_free_coherent(&priv->pci_dev->dev, | 47 | dma_free_coherent(priv->bus.dev, |
48 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, | 48 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, |
49 | priv->_agn.ict_tbl_vir, | 49 | priv->_agn.ict_tbl_vir, |
50 | priv->_agn.ict_tbl_dma); | 50 | priv->_agn.ict_tbl_dma); |
@@ -61,7 +61,7 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv) | |||
61 | 61 | ||
62 | /* allocate shrared data table */ | 62 | /* allocate shrared data table */ |
63 | priv->_agn.ict_tbl_vir = | 63 | priv->_agn.ict_tbl_vir = |
64 | dma_alloc_coherent(&priv->pci_dev->dev, | 64 | dma_alloc_coherent(priv->bus.dev, |
65 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, | 65 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, |
66 | &priv->_agn.ict_tbl_dma, GFP_KERNEL); | 66 | &priv->_agn.ict_tbl_dma, GFP_KERNEL); |
67 | if (!priv->_agn.ict_tbl_vir) | 67 | if (!priv->_agn.ict_tbl_vir) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 677f73c4c1e3..efdab6506ae7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -438,7 +438,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | |||
438 | if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && | 438 | if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && |
439 | priv->cfg->bt_params && | 439 | priv->cfg->bt_params && |
440 | priv->cfg->bt_params->advanced_bt_coexist) { | 440 | priv->cfg->bt_params->advanced_bt_coexist) { |
441 | IWL_WARN(priv, "receive reply tx with bt_kill\n"); | 441 | IWL_DEBUG_COEX(priv, "receive reply tx with bt_kill\n"); |
442 | } | 442 | } |
443 | iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); | 443 | iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); |
444 | 444 | ||
@@ -622,6 +622,9 @@ struct iwl_mod_params iwlagn_mod_params = { | |||
622 | .amsdu_size_8K = 1, | 622 | .amsdu_size_8K = 1, |
623 | .restart_fw = 1, | 623 | .restart_fw = 1, |
624 | .plcp_check = true, | 624 | .plcp_check = true, |
625 | .bt_coex_active = true, | ||
626 | .no_sleep_autoadjust = true, | ||
627 | .power_level = IWL_POWER_INDEX_1, | ||
625 | /* the rest are 0 by default */ | 628 | /* the rest are 0 by default */ |
626 | }; | 629 | }; |
627 | 630 | ||
@@ -637,9 +640,9 @@ void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
637 | /* In the reset function, these buffers may have been allocated | 640 | /* In the reset function, these buffers may have been allocated |
638 | * to an SKB, so we need to unmap and free potential storage */ | 641 | * to an SKB, so we need to unmap and free potential storage */ |
639 | if (rxq->pool[i].page != NULL) { | 642 | if (rxq->pool[i].page != NULL) { |
640 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 643 | dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, |
641 | PAGE_SIZE << priv->hw_params.rx_page_order, | 644 | PAGE_SIZE << priv->hw_params.rx_page_order, |
642 | PCI_DMA_FROMDEVICE); | 645 | DMA_FROM_DEVICE); |
643 | __iwl_free_pages(priv, rxq->pool[i].page); | 646 | __iwl_free_pages(priv, rxq->pool[i].page); |
644 | rxq->pool[i].page = NULL; | 647 | rxq->pool[i].page = NULL; |
645 | } | 648 | } |
@@ -911,9 +914,9 @@ void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority) | |||
911 | BUG_ON(rxb->page); | 914 | BUG_ON(rxb->page); |
912 | rxb->page = page; | 915 | rxb->page = page; |
913 | /* Get physical address of the RB */ | 916 | /* Get physical address of the RB */ |
914 | rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, | 917 | rxb->page_dma = dma_map_page(priv->bus.dev, page, 0, |
915 | PAGE_SIZE << priv->hw_params.rx_page_order, | 918 | PAGE_SIZE << priv->hw_params.rx_page_order, |
916 | PCI_DMA_FROMDEVICE); | 919 | DMA_FROM_DEVICE); |
917 | /* dma address must be no more than 36 bits */ | 920 | /* dma address must be no more than 36 bits */ |
918 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); | 921 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); |
919 | /* and also 256 byte aligned! */ | 922 | /* and also 256 byte aligned! */ |
@@ -956,17 +959,18 @@ void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
956 | int i; | 959 | int i; |
957 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | 960 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { |
958 | if (rxq->pool[i].page != NULL) { | 961 | if (rxq->pool[i].page != NULL) { |
959 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 962 | dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, |
960 | PAGE_SIZE << priv->hw_params.rx_page_order, | 963 | PAGE_SIZE << priv->hw_params.rx_page_order, |
961 | PCI_DMA_FROMDEVICE); | 964 | DMA_FROM_DEVICE); |
962 | __iwl_free_pages(priv, rxq->pool[i].page); | 965 | __iwl_free_pages(priv, rxq->pool[i].page); |
963 | rxq->pool[i].page = NULL; | 966 | rxq->pool[i].page = NULL; |
964 | } | 967 | } |
965 | } | 968 | } |
966 | 969 | ||
967 | dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, | 970 | dma_free_coherent(priv->bus.dev, 4 * RX_QUEUE_SIZE, |
968 | rxq->bd_dma); | 971 | rxq->bd, rxq->bd_dma); |
969 | dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), | 972 | dma_free_coherent(priv->bus.dev, |
973 | sizeof(struct iwl_rb_status), | ||
970 | rxq->rb_stts, rxq->rb_stts_dma); | 974 | rxq->rb_stts, rxq->rb_stts_dma); |
971 | rxq->bd = NULL; | 975 | rxq->bd = NULL; |
972 | rxq->rb_stts = NULL; | 976 | rxq->rb_stts = NULL; |
@@ -1528,9 +1532,18 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
1528 | might_sleep(); | 1532 | might_sleep(); |
1529 | 1533 | ||
1530 | memset(&flush_cmd, 0, sizeof(flush_cmd)); | 1534 | memset(&flush_cmd, 0, sizeof(flush_cmd)); |
1531 | flush_cmd.fifo_control = IWL_TX_FIFO_VO_MSK | IWL_TX_FIFO_VI_MSK | | 1535 | if (flush_control & BIT(IWL_RXON_CTX_BSS)) |
1532 | IWL_TX_FIFO_BE_MSK | IWL_TX_FIFO_BK_MSK; | 1536 | flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | |
1533 | if (priv->cfg->sku & IWL_SKU_N) | 1537 | IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | |
1538 | IWL_SCD_MGMT_MSK; | ||
1539 | if ((flush_control & BIT(IWL_RXON_CTX_PAN)) && | ||
1540 | (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) | ||
1541 | flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | | ||
1542 | IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | | ||
1543 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | | ||
1544 | IWL_PAN_SCD_MULTICAST_MSK; | ||
1545 | |||
1546 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
1534 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; | 1547 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; |
1535 | 1548 | ||
1536 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", | 1549 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", |
@@ -1544,7 +1557,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
1544 | { | 1557 | { |
1545 | mutex_lock(&priv->mutex); | 1558 | mutex_lock(&priv->mutex); |
1546 | ieee80211_stop_queues(priv->hw); | 1559 | ieee80211_stop_queues(priv->hw); |
1547 | if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) { | 1560 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { |
1548 | IWL_ERR(priv, "flush request fail\n"); | 1561 | IWL_ERR(priv, "flush request fail\n"); |
1549 | goto done; | 1562 | goto done; |
1550 | } | 1563 | } |
@@ -1699,7 +1712,8 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
1699 | * (might be in monitor mode), or the interface is in | 1712 | * (might be in monitor mode), or the interface is in |
1700 | * IBSS mode (no proper uCode support for coex then). | 1713 | * IBSS mode (no proper uCode support for coex then). |
1701 | */ | 1714 | */ |
1702 | if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { | 1715 | if (!iwlagn_mod_params.bt_coex_active || |
1716 | priv->iw_mode == NL80211_IFTYPE_ADHOC) { | ||
1703 | basic.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; | 1717 | basic.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; |
1704 | } else { | 1718 | } else { |
1705 | basic.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << | 1719 | basic.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << |
@@ -1710,7 +1724,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
1710 | 1724 | ||
1711 | if (priv->bt_ch_announce) | 1725 | if (priv->bt_ch_announce) |
1712 | basic.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; | 1726 | basic.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; |
1713 | IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", basic.flags); | 1727 | IWL_DEBUG_COEX(priv, "BT coex flag: 0X%x\n", basic.flags); |
1714 | } | 1728 | } |
1715 | priv->bt_enable_flag = basic.flags; | 1729 | priv->bt_enable_flag = basic.flags; |
1716 | if (priv->bt_full_concurrent) | 1730 | if (priv->bt_full_concurrent) |
@@ -1720,7 +1734,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
1720 | memcpy(basic.bt3_lookup_table, iwlagn_def_3w_lookup, | 1734 | memcpy(basic.bt3_lookup_table, iwlagn_def_3w_lookup, |
1721 | sizeof(iwlagn_def_3w_lookup)); | 1735 | sizeof(iwlagn_def_3w_lookup)); |
1722 | 1736 | ||
1723 | IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", | 1737 | IWL_DEBUG_COEX(priv, "BT coex %s in %s mode\n", |
1724 | basic.flags ? "active" : "disabled", | 1738 | basic.flags ? "active" : "disabled", |
1725 | priv->bt_full_concurrent ? | 1739 | priv->bt_full_concurrent ? |
1726 | "full concurrency" : "3-wire"); | 1740 | "full concurrency" : "3-wire"); |
@@ -1758,7 +1772,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
1758 | * coex profile notifications. Ignore that since only bad consequence | 1772 | * coex profile notifications. Ignore that since only bad consequence |
1759 | * can be not matching debug print with actual state. | 1773 | * can be not matching debug print with actual state. |
1760 | */ | 1774 | */ |
1761 | IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", | 1775 | IWL_DEBUG_COEX(priv, "BT traffic load changes: %d\n", |
1762 | priv->bt_traffic_load); | 1776 | priv->bt_traffic_load); |
1763 | 1777 | ||
1764 | switch (priv->bt_traffic_load) { | 1778 | switch (priv->bt_traffic_load) { |
@@ -1810,7 +1824,7 @@ out: | |||
1810 | static void iwlagn_print_uartmsg(struct iwl_priv *priv, | 1824 | static void iwlagn_print_uartmsg(struct iwl_priv *priv, |
1811 | struct iwl_bt_uart_msg *uart_msg) | 1825 | struct iwl_bt_uart_msg *uart_msg) |
1812 | { | 1826 | { |
1813 | IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, " | 1827 | IWL_DEBUG_COEX(priv, "Message Type = 0x%X, SSN = 0x%X, " |
1814 | "Update Req = 0x%X", | 1828 | "Update Req = 0x%X", |
1815 | (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >> | 1829 | (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >> |
1816 | BT_UART_MSG_FRAME1MSGTYPE_POS, | 1830 | BT_UART_MSG_FRAME1MSGTYPE_POS, |
@@ -1819,7 +1833,7 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, | |||
1819 | (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >> | 1833 | (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >> |
1820 | BT_UART_MSG_FRAME1UPDATEREQ_POS); | 1834 | BT_UART_MSG_FRAME1UPDATEREQ_POS); |
1821 | 1835 | ||
1822 | IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, " | 1836 | IWL_DEBUG_COEX(priv, "Open connections = 0x%X, Traffic load = 0x%X, " |
1823 | "Chl_SeqN = 0x%X, In band = 0x%X", | 1837 | "Chl_SeqN = 0x%X, In band = 0x%X", |
1824 | (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >> | 1838 | (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >> |
1825 | BT_UART_MSG_FRAME2OPENCONNECTIONS_POS, | 1839 | BT_UART_MSG_FRAME2OPENCONNECTIONS_POS, |
@@ -1830,7 +1844,7 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, | |||
1830 | (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >> | 1844 | (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >> |
1831 | BT_UART_MSG_FRAME2INBAND_POS); | 1845 | BT_UART_MSG_FRAME2INBAND_POS); |
1832 | 1846 | ||
1833 | IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " | 1847 | IWL_DEBUG_COEX(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " |
1834 | "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X", | 1848 | "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X", |
1835 | (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> | 1849 | (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> |
1836 | BT_UART_MSG_FRAME3SCOESCO_POS, | 1850 | BT_UART_MSG_FRAME3SCOESCO_POS, |
@@ -1845,11 +1859,11 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, | |||
1845 | (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >> | 1859 | (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >> |
1846 | BT_UART_MSG_FRAME3OBEX_POS); | 1860 | BT_UART_MSG_FRAME3OBEX_POS); |
1847 | 1861 | ||
1848 | IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X", | 1862 | IWL_DEBUG_COEX(priv, "Idle duration = 0x%X", |
1849 | (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >> | 1863 | (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >> |
1850 | BT_UART_MSG_FRAME4IDLEDURATION_POS); | 1864 | BT_UART_MSG_FRAME4IDLEDURATION_POS); |
1851 | 1865 | ||
1852 | IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " | 1866 | IWL_DEBUG_COEX(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " |
1853 | "eSCO Retransmissions = 0x%X", | 1867 | "eSCO Retransmissions = 0x%X", |
1854 | (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >> | 1868 | (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >> |
1855 | BT_UART_MSG_FRAME5TXACTIVITY_POS, | 1869 | BT_UART_MSG_FRAME5TXACTIVITY_POS, |
@@ -1858,13 +1872,13 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, | |||
1858 | (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >> | 1872 | (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >> |
1859 | BT_UART_MSG_FRAME5ESCORETRANSMIT_POS); | 1873 | BT_UART_MSG_FRAME5ESCORETRANSMIT_POS); |
1860 | 1874 | ||
1861 | IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", | 1875 | IWL_DEBUG_COEX(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", |
1862 | (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >> | 1876 | (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >> |
1863 | BT_UART_MSG_FRAME6SNIFFINTERVAL_POS, | 1877 | BT_UART_MSG_FRAME6SNIFFINTERVAL_POS, |
1864 | (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> | 1878 | (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> |
1865 | BT_UART_MSG_FRAME6DISCOVERABLE_POS); | 1879 | BT_UART_MSG_FRAME6DISCOVERABLE_POS); |
1866 | 1880 | ||
1867 | IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Page = " | 1881 | IWL_DEBUG_COEX(priv, "Sniff Activity = 0x%X, Page = " |
1868 | "0x%X, Inquiry = 0x%X, Connectable = 0x%X", | 1882 | "0x%X, Inquiry = 0x%X, Connectable = 0x%X", |
1869 | (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> | 1883 | (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> |
1870 | BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, | 1884 | BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, |
@@ -1914,10 +1928,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | |||
1914 | return; | 1928 | return; |
1915 | } | 1929 | } |
1916 | 1930 | ||
1917 | IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); | 1931 | IWL_DEBUG_COEX(priv, "BT Coex notification:\n"); |
1918 | IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); | 1932 | IWL_DEBUG_COEX(priv, " status: %d\n", coex->bt_status); |
1919 | IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); | 1933 | IWL_DEBUG_COEX(priv, " traffic load: %d\n", coex->bt_traffic_load); |
1920 | IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", | 1934 | IWL_DEBUG_COEX(priv, " CI compliance: %d\n", |
1921 | coex->bt_ci_compliance); | 1935 | coex->bt_ci_compliance); |
1922 | iwlagn_print_uartmsg(priv, uart_msg); | 1936 | iwlagn_print_uartmsg(priv, uart_msg); |
1923 | 1937 | ||
@@ -2315,7 +2329,8 @@ int iwlagn_start_device(struct iwl_priv *priv) | |||
2315 | { | 2329 | { |
2316 | int ret; | 2330 | int ret; |
2317 | 2331 | ||
2318 | if (iwl_prepare_card_hw(priv)) { | 2332 | if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) && |
2333 | iwl_prepare_card_hw(priv)) { | ||
2319 | IWL_WARN(priv, "Exit HW not ready\n"); | 2334 | IWL_WARN(priv, "Exit HW not ready\n"); |
2320 | return -EIO; | 2335 | return -EIO; |
2321 | } | 2336 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 348f74f1c8e8..f501d742984c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c | |||
@@ -198,7 +198,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) | |||
198 | /* Reschedule the ct_kill timer to occur in | 198 | /* Reschedule the ct_kill timer to occur in |
199 | * CT_KILL_EXIT_DURATION seconds to ensure we get a | 199 | * CT_KILL_EXIT_DURATION seconds to ensure we get a |
200 | * thermal update */ | 200 | * thermal update */ |
201 | IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n"); | 201 | IWL_DEBUG_TEMP(priv, "schedule ct_kill exit timer\n"); |
202 | mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, | 202 | mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, |
203 | jiffies + CT_KILL_EXIT_DURATION * HZ); | 203 | jiffies + CT_KILL_EXIT_DURATION * HZ); |
204 | } | 204 | } |
@@ -208,15 +208,15 @@ static void iwl_perform_ct_kill_task(struct iwl_priv *priv, | |||
208 | bool stop) | 208 | bool stop) |
209 | { | 209 | { |
210 | if (stop) { | 210 | if (stop) { |
211 | IWL_DEBUG_POWER(priv, "Stop all queues\n"); | 211 | IWL_DEBUG_TEMP(priv, "Stop all queues\n"); |
212 | if (priv->mac80211_registered) | 212 | if (priv->mac80211_registered) |
213 | ieee80211_stop_queues(priv->hw); | 213 | ieee80211_stop_queues(priv->hw); |
214 | IWL_DEBUG_POWER(priv, | 214 | IWL_DEBUG_TEMP(priv, |
215 | "Schedule 5 seconds CT_KILL Timer\n"); | 215 | "Schedule 5 seconds CT_KILL Timer\n"); |
216 | mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, | 216 | mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, |
217 | jiffies + CT_KILL_EXIT_DURATION * HZ); | 217 | jiffies + CT_KILL_EXIT_DURATION * HZ); |
218 | } else { | 218 | } else { |
219 | IWL_DEBUG_POWER(priv, "Wake all queues\n"); | 219 | IWL_DEBUG_TEMP(priv, "Wake all queues\n"); |
220 | if (priv->mac80211_registered) | 220 | if (priv->mac80211_registered) |
221 | ieee80211_wake_queues(priv->hw); | 221 | ieee80211_wake_queues(priv->hw); |
222 | } | 222 | } |
@@ -232,7 +232,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) | |||
232 | 232 | ||
233 | /* temperature timer expired, ready to go into CT_KILL state */ | 233 | /* temperature timer expired, ready to go into CT_KILL state */ |
234 | if (tt->state != IWL_TI_CT_KILL) { | 234 | if (tt->state != IWL_TI_CT_KILL) { |
235 | IWL_DEBUG_POWER(priv, "entering CT_KILL state when " | 235 | IWL_DEBUG_TEMP(priv, "entering CT_KILL state when " |
236 | "temperature timer expired\n"); | 236 | "temperature timer expired\n"); |
237 | tt->state = IWL_TI_CT_KILL; | 237 | tt->state = IWL_TI_CT_KILL; |
238 | set_bit(STATUS_CT_KILL, &priv->status); | 238 | set_bit(STATUS_CT_KILL, &priv->status); |
@@ -242,7 +242,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) | |||
242 | 242 | ||
243 | static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) | 243 | static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) |
244 | { | 244 | { |
245 | IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); | 245 | IWL_DEBUG_TEMP(priv, "Prepare to enter IWL_TI_CT_KILL\n"); |
246 | /* make request to retrieve statistics information */ | 246 | /* make request to retrieve statistics information */ |
247 | iwl_send_statistics_request(priv, CMD_SYNC, false); | 247 | iwl_send_statistics_request(priv, CMD_SYNC, false); |
248 | /* Reschedule the ct_kill wait timer */ | 248 | /* Reschedule the ct_kill wait timer */ |
@@ -273,7 +273,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
273 | (temp > tt->tt_previous_temp) && | 273 | (temp > tt->tt_previous_temp) && |
274 | ((temp - tt->tt_previous_temp) > | 274 | ((temp - tt->tt_previous_temp) > |
275 | IWL_TT_INCREASE_MARGIN)) { | 275 | IWL_TT_INCREASE_MARGIN)) { |
276 | IWL_DEBUG_POWER(priv, | 276 | IWL_DEBUG_TEMP(priv, |
277 | "Temperature increase %d degree Celsius\n", | 277 | "Temperature increase %d degree Celsius\n", |
278 | (temp - tt->tt_previous_temp)); | 278 | (temp - tt->tt_previous_temp)); |
279 | } | 279 | } |
@@ -338,9 +338,9 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
338 | } else if (old_state == IWL_TI_CT_KILL && | 338 | } else if (old_state == IWL_TI_CT_KILL && |
339 | tt->state != IWL_TI_CT_KILL) | 339 | tt->state != IWL_TI_CT_KILL) |
340 | iwl_perform_ct_kill_task(priv, false); | 340 | iwl_perform_ct_kill_task(priv, false); |
341 | IWL_DEBUG_POWER(priv, "Temperature state changed %u\n", | 341 | IWL_DEBUG_TEMP(priv, "Temperature state changed %u\n", |
342 | tt->state); | 342 | tt->state); |
343 | IWL_DEBUG_POWER(priv, "Power Index change to %u\n", | 343 | IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", |
344 | tt->tt_power_mode); | 344 | tt->tt_power_mode); |
345 | } | 345 | } |
346 | mutex_unlock(&priv->mutex); | 346 | mutex_unlock(&priv->mutex); |
@@ -397,7 +397,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
397 | (temp > tt->tt_previous_temp) && | 397 | (temp > tt->tt_previous_temp) && |
398 | ((temp - tt->tt_previous_temp) > | 398 | ((temp - tt->tt_previous_temp) > |
399 | IWL_TT_INCREASE_MARGIN)) { | 399 | IWL_TT_INCREASE_MARGIN)) { |
400 | IWL_DEBUG_POWER(priv, | 400 | IWL_DEBUG_TEMP(priv, |
401 | "Temperature increase %d " | 401 | "Temperature increase %d " |
402 | "degree Celsius\n", | 402 | "degree Celsius\n", |
403 | (temp - tt->tt_previous_temp)); | 403 | (temp - tt->tt_previous_temp)); |
@@ -467,13 +467,13 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
467 | set_bit(STATUS_CT_KILL, &priv->status); | 467 | set_bit(STATUS_CT_KILL, &priv->status); |
468 | tt->state = old_state; | 468 | tt->state = old_state; |
469 | } else { | 469 | } else { |
470 | IWL_DEBUG_POWER(priv, | 470 | IWL_DEBUG_TEMP(priv, |
471 | "Thermal Throttling to new state: %u\n", | 471 | "Thermal Throttling to new state: %u\n", |
472 | tt->state); | 472 | tt->state); |
473 | if (old_state != IWL_TI_CT_KILL && | 473 | if (old_state != IWL_TI_CT_KILL && |
474 | tt->state == IWL_TI_CT_KILL) { | 474 | tt->state == IWL_TI_CT_KILL) { |
475 | if (force) { | 475 | if (force) { |
476 | IWL_DEBUG_POWER(priv, | 476 | IWL_DEBUG_TEMP(priv, |
477 | "Enter IWL_TI_CT_KILL\n"); | 477 | "Enter IWL_TI_CT_KILL\n"); |
478 | set_bit(STATUS_CT_KILL, &priv->status); | 478 | set_bit(STATUS_CT_KILL, &priv->status); |
479 | iwl_perform_ct_kill_task(priv, true); | 479 | iwl_perform_ct_kill_task(priv, true); |
@@ -483,7 +483,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
483 | } | 483 | } |
484 | } else if (old_state == IWL_TI_CT_KILL && | 484 | } else if (old_state == IWL_TI_CT_KILL && |
485 | tt->state != IWL_TI_CT_KILL) { | 485 | tt->state != IWL_TI_CT_KILL) { |
486 | IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n"); | 486 | IWL_DEBUG_TEMP(priv, "Exit IWL_TI_CT_KILL\n"); |
487 | iwl_perform_ct_kill_task(priv, false); | 487 | iwl_perform_ct_kill_task(priv, false); |
488 | } | 488 | } |
489 | } | 489 | } |
@@ -568,7 +568,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv) | |||
568 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 568 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
569 | return; | 569 | return; |
570 | 570 | ||
571 | IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); | 571 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); |
572 | queue_work(priv->workqueue, &priv->ct_enter); | 572 | queue_work(priv->workqueue, &priv->ct_enter); |
573 | } | 573 | } |
574 | 574 | ||
@@ -577,7 +577,7 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv) | |||
577 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 577 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
578 | return; | 578 | return; |
579 | 579 | ||
580 | IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); | 580 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); |
581 | queue_work(priv->workqueue, &priv->ct_exit); | 581 | queue_work(priv->workqueue, &priv->ct_exit); |
582 | } | 582 | } |
583 | 583 | ||
@@ -603,7 +603,7 @@ void iwl_tt_handler(struct iwl_priv *priv) | |||
603 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 603 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
604 | return; | 604 | return; |
605 | 605 | ||
606 | IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); | 606 | IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); |
607 | queue_work(priv->workqueue, &priv->tt_work); | 607 | queue_work(priv->workqueue, &priv->tt_work); |
608 | } | 608 | } |
609 | 609 | ||
@@ -618,7 +618,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) | |||
618 | int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); | 618 | int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); |
619 | struct iwl_tt_trans *transaction; | 619 | struct iwl_tt_trans *transaction; |
620 | 620 | ||
621 | IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n"); | 621 | IWL_DEBUG_TEMP(priv, "Initialize Thermal Throttling\n"); |
622 | 622 | ||
623 | memset(tt, 0, sizeof(struct iwl_tt_mgmt)); | 623 | memset(tt, 0, sizeof(struct iwl_tt_mgmt)); |
624 | 624 | ||
@@ -638,7 +638,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) | |||
638 | INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); | 638 | INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); |
639 | 639 | ||
640 | if (priv->cfg->base_params->adv_thermal_throttle) { | 640 | if (priv->cfg->base_params->adv_thermal_throttle) { |
641 | IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); | 641 | IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); |
642 | tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * | 642 | tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * |
643 | IWL_TI_STATE_MAX, GFP_KERNEL); | 643 | IWL_TI_STATE_MAX, GFP_KERNEL); |
644 | tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) * | 644 | tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) * |
@@ -671,7 +671,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) | |||
671 | priv->thermal_throttle.advanced_tt = true; | 671 | priv->thermal_throttle.advanced_tt = true; |
672 | } | 672 | } |
673 | } else { | 673 | } else { |
674 | IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); | 674 | IWL_DEBUG_TEMP(priv, "Legacy Thermal Throttling\n"); |
675 | priv->thermal_throttle.advanced_tt = false; | 675 | priv->thermal_throttle.advanced_tt = false; |
676 | } | 676 | } |
677 | } | 677 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 8bd48f61a9f5..d0ac090399e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -716,10 +716,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
716 | 716 | ||
717 | /* Physical address of this Tx command's header (not MAC header!), | 717 | /* Physical address of this Tx command's header (not MAC header!), |
718 | * within command buffer array. */ | 718 | * within command buffer array. */ |
719 | txcmd_phys = pci_map_single(priv->pci_dev, | 719 | txcmd_phys = dma_map_single(priv->bus.dev, |
720 | &out_cmd->hdr, firstlen, | 720 | &out_cmd->hdr, firstlen, |
721 | PCI_DMA_BIDIRECTIONAL); | 721 | DMA_BIDIRECTIONAL); |
722 | if (unlikely(pci_dma_mapping_error(priv->pci_dev, txcmd_phys))) | 722 | if (unlikely(dma_mapping_error(priv->bus.dev, txcmd_phys))) |
723 | goto drop_unlock_sta; | 723 | goto drop_unlock_sta; |
724 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | 724 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); |
725 | dma_unmap_len_set(out_meta, len, firstlen); | 725 | dma_unmap_len_set(out_meta, len, firstlen); |
@@ -735,13 +735,13 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
735 | * if any (802.11 null frames have no payload). */ | 735 | * if any (802.11 null frames have no payload). */ |
736 | secondlen = skb->len - hdr_len; | 736 | secondlen = skb->len - hdr_len; |
737 | if (secondlen > 0) { | 737 | if (secondlen > 0) { |
738 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, | 738 | phys_addr = dma_map_single(priv->bus.dev, skb->data + hdr_len, |
739 | secondlen, PCI_DMA_TODEVICE); | 739 | secondlen, DMA_TO_DEVICE); |
740 | if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { | 740 | if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) { |
741 | pci_unmap_single(priv->pci_dev, | 741 | dma_unmap_single(priv->bus.dev, |
742 | dma_unmap_addr(out_meta, mapping), | 742 | dma_unmap_addr(out_meta, mapping), |
743 | dma_unmap_len(out_meta, len), | 743 | dma_unmap_len(out_meta, len), |
744 | PCI_DMA_BIDIRECTIONAL); | 744 | DMA_BIDIRECTIONAL); |
745 | goto drop_unlock_sta; | 745 | goto drop_unlock_sta; |
746 | } | 746 | } |
747 | } | 747 | } |
@@ -764,8 +764,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
764 | offsetof(struct iwl_tx_cmd, scratch); | 764 | offsetof(struct iwl_tx_cmd, scratch); |
765 | 765 | ||
766 | /* take back ownership of DMA buffer to enable update */ | 766 | /* take back ownership of DMA buffer to enable update */ |
767 | pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys, | 767 | dma_sync_single_for_cpu(priv->bus.dev, txcmd_phys, firstlen, |
768 | firstlen, PCI_DMA_BIDIRECTIONAL); | 768 | DMA_BIDIRECTIONAL); |
769 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 769 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
770 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | 770 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); |
771 | 771 | ||
@@ -780,8 +780,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
780 | iwlagn_txq_update_byte_cnt_tbl(priv, txq, | 780 | iwlagn_txq_update_byte_cnt_tbl(priv, txq, |
781 | le16_to_cpu(tx_cmd->len)); | 781 | le16_to_cpu(tx_cmd->len)); |
782 | 782 | ||
783 | pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, | 783 | dma_sync_single_for_device(priv->bus.dev, txcmd_phys, firstlen, |
784 | firstlen, PCI_DMA_BIDIRECTIONAL); | 784 | DMA_BIDIRECTIONAL); |
785 | 785 | ||
786 | trace_iwlwifi_dev_tx(priv, | 786 | trace_iwlwifi_dev_tx(priv, |
787 | &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], | 787 | &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], |
@@ -834,8 +834,8 @@ drop_unlock_priv: | |||
834 | static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, | 834 | static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, |
835 | struct iwl_dma_ptr *ptr, size_t size) | 835 | struct iwl_dma_ptr *ptr, size_t size) |
836 | { | 836 | { |
837 | ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma, | 837 | ptr->addr = dma_alloc_coherent(priv->bus.dev, size, |
838 | GFP_KERNEL); | 838 | &ptr->dma, GFP_KERNEL); |
839 | if (!ptr->addr) | 839 | if (!ptr->addr) |
840 | return -ENOMEM; | 840 | return -ENOMEM; |
841 | ptr->size = size; | 841 | ptr->size = size; |
@@ -848,7 +848,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv, | |||
848 | if (unlikely(!ptr->addr)) | 848 | if (unlikely(!ptr->addr)) |
849 | return; | 849 | return; |
850 | 850 | ||
851 | dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma); | 851 | dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma); |
852 | memset(ptr, 0, sizeof(*ptr)); | 852 | memset(ptr, 0, sizeof(*ptr)); |
853 | } | 853 | } |
854 | 854 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 97de5d9de67b..de8277e32253 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -143,7 +143,7 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, | |||
143 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | 143 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | |
144 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | 144 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); |
145 | 145 | ||
146 | IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name); | 146 | IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name); |
147 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 147 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, |
148 | priv->ucode_write_complete, 5 * HZ); | 148 | priv->ucode_write_complete, 5 * HZ); |
149 | if (ret == -ERESTARTSYS) { | 149 | if (ret == -ERESTARTSYS) { |
@@ -183,10 +183,7 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv) | |||
183 | __le16 *xtal_calib = | 183 | __le16 *xtal_calib = |
184 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL); | 184 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL); |
185 | 185 | ||
186 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; | 186 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); |
187 | cmd.hdr.first_group = 0; | ||
188 | cmd.hdr.groups_num = 1; | ||
189 | cmd.hdr.data_valid = 1; | ||
190 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | 187 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
191 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); | 188 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); |
192 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], | 189 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], |
@@ -197,15 +194,14 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) | |||
197 | { | 194 | { |
198 | struct iwl_calib_temperature_offset_cmd cmd; | 195 | struct iwl_calib_temperature_offset_cmd cmd; |
199 | __le16 *offset_calib = | 196 | __le16 *offset_calib = |
200 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); | 197 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); |
201 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD; | 198 | |
202 | cmd.hdr.first_group = 0; | 199 | memset(&cmd, 0, sizeof(cmd)); |
203 | cmd.hdr.groups_num = 1; | 200 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
204 | cmd.hdr.data_valid = 1; | ||
205 | cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]); | 201 | cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]); |
206 | if (!(cmd.radio_sensor_offset)) | 202 | if (!(cmd.radio_sensor_offset)) |
207 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; | 203 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; |
208 | cmd.reserved = 0; | 204 | |
209 | IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", | 205 | IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", |
210 | cmd.radio_sensor_offset); | 206 | cmd.radio_sensor_offset); |
211 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET], | 207 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET], |
@@ -508,7 +504,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, | |||
508 | u32 val; | 504 | u32 val; |
509 | u32 i; | 505 | u32 i; |
510 | 506 | ||
511 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); | 507 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
512 | 508 | ||
513 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | 509 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { |
514 | /* read data comes through single port, auto-incr addr */ | 510 | /* read data comes through single port, auto-incr addr */ |
@@ -533,7 +529,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
533 | u32 offs; | 529 | u32 offs; |
534 | int errors = 0; | 530 | int errors = 0; |
535 | 531 | ||
536 | IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); | 532 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
537 | 533 | ||
538 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, | 534 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, |
539 | IWLAGN_RTC_INST_LOWER_BOUND); | 535 | IWLAGN_RTC_INST_LOWER_BOUND); |
@@ -559,7 +555,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
559 | static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img) | 555 | static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img) |
560 | { | 556 | { |
561 | if (!iwlcore_verify_inst_sparse(priv, &img->code)) { | 557 | if (!iwlcore_verify_inst_sparse(priv, &img->code)) { |
562 | IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n"); | 558 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); |
563 | return 0; | 559 | return 0; |
564 | } | 560 | } |
565 | 561 | ||
@@ -583,7 +579,7 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, | |||
583 | 579 | ||
584 | palive = &pkt->u.alive_frame; | 580 | palive = &pkt->u.alive_frame; |
585 | 581 | ||
586 | IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " | 582 | IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " |
587 | "0x%01X 0x%01X\n", | 583 | "0x%01X 0x%01X\n", |
588 | palive->is_valid, palive->ver_type, | 584 | palive->is_valid, palive->ver_type, |
589 | palive->ver_subtype); | 585 | palive->ver_subtype); |
@@ -602,12 +598,12 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, | |||
602 | 598 | ||
603 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | 599 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, |
604 | struct fw_img *image, | 600 | struct fw_img *image, |
605 | int subtype, int alternate_subtype) | 601 | enum iwlagn_ucode_type ucode_type) |
606 | { | 602 | { |
607 | struct iwl_notification_wait alive_wait; | 603 | struct iwl_notification_wait alive_wait; |
608 | struct iwlagn_alive_data alive_data; | 604 | struct iwlagn_alive_data alive_data; |
609 | int ret; | 605 | int ret; |
610 | enum iwlagn_ucode_subtype old_type; | 606 | enum iwlagn_ucode_type old_type; |
611 | 607 | ||
612 | ret = iwlagn_start_device(priv); | 608 | ret = iwlagn_start_device(priv); |
613 | if (ret) | 609 | if (ret) |
@@ -617,7 +613,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
617 | iwlagn_alive_fn, &alive_data); | 613 | iwlagn_alive_fn, &alive_data); |
618 | 614 | ||
619 | old_type = priv->ucode_type; | 615 | old_type = priv->ucode_type; |
620 | priv->ucode_type = subtype; | 616 | priv->ucode_type = ucode_type; |
621 | 617 | ||
622 | ret = iwlagn_load_given_ucode(priv, image); | 618 | ret = iwlagn_load_given_ucode(priv, image); |
623 | if (ret) { | 619 | if (ret) { |
@@ -645,15 +641,6 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
645 | return -EIO; | 641 | return -EIO; |
646 | } | 642 | } |
647 | 643 | ||
648 | if (alive_data.subtype != subtype && | ||
649 | alive_data.subtype != alternate_subtype) { | ||
650 | IWL_ERR(priv, | ||
651 | "Loaded ucode is not expected type (got %d, expected %d)!\n", | ||
652 | alive_data.subtype, subtype); | ||
653 | priv->ucode_type = old_type; | ||
654 | return -EIO; | ||
655 | } | ||
656 | |||
657 | ret = iwl_verify_ucode(priv, image); | 644 | ret = iwl_verify_ucode(priv, image); |
658 | if (ret) { | 645 | if (ret) { |
659 | priv->ucode_type = old_type; | 646 | priv->ucode_type = old_type; |
@@ -685,7 +672,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
685 | if (!priv->ucode_init.code.len) | 672 | if (!priv->ucode_init.code.len) |
686 | return 0; | 673 | return 0; |
687 | 674 | ||
688 | if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED) | 675 | if (priv->ucode_type != IWL_UCODE_NONE) |
689 | return 0; | 676 | return 0; |
690 | 677 | ||
691 | iwlagn_init_notification_wait(priv, &calib_wait, | 678 | iwlagn_init_notification_wait(priv, &calib_wait, |
@@ -694,7 +681,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
694 | 681 | ||
695 | /* Will also start the device */ | 682 | /* Will also start the device */ |
696 | ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, | 683 | ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, |
697 | UCODE_SUBTYPE_INIT, -1); | 684 | IWL_UCODE_INIT); |
698 | if (ret) | 685 | if (ret) |
699 | goto error; | 686 | goto error; |
700 | 687 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 099c2795ec0b..77ceb8deff75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/pci.h> | ||
36 | #include <linux/pci-aspm.h> | ||
37 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
38 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
39 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
@@ -49,8 +47,6 @@ | |||
49 | 47 | ||
50 | #include <asm/div64.h> | 48 | #include <asm/div64.h> |
51 | 49 | ||
52 | #define DRV_NAME "iwlagn" | ||
53 | |||
54 | #include "iwl-eeprom.h" | 50 | #include "iwl-eeprom.h" |
55 | #include "iwl-dev.h" | 51 | #include "iwl-dev.h" |
56 | #include "iwl-core.h" | 52 | #include "iwl-core.h" |
@@ -59,6 +55,7 @@ | |||
59 | #include "iwl-sta.h" | 55 | #include "iwl-sta.h" |
60 | #include "iwl-agn-calib.h" | 56 | #include "iwl-agn-calib.h" |
61 | #include "iwl-agn.h" | 57 | #include "iwl-agn.h" |
58 | #include "iwl-pci.h" | ||
62 | 59 | ||
63 | 60 | ||
64 | /****************************************************************************** | 61 | /****************************************************************************** |
@@ -440,10 +437,8 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
440 | if (!iwl_is_ready_rf(priv)) | 437 | if (!iwl_is_ready_rf(priv)) |
441 | return; | 438 | return; |
442 | 439 | ||
443 | if (priv->cfg->ops->lib->txfifo_flush) { | 440 | IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); |
444 | IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); | 441 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
445 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | ||
446 | } | ||
447 | } | 442 | } |
448 | 443 | ||
449 | /** | 444 | /** |
@@ -497,9 +492,9 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
497 | 492 | ||
498 | rxq->queue[i] = NULL; | 493 | rxq->queue[i] = NULL; |
499 | 494 | ||
500 | pci_unmap_page(priv->pci_dev, rxb->page_dma, | 495 | dma_unmap_page(priv->bus.dev, rxb->page_dma, |
501 | PAGE_SIZE << priv->hw_params.rx_page_order, | 496 | PAGE_SIZE << priv->hw_params.rx_page_order, |
502 | PCI_DMA_FROMDEVICE); | 497 | DMA_FROM_DEVICE); |
503 | pkt = rxb_addr(rxb); | 498 | pkt = rxb_addr(rxb); |
504 | 499 | ||
505 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 500 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
@@ -581,9 +576,9 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
581 | * rx_free list for reuse later. */ | 576 | * rx_free list for reuse later. */ |
582 | spin_lock_irqsave(&rxq->lock, flags); | 577 | spin_lock_irqsave(&rxq->lock, flags); |
583 | if (rxb->page != NULL) { | 578 | if (rxb->page != NULL) { |
584 | rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, | 579 | rxb->page_dma = dma_map_page(priv->bus.dev, rxb->page, |
585 | 0, PAGE_SIZE << priv->hw_params.rx_page_order, | 580 | 0, PAGE_SIZE << priv->hw_params.rx_page_order, |
586 | PCI_DMA_FROMDEVICE); | 581 | DMA_FROM_DEVICE); |
587 | list_add_tail(&rxb->list, &rxq->rx_free); | 582 | list_add_tail(&rxb->list, &rxq->rx_free); |
588 | rxq->free_count++; | 583 | rxq->free_count++; |
589 | } else | 584 | } else |
@@ -939,22 +934,28 @@ static struct attribute_group iwl_attribute_group = { | |||
939 | * | 934 | * |
940 | ******************************************************************************/ | 935 | ******************************************************************************/ |
941 | 936 | ||
942 | static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) | 937 | static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc) |
943 | { | 938 | { |
944 | if (desc->v_addr) | 939 | if (desc->v_addr) |
945 | dma_free_coherent(&pci_dev->dev, desc->len, | 940 | dma_free_coherent(priv->bus.dev, desc->len, |
946 | desc->v_addr, desc->p_addr); | 941 | desc->v_addr, desc->p_addr); |
947 | desc->v_addr = NULL; | 942 | desc->v_addr = NULL; |
948 | desc->len = 0; | 943 | desc->len = 0; |
949 | } | 944 | } |
950 | 945 | ||
951 | static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img) | 946 | static void iwl_free_fw_img(struct iwl_priv *priv, struct fw_img *img) |
952 | { | 947 | { |
953 | iwl_free_fw_desc(pci_dev, &img->code); | 948 | iwl_free_fw_desc(priv, &img->code); |
954 | iwl_free_fw_desc(pci_dev, &img->data); | 949 | iwl_free_fw_desc(priv, &img->data); |
955 | } | 950 | } |
956 | 951 | ||
957 | static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc, | 952 | static void iwl_dealloc_ucode(struct iwl_priv *priv) |
953 | { | ||
954 | iwl_free_fw_img(priv, &priv->ucode_rt); | ||
955 | iwl_free_fw_img(priv, &priv->ucode_init); | ||
956 | } | ||
957 | |||
958 | static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc, | ||
958 | const void *data, size_t len) | 959 | const void *data, size_t len) |
959 | { | 960 | { |
960 | if (!len) { | 961 | if (!len) { |
@@ -962,21 +963,16 @@ static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc, | |||
962 | return -EINVAL; | 963 | return -EINVAL; |
963 | } | 964 | } |
964 | 965 | ||
965 | desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len, | 966 | desc->v_addr = dma_alloc_coherent(priv->bus.dev, len, |
966 | &desc->p_addr, GFP_KERNEL); | 967 | &desc->p_addr, GFP_KERNEL); |
967 | if (!desc->v_addr) | 968 | if (!desc->v_addr) |
968 | return -ENOMEM; | 969 | return -ENOMEM; |
970 | |||
969 | desc->len = len; | 971 | desc->len = len; |
970 | memcpy(desc->v_addr, data, len); | 972 | memcpy(desc->v_addr, data, len); |
971 | return 0; | 973 | return 0; |
972 | } | 974 | } |
973 | 975 | ||
974 | static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) | ||
975 | { | ||
976 | iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt); | ||
977 | iwl_free_fw_img(priv->pci_dev, &priv->ucode_init); | ||
978 | } | ||
979 | |||
980 | struct iwlagn_ucode_capabilities { | 976 | struct iwlagn_ucode_capabilities { |
981 | u32 max_probe_length; | 977 | u32 max_probe_length; |
982 | u32 standard_phy_calibration_size; | 978 | u32 standard_phy_calibration_size; |
@@ -1021,8 +1017,8 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) | |||
1021 | priv->firmware_name); | 1017 | priv->firmware_name); |
1022 | 1018 | ||
1023 | return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, | 1019 | return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, |
1024 | &priv->pci_dev->dev, GFP_KERNEL, priv, | 1020 | priv->bus.dev, |
1025 | iwl_ucode_callback); | 1021 | GFP_KERNEL, priv, iwl_ucode_callback); |
1026 | } | 1022 | } |
1027 | 1023 | ||
1028 | struct iwlagn_firmware_pieces { | 1024 | struct iwlagn_firmware_pieces { |
@@ -1443,19 +1439,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1443 | /* Runtime instructions and 2 copies of data: | 1439 | /* Runtime instructions and 2 copies of data: |
1444 | * 1) unmodified from disk | 1440 | * 1) unmodified from disk |
1445 | * 2) backup cache for save/restore during power-downs */ | 1441 | * 2) backup cache for save/restore during power-downs */ |
1446 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code, | 1442 | if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.code, |
1447 | pieces.inst, pieces.inst_size)) | 1443 | pieces.inst, pieces.inst_size)) |
1448 | goto err_pci_alloc; | 1444 | goto err_pci_alloc; |
1449 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data, | 1445 | if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.data, |
1450 | pieces.data, pieces.data_size)) | 1446 | pieces.data, pieces.data_size)) |
1451 | goto err_pci_alloc; | 1447 | goto err_pci_alloc; |
1452 | 1448 | ||
1453 | /* Initialization instructions and data */ | 1449 | /* Initialization instructions and data */ |
1454 | if (pieces.init_size && pieces.init_data_size) { | 1450 | if (pieces.init_size && pieces.init_data_size) { |
1455 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code, | 1451 | if (iwl_alloc_fw_desc(priv, &priv->ucode_init.code, |
1456 | pieces.init, pieces.init_size)) | 1452 | pieces.init, pieces.init_size)) |
1457 | goto err_pci_alloc; | 1453 | goto err_pci_alloc; |
1458 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data, | 1454 | if (iwl_alloc_fw_desc(priv, &priv->ucode_init.data, |
1459 | pieces.init_data, pieces.init_data_size)) | 1455 | pieces.init_data, pieces.init_data_size)) |
1460 | goto err_pci_alloc; | 1456 | goto err_pci_alloc; |
1461 | } | 1457 | } |
@@ -1485,7 +1481,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1485 | priv->new_scan_threshold_behaviour = | 1481 | priv->new_scan_threshold_behaviour = |
1486 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | 1482 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); |
1487 | 1483 | ||
1488 | if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { | 1484 | if ((priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE) && |
1485 | (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) { | ||
1489 | priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); | 1486 | priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); |
1490 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | 1487 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; |
1491 | } else | 1488 | } else |
@@ -1523,7 +1520,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1523 | if (err) | 1520 | if (err) |
1524 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | 1521 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); |
1525 | 1522 | ||
1526 | err = sysfs_create_group(&priv->pci_dev->dev.kobj, | 1523 | err = sysfs_create_group(&(priv->bus.dev->kobj), |
1527 | &iwl_attribute_group); | 1524 | &iwl_attribute_group); |
1528 | if (err) { | 1525 | if (err) { |
1529 | IWL_ERR(priv, "failed to create sysfs device attributes\n"); | 1526 | IWL_ERR(priv, "failed to create sysfs device attributes\n"); |
@@ -1544,10 +1541,10 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1544 | 1541 | ||
1545 | err_pci_alloc: | 1542 | err_pci_alloc: |
1546 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 1543 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
1547 | iwl_dealloc_ucode_pci(priv); | 1544 | iwl_dealloc_ucode(priv); |
1548 | out_unbind: | 1545 | out_unbind: |
1549 | complete(&priv->_agn.firmware_loading_complete); | 1546 | complete(&priv->_agn.firmware_loading_complete); |
1550 | device_release_driver(&priv->pci_dev->dev); | 1547 | device_release_driver(priv->bus.dev); |
1551 | release_firmware(ucode_raw); | 1548 | release_firmware(ucode_raw); |
1552 | } | 1549 | } |
1553 | 1550 | ||
@@ -1626,7 +1623,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1626 | struct iwl_error_event_table table; | 1623 | struct iwl_error_event_table table; |
1627 | 1624 | ||
1628 | base = priv->device_pointers.error_event_table; | 1625 | base = priv->device_pointers.error_event_table; |
1629 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { | 1626 | if (priv->ucode_type == IWL_UCODE_INIT) { |
1630 | if (!base) | 1627 | if (!base) |
1631 | base = priv->_agn.init_errlog_ptr; | 1628 | base = priv->_agn.init_errlog_ptr; |
1632 | } else { | 1629 | } else { |
@@ -1638,7 +1635,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1638 | IWL_ERR(priv, | 1635 | IWL_ERR(priv, |
1639 | "Not valid error log pointer 0x%08X for %s uCode\n", | 1636 | "Not valid error log pointer 0x%08X for %s uCode\n", |
1640 | base, | 1637 | base, |
1641 | (priv->ucode_type == UCODE_SUBTYPE_INIT) | 1638 | (priv->ucode_type == IWL_UCODE_INIT) |
1642 | ? "Init" : "RT"); | 1639 | ? "Init" : "RT"); |
1643 | return; | 1640 | return; |
1644 | } | 1641 | } |
@@ -1702,7 +1699,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1702 | return pos; | 1699 | return pos; |
1703 | 1700 | ||
1704 | base = priv->device_pointers.log_event_table; | 1701 | base = priv->device_pointers.log_event_table; |
1705 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { | 1702 | if (priv->ucode_type == IWL_UCODE_INIT) { |
1706 | if (!base) | 1703 | if (!base) |
1707 | base = priv->_agn.init_evtlog_ptr; | 1704 | base = priv->_agn.init_evtlog_ptr; |
1708 | } else { | 1705 | } else { |
@@ -1815,7 +1812,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
1815 | size_t bufsz = 0; | 1812 | size_t bufsz = 0; |
1816 | 1813 | ||
1817 | base = priv->device_pointers.log_event_table; | 1814 | base = priv->device_pointers.log_event_table; |
1818 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { | 1815 | if (priv->ucode_type == IWL_UCODE_INIT) { |
1819 | logsize = priv->_agn.init_evtlog_size; | 1816 | logsize = priv->_agn.init_evtlog_size; |
1820 | if (!base) | 1817 | if (!base) |
1821 | base = priv->_agn.init_evtlog_ptr; | 1818 | base = priv->_agn.init_evtlog_ptr; |
@@ -1829,7 +1826,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
1829 | IWL_ERR(priv, | 1826 | IWL_ERR(priv, |
1830 | "Invalid event log pointer 0x%08X for %s uCode\n", | 1827 | "Invalid event log pointer 0x%08X for %s uCode\n", |
1831 | base, | 1828 | base, |
1832 | (priv->ucode_type == UCODE_SUBTYPE_INIT) | 1829 | (priv->ucode_type == IWL_UCODE_INIT) |
1833 | ? "Init" : "RT"); | 1830 | ? "Init" : "RT"); |
1834 | return -EINVAL; | 1831 | return -EINVAL; |
1835 | } | 1832 | } |
@@ -2210,8 +2207,7 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2210 | 2207 | ||
2211 | ret = iwlagn_load_ucode_wait_alive(priv, | 2208 | ret = iwlagn_load_ucode_wait_alive(priv, |
2212 | &priv->ucode_rt, | 2209 | &priv->ucode_rt, |
2213 | UCODE_SUBTYPE_REGULAR, | 2210 | IWL_UCODE_REGULAR); |
2214 | UCODE_SUBTYPE_REGULAR_NEW); | ||
2215 | if (ret) { | 2211 | if (ret) { |
2216 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | 2212 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); |
2217 | goto error; | 2213 | goto error; |
@@ -2516,7 +2512,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
2516 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | 2512 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | |
2517 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 2513 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; |
2518 | 2514 | ||
2519 | if (priv->cfg->sku & IWL_SKU_N) | 2515 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) |
2520 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 2516 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
2521 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | 2517 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; |
2522 | 2518 | ||
@@ -2549,11 +2545,10 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
2549 | WIPHY_FLAG_DISABLE_BEACON_HINTS | | 2545 | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
2550 | WIPHY_FLAG_IBSS_RSN; | 2546 | WIPHY_FLAG_IBSS_RSN; |
2551 | 2547 | ||
2552 | /* | 2548 | if (iwlagn_mod_params.power_save) |
2553 | * For now, disable PS by default because it affects | 2549 | hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; |
2554 | * RX performance significantly. | 2550 | else |
2555 | */ | 2551 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
2556 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
2557 | 2552 | ||
2558 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | 2553 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; |
2559 | /* we create the 802.11 header and a zero-length SSID element */ | 2554 | /* we create the 802.11 header and a zero-length SSID element */ |
@@ -2757,7 +2752,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
2757 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | 2752 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", |
2758 | sta->addr, tid); | 2753 | sta->addr, tid); |
2759 | 2754 | ||
2760 | if (!(priv->cfg->sku & IWL_SKU_N)) | 2755 | if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) |
2761 | return -EACCES; | 2756 | return -EACCES; |
2762 | 2757 | ||
2763 | mutex_lock(&priv->mutex); | 2758 | mutex_lock(&priv->mutex); |
@@ -3052,10 +3047,6 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
3052 | mutex_lock(&priv->mutex); | 3047 | mutex_lock(&priv->mutex); |
3053 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 3048 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
3054 | 3049 | ||
3055 | /* do not support "flush" */ | ||
3056 | if (!priv->cfg->ops->lib->txfifo_flush) | ||
3057 | goto done; | ||
3058 | |||
3059 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 3050 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
3060 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); | 3051 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); |
3061 | goto done; | 3052 | goto done; |
@@ -3071,7 +3062,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
3071 | */ | 3062 | */ |
3072 | if (drop) { | 3063 | if (drop) { |
3073 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); | 3064 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); |
3074 | if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) { | 3065 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { |
3075 | IWL_ERR(priv, "flush request fail\n"); | 3066 | IWL_ERR(priv, "flush request fail\n"); |
3076 | goto done; | 3067 | goto done; |
3077 | } | 3068 | } |
@@ -3352,14 +3343,11 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
3352 | .offchannel_tx = iwl_mac_offchannel_tx, | 3343 | .offchannel_tx = iwl_mac_offchannel_tx, |
3353 | .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, | 3344 | .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, |
3354 | CFG80211_TESTMODE_CMD(iwl_testmode_cmd) | 3345 | CFG80211_TESTMODE_CMD(iwl_testmode_cmd) |
3346 | CFG80211_TESTMODE_DUMP(iwl_testmode_dump) | ||
3355 | }; | 3347 | }; |
3356 | 3348 | ||
3357 | static u32 iwl_hw_detect(struct iwl_priv *priv) | 3349 | static u32 iwl_hw_detect(struct iwl_priv *priv) |
3358 | { | 3350 | { |
3359 | u8 rev_id; | ||
3360 | |||
3361 | pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); | ||
3362 | IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); | ||
3363 | return iwl_read32(priv, CSR_HW_REV); | 3351 | return iwl_read32(priv, CSR_HW_REV); |
3364 | } | 3352 | } |
3365 | 3353 | ||
@@ -3375,7 +3363,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
3375 | priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; | 3363 | priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; |
3376 | 3364 | ||
3377 | if (iwlagn_mod_params.disable_11n) | 3365 | if (iwlagn_mod_params.disable_11n) |
3378 | priv->cfg->sku &= ~IWL_SKU_N; | 3366 | priv->cfg->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; |
3379 | 3367 | ||
3380 | /* Device-specific setup */ | 3368 | /* Device-specific setup */ |
3381 | return priv->cfg->ops->lib->set_hw_params(priv); | 3369 | return priv->cfg->ops->lib->set_hw_params(priv); |
@@ -3425,29 +3413,9 @@ out: | |||
3425 | return hw; | 3413 | return hw; |
3426 | } | 3414 | } |
3427 | 3415 | ||
3428 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 3416 | static void iwl_init_context(struct iwl_priv *priv) |
3429 | { | 3417 | { |
3430 | int err = 0, i; | 3418 | int i; |
3431 | struct iwl_priv *priv; | ||
3432 | struct ieee80211_hw *hw; | ||
3433 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | ||
3434 | unsigned long flags; | ||
3435 | u16 pci_cmd, num_mac; | ||
3436 | u32 hw_rev; | ||
3437 | |||
3438 | /************************ | ||
3439 | * 1. Allocating HW data | ||
3440 | ************************/ | ||
3441 | |||
3442 | hw = iwl_alloc_all(cfg); | ||
3443 | if (!hw) { | ||
3444 | err = -ENOMEM; | ||
3445 | goto out; | ||
3446 | } | ||
3447 | priv = hw->priv; | ||
3448 | /* At this point both hw and priv are allocated. */ | ||
3449 | |||
3450 | priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED; | ||
3451 | 3419 | ||
3452 | /* | 3420 | /* |
3453 | * The default context is always valid, | 3421 | * The default context is always valid, |
@@ -3479,8 +3447,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3479 | priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; | 3447 | priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; |
3480 | 3448 | ||
3481 | priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; | 3449 | priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; |
3482 | priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; | 3450 | priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = |
3483 | priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = REPLY_WIPAN_RXON_ASSOC; | 3451 | REPLY_WIPAN_RXON_TIMING; |
3452 | priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = | ||
3453 | REPLY_WIPAN_RXON_ASSOC; | ||
3484 | priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM; | 3454 | priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM; |
3485 | priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN; | 3455 | priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN; |
3486 | priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; | 3456 | priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; |
@@ -3500,12 +3470,41 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3500 | priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; | 3470 | priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; |
3501 | 3471 | ||
3502 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 3472 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
3473 | } | ||
3474 | |||
3475 | int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, | ||
3476 | struct iwl_cfg *cfg) | ||
3477 | { | ||
3478 | int err = 0; | ||
3479 | struct iwl_priv *priv; | ||
3480 | struct ieee80211_hw *hw; | ||
3481 | u16 num_mac; | ||
3482 | u32 hw_rev; | ||
3503 | 3483 | ||
3504 | SET_IEEE80211_DEV(hw, &pdev->dev); | 3484 | /************************ |
3485 | * 1. Allocating HW data | ||
3486 | ************************/ | ||
3487 | hw = iwl_alloc_all(cfg); | ||
3488 | if (!hw) { | ||
3489 | err = -ENOMEM; | ||
3490 | goto out; | ||
3491 | } | ||
3492 | |||
3493 | priv = hw->priv; | ||
3494 | |||
3495 | priv->bus.priv = priv; | ||
3496 | priv->bus.bus_specific = bus_specific; | ||
3497 | priv->bus.ops = bus_ops; | ||
3498 | priv->bus.irq = priv->bus.ops->get_irq(&priv->bus); | ||
3499 | priv->bus.ops->set_drv_data(&priv->bus, priv); | ||
3500 | priv->bus.dev = priv->bus.ops->get_dev(&priv->bus); | ||
3501 | |||
3502 | /* At this point both hw and priv are allocated. */ | ||
3503 | |||
3504 | SET_IEEE80211_DEV(hw, priv->bus.dev); | ||
3505 | 3505 | ||
3506 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); | 3506 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); |
3507 | priv->cfg = cfg; | 3507 | priv->cfg = cfg; |
3508 | priv->pci_dev = pdev; | ||
3509 | priv->inta_mask = CSR_INI_SET_MASK; | 3508 | priv->inta_mask = CSR_INI_SET_MASK; |
3510 | 3509 | ||
3511 | /* is antenna coupling more than 35dB ? */ | 3510 | /* is antenna coupling more than 35dB ? */ |
@@ -3521,52 +3520,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3521 | if (iwl_alloc_traffic_mem(priv)) | 3520 | if (iwl_alloc_traffic_mem(priv)) |
3522 | IWL_ERR(priv, "Not enough memory to generate traffic log\n"); | 3521 | IWL_ERR(priv, "Not enough memory to generate traffic log\n"); |
3523 | 3522 | ||
3524 | /************************** | ||
3525 | * 2. Initializing PCI bus | ||
3526 | **************************/ | ||
3527 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | ||
3528 | PCIE_LINK_STATE_CLKPM); | ||
3529 | |||
3530 | if (pci_enable_device(pdev)) { | ||
3531 | err = -ENODEV; | ||
3532 | goto out_ieee80211_free_hw; | ||
3533 | } | ||
3534 | |||
3535 | pci_set_master(pdev); | ||
3536 | |||
3537 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
3538 | if (!err) | ||
3539 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
3540 | if (err) { | ||
3541 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
3542 | if (!err) | ||
3543 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
3544 | /* both attempts failed: */ | ||
3545 | if (err) { | ||
3546 | IWL_WARN(priv, "No suitable DMA available.\n"); | ||
3547 | goto out_pci_disable_device; | ||
3548 | } | ||
3549 | } | ||
3550 | |||
3551 | err = pci_request_regions(pdev, DRV_NAME); | ||
3552 | if (err) | ||
3553 | goto out_pci_disable_device; | ||
3554 | |||
3555 | pci_set_drvdata(pdev, priv); | ||
3556 | |||
3557 | |||
3558 | /*********************** | ||
3559 | * 3. Read REV register | ||
3560 | ***********************/ | ||
3561 | priv->hw_base = pci_iomap(pdev, 0, 0); | ||
3562 | if (!priv->hw_base) { | ||
3563 | err = -ENODEV; | ||
3564 | goto out_pci_release_regions; | ||
3565 | } | ||
3566 | |||
3567 | IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n", | ||
3568 | (unsigned long long) pci_resource_len(pdev, 0)); | ||
3569 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); | ||
3570 | 3523 | ||
3571 | /* these spin locks will be used in apm_ops.init and EEPROM access | 3524 | /* these spin locks will be used in apm_ops.init and EEPROM access |
3572 | * we should init now | 3525 | * we should init now |
@@ -3581,17 +3534,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3581 | */ | 3534 | */ |
3582 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 3535 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
3583 | 3536 | ||
3537 | /*********************** | ||
3538 | * 3. Read REV register | ||
3539 | ***********************/ | ||
3584 | hw_rev = iwl_hw_detect(priv); | 3540 | hw_rev = iwl_hw_detect(priv); |
3585 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", | 3541 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", |
3586 | priv->cfg->name, hw_rev); | 3542 | priv->cfg->name, hw_rev); |
3587 | 3543 | ||
3588 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | ||
3589 | * PCI Tx retries from interfering with C3 CPU state */ | ||
3590 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
3591 | |||
3592 | if (iwl_prepare_card_hw(priv)) { | 3544 | if (iwl_prepare_card_hw(priv)) { |
3545 | err = -EIO; | ||
3593 | IWL_WARN(priv, "Failed, HW not ready\n"); | 3546 | IWL_WARN(priv, "Failed, HW not ready\n"); |
3594 | goto out_iounmap; | 3547 | goto out_free_traffic_mem; |
3595 | } | 3548 | } |
3596 | 3549 | ||
3597 | /***************** | 3550 | /***************** |
@@ -3601,7 +3554,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3601 | err = iwl_eeprom_init(priv, hw_rev); | 3554 | err = iwl_eeprom_init(priv, hw_rev); |
3602 | if (err) { | 3555 | if (err) { |
3603 | IWL_ERR(priv, "Unable to init EEPROM\n"); | 3556 | IWL_ERR(priv, "Unable to init EEPROM\n"); |
3604 | goto out_iounmap; | 3557 | goto out_free_traffic_mem; |
3605 | } | 3558 | } |
3606 | err = iwl_eeprom_check_version(priv); | 3559 | err = iwl_eeprom_check_version(priv); |
3607 | if (err) | 3560 | if (err) |
@@ -3624,10 +3577,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3624 | priv->hw->wiphy->n_addresses++; | 3577 | priv->hw->wiphy->n_addresses++; |
3625 | } | 3578 | } |
3626 | 3579 | ||
3580 | /* initialize all valid contexts */ | ||
3581 | iwl_init_context(priv); | ||
3582 | |||
3627 | /************************ | 3583 | /************************ |
3628 | * 5. Setup HW constants | 3584 | * 5. Setup HW constants |
3629 | ************************/ | 3585 | ************************/ |
3630 | if (iwl_set_hw_params(priv)) { | 3586 | if (iwl_set_hw_params(priv)) { |
3587 | err = -ENOENT; | ||
3631 | IWL_ERR(priv, "failed to set hw parameters\n"); | 3588 | IWL_ERR(priv, "failed to set hw parameters\n"); |
3632 | goto out_free_eeprom; | 3589 | goto out_free_eeprom; |
3633 | } | 3590 | } |
@@ -3644,19 +3601,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3644 | /******************** | 3601 | /******************** |
3645 | * 7. Setup services | 3602 | * 7. Setup services |
3646 | ********************/ | 3603 | ********************/ |
3647 | spin_lock_irqsave(&priv->lock, flags); | ||
3648 | iwl_disable_interrupts(priv); | ||
3649 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3650 | |||
3651 | pci_enable_msi(priv->pci_dev); | ||
3652 | |||
3653 | iwl_alloc_isr_ict(priv); | 3604 | iwl_alloc_isr_ict(priv); |
3654 | 3605 | ||
3655 | err = request_irq(priv->pci_dev->irq, iwl_isr_ict, | 3606 | err = request_irq(priv->bus.irq, iwl_isr_ict, IRQF_SHARED, |
3656 | IRQF_SHARED, DRV_NAME, priv); | 3607 | DRV_NAME, priv); |
3657 | if (err) { | 3608 | if (err) { |
3658 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); | 3609 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus.irq); |
3659 | goto out_disable_msi; | 3610 | goto out_uninit_drv; |
3660 | } | 3611 | } |
3661 | 3612 | ||
3662 | iwl_setup_deferred_work(priv); | 3613 | iwl_setup_deferred_work(priv); |
@@ -3664,16 +3615,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3664 | iwl_testmode_init(priv); | 3615 | iwl_testmode_init(priv); |
3665 | 3616 | ||
3666 | /********************************************* | 3617 | /********************************************* |
3667 | * 8. Enable interrupts and read RFKILL state | 3618 | * 8. Enable interrupts |
3668 | *********************************************/ | 3619 | *********************************************/ |
3669 | 3620 | ||
3670 | /* enable rfkill interrupt: hw bug w/a */ | ||
3671 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | ||
3672 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
3673 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
3674 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); | ||
3675 | } | ||
3676 | |||
3677 | iwl_enable_rfkill_int(priv); | 3621 | iwl_enable_rfkill_int(priv); |
3678 | 3622 | ||
3679 | /* If platform's RF_KILL switch is NOT set to KILL */ | 3623 | /* If platform's RF_KILL switch is NOT set to KILL */ |
@@ -3699,41 +3643,30 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3699 | out_destroy_workqueue: | 3643 | out_destroy_workqueue: |
3700 | destroy_workqueue(priv->workqueue); | 3644 | destroy_workqueue(priv->workqueue); |
3701 | priv->workqueue = NULL; | 3645 | priv->workqueue = NULL; |
3702 | free_irq(priv->pci_dev->irq, priv); | 3646 | free_irq(priv->bus.irq, priv); |
3703 | out_disable_msi: | ||
3704 | iwl_free_isr_ict(priv); | 3647 | iwl_free_isr_ict(priv); |
3705 | pci_disable_msi(priv->pci_dev); | 3648 | out_uninit_drv: |
3706 | iwl_uninit_drv(priv); | 3649 | iwl_uninit_drv(priv); |
3707 | out_free_eeprom: | 3650 | out_free_eeprom: |
3708 | iwl_eeprom_free(priv); | 3651 | iwl_eeprom_free(priv); |
3709 | out_iounmap: | 3652 | out_free_traffic_mem: |
3710 | pci_iounmap(pdev, priv->hw_base); | ||
3711 | out_pci_release_regions: | ||
3712 | pci_set_drvdata(pdev, NULL); | ||
3713 | pci_release_regions(pdev); | ||
3714 | out_pci_disable_device: | ||
3715 | pci_disable_device(pdev); | ||
3716 | out_ieee80211_free_hw: | ||
3717 | iwl_free_traffic_mem(priv); | 3653 | iwl_free_traffic_mem(priv); |
3718 | ieee80211_free_hw(priv->hw); | 3654 | ieee80211_free_hw(priv->hw); |
3719 | out: | 3655 | out: |
3720 | return err; | 3656 | return err; |
3721 | } | 3657 | } |
3722 | 3658 | ||
3723 | static void __devexit iwl_pci_remove(struct pci_dev *pdev) | 3659 | void __devexit iwl_remove(struct iwl_priv * priv) |
3724 | { | 3660 | { |
3725 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
3726 | unsigned long flags; | 3661 | unsigned long flags; |
3727 | 3662 | ||
3728 | if (!priv) | ||
3729 | return; | ||
3730 | |||
3731 | wait_for_completion(&priv->_agn.firmware_loading_complete); | 3663 | wait_for_completion(&priv->_agn.firmware_loading_complete); |
3732 | 3664 | ||
3733 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); | 3665 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); |
3734 | 3666 | ||
3735 | iwl_dbgfs_unregister(priv); | 3667 | iwl_dbgfs_unregister(priv); |
3736 | sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); | 3668 | sysfs_remove_group(&priv->bus.dev->kobj, |
3669 | &iwl_attribute_group); | ||
3737 | 3670 | ||
3738 | /* ieee80211_unregister_hw call wil cause iwl_mac_stop to | 3671 | /* ieee80211_unregister_hw call wil cause iwl_mac_stop to |
3739 | * to be called and iwl_down since we are removing the device | 3672 | * to be called and iwl_down since we are removing the device |
@@ -3763,7 +3696,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3763 | 3696 | ||
3764 | iwl_synchronize_irq(priv); | 3697 | iwl_synchronize_irq(priv); |
3765 | 3698 | ||
3766 | iwl_dealloc_ucode_pci(priv); | 3699 | iwl_dealloc_ucode(priv); |
3767 | 3700 | ||
3768 | if (priv->rxq.bd) | 3701 | if (priv->rxq.bd) |
3769 | iwlagn_rx_queue_free(priv, &priv->rxq); | 3702 | iwlagn_rx_queue_free(priv, &priv->rxq); |
@@ -3782,12 +3715,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3782 | priv->workqueue = NULL; | 3715 | priv->workqueue = NULL; |
3783 | iwl_free_traffic_mem(priv); | 3716 | iwl_free_traffic_mem(priv); |
3784 | 3717 | ||
3785 | free_irq(priv->pci_dev->irq, priv); | 3718 | free_irq(priv->bus.irq, priv); |
3786 | pci_disable_msi(priv->pci_dev); | 3719 | priv->bus.ops->set_drv_data(&priv->bus, NULL); |
3787 | pci_iounmap(pdev, priv->hw_base); | ||
3788 | pci_release_regions(pdev); | ||
3789 | pci_disable_device(pdev); | ||
3790 | pci_set_drvdata(pdev, NULL); | ||
3791 | 3720 | ||
3792 | iwl_uninit_drv(priv); | 3721 | iwl_uninit_drv(priv); |
3793 | 3722 | ||
@@ -3804,206 +3733,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3804 | * driver and module entry point | 3733 | * driver and module entry point |
3805 | * | 3734 | * |
3806 | *****************************************************************************/ | 3735 | *****************************************************************************/ |
3807 | |||
3808 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | ||
3809 | static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | ||
3810 | {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ | ||
3811 | {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
3812 | {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ | ||
3813 | {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
3814 | {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ | ||
3815 | {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ | ||
3816 | {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ | ||
3817 | {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ | ||
3818 | {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ | ||
3819 | {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
3820 | {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ | ||
3821 | {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
3822 | {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ | ||
3823 | {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ | ||
3824 | {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ | ||
3825 | {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ | ||
3826 | {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ | ||
3827 | {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
3828 | {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ | ||
3829 | {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
3830 | {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ | ||
3831 | {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ | ||
3832 | {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ | ||
3833 | {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ | ||
3834 | |||
3835 | /* 5300 Series WiFi */ | ||
3836 | {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3837 | {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3838 | {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3839 | {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3840 | {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3841 | {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3842 | {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3843 | {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3844 | {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3845 | {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3846 | {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3847 | {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3848 | |||
3849 | /* 5350 Series WiFi/WiMax */ | ||
3850 | {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3851 | {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3852 | {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3853 | |||
3854 | /* 5150 Series Wifi/WiMax */ | ||
3855 | {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3856 | {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3857 | {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ | ||
3858 | {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
3859 | {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3860 | {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3861 | |||
3862 | {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3863 | {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3864 | {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ | ||
3865 | {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
3866 | |||
3867 | /* 6x00 Series */ | ||
3868 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, | ||
3869 | {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, | ||
3870 | {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, | ||
3871 | {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, | ||
3872 | {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, | ||
3873 | {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, | ||
3874 | {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, | ||
3875 | {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, | ||
3876 | {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, | ||
3877 | {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, | ||
3878 | |||
3879 | /* 6x05 Series */ | ||
3880 | {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, | ||
3881 | {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, | ||
3882 | {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, | ||
3883 | {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, | ||
3884 | {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, | ||
3885 | {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, | ||
3886 | {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, | ||
3887 | |||
3888 | /* 6x30 Series */ | ||
3889 | {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, | ||
3890 | {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, | ||
3891 | {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, | ||
3892 | {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)}, | ||
3893 | {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)}, | ||
3894 | {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)}, | ||
3895 | {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)}, | ||
3896 | {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)}, | ||
3897 | {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)}, | ||
3898 | {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)}, | ||
3899 | {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)}, | ||
3900 | {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)}, | ||
3901 | {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)}, | ||
3902 | {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)}, | ||
3903 | {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)}, | ||
3904 | {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)}, | ||
3905 | |||
3906 | /* 6x50 WiFi/WiMax Series */ | ||
3907 | {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, | ||
3908 | {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, | ||
3909 | {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, | ||
3910 | {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, | ||
3911 | {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, | ||
3912 | {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, | ||
3913 | |||
3914 | /* 6150 WiFi/WiMax Series */ | ||
3915 | {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, | ||
3916 | {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, | ||
3917 | {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, | ||
3918 | {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, | ||
3919 | {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, | ||
3920 | {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, | ||
3921 | |||
3922 | /* 1000 Series WiFi */ | ||
3923 | {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, | ||
3924 | {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, | ||
3925 | {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)}, | ||
3926 | {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)}, | ||
3927 | {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)}, | ||
3928 | {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)}, | ||
3929 | {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)}, | ||
3930 | {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)}, | ||
3931 | {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)}, | ||
3932 | {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, | ||
3933 | {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, | ||
3934 | {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, | ||
3935 | |||
3936 | /* 100 Series WiFi */ | ||
3937 | {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, | ||
3938 | {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, | ||
3939 | {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, | ||
3940 | {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)}, | ||
3941 | {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, | ||
3942 | {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)}, | ||
3943 | |||
3944 | /* 130 Series WiFi */ | ||
3945 | {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, | ||
3946 | {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, | ||
3947 | {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, | ||
3948 | {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, | ||
3949 | {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, | ||
3950 | {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, | ||
3951 | |||
3952 | /* 2x00 Series */ | ||
3953 | {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, | ||
3954 | {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, | ||
3955 | {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, | ||
3956 | {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, | ||
3957 | {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, | ||
3958 | {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, | ||
3959 | |||
3960 | /* 2x30 Series */ | ||
3961 | {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, | ||
3962 | {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, | ||
3963 | {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, | ||
3964 | {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, | ||
3965 | {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, | ||
3966 | {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, | ||
3967 | |||
3968 | /* 6x35 Series */ | ||
3969 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, | ||
3970 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | ||
3971 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | ||
3972 | {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, | ||
3973 | {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, | ||
3974 | {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, | ||
3975 | {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, | ||
3976 | {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, | ||
3977 | {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, | ||
3978 | |||
3979 | /* 105 Series */ | ||
3980 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, | ||
3981 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, | ||
3982 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, | ||
3983 | {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, | ||
3984 | {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, | ||
3985 | {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, | ||
3986 | |||
3987 | /* 135 Series */ | ||
3988 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, | ||
3989 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, | ||
3990 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, | ||
3991 | {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, | ||
3992 | {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, | ||
3993 | {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, | ||
3994 | |||
3995 | {0} | ||
3996 | }; | ||
3997 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); | ||
3998 | |||
3999 | static struct pci_driver iwl_driver = { | ||
4000 | .name = DRV_NAME, | ||
4001 | .id_table = iwl_hw_card_ids, | ||
4002 | .probe = iwl_pci_probe, | ||
4003 | .remove = __devexit_p(iwl_pci_remove), | ||
4004 | .driver.pm = IWL_PM_OPS, | ||
4005 | }; | ||
4006 | |||
4007 | static int __init iwl_init(void) | 3736 | static int __init iwl_init(void) |
4008 | { | 3737 | { |
4009 | 3738 | ||
@@ -4017,12 +3746,10 @@ static int __init iwl_init(void) | |||
4017 | return ret; | 3746 | return ret; |
4018 | } | 3747 | } |
4019 | 3748 | ||
4020 | ret = pci_register_driver(&iwl_driver); | 3749 | ret = iwl_pci_register_driver(); |
4021 | if (ret) { | ||
4022 | pr_err("Unable to initialize PCI module\n"); | ||
4023 | goto error_register; | ||
4024 | } | ||
4025 | 3750 | ||
3751 | if (ret) | ||
3752 | goto error_register; | ||
4026 | return ret; | 3753 | return ret; |
4027 | 3754 | ||
4028 | error_register: | 3755 | error_register: |
@@ -4032,7 +3759,7 @@ error_register: | |||
4032 | 3759 | ||
4033 | static void __exit iwl_exit(void) | 3760 | static void __exit iwl_exit(void) |
4034 | { | 3761 | { |
4035 | pci_unregister_driver(&iwl_driver); | 3762 | iwl_pci_unregister_driver(); |
4036 | iwlagn_rate_control_unregister(); | 3763 | iwlagn_rate_control_unregister(); |
4037 | } | 3764 | } |
4038 | 3765 | ||
@@ -4074,3 +3801,47 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); | |||
4074 | 3801 | ||
4075 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); | 3802 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); |
4076 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); | 3803 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); |
3804 | |||
3805 | /* | ||
3806 | * set bt_coex_active to true, uCode will do kill/defer | ||
3807 | * every time the priority line is asserted (BT is sending signals on the | ||
3808 | * priority line in the PCIx). | ||
3809 | * set bt_coex_active to false, uCode will ignore the BT activity and | ||
3810 | * perform the normal operation | ||
3811 | * | ||
3812 | * User might experience transmit issue on some platform due to WiFi/BT | ||
3813 | * co-exist problem. The possible behaviors are: | ||
3814 | * Able to scan and finding all the available AP | ||
3815 | * Not able to associate with any AP | ||
3816 | * On those platforms, WiFi communication can be restored by set | ||
3817 | * "bt_coex_active" module parameter to "false" | ||
3818 | * | ||
3819 | * default: bt_coex_active = true (BT_COEX_ENABLE) | ||
3820 | */ | ||
3821 | module_param_named(bt_coex_active, iwlagn_mod_params.bt_coex_active, | ||
3822 | bool, S_IRUGO); | ||
3823 | MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); | ||
3824 | |||
3825 | module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO); | ||
3826 | MODULE_PARM_DESC(led_mode, "0=system default, " | ||
3827 | "1=On(RF On)/Off(RF Off), 2=blinking (default: 0)"); | ||
3828 | |||
3829 | module_param_named(power_save, iwlagn_mod_params.power_save, | ||
3830 | bool, S_IRUGO); | ||
3831 | MODULE_PARM_DESC(power_save, | ||
3832 | "enable WiFi power management (default: disable)"); | ||
3833 | |||
3834 | module_param_named(power_level, iwlagn_mod_params.power_level, | ||
3835 | int, S_IRUGO); | ||
3836 | MODULE_PARM_DESC(power_level, | ||
3837 | "default power save level (range from 1 - 5, default: 1)"); | ||
3838 | |||
3839 | /* | ||
3840 | * For now, keep using power level 1 instead of automatically | ||
3841 | * adjusting ... | ||
3842 | */ | ||
3843 | module_param_named(no_sleep_autoadjust, iwlagn_mod_params.no_sleep_autoadjust, | ||
3844 | bool, S_IRUGO); | ||
3845 | MODULE_PARM_DESC(no_sleep_autoadjust, | ||
3846 | "don't automatically adjust sleep level " | ||
3847 | "according to maximum network latency (default: true)"); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index d1716844002e..6d5584ae5ebf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -125,10 +125,18 @@ irqreturn_t iwl_isr_ict(int irq, void *data); | |||
125 | static inline void iwl_synchronize_irq(struct iwl_priv *priv) | 125 | static inline void iwl_synchronize_irq(struct iwl_priv *priv) |
126 | { | 126 | { |
127 | /* wait to make sure we flush pending tasklet*/ | 127 | /* wait to make sure we flush pending tasklet*/ |
128 | synchronize_irq(priv->pci_dev->irq); | 128 | synchronize_irq(priv->bus.irq); |
129 | tasklet_kill(&priv->irq_tasklet); | 129 | tasklet_kill(&priv->irq_tasklet); |
130 | } | 130 | } |
131 | 131 | ||
132 | static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) | ||
133 | { | ||
134 | hdr->op_code = cmd; | ||
135 | hdr->first_group = 0; | ||
136 | hdr->groups_num = 1; | ||
137 | hdr->data_valid = 1; | ||
138 | } | ||
139 | |||
132 | int iwl_prepare_card_hw(struct iwl_priv *priv); | 140 | int iwl_prepare_card_hw(struct iwl_priv *priv); |
133 | 141 | ||
134 | int iwlagn_start_device(struct iwl_priv *priv); | 142 | int iwlagn_start_device(struct iwl_priv *priv); |
@@ -161,7 +169,7 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv); | |||
161 | int iwlagn_run_init_ucode(struct iwl_priv *priv); | 169 | int iwlagn_run_init_ucode(struct iwl_priv *priv); |
162 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | 170 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, |
163 | struct fw_img *image, | 171 | struct fw_img *image, |
164 | int subtype, int alternate_subtype); | 172 | enum iwlagn_ucode_type ucode_type); |
165 | 173 | ||
166 | /* lib */ | 174 | /* lib */ |
167 | void iwl_check_abort_status(struct iwl_priv *priv, | 175 | void iwl_check_abort_status(struct iwl_priv *priv, |
@@ -343,6 +351,9 @@ extern int iwl_alive_start(struct iwl_priv *priv); | |||
343 | /* svtool */ | 351 | /* svtool */ |
344 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL | 352 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL |
345 | extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); | 353 | extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); |
354 | extern int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
355 | struct netlink_callback *cb, | ||
356 | void *data, int len); | ||
346 | extern void iwl_testmode_init(struct iwl_priv *priv); | 357 | extern void iwl_testmode_init(struct iwl_priv *priv); |
347 | extern void iwl_testmode_cleanup(struct iwl_priv *priv); | 358 | extern void iwl_testmode_cleanup(struct iwl_priv *priv); |
348 | #else | 359 | #else |
@@ -352,6 +363,13 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
352 | return -ENOSYS; | 363 | return -ENOSYS; |
353 | } | 364 | } |
354 | static inline | 365 | static inline |
366 | int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
367 | struct netlink_callback *cb, | ||
368 | void *data, int len) | ||
369 | { | ||
370 | return -ENOSYS; | ||
371 | } | ||
372 | static inline | ||
355 | void iwl_testmode_init(struct iwl_priv *priv) | 373 | void iwl_testmode_init(struct iwl_priv *priv) |
356 | { | 374 | { |
357 | } | 375 | } |
@@ -361,4 +379,8 @@ void iwl_testmode_cleanup(struct iwl_priv *priv) | |||
361 | } | 379 | } |
362 | #endif | 380 | #endif |
363 | 381 | ||
382 | int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, | ||
383 | struct iwl_cfg *cfg); | ||
384 | void __devexit iwl_remove(struct iwl_priv * priv); | ||
385 | |||
364 | #endif /* __iwl_agn_h__ */ | 386 | #endif /* __iwl_agn_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 6ee5f1aa555c..8a2edf8dce32 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -384,18 +384,6 @@ struct iwl_tx_ant_config_cmd { | |||
384 | 384 | ||
385 | #define UCODE_VALID_OK cpu_to_le32(0x1) | 385 | #define UCODE_VALID_OK cpu_to_le32(0x1) |
386 | 386 | ||
387 | enum iwlagn_ucode_subtype { | ||
388 | UCODE_SUBTYPE_REGULAR = 0, | ||
389 | UCODE_SUBTYPE_REGULAR_NEW = 1, | ||
390 | UCODE_SUBTYPE_INIT = 9, | ||
391 | |||
392 | /* | ||
393 | * Not a valid subtype, the ucode has just a u8, so | ||
394 | * we can use something > 0xff for this value. | ||
395 | */ | ||
396 | UCODE_SUBTYPE_NONE_LOADED = 0x100, | ||
397 | }; | ||
398 | |||
399 | /** | 387 | /** |
400 | * REPLY_ALIVE = 0x1 (response only, not a command) | 388 | * REPLY_ALIVE = 0x1 (response only, not a command) |
401 | * | 389 | * |
@@ -984,15 +972,26 @@ struct iwl_rem_sta_cmd { | |||
984 | u8 reserved2[2]; | 972 | u8 reserved2[2]; |
985 | } __packed; | 973 | } __packed; |
986 | 974 | ||
987 | #define IWL_TX_FIFO_BK_MSK cpu_to_le32(BIT(0)) | 975 | |
988 | #define IWL_TX_FIFO_BE_MSK cpu_to_le32(BIT(1)) | 976 | /* WiFi queues mask */ |
989 | #define IWL_TX_FIFO_VI_MSK cpu_to_le32(BIT(2)) | 977 | #define IWL_SCD_BK_MSK cpu_to_le32(BIT(0)) |
990 | #define IWL_TX_FIFO_VO_MSK cpu_to_le32(BIT(3)) | 978 | #define IWL_SCD_BE_MSK cpu_to_le32(BIT(1)) |
979 | #define IWL_SCD_VI_MSK cpu_to_le32(BIT(2)) | ||
980 | #define IWL_SCD_VO_MSK cpu_to_le32(BIT(3)) | ||
981 | #define IWL_SCD_MGMT_MSK cpu_to_le32(BIT(3)) | ||
982 | |||
983 | /* PAN queues mask */ | ||
984 | #define IWL_PAN_SCD_BK_MSK cpu_to_le32(BIT(4)) | ||
985 | #define IWL_PAN_SCD_BE_MSK cpu_to_le32(BIT(5)) | ||
986 | #define IWL_PAN_SCD_VI_MSK cpu_to_le32(BIT(6)) | ||
987 | #define IWL_PAN_SCD_VO_MSK cpu_to_le32(BIT(7)) | ||
988 | #define IWL_PAN_SCD_MGMT_MSK cpu_to_le32(BIT(7)) | ||
989 | #define IWL_PAN_SCD_MULTICAST_MSK cpu_to_le32(BIT(8)) | ||
990 | |||
991 | #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) | 991 | #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) |
992 | 992 | ||
993 | #define IWL_DROP_SINGLE 0 | 993 | #define IWL_DROP_SINGLE 0 |
994 | #define IWL_DROP_SELECTED 1 | 994 | #define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN)) |
995 | #define IWL_DROP_ALL 2 | ||
996 | 995 | ||
997 | /* | 996 | /* |
998 | * REPLY_TXFIFO_FLUSH = 0x1e(command and response) | 997 | * REPLY_TXFIFO_FLUSH = 0x1e(command and response) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5416b12cd931..cde725326c32 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -43,27 +43,6 @@ | |||
43 | #include "iwl-helpers.h" | 43 | #include "iwl-helpers.h" |
44 | #include "iwl-agn.h" | 44 | #include "iwl-agn.h" |
45 | 45 | ||
46 | |||
47 | /* | ||
48 | * set bt_coex_active to true, uCode will do kill/defer | ||
49 | * every time the priority line is asserted (BT is sending signals on the | ||
50 | * priority line in the PCIx). | ||
51 | * set bt_coex_active to false, uCode will ignore the BT activity and | ||
52 | * perform the normal operation | ||
53 | * | ||
54 | * User might experience transmit issue on some platform due to WiFi/BT | ||
55 | * co-exist problem. The possible behaviors are: | ||
56 | * Able to scan and finding all the available AP | ||
57 | * Not able to associate with any AP | ||
58 | * On those platforms, WiFi communication can be restored by set | ||
59 | * "bt_coex_active" module parameter to "false" | ||
60 | * | ||
61 | * default: bt_coex_active = true (BT_COEX_ENABLE) | ||
62 | */ | ||
63 | bool bt_coex_active = true; | ||
64 | module_param(bt_coex_active, bool, S_IRUGO); | ||
65 | MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); | ||
66 | |||
67 | u32 iwl_debug_level; | 46 | u32 iwl_debug_level; |
68 | 47 | ||
69 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 48 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
@@ -164,7 +143,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
164 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | 143 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; |
165 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; | 144 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; |
166 | 145 | ||
167 | if (priv->cfg->sku & IWL_SKU_N) | 146 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) |
168 | iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, | 147 | iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, |
169 | IEEE80211_BAND_5GHZ); | 148 | IEEE80211_BAND_5GHZ); |
170 | 149 | ||
@@ -174,7 +153,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
174 | sband->bitrates = rates; | 153 | sband->bitrates = rates; |
175 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; | 154 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; |
176 | 155 | ||
177 | if (priv->cfg->sku & IWL_SKU_N) | 156 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) |
178 | iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, | 157 | iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, |
179 | IEEE80211_BAND_2GHZ); | 158 | IEEE80211_BAND_2GHZ); |
180 | 159 | ||
@@ -229,12 +208,12 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
229 | priv->tx_power_next = max_tx_power; | 208 | priv->tx_power_next = max_tx_power; |
230 | 209 | ||
231 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | 210 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
232 | priv->cfg->sku & IWL_SKU_A) { | 211 | priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) { |
212 | char buf[32]; | ||
213 | priv->bus.ops->get_hw_id(&priv->bus, buf, sizeof(buf)); | ||
233 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | 214 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
234 | "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n", | 215 | "Please send your %s to maintainer.\n", buf); |
235 | priv->pci_dev->device, | 216 | priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; |
236 | priv->pci_dev->subsystem_device); | ||
237 | priv->cfg->sku &= ~IWL_SKU_A; | ||
238 | } | 217 | } |
239 | 218 | ||
240 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 219 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
@@ -1018,8 +997,6 @@ void iwl_apm_stop(struct iwl_priv *priv) | |||
1018 | int iwl_apm_init(struct iwl_priv *priv) | 997 | int iwl_apm_init(struct iwl_priv *priv) |
1019 | { | 998 | { |
1020 | int ret = 0; | 999 | int ret = 0; |
1021 | u16 lctl; | ||
1022 | |||
1023 | IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); | 1000 | IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); |
1024 | 1001 | ||
1025 | /* | 1002 | /* |
@@ -1048,27 +1025,7 @@ int iwl_apm_init(struct iwl_priv *priv) | |||
1048 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1025 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
1049 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); | 1026 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); |
1050 | 1027 | ||
1051 | /* | 1028 | priv->bus.ops->apm_config(&priv->bus); |
1052 | * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition. | ||
1053 | * Check if BIOS (or OS) enabled L1-ASPM on this device. | ||
1054 | * If so (likely), disable L0S, so device moves directly L0->L1; | ||
1055 | * costs negligible amount of power savings. | ||
1056 | * If not (unlikely), enable L0S, so there is at least some | ||
1057 | * power savings, even without L1. | ||
1058 | */ | ||
1059 | lctl = iwl_pcie_link_ctl(priv); | ||
1060 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == | ||
1061 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { | ||
1062 | /* L1-ASPM enabled; disable(!) L0S */ | ||
1063 | iwl_set_bit(priv, CSR_GIO_REG, | ||
1064 | CSR_GIO_REG_VAL_L0S_ENABLED); | ||
1065 | IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); | ||
1066 | } else { | ||
1067 | /* L1-ASPM disabled; enable(!) L0S */ | ||
1068 | iwl_clear_bit(priv, CSR_GIO_REG, | ||
1069 | CSR_GIO_REG_VAL_L0S_ENABLED); | ||
1070 | IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); | ||
1071 | } | ||
1072 | 1029 | ||
1073 | /* Configure analog phase-lock-loop before activating to D0A */ | 1030 | /* Configure analog phase-lock-loop before activating to D0A */ |
1074 | if (priv->cfg->base_params->pll_cfg_val) | 1031 | if (priv->cfg->base_params->pll_cfg_val) |
@@ -1179,7 +1136,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) | |||
1179 | .kill_cts_mask = 0, | 1136 | .kill_cts_mask = 0, |
1180 | }; | 1137 | }; |
1181 | 1138 | ||
1182 | if (!bt_coex_active) | 1139 | if (!iwlagn_mod_params.bt_coex_active) |
1183 | bt_cmd.flags = BT_COEX_DISABLE; | 1140 | bt_cmd.flags = BT_COEX_DISABLE; |
1184 | else | 1141 | else |
1185 | bt_cmd.flags = BT_COEX_ENABLE; | 1142 | bt_cmd.flags = BT_COEX_ENABLE; |
@@ -1969,11 +1926,8 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, | |||
1969 | 1926 | ||
1970 | #ifdef CONFIG_PM | 1927 | #ifdef CONFIG_PM |
1971 | 1928 | ||
1972 | int iwl_pci_suspend(struct device *device) | 1929 | int iwl_suspend(struct iwl_priv *priv) |
1973 | { | 1930 | { |
1974 | struct pci_dev *pdev = to_pci_dev(device); | ||
1975 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
1976 | |||
1977 | /* | 1931 | /* |
1978 | * This function is called when system goes into suspend state | 1932 | * This function is called when system goes into suspend state |
1979 | * mac80211 will call iwl_mac_stop() from the mac80211 suspend function | 1933 | * mac80211 will call iwl_mac_stop() from the mac80211 suspend function |
@@ -1986,18 +1940,10 @@ int iwl_pci_suspend(struct device *device) | |||
1986 | return 0; | 1940 | return 0; |
1987 | } | 1941 | } |
1988 | 1942 | ||
1989 | int iwl_pci_resume(struct device *device) | 1943 | int iwl_resume(struct iwl_priv *priv) |
1990 | { | 1944 | { |
1991 | struct pci_dev *pdev = to_pci_dev(device); | ||
1992 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
1993 | bool hw_rfkill = false; | 1945 | bool hw_rfkill = false; |
1994 | 1946 | ||
1995 | /* | ||
1996 | * We disable the RETRY_TIMEOUT register (0x41) to keep | ||
1997 | * PCI Tx retries from interfering with C3 CPU state. | ||
1998 | */ | ||
1999 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
2000 | |||
2001 | iwl_enable_interrupts(priv); | 1947 | iwl_enable_interrupts(priv); |
2002 | 1948 | ||
2003 | if (!(iwl_read32(priv, CSR_GP_CNTRL) & | 1949 | if (!(iwl_read32(priv, CSR_GP_CNTRL) & |
@@ -2014,13 +1960,4 @@ int iwl_pci_resume(struct device *device) | |||
2014 | return 0; | 1960 | return 0; |
2015 | } | 1961 | } |
2016 | 1962 | ||
2017 | const struct dev_pm_ops iwl_pm_ops = { | ||
2018 | .suspend = iwl_pci_suspend, | ||
2019 | .resume = iwl_pci_resume, | ||
2020 | .freeze = iwl_pci_suspend, | ||
2021 | .thaw = iwl_pci_resume, | ||
2022 | .poweroff = iwl_pci_suspend, | ||
2023 | .restore = iwl_pci_resume, | ||
2024 | }; | ||
2025 | |||
2026 | #endif /* CONFIG_PM */ | 1963 | #endif /* CONFIG_PM */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 05ea88aa76e3..adf9f9b2efb5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -76,17 +76,8 @@ struct iwl_cmd; | |||
76 | #define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" | 76 | #define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" |
77 | #define DRV_AUTHOR "<ilw@linux.intel.com>" | 77 | #define DRV_AUTHOR "<ilw@linux.intel.com>" |
78 | 78 | ||
79 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ | ||
80 | .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ | ||
81 | .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ | ||
82 | .driver_data = (kernel_ulong_t)&(cfg) | ||
83 | |||
84 | #define TIME_UNIT 1024 | 79 | #define TIME_UNIT 1024 |
85 | 80 | ||
86 | #define IWL_SKU_G 0x1 | ||
87 | #define IWL_SKU_A 0x2 | ||
88 | #define IWL_SKU_N 0x8 | ||
89 | |||
90 | #define IWL_CMD(x) case x: return #x | 81 | #define IWL_CMD(x) case x: return #x |
91 | 82 | ||
92 | struct iwl_hcmd_ops { | 83 | struct iwl_hcmd_ops { |
@@ -146,10 +137,6 @@ struct iwl_lib_ops { | |||
146 | 137 | ||
147 | /* temperature */ | 138 | /* temperature */ |
148 | struct iwl_temp_ops temp_ops; | 139 | struct iwl_temp_ops temp_ops; |
149 | |||
150 | int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | ||
151 | void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | ||
152 | |||
153 | }; | 140 | }; |
154 | 141 | ||
155 | /* NIC specific ops */ | 142 | /* NIC specific ops */ |
@@ -173,6 +160,11 @@ struct iwl_mod_params { | |||
173 | int restart_fw; /* def: 1 = restart firmware */ | 160 | int restart_fw; /* def: 1 = restart firmware */ |
174 | bool plcp_check; /* def: true = enable plcp health check */ | 161 | bool plcp_check; /* def: true = enable plcp health check */ |
175 | bool ack_check; /* def: false = disable ack health check */ | 162 | bool ack_check; /* def: false = disable ack health check */ |
163 | bool bt_coex_active; /* def: true = enable bt coex */ | ||
164 | int led_mode; /* def: 0 = system default */ | ||
165 | bool no_sleep_autoadjust; /* def: true = disable autoadjust */ | ||
166 | bool power_save; /* def: false = disable power save */ | ||
167 | int power_level; /* def: 1 = power level */ | ||
176 | }; | 168 | }; |
177 | 169 | ||
178 | /* | 170 | /* |
@@ -289,7 +281,7 @@ struct iwl_cfg { | |||
289 | const unsigned int ucode_api_min; | 281 | const unsigned int ucode_api_min; |
290 | u8 valid_tx_ant; | 282 | u8 valid_tx_ant; |
291 | u8 valid_rx_ant; | 283 | u8 valid_rx_ant; |
292 | unsigned int sku; | 284 | u16 sku; |
293 | u16 eeprom_ver; | 285 | u16 eeprom_ver; |
294 | u16 eeprom_calib_ver; | 286 | u16 eeprom_calib_ver; |
295 | const struct iwl_ops *ops; | 287 | const struct iwl_ops *ops; |
@@ -480,36 +472,14 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, | |||
480 | 472 | ||
481 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 473 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); |
482 | 474 | ||
483 | |||
484 | /***************************************************** | ||
485 | * PCI * | ||
486 | *****************************************************/ | ||
487 | |||
488 | static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) | ||
489 | { | ||
490 | int pos; | ||
491 | u16 pci_lnk_ctl; | ||
492 | pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP); | ||
493 | pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); | ||
494 | return pci_lnk_ctl; | ||
495 | } | ||
496 | |||
497 | void iwl_bg_watchdog(unsigned long data); | 475 | void iwl_bg_watchdog(unsigned long data); |
498 | u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval); | 476 | u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval); |
499 | __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, | 477 | __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, |
500 | u32 addon, u32 beacon_interval); | 478 | u32 addon, u32 beacon_interval); |
501 | 479 | ||
502 | #ifdef CONFIG_PM | 480 | #ifdef CONFIG_PM |
503 | int iwl_pci_suspend(struct device *device); | 481 | int iwl_suspend(struct iwl_priv *priv); |
504 | int iwl_pci_resume(struct device *device); | 482 | int iwl_resume(struct iwl_priv *priv); |
505 | extern const struct dev_pm_ops iwl_pm_ops; | ||
506 | |||
507 | #define IWL_PM_OPS (&iwl_pm_ops) | ||
508 | |||
509 | #else /* !CONFIG_PM */ | ||
510 | |||
511 | #define IWL_PM_OPS NULL | ||
512 | |||
513 | #endif /* !CONFIG_PM */ | 483 | #endif /* !CONFIG_PM */ |
514 | 484 | ||
515 | /***************************************************** | 485 | /***************************************************** |
@@ -624,7 +594,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) | |||
624 | priv->cfg->bt_params->advanced_bt_coexist; | 594 | priv->cfg->bt_params->advanced_bt_coexist; |
625 | } | 595 | } |
626 | 596 | ||
627 | extern bool bt_coex_active; | ||
628 | extern bool bt_siso_mode; | 597 | extern bool bt_siso_mode; |
629 | 598 | ||
630 | 599 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 2824ccbcc1fc..eb95d1a37487 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -32,10 +32,10 @@ | |||
32 | struct iwl_priv; | 32 | struct iwl_priv; |
33 | extern u32 iwl_debug_level; | 33 | extern u32 iwl_debug_level; |
34 | 34 | ||
35 | #define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a) | 35 | #define IWL_ERR(p, f, a...) dev_err(p->bus.ops->get_dev(&p->bus), f, ## a) |
36 | #define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a) | 36 | #define IWL_WARN(p, f, a...) dev_warn(p->bus.ops->get_dev(&p->bus), f, ## a) |
37 | #define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a) | 37 | #define IWL_INFO(p, f, a...) dev_info(p->bus.ops->get_dev(&p->bus), f, ## a) |
38 | #define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a) | 38 | #define IWL_CRIT(p, f, a...) dev_crit(p->bus.ops->get_dev(&p->bus), f, ## a) |
39 | 39 | ||
40 | #define iwl_print_hex_error(priv, p, len) \ | 40 | #define iwl_print_hex_error(priv, p, len) \ |
41 | do { \ | 41 | do { \ |
@@ -125,13 +125,13 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
125 | /* 0x00000F00 - 0x00000100 */ | 125 | /* 0x00000F00 - 0x00000100 */ |
126 | #define IWL_DL_POWER (1 << 8) | 126 | #define IWL_DL_POWER (1 << 8) |
127 | #define IWL_DL_TEMP (1 << 9) | 127 | #define IWL_DL_TEMP (1 << 9) |
128 | #define IWL_DL_NOTIF (1 << 10) | 128 | /* reserved (1 << 10) */ |
129 | #define IWL_DL_SCAN (1 << 11) | 129 | #define IWL_DL_SCAN (1 << 11) |
130 | /* 0x0000F000 - 0x00001000 */ | 130 | /* 0x0000F000 - 0x00001000 */ |
131 | #define IWL_DL_ASSOC (1 << 12) | 131 | #define IWL_DL_ASSOC (1 << 12) |
132 | #define IWL_DL_DROP (1 << 13) | 132 | #define IWL_DL_DROP (1 << 13) |
133 | #define IWL_DL_TXPOWER (1 << 14) | 133 | /* reserved (1 << 14) */ |
134 | #define IWL_DL_AP (1 << 15) | 134 | #define IWL_DL_COEX (1 << 15) |
135 | /* 0x000F0000 - 0x00010000 */ | 135 | /* 0x000F0000 - 0x00010000 */ |
136 | #define IWL_DL_FW (1 << 16) | 136 | #define IWL_DL_FW (1 << 16) |
137 | #define IWL_DL_RF_KILL (1 << 17) | 137 | #define IWL_DL_RF_KILL (1 << 17) |
@@ -171,12 +171,10 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
171 | #define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a) | 171 | #define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a) |
172 | #define IWL_DEBUG_DROP_LIMIT(p, f, a...) \ | 172 | #define IWL_DEBUG_DROP_LIMIT(p, f, a...) \ |
173 | IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) | 173 | IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) |
174 | #define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a) | 174 | #define IWL_DEBUG_COEX(p, f, a...) IWL_DEBUG(p, IWL_DL_COEX, f, ## a) |
175 | #define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a) | ||
176 | #define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) | 175 | #define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) |
177 | #define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ | 176 | #define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ |
178 | IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a) | 177 | IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a) |
179 | #define IWL_DEBUG_NOTIF(p, f, a...) IWL_DEBUG(p, IWL_DL_NOTIF, f, ## a) | ||
180 | #define IWL_DEBUG_ASSOC(p, f, a...) \ | 178 | #define IWL_DEBUG_ASSOC(p, f, a...) \ |
181 | IWL_DEBUG(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) | 179 | IWL_DEBUG(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) |
182 | #define IWL_DEBUG_ASSOC_LIMIT(p, f, a...) \ | 180 | #define IWL_DEBUG_ASSOC_LIMIT(p, f, a...) \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 0e6a04b739ad..6f9ebae8ca06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -227,7 +227,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
227 | /* default is to dump the entire data segment */ | 227 | /* default is to dump the entire data segment */ |
228 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 228 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
229 | priv->dbgfs_sram_offset = 0x800000; | 229 | priv->dbgfs_sram_offset = 0x800000; |
230 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) | 230 | if (priv->ucode_type == IWL_UCODE_INIT) |
231 | priv->dbgfs_sram_len = priv->ucode_init.data.len; | 231 | priv->dbgfs_sram_len = priv->ucode_init.data.len; |
232 | else | 232 | else |
233 | priv->dbgfs_sram_len = priv->ucode_rt.data.len; | 233 | priv->dbgfs_sram_len = priv->ucode_rt.data.len; |
@@ -2493,7 +2493,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, | |||
2493 | if (iwl_is_rfkill(priv)) | 2493 | if (iwl_is_rfkill(priv)) |
2494 | return -EFAULT; | 2494 | return -EFAULT; |
2495 | 2495 | ||
2496 | priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL); | 2496 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
2497 | 2497 | ||
2498 | return count; | 2498 | return count; |
2499 | } | 2499 | } |
@@ -2693,8 +2693,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2693 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); | 2693 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); |
2694 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); | 2694 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); |
2695 | DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); | 2695 | DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); |
2696 | if (priv->cfg->ops->lib->dev_txfifo_flush) | 2696 | DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); |
2697 | DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); | ||
2698 | DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); | 2697 | DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); |
2699 | 2698 | ||
2700 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); | 2699 | DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7ad98d868954..f1b1128ee1c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -49,6 +49,8 @@ | |||
49 | #include "iwl-agn-rs.h" | 49 | #include "iwl-agn-rs.h" |
50 | #include "iwl-agn-tt.h" | 50 | #include "iwl-agn-tt.h" |
51 | 51 | ||
52 | #define DRV_NAME "iwlagn" | ||
53 | |||
52 | struct iwl_tx_queue; | 54 | struct iwl_tx_queue; |
53 | 55 | ||
54 | /* CT-KILL constants */ | 56 | /* CT-KILL constants */ |
@@ -1169,14 +1171,63 @@ enum iwl_scan_type { | |||
1169 | IWL_SCAN_OFFCH_TX, | 1171 | IWL_SCAN_OFFCH_TX, |
1170 | }; | 1172 | }; |
1171 | 1173 | ||
1174 | enum iwlagn_ucode_type { | ||
1175 | IWL_UCODE_NONE, | ||
1176 | IWL_UCODE_REGULAR, | ||
1177 | IWL_UCODE_INIT, | ||
1178 | IWL_UCODE_WOWLAN, | ||
1179 | }; | ||
1180 | |||
1172 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL | 1181 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL |
1173 | struct iwl_testmode_trace { | 1182 | struct iwl_testmode_trace { |
1183 | u32 buff_size; | ||
1184 | u32 total_size; | ||
1185 | u32 num_chunks; | ||
1174 | u8 *cpu_addr; | 1186 | u8 *cpu_addr; |
1175 | u8 *trace_addr; | 1187 | u8 *trace_addr; |
1176 | dma_addr_t dma_addr; | 1188 | dma_addr_t dma_addr; |
1177 | bool trace_enabled; | 1189 | bool trace_enabled; |
1178 | }; | 1190 | }; |
1179 | #endif | 1191 | #endif |
1192 | |||
1193 | struct iwl_bus; | ||
1194 | |||
1195 | /** | ||
1196 | * struct iwl_bus_ops - bus specific operations | ||
1197 | |||
1198 | * @get_pm_support: must returns true if the bus can go to sleep | ||
1199 | * @apm_config: will be called during the config of the APM configuration | ||
1200 | * @set_drv_data: set the priv pointer to the bus layer | ||
1201 | * @get_dev: returns the device struct | ||
1202 | * @get_irq: returns the irq number | ||
1203 | * @get_hw_id: prints the hw_id in the provided buffer | ||
1204 | * @write8: write a byte to register at offset ofs | ||
1205 | * @write32: write a dword to register at offset ofs | ||
1206 | * @wread32: read a dword at register at offset ofs | ||
1207 | */ | ||
1208 | struct iwl_bus_ops { | ||
1209 | bool (*get_pm_support)(struct iwl_bus *bus); | ||
1210 | void (*apm_config)(struct iwl_bus *bus); | ||
1211 | void (*set_drv_data)(struct iwl_bus *bus, void *priv); | ||
1212 | struct device *(*get_dev)(const struct iwl_bus *bus); | ||
1213 | unsigned int (*get_irq)(const struct iwl_bus *bus); | ||
1214 | void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len); | ||
1215 | void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); | ||
1216 | void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); | ||
1217 | u32 (*read32)(struct iwl_bus *bus, u32 ofs); | ||
1218 | }; | ||
1219 | |||
1220 | struct iwl_bus { | ||
1221 | /* pointer to bus specific struct */ | ||
1222 | void *bus_specific; | ||
1223 | |||
1224 | /* Common data to all buses */ | ||
1225 | struct iwl_priv *priv; /* driver's context */ | ||
1226 | struct device *dev; | ||
1227 | struct iwl_bus_ops *ops; | ||
1228 | unsigned int irq; | ||
1229 | }; | ||
1230 | |||
1180 | struct iwl_priv { | 1231 | struct iwl_priv { |
1181 | 1232 | ||
1182 | /* ieee device used by generic ieee processing code */ | 1233 | /* ieee device used by generic ieee processing code */ |
@@ -1244,17 +1295,14 @@ struct iwl_priv { | |||
1244 | spinlock_t reg_lock; /* protect hw register access */ | 1295 | spinlock_t reg_lock; /* protect hw register access */ |
1245 | struct mutex mutex; | 1296 | struct mutex mutex; |
1246 | 1297 | ||
1247 | /* basic pci-network driver stuff */ | 1298 | struct iwl_bus bus; /* bus specific data */ |
1248 | struct pci_dev *pci_dev; | ||
1249 | |||
1250 | /* pci hardware address support */ | ||
1251 | void __iomem *hw_base; | ||
1252 | 1299 | ||
1253 | /* microcode/device supports multiple contexts */ | 1300 | /* microcode/device supports multiple contexts */ |
1254 | u8 valid_contexts; | 1301 | u8 valid_contexts; |
1255 | 1302 | ||
1256 | /* command queue number */ | 1303 | /* command queue number */ |
1257 | u8 cmd_queue; | 1304 | u8 cmd_queue; |
1305 | u8 last_sync_cmd_id; | ||
1258 | 1306 | ||
1259 | /* max number of station keys */ | 1307 | /* max number of station keys */ |
1260 | u8 sta_key_max_num; | 1308 | u8 sta_key_max_num; |
@@ -1271,7 +1319,7 @@ struct iwl_priv { | |||
1271 | struct fw_img ucode_rt; | 1319 | struct fw_img ucode_rt; |
1272 | struct fw_img ucode_init; | 1320 | struct fw_img ucode_init; |
1273 | 1321 | ||
1274 | enum iwlagn_ucode_subtype ucode_type; | 1322 | enum iwlagn_ucode_type ucode_type; |
1275 | u8 ucode_write_complete; /* the image write is complete */ | 1323 | u8 ucode_write_complete; /* the image write is complete */ |
1276 | char firmware_name[25]; | 1324 | char firmware_name[25]; |
1277 | 1325 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 47a56bc1cd12..768d0ee276f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -834,3 +834,28 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, | |||
834 | 834 | ||
835 | return NULL; | 835 | return NULL; |
836 | } | 836 | } |
837 | |||
838 | void iwl_rf_config(struct iwl_priv *priv) | ||
839 | { | ||
840 | u16 radio_cfg; | ||
841 | |||
842 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | ||
843 | |||
844 | /* write radio config values to register */ | ||
845 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { | ||
846 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
847 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | | ||
848 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | | ||
849 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
850 | IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", | ||
851 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg), | ||
852 | EEPROM_RF_CFG_STEP_MSK(radio_cfg), | ||
853 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
854 | } else | ||
855 | WARN_ON(1); | ||
856 | |||
857 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
858 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
859 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
860 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
861 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index c960c6fa009b..804f910c651e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -110,12 +110,10 @@ enum { | |||
110 | }; | 110 | }; |
111 | 111 | ||
112 | /* SKU Capabilities */ | 112 | /* SKU Capabilities */ |
113 | /* 5000 and up */ | 113 | #define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) |
114 | #define EEPROM_SKU_CAP_BAND_POS (4) | 114 | #define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) |
115 | #define EEPROM_SKU_CAP_BAND_SELECTION \ | ||
116 | (3 << EEPROM_SKU_CAP_BAND_POS) | ||
117 | #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) | 115 | #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) |
118 | #define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) | 116 | #define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) |
119 | #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) | 117 | #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) |
120 | 118 | ||
121 | /* *regulatory* channel data format in eeprom, one for each channel. | 119 | /* *regulatory* channel data format in eeprom, one for each channel. |
@@ -164,16 +162,12 @@ struct iwl_eeprom_enhanced_txpwr { | |||
164 | s8 mimo3_max; | 162 | s8 mimo3_max; |
165 | } __packed; | 163 | } __packed; |
166 | 164 | ||
167 | /* 5000 Specific */ | 165 | /* calibration */ |
168 | #define EEPROM_5000_TX_POWER_VERSION (4) | ||
169 | #define EEPROM_5000_EEPROM_VERSION (0x11A) | ||
170 | |||
171 | /* 5000 and up calibration */ | ||
172 | #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) | 166 | #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) |
173 | #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) | 167 | #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) |
174 | 168 | ||
175 | /* 5000 temperature */ | 169 | /* temperature */ |
176 | #define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) | 170 | #define EEPROM_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) |
177 | 171 | ||
178 | /* agn links */ | 172 | /* agn links */ |
179 | #define EEPROM_LINK_HOST (2*0x64) | 173 | #define EEPROM_LINK_HOST (2*0x64) |
@@ -205,6 +199,10 @@ struct iwl_eeprom_enhanced_txpwr { | |||
205 | #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ | 199 | #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ |
206 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ | 200 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ |
207 | 201 | ||
202 | /* 5000 Specific */ | ||
203 | #define EEPROM_5000_TX_POWER_VERSION (4) | ||
204 | #define EEPROM_5000_EEPROM_VERSION (0x11A) | ||
205 | |||
208 | /* 5050 Specific */ | 206 | /* 5050 Specific */ |
209 | #define EEPROM_5050_TX_POWER_VERSION (4) | 207 | #define EEPROM_5050_TX_POWER_VERSION (4) |
210 | #define EEPROM_5050_EEPROM_VERSION (0x21E) | 208 | #define EEPROM_5050_EEPROM_VERSION (0x21E) |
@@ -270,13 +268,13 @@ extern const u8 iwl_eeprom_band_1[14]; | |||
270 | 268 | ||
271 | /* General */ | 269 | /* General */ |
272 | #define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ | 270 | #define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ |
271 | #define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ | ||
273 | #define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ | 272 | #define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ |
274 | #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ | 273 | #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ |
275 | #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ | 274 | #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ |
276 | #define EEPROM_VERSION (2*0x44) /* 2 bytes */ | 275 | #define EEPROM_VERSION (2*0x44) /* 2 bytes */ |
277 | #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ | 276 | #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ |
278 | #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ | 277 | #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ |
279 | #define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ | ||
280 | #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ | 278 | #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ |
281 | #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ | 279 | #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ |
282 | 280 | ||
@@ -311,5 +309,6 @@ void iwl_free_channel_map(struct iwl_priv *priv); | |||
311 | const struct iwl_channel_info *iwl_get_channel_info( | 309 | const struct iwl_channel_info *iwl_get_channel_info( |
312 | const struct iwl_priv *priv, | 310 | const struct iwl_priv *priv, |
313 | enum ieee80211_band band, u16 channel); | 311 | enum ieee80211_band band, u16 channel); |
312 | void iwl_rf_config(struct iwl_priv *priv); | ||
314 | 313 | ||
315 | #endif /* __iwl_eeprom_h__ */ | 314 | #endif /* __iwl_eeprom_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 76f996623140..7cdb1ec73b54 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -181,7 +181,16 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
181 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", | 181 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", |
182 | get_cmd_string(cmd->id)); | 182 | get_cmd_string(cmd->id)); |
183 | 183 | ||
184 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); | 184 | if (test_and_set_bit(STATUS_HCMD_ACTIVE, &priv->status)) { |
185 | IWL_ERR(priv, "STATUS_HCMD_ACTIVE already set while sending %s" | ||
186 | ". Previous SYNC cmdn is %s\n", | ||
187 | get_cmd_string(cmd->id), | ||
188 | get_cmd_string(priv->last_sync_cmd_id)); | ||
189 | WARN_ON(1); | ||
190 | } else { | ||
191 | priv->last_sync_cmd_id = cmd->id; | ||
192 | } | ||
193 | |||
185 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", | 194 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", |
186 | get_cmd_string(cmd->id)); | 195 | get_cmd_string(cmd->id)); |
187 | 196 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 41207a3645b8..9d91552d13c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -120,7 +120,16 @@ static inline void iwl_wake_any_queue(struct iwl_priv *priv, | |||
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | #ifdef ieee80211_stop_queue | ||
124 | #undef ieee80211_stop_queue | ||
125 | #endif | ||
126 | |||
123 | #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue | 127 | #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue |
128 | |||
129 | #ifdef ieee80211_wake_queue | ||
130 | #undef ieee80211_wake_queue | ||
131 | #endif | ||
132 | |||
124 | #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue | 133 | #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue |
125 | 134 | ||
126 | static inline void iwl_disable_interrupts(struct iwl_priv *priv) | 135 | static inline void iwl_disable_interrupts(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 869edc580ec6..c56eae74c3cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -38,18 +38,18 @@ | |||
38 | static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val) | 38 | static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val) |
39 | { | 39 | { |
40 | trace_iwlwifi_dev_iowrite8(priv, ofs, val); | 40 | trace_iwlwifi_dev_iowrite8(priv, ofs, val); |
41 | iowrite8(val, priv->hw_base + ofs); | 41 | priv->bus.ops->write8(&priv->bus, ofs, val); |
42 | } | 42 | } |
43 | 43 | ||
44 | static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) | 44 | static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) |
45 | { | 45 | { |
46 | trace_iwlwifi_dev_iowrite32(priv, ofs, val); | 46 | trace_iwlwifi_dev_iowrite32(priv, ofs, val); |
47 | iowrite32(val, priv->hw_base + ofs); | 47 | priv->bus.ops->write32(&priv->bus, ofs, val); |
48 | } | 48 | } |
49 | 49 | ||
50 | static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs) | 50 | static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs) |
51 | { | 51 | { |
52 | u32 val = ioread32(priv->hw_base + ofs); | 52 | u32 val = priv->bus.ops->read32(&priv->bus, ofs); |
53 | trace_iwlwifi_dev_ioread32(priv, ofs, val); | 53 | trace_iwlwifi_dev_ioread32(priv, ofs, val); |
54 | return val; | 54 | return val; |
55 | } | 55 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 7c23beb49d7c..ff08da099754 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -28,8 +28,6 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/pci.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
34 | #include <linux/skbuff.h> | 32 | #include <linux/skbuff.h> |
35 | #include <linux/netdevice.h> | 33 | #include <linux/netdevice.h> |
@@ -40,14 +38,9 @@ | |||
40 | 38 | ||
41 | #include "iwl-dev.h" | 39 | #include "iwl-dev.h" |
42 | #include "iwl-core.h" | 40 | #include "iwl-core.h" |
41 | #include "iwl-agn.h" | ||
43 | #include "iwl-io.h" | 42 | #include "iwl-io.h" |
44 | 43 | ||
45 | /* default: IWL_LED_BLINK(0) using blinking index table */ | ||
46 | static int led_mode; | ||
47 | module_param(led_mode, int, S_IRUGO); | ||
48 | MODULE_PARM_DESC(led_mode, "0=system default, " | ||
49 | "1=On(RF On)/Off(RF Off), 2=blinking"); | ||
50 | |||
51 | /* Throughput OFF time(ms) ON time (ms) | 44 | /* Throughput OFF time(ms) ON time (ms) |
52 | * >300 25 25 | 45 | * >300 25 25 |
53 | * >200 to 300 40 40 | 46 | * >200 to 300 40 40 |
@@ -181,7 +174,7 @@ static int iwl_led_blink_set(struct led_classdev *led_cdev, | |||
181 | 174 | ||
182 | void iwl_leds_init(struct iwl_priv *priv) | 175 | void iwl_leds_init(struct iwl_priv *priv) |
183 | { | 176 | { |
184 | int mode = led_mode; | 177 | int mode = iwlagn_mod_params.led_mode; |
185 | int ret; | 178 | int ret; |
186 | 179 | ||
187 | if (mode == IWL_LED_DEFAULT) | 180 | if (mode == IWL_LED_DEFAULT) |
@@ -209,7 +202,8 @@ void iwl_leds_init(struct iwl_priv *priv) | |||
209 | break; | 202 | break; |
210 | } | 203 | } |
211 | 204 | ||
212 | ret = led_classdev_register(&priv->pci_dev->dev, &priv->led); | 205 | ret = led_classdev_register(priv->bus.dev, |
206 | &priv->led); | ||
213 | if (ret) { | 207 | if (ret) { |
214 | kfree(priv->led.name); | 208 | kfree(priv->led.name); |
215 | return; | 209 | return; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c new file mode 100644 index 000000000000..7328fbff7f7b --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
@@ -0,0 +1,571 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | #include <linux/pci.h> | ||
64 | #include <linux/pci-aspm.h> | ||
65 | |||
66 | #include "iwl-pci.h" | ||
67 | #include "iwl-agn.h" | ||
68 | #include "iwl-core.h" | ||
69 | #include "iwl-io.h" | ||
70 | |||
71 | /* PCI registers */ | ||
72 | #define PCI_CFG_RETRY_TIMEOUT 0x041 | ||
73 | #define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 | ||
74 | #define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 | ||
75 | |||
76 | struct iwl_pci_bus { | ||
77 | /* basic pci-network driver stuff */ | ||
78 | struct pci_dev *pci_dev; | ||
79 | |||
80 | /* pci hardware address support */ | ||
81 | void __iomem *hw_base; | ||
82 | }; | ||
83 | |||
84 | #define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ | ||
85 | ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) | ||
86 | |||
87 | #define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ | ||
88 | ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) | ||
89 | |||
90 | static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus) | ||
91 | { | ||
92 | int pos; | ||
93 | u16 pci_lnk_ctl; | ||
94 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | ||
95 | |||
96 | pos = pci_find_capability(pci_dev, PCI_CAP_ID_EXP); | ||
97 | pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); | ||
98 | return pci_lnk_ctl; | ||
99 | } | ||
100 | |||
101 | static bool iwl_pci_is_pm_supported(struct iwl_bus *bus) | ||
102 | { | ||
103 | u16 lctl = iwl_pciexp_link_ctrl(bus); | ||
104 | |||
105 | return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); | ||
106 | } | ||
107 | |||
108 | static void iwl_pci_apm_config(struct iwl_bus *bus) | ||
109 | { | ||
110 | /* | ||
111 | * HW bug W/A for instability in PCIe bus L0S->L1 transition. | ||
112 | * Check if BIOS (or OS) enabled L1-ASPM on this device. | ||
113 | * If so (likely), disable L0S, so device moves directly L0->L1; | ||
114 | * costs negligible amount of power savings. | ||
115 | * If not (unlikely), enable L0S, so there is at least some | ||
116 | * power savings, even without L1. | ||
117 | */ | ||
118 | u16 lctl = iwl_pciexp_link_ctrl(bus); | ||
119 | |||
120 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == | ||
121 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { | ||
122 | /* L1-ASPM enabled; disable(!) L0S */ | ||
123 | iwl_set_bit(bus->priv, CSR_GIO_REG, | ||
124 | CSR_GIO_REG_VAL_L0S_ENABLED); | ||
125 | IWL_DEBUG_POWER(bus->priv, "L1 Enabled; Disabling L0S\n"); | ||
126 | } else { | ||
127 | /* L1-ASPM disabled; enable(!) L0S */ | ||
128 | iwl_clear_bit(bus->priv, CSR_GIO_REG, | ||
129 | CSR_GIO_REG_VAL_L0S_ENABLED); | ||
130 | IWL_DEBUG_POWER(bus->priv, "L1 Disabled; Enabling L0S\n"); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_priv) | ||
135 | { | ||
136 | pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_priv); | ||
137 | } | ||
138 | |||
139 | static struct device *iwl_pci_get_dev(const struct iwl_bus *bus) | ||
140 | { | ||
141 | return &(IWL_BUS_GET_PCI_DEV(bus)->dev); | ||
142 | } | ||
143 | |||
144 | static unsigned int iwl_pci_get_irq(const struct iwl_bus *bus) | ||
145 | { | ||
146 | return IWL_BUS_GET_PCI_DEV(bus)->irq; | ||
147 | } | ||
148 | |||
149 | static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], | ||
150 | int buf_len) | ||
151 | { | ||
152 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | ||
153 | |||
154 | snprintf(buf, buf_len, "PCI ID: 0x%04X:0x%04X", pci_dev->device, | ||
155 | pci_dev->subsystem_device); | ||
156 | } | ||
157 | |||
158 | static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) | ||
159 | { | ||
160 | iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); | ||
161 | } | ||
162 | |||
163 | static void iwl_pci_write32(struct iwl_bus *bus, u32 ofs, u32 val) | ||
164 | { | ||
165 | iowrite32(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); | ||
166 | } | ||
167 | |||
168 | static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) | ||
169 | { | ||
170 | u32 val = ioread32(IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); | ||
171 | return val; | ||
172 | } | ||
173 | |||
174 | static struct iwl_bus_ops pci_ops = { | ||
175 | .get_pm_support = iwl_pci_is_pm_supported, | ||
176 | .apm_config = iwl_pci_apm_config, | ||
177 | .set_drv_data = iwl_pci_set_drv_data, | ||
178 | .get_dev = iwl_pci_get_dev, | ||
179 | .get_irq = iwl_pci_get_irq, | ||
180 | .get_hw_id = iwl_pci_get_hw_id, | ||
181 | .write8 = iwl_pci_write8, | ||
182 | .write32 = iwl_pci_write32, | ||
183 | .read32 = iwl_pci_read32, | ||
184 | }; | ||
185 | |||
186 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ | ||
187 | .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ | ||
188 | .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ | ||
189 | .driver_data = (kernel_ulong_t)&(cfg) | ||
190 | |||
191 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | ||
192 | static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | ||
193 | {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ | ||
194 | {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
195 | {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ | ||
196 | {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
197 | {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ | ||
198 | {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ | ||
199 | {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ | ||
200 | {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ | ||
201 | {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ | ||
202 | {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
203 | {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ | ||
204 | {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
205 | {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ | ||
206 | {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ | ||
207 | {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ | ||
208 | {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ | ||
209 | {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ | ||
210 | {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
211 | {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ | ||
212 | {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
213 | {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ | ||
214 | {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ | ||
215 | {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ | ||
216 | {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ | ||
217 | |||
218 | /* 5300 Series WiFi */ | ||
219 | {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ | ||
220 | {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
221 | {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ | ||
222 | {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
223 | {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ | ||
224 | {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
225 | {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ | ||
226 | {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
227 | {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ | ||
228 | {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
229 | {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ | ||
230 | {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
231 | |||
232 | /* 5350 Series WiFi/WiMax */ | ||
233 | {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ | ||
234 | {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ | ||
235 | {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ | ||
236 | |||
237 | /* 5150 Series Wifi/WiMax */ | ||
238 | {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ | ||
239 | {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
240 | {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ | ||
241 | {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
242 | {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ | ||
243 | {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
244 | |||
245 | {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ | ||
246 | {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
247 | {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ | ||
248 | {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
249 | |||
250 | /* 6x00 Series */ | ||
251 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, | ||
252 | {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, | ||
253 | {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, | ||
254 | {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, | ||
255 | {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, | ||
256 | {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, | ||
257 | {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, | ||
258 | {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, | ||
259 | {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, | ||
260 | {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, | ||
261 | |||
262 | /* 6x05 Series */ | ||
263 | {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, | ||
264 | {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, | ||
265 | {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, | ||
266 | {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, | ||
267 | {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, | ||
268 | {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, | ||
269 | {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, | ||
270 | |||
271 | /* 6x30 Series */ | ||
272 | {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, | ||
273 | {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, | ||
274 | {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, | ||
275 | {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)}, | ||
276 | {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)}, | ||
277 | {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)}, | ||
278 | {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)}, | ||
279 | {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)}, | ||
280 | {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)}, | ||
281 | {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)}, | ||
282 | {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)}, | ||
283 | {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)}, | ||
284 | {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)}, | ||
285 | {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)}, | ||
286 | {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)}, | ||
287 | {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)}, | ||
288 | |||
289 | /* 6x50 WiFi/WiMax Series */ | ||
290 | {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, | ||
291 | {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, | ||
292 | {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, | ||
293 | {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, | ||
294 | {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, | ||
295 | {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, | ||
296 | |||
297 | /* 6150 WiFi/WiMax Series */ | ||
298 | {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, | ||
299 | {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, | ||
300 | {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, | ||
301 | {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, | ||
302 | {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, | ||
303 | {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, | ||
304 | |||
305 | /* 1000 Series WiFi */ | ||
306 | {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, | ||
307 | {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, | ||
308 | {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)}, | ||
309 | {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)}, | ||
310 | {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)}, | ||
311 | {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)}, | ||
312 | {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)}, | ||
313 | {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)}, | ||
314 | {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)}, | ||
315 | {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, | ||
316 | {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, | ||
317 | {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, | ||
318 | |||
319 | /* 100 Series WiFi */ | ||
320 | {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, | ||
321 | {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, | ||
322 | {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, | ||
323 | {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)}, | ||
324 | {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, | ||
325 | {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)}, | ||
326 | |||
327 | /* 130 Series WiFi */ | ||
328 | {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, | ||
329 | {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, | ||
330 | {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, | ||
331 | {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, | ||
332 | {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, | ||
333 | {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, | ||
334 | |||
335 | /* 2x00 Series */ | ||
336 | {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, | ||
337 | {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, | ||
338 | {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, | ||
339 | {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, | ||
340 | {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, | ||
341 | {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, | ||
342 | |||
343 | /* 2x30 Series */ | ||
344 | {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, | ||
345 | {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, | ||
346 | {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, | ||
347 | {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, | ||
348 | {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, | ||
349 | {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, | ||
350 | |||
351 | /* 6x35 Series */ | ||
352 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, | ||
353 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | ||
354 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | ||
355 | {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, | ||
356 | {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, | ||
357 | {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, | ||
358 | {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, | ||
359 | {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, | ||
360 | {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, | ||
361 | |||
362 | /* 105 Series */ | ||
363 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, | ||
364 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, | ||
365 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, | ||
366 | {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, | ||
367 | {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, | ||
368 | {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, | ||
369 | |||
370 | /* 135 Series */ | ||
371 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, | ||
372 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, | ||
373 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, | ||
374 | {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, | ||
375 | {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, | ||
376 | {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, | ||
377 | |||
378 | {0} | ||
379 | }; | ||
380 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); | ||
381 | |||
382 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
383 | { | ||
384 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | ||
385 | struct iwl_pci_bus *bus; | ||
386 | u8 rev_id; | ||
387 | u16 pci_cmd; | ||
388 | int err; | ||
389 | |||
390 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); | ||
391 | if (!bus) { | ||
392 | pr_err("Couldn't allocate iwl_pci_bus"); | ||
393 | err = -ENOMEM; | ||
394 | goto out_no_pci; | ||
395 | } | ||
396 | |||
397 | bus->pci_dev = pdev; | ||
398 | |||
399 | /* W/A - seems to solve weird behavior. We need to remove this if we | ||
400 | * don't want to stay in L1 all the time. This wastes a lot of power */ | ||
401 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | ||
402 | PCIE_LINK_STATE_CLKPM); | ||
403 | |||
404 | if (pci_enable_device(pdev)) { | ||
405 | err = -ENODEV; | ||
406 | goto out_no_pci; | ||
407 | } | ||
408 | |||
409 | pci_set_master(pdev); | ||
410 | |||
411 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
412 | if (!err) | ||
413 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); | ||
414 | if (err) { | ||
415 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
416 | if (!err) | ||
417 | err = pci_set_consistent_dma_mask(pdev, | ||
418 | DMA_BIT_MASK(32)); | ||
419 | /* both attempts failed: */ | ||
420 | if (err) { | ||
421 | pr_err("No suitable DMA available.\n"); | ||
422 | goto out_pci_disable_device; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | err = pci_request_regions(pdev, DRV_NAME); | ||
427 | if (err) { | ||
428 | pr_err("pci_request_regions failed"); | ||
429 | goto out_pci_disable_device; | ||
430 | } | ||
431 | |||
432 | bus->hw_base = pci_iomap(pdev, 0, 0); | ||
433 | if (!bus->hw_base) { | ||
434 | pr_err("pci_iomap failed"); | ||
435 | err = -ENODEV; | ||
436 | goto out_pci_release_regions; | ||
437 | } | ||
438 | |||
439 | pr_info("pci_resource_len = 0x%08llx\n", | ||
440 | (unsigned long long) pci_resource_len(pdev, 0)); | ||
441 | pr_info("pci_resource_base = %p\n", bus->hw_base); | ||
442 | |||
443 | pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); | ||
444 | pr_info("HW Revision ID = 0x%X\n", rev_id); | ||
445 | |||
446 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | ||
447 | * PCI Tx retries from interfering with C3 CPU state */ | ||
448 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
449 | |||
450 | err = pci_enable_msi(pdev); | ||
451 | if (err) { | ||
452 | pr_err("pci_enable_msi failed"); | ||
453 | goto out_iounmap; | ||
454 | } | ||
455 | |||
456 | /* TODO: Move this away, not needed if not MSI */ | ||
457 | /* enable rfkill interrupt: hw bug w/a */ | ||
458 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | ||
459 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
460 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
461 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | ||
462 | } | ||
463 | |||
464 | err = iwl_probe((void *) bus, &pci_ops, cfg); | ||
465 | if (err) | ||
466 | goto out_disable_msi; | ||
467 | return 0; | ||
468 | |||
469 | out_disable_msi: | ||
470 | pci_disable_msi(pdev); | ||
471 | out_iounmap: | ||
472 | pci_iounmap(pdev, bus->hw_base); | ||
473 | out_pci_release_regions: | ||
474 | pci_set_drvdata(pdev, NULL); | ||
475 | pci_release_regions(pdev); | ||
476 | out_pci_disable_device: | ||
477 | pci_disable_device(pdev); | ||
478 | out_no_pci: | ||
479 | kfree(bus); | ||
480 | return err; | ||
481 | } | ||
482 | |||
483 | static void iwl_pci_down(void *bus) | ||
484 | { | ||
485 | struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus; | ||
486 | |||
487 | pci_disable_msi(pci_bus->pci_dev); | ||
488 | pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base); | ||
489 | pci_release_regions(pci_bus->pci_dev); | ||
490 | pci_disable_device(pci_bus->pci_dev); | ||
491 | pci_set_drvdata(pci_bus->pci_dev, NULL); | ||
492 | |||
493 | kfree(pci_bus); | ||
494 | } | ||
495 | |||
496 | static void __devexit iwl_pci_remove(struct pci_dev *pdev) | ||
497 | { | ||
498 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
499 | |||
500 | /* This can happen if probe failed */ | ||
501 | if (unlikely(!priv)) | ||
502 | return; | ||
503 | |||
504 | iwl_remove(priv); | ||
505 | |||
506 | iwl_pci_down(IWL_BUS_GET_PCI_BUS(&priv->bus)); | ||
507 | } | ||
508 | |||
509 | #ifdef CONFIG_PM | ||
510 | |||
511 | static int iwl_pci_suspend(struct device *device) | ||
512 | { | ||
513 | struct pci_dev *pdev = to_pci_dev(device); | ||
514 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
515 | |||
516 | return iwl_suspend(priv); | ||
517 | } | ||
518 | |||
519 | static int iwl_pci_resume(struct device *device) | ||
520 | { | ||
521 | struct pci_dev *pdev = to_pci_dev(device); | ||
522 | struct iwl_priv *priv = pci_get_drvdata(pdev); | ||
523 | |||
524 | /* | ||
525 | * We disable the RETRY_TIMEOUT register (0x41) to keep | ||
526 | * PCI Tx retries from interfering with C3 CPU state. | ||
527 | */ | ||
528 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
529 | |||
530 | return iwl_resume(priv); | ||
531 | } | ||
532 | |||
533 | static const struct dev_pm_ops iwl_dev_pm_ops = { | ||
534 | .suspend = iwl_pci_suspend, | ||
535 | .resume = iwl_pci_resume, | ||
536 | .freeze = iwl_pci_suspend, | ||
537 | .thaw = iwl_pci_resume, | ||
538 | .poweroff = iwl_pci_suspend, | ||
539 | .restore = iwl_pci_resume, | ||
540 | }; | ||
541 | |||
542 | #define IWL_PM_OPS (&iwl_dev_pm_ops) | ||
543 | |||
544 | #else | ||
545 | |||
546 | #define IWL_PM_OPS NULL | ||
547 | |||
548 | #endif | ||
549 | |||
550 | static struct pci_driver iwl_pci_driver = { | ||
551 | .name = DRV_NAME, | ||
552 | .id_table = iwl_hw_card_ids, | ||
553 | .probe = iwl_pci_probe, | ||
554 | .remove = __devexit_p(iwl_pci_remove), | ||
555 | .driver.pm = IWL_PM_OPS, | ||
556 | }; | ||
557 | |||
558 | int __must_check iwl_pci_register_driver(void) | ||
559 | { | ||
560 | int ret; | ||
561 | ret = pci_register_driver(&iwl_pci_driver); | ||
562 | if (ret) | ||
563 | pr_err("Unable to initialize PCI module\n"); | ||
564 | |||
565 | return ret; | ||
566 | } | ||
567 | |||
568 | void iwl_pci_unregister_driver(void) | ||
569 | { | ||
570 | pci_unregister_driver(&iwl_pci_driver); | ||
571 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.h b/drivers/net/wireless/iwlwifi/iwl-pci.h new file mode 100644 index 000000000000..9396c7c8d6a4 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-pci.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | #ifndef __iwl_pci_h__ | ||
64 | #define __iwl_pci_h__ | ||
65 | |||
66 | int __must_check iwl_pci_register_driver(void); | ||
67 | void iwl_pci_unregister_driver(void); | ||
68 | |||
69 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 595c930b28ae..565e57e48be8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #include "iwl-eeprom.h" | 37 | #include "iwl-eeprom.h" |
38 | #include "iwl-dev.h" | 38 | #include "iwl-dev.h" |
39 | #include "iwl-agn.h" | ||
39 | #include "iwl-core.h" | 40 | #include "iwl-core.h" |
40 | #include "iwl-io.h" | 41 | #include "iwl-io.h" |
41 | #include "iwl-commands.h" | 42 | #include "iwl-commands.h" |
@@ -51,16 +52,6 @@ | |||
51 | */ | 52 | */ |
52 | 53 | ||
53 | /* | 54 | /* |
54 | * For now, keep using power level 1 instead of automatically | ||
55 | * adjusting ... | ||
56 | */ | ||
57 | bool no_sleep_autoadjust = true; | ||
58 | module_param(no_sleep_autoadjust, bool, S_IRUGO); | ||
59 | MODULE_PARM_DESC(no_sleep_autoadjust, | ||
60 | "don't automatically adjust sleep level " | ||
61 | "according to maximum network latency"); | ||
62 | |||
63 | /* | ||
64 | * This defines the old power levels. They are still used by default | 55 | * This defines the old power levels. They are still used by default |
65 | * (level 1) and for thermal throttle (levels 3 through 5) | 56 | * (level 1) and for thermal throttle (levels 3 through 5) |
66 | */ | 57 | */ |
@@ -254,7 +245,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
254 | } | 245 | } |
255 | } | 246 | } |
256 | 247 | ||
257 | if (priv->power_data.pci_pm) | 248 | if (priv->power_data.bus_pm) |
258 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | 249 | cmd->flags |= IWL_POWER_PCI_PM_MSK; |
259 | else | 250 | else |
260 | cmd->flags &= ~IWL_POWER_PCI_PM_MSK; | 251 | cmd->flags &= ~IWL_POWER_PCI_PM_MSK; |
@@ -269,7 +260,7 @@ static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv, | |||
269 | { | 260 | { |
270 | memset(cmd, 0, sizeof(*cmd)); | 261 | memset(cmd, 0, sizeof(*cmd)); |
271 | 262 | ||
272 | if (priv->power_data.pci_pm) | 263 | if (priv->power_data.bus_pm) |
273 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | 264 | cmd->flags |= IWL_POWER_PCI_PM_MSK; |
274 | 265 | ||
275 | IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); | 266 | IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); |
@@ -305,7 +296,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, | |||
305 | cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | | 296 | cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | |
306 | IWL_POWER_FAST_PD; /* no use seeing frames for others */ | 297 | IWL_POWER_FAST_PD; /* no use seeing frames for others */ |
307 | 298 | ||
308 | if (priv->power_data.pci_pm) | 299 | if (priv->power_data.bus_pm) |
309 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | 300 | cmd->flags |= IWL_POWER_PCI_PM_MSK; |
310 | 301 | ||
311 | if (priv->cfg->base_params->shadow_reg_enable) | 302 | if (priv->cfg->base_params->shadow_reg_enable) |
@@ -367,9 +358,15 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, | |||
367 | iwl_static_sleep_cmd(priv, cmd, | 358 | iwl_static_sleep_cmd(priv, cmd, |
368 | priv->power_data.debug_sleep_level_override, | 359 | priv->power_data.debug_sleep_level_override, |
369 | dtimper); | 360 | dtimper); |
370 | else if (no_sleep_autoadjust) | 361 | else if (iwlagn_mod_params.no_sleep_autoadjust) { |
371 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper); | 362 | if (iwlagn_mod_params.power_level > IWL_POWER_INDEX_1 && |
372 | else | 363 | iwlagn_mod_params.power_level <= IWL_POWER_INDEX_5) |
364 | iwl_static_sleep_cmd(priv, cmd, | ||
365 | iwlagn_mod_params.power_level, dtimper); | ||
366 | else | ||
367 | iwl_static_sleep_cmd(priv, cmd, | ||
368 | IWL_POWER_INDEX_1, dtimper); | ||
369 | } else | ||
373 | iwl_power_fill_sleep_cmd(priv, cmd, | 370 | iwl_power_fill_sleep_cmd(priv, cmd, |
374 | priv->hw->conf.dynamic_ps_timeout, | 371 | priv->hw->conf.dynamic_ps_timeout, |
375 | priv->hw->conf.max_sleep_period); | 372 | priv->hw->conf.max_sleep_period); |
@@ -434,9 +431,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) | |||
434 | /* initialize to default */ | 431 | /* initialize to default */ |
435 | void iwl_power_initialize(struct iwl_priv *priv) | 432 | void iwl_power_initialize(struct iwl_priv *priv) |
436 | { | 433 | { |
437 | u16 lctl = iwl_pcie_link_ctl(priv); | 434 | priv->power_data.bus_pm = priv->bus.ops->get_pm_support(&priv->bus); |
438 | |||
439 | priv->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); | ||
440 | 435 | ||
441 | priv->power_data.debug_sleep_level_override = -1; | 436 | priv->power_data.debug_sleep_level_override = -1; |
442 | 437 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 59635d784e27..5f7b720cf1a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h | |||
@@ -43,7 +43,7 @@ struct iwl_power_mgr { | |||
43 | struct iwl_powertable_cmd sleep_cmd; | 43 | struct iwl_powertable_cmd sleep_cmd; |
44 | struct iwl_powertable_cmd sleep_cmd_next; | 44 | struct iwl_powertable_cmd sleep_cmd_next; |
45 | int debug_sleep_level_override; | 45 | int debug_sleep_level_override; |
46 | bool pci_pm; | 46 | bool bus_pm; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, | 49 | int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index b774517aa9fa..3efa7066e987 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -182,7 +182,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q | |||
182 | int iwl_rx_queue_alloc(struct iwl_priv *priv) | 182 | int iwl_rx_queue_alloc(struct iwl_priv *priv) |
183 | { | 183 | { |
184 | struct iwl_rx_queue *rxq = &priv->rxq; | 184 | struct iwl_rx_queue *rxq = &priv->rxq; |
185 | struct device *dev = &priv->pci_dev->dev; | 185 | struct device *dev = priv->bus.dev; |
186 | int i; | 186 | int i; |
187 | 187 | ||
188 | spin_lock_init(&rxq->lock); | 188 | spin_lock_init(&rxq->lock); |
@@ -213,7 +213,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) | |||
213 | return 0; | 213 | return 0; |
214 | 214 | ||
215 | err_rb: | 215 | err_rb: |
216 | dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, | 216 | dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd, |
217 | rxq->bd_dma); | 217 | rxq->bd_dma); |
218 | err_bd: | 218 | err_bd: |
219 | return -ENOMEM; | 219 | return -ENOMEM; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 69b7e6bf2d6f..c00aa5a1b8b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c | |||
@@ -69,7 +69,6 @@ | |||
69 | #include <net/mac80211.h> | 69 | #include <net/mac80211.h> |
70 | #include <net/netlink.h> | 70 | #include <net/netlink.h> |
71 | 71 | ||
72 | |||
73 | #include "iwl-dev.h" | 72 | #include "iwl-dev.h" |
74 | #include "iwl-core.h" | 73 | #include "iwl-core.h" |
75 | #include "iwl-debug.h" | 74 | #include "iwl-debug.h" |
@@ -101,9 +100,11 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | |||
101 | [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, | 100 | [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, |
102 | 101 | ||
103 | [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, | 102 | [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, |
104 | [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, }, | 103 | [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, }, |
104 | [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, }, | ||
105 | 105 | ||
106 | [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, | 106 | [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, |
107 | |||
107 | }; | 108 | }; |
108 | 109 | ||
109 | /* | 110 | /* |
@@ -179,19 +180,21 @@ void iwl_testmode_init(struct iwl_priv *priv) | |||
179 | 180 | ||
180 | static void iwl_trace_cleanup(struct iwl_priv *priv) | 181 | static void iwl_trace_cleanup(struct iwl_priv *priv) |
181 | { | 182 | { |
182 | struct device *dev = &priv->pci_dev->dev; | 183 | struct device *dev = priv->bus.dev; |
183 | 184 | ||
184 | if (priv->testmode_trace.trace_enabled) { | 185 | if (priv->testmode_trace.trace_enabled) { |
185 | if (priv->testmode_trace.cpu_addr && | 186 | if (priv->testmode_trace.cpu_addr && |
186 | priv->testmode_trace.dma_addr) | 187 | priv->testmode_trace.dma_addr) |
187 | dma_free_coherent(dev, | 188 | dma_free_coherent(dev, |
188 | TRACE_TOTAL_SIZE, | 189 | priv->testmode_trace.total_size, |
189 | priv->testmode_trace.cpu_addr, | 190 | priv->testmode_trace.cpu_addr, |
190 | priv->testmode_trace.dma_addr); | 191 | priv->testmode_trace.dma_addr); |
191 | priv->testmode_trace.trace_enabled = false; | 192 | priv->testmode_trace.trace_enabled = false; |
192 | priv->testmode_trace.cpu_addr = NULL; | 193 | priv->testmode_trace.cpu_addr = NULL; |
193 | priv->testmode_trace.trace_addr = NULL; | 194 | priv->testmode_trace.trace_addr = NULL; |
194 | priv->testmode_trace.dma_addr = 0; | 195 | priv->testmode_trace.dma_addr = 0; |
196 | priv->testmode_trace.buff_size = 0; | ||
197 | priv->testmode_trace.total_size = 0; | ||
195 | } | 198 | } |
196 | } | 199 | } |
197 | 200 | ||
@@ -394,7 +397,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
394 | 397 | ||
395 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | 398 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: |
396 | status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, | 399 | status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, |
397 | UCODE_SUBTYPE_INIT, -1); | 400 | IWL_UCODE_INIT); |
398 | if (status) | 401 | if (status) |
399 | IWL_DEBUG_INFO(priv, | 402 | IWL_DEBUG_INFO(priv, |
400 | "Error loading init ucode: %d\n", status); | 403 | "Error loading init ucode: %d\n", status); |
@@ -408,8 +411,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
408 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 411 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
409 | status = iwlagn_load_ucode_wait_alive(priv, | 412 | status = iwlagn_load_ucode_wait_alive(priv, |
410 | &priv->ucode_rt, | 413 | &priv->ucode_rt, |
411 | UCODE_SUBTYPE_REGULAR, | 414 | IWL_UCODE_REGULAR); |
412 | UCODE_SUBTYPE_REGULAR_NEW); | ||
413 | if (status) { | 415 | if (status) { |
414 | IWL_DEBUG_INFO(priv, | 416 | IWL_DEBUG_INFO(priv, |
415 | "Error loading runtime ucode: %d\n", status); | 417 | "Error loading runtime ucode: %d\n", status); |
@@ -482,16 +484,29 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) | |||
482 | struct iwl_priv *priv = hw->priv; | 484 | struct iwl_priv *priv = hw->priv; |
483 | struct sk_buff *skb; | 485 | struct sk_buff *skb; |
484 | int status = 0; | 486 | int status = 0; |
485 | struct device *dev = &priv->pci_dev->dev; | 487 | struct device *dev = priv->bus.dev; |
486 | 488 | ||
487 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 489 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { |
488 | case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: | 490 | case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: |
489 | if (priv->testmode_trace.trace_enabled) | 491 | if (priv->testmode_trace.trace_enabled) |
490 | return -EBUSY; | 492 | return -EBUSY; |
491 | 493 | ||
494 | if (!tb[IWL_TM_ATTR_TRACE_SIZE]) | ||
495 | priv->testmode_trace.buff_size = TRACE_BUFF_SIZE_DEF; | ||
496 | else | ||
497 | priv->testmode_trace.buff_size = | ||
498 | nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]); | ||
499 | if (!priv->testmode_trace.buff_size) | ||
500 | return -EINVAL; | ||
501 | if (priv->testmode_trace.buff_size < TRACE_BUFF_SIZE_MIN || | ||
502 | priv->testmode_trace.buff_size > TRACE_BUFF_SIZE_MAX) | ||
503 | return -EINVAL; | ||
504 | |||
505 | priv->testmode_trace.total_size = | ||
506 | priv->testmode_trace.buff_size + TRACE_BUFF_PADD; | ||
492 | priv->testmode_trace.cpu_addr = | 507 | priv->testmode_trace.cpu_addr = |
493 | dma_alloc_coherent(dev, | 508 | dma_alloc_coherent(dev, |
494 | TRACE_TOTAL_SIZE, | 509 | priv->testmode_trace.total_size, |
495 | &priv->testmode_trace.dma_addr, | 510 | &priv->testmode_trace.dma_addr, |
496 | GFP_KERNEL); | 511 | GFP_KERNEL); |
497 | if (!priv->testmode_trace.cpu_addr) | 512 | if (!priv->testmode_trace.cpu_addr) |
@@ -500,7 +515,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) | |||
500 | priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN( | 515 | priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN( |
501 | priv->testmode_trace.cpu_addr, 0x100); | 516 | priv->testmode_trace.cpu_addr, 0x100); |
502 | memset(priv->testmode_trace.trace_addr, 0x03B, | 517 | memset(priv->testmode_trace.trace_addr, 0x03B, |
503 | TRACE_BUFF_SIZE); | 518 | priv->testmode_trace.buff_size); |
504 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | 519 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, |
505 | sizeof(priv->testmode_trace.dma_addr) + 20); | 520 | sizeof(priv->testmode_trace.dma_addr) + 20); |
506 | if (!skb) { | 521 | if (!skb) { |
@@ -518,34 +533,14 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) | |||
518 | "Error sending msg : %d\n", | 533 | "Error sending msg : %d\n", |
519 | status); | 534 | status); |
520 | } | 535 | } |
536 | priv->testmode_trace.num_chunks = | ||
537 | DIV_ROUND_UP(priv->testmode_trace.buff_size, | ||
538 | TRACE_CHUNK_SIZE); | ||
521 | break; | 539 | break; |
522 | 540 | ||
523 | case IWL_TM_CMD_APP2DEV_END_TRACE: | 541 | case IWL_TM_CMD_APP2DEV_END_TRACE: |
524 | iwl_trace_cleanup(priv); | 542 | iwl_trace_cleanup(priv); |
525 | break; | 543 | break; |
526 | |||
527 | case IWL_TM_CMD_APP2DEV_READ_TRACE: | ||
528 | if (priv->testmode_trace.trace_enabled && | ||
529 | priv->testmode_trace.trace_addr) { | ||
530 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | ||
531 | 20 + TRACE_BUFF_SIZE); | ||
532 | if (skb == NULL) { | ||
533 | IWL_DEBUG_INFO(priv, | ||
534 | "Error allocating memory\n"); | ||
535 | return -ENOMEM; | ||
536 | } | ||
537 | NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA, | ||
538 | TRACE_BUFF_SIZE, | ||
539 | priv->testmode_trace.trace_addr); | ||
540 | status = cfg80211_testmode_reply(skb); | ||
541 | if (status < 0) { | ||
542 | IWL_DEBUG_INFO(priv, | ||
543 | "Error sending msg : %d\n", status); | ||
544 | } | ||
545 | } else | ||
546 | return -EFAULT; | ||
547 | break; | ||
548 | |||
549 | default: | 544 | default: |
550 | IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n"); | 545 | IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n"); |
551 | return -ENOSYS; | 546 | return -ENOSYS; |
@@ -560,6 +555,37 @@ nla_put_failure: | |||
560 | return -EMSGSIZE; | 555 | return -EMSGSIZE; |
561 | } | 556 | } |
562 | 557 | ||
558 | static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, | ||
559 | struct sk_buff *skb, | ||
560 | struct netlink_callback *cb) | ||
561 | { | ||
562 | struct iwl_priv *priv = hw->priv; | ||
563 | int idx, length; | ||
564 | |||
565 | if (priv->testmode_trace.trace_enabled && | ||
566 | priv->testmode_trace.trace_addr) { | ||
567 | idx = cb->args[4]; | ||
568 | if (idx >= priv->testmode_trace.num_chunks) | ||
569 | return -ENOENT; | ||
570 | length = TRACE_CHUNK_SIZE; | ||
571 | if (((idx + 1) == priv->testmode_trace.num_chunks) && | ||
572 | (priv->testmode_trace.buff_size % TRACE_CHUNK_SIZE)) | ||
573 | length = priv->testmode_trace.buff_size % | ||
574 | TRACE_CHUNK_SIZE; | ||
575 | |||
576 | NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length, | ||
577 | priv->testmode_trace.trace_addr + | ||
578 | (TRACE_CHUNK_SIZE * idx)); | ||
579 | idx++; | ||
580 | cb->args[4] = idx; | ||
581 | return 0; | ||
582 | } else | ||
583 | return -EFAULT; | ||
584 | |||
585 | nla_put_failure: | ||
586 | return -ENOBUFS; | ||
587 | } | ||
588 | |||
563 | /* The testmode gnl message handler that takes the gnl message from the | 589 | /* The testmode gnl message handler that takes the gnl message from the |
564 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then | 590 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then |
565 | * invoke the corresponding handlers. | 591 | * invoke the corresponding handlers. |
@@ -638,3 +664,50 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
638 | mutex_unlock(&priv->mutex); | 664 | mutex_unlock(&priv->mutex); |
639 | return result; | 665 | return result; |
640 | } | 666 | } |
667 | |||
668 | int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
669 | struct netlink_callback *cb, | ||
670 | void *data, int len) | ||
671 | { | ||
672 | struct nlattr *tb[IWL_TM_ATTR_MAX]; | ||
673 | struct iwl_priv *priv = hw->priv; | ||
674 | int result; | ||
675 | u32 cmd; | ||
676 | |||
677 | if (cb->args[3]) { | ||
678 | /* offset by 1 since commands start at 0 */ | ||
679 | cmd = cb->args[3] - 1; | ||
680 | } else { | ||
681 | result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, | ||
682 | iwl_testmode_gnl_msg_policy); | ||
683 | if (result) { | ||
684 | IWL_DEBUG_INFO(priv, | ||
685 | "Error parsing the gnl message : %d\n", result); | ||
686 | return result; | ||
687 | } | ||
688 | |||
689 | /* IWL_TM_ATTR_COMMAND is absolutely mandatory */ | ||
690 | if (!tb[IWL_TM_ATTR_COMMAND]) { | ||
691 | IWL_DEBUG_INFO(priv, | ||
692 | "Error finding testmode command type\n"); | ||
693 | return -ENOMSG; | ||
694 | } | ||
695 | cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); | ||
696 | cb->args[3] = cmd + 1; | ||
697 | } | ||
698 | |||
699 | /* in case multiple accesses to the device happens */ | ||
700 | mutex_lock(&priv->mutex); | ||
701 | switch (cmd) { | ||
702 | case IWL_TM_CMD_APP2DEV_READ_TRACE: | ||
703 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); | ||
704 | result = iwl_testmode_trace_dump(hw, tb, skb, cb); | ||
705 | break; | ||
706 | default: | ||
707 | result = -EINVAL; | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | mutex_unlock(&priv->mutex); | ||
712 | return result; | ||
713 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index a88085e9b361..160911a3716a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h | |||
@@ -166,7 +166,8 @@ enum iwl_tm_attr_t { | |||
166 | * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address | 166 | * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address |
167 | */ | 167 | */ |
168 | IWL_TM_ATTR_TRACE_ADDR, | 168 | IWL_TM_ATTR_TRACE_ADDR, |
169 | IWL_TM_ATTR_TRACE_DATA, | 169 | IWL_TM_ATTR_TRACE_SIZE, |
170 | IWL_TM_ATTR_TRACE_DUMP, | ||
170 | 171 | ||
171 | /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, | 172 | /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, |
172 | * The mandatory fields are: | 173 | * The mandatory fields are: |
@@ -178,8 +179,10 @@ enum iwl_tm_attr_t { | |||
178 | }; | 179 | }; |
179 | 180 | ||
180 | /* uCode trace buffer */ | 181 | /* uCode trace buffer */ |
181 | #define TRACE_BUFF_SIZE 0x20000 | 182 | #define TRACE_BUFF_SIZE_MAX 0x200000 |
183 | #define TRACE_BUFF_SIZE_MIN 0x20000 | ||
184 | #define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN | ||
182 | #define TRACE_BUFF_PADD 0x2000 | 185 | #define TRACE_BUFF_PADD 0x2000 |
183 | #define TRACE_TOTAL_SIZE (TRACE_BUFF_SIZE + TRACE_BUFF_PADD) | 186 | #define TRACE_CHUNK_SIZE (PAGE_SIZE - 1024) |
184 | 187 | ||
185 | #endif | 188 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1084fe0e8a86..fd8aee9972c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -128,7 +128,6 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | |||
128 | static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, | 128 | static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, |
129 | struct iwl_tfd *tfd) | 129 | struct iwl_tfd *tfd) |
130 | { | 130 | { |
131 | struct pci_dev *dev = priv->pci_dev; | ||
132 | int i; | 131 | int i; |
133 | int num_tbs; | 132 | int num_tbs; |
134 | 133 | ||
@@ -143,15 +142,15 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, | |||
143 | 142 | ||
144 | /* Unmap tx_cmd */ | 143 | /* Unmap tx_cmd */ |
145 | if (num_tbs) | 144 | if (num_tbs) |
146 | pci_unmap_single(dev, | 145 | dma_unmap_single(priv->bus.dev, |
147 | dma_unmap_addr(meta, mapping), | 146 | dma_unmap_addr(meta, mapping), |
148 | dma_unmap_len(meta, len), | 147 | dma_unmap_len(meta, len), |
149 | PCI_DMA_BIDIRECTIONAL); | 148 | DMA_BIDIRECTIONAL); |
150 | 149 | ||
151 | /* Unmap chunks, if any. */ | 150 | /* Unmap chunks, if any. */ |
152 | for (i = 1; i < num_tbs; i++) | 151 | for (i = 1; i < num_tbs; i++) |
153 | pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), | 152 | dma_unmap_single(priv->bus.dev, iwl_tfd_tb_get_addr(tfd, i), |
154 | iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); | 153 | iwl_tfd_tb_get_len(tfd, i), DMA_TO_DEVICE); |
155 | } | 154 | } |
156 | 155 | ||
157 | /** | 156 | /** |
@@ -266,7 +265,7 @@ void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) | |||
266 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | 265 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) |
267 | { | 266 | { |
268 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 267 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
269 | struct device *dev = &priv->pci_dev->dev; | 268 | struct device *dev = priv->bus.dev; |
270 | int i; | 269 | int i; |
271 | 270 | ||
272 | iwl_tx_queue_unmap(priv, txq_id); | 271 | iwl_tx_queue_unmap(priv, txq_id); |
@@ -310,10 +309,10 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) | |||
310 | i = get_cmd_index(q, q->read_ptr); | 309 | i = get_cmd_index(q, q->read_ptr); |
311 | 310 | ||
312 | if (txq->meta[i].flags & CMD_MAPPED) { | 311 | if (txq->meta[i].flags & CMD_MAPPED) { |
313 | pci_unmap_single(priv->pci_dev, | 312 | dma_unmap_single(priv->bus.dev, |
314 | dma_unmap_addr(&txq->meta[i], mapping), | 313 | dma_unmap_addr(&txq->meta[i], mapping), |
315 | dma_unmap_len(&txq->meta[i], len), | 314 | dma_unmap_len(&txq->meta[i], len), |
316 | PCI_DMA_BIDIRECTIONAL); | 315 | DMA_BIDIRECTIONAL); |
317 | txq->meta[i].flags = 0; | 316 | txq->meta[i].flags = 0; |
318 | } | 317 | } |
319 | 318 | ||
@@ -332,7 +331,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) | |||
332 | void iwl_cmd_queue_free(struct iwl_priv *priv) | 331 | void iwl_cmd_queue_free(struct iwl_priv *priv) |
333 | { | 332 | { |
334 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | 333 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; |
335 | struct device *dev = &priv->pci_dev->dev; | 334 | struct device *dev = priv->bus.dev; |
336 | int i; | 335 | int i; |
337 | 336 | ||
338 | iwl_cmd_queue_unmap(priv); | 337 | iwl_cmd_queue_unmap(priv); |
@@ -434,7 +433,7 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, | |||
434 | static int iwl_tx_queue_alloc(struct iwl_priv *priv, | 433 | static int iwl_tx_queue_alloc(struct iwl_priv *priv, |
435 | struct iwl_tx_queue *txq, u32 id) | 434 | struct iwl_tx_queue *txq, u32 id) |
436 | { | 435 | { |
437 | struct device *dev = &priv->pci_dev->dev; | 436 | struct device *dev = priv->bus.dev; |
438 | size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; | 437 | size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; |
439 | 438 | ||
440 | /* Driver private data, only for Tx (not command) queues, | 439 | /* Driver private data, only for Tx (not command) queues, |
@@ -456,7 +455,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, | |||
456 | txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, | 455 | txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, |
457 | GFP_KERNEL); | 456 | GFP_KERNEL); |
458 | if (!txq->tfds) { | 457 | if (!txq->tfds) { |
459 | IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); | 458 | IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz); |
460 | goto error; | 459 | goto error; |
461 | } | 460 | } |
462 | txq->q.id = id; | 461 | txq->q.id = id; |
@@ -677,9 +676,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
677 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, | 676 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, |
678 | q->write_ptr, idx, priv->cmd_queue); | 677 | q->write_ptr, idx, priv->cmd_queue); |
679 | 678 | ||
680 | phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, | 679 | phys_addr = dma_map_single(priv->bus.dev, &out_cmd->hdr, copy_size, |
681 | copy_size, PCI_DMA_BIDIRECTIONAL); | 680 | DMA_BIDIRECTIONAL); |
682 | if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { | 681 | if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) { |
683 | idx = -ENOMEM; | 682 | idx = -ENOMEM; |
684 | goto out; | 683 | goto out; |
685 | } | 684 | } |
@@ -699,9 +698,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
699 | continue; | 698 | continue; |
700 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | 699 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) |
701 | continue; | 700 | continue; |
702 | phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i], | 701 | phys_addr = dma_map_single(priv->bus.dev, (void *)cmd->data[i], |
703 | cmd->len[i], PCI_DMA_TODEVICE); | 702 | cmd->len[i], DMA_TO_DEVICE); |
704 | if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) { | 703 | if (dma_mapping_error(priv->bus.dev, phys_addr)) { |
705 | iwlagn_unmap_tfd(priv, out_meta, | 704 | iwlagn_unmap_tfd(priv, out_meta, |
706 | &txq->tfds[q->write_ptr]); | 705 | &txq->tfds[q->write_ptr]); |
707 | idx = -ENOMEM; | 706 | idx = -ENOMEM; |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 224e9853c480..387786e1b394 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -892,6 +892,37 @@ static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv) | |||
892 | 892 | ||
893 | } | 893 | } |
894 | 894 | ||
895 | static struct mmc_host *reset_host; | ||
896 | |||
897 | static void if_sdio_reset_card_worker(struct work_struct *work) | ||
898 | { | ||
899 | /* | ||
900 | * The actual reset operation must be run outside of lbs_thread. This | ||
901 | * is because mmc_remove_host() will cause the device to be instantly | ||
902 | * destroyed, and the libertas driver then needs to end lbs_thread, | ||
903 | * leading to a deadlock. | ||
904 | * | ||
905 | * We run it in a workqueue totally independent from the if_sdio_card | ||
906 | * instance for that reason. | ||
907 | */ | ||
908 | |||
909 | pr_info("Resetting card..."); | ||
910 | mmc_remove_host(reset_host); | ||
911 | mmc_add_host(reset_host); | ||
912 | } | ||
913 | static DECLARE_WORK(card_reset_work, if_sdio_reset_card_worker); | ||
914 | |||
915 | static void if_sdio_reset_card(struct lbs_private *priv) | ||
916 | { | ||
917 | struct if_sdio_card *card = priv->card; | ||
918 | |||
919 | if (work_pending(&card_reset_work)) | ||
920 | return; | ||
921 | |||
922 | reset_host = card->func->card->host; | ||
923 | schedule_work(&card_reset_work); | ||
924 | } | ||
925 | |||
895 | /*******************************************************************/ | 926 | /*******************************************************************/ |
896 | /* SDIO callbacks */ | 927 | /* SDIO callbacks */ |
897 | /*******************************************************************/ | 928 | /*******************************************************************/ |
@@ -1065,6 +1096,7 @@ static int if_sdio_probe(struct sdio_func *func, | |||
1065 | priv->enter_deep_sleep = if_sdio_enter_deep_sleep; | 1096 | priv->enter_deep_sleep = if_sdio_enter_deep_sleep; |
1066 | priv->exit_deep_sleep = if_sdio_exit_deep_sleep; | 1097 | priv->exit_deep_sleep = if_sdio_exit_deep_sleep; |
1067 | priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; | 1098 | priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; |
1099 | priv->reset_card = if_sdio_reset_card; | ||
1068 | 1100 | ||
1069 | sdio_claim_host(func); | 1101 | sdio_claim_host(func); |
1070 | 1102 | ||
@@ -1301,6 +1333,8 @@ static void __exit if_sdio_exit_module(void) | |||
1301 | /* Set the flag as user is removing this module. */ | 1333 | /* Set the flag as user is removing this module. */ |
1302 | user_rmmod = 1; | 1334 | user_rmmod = 1; |
1303 | 1335 | ||
1336 | cancel_work_sync(&card_reset_work); | ||
1337 | |||
1304 | sdio_unregister_driver(&if_sdio_driver); | 1338 | sdio_unregister_driver(&if_sdio_driver); |
1305 | 1339 | ||
1306 | lbs_deb_leave(LBS_DEB_SDIO); | 1340 | lbs_deb_leave(LBS_DEB_SDIO); |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 4fa0be9943f9..e0286cfbc91d 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -1034,7 +1034,6 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) | |||
1034 | static int if_spi_init_card(struct if_spi_card *card) | 1034 | static int if_spi_init_card(struct if_spi_card *card) |
1035 | { | 1035 | { |
1036 | struct lbs_private *priv = card->priv; | 1036 | struct lbs_private *priv = card->priv; |
1037 | struct spi_device *spi = card->spi; | ||
1038 | int err, i; | 1037 | int err, i; |
1039 | u32 scratch; | 1038 | u32 scratch; |
1040 | const struct firmware *helper = NULL; | 1039 | const struct firmware *helper = NULL; |
@@ -1082,8 +1081,9 @@ static int if_spi_init_card(struct if_spi_card *card) | |||
1082 | "attached to SPI bus_num %d, chip_select %d. " | 1081 | "attached to SPI bus_num %d, chip_select %d. " |
1083 | "spi->max_speed_hz=%d\n", | 1082 | "spi->max_speed_hz=%d\n", |
1084 | card->card_id, card->card_rev, | 1083 | card->card_id, card->card_rev, |
1085 | spi->master->bus_num, spi->chip_select, | 1084 | card->spi->master->bus_num, |
1086 | spi->max_speed_hz); | 1085 | card->spi->chip_select, |
1086 | card->spi->max_speed_hz); | ||
1087 | err = if_spi_prog_helper_firmware(card, helper); | 1087 | err = if_spi_prog_helper_firmware(card, helper); |
1088 | if (err) | 1088 | if (err) |
1089 | goto out; | 1089 | goto out; |
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 916183d39009..34bba5234294 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
@@ -185,13 +185,12 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | |||
185 | * | 185 | * |
186 | * Handling includes changing the header fields into CPU format. | 186 | * Handling includes changing the header fields into CPU format. |
187 | */ | 187 | */ |
188 | int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) | 188 | int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, |
189 | struct mwifiex_ds_11n_tx_cfg *tx_cfg) | ||
189 | { | 190 | { |
190 | struct mwifiex_ds_11n_tx_cfg *tx_cfg; | ||
191 | struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; | 191 | struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; |
192 | 192 | ||
193 | if (data_buf) { | 193 | if (tx_cfg) { |
194 | tx_cfg = (struct mwifiex_ds_11n_tx_cfg *) data_buf; | ||
195 | tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap); | 194 | tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap); |
196 | tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info); | 195 | tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info); |
197 | } | 196 | } |
@@ -208,11 +207,10 @@ int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) | |||
208 | */ | 207 | */ |
209 | int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, | 208 | int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, |
210 | struct host_cmd_ds_command *cmd, int cmd_action, | 209 | struct host_cmd_ds_command *cmd, int cmd_action, |
211 | void *data_buf) | 210 | u16 *buf_size) |
212 | { | 211 | { |
213 | struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf; | 212 | struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf; |
214 | u16 action = (u16) cmd_action; | 213 | u16 action = (u16) cmd_action; |
215 | u16 buf_size = *((u16 *) data_buf); | ||
216 | 214 | ||
217 | cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF); | 215 | cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF); |
218 | cmd->size = | 216 | cmd->size = |
@@ -220,8 +218,8 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, | |||
220 | tx_buf->action = cpu_to_le16(action); | 218 | tx_buf->action = cpu_to_le16(action); |
221 | switch (action) { | 219 | switch (action) { |
222 | case HostCmd_ACT_GEN_SET: | 220 | case HostCmd_ACT_GEN_SET: |
223 | dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", buf_size); | 221 | dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", *buf_size); |
224 | tx_buf->buff_size = cpu_to_le16(buf_size); | 222 | tx_buf->buff_size = cpu_to_le16(*buf_size); |
225 | break; | 223 | break; |
226 | case HostCmd_ACT_GEN_GET: | 224 | case HostCmd_ACT_GEN_GET: |
227 | default: | 225 | default: |
@@ -240,13 +238,12 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, | |||
240 | * - Ensuring correct endian-ness | 238 | * - Ensuring correct endian-ness |
241 | */ | 239 | */ |
242 | int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, | 240 | int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, |
243 | int cmd_action, void *data_buf) | 241 | int cmd_action, |
242 | struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl) | ||
244 | { | 243 | { |
245 | struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = | 244 | struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = |
246 | &cmd->params.amsdu_aggr_ctrl; | 245 | &cmd->params.amsdu_aggr_ctrl; |
247 | u16 action = (u16) cmd_action; | 246 | u16 action = (u16) cmd_action; |
248 | struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl = | ||
249 | (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf; | ||
250 | 247 | ||
251 | cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL); | 248 | cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL); |
252 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl) | 249 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl) |
@@ -272,15 +269,13 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, | |||
272 | * Handling includes changing the header fields into CPU format. | 269 | * Handling includes changing the header fields into CPU format. |
273 | */ | 270 | */ |
274 | int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, | 271 | int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, |
275 | void *data_buf) | 272 | struct mwifiex_ds_11n_amsdu_aggr_ctrl |
273 | *amsdu_aggr_ctrl) | ||
276 | { | 274 | { |
277 | struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl; | ||
278 | struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = | 275 | struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = |
279 | &resp->params.amsdu_aggr_ctrl; | 276 | &resp->params.amsdu_aggr_ctrl; |
280 | 277 | ||
281 | if (data_buf) { | 278 | if (amsdu_aggr_ctrl) { |
282 | amsdu_aggr_ctrl = | ||
283 | (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf; | ||
284 | amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable); | 279 | amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable); |
285 | amsdu_aggr_ctrl->curr_buf_size = | 280 | amsdu_aggr_ctrl->curr_buf_size = |
286 | le16_to_cpu(amsdu_ctrl->curr_buf_size); | 281 | le16_to_cpu(amsdu_ctrl->curr_buf_size); |
@@ -296,12 +291,10 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, | |||
296 | * - Setting HT Tx capability and HT Tx information fields | 291 | * - Setting HT Tx capability and HT Tx information fields |
297 | * - Ensuring correct endian-ness | 292 | * - Ensuring correct endian-ness |
298 | */ | 293 | */ |
299 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, | 294 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, |
300 | u16 cmd_action, void *data_buf) | 295 | struct mwifiex_ds_11n_tx_cfg *txcfg) |
301 | { | 296 | { |
302 | struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; | 297 | struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; |
303 | struct mwifiex_ds_11n_tx_cfg *txcfg = | ||
304 | (struct mwifiex_ds_11n_tx_cfg *) data_buf; | ||
305 | 298 | ||
306 | cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG); | 299 | cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG); |
307 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN); | 300 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN); |
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index a4390a1a2a9f..90b421e343d4 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h | |||
@@ -29,9 +29,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, | |||
29 | int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | 29 | int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, |
30 | struct host_cmd_ds_command *resp); | 30 | struct host_cmd_ds_command *resp); |
31 | int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, | 31 | int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, |
32 | void *data_buf); | 32 | struct mwifiex_ds_11n_tx_cfg *tx_cfg); |
33 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, | 33 | int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, |
34 | u16 cmd_action, void *data_buf); | 34 | struct mwifiex_ds_11n_tx_cfg *txcfg); |
35 | 35 | ||
36 | int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | 36 | int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, |
37 | struct mwifiex_bssdescriptor *bss_desc, | 37 | struct mwifiex_bssdescriptor *bss_desc, |
@@ -62,12 +62,14 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, | |||
62 | int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, | 62 | int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, |
63 | struct mwifiex_ds_tx_ba_stream_tbl *buf); | 63 | struct mwifiex_ds_tx_ba_stream_tbl *buf); |
64 | int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, | 64 | int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, |
65 | void *data_buf); | 65 | struct mwifiex_ds_11n_amsdu_aggr_ctrl |
66 | *amsdu_aggr_ctrl); | ||
66 | int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, | 67 | int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, |
67 | struct host_cmd_ds_command *cmd, | 68 | struct host_cmd_ds_command *cmd, |
68 | int cmd_action, void *data_buf); | 69 | int cmd_action, u16 *buf_size); |
69 | int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, | 70 | int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, |
70 | int cmd_action, void *data_buf); | 71 | int cmd_action, |
72 | struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl); | ||
71 | 73 | ||
72 | /* | 74 | /* |
73 | * This function checks whether AMPDU is allowed or not for a particular TID. | 75 | * This function checks whether AMPDU is allowed or not for a particular TID. |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index e5dfdc39a921..7aa9aa0ac958 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -328,13 +328,12 @@ int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) | |||
328 | */ | 328 | */ |
329 | int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | 329 | int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, |
330 | struct host_cmd_ds_command *cmd, | 330 | struct host_cmd_ds_command *cmd, |
331 | void *data_buf) | 331 | struct host_cmd_ds_11n_addba_req |
332 | *cmd_addba_req) | ||
332 | { | 333 | { |
333 | struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = | 334 | struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = |
334 | (struct host_cmd_ds_11n_addba_rsp *) | 335 | (struct host_cmd_ds_11n_addba_rsp *) |
335 | &cmd->params.add_ba_rsp; | 336 | &cmd->params.add_ba_rsp; |
336 | struct host_cmd_ds_11n_addba_req *cmd_addba_req = | ||
337 | (struct host_cmd_ds_11n_addba_req *) data_buf; | ||
338 | u8 tid; | 337 | u8 tid; |
339 | int win_size; | 338 | int win_size; |
340 | uint16_t block_ack_param_set; | 339 | uint16_t block_ack_param_set; |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index f3ca8c8c18f9..033c8adbdcd4 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h | |||
@@ -52,8 +52,9 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, | |||
52 | int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, | 52 | int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, |
53 | void *data_buf); | 53 | void *data_buf); |
54 | int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | 54 | int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, |
55 | struct host_cmd_ds_command | 55 | struct host_cmd_ds_command *cmd, |
56 | *cmd, void *data_buf); | 56 | struct host_cmd_ds_11n_addba_req |
57 | *cmd_addba_req); | ||
57 | int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, | 58 | int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, |
58 | void *data_buf); | 59 | void *data_buf); |
59 | void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); | 60 | void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index cd89fed206ae..b5352afb8714 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -104,13 +104,11 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, | |||
104 | * main thread. | 104 | * main thread. |
105 | */ | 105 | */ |
106 | static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv, | 106 | static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv, |
107 | struct host_cmd_ds_command *cmd, void *data_buf) | 107 | struct host_cmd_ds_command *cmd, |
108 | struct mwifiex_ds_misc_cmd *pcmd_ptr) | ||
108 | { | 109 | { |
109 | struct mwifiex_ds_misc_cmd *pcmd_ptr = | ||
110 | (struct mwifiex_ds_misc_cmd *) data_buf; | ||
111 | |||
112 | /* Copy the HOST command to command buffer */ | 110 | /* Copy the HOST command to command buffer */ |
113 | memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len); | 111 | memcpy(cmd, pcmd_ptr->cmd, pcmd_ptr->len); |
114 | dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len); | 112 | dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len); |
115 | return 0; | 113 | return 0; |
116 | } | 114 | } |
@@ -707,15 +705,14 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
707 | 705 | ||
708 | if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { | 706 | if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { |
709 | /* Copy original response back to response buffer */ | 707 | /* Copy original response back to response buffer */ |
710 | struct mwifiex_ds_misc_cmd *hostcmd = NULL; | 708 | struct mwifiex_ds_misc_cmd *hostcmd; |
711 | uint16_t size = le16_to_cpu(resp->size); | 709 | uint16_t size = le16_to_cpu(resp->size); |
712 | dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size); | 710 | dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size); |
713 | size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER); | 711 | size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER); |
714 | if (adapter->curr_cmd->data_buf) { | 712 | if (adapter->curr_cmd->data_buf) { |
715 | hostcmd = (struct mwifiex_ds_misc_cmd *) | 713 | hostcmd = adapter->curr_cmd->data_buf; |
716 | adapter->curr_cmd->data_buf; | ||
717 | hostcmd->len = size; | 714 | hostcmd->len = size; |
718 | memcpy(hostcmd->cmd, (void *) resp, size); | 715 | memcpy(hostcmd->cmd, resp, size); |
719 | } | 716 | } |
720 | } | 717 | } |
721 | orig_cmdresp_no = le16_to_cpu(resp->command); | 718 | orig_cmdresp_no = le16_to_cpu(resp->command); |
@@ -1155,7 +1152,7 @@ EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp); | |||
1155 | int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | 1152 | int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, |
1156 | struct host_cmd_ds_command *cmd, | 1153 | struct host_cmd_ds_command *cmd, |
1157 | u16 cmd_action, uint16_t ps_bitmap, | 1154 | u16 cmd_action, uint16_t ps_bitmap, |
1158 | void *data_buf) | 1155 | struct mwifiex_ds_auto_ds *auto_ds) |
1159 | { | 1156 | { |
1160 | struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh = | 1157 | struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh = |
1161 | &cmd->params.psmode_enh; | 1158 | &cmd->params.psmode_enh; |
@@ -1218,9 +1215,8 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | |||
1218 | sizeof(struct mwifiex_ie_types_header)); | 1215 | sizeof(struct mwifiex_ie_types_header)); |
1219 | cmd_size += sizeof(*auto_ds_tlv); | 1216 | cmd_size += sizeof(*auto_ds_tlv); |
1220 | tlv += sizeof(*auto_ds_tlv); | 1217 | tlv += sizeof(*auto_ds_tlv); |
1221 | if (data_buf) | 1218 | if (auto_ds) |
1222 | idletime = ((struct mwifiex_ds_auto_ds *) | 1219 | idletime = auto_ds->idle_time; |
1223 | data_buf)->idle_time; | ||
1224 | dev_dbg(priv->adapter->dev, | 1220 | dev_dbg(priv->adapter->dev, |
1225 | "cmd: PS Command: Enter Auto Deep Sleep\n"); | 1221 | "cmd: PS Command: Enter Auto Deep Sleep\n"); |
1226 | auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); | 1222 | auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); |
@@ -1239,7 +1235,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | |||
1239 | */ | 1235 | */ |
1240 | int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, | 1236 | int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, |
1241 | struct host_cmd_ds_command *resp, | 1237 | struct host_cmd_ds_command *resp, |
1242 | void *data_buf) | 1238 | struct mwifiex_ds_pm_cfg *pm_cfg) |
1243 | { | 1239 | { |
1244 | struct mwifiex_adapter *adapter = priv->adapter; | 1240 | struct mwifiex_adapter *adapter = priv->adapter; |
1245 | struct host_cmd_ds_802_11_ps_mode_enh *ps_mode = | 1241 | struct host_cmd_ds_802_11_ps_mode_enh *ps_mode = |
@@ -1282,10 +1278,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, | |||
1282 | 1278 | ||
1283 | dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap); | 1279 | dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap); |
1284 | 1280 | ||
1285 | if (data_buf) { | 1281 | if (pm_cfg) { |
1286 | /* This section is for get power save mode */ | 1282 | /* This section is for get power save mode */ |
1287 | struct mwifiex_ds_pm_cfg *pm_cfg = | ||
1288 | (struct mwifiex_ds_pm_cfg *)data_buf; | ||
1289 | if (ps_bitmap & BITMAP_STA_PS) | 1283 | if (ps_bitmap & BITMAP_STA_PS) |
1290 | pm_cfg->param.ps_mode = 1; | 1284 | pm_cfg->param.ps_mode = 1; |
1291 | else | 1285 | else |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 5eab3dc29b1c..644e2e405cb5 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -364,10 +364,9 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv, | |||
364 | */ | 364 | */ |
365 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | 365 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, |
366 | struct host_cmd_ds_command *cmd, | 366 | struct host_cmd_ds_command *cmd, |
367 | void *data_buf) | 367 | struct mwifiex_bssdescriptor *bss_desc) |
368 | { | 368 | { |
369 | struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate; | 369 | struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate; |
370 | struct mwifiex_bssdescriptor *bss_desc; | ||
371 | struct mwifiex_ie_types_ssid_param_set *ssid_tlv; | 370 | struct mwifiex_ie_types_ssid_param_set *ssid_tlv; |
372 | struct mwifiex_ie_types_phy_param_set *phy_tlv; | 371 | struct mwifiex_ie_types_phy_param_set *phy_tlv; |
373 | struct mwifiex_ie_types_ss_param_set *ss_tlv; | 372 | struct mwifiex_ie_types_ss_param_set *ss_tlv; |
@@ -380,7 +379,6 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
380 | u8 *pos; | 379 | u8 *pos; |
381 | int rsn_ie_len = 0; | 380 | int rsn_ie_len = 0; |
382 | 381 | ||
383 | bss_desc = (struct mwifiex_bssdescriptor *) data_buf; | ||
384 | pos = (u8 *) assoc; | 382 | pos = (u8 *) assoc; |
385 | 383 | ||
386 | mwifiex_cfg_tx_buf(priv, bss_desc); | 384 | mwifiex_cfg_tx_buf(priv, bss_desc); |
@@ -748,7 +746,8 @@ done: | |||
748 | */ | 746 | */ |
749 | int | 747 | int |
750 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 748 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
751 | struct host_cmd_ds_command *cmd, void *data_buf) | 749 | struct host_cmd_ds_command *cmd, |
750 | struct mwifiex_802_11_ssid *req_ssid) | ||
752 | { | 751 | { |
753 | int rsn_ie_len = 0; | 752 | int rsn_ie_len = 0; |
754 | struct mwifiex_adapter *adapter = priv->adapter; | 753 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -786,20 +785,15 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
786 | 785 | ||
787 | memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN); | 786 | memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN); |
788 | 787 | ||
789 | memcpy(adhoc_start->ssid, | 788 | memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); |
790 | ((struct mwifiex_802_11_ssid *) data_buf)->ssid, | ||
791 | ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len); | ||
792 | 789 | ||
793 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", | 790 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", |
794 | adhoc_start->ssid); | 791 | adhoc_start->ssid); |
795 | 792 | ||
796 | memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); | 793 | memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); |
797 | memcpy(bss_desc->ssid.ssid, | 794 | memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len); |
798 | ((struct mwifiex_802_11_ssid *) data_buf)->ssid, | ||
799 | ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len); | ||
800 | 795 | ||
801 | bss_desc->ssid.ssid_len = | 796 | bss_desc->ssid.ssid_len = req_ssid->ssid_len; |
802 | ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len; | ||
803 | 797 | ||
804 | /* Set the BSS mode */ | 798 | /* Set the BSS mode */ |
805 | adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS; | 799 | adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS; |
@@ -1036,13 +1030,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
1036 | */ | 1030 | */ |
1037 | int | 1031 | int |
1038 | mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | 1032 | mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, |
1039 | struct host_cmd_ds_command *cmd, void *data_buf) | 1033 | struct host_cmd_ds_command *cmd, |
1034 | struct mwifiex_bssdescriptor *bss_desc) | ||
1040 | { | 1035 | { |
1041 | int rsn_ie_len = 0; | 1036 | int rsn_ie_len = 0; |
1042 | struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join = | 1037 | struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join = |
1043 | &cmd->params.adhoc_join; | 1038 | &cmd->params.adhoc_join; |
1044 | struct mwifiex_bssdescriptor *bss_desc = | ||
1045 | (struct mwifiex_bssdescriptor *) data_buf; | ||
1046 | struct mwifiex_ie_types_chan_list_param_set *chan_tlv; | 1039 | struct mwifiex_ie_types_chan_list_param_set *chan_tlv; |
1047 | u32 cmd_append_size = 0; | 1040 | u32 cmd_append_size = 0; |
1048 | u16 tmp_cap; | 1041 | u16 tmp_cap; |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 4f43443036f4..e5fc53dc6887 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -26,9 +26,6 @@ | |||
26 | 26 | ||
27 | const char driver_version[] = "mwifiex " VERSION " (%s) "; | 27 | const char driver_version[] = "mwifiex " VERSION " (%s) "; |
28 | 28 | ||
29 | struct mwifiex_adapter *g_adapter; | ||
30 | EXPORT_SYMBOL_GPL(g_adapter); | ||
31 | |||
32 | static struct mwifiex_bss_attr mwifiex_bss_sta[] = { | 29 | static struct mwifiex_bss_attr mwifiex_bss_sta[] = { |
33 | {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0}, | 30 | {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0}, |
34 | }; | 31 | }; |
@@ -60,7 +57,8 @@ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { | |||
60 | * proper cleanup before exiting. | 57 | * proper cleanup before exiting. |
61 | */ | 58 | */ |
62 | static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, | 59 | static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, |
63 | struct mwifiex_drv_mode *drv_mode_ptr) | 60 | struct mwifiex_drv_mode *drv_mode_ptr, |
61 | void **padapter) | ||
64 | { | 62 | { |
65 | struct mwifiex_adapter *adapter; | 63 | struct mwifiex_adapter *adapter; |
66 | int i; | 64 | int i; |
@@ -69,7 +67,7 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, | |||
69 | if (!adapter) | 67 | if (!adapter) |
70 | return -ENOMEM; | 68 | return -ENOMEM; |
71 | 69 | ||
72 | g_adapter = adapter; | 70 | *padapter = adapter; |
73 | adapter->card = card; | 71 | adapter->card = card; |
74 | 72 | ||
75 | /* Save interface specific operations in adapter */ | 73 | /* Save interface specific operations in adapter */ |
@@ -324,7 +322,7 @@ exit_main_proc: | |||
324 | * and initializing the private structures. | 322 | * and initializing the private structures. |
325 | */ | 323 | */ |
326 | static int | 324 | static int |
327 | mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) | 325 | mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter) |
328 | { | 326 | { |
329 | int i; | 327 | int i; |
330 | struct mwifiex_drv_mode *drv_mode_ptr; | 328 | struct mwifiex_drv_mode *drv_mode_ptr; |
@@ -343,7 +341,7 @@ mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) | |||
343 | return -1; | 341 | return -1; |
344 | } | 342 | } |
345 | 343 | ||
346 | if (mwifiex_register(card, if_ops, drv_mode_ptr)) | 344 | if (mwifiex_register(card, if_ops, drv_mode_ptr, padapter)) |
347 | return -1; | 345 | return -1; |
348 | 346 | ||
349 | return 0; | 347 | return 0; |
@@ -555,7 +553,7 @@ static int | |||
555 | mwifiex_set_mac_address(struct net_device *dev, void *addr) | 553 | mwifiex_set_mac_address(struct net_device *dev, void *addr) |
556 | { | 554 | { |
557 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 555 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
558 | struct sockaddr *hw_addr = (struct sockaddr *) addr; | 556 | struct sockaddr *hw_addr = addr; |
559 | int ret; | 557 | int ret; |
560 | 558 | ||
561 | memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); | 559 | memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); |
@@ -855,13 +853,11 @@ mwifiex_add_card(void *card, struct semaphore *sem, | |||
855 | if (down_interruptible(sem)) | 853 | if (down_interruptible(sem)) |
856 | goto exit_sem_err; | 854 | goto exit_sem_err; |
857 | 855 | ||
858 | if (mwifiex_init_sw(card, if_ops)) { | 856 | if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) { |
859 | pr_err("%s: software init failed\n", __func__); | 857 | pr_err("%s: software init failed\n", __func__); |
860 | goto err_init_sw; | 858 | goto err_init_sw; |
861 | } | 859 | } |
862 | 860 | ||
863 | adapter = g_adapter; | ||
864 | |||
865 | adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; | 861 | adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; |
866 | adapter->surprise_removed = false; | 862 | adapter->surprise_removed = false; |
867 | init_waitqueue_head(&adapter->init_wait_q); | 863 | init_waitqueue_head(&adapter->init_wait_q); |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 57b183af72d7..03691c02a6e8 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -39,7 +39,6 @@ | |||
39 | #include "fw.h" | 39 | #include "fw.h" |
40 | 40 | ||
41 | extern const char driver_version[]; | 41 | extern const char driver_version[]; |
42 | extern struct mwifiex_adapter *g_adapter; | ||
43 | 42 | ||
44 | enum { | 43 | enum { |
45 | MWIFIEX_ASYNC_CMD, | 44 | MWIFIEX_ASYNC_CMD, |
@@ -737,10 +736,10 @@ void mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *, u8 *, | |||
737 | int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | 736 | int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, |
738 | struct host_cmd_ds_command *cmd, | 737 | struct host_cmd_ds_command *cmd, |
739 | u16 cmd_action, uint16_t ps_bitmap, | 738 | u16 cmd_action, uint16_t ps_bitmap, |
740 | void *data_buf); | 739 | struct mwifiex_ds_auto_ds *auto_ds); |
741 | int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, | 740 | int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, |
742 | struct host_cmd_ds_command *resp, | 741 | struct host_cmd_ds_command *resp, |
743 | void *data_buf); | 742 | struct mwifiex_ds_pm_cfg *pm_cfg); |
744 | void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); | 743 | void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); |
745 | void mwifiex_hs_activated_event(struct mwifiex_private *priv, | 744 | void mwifiex_hs_activated_event(struct mwifiex_private *priv, |
746 | u8 activated); | 745 | u8 activated); |
@@ -752,7 +751,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, | |||
752 | u16 cmd_action, u32 cmd_oid, | 751 | u16 cmd_action, u32 cmd_oid, |
753 | void *data_buf, void *cmd_buf); | 752 | void *data_buf, void *cmd_buf); |
754 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, | 753 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, |
755 | void *cmd_buf); | 754 | struct host_cmd_ds_command *resp); |
756 | int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, | 755 | int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, |
757 | struct sk_buff *skb); | 756 | struct sk_buff *skb); |
758 | int mwifiex_process_sta_event(struct mwifiex_private *); | 757 | int mwifiex_process_sta_event(struct mwifiex_private *); |
@@ -761,7 +760,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); | |||
761 | int mwifiex_scan_networks(struct mwifiex_private *priv, | 760 | int mwifiex_scan_networks(struct mwifiex_private *priv, |
762 | const struct mwifiex_user_scan_cfg *user_scan_in); | 761 | const struct mwifiex_user_scan_cfg *user_scan_in); |
763 | int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, | 762 | int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, |
764 | void *data_buf); | 763 | struct mwifiex_scan_cmd_config *scan_cfg); |
765 | void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | 764 | void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, |
766 | struct cmd_ctrl_node *cmd_node); | 765 | struct cmd_ctrl_node *cmd_node); |
767 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | 766 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, |
@@ -778,8 +777,8 @@ s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | |||
778 | int mwifiex_associate(struct mwifiex_private *priv, | 777 | int mwifiex_associate(struct mwifiex_private *priv, |
779 | struct mwifiex_bssdescriptor *bss_desc); | 778 | struct mwifiex_bssdescriptor *bss_desc); |
780 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | 779 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, |
781 | struct host_cmd_ds_command | 780 | struct host_cmd_ds_command *cmd, |
782 | *cmd, void *data_buf); | 781 | struct mwifiex_bssdescriptor *bss_desc); |
783 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | 782 | int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, |
784 | struct host_cmd_ds_command *resp); | 783 | struct host_cmd_ds_command *resp); |
785 | void mwifiex_reset_connect_state(struct mwifiex_private *priv); | 784 | void mwifiex_reset_connect_state(struct mwifiex_private *priv); |
@@ -792,10 +791,10 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, | |||
792 | struct mwifiex_bssdescriptor *bss_desc); | 791 | struct mwifiex_bssdescriptor *bss_desc); |
793 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 792 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
794 | struct host_cmd_ds_command *cmd, | 793 | struct host_cmd_ds_command *cmd, |
795 | void *data_buf); | 794 | struct mwifiex_802_11_ssid *req_ssid); |
796 | int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | 795 | int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, |
797 | struct host_cmd_ds_command *cmd, | 796 | struct host_cmd_ds_command *cmd, |
798 | void *data_buf); | 797 | struct mwifiex_bssdescriptor *bss_desc); |
799 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | 798 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, |
800 | struct host_cmd_ds_command *resp); | 799 | struct host_cmd_ds_command *resp); |
801 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); | 800 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 5c22860fb40a..6f88c8ab5de5 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -2357,12 +2357,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
2357 | * - Setting command ID, and proper size | 2357 | * - Setting command ID, and proper size |
2358 | * - Ensuring correct endian-ness | 2358 | * - Ensuring correct endian-ness |
2359 | */ | 2359 | */ |
2360 | int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf) | 2360 | int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, |
2361 | struct mwifiex_scan_cmd_config *scan_cfg) | ||
2361 | { | 2362 | { |
2362 | struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; | 2363 | struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; |
2363 | struct mwifiex_scan_cmd_config *scan_cfg; | ||
2364 | |||
2365 | scan_cfg = (struct mwifiex_scan_cmd_config *) data_buf; | ||
2366 | 2364 | ||
2367 | /* Set fixed field variables in scan command */ | 2365 | /* Set fixed field variables in scan command */ |
2368 | scan_cmd->bss_mode = scan_cfg->bss_mode; | 2366 | scan_cmd->bss_mode = scan_cfg->bss_mode; |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 4327b6d099c8..711fa689a95c 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -31,10 +31,27 @@ | |||
31 | 31 | ||
32 | #define SDIO_VERSION "1.0" | 32 | #define SDIO_VERSION "1.0" |
33 | 33 | ||
34 | /* The mwifiex_sdio_remove() callback function is called when | ||
35 | * user removes this module from kernel space or ejects | ||
36 | * the card from the slot. The driver handles these 2 cases | ||
37 | * differently. | ||
38 | * If the user is removing the module, the few commands (FUNC_SHUTDOWN, | ||
39 | * HS_CANCEL etc.) are sent to the firmware. | ||
40 | * If the card is removed, there is no need to send these command. | ||
41 | * | ||
42 | * The variable 'user_rmmod' is used to distinguish these two | ||
43 | * scenarios. This flag is initialized as FALSE in case the card | ||
44 | * is removed, and will be set to TRUE for module removal when | ||
45 | * module_exit function is called. | ||
46 | */ | ||
47 | static u8 user_rmmod; | ||
48 | |||
34 | static struct mwifiex_if_ops sdio_ops; | 49 | static struct mwifiex_if_ops sdio_ops; |
35 | 50 | ||
36 | static struct semaphore add_remove_card_sem; | 51 | static struct semaphore add_remove_card_sem; |
37 | 52 | ||
53 | static int mwifiex_sdio_resume(struct device *dev); | ||
54 | |||
38 | /* | 55 | /* |
39 | * SDIO probe. | 56 | * SDIO probe. |
40 | * | 57 | * |
@@ -93,17 +110,36 @@ static void | |||
93 | mwifiex_sdio_remove(struct sdio_func *func) | 110 | mwifiex_sdio_remove(struct sdio_func *func) |
94 | { | 111 | { |
95 | struct sdio_mmc_card *card; | 112 | struct sdio_mmc_card *card; |
113 | struct mwifiex_adapter *adapter; | ||
114 | int i; | ||
96 | 115 | ||
97 | pr_debug("info: SDIO func num=%d\n", func->num); | 116 | pr_debug("info: SDIO func num=%d\n", func->num); |
98 | 117 | ||
99 | if (func) { | 118 | card = sdio_get_drvdata(func); |
100 | card = sdio_get_drvdata(func); | 119 | if (!card) |
101 | if (card) { | 120 | return; |
102 | mwifiex_remove_card(card->adapter, | 121 | |
103 | &add_remove_card_sem); | 122 | adapter = card->adapter; |
104 | kfree(card); | 123 | if (!adapter || !adapter->priv_num) |
105 | } | 124 | return; |
125 | |||
126 | if (user_rmmod) { | ||
127 | if (adapter->is_suspended) | ||
128 | mwifiex_sdio_resume(adapter->dev); | ||
129 | |||
130 | for (i = 0; i < adapter->priv_num; i++) | ||
131 | if ((GET_BSS_ROLE(adapter->priv[i]) == | ||
132 | MWIFIEX_BSS_ROLE_STA) && | ||
133 | adapter->priv[i]->media_connected) | ||
134 | mwifiex_deauthenticate(adapter->priv[i], NULL); | ||
135 | |||
136 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, | ||
137 | MWIFIEX_BSS_ROLE_ANY), | ||
138 | MWIFIEX_FUNC_SHUTDOWN); | ||
106 | } | 139 | } |
140 | |||
141 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); | ||
142 | kfree(card); | ||
107 | } | 143 | } |
108 | 144 | ||
109 | /* | 145 | /* |
@@ -1696,6 +1732,9 @@ mwifiex_sdio_init_module(void) | |||
1696 | { | 1732 | { |
1697 | sema_init(&add_remove_card_sem, 1); | 1733 | sema_init(&add_remove_card_sem, 1); |
1698 | 1734 | ||
1735 | /* Clear the flag in case user removes the card. */ | ||
1736 | user_rmmod = 0; | ||
1737 | |||
1699 | return sdio_register_driver(&mwifiex_sdio); | 1738 | return sdio_register_driver(&mwifiex_sdio); |
1700 | } | 1739 | } |
1701 | 1740 | ||
@@ -1711,32 +1750,12 @@ mwifiex_sdio_init_module(void) | |||
1711 | static void | 1750 | static void |
1712 | mwifiex_sdio_cleanup_module(void) | 1751 | mwifiex_sdio_cleanup_module(void) |
1713 | { | 1752 | { |
1714 | struct mwifiex_adapter *adapter = g_adapter; | 1753 | if (!down_interruptible(&add_remove_card_sem)) |
1715 | int i; | 1754 | up(&add_remove_card_sem); |
1716 | |||
1717 | if (down_interruptible(&add_remove_card_sem)) | ||
1718 | goto exit_sem_err; | ||
1719 | |||
1720 | if (!adapter || !adapter->priv_num) | ||
1721 | goto exit; | ||
1722 | |||
1723 | if (adapter->is_suspended) | ||
1724 | mwifiex_sdio_resume(adapter->dev); | ||
1725 | |||
1726 | for (i = 0; i < adapter->priv_num; i++) | ||
1727 | if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && | ||
1728 | adapter->priv[i]->media_connected) | ||
1729 | mwifiex_deauthenticate(adapter->priv[i], NULL); | ||
1730 | |||
1731 | if (!adapter->surprise_removed) | ||
1732 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, | ||
1733 | MWIFIEX_BSS_ROLE_ANY), | ||
1734 | MWIFIEX_FUNC_SHUTDOWN); | ||
1735 | 1755 | ||
1736 | exit: | 1756 | /* Set the flag as user is removing this module. */ |
1737 | up(&add_remove_card_sem); | 1757 | user_rmmod = 1; |
1738 | 1758 | ||
1739 | exit_sem_err: | ||
1740 | sdio_unregister_driver(&mwifiex_sdio); | 1759 | sdio_unregister_driver(&mwifiex_sdio); |
1741 | } | 1760 | } |
1742 | 1761 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 8af3a78d2723..d85a0a60aa6a 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -67,10 +67,9 @@ mwifiex_cmd_802_11_rssi_info(struct mwifiex_private *priv, | |||
67 | */ | 67 | */ |
68 | static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, | 68 | static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, |
69 | struct host_cmd_ds_command *cmd, | 69 | struct host_cmd_ds_command *cmd, |
70 | u16 cmd_action, void *data_buf) | 70 | u16 cmd_action, u16 *action) |
71 | { | 71 | { |
72 | struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl; | 72 | struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl; |
73 | u16 action = *((u16 *) data_buf); | ||
74 | 73 | ||
75 | if (cmd_action != HostCmd_ACT_GEN_SET) { | 74 | if (cmd_action != HostCmd_ACT_GEN_SET) { |
76 | dev_err(priv->adapter->dev, | 75 | dev_err(priv->adapter->dev, |
@@ -81,7 +80,7 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, | |||
81 | cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL); | 80 | cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL); |
82 | cmd->size = | 81 | cmd->size = |
83 | cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN); | 82 | cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN); |
84 | mac_ctrl->action = cpu_to_le16(action); | 83 | mac_ctrl->action = cpu_to_le16(*action); |
85 | 84 | ||
86 | return 0; | 85 | return 0; |
87 | } | 86 | } |
@@ -104,10 +103,9 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, | |||
104 | static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | 103 | static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, |
105 | struct host_cmd_ds_command *cmd, | 104 | struct host_cmd_ds_command *cmd, |
106 | u16 cmd_action, u32 cmd_oid, | 105 | u16 cmd_action, u32 cmd_oid, |
107 | void *data_buf) | 106 | u32 *ul_temp) |
108 | { | 107 | { |
109 | struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib; | 108 | struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib; |
110 | u32 ul_temp; | ||
111 | 109 | ||
112 | dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); | 110 | dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); |
113 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); | 111 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); |
@@ -127,9 +125,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | |||
127 | if (cmd_action == HostCmd_ACT_GEN_SET) { | 125 | if (cmd_action == HostCmd_ACT_GEN_SET) { |
128 | snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); | 126 | snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); |
129 | snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); | 127 | snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); |
130 | ul_temp = *((u32 *) data_buf); | ||
131 | *((__le16 *) (snmp_mib->value)) = | 128 | *((__le16 *) (snmp_mib->value)) = |
132 | cpu_to_le16((u16) ul_temp); | 129 | cpu_to_le16((u16) *ul_temp); |
133 | cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) | 130 | cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) |
134 | + sizeof(u16)); | 131 | + sizeof(u16)); |
135 | } | 132 | } |
@@ -139,9 +136,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | |||
139 | if (cmd_action == HostCmd_ACT_GEN_SET) { | 136 | if (cmd_action == HostCmd_ACT_GEN_SET) { |
140 | snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); | 137 | snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); |
141 | snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); | 138 | snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); |
142 | ul_temp = *((u32 *) data_buf); | ||
143 | *(__le16 *) (snmp_mib->value) = | 139 | *(__le16 *) (snmp_mib->value) = |
144 | cpu_to_le16((u16) ul_temp); | 140 | cpu_to_le16((u16) *ul_temp); |
145 | cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) | 141 | cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) |
146 | + sizeof(u16)); | 142 | + sizeof(u16)); |
147 | } | 143 | } |
@@ -152,9 +148,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | |||
152 | if (cmd_action == HostCmd_ACT_GEN_SET) { | 148 | if (cmd_action == HostCmd_ACT_GEN_SET) { |
153 | snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); | 149 | snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); |
154 | snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); | 150 | snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); |
155 | ul_temp = (*(u32 *) data_buf); | ||
156 | *((__le16 *) (snmp_mib->value)) = | 151 | *((__le16 *) (snmp_mib->value)) = |
157 | cpu_to_le16((u16) ul_temp); | 152 | cpu_to_le16((u16) *ul_temp); |
158 | cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) | 153 | cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) |
159 | + sizeof(u16)); | 154 | + sizeof(u16)); |
160 | } | 155 | } |
@@ -164,9 +159,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | |||
164 | if (cmd_action == HostCmd_ACT_GEN_SET) { | 159 | if (cmd_action == HostCmd_ACT_GEN_SET) { |
165 | snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); | 160 | snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); |
166 | snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); | 161 | snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); |
167 | ul_temp = *(u32 *) data_buf; | ||
168 | *((__le16 *) (snmp_mib->value)) = | 162 | *((__le16 *) (snmp_mib->value)) = |
169 | cpu_to_le16((u16) ul_temp); | 163 | cpu_to_le16((u16) *ul_temp); |
170 | cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) | 164 | cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) |
171 | + sizeof(u16)); | 165 | + sizeof(u16)); |
172 | } | 166 | } |
@@ -209,13 +203,11 @@ mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd) | |||
209 | */ | 203 | */ |
210 | static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, | 204 | static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, |
211 | struct host_cmd_ds_command *cmd, | 205 | struct host_cmd_ds_command *cmd, |
212 | u16 cmd_action, void *data_buf) | 206 | u16 cmd_action, u16 *pbitmap_rates) |
213 | { | 207 | { |
214 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg; | 208 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg; |
215 | struct mwifiex_rate_scope *rate_scope; | 209 | struct mwifiex_rate_scope *rate_scope; |
216 | struct mwifiex_rate_drop_pattern *rate_drop; | 210 | struct mwifiex_rate_drop_pattern *rate_drop; |
217 | u16 *pbitmap_rates = (u16 *) data_buf; | ||
218 | |||
219 | u32 i; | 211 | u32 i; |
220 | 212 | ||
221 | cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG); | 213 | cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG); |
@@ -272,10 +264,10 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, | |||
272 | * - Ensuring correct endian-ness | 264 | * - Ensuring correct endian-ness |
273 | */ | 265 | */ |
274 | static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, | 266 | static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, |
275 | u16 cmd_action, void *data_buf) | 267 | u16 cmd_action, |
268 | struct host_cmd_ds_txpwr_cfg *txp) | ||
276 | { | 269 | { |
277 | struct mwifiex_types_power_group *pg_tlv; | 270 | struct mwifiex_types_power_group *pg_tlv; |
278 | struct host_cmd_ds_txpwr_cfg *txp; | ||
279 | struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg; | 271 | struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg; |
280 | 272 | ||
281 | cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG); | 273 | cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG); |
@@ -283,12 +275,11 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, | |||
283 | cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg)); | 275 | cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg)); |
284 | switch (cmd_action) { | 276 | switch (cmd_action) { |
285 | case HostCmd_ACT_GEN_SET: | 277 | case HostCmd_ACT_GEN_SET: |
286 | txp = (struct host_cmd_ds_txpwr_cfg *) data_buf; | ||
287 | if (txp->mode) { | 278 | if (txp->mode) { |
288 | pg_tlv = (struct mwifiex_types_power_group | 279 | pg_tlv = (struct mwifiex_types_power_group |
289 | *) ((unsigned long) data_buf + | 280 | *) ((unsigned long) txp + |
290 | sizeof(struct host_cmd_ds_txpwr_cfg)); | 281 | sizeof(struct host_cmd_ds_txpwr_cfg)); |
291 | memmove(cmd_txp_cfg, data_buf, | 282 | memmove(cmd_txp_cfg, txp, |
292 | sizeof(struct host_cmd_ds_txpwr_cfg) + | 283 | sizeof(struct host_cmd_ds_txpwr_cfg) + |
293 | sizeof(struct mwifiex_types_power_group) + | 284 | sizeof(struct mwifiex_types_power_group) + |
294 | pg_tlv->length); | 285 | pg_tlv->length); |
@@ -300,8 +291,7 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, | |||
300 | sizeof(struct mwifiex_types_power_group) + | 291 | sizeof(struct mwifiex_types_power_group) + |
301 | pg_tlv->length); | 292 | pg_tlv->length); |
302 | } else { | 293 | } else { |
303 | memmove(cmd_txp_cfg, data_buf, | 294 | memmove(cmd_txp_cfg, txp, sizeof(*txp)); |
304 | sizeof(struct host_cmd_ds_txpwr_cfg)); | ||
305 | } | 295 | } |
306 | cmd_txp_cfg->action = cpu_to_le16(cmd_action); | 296 | cmd_txp_cfg->action = cpu_to_le16(cmd_action); |
307 | break; | 297 | break; |
@@ -322,22 +312,23 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, | |||
322 | * (as required) | 312 | * (as required) |
323 | * - Ensuring correct endian-ness | 313 | * - Ensuring correct endian-ness |
324 | */ | 314 | */ |
325 | static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, | 315 | static int |
326 | struct host_cmd_ds_command *cmd, | 316 | mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, |
327 | u16 cmd_action, | 317 | struct host_cmd_ds_command *cmd, |
328 | struct mwifiex_hs_config_param *data_buf) | 318 | u16 cmd_action, |
319 | struct mwifiex_hs_config_param *hscfg_param) | ||
329 | { | 320 | { |
330 | struct mwifiex_adapter *adapter = priv->adapter; | 321 | struct mwifiex_adapter *adapter = priv->adapter; |
331 | struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg; | 322 | struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg; |
332 | u16 hs_activate = false; | 323 | u16 hs_activate = false; |
333 | 324 | ||
334 | if (data_buf == NULL) | 325 | if (!hscfg_param) |
335 | /* New Activate command */ | 326 | /* New Activate command */ |
336 | hs_activate = true; | 327 | hs_activate = true; |
337 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); | 328 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); |
338 | 329 | ||
339 | if (!hs_activate && | 330 | if (!hs_activate && |
340 | (data_buf->conditions | 331 | (hscfg_param->conditions |
341 | != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) | 332 | != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) |
342 | && ((adapter->arp_filter_size > 0) | 333 | && ((adapter->arp_filter_size > 0) |
343 | && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { | 334 | && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { |
@@ -359,9 +350,9 @@ static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, | |||
359 | hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED; | 350 | hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED; |
360 | } else { | 351 | } else { |
361 | hs_cfg->action = cpu_to_le16(HS_CONFIGURE); | 352 | hs_cfg->action = cpu_to_le16(HS_CONFIGURE); |
362 | hs_cfg->params.hs_config.conditions = data_buf->conditions; | 353 | hs_cfg->params.hs_config.conditions = hscfg_param->conditions; |
363 | hs_cfg->params.hs_config.gpio = data_buf->gpio; | 354 | hs_cfg->params.hs_config.gpio = hscfg_param->gpio; |
364 | hs_cfg->params.hs_config.gap = data_buf->gap; | 355 | hs_cfg->params.hs_config.gap = hscfg_param->gap; |
365 | dev_dbg(adapter->dev, | 356 | dev_dbg(adapter->dev, |
366 | "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n", | 357 | "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n", |
367 | hs_cfg->params.hs_config.conditions, | 358 | hs_cfg->params.hs_config.conditions, |
@@ -405,11 +396,11 @@ static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv, | |||
405 | * - Setting MAC multicast address | 396 | * - Setting MAC multicast address |
406 | * - Ensuring correct endian-ness | 397 | * - Ensuring correct endian-ness |
407 | */ | 398 | */ |
408 | static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, | 399 | static int |
409 | u16 cmd_action, void *data_buf) | 400 | mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, |
401 | u16 cmd_action, | ||
402 | struct mwifiex_multicast_list *mcast_list) | ||
410 | { | 403 | { |
411 | struct mwifiex_multicast_list *mcast_list = | ||
412 | (struct mwifiex_multicast_list *) data_buf; | ||
413 | struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr; | 404 | struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr; |
414 | 405 | ||
415 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) + | 406 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) + |
@@ -435,7 +426,7 @@ static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, | |||
435 | */ | 426 | */ |
436 | static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, | 427 | static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, |
437 | struct host_cmd_ds_command *cmd, | 428 | struct host_cmd_ds_command *cmd, |
438 | void *data_buf) | 429 | u8 *mac) |
439 | { | 430 | { |
440 | struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth; | 431 | struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth; |
441 | 432 | ||
@@ -444,7 +435,7 @@ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, | |||
444 | + S_DS_GEN); | 435 | + S_DS_GEN); |
445 | 436 | ||
446 | /* Set AP MAC address */ | 437 | /* Set AP MAC address */ |
447 | memcpy(deauth->mac_addr, (u8 *) data_buf, ETH_ALEN); | 438 | memcpy(deauth->mac_addr, mac, ETH_ALEN); |
448 | 439 | ||
449 | dev_dbg(priv->adapter->dev, "cmd: Deauth: %pM\n", deauth->mac_addr); | 440 | dev_dbg(priv->adapter->dev, "cmd: Deauth: %pM\n", deauth->mac_addr); |
450 | 441 | ||
@@ -543,15 +534,14 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, | |||
543 | * encryption (TKIP, AES) (as required) | 534 | * encryption (TKIP, AES) (as required) |
544 | * - Ensuring correct endian-ness | 535 | * - Ensuring correct endian-ness |
545 | */ | 536 | */ |
546 | static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | 537 | static int |
547 | struct host_cmd_ds_command *cmd, | 538 | mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, |
548 | u16 cmd_action, | 539 | struct host_cmd_ds_command *cmd, |
549 | u32 cmd_oid, void *data_buf) | 540 | u16 cmd_action, u32 cmd_oid, |
541 | struct mwifiex_ds_encrypt_key *enc_key) | ||
550 | { | 542 | { |
551 | struct host_cmd_ds_802_11_key_material *key_material = | 543 | struct host_cmd_ds_802_11_key_material *key_material = |
552 | &cmd->params.key_material; | 544 | &cmd->params.key_material; |
553 | struct mwifiex_ds_encrypt_key *enc_key = | ||
554 | (struct mwifiex_ds_encrypt_key *) data_buf; | ||
555 | u16 key_param_len = 0; | 545 | u16 key_param_len = 0; |
556 | int ret = 0; | 546 | int ret = 0; |
557 | const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 547 | const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
@@ -741,7 +731,7 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, | |||
741 | */ | 731 | */ |
742 | static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, | 732 | static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, |
743 | struct host_cmd_ds_command *cmd, | 733 | struct host_cmd_ds_command *cmd, |
744 | u16 cmd_action, void *data_buf) | 734 | u16 cmd_action, u16 *channel) |
745 | { | 735 | { |
746 | struct host_cmd_ds_802_11_rf_channel *rf_chan = | 736 | struct host_cmd_ds_802_11_rf_channel *rf_chan = |
747 | &cmd->params.rf_channel; | 737 | &cmd->params.rf_channel; |
@@ -759,7 +749,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, | |||
759 | 749 | ||
760 | rf_type = le16_to_cpu(rf_chan->rf_type); | 750 | rf_type = le16_to_cpu(rf_chan->rf_type); |
761 | SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset); | 751 | SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset); |
762 | rf_chan->current_channel = cpu_to_le16(*((u16 *) data_buf)); | 752 | rf_chan->current_channel = cpu_to_le16(*channel); |
763 | } | 753 | } |
764 | rf_chan->action = cpu_to_le16(cmd_action); | 754 | rf_chan->action = cpu_to_le16(cmd_action); |
765 | return 0; | 755 | return 0; |
@@ -774,11 +764,10 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, | |||
774 | * - Ensuring correct endian-ness | 764 | * - Ensuring correct endian-ness |
775 | */ | 765 | */ |
776 | static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, | 766 | static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, |
777 | u16 cmd_action, void *data_buf) | 767 | u16 cmd_action, u16 *enable) |
778 | { | 768 | { |
779 | struct host_cmd_ds_802_11_ibss_status *ibss_coal = | 769 | struct host_cmd_ds_802_11_ibss_status *ibss_coal = |
780 | &(cmd->params.ibss_coalescing); | 770 | &(cmd->params.ibss_coalescing); |
781 | u16 enable = 0; | ||
782 | 771 | ||
783 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS); | 772 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS); |
784 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) + | 773 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) + |
@@ -788,9 +777,8 @@ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, | |||
788 | 777 | ||
789 | switch (cmd_action) { | 778 | switch (cmd_action) { |
790 | case HostCmd_ACT_GEN_SET: | 779 | case HostCmd_ACT_GEN_SET: |
791 | if (data_buf != NULL) | 780 | if (enable) |
792 | enable = *(u16 *) data_buf; | 781 | ibss_coal->enable = cpu_to_le16(*enable); |
793 | ibss_coal->enable = cpu_to_le16(enable); | ||
794 | break; | 782 | break; |
795 | 783 | ||
796 | /* In other case.. Nothing to do */ | 784 | /* In other case.. Nothing to do */ |
@@ -822,9 +810,8 @@ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, | |||
822 | static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | 810 | static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, |
823 | u16 cmd_action, void *data_buf) | 811 | u16 cmd_action, void *data_buf) |
824 | { | 812 | { |
825 | struct mwifiex_ds_reg_rw *reg_rw; | 813 | struct mwifiex_ds_reg_rw *reg_rw = data_buf; |
826 | 814 | ||
827 | reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; | ||
828 | switch (le16_to_cpu(cmd->command)) { | 815 | switch (le16_to_cpu(cmd->command)) { |
829 | case HostCmd_CMD_MAC_REG_ACCESS: | 816 | case HostCmd_CMD_MAC_REG_ACCESS: |
830 | { | 817 | { |
@@ -893,8 +880,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
893 | } | 880 | } |
894 | case HostCmd_CMD_802_11_EEPROM_ACCESS: | 881 | case HostCmd_CMD_802_11_EEPROM_ACCESS: |
895 | { | 882 | { |
896 | struct mwifiex_ds_read_eeprom *rd_eeprom = | 883 | struct mwifiex_ds_read_eeprom *rd_eeprom = data_buf; |
897 | (struct mwifiex_ds_read_eeprom *) data_buf; | ||
898 | struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom = | 884 | struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom = |
899 | (struct host_cmd_ds_802_11_eeprom_access *) | 885 | (struct host_cmd_ds_802_11_eeprom_access *) |
900 | &cmd->params.eeprom; | 886 | &cmd->params.eeprom; |
@@ -923,8 +909,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
923 | u16 cmd_action, u32 cmd_oid, | 909 | u16 cmd_action, u32 cmd_oid, |
924 | void *data_buf, void *cmd_buf) | 910 | void *data_buf, void *cmd_buf) |
925 | { | 911 | { |
926 | struct host_cmd_ds_command *cmd_ptr = | 912 | struct host_cmd_ds_command *cmd_ptr = cmd_buf; |
927 | (struct host_cmd_ds_command *) cmd_buf; | ||
928 | int ret = 0; | 913 | int ret = 0; |
929 | 914 | ||
930 | /* Prepare command */ | 915 | /* Prepare command */ |
@@ -1181,7 +1166,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1181 | /* Send request to firmware */ | 1166 | /* Send request to firmware */ |
1182 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, | 1167 | ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, |
1183 | HostCmd_ACT_GEN_SET, 0, | 1168 | HostCmd_ACT_GEN_SET, 0, |
1184 | (void *) &amsdu_aggr_ctrl); | 1169 | &amsdu_aggr_ctrl); |
1185 | if (ret) | 1170 | if (ret) |
1186 | return -1; | 1171 | return -1; |
1187 | /* MAC Control must be the last command in init_fw */ | 1172 | /* MAC Control must be the last command in init_fw */ |
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index d08f76429a0a..ad64c87b91d6 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -120,11 +120,10 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
120 | */ | 120 | */ |
121 | static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, | 121 | static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, |
122 | struct host_cmd_ds_command *resp, | 122 | struct host_cmd_ds_command *resp, |
123 | void *data_buf) | 123 | struct mwifiex_ds_get_signal *signal) |
124 | { | 124 | { |
125 | struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = | 125 | struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = |
126 | &resp->params.rssi_info_rsp; | 126 | &resp->params.rssi_info_rsp; |
127 | struct mwifiex_ds_get_signal *signal; | ||
128 | 127 | ||
129 | priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); | 128 | priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); |
130 | priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); | 129 | priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); |
@@ -139,9 +138,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, | |||
139 | priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg); | 138 | priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg); |
140 | 139 | ||
141 | /* Need to indicate IOCTL complete */ | 140 | /* Need to indicate IOCTL complete */ |
142 | if (data_buf) { | 141 | if (signal) { |
143 | signal = (struct mwifiex_ds_get_signal *) data_buf; | 142 | memset(signal, 0, sizeof(*signal)); |
144 | memset(signal, 0, sizeof(struct mwifiex_ds_get_signal)); | ||
145 | 143 | ||
146 | signal->selector = ALL_RSSI_INFO_MASK; | 144 | signal->selector = ALL_RSSI_INFO_MASK; |
147 | 145 | ||
@@ -185,32 +183,30 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, | |||
185 | */ | 183 | */ |
186 | static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, | 184 | static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, |
187 | struct host_cmd_ds_command *resp, | 185 | struct host_cmd_ds_command *resp, |
188 | void *data_buf) | 186 | u32 *ul_temp) |
189 | { | 187 | { |
190 | struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib; | 188 | struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib; |
191 | u16 oid = le16_to_cpu(smib->oid); | 189 | u16 oid = le16_to_cpu(smib->oid); |
192 | u16 query_type = le16_to_cpu(smib->query_type); | 190 | u16 query_type = le16_to_cpu(smib->query_type); |
193 | u32 ul_temp; | ||
194 | 191 | ||
195 | dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," | 192 | dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," |
196 | " query_type = %#x, buf size = %#x\n", | 193 | " query_type = %#x, buf size = %#x\n", |
197 | oid, query_type, le16_to_cpu(smib->buf_size)); | 194 | oid, query_type, le16_to_cpu(smib->buf_size)); |
198 | if (query_type == HostCmd_ACT_GEN_GET) { | 195 | if (query_type == HostCmd_ACT_GEN_GET) { |
199 | ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); | 196 | if (ul_temp) |
200 | if (data_buf) | 197 | *ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); |
201 | *(u32 *)data_buf = ul_temp; | ||
202 | switch (oid) { | 198 | switch (oid) { |
203 | case FRAG_THRESH_I: | 199 | case FRAG_THRESH_I: |
204 | dev_dbg(priv->adapter->dev, | 200 | dev_dbg(priv->adapter->dev, |
205 | "info: SNMP_RESP: FragThsd =%u\n", ul_temp); | 201 | "info: SNMP_RESP: FragThsd =%u\n", *ul_temp); |
206 | break; | 202 | break; |
207 | case RTS_THRESH_I: | 203 | case RTS_THRESH_I: |
208 | dev_dbg(priv->adapter->dev, | 204 | dev_dbg(priv->adapter->dev, |
209 | "info: SNMP_RESP: RTSThsd =%u\n", ul_temp); | 205 | "info: SNMP_RESP: RTSThsd =%u\n", *ul_temp); |
210 | break; | 206 | break; |
211 | case SHORT_RETRY_LIM_I: | 207 | case SHORT_RETRY_LIM_I: |
212 | dev_dbg(priv->adapter->dev, | 208 | dev_dbg(priv->adapter->dev, |
213 | "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp); | 209 | "info: SNMP_RESP: TxRetryCount=%u\n", *ul_temp); |
214 | break; | 210 | break; |
215 | default: | 211 | default: |
216 | break; | 212 | break; |
@@ -228,14 +224,12 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, | |||
228 | */ | 224 | */ |
229 | static int mwifiex_ret_get_log(struct mwifiex_private *priv, | 225 | static int mwifiex_ret_get_log(struct mwifiex_private *priv, |
230 | struct host_cmd_ds_command *resp, | 226 | struct host_cmd_ds_command *resp, |
231 | void *data_buf) | 227 | struct mwifiex_ds_get_stats *stats) |
232 | { | 228 | { |
233 | struct host_cmd_ds_802_11_get_log *get_log = | 229 | struct host_cmd_ds_802_11_get_log *get_log = |
234 | (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; | 230 | (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; |
235 | struct mwifiex_ds_get_stats *stats; | ||
236 | 231 | ||
237 | if (data_buf) { | 232 | if (stats) { |
238 | stats = (struct mwifiex_ds_get_stats *) data_buf; | ||
239 | stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); | 233 | stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); |
240 | stats->failed = le32_to_cpu(get_log->failed); | 234 | stats->failed = le32_to_cpu(get_log->failed); |
241 | stats->retry = le32_to_cpu(get_log->retry); | 235 | stats->retry = le32_to_cpu(get_log->retry); |
@@ -278,9 +272,8 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv, | |||
278 | */ | 272 | */ |
279 | static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | 273 | static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, |
280 | struct host_cmd_ds_command *resp, | 274 | struct host_cmd_ds_command *resp, |
281 | void *data_buf) | 275 | struct mwifiex_rate_cfg *ds_rate) |
282 | { | 276 | { |
283 | struct mwifiex_rate_cfg *ds_rate; | ||
284 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; | 277 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; |
285 | struct mwifiex_rate_scope *rate_scope; | 278 | struct mwifiex_rate_scope *rate_scope; |
286 | struct mwifiex_ie_types_header *head; | 279 | struct mwifiex_ie_types_header *head; |
@@ -329,8 +322,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
329 | HostCmd_CMD_802_11_TX_RATE_QUERY, | 322 | HostCmd_CMD_802_11_TX_RATE_QUERY, |
330 | HostCmd_ACT_GEN_GET, 0, NULL); | 323 | HostCmd_ACT_GEN_GET, 0, NULL); |
331 | 324 | ||
332 | if (data_buf) { | 325 | if (ds_rate) { |
333 | ds_rate = (struct mwifiex_rate_cfg *) data_buf; | ||
334 | if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { | 326 | if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { |
335 | if (priv->is_data_rate_auto) { | 327 | if (priv->is_data_rate_auto) { |
336 | ds_rate->is_rate_auto = 1; | 328 | ds_rate->is_rate_auto = 1; |
@@ -413,8 +405,7 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) | |||
413 | * and saving the current Tx power level in driver. | 405 | * and saving the current Tx power level in driver. |
414 | */ | 406 | */ |
415 | static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, | 407 | static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, |
416 | struct host_cmd_ds_command *resp, | 408 | struct host_cmd_ds_command *resp) |
417 | void *data_buf) | ||
418 | { | 409 | { |
419 | struct mwifiex_adapter *adapter = priv->adapter; | 410 | struct mwifiex_adapter *adapter = priv->adapter; |
420 | struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg; | 411 | struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg; |
@@ -631,21 +622,21 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, | |||
631 | */ | 622 | */ |
632 | static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, | 623 | static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, |
633 | struct host_cmd_ds_command *resp, | 624 | struct host_cmd_ds_command *resp, |
634 | void *data_buf) | 625 | u16 *new_channel) |
635 | { | 626 | { |
636 | struct host_cmd_ds_802_11_rf_channel *rf_channel = | 627 | struct host_cmd_ds_802_11_rf_channel *rf_channel = |
637 | &resp->params.rf_channel; | 628 | &resp->params.rf_channel; |
638 | u16 new_channel = le16_to_cpu(rf_channel->current_channel); | ||
639 | 629 | ||
640 | if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { | 630 | if (new_channel) |
631 | *new_channel = le16_to_cpu(rf_channel->current_channel); | ||
632 | |||
633 | if (priv->curr_bss_params.bss_descriptor.channel != *new_channel) { | ||
641 | dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", | 634 | dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", |
642 | priv->curr_bss_params.bss_descriptor.channel, | 635 | priv->curr_bss_params.bss_descriptor.channel, |
643 | new_channel); | 636 | *new_channel); |
644 | /* Update the channel again */ | 637 | /* Update the channel again */ |
645 | priv->curr_bss_params.bss_descriptor.channel = new_channel; | 638 | priv->curr_bss_params.bss_descriptor.channel = *new_channel; |
646 | } | 639 | } |
647 | if (data_buf) | ||
648 | *((u16 *)data_buf) = new_channel; | ||
649 | 640 | ||
650 | return 0; | 641 | return 0; |
651 | } | 642 | } |
@@ -658,13 +649,11 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, | |||
658 | */ | 649 | */ |
659 | static int mwifiex_ret_ver_ext(struct mwifiex_private *priv, | 650 | static int mwifiex_ret_ver_ext(struct mwifiex_private *priv, |
660 | struct host_cmd_ds_command *resp, | 651 | struct host_cmd_ds_command *resp, |
661 | void *data_buf) | 652 | struct host_cmd_ds_version_ext *version_ext) |
662 | { | 653 | { |
663 | struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext; | 654 | struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext; |
664 | struct host_cmd_ds_version_ext *version_ext; | ||
665 | 655 | ||
666 | if (data_buf) { | 656 | if (version_ext) { |
667 | version_ext = (struct host_cmd_ds_version_ext *)data_buf; | ||
668 | version_ext->version_str_sel = ver_ext->version_str_sel; | 657 | version_ext->version_str_sel = ver_ext->version_str_sel; |
669 | memcpy(version_ext->version_str, ver_ext->version_str, | 658 | memcpy(version_ext->version_str, ver_ext->version_str, |
670 | sizeof(char) * 128); | 659 | sizeof(char) * 128); |
@@ -686,8 +675,8 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, | |||
686 | struct mwifiex_ds_read_eeprom *eeprom; | 675 | struct mwifiex_ds_read_eeprom *eeprom; |
687 | 676 | ||
688 | if (data_buf) { | 677 | if (data_buf) { |
689 | reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; | 678 | reg_rw = data_buf; |
690 | eeprom = (struct mwifiex_ds_read_eeprom *) data_buf; | 679 | eeprom = data_buf; |
691 | switch (type) { | 680 | switch (type) { |
692 | case HostCmd_CMD_MAC_REG_ACCESS: | 681 | case HostCmd_CMD_MAC_REG_ACCESS: |
693 | { | 682 | { |
@@ -825,13 +814,11 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, | |||
825 | * This is a generic function, which calls command specific | 814 | * This is a generic function, which calls command specific |
826 | * response handlers based on the command ID. | 815 | * response handlers based on the command ID. |
827 | */ | 816 | */ |
828 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | 817 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, |
829 | u16 cmdresp_no, void *cmd_buf) | 818 | struct host_cmd_ds_command *resp) |
830 | { | 819 | { |
831 | int ret = 0; | 820 | int ret = 0; |
832 | struct mwifiex_adapter *adapter = priv->adapter; | 821 | struct mwifiex_adapter *adapter = priv->adapter; |
833 | struct host_cmd_ds_command *resp = | ||
834 | (struct host_cmd_ds_command *) cmd_buf; | ||
835 | void *data_buf = adapter->curr_cmd->data_buf; | 822 | void *data_buf = adapter->curr_cmd->data_buf; |
836 | 823 | ||
837 | /* If the command is not successful, cleanup and return failure */ | 824 | /* If the command is not successful, cleanup and return failure */ |
@@ -865,7 +852,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, | |||
865 | "info: CMD_RESP: BG_SCAN result is ready!\n"); | 852 | "info: CMD_RESP: BG_SCAN result is ready!\n"); |
866 | break; | 853 | break; |
867 | case HostCmd_CMD_TXPWR_CFG: | 854 | case HostCmd_CMD_TXPWR_CFG: |
868 | ret = mwifiex_ret_tx_power_cfg(priv, resp, data_buf); | 855 | ret = mwifiex_ret_tx_power_cfg(priv, resp); |
869 | break; | 856 | break; |
870 | case HostCmd_CMD_802_11_PS_MODE_ENH: | 857 | case HostCmd_CMD_802_11_PS_MODE_ENH: |
871 | ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf); | 858 | ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf); |
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 1fdddece7479..27430512f7cd 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c | |||
@@ -187,7 +187,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, | |||
187 | ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num, | 187 | ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num, |
188 | local_rx_pd->priority, ta, | 188 | local_rx_pd->priority, ta, |
189 | (u8) local_rx_pd->rx_pkt_type, | 189 | (u8) local_rx_pd->rx_pkt_type, |
190 | (void *) skb); | 190 | skb); |
191 | 191 | ||
192 | if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { | 192 | if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { |
193 | if (priv && (ret == -1)) | 193 | if (priv && (ret == -1)) |
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index aaa50c074196..6190b2fa57a3 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c | |||
@@ -71,7 +71,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, | |||
71 | u8 *head_ptr; | 71 | u8 *head_ptr; |
72 | struct txpd *local_tx_pd = NULL; | 72 | struct txpd *local_tx_pd = NULL; |
73 | 73 | ||
74 | head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb); | 74 | head_ptr = mwifiex_process_sta_txpd(priv, skb); |
75 | if (head_ptr) { | 75 | if (head_ptr) { |
76 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) | 76 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) |
77 | local_tx_pd = | 77 | local_tx_pd = |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 939821b4af2f..0955c941317f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -583,6 +583,18 @@ void rt2x00lib_rxdone(struct queue_entry *entry) | |||
583 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | 583 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
584 | 584 | ||
585 | /* | 585 | /* |
586 | * Check for valid size in case we get corrupted descriptor from | ||
587 | * hardware. | ||
588 | */ | ||
589 | if (unlikely(rxdesc.size == 0 || | ||
590 | rxdesc.size > entry->queue->data_size)) { | ||
591 | WARNING(rt2x00dev, "Wrong frame size %d max %d.\n", | ||
592 | rxdesc.size, entry->queue->data_size); | ||
593 | dev_kfree_skb(entry->skb); | ||
594 | goto renew_skb; | ||
595 | } | ||
596 | |||
597 | /* | ||
586 | * The data behind the ieee80211 header must be | 598 | * The data behind the ieee80211 header must be |
587 | * aligned on a 4 byte boundary. | 599 | * aligned on a 4 byte boundary. |
588 | */ | 600 | */ |
@@ -642,6 +654,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry) | |||
642 | 654 | ||
643 | ieee80211_rx_ni(rt2x00dev->hw, entry->skb); | 655 | ieee80211_rx_ni(rt2x00dev->hw, entry->skb); |
644 | 656 | ||
657 | renew_skb: | ||
645 | /* | 658 | /* |
646 | * Replace the skb with the freshly allocated one. | 659 | * Replace the skb with the freshly allocated one. |
647 | */ | 660 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 8f90f6268077..b6b4542c2460 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -802,6 +802,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
802 | int retval; | 802 | int retval; |
803 | 803 | ||
804 | usb_dev = usb_get_dev(usb_dev); | 804 | usb_dev = usb_get_dev(usb_dev); |
805 | usb_reset_device(usb_dev); | ||
805 | 806 | ||
806 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); | 807 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); |
807 | if (!hw) { | 808 | if (!hw) { |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index fb5e43bd7c3c..bc13533a5418 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -523,7 +523,7 @@ static void _rtl_query_shortgi(struct ieee80211_hw *hw, | |||
523 | mac->opmode == NL80211_IFTYPE_ADHOC) | 523 | mac->opmode == NL80211_IFTYPE_ADHOC) |
524 | bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 524 | bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
525 | 525 | ||
526 | if ((bw_40 == true) && sgi_40) | 526 | if (bw_40 && sgi_40) |
527 | tcb_desc->use_shortgi = true; | 527 | tcb_desc->use_shortgi = true; |
528 | else if ((bw_40 == false) && sgi_20) | 528 | else if ((bw_40 == false) && sgi_20) |
529 | tcb_desc->use_shortgi = true; | 529 | tcb_desc->use_shortgi = true; |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index d2ec2535aa3c..03ce69660b26 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -335,8 +335,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
335 | * before going offchannel, or dis-association or delete BA will | 335 | * before going offchannel, or dis-association or delete BA will |
336 | * happen by AP | 336 | * happen by AP |
337 | */ | 337 | */ |
338 | if (rtlpriv->mac80211.offchan_deley) { | 338 | if (rtlpriv->mac80211.offchan_delay) { |
339 | rtlpriv->mac80211.offchan_deley = false; | 339 | rtlpriv->mac80211.offchan_delay = false; |
340 | mdelay(50); | 340 | mdelay(50); |
341 | } | 341 | } |
342 | rtlphy->current_channel = wide_chan; | 342 | rtlphy->current_channel = wide_chan; |
@@ -443,11 +443,11 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, | |||
443 | sta_entry->wireless_mode = WIRELESS_MODE_G; | 443 | sta_entry->wireless_mode = WIRELESS_MODE_G; |
444 | if (sta->supp_rates[0] <= 0xf) | 444 | if (sta->supp_rates[0] <= 0xf) |
445 | sta_entry->wireless_mode = WIRELESS_MODE_B; | 445 | sta_entry->wireless_mode = WIRELESS_MODE_B; |
446 | if (sta->ht_cap.ht_supported == true) | 446 | if (sta->ht_cap.ht_supported) |
447 | sta_entry->wireless_mode = WIRELESS_MODE_N_24G; | 447 | sta_entry->wireless_mode = WIRELESS_MODE_N_24G; |
448 | } else if (rtlhal->current_bandtype == BAND_ON_5G) { | 448 | } else if (rtlhal->current_bandtype == BAND_ON_5G) { |
449 | sta_entry->wireless_mode = WIRELESS_MODE_A; | 449 | sta_entry->wireless_mode = WIRELESS_MODE_A; |
450 | if (sta->ht_cap.ht_supported == true) | 450 | if (sta->ht_cap.ht_supported) |
451 | sta_entry->wireless_mode = WIRELESS_MODE_N_24G; | 451 | sta_entry->wireless_mode = WIRELESS_MODE_N_24G; |
452 | } | 452 | } |
453 | 453 | ||
@@ -650,7 +650,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
650 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 650 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
651 | ("BSS_CHANGED_HT\n")); | 651 | ("BSS_CHANGED_HT\n")); |
652 | rcu_read_lock(); | 652 | rcu_read_lock(); |
653 | sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); | 653 | sta = get_sta(hw, vif, bss_conf->bssid); |
654 | if (sta) { | 654 | if (sta) { |
655 | if (sta->ht_cap.ampdu_density > | 655 | if (sta->ht_cap.ampdu_density > |
656 | mac->current_ampdu_density) | 656 | mac->current_ampdu_density) |
@@ -685,7 +685,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
685 | rtlpriv->cfg->ops->set_network_type(hw, vif->type); | 685 | rtlpriv->cfg->ops->set_network_type(hw, vif->type); |
686 | 686 | ||
687 | rcu_read_lock(); | 687 | rcu_read_lock(); |
688 | sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); | 688 | sta = get_sta(hw, vif, bss_conf->bssid); |
689 | if (!sta) { | 689 | if (!sta) { |
690 | rcu_read_unlock(); | 690 | rcu_read_unlock(); |
691 | goto out; | 691 | goto out; |
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 4b247db2861d..f02824a3b747 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h | |||
@@ -30,6 +30,8 @@ | |||
30 | #ifndef __RTL_CORE_H__ | 30 | #ifndef __RTL_CORE_H__ |
31 | #define __RTL_CORE_H__ | 31 | #define __RTL_CORE_H__ |
32 | 32 | ||
33 | #include <net/mac80211.h> | ||
34 | |||
33 | #define RTL_SUPPORTED_FILTERS \ | 35 | #define RTL_SUPPORTED_FILTERS \ |
34 | (FIF_PROMISC_IN_BSS | \ | 36 | (FIF_PROMISC_IN_BSS | \ |
35 | FIF_ALLMULTI | FIF_CONTROL | \ | 37 | FIF_ALLMULTI | FIF_CONTROL | \ |
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 0b562322f138..3fc21f60bb04 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
@@ -382,7 +382,7 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) | |||
382 | } | 382 | } |
383 | } | 383 | } |
384 | 384 | ||
385 | if (wordchanged == true) | 385 | if (wordchanged) |
386 | hdr_num++; | 386 | hdr_num++; |
387 | } | 387 | } |
388 | 388 | ||
@@ -453,7 +453,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) | |||
453 | base = offset * 8; | 453 | base = offset * 8; |
454 | 454 | ||
455 | for (i = 0; i < 8; i++) { | 455 | for (i = 0; i < 8; i++) { |
456 | if (first_pg == true) { | 456 | if (first_pg) { |
457 | 457 | ||
458 | word_en &= ~(BIT(i / 2)); | 458 | word_en &= ~(BIT(i / 2)); |
459 | 459 | ||
@@ -505,7 +505,7 @@ void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw) | |||
505 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 505 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
506 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 506 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
507 | 507 | ||
508 | if (rtlefuse->autoload_failflag == true) | 508 | if (rtlefuse->autoload_failflag) |
509 | memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, | 509 | memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, |
510 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); | 510 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); |
511 | else | 511 | else |
@@ -690,7 +690,7 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
690 | } | 690 | } |
691 | } | 691 | } |
692 | 692 | ||
693 | if (dataempty == true) { | 693 | if (dataempty) { |
694 | *readstate = PG_STATE_DATA; | 694 | *readstate = PG_STATE_DATA; |
695 | } else { | 695 | } else { |
696 | *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; | 696 | *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index e502db0532e5..ad39af462f87 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -581,7 +581,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) | |||
581 | fc = rtl_get_fc(skb); | 581 | fc = rtl_get_fc(skb); |
582 | if (ieee80211_is_nullfunc(fc)) { | 582 | if (ieee80211_is_nullfunc(fc)) { |
583 | if (ieee80211_has_pm(fc)) { | 583 | if (ieee80211_has_pm(fc)) { |
584 | rtlpriv->mac80211.offchan_deley = true; | 584 | rtlpriv->mac80211.offchan_delay = true; |
585 | rtlpriv->psc.state_inap = 1; | 585 | rtlpriv->psc.state_inap = 1; |
586 | } else { | 586 | } else { |
587 | rtlpriv->psc.state_inap = 0; | 587 | rtlpriv->psc.state_inap = 0; |
@@ -626,6 +626,56 @@ tx_status_ok: | |||
626 | } | 626 | } |
627 | } | 627 | } |
628 | 628 | ||
629 | static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
630 | struct ieee80211_rx_status rx_status) | ||
631 | { | ||
632 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
633 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); | ||
634 | __le16 fc = rtl_get_fc(skb); | ||
635 | bool unicast = false; | ||
636 | struct sk_buff *uskb = NULL; | ||
637 | u8 *pdata; | ||
638 | |||
639 | |||
640 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); | ||
641 | |||
642 | if (is_broadcast_ether_addr(hdr->addr1)) { | ||
643 | ;/*TODO*/ | ||
644 | } else if (is_multicast_ether_addr(hdr->addr1)) { | ||
645 | ;/*TODO*/ | ||
646 | } else { | ||
647 | unicast = true; | ||
648 | rtlpriv->stats.rxbytesunicast += skb->len; | ||
649 | } | ||
650 | |||
651 | rtl_is_special_data(hw, skb, false); | ||
652 | |||
653 | if (ieee80211_is_data(fc)) { | ||
654 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); | ||
655 | |||
656 | if (unicast) | ||
657 | rtlpriv->link_info.num_rx_inperiod++; | ||
658 | } | ||
659 | |||
660 | /* for sw lps */ | ||
661 | rtl_swlps_beacon(hw, (void *)skb->data, skb->len); | ||
662 | rtl_recognize_peer(hw, (void *)skb->data, skb->len); | ||
663 | if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && | ||
664 | (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) && | ||
665 | (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc))) | ||
666 | return; | ||
667 | |||
668 | if (unlikely(!rtl_action_proc(hw, skb, false))) | ||
669 | return; | ||
670 | |||
671 | uskb = dev_alloc_skb(skb->len + 128); | ||
672 | memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status)); | ||
673 | pdata = (u8 *)skb_put(uskb, skb->len); | ||
674 | memcpy(pdata, skb->data, skb->len); | ||
675 | |||
676 | ieee80211_rx_irqsafe(hw, uskb); | ||
677 | } | ||
678 | |||
629 | static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | 679 | static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) |
630 | { | 680 | { |
631 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 681 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -637,7 +687,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
637 | u8 own; | 687 | u8 own; |
638 | u8 tmp_one; | 688 | u8 tmp_one; |
639 | u32 bufferaddress; | 689 | u32 bufferaddress; |
640 | bool unicast = false; | ||
641 | 690 | ||
642 | struct rtl_stats stats = { | 691 | struct rtl_stats stats = { |
643 | .signal = 0, | 692 | .signal = 0, |
@@ -654,128 +703,63 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
654 | /*rx pkt */ | 703 | /*rx pkt */ |
655 | struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ | 704 | struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ |
656 | index]; | 705 | index]; |
706 | struct sk_buff *new_skb = NULL; | ||
657 | 707 | ||
658 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, | 708 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, |
659 | false, HW_DESC_OWN); | 709 | false, HW_DESC_OWN); |
660 | 710 | ||
661 | if (own) { | 711 | /*wait data to be filled by hardware */ |
662 | /*wait data to be filled by hardware */ | 712 | if (own) |
663 | break; | 713 | break; |
664 | } else { | ||
665 | struct ieee80211_hdr *hdr; | ||
666 | __le16 fc; | ||
667 | struct sk_buff *new_skb = NULL; | ||
668 | |||
669 | rtlpriv->cfg->ops->query_rx_desc(hw, &stats, | ||
670 | &rx_status, | ||
671 | (u8 *) pdesc, skb); | ||
672 | |||
673 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); | ||
674 | if (unlikely(!new_skb)) { | ||
675 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), | ||
676 | DBG_DMESG, | ||
677 | ("can't alloc skb for rx\n")); | ||
678 | goto done; | ||
679 | } | ||
680 | 714 | ||
681 | pci_unmap_single(rtlpci->pdev, | 715 | rtlpriv->cfg->ops->query_rx_desc(hw, &stats, |
682 | *((dma_addr_t *) skb->cb), | 716 | &rx_status, |
683 | rtlpci->rxbuffersize, | 717 | (u8 *) pdesc, skb); |
684 | PCI_DMA_FROMDEVICE); | ||
685 | 718 | ||
686 | skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, | 719 | if (stats.crc || stats.hwerror) |
687 | false, | 720 | goto done; |
688 | HW_DESC_RXPKT_LEN)); | ||
689 | skb_reserve(skb, | ||
690 | stats.rx_drvinfo_size + stats.rx_bufshift); | ||
691 | 721 | ||
692 | /* | 722 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); |
693 | *NOTICE This can not be use for mac80211, | 723 | if (unlikely(!new_skb)) { |
694 | *this is done in mac80211 code, | 724 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), |
695 | *if you done here sec DHCP will fail | 725 | DBG_DMESG, |
696 | *skb_trim(skb, skb->len - 4); | 726 | ("can't alloc skb for rx\n")); |
697 | */ | 727 | goto done; |
728 | } | ||
698 | 729 | ||
699 | hdr = rtl_get_hdr(skb); | 730 | pci_unmap_single(rtlpci->pdev, |
700 | fc = rtl_get_fc(skb); | 731 | *((dma_addr_t *) skb->cb), |
701 | 732 | rtlpci->rxbuffersize, | |
702 | if (!stats.crc && !stats.hwerror) { | 733 | PCI_DMA_FROMDEVICE); |
703 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, | ||
704 | sizeof(rx_status)); | ||
705 | |||
706 | if (is_broadcast_ether_addr(hdr->addr1)) { | ||
707 | ;/*TODO*/ | ||
708 | } else if (is_multicast_ether_addr(hdr->addr1)) { | ||
709 | ;/*TODO*/ | ||
710 | } else { | ||
711 | unicast = true; | ||
712 | rtlpriv->stats.rxbytesunicast += | ||
713 | skb->len; | ||
714 | } | ||
715 | |||
716 | rtl_is_special_data(hw, skb, false); | ||
717 | |||
718 | if (ieee80211_is_data(fc)) { | ||
719 | rtlpriv->cfg->ops->led_control(hw, | ||
720 | LED_CTL_RX); | ||
721 | |||
722 | if (unicast) | ||
723 | rtlpriv->link_info. | ||
724 | num_rx_inperiod++; | ||
725 | } | ||
726 | |||
727 | /* for sw lps */ | ||
728 | rtl_swlps_beacon(hw, (void *)skb->data, | ||
729 | skb->len); | ||
730 | rtl_recognize_peer(hw, (void *)skb->data, | ||
731 | skb->len); | ||
732 | if ((rtlpriv->mac80211.opmode == | ||
733 | NL80211_IFTYPE_AP) && | ||
734 | (rtlpriv->rtlhal.current_bandtype == | ||
735 | BAND_ON_2_4G) && | ||
736 | (ieee80211_is_beacon(fc) || | ||
737 | ieee80211_is_probe_resp(fc))) { | ||
738 | dev_kfree_skb_any(skb); | ||
739 | } else { | ||
740 | if (unlikely(!rtl_action_proc(hw, skb, | ||
741 | false))) { | ||
742 | dev_kfree_skb_any(skb); | ||
743 | } else { | ||
744 | struct sk_buff *uskb = NULL; | ||
745 | u8 *pdata; | ||
746 | uskb = dev_alloc_skb(skb->len | ||
747 | + 128); | ||
748 | memcpy(IEEE80211_SKB_RXCB(uskb), | ||
749 | &rx_status, | ||
750 | sizeof(rx_status)); | ||
751 | pdata = (u8 *)skb_put(uskb, | ||
752 | skb->len); | ||
753 | memcpy(pdata, skb->data, | ||
754 | skb->len); | ||
755 | dev_kfree_skb_any(skb); | ||
756 | |||
757 | ieee80211_rx_irqsafe(hw, uskb); | ||
758 | } | ||
759 | } | ||
760 | } else { | ||
761 | dev_kfree_skb_any(skb); | ||
762 | } | ||
763 | 734 | ||
764 | if (((rtlpriv->link_info.num_rx_inperiod + | 735 | skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false, |
765 | rtlpriv->link_info.num_tx_inperiod) > 8) || | 736 | HW_DESC_RXPKT_LEN)); |
766 | (rtlpriv->link_info.num_rx_inperiod > 2)) { | 737 | skb_reserve(skb, stats.rx_drvinfo_size + stats.rx_bufshift); |
767 | tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); | ||
768 | } | ||
769 | 738 | ||
770 | skb = new_skb; | 739 | /* |
740 | * NOTICE This can not be use for mac80211, | ||
741 | * this is done in mac80211 code, | ||
742 | * if you done here sec DHCP will fail | ||
743 | * skb_trim(skb, skb->len - 4); | ||
744 | */ | ||
771 | 745 | ||
772 | rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; | 746 | _rtl_receive_one(hw, skb, rx_status); |
773 | *((dma_addr_t *) skb->cb) = | 747 | |
748 | if (((rtlpriv->link_info.num_rx_inperiod + | ||
749 | rtlpriv->link_info.num_tx_inperiod) > 8) || | ||
750 | (rtlpriv->link_info.num_rx_inperiod > 2)) { | ||
751 | tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); | ||
752 | } | ||
753 | |||
754 | dev_kfree_skb_any(skb); | ||
755 | skb = new_skb; | ||
756 | |||
757 | rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; | ||
758 | *((dma_addr_t *) skb->cb) = | ||
774 | pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), | 759 | pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), |
775 | rtlpci->rxbuffersize, | 760 | rtlpci->rxbuffersize, |
776 | PCI_DMA_FROMDEVICE); | 761 | PCI_DMA_FROMDEVICE); |
777 | 762 | ||
778 | } | ||
779 | done: | 763 | done: |
780 | bufferaddress = (*((dma_addr_t *)skb->cb)); | 764 | bufferaddress = (*((dma_addr_t *)skb->cb)); |
781 | tmp_one = 1; | 765 | tmp_one = 1; |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index d14c13d02177..a693feffbe72 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -79,59 +79,18 @@ EXPORT_SYMBOL(rtl_ps_disable_nic); | |||
79 | 79 | ||
80 | bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, | 80 | bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, |
81 | enum rf_pwrstate state_toset, | 81 | enum rf_pwrstate state_toset, |
82 | u32 changesource, bool protect_or_not) | 82 | u32 changesource) |
83 | { | 83 | { |
84 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 84 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
85 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 85 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
86 | bool actionallowed = false; | 86 | bool actionallowed = false; |
87 | u16 rfwait_cnt = 0; | ||
88 | 87 | ||
89 | /*protect_or_not = true; */ | ||
90 | |||
91 | if (protect_or_not) | ||
92 | goto no_protect; | ||
93 | |||
94 | /* | ||
95 | *Only one thread can change | ||
96 | *the RF state at one time, and others | ||
97 | *should wait to be executed. | ||
98 | */ | ||
99 | while (true) { | ||
100 | spin_lock(&rtlpriv->locks.rf_ps_lock); | ||
101 | if (ppsc->rfchange_inprogress) { | ||
102 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
103 | |||
104 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
105 | ("RF Change in progress!" | ||
106 | "Wait to set..state_toset(%d).\n", | ||
107 | state_toset)); | ||
108 | |||
109 | /* Set RF after the previous action is done. */ | ||
110 | while (ppsc->rfchange_inprogress) { | ||
111 | rfwait_cnt++; | ||
112 | mdelay(1); | ||
113 | |||
114 | /* | ||
115 | *Wait too long, return false to avoid | ||
116 | *to be stuck here. | ||
117 | */ | ||
118 | if (rfwait_cnt > 100) | ||
119 | return false; | ||
120 | } | ||
121 | } else { | ||
122 | ppsc->rfchange_inprogress = true; | ||
123 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
124 | break; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | no_protect: | ||
129 | switch (state_toset) { | 88 | switch (state_toset) { |
130 | case ERFON: | 89 | case ERFON: |
131 | ppsc->rfoff_reason &= (~changesource); | 90 | ppsc->rfoff_reason &= (~changesource); |
132 | 91 | ||
133 | if ((changesource == RF_CHANGE_BY_HW) && | 92 | if ((changesource == RF_CHANGE_BY_HW) && |
134 | (ppsc->hwradiooff == true)) { | 93 | (ppsc->hwradiooff)) { |
135 | ppsc->hwradiooff = false; | 94 | ppsc->hwradiooff = false; |
136 | } | 95 | } |
137 | 96 | ||
@@ -167,12 +126,6 @@ no_protect: | |||
167 | if (actionallowed) | 126 | if (actionallowed) |
168 | rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); | 127 | rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); |
169 | 128 | ||
170 | if (!protect_or_not) { | ||
171 | spin_lock(&rtlpriv->locks.rf_ps_lock); | ||
172 | ppsc->rfchange_inprogress = false; | ||
173 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
174 | } | ||
175 | |||
176 | return actionallowed; | 129 | return actionallowed; |
177 | } | 130 | } |
178 | EXPORT_SYMBOL(rtl_ps_set_rf_state); | 131 | EXPORT_SYMBOL(rtl_ps_set_rf_state); |
@@ -195,8 +148,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) | |||
195 | } | 148 | } |
196 | } | 149 | } |
197 | 150 | ||
198 | rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, | 151 | rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, RF_CHANGE_BY_IPS); |
199 | RF_CHANGE_BY_IPS, false); | ||
200 | 152 | ||
201 | if (ppsc->inactive_pwrstate == ERFOFF && | 153 | if (ppsc->inactive_pwrstate == ERFOFF && |
202 | rtlhal->interface == INTF_PCI) { | 154 | rtlhal->interface == INTF_PCI) { |
@@ -587,7 +539,7 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
587 | } | 539 | } |
588 | 540 | ||
589 | spin_lock(&rtlpriv->locks.lps_lock); | 541 | spin_lock(&rtlpriv->locks.lps_lock); |
590 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false); | 542 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); |
591 | spin_unlock(&rtlpriv->locks.lps_lock); | 543 | spin_unlock(&rtlpriv->locks.lps_lock); |
592 | } | 544 | } |
593 | 545 | ||
@@ -621,15 +573,8 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
621 | if (rtlpriv->link_info.busytraffic) | 573 | if (rtlpriv->link_info.busytraffic) |
622 | return; | 574 | return; |
623 | 575 | ||
624 | spin_lock(&rtlpriv->locks.rf_ps_lock); | ||
625 | if (rtlpriv->psc.rfchange_inprogress) { | ||
626 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
627 | return; | ||
628 | } | ||
629 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
630 | |||
631 | spin_lock(&rtlpriv->locks.lps_lock); | 576 | spin_lock(&rtlpriv->locks.lps_lock); |
632 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false); | 577 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); |
633 | spin_unlock(&rtlpriv->locks.lps_lock); | 578 | spin_unlock(&rtlpriv->locks.lps_lock); |
634 | 579 | ||
635 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && | 580 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && |
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index e3bf89840370..84628e6041c7 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h | |||
@@ -33,8 +33,7 @@ | |||
33 | #define MAX_SW_LPS_SLEEP_INTV 5 | 33 | #define MAX_SW_LPS_SLEEP_INTV 5 |
34 | 34 | ||
35 | bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, | 35 | bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, |
36 | enum rf_pwrstate state_toset, u32 changesource, | 36 | enum rf_pwrstate state_toset, u32 changesource); |
37 | bool protect_or_not); | ||
38 | bool rtl_ps_enable_nic(struct ieee80211_hw *hw); | 37 | bool rtl_ps_enable_nic(struct ieee80211_hw *hw); |
39 | bool rtl_ps_disable_nic(struct ieee80211_hw *hw); | 38 | bool rtl_ps_disable_nic(struct ieee80211_hw *hw); |
40 | void rtl_ips_nic_off(struct ieee80211_hw *hw); | 39 | void rtl_ips_nic_off(struct ieee80211_hw *hw); |
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 30da68a77786..539df66dce0a 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c | |||
@@ -200,7 +200,7 @@ static void rtl_tx_status(void *ppriv, | |||
200 | if (sta) { | 200 | if (sta) { |
201 | /* Check if aggregation has to be enabled for this tid */ | 201 | /* Check if aggregation has to be enabled for this tid */ |
202 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | 202 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
203 | if ((sta->ht_cap.ht_supported == true) && | 203 | if ((sta->ht_cap.ht_supported) && |
204 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 204 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { |
205 | if (ieee80211_is_data_qos(fc)) { | 205 | if (ieee80211_is_data_qos(fc)) { |
206 | u8 tid = rtl_get_tid(skb); | 206 | u8 tid = rtl_get_tid(skb); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 97183829b9be..a00774e7090d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -474,7 +474,7 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) | |||
474 | { | 474 | { |
475 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 475 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
476 | 476 | ||
477 | if (mac->act_scanning == true) | 477 | if (mac->act_scanning) |
478 | return; | 478 | return; |
479 | 479 | ||
480 | if (mac->link_state >= MAC80211_LINKED) | 480 | if (mac->link_state >= MAC80211_LINKED) |
@@ -670,7 +670,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
670 | u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; | 670 | u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; |
671 | int i; | 671 | int i; |
672 | bool is2t = IS_92C_SERIAL(rtlhal->version); | 672 | bool is2t = IS_92C_SERIAL(rtlhal->version); |
673 | u8 txpwr_level[2] = {0, 0}; | 673 | s8 txpwr_level[2] = {0, 0}; |
674 | u8 ofdm_min_index = 6, rf; | 674 | u8 ofdm_min_index = 6, rf; |
675 | 675 | ||
676 | rtlpriv->dm.txpower_trackinginit = true; | 676 | rtlpriv->dm.txpower_trackinginit = true; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 944f55e9d316..bc6ae9dcf940 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -488,7 +488,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
488 | case HW_VAR_CORRECT_TSF:{ | 488 | case HW_VAR_CORRECT_TSF:{ |
489 | u8 btype_ibss = ((u8 *) (val))[0]; | 489 | u8 btype_ibss = ((u8 *) (val))[0]; |
490 | 490 | ||
491 | if (btype_ibss == true) | 491 | if (btype_ibss) |
492 | _rtl92ce_stop_tx_beacon(hw); | 492 | _rtl92ce_stop_tx_beacon(hw); |
493 | 493 | ||
494 | _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); | 494 | _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3)); |
@@ -500,7 +500,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
500 | 500 | ||
501 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); | 501 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); |
502 | 502 | ||
503 | if (btype_ibss == true) | 503 | if (btype_ibss) |
504 | _rtl92ce_resume_tx_beacon(hw); | 504 | _rtl92ce_resume_tx_beacon(hw); |
505 | 505 | ||
506 | break; | 506 | break; |
@@ -1121,7 +1121,7 @@ void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) | |||
1121 | if (rtlpriv->psc.rfpwr_state != ERFON) | 1121 | if (rtlpriv->psc.rfpwr_state != ERFON) |
1122 | return; | 1122 | return; |
1123 | 1123 | ||
1124 | if (check_bssid == true) { | 1124 | if (check_bssid) { |
1125 | reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); | 1125 | reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); |
1126 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | 1126 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, |
1127 | (u8 *) (®_rcr)); | 1127 | (u8 *) (®_rcr)); |
@@ -1585,7 +1585,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) | |||
1585 | rtlefuse->autoload_failflag = false; | 1585 | rtlefuse->autoload_failflag = false; |
1586 | } | 1586 | } |
1587 | 1587 | ||
1588 | if (rtlefuse->autoload_failflag == true) | 1588 | if (rtlefuse->autoload_failflag) |
1589 | return; | 1589 | return; |
1590 | 1590 | ||
1591 | for (i = 0; i < 6; i += 2) { | 1591 | for (i = 0; i < 6; i += 2) { |
@@ -1994,7 +1994,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) | |||
1994 | u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); | 1994 | u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); |
1995 | e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; | 1995 | e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; |
1996 | 1996 | ||
1997 | if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { | 1997 | if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { |
1998 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | 1998 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, |
1999 | ("GPIOChangeRF - HW Radio ON, RF ON\n")); | 1999 | ("GPIOChangeRF - HW Radio ON, RF ON\n")); |
2000 | 2000 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 9dd1ed7b6422..28a1a707d09c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c | |||
@@ -84,7 +84,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
84 | break; | 84 | break; |
85 | case LED_PIN_LED0: | 85 | case LED_PIN_LED0: |
86 | ledcfg &= 0xf0; | 86 | ledcfg &= 0xf0; |
87 | if (pcipriv->ledctl.led_opendrain == true) | 87 | if (pcipriv->ledctl.led_opendrain) |
88 | rtl_write_byte(rtlpriv, REG_LEDCFG2, | 88 | rtl_write_byte(rtlpriv, REG_LEDCFG2, |
89 | (ledcfg | BIT(1) | BIT(5) | BIT(6))); | 89 | (ledcfg | BIT(1) | BIT(5) | BIT(6))); |
90 | else | 90 | else |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 90d0f2cf3b27..d3b01e6023ba 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | |||
@@ -76,7 +76,7 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | |||
76 | if (rtlefuse->eeprom_regulatory != 0) | 76 | if (rtlefuse->eeprom_regulatory != 0) |
77 | turbo_scanoff = true; | 77 | turbo_scanoff = true; |
78 | 78 | ||
79 | if (mac->act_scanning == true) { | 79 | if (mac->act_scanning) { |
80 | tx_agc[RF90_PATH_A] = 0x3f3f3f3f; | 80 | tx_agc[RF90_PATH_A] = 0x3f3f3f3f; |
81 | tx_agc[RF90_PATH_B] = 0x3f3f3f3f; | 81 | tx_agc[RF90_PATH_B] = 0x3f3f3f3f; |
82 | 82 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 2492cc234c03..230bbe900d8d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
@@ -225,7 +225,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
225 | { | 225 | { |
226 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 226 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
227 | struct phy_sts_cck_8192s_t *cck_buf; | 227 | struct phy_sts_cck_8192s_t *cck_buf; |
228 | s8 rx_pwr_all, rx_pwr[4]; | 228 | s8 rx_pwr_all = 0, rx_pwr[4]; |
229 | u8 evm, pwdb_all, rf_rx_num = 0; | 229 | u8 evm, pwdb_all, rf_rx_num = 0; |
230 | u8 i, max_spatial_stream; | 230 | u8 i, max_spatial_stream; |
231 | u32 rssi, total_rssi = 0; | 231 | u32 rssi, total_rssi = 0; |
@@ -678,7 +678,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, | |||
678 | GET_RX_DESC_PAGGR(pdesc)); | 678 | GET_RX_DESC_PAGGR(pdesc)); |
679 | 679 | ||
680 | rx_status->mactime = GET_RX_DESC_TSFL(pdesc); | 680 | rx_status->mactime = GET_RX_DESC_TSFL(pdesc); |
681 | if (phystatus == true) { | 681 | if (phystatus) { |
682 | p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + | 682 | p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + |
683 | stats->rx_bufshift); | 683 | stats->rx_bufshift); |
684 | 684 | ||
@@ -927,7 +927,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
927 | 927 | ||
928 | void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | 928 | void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) |
929 | { | 929 | { |
930 | if (istx == true) { | 930 | if (istx) { |
931 | switch (desc_name) { | 931 | switch (desc_name) { |
932 | case HW_DESC_OWN: | 932 | case HW_DESC_OWN: |
933 | wmb(); | 933 | wmb(); |
@@ -968,7 +968,7 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) | |||
968 | { | 968 | { |
969 | u32 ret = 0; | 969 | u32 ret = 0; |
970 | 970 | ||
971 | if (istx == true) { | 971 | if (istx) { |
972 | switch (desc_name) { | 972 | switch (desc_name) { |
973 | case HW_DESC_OWN: | 973 | case HW_DESC_OWN: |
974 | ret = GET_TX_DESC_OWN(p_desc); | 974 | ret = GET_TX_DESC_OWN(p_desc); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 52e2af58c1ed..2b34764fbf73 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -520,7 +520,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) | |||
520 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); | 520 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); |
521 | rtlefuse->autoload_failflag = false; | 521 | rtlefuse->autoload_failflag = false; |
522 | } | 522 | } |
523 | if (rtlefuse->autoload_failflag == true) | 523 | if (rtlefuse->autoload_failflag) |
524 | return; | 524 | return; |
525 | for (i = 0; i < 6; i += 2) { | 525 | for (i = 0; i < 6; i += 2) { |
526 | usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; | 526 | usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; |
@@ -1594,7 +1594,7 @@ static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw, | |||
1594 | default: | 1594 | default: |
1595 | break; | 1595 | break; |
1596 | } | 1596 | } |
1597 | if (filterout_non_associated_bssid == true) { | 1597 | if (filterout_non_associated_bssid) { |
1598 | if (IS_NORMAL_CHIP(rtlhal->version)) { | 1598 | if (IS_NORMAL_CHIP(rtlhal->version)) { |
1599 | switch (rtlphy->current_io_type) { | 1599 | switch (rtlphy->current_io_type) { |
1600 | case IO_CMD_RESUME_DM_BY_SCAN: | 1600 | case IO_CMD_RESUME_DM_BY_SCAN: |
@@ -2155,7 +2155,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
2155 | case HW_VAR_CORRECT_TSF:{ | 2155 | case HW_VAR_CORRECT_TSF:{ |
2156 | u8 btype_ibss = ((u8 *) (val))[0]; | 2156 | u8 btype_ibss = ((u8 *) (val))[0]; |
2157 | 2157 | ||
2158 | if (btype_ibss == true) | 2158 | if (btype_ibss) |
2159 | _rtl92cu_stop_tx_beacon(hw); | 2159 | _rtl92cu_stop_tx_beacon(hw); |
2160 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); | 2160 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); |
2161 | rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf & | 2161 | rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf & |
@@ -2163,7 +2163,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
2163 | rtl_write_dword(rtlpriv, REG_TSFTR + 4, | 2163 | rtl_write_dword(rtlpriv, REG_TSFTR + 4, |
2164 | (u32)((mac->tsf >> 32) & 0xffffffff)); | 2164 | (u32)((mac->tsf >> 32) & 0xffffffff)); |
2165 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); | 2165 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); |
2166 | if (btype_ibss == true) | 2166 | if (btype_ibss) |
2167 | _rtl92cu_resume_tx_beacon(hw); | 2167 | _rtl92cu_resume_tx_beacon(hw); |
2168 | break; | 2168 | break; |
2169 | } | 2169 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c index 332c74348a69..2ff9d8314e7b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c | |||
@@ -82,7 +82,7 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
82 | break; | 82 | break; |
83 | case LED_PIN_LED0: | 83 | case LED_PIN_LED0: |
84 | ledcfg &= 0xf0; | 84 | ledcfg &= 0xf0; |
85 | if (usbpriv->ledctl.led_opendrain == true) | 85 | if (usbpriv->ledctl.led_opendrain) |
86 | rtl_write_byte(rtlpriv, REG_LEDCFG2, | 86 | rtl_write_byte(rtlpriv, REG_LEDCFG2, |
87 | (ledcfg | BIT(1) | BIT(5) | BIT(6))); | 87 | (ledcfg | BIT(1) | BIT(5) | BIT(6))); |
88 | else | 88 | else |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index c7576ec4744e..1e851aae58db 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | |||
@@ -82,7 +82,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | |||
82 | (rtlefuse->external_pa)) | 82 | (rtlefuse->external_pa)) |
83 | turbo_scanoff = true; | 83 | turbo_scanoff = true; |
84 | } | 84 | } |
85 | if (mac->act_scanning == true) { | 85 | if (mac->act_scanning) { |
86 | tx_agc[RF90_PATH_A] = 0x3f3f3f3f; | 86 | tx_agc[RF90_PATH_A] = 0x3f3f3f3f; |
87 | tx_agc[RF90_PATH_B] = 0x3f3f3f3f; | 87 | tx_agc[RF90_PATH_B] = 0x3f3f3f3f; |
88 | if (turbo_scanoff) { | 88 | if (turbo_scanoff) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 3a92ba3c4a1e..906e7aa55bc3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
@@ -342,7 +342,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, | |||
342 | (u8)GET_RX_DESC_RX_MCS(pdesc), | 342 | (u8)GET_RX_DESC_RX_MCS(pdesc), |
343 | (bool)GET_RX_DESC_PAGGR(pdesc)); | 343 | (bool)GET_RX_DESC_PAGGR(pdesc)); |
344 | rx_status->mactime = GET_RX_DESC_TSFL(pdesc); | 344 | rx_status->mactime = GET_RX_DESC_TSFL(pdesc); |
345 | if (phystatus == true) { | 345 | if (phystatus) { |
346 | p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); | 346 | p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); |
347 | rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, | 347 | rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, |
348 | p_drvinfo); | 348 | p_drvinfo); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 609c7ec7e66a..4203a8531ca0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c | |||
@@ -452,7 +452,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) | |||
452 | if (rtlpriv->psc.rfpwr_state != ERFON) | 452 | if (rtlpriv->psc.rfpwr_state != ERFON) |
453 | return; | 453 | return; |
454 | 454 | ||
455 | if (digtable.backoff_enable_flag == true) | 455 | if (digtable.backoff_enable_flag) |
456 | rtl92s_backoff_enable_flag(hw); | 456 | rtl92s_backoff_enable_flag(hw); |
457 | else | 457 | else |
458 | digtable.backoff_val = DM_DIG_BACKOFF; | 458 | digtable.backoff_val = DM_DIG_BACKOFF; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 35dd12d0dcf3..13da7b3c0202 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c | |||
@@ -516,7 +516,7 @@ static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw) | |||
516 | mdelay(10); | 516 | mdelay(10); |
517 | 517 | ||
518 | /* check GPIO3 */ | 518 | /* check GPIO3 */ |
519 | u1tmp = rtl_read_byte(rtlpriv, GPIO_IN); | 519 | u1tmp = rtl_read_byte(rtlpriv, GPIO_IN_SE); |
520 | retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF; | 520 | retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF; |
521 | 521 | ||
522 | return retval; | 522 | return retval; |
@@ -994,7 +994,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) | |||
994 | 994 | ||
995 | rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT; | 995 | rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT; |
996 | rtlpriv->psc.rfpwr_state = ERFON; | 996 | rtlpriv->psc.rfpwr_state = ERFON; |
997 | rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason, true); | 997 | /* FIXME: check spinlocks if this block is uncommented */ |
998 | rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason); | ||
998 | } else { | 999 | } else { |
999 | /* gpio radio on/off is out of adapter start */ | 1000 | /* gpio radio on/off is out of adapter start */ |
1000 | if (rtlpriv->psc.hwradiooff == false) { | 1001 | if (rtlpriv->psc.hwradiooff == false) { |
@@ -1105,7 +1106,7 @@ void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) | |||
1105 | if (rtlpriv->psc.rfpwr_state != ERFON) | 1106 | if (rtlpriv->psc.rfpwr_state != ERFON) |
1106 | return; | 1107 | return; |
1107 | 1108 | ||
1108 | if (check_bssid == true) { | 1109 | if (check_bssid) { |
1109 | reg_rcr |= (RCR_CBSSID); | 1110 | reg_rcr |= (RCR_CBSSID); |
1110 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); | 1111 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); |
1111 | } else if (check_bssid == false) { | 1112 | } else if (check_bssid == false) { |
@@ -1651,7 +1652,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
1651 | rtlefuse->autoload_failflag = false; | 1652 | rtlefuse->autoload_failflag = false; |
1652 | } | 1653 | } |
1653 | 1654 | ||
1654 | if (rtlefuse->autoload_failflag == true) | 1655 | if (rtlefuse->autoload_failflag) |
1655 | return; | 1656 | return; |
1656 | 1657 | ||
1657 | _rtl8192se_get_IC_Inferiority(hw); | 1658 | _rtl8192se_get_IC_Inferiority(hw); |
@@ -2301,7 +2302,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) | |||
2301 | 2302 | ||
2302 | rfpwr_toset = _rtl92se_rf_onoff_detect(hw); | 2303 | rfpwr_toset = _rtl92se_rf_onoff_detect(hw); |
2303 | 2304 | ||
2304 | if ((ppsc->hwradiooff == true) && (rfpwr_toset == ERFON)) { | 2305 | if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { |
2305 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | 2306 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, |
2306 | ("RFKILL-HW Radio ON, RF ON\n")); | 2307 | ("RFKILL-HW Radio ON, RF ON\n")); |
2307 | 2308 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index 6d4f66616680..e3fe7c90ebf4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c | |||
@@ -90,7 +90,7 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
90 | break; | 90 | break; |
91 | case LED_PIN_LED0: | 91 | case LED_PIN_LED0: |
92 | ledcfg &= 0xf0; | 92 | ledcfg &= 0xf0; |
93 | if (pcipriv->ledctl.led_opendrain == true) | 93 | if (pcipriv->ledctl.led_opendrain) |
94 | rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1))); | 94 | rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1))); |
95 | else | 95 | else |
96 | rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3))); | 96 | rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3))); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 7ee2daccd7d5..81a5aa4370cf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c | |||
@@ -1416,7 +1416,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) | |||
1416 | break; | 1416 | break; |
1417 | case FW_CMD_HIGH_PWR_ENABLE: | 1417 | case FW_CMD_HIGH_PWR_ENABLE: |
1418 | if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || | 1418 | if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || |
1419 | (rtlpriv->dm.dynamic_txpower_enable == true)) | 1419 | rtlpriv->dm.dynamic_txpower_enable) |
1420 | break; | 1420 | break; |
1421 | 1421 | ||
1422 | /* CCA threshold */ | 1422 | /* CCA threshold */ |
@@ -1608,7 +1608,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) | |||
1608 | fw_cmdmap &= ~FW_DIG_ENABLE_CTL; | 1608 | fw_cmdmap &= ~FW_DIG_ENABLE_CTL; |
1609 | 1609 | ||
1610 | if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || | 1610 | if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || |
1611 | (rtlpriv->dm.dynamic_txpower_enable == true)) | 1611 | rtlpriv->dm.dynamic_txpower_enable) |
1612 | fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; | 1612 | fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; |
1613 | 1613 | ||
1614 | if ((digtable.dig_ext_port_stage == | 1614 | if ((digtable.dig_ext_port_stage == |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h index 0116eaddbfac..ea32ef2d4098 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h | |||
@@ -248,12 +248,8 @@ | |||
248 | #define PSTIME 0x02E0 | 248 | #define PSTIME 0x02E0 |
249 | #define TIMER0 0x02E4 | 249 | #define TIMER0 0x02E4 |
250 | #define TIMER1 0x02E8 | 250 | #define TIMER1 0x02E8 |
251 | #define GPIO_CTRL 0x02EC | 251 | #define GPIO_IN_SE 0x02EC |
252 | #define GPIO_IN 0x02EC | ||
253 | #define GPIO_OUT 0x02ED | ||
254 | #define GPIO_IO_SEL 0x02EE | 252 | #define GPIO_IO_SEL 0x02EE |
255 | #define GPIO_MOD 0x02EF | ||
256 | #define GPIO_INTCTRL 0x02F0 | ||
257 | #define MAC_PINMUX_CFG 0x02F1 | 253 | #define MAC_PINMUX_CFG 0x02F1 |
258 | #define LEDCFG 0x02F2 | 254 | #define LEDCFG 0x02F2 |
259 | #define PHY_REG 0x02F3 | 255 | #define PHY_REG 0x02F3 |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 1d3a48330399..c6e3a4ca42f9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c | |||
@@ -410,7 +410,7 @@ void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel) | |||
410 | (rtlefuse->eeprom_regulatory != 0))) | 410 | (rtlefuse->eeprom_regulatory != 0))) |
411 | dont_inc_cck_or_turboscanoff = true; | 411 | dont_inc_cck_or_turboscanoff = true; |
412 | 412 | ||
413 | if (mac->act_scanning == true) { | 413 | if (mac->act_scanning) { |
414 | txagc = 0x3f; | 414 | txagc = 0x3f; |
415 | if (dont_inc_cck_or_turboscanoff) | 415 | if (dont_inc_cck_or_turboscanoff) |
416 | txagc = pwrlevel; | 416 | txagc = pwrlevel; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index d509cf6a1e4d..cffe30851f79 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
@@ -661,7 +661,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, | |||
661 | 661 | ||
662 | 662 | ||
663 | rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc); | 663 | rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc); |
664 | if (phystatus == true) { | 664 | if (phystatus) { |
665 | p_drvinfo = (struct rx_fwinfo *)(skb->data + | 665 | p_drvinfo = (struct rx_fwinfo *)(skb->data + |
666 | stats->rx_bufshift); | 666 | stats->rx_bufshift); |
667 | _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc, | 667 | _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc, |
@@ -900,7 +900,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, | |||
900 | 900 | ||
901 | void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | 901 | void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) |
902 | { | 902 | { |
903 | if (istx == true) { | 903 | if (istx) { |
904 | switch (desc_name) { | 904 | switch (desc_name) { |
905 | case HW_DESC_OWN: | 905 | case HW_DESC_OWN: |
906 | wmb(); | 906 | wmb(); |
@@ -941,7 +941,7 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) | |||
941 | { | 941 | { |
942 | u32 ret = 0; | 942 | u32 ret = 0; |
943 | 943 | ||
944 | if (istx == true) { | 944 | if (istx) { |
945 | switch (desc_name) { | 945 | switch (desc_name) { |
946 | case HW_DESC_OWN: | 946 | case HW_DESC_OWN: |
947 | ret = GET_TX_DESC_OWN(desc); | 947 | ret = GET_TX_DESC_OWN(desc); |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 9d003e0864f5..c54cda5ce22a 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -938,7 +938,7 @@ struct rtl_mac { | |||
938 | int n_channels; | 938 | int n_channels; |
939 | int n_bitrates; | 939 | int n_bitrates; |
940 | 940 | ||
941 | bool offchan_deley; | 941 | bool offchan_delay; |
942 | 942 | ||
943 | /*filters */ | 943 | /*filters */ |
944 | u32 rx_conf; | 944 | u32 rx_conf; |
@@ -1983,7 +1983,7 @@ static inline u16 rtl_get_tid(struct sk_buff *skb) | |||
1983 | 1983 | ||
1984 | static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, | 1984 | static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, |
1985 | struct ieee80211_vif *vif, | 1985 | struct ieee80211_vif *vif, |
1986 | u8 *bssid) | 1986 | const u8 *bssid) |
1987 | { | 1987 | { |
1988 | return ieee80211_find_sta(vif, bssid); | 1988 | return ieee80211_find_sta(vif, bssid); |
1989 | } | 1989 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 4be7c3b5b265..117c4123943c 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -21,6 +21,8 @@ | |||
21 | #ifndef _ZD_CHIP_H | 21 | #ifndef _ZD_CHIP_H |
22 | #define _ZD_CHIP_H | 22 | #define _ZD_CHIP_H |
23 | 23 | ||
24 | #include <net/mac80211.h> | ||
25 | |||
24 | #include "zd_rf.h" | 26 | #include "zd_rf.h" |
25 | #include "zd_usb.h" | 27 | #include "zd_usb.h" |
26 | 28 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h index 5463ca9ebc01..9a1b013f81be 100644 --- a/drivers/net/wireless/zd1211rw/zd_def.h +++ b/drivers/net/wireless/zd1211rw/zd_def.h | |||
@@ -37,9 +37,15 @@ typedef u16 __nocast zd_addr_t; | |||
37 | if (net_ratelimit()) \ | 37 | if (net_ratelimit()) \ |
38 | dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \ | 38 | dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \ |
39 | } while (0) | 39 | } while (0) |
40 | # define dev_dbg_f_cond(dev, cond, fmt, args...) ({ \ | ||
41 | bool __cond = !!(cond); \ | ||
42 | if (unlikely(__cond)) \ | ||
43 | dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \ | ||
44 | }) | ||
40 | #else | 45 | #else |
41 | # define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0) | 46 | # define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0) |
42 | # define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0) | 47 | # define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0) |
48 | # define dev_dbg_f_cond(dev, cond, fmt, args...) do { (void)(dev); } while (0) | ||
43 | #endif /* DEBUG */ | 49 | #endif /* DEBUG */ |
44 | 50 | ||
45 | #ifdef DEBUG | 51 | #ifdef DEBUG |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 5037c8b2b415..cabfae1e70b1 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -143,7 +143,7 @@ static void beacon_enable(struct zd_mac *mac); | |||
143 | static void beacon_disable(struct zd_mac *mac); | 143 | static void beacon_disable(struct zd_mac *mac); |
144 | static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble); | 144 | static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble); |
145 | static int zd_mac_config_beacon(struct ieee80211_hw *hw, | 145 | static int zd_mac_config_beacon(struct ieee80211_hw *hw, |
146 | struct sk_buff *beacon); | 146 | struct sk_buff *beacon, bool in_intr); |
147 | 147 | ||
148 | static int zd_reg2alpha2(u8 regdomain, char *alpha2) | 148 | static int zd_reg2alpha2(u8 regdomain, char *alpha2) |
149 | { | 149 | { |
@@ -160,6 +160,22 @@ static int zd_reg2alpha2(u8 regdomain, char *alpha2) | |||
160 | return 1; | 160 | return 1; |
161 | } | 161 | } |
162 | 162 | ||
163 | static int zd_check_signal(struct ieee80211_hw *hw, int signal) | ||
164 | { | ||
165 | struct zd_mac *mac = zd_hw_mac(hw); | ||
166 | |||
167 | dev_dbg_f_cond(zd_mac_dev(mac), signal < 0 || signal > 100, | ||
168 | "%s: signal value from device not in range 0..100, " | ||
169 | "but %d.\n", __func__, signal); | ||
170 | |||
171 | if (signal < 0) | ||
172 | signal = 0; | ||
173 | else if (signal > 100) | ||
174 | signal = 100; | ||
175 | |||
176 | return signal; | ||
177 | } | ||
178 | |||
163 | int zd_mac_preinit_hw(struct ieee80211_hw *hw) | 179 | int zd_mac_preinit_hw(struct ieee80211_hw *hw) |
164 | { | 180 | { |
165 | int r; | 181 | int r; |
@@ -387,10 +403,8 @@ int zd_restore_settings(struct zd_mac *mac) | |||
387 | mac->type == NL80211_IFTYPE_AP) { | 403 | mac->type == NL80211_IFTYPE_AP) { |
388 | if (mac->vif != NULL) { | 404 | if (mac->vif != NULL) { |
389 | beacon = ieee80211_beacon_get(mac->hw, mac->vif); | 405 | beacon = ieee80211_beacon_get(mac->hw, mac->vif); |
390 | if (beacon) { | 406 | if (beacon) |
391 | zd_mac_config_beacon(mac->hw, beacon); | 407 | zd_mac_config_beacon(mac->hw, beacon, false); |
392 | kfree_skb(beacon); | ||
393 | } | ||
394 | } | 408 | } |
395 | 409 | ||
396 | zd_set_beacon_interval(&mac->chip, beacon_interval, | 410 | zd_set_beacon_interval(&mac->chip, beacon_interval, |
@@ -461,7 +475,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
461 | if (i<IEEE80211_TX_MAX_RATES) | 475 | if (i<IEEE80211_TX_MAX_RATES) |
462 | info->status.rates[i].idx = -1; /* terminate */ | 476 | info->status.rates[i].idx = -1; /* terminate */ |
463 | 477 | ||
464 | info->status.ack_signal = ackssi; | 478 | info->status.ack_signal = zd_check_signal(hw, ackssi); |
465 | ieee80211_tx_status_irqsafe(hw, skb); | 479 | ieee80211_tx_status_irqsafe(hw, skb); |
466 | } | 480 | } |
467 | 481 | ||
@@ -664,7 +678,34 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
664 | /* FIXME: Management frame? */ | 678 | /* FIXME: Management frame? */ |
665 | } | 679 | } |
666 | 680 | ||
667 | static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) | 681 | static bool zd_mac_match_cur_beacon(struct zd_mac *mac, struct sk_buff *beacon) |
682 | { | ||
683 | if (!mac->beacon.cur_beacon) | ||
684 | return false; | ||
685 | |||
686 | if (mac->beacon.cur_beacon->len != beacon->len) | ||
687 | return false; | ||
688 | |||
689 | return !memcmp(beacon->data, mac->beacon.cur_beacon->data, beacon->len); | ||
690 | } | ||
691 | |||
692 | static void zd_mac_free_cur_beacon_locked(struct zd_mac *mac) | ||
693 | { | ||
694 | ZD_ASSERT(mutex_is_locked(&mac->chip.mutex)); | ||
695 | |||
696 | kfree_skb(mac->beacon.cur_beacon); | ||
697 | mac->beacon.cur_beacon = NULL; | ||
698 | } | ||
699 | |||
700 | static void zd_mac_free_cur_beacon(struct zd_mac *mac) | ||
701 | { | ||
702 | mutex_lock(&mac->chip.mutex); | ||
703 | zd_mac_free_cur_beacon_locked(mac); | ||
704 | mutex_unlock(&mac->chip.mutex); | ||
705 | } | ||
706 | |||
707 | static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon, | ||
708 | bool in_intr) | ||
668 | { | 709 | { |
669 | struct zd_mac *mac = zd_hw_mac(hw); | 710 | struct zd_mac *mac = zd_hw_mac(hw); |
670 | int r, ret, num_cmds, req_pos = 0; | 711 | int r, ret, num_cmds, req_pos = 0; |
@@ -674,13 +715,21 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) | |||
674 | unsigned long end_jiffies, message_jiffies; | 715 | unsigned long end_jiffies, message_jiffies; |
675 | struct zd_ioreq32 *ioreqs; | 716 | struct zd_ioreq32 *ioreqs; |
676 | 717 | ||
718 | mutex_lock(&mac->chip.mutex); | ||
719 | |||
720 | /* Check if hw already has this beacon. */ | ||
721 | if (zd_mac_match_cur_beacon(mac, beacon)) { | ||
722 | r = 0; | ||
723 | goto out_nofree; | ||
724 | } | ||
725 | |||
677 | /* Alloc memory for full beacon write at once. */ | 726 | /* Alloc memory for full beacon write at once. */ |
678 | num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len; | 727 | num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len; |
679 | ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL); | 728 | ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL); |
680 | if (!ioreqs) | 729 | if (!ioreqs) { |
681 | return -ENOMEM; | 730 | r = -ENOMEM; |
682 | 731 | goto out_nofree; | |
683 | mutex_lock(&mac->chip.mutex); | 732 | } |
684 | 733 | ||
685 | r = zd_iowrite32_locked(&mac->chip, 0, CR_BCN_FIFO_SEMAPHORE); | 734 | r = zd_iowrite32_locked(&mac->chip, 0, CR_BCN_FIFO_SEMAPHORE); |
686 | if (r < 0) | 735 | if (r < 0) |
@@ -688,6 +737,10 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) | |||
688 | r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE); | 737 | r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE); |
689 | if (r < 0) | 738 | if (r < 0) |
690 | goto release_sema; | 739 | goto release_sema; |
740 | if (in_intr && tmp & 0x2) { | ||
741 | r = -EBUSY; | ||
742 | goto release_sema; | ||
743 | } | ||
691 | 744 | ||
692 | end_jiffies = jiffies + HZ / 2; /*~500ms*/ | 745 | end_jiffies = jiffies + HZ / 2; /*~500ms*/ |
693 | message_jiffies = jiffies + HZ / 10; /*~100ms*/ | 746 | message_jiffies = jiffies + HZ / 10; /*~100ms*/ |
@@ -742,7 +795,7 @@ release_sema: | |||
742 | end_jiffies = jiffies + HZ / 2; /*~500ms*/ | 795 | end_jiffies = jiffies + HZ / 2; /*~500ms*/ |
743 | ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE); | 796 | ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE); |
744 | while (ret < 0) { | 797 | while (ret < 0) { |
745 | if (time_is_before_eq_jiffies(end_jiffies)) { | 798 | if (in_intr || time_is_before_eq_jiffies(end_jiffies)) { |
746 | ret = -ETIMEDOUT; | 799 | ret = -ETIMEDOUT; |
747 | break; | 800 | break; |
748 | } | 801 | } |
@@ -757,9 +810,19 @@ release_sema: | |||
757 | if (r < 0 || ret < 0) { | 810 | if (r < 0 || ret < 0) { |
758 | if (r >= 0) | 811 | if (r >= 0) |
759 | r = ret; | 812 | r = ret; |
813 | |||
814 | /* We don't know if beacon was written successfully or not, | ||
815 | * so clear current. */ | ||
816 | zd_mac_free_cur_beacon_locked(mac); | ||
817 | |||
760 | goto out; | 818 | goto out; |
761 | } | 819 | } |
762 | 820 | ||
821 | /* Beacon has now been written successfully, update current. */ | ||
822 | zd_mac_free_cur_beacon_locked(mac); | ||
823 | mac->beacon.cur_beacon = beacon; | ||
824 | beacon = NULL; | ||
825 | |||
763 | /* 802.11b/g 2.4G CCK 1Mb | 826 | /* 802.11b/g 2.4G CCK 1Mb |
764 | * 802.11a, not yet implemented, uses different values (see GPL vendor | 827 | * 802.11a, not yet implemented, uses different values (see GPL vendor |
765 | * driver) | 828 | * driver) |
@@ -767,11 +830,17 @@ release_sema: | |||
767 | r = zd_iowrite32_locked(&mac->chip, 0x00000400 | (full_len << 19), | 830 | r = zd_iowrite32_locked(&mac->chip, 0x00000400 | (full_len << 19), |
768 | CR_BCN_PLCP_CFG); | 831 | CR_BCN_PLCP_CFG); |
769 | out: | 832 | out: |
770 | mutex_unlock(&mac->chip.mutex); | ||
771 | kfree(ioreqs); | 833 | kfree(ioreqs); |
834 | out_nofree: | ||
835 | kfree_skb(beacon); | ||
836 | mutex_unlock(&mac->chip.mutex); | ||
837 | |||
772 | return r; | 838 | return r; |
773 | 839 | ||
774 | reset_device: | 840 | reset_device: |
841 | zd_mac_free_cur_beacon_locked(mac); | ||
842 | kfree_skb(beacon); | ||
843 | |||
775 | mutex_unlock(&mac->chip.mutex); | 844 | mutex_unlock(&mac->chip.mutex); |
776 | kfree(ioreqs); | 845 | kfree(ioreqs); |
777 | 846 | ||
@@ -982,7 +1051,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
982 | 1051 | ||
983 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; | 1052 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; |
984 | stats.band = IEEE80211_BAND_2GHZ; | 1053 | stats.band = IEEE80211_BAND_2GHZ; |
985 | stats.signal = status->signal_strength; | 1054 | stats.signal = zd_check_signal(hw, status->signal_strength); |
986 | 1055 | ||
987 | rate = zd_rx_rate(buffer, status); | 1056 | rate = zd_rx_rate(buffer, status); |
988 | 1057 | ||
@@ -1057,6 +1126,8 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, | |||
1057 | mac->vif = NULL; | 1126 | mac->vif = NULL; |
1058 | zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED); | 1127 | zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED); |
1059 | zd_write_mac_addr(&mac->chip, NULL); | 1128 | zd_write_mac_addr(&mac->chip, NULL); |
1129 | |||
1130 | zd_mac_free_cur_beacon(mac); | ||
1060 | } | 1131 | } |
1061 | 1132 | ||
1062 | static int zd_op_config(struct ieee80211_hw *hw, u32 changed) | 1133 | static int zd_op_config(struct ieee80211_hw *hw, u32 changed) |
@@ -1094,10 +1165,8 @@ static void zd_beacon_done(struct zd_mac *mac) | |||
1094 | * Fetch next beacon so that tim_count is updated. | 1165 | * Fetch next beacon so that tim_count is updated. |
1095 | */ | 1166 | */ |
1096 | beacon = ieee80211_beacon_get(mac->hw, mac->vif); | 1167 | beacon = ieee80211_beacon_get(mac->hw, mac->vif); |
1097 | if (beacon) { | 1168 | if (beacon) |
1098 | zd_mac_config_beacon(mac->hw, beacon); | 1169 | zd_mac_config_beacon(mac->hw, beacon, true); |
1099 | kfree_skb(beacon); | ||
1100 | } | ||
1101 | 1170 | ||
1102 | spin_lock_irq(&mac->lock); | 1171 | spin_lock_irq(&mac->lock); |
1103 | mac->beacon.last_update = jiffies; | 1172 | mac->beacon.last_update = jiffies; |
@@ -1222,9 +1291,8 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1222 | 1291 | ||
1223 | if (beacon) { | 1292 | if (beacon) { |
1224 | zd_chip_disable_hwint(&mac->chip); | 1293 | zd_chip_disable_hwint(&mac->chip); |
1225 | zd_mac_config_beacon(hw, beacon); | 1294 | zd_mac_config_beacon(hw, beacon, false); |
1226 | zd_chip_enable_hwint(&mac->chip); | 1295 | zd_chip_enable_hwint(&mac->chip); |
1227 | kfree_skb(beacon); | ||
1228 | } | 1296 | } |
1229 | } | 1297 | } |
1230 | 1298 | ||
@@ -1361,7 +1429,8 @@ static void beacon_watchdog_handler(struct work_struct *work) | |||
1361 | spin_lock_irq(&mac->lock); | 1429 | spin_lock_irq(&mac->lock); |
1362 | interval = mac->beacon.interval; | 1430 | interval = mac->beacon.interval; |
1363 | period = mac->beacon.period; | 1431 | period = mac->beacon.period; |
1364 | timeout = mac->beacon.last_update + msecs_to_jiffies(interval) + HZ; | 1432 | timeout = mac->beacon.last_update + |
1433 | msecs_to_jiffies(interval * 1024 / 1000) * 3; | ||
1365 | spin_unlock_irq(&mac->lock); | 1434 | spin_unlock_irq(&mac->lock); |
1366 | 1435 | ||
1367 | if (interval > 0 && time_is_before_jiffies(timeout)) { | 1436 | if (interval > 0 && time_is_before_jiffies(timeout)) { |
@@ -1374,8 +1443,9 @@ static void beacon_watchdog_handler(struct work_struct *work) | |||
1374 | 1443 | ||
1375 | beacon = ieee80211_beacon_get(mac->hw, mac->vif); | 1444 | beacon = ieee80211_beacon_get(mac->hw, mac->vif); |
1376 | if (beacon) { | 1445 | if (beacon) { |
1377 | zd_mac_config_beacon(mac->hw, beacon); | 1446 | zd_mac_free_cur_beacon(mac); |
1378 | kfree_skb(beacon); | 1447 | |
1448 | zd_mac_config_beacon(mac->hw, beacon, false); | ||
1379 | } | 1449 | } |
1380 | 1450 | ||
1381 | zd_set_beacon_interval(&mac->chip, interval, period, mac->type); | 1451 | zd_set_beacon_interval(&mac->chip, interval, period, mac->type); |
@@ -1410,6 +1480,8 @@ static void beacon_disable(struct zd_mac *mac) | |||
1410 | { | 1480 | { |
1411 | dev_dbg_f(zd_mac_dev(mac), "\n"); | 1481 | dev_dbg_f(zd_mac_dev(mac), "\n"); |
1412 | cancel_delayed_work_sync(&mac->beacon.watchdog_work); | 1482 | cancel_delayed_work_sync(&mac->beacon.watchdog_work); |
1483 | |||
1484 | zd_mac_free_cur_beacon(mac); | ||
1413 | } | 1485 | } |
1414 | 1486 | ||
1415 | #define LINK_LED_WORK_DELAY HZ | 1487 | #define LINK_LED_WORK_DELAY HZ |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index f8c93c3fe755..c01eca859f95 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -165,6 +165,7 @@ struct housekeeping { | |||
165 | 165 | ||
166 | struct beacon { | 166 | struct beacon { |
167 | struct delayed_work watchdog_work; | 167 | struct delayed_work watchdog_work; |
168 | struct sk_buff *cur_beacon; | ||
168 | unsigned long last_update; | 169 | unsigned long last_update; |
169 | u16 interval; | 170 | u16 interval; |
170 | u8 period; | 171 | u8 period; |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 631194d49828..cf0d69dd7be5 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -111,6 +111,9 @@ MODULE_DEVICE_TABLE(usb, usb_ids); | |||
111 | #define FW_ZD1211_PREFIX "zd1211/zd1211_" | 111 | #define FW_ZD1211_PREFIX "zd1211/zd1211_" |
112 | #define FW_ZD1211B_PREFIX "zd1211/zd1211b_" | 112 | #define FW_ZD1211B_PREFIX "zd1211/zd1211b_" |
113 | 113 | ||
114 | static bool check_read_regs(struct zd_usb *usb, struct usb_req_read_regs *req, | ||
115 | unsigned int count); | ||
116 | |||
114 | /* USB device initialization */ | 117 | /* USB device initialization */ |
115 | static void int_urb_complete(struct urb *urb); | 118 | static void int_urb_complete(struct urb *urb); |
116 | 119 | ||
@@ -365,6 +368,20 @@ exit: | |||
365 | 368 | ||
366 | #define urb_dev(urb) (&(urb)->dev->dev) | 369 | #define urb_dev(urb) (&(urb)->dev->dev) |
367 | 370 | ||
371 | static inline void handle_regs_int_override(struct urb *urb) | ||
372 | { | ||
373 | struct zd_usb *usb = urb->context; | ||
374 | struct zd_usb_interrupt *intr = &usb->intr; | ||
375 | |||
376 | spin_lock(&intr->lock); | ||
377 | if (atomic_read(&intr->read_regs_enabled)) { | ||
378 | atomic_set(&intr->read_regs_enabled, 0); | ||
379 | intr->read_regs_int_overridden = 1; | ||
380 | complete(&intr->read_regs.completion); | ||
381 | } | ||
382 | spin_unlock(&intr->lock); | ||
383 | } | ||
384 | |||
368 | static inline void handle_regs_int(struct urb *urb) | 385 | static inline void handle_regs_int(struct urb *urb) |
369 | { | 386 | { |
370 | struct zd_usb *usb = urb->context; | 387 | struct zd_usb *usb = urb->context; |
@@ -383,25 +400,45 @@ static inline void handle_regs_int(struct urb *urb) | |||
383 | USB_MAX_EP_INT_BUFFER); | 400 | USB_MAX_EP_INT_BUFFER); |
384 | spin_unlock(&mac->lock); | 401 | spin_unlock(&mac->lock); |
385 | schedule_work(&mac->process_intr); | 402 | schedule_work(&mac->process_intr); |
386 | } else if (intr->read_regs_enabled) { | 403 | } else if (atomic_read(&intr->read_regs_enabled)) { |
387 | intr->read_regs.length = len = urb->actual_length; | 404 | len = urb->actual_length; |
388 | 405 | intr->read_regs.length = urb->actual_length; | |
389 | if (len > sizeof(intr->read_regs.buffer)) | 406 | if (len > sizeof(intr->read_regs.buffer)) |
390 | len = sizeof(intr->read_regs.buffer); | 407 | len = sizeof(intr->read_regs.buffer); |
408 | |||
391 | memcpy(intr->read_regs.buffer, urb->transfer_buffer, len); | 409 | memcpy(intr->read_regs.buffer, urb->transfer_buffer, len); |
392 | intr->read_regs_enabled = 0; | 410 | |
411 | /* Sometimes USB_INT_ID_REGS is not overridden, but comes after | ||
412 | * USB_INT_ID_RETRY_FAILED. Read-reg retry then gets this | ||
413 | * delayed USB_INT_ID_REGS, but leaves USB_INT_ID_REGS of | ||
414 | * retry unhandled. Next read-reg command then might catch | ||
415 | * this wrong USB_INT_ID_REGS. Fix by ignoring wrong reads. | ||
416 | */ | ||
417 | if (!check_read_regs(usb, intr->read_regs.req, | ||
418 | intr->read_regs.req_count)) | ||
419 | goto out; | ||
420 | |||
421 | atomic_set(&intr->read_regs_enabled, 0); | ||
422 | intr->read_regs_int_overridden = 0; | ||
393 | complete(&intr->read_regs.completion); | 423 | complete(&intr->read_regs.completion); |
424 | |||
394 | goto out; | 425 | goto out; |
395 | } | 426 | } |
396 | 427 | ||
397 | out: | 428 | out: |
398 | spin_unlock(&intr->lock); | 429 | spin_unlock(&intr->lock); |
430 | |||
431 | /* CR_INTERRUPT might override read_reg too. */ | ||
432 | if (int_num == CR_INTERRUPT && atomic_read(&intr->read_regs_enabled)) | ||
433 | handle_regs_int_override(urb); | ||
399 | } | 434 | } |
400 | 435 | ||
401 | static void int_urb_complete(struct urb *urb) | 436 | static void int_urb_complete(struct urb *urb) |
402 | { | 437 | { |
403 | int r; | 438 | int r; |
404 | struct usb_int_header *hdr; | 439 | struct usb_int_header *hdr; |
440 | struct zd_usb *usb; | ||
441 | struct zd_usb_interrupt *intr; | ||
405 | 442 | ||
406 | switch (urb->status) { | 443 | switch (urb->status) { |
407 | case 0: | 444 | case 0: |
@@ -430,6 +467,14 @@ static void int_urb_complete(struct urb *urb) | |||
430 | goto resubmit; | 467 | goto resubmit; |
431 | } | 468 | } |
432 | 469 | ||
470 | /* USB_INT_ID_RETRY_FAILED triggered by tx-urb submit can override | ||
471 | * pending USB_INT_ID_REGS causing read command timeout. | ||
472 | */ | ||
473 | usb = urb->context; | ||
474 | intr = &usb->intr; | ||
475 | if (hdr->id != USB_INT_ID_REGS && atomic_read(&intr->read_regs_enabled)) | ||
476 | handle_regs_int_override(urb); | ||
477 | |||
433 | switch (hdr->id) { | 478 | switch (hdr->id) { |
434 | case USB_INT_ID_REGS: | 479 | case USB_INT_ID_REGS: |
435 | handle_regs_int(urb); | 480 | handle_regs_int(urb); |
@@ -579,8 +624,8 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, | |||
579 | 624 | ||
580 | if (length < sizeof(struct rx_length_info)) { | 625 | if (length < sizeof(struct rx_length_info)) { |
581 | /* It's not a complete packet anyhow. */ | 626 | /* It's not a complete packet anyhow. */ |
582 | printk("%s: invalid, small RX packet : %d\n", | 627 | dev_dbg_f(zd_usb_dev(usb), "invalid, small RX packet : %d\n", |
583 | __func__, length); | 628 | length); |
584 | return; | 629 | return; |
585 | } | 630 | } |
586 | length_info = (struct rx_length_info *) | 631 | length_info = (struct rx_length_info *) |
@@ -1129,6 +1174,7 @@ static inline void init_usb_interrupt(struct zd_usb *usb) | |||
1129 | spin_lock_init(&intr->lock); | 1174 | spin_lock_init(&intr->lock); |
1130 | intr->interval = int_urb_interval(zd_usb_to_usbdev(usb)); | 1175 | intr->interval = int_urb_interval(zd_usb_to_usbdev(usb)); |
1131 | init_completion(&intr->read_regs.completion); | 1176 | init_completion(&intr->read_regs.completion); |
1177 | atomic_set(&intr->read_regs_enabled, 0); | ||
1132 | intr->read_regs.cr_int_addr = cpu_to_le16((u16)CR_INTERRUPT); | 1178 | intr->read_regs.cr_int_addr = cpu_to_le16((u16)CR_INTERRUPT); |
1133 | } | 1179 | } |
1134 | 1180 | ||
@@ -1563,12 +1609,16 @@ static int usb_int_regs_length(unsigned int count) | |||
1563 | return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); | 1609 | return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); |
1564 | } | 1610 | } |
1565 | 1611 | ||
1566 | static void prepare_read_regs_int(struct zd_usb *usb) | 1612 | static void prepare_read_regs_int(struct zd_usb *usb, |
1613 | struct usb_req_read_regs *req, | ||
1614 | unsigned int count) | ||
1567 | { | 1615 | { |
1568 | struct zd_usb_interrupt *intr = &usb->intr; | 1616 | struct zd_usb_interrupt *intr = &usb->intr; |
1569 | 1617 | ||
1570 | spin_lock_irq(&intr->lock); | 1618 | spin_lock_irq(&intr->lock); |
1571 | intr->read_regs_enabled = 1; | 1619 | atomic_set(&intr->read_regs_enabled, 1); |
1620 | intr->read_regs.req = req; | ||
1621 | intr->read_regs.req_count = count; | ||
1572 | INIT_COMPLETION(intr->read_regs.completion); | 1622 | INIT_COMPLETION(intr->read_regs.completion); |
1573 | spin_unlock_irq(&intr->lock); | 1623 | spin_unlock_irq(&intr->lock); |
1574 | } | 1624 | } |
@@ -1578,22 +1628,18 @@ static void disable_read_regs_int(struct zd_usb *usb) | |||
1578 | struct zd_usb_interrupt *intr = &usb->intr; | 1628 | struct zd_usb_interrupt *intr = &usb->intr; |
1579 | 1629 | ||
1580 | spin_lock_irq(&intr->lock); | 1630 | spin_lock_irq(&intr->lock); |
1581 | intr->read_regs_enabled = 0; | 1631 | atomic_set(&intr->read_regs_enabled, 0); |
1582 | spin_unlock_irq(&intr->lock); | 1632 | spin_unlock_irq(&intr->lock); |
1583 | } | 1633 | } |
1584 | 1634 | ||
1585 | static int get_results(struct zd_usb *usb, u16 *values, | 1635 | static bool check_read_regs(struct zd_usb *usb, struct usb_req_read_regs *req, |
1586 | struct usb_req_read_regs *req, unsigned int count) | 1636 | unsigned int count) |
1587 | { | 1637 | { |
1588 | int r; | ||
1589 | int i; | 1638 | int i; |
1590 | struct zd_usb_interrupt *intr = &usb->intr; | 1639 | struct zd_usb_interrupt *intr = &usb->intr; |
1591 | struct read_regs_int *rr = &intr->read_regs; | 1640 | struct read_regs_int *rr = &intr->read_regs; |
1592 | struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; | 1641 | struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; |
1593 | 1642 | ||
1594 | spin_lock_irq(&intr->lock); | ||
1595 | |||
1596 | r = -EIO; | ||
1597 | /* The created block size seems to be larger than expected. | 1643 | /* The created block size seems to be larger than expected. |
1598 | * However results appear to be correct. | 1644 | * However results appear to be correct. |
1599 | */ | 1645 | */ |
@@ -1601,13 +1647,14 @@ static int get_results(struct zd_usb *usb, u16 *values, | |||
1601 | dev_dbg_f(zd_usb_dev(usb), | 1647 | dev_dbg_f(zd_usb_dev(usb), |
1602 | "error: actual length %d less than expected %d\n", | 1648 | "error: actual length %d less than expected %d\n", |
1603 | rr->length, usb_int_regs_length(count)); | 1649 | rr->length, usb_int_regs_length(count)); |
1604 | goto error_unlock; | 1650 | return false; |
1605 | } | 1651 | } |
1652 | |||
1606 | if (rr->length > sizeof(rr->buffer)) { | 1653 | if (rr->length > sizeof(rr->buffer)) { |
1607 | dev_dbg_f(zd_usb_dev(usb), | 1654 | dev_dbg_f(zd_usb_dev(usb), |
1608 | "error: actual length %d exceeds buffer size %zu\n", | 1655 | "error: actual length %d exceeds buffer size %zu\n", |
1609 | rr->length, sizeof(rr->buffer)); | 1656 | rr->length, sizeof(rr->buffer)); |
1610 | goto error_unlock; | 1657 | return false; |
1611 | } | 1658 | } |
1612 | 1659 | ||
1613 | for (i = 0; i < count; i++) { | 1660 | for (i = 0; i < count; i++) { |
@@ -1617,8 +1664,39 @@ static int get_results(struct zd_usb *usb, u16 *values, | |||
1617 | "rd[%d] addr %#06hx expected %#06hx\n", i, | 1664 | "rd[%d] addr %#06hx expected %#06hx\n", i, |
1618 | le16_to_cpu(rd->addr), | 1665 | le16_to_cpu(rd->addr), |
1619 | le16_to_cpu(req->addr[i])); | 1666 | le16_to_cpu(req->addr[i])); |
1620 | goto error_unlock; | 1667 | return false; |
1621 | } | 1668 | } |
1669 | } | ||
1670 | |||
1671 | return true; | ||
1672 | } | ||
1673 | |||
1674 | static int get_results(struct zd_usb *usb, u16 *values, | ||
1675 | struct usb_req_read_regs *req, unsigned int count, | ||
1676 | bool *retry) | ||
1677 | { | ||
1678 | int r; | ||
1679 | int i; | ||
1680 | struct zd_usb_interrupt *intr = &usb->intr; | ||
1681 | struct read_regs_int *rr = &intr->read_regs; | ||
1682 | struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; | ||
1683 | |||
1684 | spin_lock_irq(&intr->lock); | ||
1685 | |||
1686 | r = -EIO; | ||
1687 | |||
1688 | /* Read failed because firmware bug? */ | ||
1689 | *retry = !!intr->read_regs_int_overridden; | ||
1690 | if (*retry) | ||
1691 | goto error_unlock; | ||
1692 | |||
1693 | if (!check_read_regs(usb, req, count)) { | ||
1694 | dev_dbg_f(zd_usb_dev(usb), "error: invalid read regs\n"); | ||
1695 | goto error_unlock; | ||
1696 | } | ||
1697 | |||
1698 | for (i = 0; i < count; i++) { | ||
1699 | struct reg_data *rd = ®s->regs[i]; | ||
1622 | values[i] = le16_to_cpu(rd->value); | 1700 | values[i] = le16_to_cpu(rd->value); |
1623 | } | 1701 | } |
1624 | 1702 | ||
@@ -1631,11 +1709,11 @@ error_unlock: | |||
1631 | int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | 1709 | int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, |
1632 | const zd_addr_t *addresses, unsigned int count) | 1710 | const zd_addr_t *addresses, unsigned int count) |
1633 | { | 1711 | { |
1634 | int r; | 1712 | int r, i, req_len, actual_req_len, try_count = 0; |
1635 | int i, req_len, actual_req_len; | ||
1636 | struct usb_device *udev; | 1713 | struct usb_device *udev; |
1637 | struct usb_req_read_regs *req = NULL; | 1714 | struct usb_req_read_regs *req = NULL; |
1638 | unsigned long timeout; | 1715 | unsigned long timeout; |
1716 | bool retry = false; | ||
1639 | 1717 | ||
1640 | if (count < 1) { | 1718 | if (count < 1) { |
1641 | dev_dbg_f(zd_usb_dev(usb), "error: count is zero\n"); | 1719 | dev_dbg_f(zd_usb_dev(usb), "error: count is zero\n"); |
@@ -1671,8 +1749,10 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | |||
1671 | for (i = 0; i < count; i++) | 1749 | for (i = 0; i < count; i++) |
1672 | req->addr[i] = cpu_to_le16((u16)addresses[i]); | 1750 | req->addr[i] = cpu_to_le16((u16)addresses[i]); |
1673 | 1751 | ||
1752 | retry_read: | ||
1753 | try_count++; | ||
1674 | udev = zd_usb_to_usbdev(usb); | 1754 | udev = zd_usb_to_usbdev(usb); |
1675 | prepare_read_regs_int(usb); | 1755 | prepare_read_regs_int(usb, req, count); |
1676 | r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); | 1756 | r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); |
1677 | if (r) { | 1757 | if (r) { |
1678 | dev_dbg_f(zd_usb_dev(usb), | 1758 | dev_dbg_f(zd_usb_dev(usb), |
@@ -1696,7 +1776,12 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | |||
1696 | goto error; | 1776 | goto error; |
1697 | } | 1777 | } |
1698 | 1778 | ||
1699 | r = get_results(usb, values, req, count); | 1779 | r = get_results(usb, values, req, count, &retry); |
1780 | if (retry && try_count < 20) { | ||
1781 | dev_dbg_f(zd_usb_dev(usb), "read retry, tries so far: %d\n", | ||
1782 | try_count); | ||
1783 | goto retry_read; | ||
1784 | } | ||
1700 | error: | 1785 | error: |
1701 | return r; | 1786 | return r; |
1702 | } | 1787 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index bf942843b733..99193b456a79 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h | |||
@@ -144,6 +144,8 @@ struct usb_int_retry_fail { | |||
144 | 144 | ||
145 | struct read_regs_int { | 145 | struct read_regs_int { |
146 | struct completion completion; | 146 | struct completion completion; |
147 | struct usb_req_read_regs *req; | ||
148 | unsigned int req_count; | ||
147 | /* Stores the USB int structure and contains the USB address of the | 149 | /* Stores the USB int structure and contains the USB address of the |
148 | * first requested register before request. | 150 | * first requested register before request. |
149 | */ | 151 | */ |
@@ -169,7 +171,8 @@ struct zd_usb_interrupt { | |||
169 | void *buffer; | 171 | void *buffer; |
170 | dma_addr_t buffer_dma; | 172 | dma_addr_t buffer_dma; |
171 | int interval; | 173 | int interval; |
172 | u8 read_regs_enabled:1; | 174 | atomic_t read_regs_enabled; |
175 | u8 read_regs_int_overridden:1; | ||
173 | }; | 176 | }; |
174 | 177 | ||
175 | static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr) | 178 | static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr) |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 305ade7825f7..a7aef47bf739 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -417,9 +417,9 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc) | |||
417 | u32 min_msk = 0, max_msk = 0; | 417 | u32 min_msk = 0, max_msk = 0; |
418 | unsigned int i; | 418 | unsigned int i; |
419 | const struct pmu_res_updown_tab_entry *updown_tab = NULL; | 419 | const struct pmu_res_updown_tab_entry *updown_tab = NULL; |
420 | unsigned int updown_tab_size; | 420 | unsigned int updown_tab_size = 0; |
421 | const struct pmu_res_depend_tab_entry *depend_tab = NULL; | 421 | const struct pmu_res_depend_tab_entry *depend_tab = NULL; |
422 | unsigned int depend_tab_size; | 422 | unsigned int depend_tab_size = 0; |
423 | 423 | ||
424 | switch (bus->chip_id) { | 424 | switch (bus->chip_id) { |
425 | case 0x4312: | 425 | case 0x4312: |
diff --git a/drivers/ssb/driver_gige.c b/drivers/ssb/driver_gige.c index 5ba92a2719a4..d75890909222 100644 --- a/drivers/ssb/driver_gige.c +++ b/drivers/ssb/driver_gige.c | |||
@@ -106,8 +106,9 @@ void gige_pcicfg_write32(struct ssb_gige *dev, | |||
106 | gige_write32(dev, SSB_GIGE_PCICFG + offset, value); | 106 | gige_write32(dev, SSB_GIGE_PCICFG + offset, value); |
107 | } | 107 | } |
108 | 108 | ||
109 | static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn, | 109 | static int __devinit ssb_gige_pci_read_config(struct pci_bus *bus, |
110 | int reg, int size, u32 *val) | 110 | unsigned int devfn, int reg, |
111 | int size, u32 *val) | ||
111 | { | 112 | { |
112 | struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); | 113 | struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); |
113 | unsigned long flags; | 114 | unsigned long flags; |
@@ -136,8 +137,9 @@ static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
136 | return PCIBIOS_SUCCESSFUL; | 137 | return PCIBIOS_SUCCESSFUL; |
137 | } | 138 | } |
138 | 139 | ||
139 | static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn, | 140 | static int __devinit ssb_gige_pci_write_config(struct pci_bus *bus, |
140 | int reg, int size, u32 val) | 141 | unsigned int devfn, int reg, |
142 | int size, u32 val) | ||
141 | { | 143 | { |
142 | struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); | 144 | struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops); |
143 | unsigned long flags; | 145 | unsigned long flags; |
@@ -166,7 +168,8 @@ static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
166 | return PCIBIOS_SUCCESSFUL; | 168 | return PCIBIOS_SUCCESSFUL; |
167 | } | 169 | } |
168 | 170 | ||
169 | static int ssb_gige_probe(struct ssb_device *sdev, const struct ssb_device_id *id) | 171 | static int __devinit ssb_gige_probe(struct ssb_device *sdev, |
172 | const struct ssb_device_id *id) | ||
170 | { | 173 | { |
171 | struct ssb_gige *dev; | 174 | struct ssb_gige *dev; |
172 | u32 base, tmslow, tmshigh; | 175 | u32 base, tmslow, tmshigh; |
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 2a20dabec76d..21b9465f71ad 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
@@ -314,7 +314,7 @@ int ssb_pcicore_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
314 | return ssb_mips_irq(extpci_core->dev) + 2; | 314 | return ssb_mips_irq(extpci_core->dev) + 2; |
315 | } | 315 | } |
316 | 316 | ||
317 | static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) | 317 | static void __devinit ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) |
318 | { | 318 | { |
319 | u32 val; | 319 | u32 val; |
320 | 320 | ||
@@ -379,7 +379,7 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) | |||
379 | register_pci_controller(&ssb_pcicore_controller); | 379 | register_pci_controller(&ssb_pcicore_controller); |
380 | } | 380 | } |
381 | 381 | ||
382 | static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) | 382 | static int __devinit pcicore_is_in_hostmode(struct ssb_pcicore *pc) |
383 | { | 383 | { |
384 | struct ssb_bus *bus = pc->dev->bus; | 384 | struct ssb_bus *bus = pc->dev->bus; |
385 | u16 chipid_top; | 385 | u16 chipid_top; |
@@ -412,7 +412,7 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) | |||
412 | * Workarounds. | 412 | * Workarounds. |
413 | **************************************************/ | 413 | **************************************************/ |
414 | 414 | ||
415 | static void ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc) | 415 | static void __devinit ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc) |
416 | { | 416 | { |
417 | u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0)); | 417 | u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0)); |
418 | if (((tmp & 0xF000) >> 12) != pc->dev->core_index) { | 418 | if (((tmp & 0xF000) >> 12) != pc->dev->core_index) { |
@@ -514,13 +514,13 @@ static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) | |||
514 | * Generic and Clientmode operation code. | 514 | * Generic and Clientmode operation code. |
515 | **************************************************/ | 515 | **************************************************/ |
516 | 516 | ||
517 | static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) | 517 | static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) |
518 | { | 518 | { |
519 | /* Disable PCI interrupts. */ | 519 | /* Disable PCI interrupts. */ |
520 | ssb_write32(pc->dev, SSB_INTVEC, 0); | 520 | ssb_write32(pc->dev, SSB_INTVEC, 0); |
521 | } | 521 | } |
522 | 522 | ||
523 | void ssb_pcicore_init(struct ssb_pcicore *pc) | 523 | void __devinit ssb_pcicore_init(struct ssb_pcicore *pc) |
524 | { | 524 | { |
525 | struct ssb_device *dev = pc->dev; | 525 | struct ssb_device *dev = pc->dev; |
526 | 526 | ||
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index f8a13f863217..e568664f8b9c 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -557,7 +557,7 @@ error: | |||
557 | } | 557 | } |
558 | 558 | ||
559 | /* Needs ssb_buses_lock() */ | 559 | /* Needs ssb_buses_lock() */ |
560 | static int ssb_attach_queued_buses(void) | 560 | static int __devinit ssb_attach_queued_buses(void) |
561 | { | 561 | { |
562 | struct ssb_bus *bus, *n; | 562 | struct ssb_bus *bus, *n; |
563 | int err = 0; | 563 | int err = 0; |
@@ -768,9 +768,9 @@ out: | |||
768 | return err; | 768 | return err; |
769 | } | 769 | } |
770 | 770 | ||
771 | static int ssb_bus_register(struct ssb_bus *bus, | 771 | static int __devinit ssb_bus_register(struct ssb_bus *bus, |
772 | ssb_invariants_func_t get_invariants, | 772 | ssb_invariants_func_t get_invariants, |
773 | unsigned long baseaddr) | 773 | unsigned long baseaddr) |
774 | { | 774 | { |
775 | int err; | 775 | int err; |
776 | 776 | ||
@@ -851,8 +851,8 @@ err_disable_xtal: | |||
851 | } | 851 | } |
852 | 852 | ||
853 | #ifdef CONFIG_SSB_PCIHOST | 853 | #ifdef CONFIG_SSB_PCIHOST |
854 | int ssb_bus_pcibus_register(struct ssb_bus *bus, | 854 | int __devinit ssb_bus_pcibus_register(struct ssb_bus *bus, |
855 | struct pci_dev *host_pci) | 855 | struct pci_dev *host_pci) |
856 | { | 856 | { |
857 | int err; | 857 | int err; |
858 | 858 | ||
@@ -875,9 +875,9 @@ EXPORT_SYMBOL(ssb_bus_pcibus_register); | |||
875 | #endif /* CONFIG_SSB_PCIHOST */ | 875 | #endif /* CONFIG_SSB_PCIHOST */ |
876 | 876 | ||
877 | #ifdef CONFIG_SSB_PCMCIAHOST | 877 | #ifdef CONFIG_SSB_PCMCIAHOST |
878 | int ssb_bus_pcmciabus_register(struct ssb_bus *bus, | 878 | int __devinit ssb_bus_pcmciabus_register(struct ssb_bus *bus, |
879 | struct pcmcia_device *pcmcia_dev, | 879 | struct pcmcia_device *pcmcia_dev, |
880 | unsigned long baseaddr) | 880 | unsigned long baseaddr) |
881 | { | 881 | { |
882 | int err; | 882 | int err; |
883 | 883 | ||
@@ -897,8 +897,9 @@ EXPORT_SYMBOL(ssb_bus_pcmciabus_register); | |||
897 | #endif /* CONFIG_SSB_PCMCIAHOST */ | 897 | #endif /* CONFIG_SSB_PCMCIAHOST */ |
898 | 898 | ||
899 | #ifdef CONFIG_SSB_SDIOHOST | 899 | #ifdef CONFIG_SSB_SDIOHOST |
900 | int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func, | 900 | int __devinit ssb_bus_sdiobus_register(struct ssb_bus *bus, |
901 | unsigned int quirks) | 901 | struct sdio_func *func, |
902 | unsigned int quirks) | ||
902 | { | 903 | { |
903 | int err; | 904 | int err; |
904 | 905 | ||
@@ -918,9 +919,9 @@ int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func, | |||
918 | EXPORT_SYMBOL(ssb_bus_sdiobus_register); | 919 | EXPORT_SYMBOL(ssb_bus_sdiobus_register); |
919 | #endif /* CONFIG_SSB_PCMCIAHOST */ | 920 | #endif /* CONFIG_SSB_PCMCIAHOST */ |
920 | 921 | ||
921 | int ssb_bus_ssbbus_register(struct ssb_bus *bus, | 922 | int __devinit ssb_bus_ssbbus_register(struct ssb_bus *bus, |
922 | unsigned long baseaddr, | 923 | unsigned long baseaddr, |
923 | ssb_invariants_func_t get_invariants) | 924 | ssb_invariants_func_t get_invariants) |
924 | { | 925 | { |
925 | int err; | 926 | int err; |
926 | 927 | ||
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c index f6c8c81a0025..d7a98131ebf3 100644 --- a/drivers/ssb/pcihost_wrapper.c +++ b/drivers/ssb/pcihost_wrapper.c | |||
@@ -53,8 +53,8 @@ static int ssb_pcihost_resume(struct pci_dev *dev) | |||
53 | # define ssb_pcihost_resume NULL | 53 | # define ssb_pcihost_resume NULL |
54 | #endif /* CONFIG_PM */ | 54 | #endif /* CONFIG_PM */ |
55 | 55 | ||
56 | static int ssb_pcihost_probe(struct pci_dev *dev, | 56 | static int __devinit ssb_pcihost_probe(struct pci_dev *dev, |
57 | const struct pci_device_id *id) | 57 | const struct pci_device_id *id) |
58 | { | 58 | { |
59 | struct ssb_bus *ssb; | 59 | struct ssb_bus *ssb; |
60 | int err = -ENOMEM; | 60 | int err = -ENOMEM; |
@@ -110,7 +110,7 @@ static void ssb_pcihost_remove(struct pci_dev *dev) | |||
110 | pci_set_drvdata(dev, NULL); | 110 | pci_set_drvdata(dev, NULL); |
111 | } | 111 | } |
112 | 112 | ||
113 | int ssb_pcihost_register(struct pci_driver *driver) | 113 | int __devinit ssb_pcihost_register(struct pci_driver *driver) |
114 | { | 114 | { |
115 | driver->probe = ssb_pcihost_probe; | 115 | driver->probe = ssb_pcihost_probe; |
116 | driver->remove = ssb_pcihost_remove; | 116 | driver->remove = ssb_pcihost_remove; |
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index 60a7c49dcb49..6e3f54f37844 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h | |||
@@ -30,6 +30,8 @@ struct ath9k_platform_data { | |||
30 | u32 gpio_val; | 30 | u32 gpio_val; |
31 | 31 | ||
32 | bool is_clk_25mhz; | 32 | bool is_clk_25mhz; |
33 | int (*get_mac_revision)(void); | ||
34 | int (*external_reset)(void); | ||
33 | }; | 35 | }; |
34 | 36 | ||
35 | #endif /* _LINUX_ATH9K_PLATFORM_H */ | 37 | #endif /* _LINUX_ATH9K_PLATFORM_H */ |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 6ff080eac0b2..3895aeb494a3 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
@@ -244,6 +244,7 @@ void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value) | |||
244 | } | 244 | } |
245 | 245 | ||
246 | extern bool bcma_core_is_enabled(struct bcma_device *core); | 246 | extern bool bcma_core_is_enabled(struct bcma_device *core); |
247 | extern void bcma_core_disable(struct bcma_device *core, u32 flags); | ||
247 | extern int bcma_core_enable(struct bcma_device *core, u32 flags); | 248 | extern int bcma_core_enable(struct bcma_device *core, u32 flags); |
248 | 249 | ||
249 | #endif /* LINUX_BCMA_H_ */ | 250 | #endif /* LINUX_BCMA_H_ */ |
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h index b7e191cf00ec..3871b668caf9 100644 --- a/include/linux/bcma/bcma_driver_pci.h +++ b/include/linux/bcma/bcma_driver_pci.h | |||
@@ -85,5 +85,7 @@ struct bcma_drv_pci { | |||
85 | #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) | 85 | #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) |
86 | 86 | ||
87 | extern void bcma_core_pci_init(struct bcma_drv_pci *pc); | 87 | extern void bcma_core_pci_init(struct bcma_drv_pci *pc); |
88 | extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, | ||
89 | struct bcma_device *core, bool enable); | ||
88 | 90 | ||
89 | #endif /* LINUX_BCMA_DRIVER_PCI_H_ */ | 91 | #endif /* LINUX_BCMA_DRIVER_PCI_H_ */ |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index fdd0188a167e..2e17c5dbdcb8 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -49,6 +49,7 @@ struct nlmsghdr { | |||
49 | #define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */ | 49 | #define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */ |
50 | #define NLM_F_ACK 4 /* Reply with ack, with zero or error code */ | 50 | #define NLM_F_ACK 4 /* Reply with ack, with zero or error code */ |
51 | #define NLM_F_ECHO 8 /* Echo this request */ | 51 | #define NLM_F_ECHO 8 /* Echo this request */ |
52 | #define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */ | ||
52 | 53 | ||
53 | /* Modifiers to GET request */ | 54 | /* Modifiers to GET request */ |
54 | #define NLM_F_ROOT 0x100 /* specify tree root */ | 55 | #define NLM_F_ROOT 0x100 /* specify tree root */ |
@@ -223,6 +224,7 @@ struct netlink_callback { | |||
223 | int (*done)(struct netlink_callback *cb); | 224 | int (*done)(struct netlink_callback *cb); |
224 | u16 family; | 225 | u16 family; |
225 | u16 min_dump_alloc; | 226 | u16 min_dump_alloc; |
227 | unsigned int prev_seq, seq; | ||
226 | long args[6]; | 228 | long args[6]; |
227 | }; | 229 | }; |
228 | 230 | ||
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 43750439c521..7bccaf921cab 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -69,6 +69,13 @@ struct bt_security { | |||
69 | #define BT_FLUSHABLE_OFF 0 | 69 | #define BT_FLUSHABLE_OFF 0 |
70 | #define BT_FLUSHABLE_ON 1 | 70 | #define BT_FLUSHABLE_ON 1 |
71 | 71 | ||
72 | #define BT_POWER 9 | ||
73 | struct bt_power { | ||
74 | __u8 force_active; | ||
75 | }; | ||
76 | #define BT_POWER_FORCE_ACTIVE_OFF 0 | ||
77 | #define BT_POWER_FORCE_ACTIVE_ON 1 | ||
78 | |||
72 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) | 79 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) |
73 | #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) | 80 | #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) |
74 | #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) | 81 | #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) |
@@ -130,7 +137,8 @@ int bt_sock_register(int proto, const struct net_proto_family *ops); | |||
130 | int bt_sock_unregister(int proto); | 137 | int bt_sock_unregister(int proto); |
131 | void bt_sock_link(struct bt_sock_list *l, struct sock *s); | 138 | void bt_sock_link(struct bt_sock_list *l, struct sock *s); |
132 | void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); | 139 | void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); |
133 | int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); | 140 | int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
141 | struct msghdr *msg, size_t len, int flags); | ||
134 | int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | 142 | int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, |
135 | struct msghdr *msg, size_t len, int flags); | 143 | struct msghdr *msg, size_t len, int flags); |
136 | uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); | 144 | uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); |
@@ -150,6 +158,7 @@ struct bt_skb_cb { | |||
150 | __u8 retries; | 158 | __u8 retries; |
151 | __u8 sar; | 159 | __u8 sar; |
152 | unsigned short channel; | 160 | unsigned short channel; |
161 | __u8 force_active; | ||
153 | }; | 162 | }; |
154 | #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) | 163 | #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) |
155 | 164 | ||
@@ -164,8 +173,8 @@ static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how) | |||
164 | return skb; | 173 | return skb; |
165 | } | 174 | } |
166 | 175 | ||
167 | static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long len, | 176 | static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, |
168 | int nb, int *err) | 177 | unsigned long len, int nb, int *err) |
169 | { | 178 | { |
170 | struct sk_buff *skb; | 179 | struct sk_buff *skb; |
171 | 180 | ||
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 0c20227e57f6..65345cd215be 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -710,6 +710,12 @@ struct hci_rp_le_read_buffer_size { | |||
710 | __u8 le_max_pkt; | 710 | __u8 le_max_pkt; |
711 | } __packed; | 711 | } __packed; |
712 | 712 | ||
713 | #define HCI_OP_LE_SET_SCAN_ENABLE 0x200c | ||
714 | struct hci_cp_le_set_scan_enable { | ||
715 | __u8 enable; | ||
716 | __u8 filter_dup; | ||
717 | } __packed; | ||
718 | |||
713 | #define HCI_OP_LE_CREATE_CONN 0x200d | 719 | #define HCI_OP_LE_CREATE_CONN 0x200d |
714 | struct hci_cp_le_create_conn { | 720 | struct hci_cp_le_create_conn { |
715 | __le16 scan_interval; | 721 | __le16 scan_interval; |
@@ -739,6 +745,33 @@ struct hci_cp_le_conn_update { | |||
739 | __le16 max_ce_len; | 745 | __le16 max_ce_len; |
740 | } __packed; | 746 | } __packed; |
741 | 747 | ||
748 | #define HCI_OP_LE_START_ENC 0x2019 | ||
749 | struct hci_cp_le_start_enc { | ||
750 | __le16 handle; | ||
751 | __u8 rand[8]; | ||
752 | __le16 ediv; | ||
753 | __u8 ltk[16]; | ||
754 | } __packed; | ||
755 | |||
756 | #define HCI_OP_LE_LTK_REPLY 0x201a | ||
757 | struct hci_cp_le_ltk_reply { | ||
758 | __le16 handle; | ||
759 | __u8 ltk[16]; | ||
760 | } __packed; | ||
761 | struct hci_rp_le_ltk_reply { | ||
762 | __u8 status; | ||
763 | __le16 handle; | ||
764 | } __packed; | ||
765 | |||
766 | #define HCI_OP_LE_LTK_NEG_REPLY 0x201b | ||
767 | struct hci_cp_le_ltk_neg_reply { | ||
768 | __le16 handle; | ||
769 | } __packed; | ||
770 | struct hci_rp_le_ltk_neg_reply { | ||
771 | __u8 status; | ||
772 | __le16 handle; | ||
773 | } __packed; | ||
774 | |||
742 | /* ---- HCI Events ---- */ | 775 | /* ---- HCI Events ---- */ |
743 | #define HCI_EV_INQUIRY_COMPLETE 0x01 | 776 | #define HCI_EV_INQUIRY_COMPLETE 0x01 |
744 | 777 | ||
@@ -1029,6 +1062,32 @@ struct hci_ev_le_conn_complete { | |||
1029 | __u8 clk_accurancy; | 1062 | __u8 clk_accurancy; |
1030 | } __packed; | 1063 | } __packed; |
1031 | 1064 | ||
1065 | #define HCI_EV_LE_LTK_REQ 0x05 | ||
1066 | struct hci_ev_le_ltk_req { | ||
1067 | __le16 handle; | ||
1068 | __u8 random[8]; | ||
1069 | __le16 ediv; | ||
1070 | } __packed; | ||
1071 | |||
1072 | /* Advertising report event types */ | ||
1073 | #define ADV_IND 0x00 | ||
1074 | #define ADV_DIRECT_IND 0x01 | ||
1075 | #define ADV_SCAN_IND 0x02 | ||
1076 | #define ADV_NONCONN_IND 0x03 | ||
1077 | #define ADV_SCAN_RSP 0x04 | ||
1078 | |||
1079 | #define ADDR_LE_DEV_PUBLIC 0x00 | ||
1080 | #define ADDR_LE_DEV_RANDOM 0x01 | ||
1081 | |||
1082 | #define HCI_EV_LE_ADVERTISING_REPORT 0x02 | ||
1083 | struct hci_ev_le_advertising_info { | ||
1084 | __u8 evt_type; | ||
1085 | __u8 bdaddr_type; | ||
1086 | bdaddr_t bdaddr; | ||
1087 | __u8 length; | ||
1088 | __u8 data[0]; | ||
1089 | } __packed; | ||
1090 | |||
1032 | /* Internal events generated by Bluetooth stack */ | 1091 | /* Internal events generated by Bluetooth stack */ |
1033 | #define HCI_EV_STACK_INTERNAL 0xfd | 1092 | #define HCI_EV_STACK_INTERNAL 0xfd |
1034 | struct hci_ev_stack_internal { | 1093 | struct hci_ev_stack_internal { |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7851c05833e2..19639df80e67 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -90,6 +90,12 @@ struct oob_data { | |||
90 | u8 randomizer[16]; | 90 | u8 randomizer[16]; |
91 | }; | 91 | }; |
92 | 92 | ||
93 | struct adv_entry { | ||
94 | struct list_head list; | ||
95 | bdaddr_t bdaddr; | ||
96 | u8 bdaddr_type; | ||
97 | }; | ||
98 | |||
93 | #define NUM_REASSEMBLY 4 | 99 | #define NUM_REASSEMBLY 4 |
94 | struct hci_dev { | 100 | struct hci_dev { |
95 | struct list_head list; | 101 | struct list_head list; |
@@ -172,6 +178,8 @@ struct hci_dev { | |||
172 | 178 | ||
173 | __u16 init_last_cmd; | 179 | __u16 init_last_cmd; |
174 | 180 | ||
181 | struct crypto_blkcipher *tfm; | ||
182 | |||
175 | struct inquiry_cache inq_cache; | 183 | struct inquiry_cache inq_cache; |
176 | struct hci_conn_hash conn_hash; | 184 | struct hci_conn_hash conn_hash; |
177 | struct list_head blacklist; | 185 | struct list_head blacklist; |
@@ -182,6 +190,9 @@ struct hci_dev { | |||
182 | 190 | ||
183 | struct list_head remote_oob_data; | 191 | struct list_head remote_oob_data; |
184 | 192 | ||
193 | struct list_head adv_entries; | ||
194 | struct timer_list adv_timer; | ||
195 | |||
185 | struct hci_dev_stats stat; | 196 | struct hci_dev_stats stat; |
186 | 197 | ||
187 | struct sk_buff_head driver_init; | 198 | struct sk_buff_head driver_init; |
@@ -216,6 +227,7 @@ struct hci_conn { | |||
216 | spinlock_t lock; | 227 | spinlock_t lock; |
217 | 228 | ||
218 | bdaddr_t dst; | 229 | bdaddr_t dst; |
230 | __u8 dst_type; | ||
219 | __u16 handle; | 231 | __u16 handle; |
220 | __u16 state; | 232 | __u16 state; |
221 | __u8 mode; | 233 | __u8 mode; |
@@ -238,6 +250,7 @@ struct hci_conn { | |||
238 | __u8 power_save; | 250 | __u8 power_save; |
239 | __u16 disc_timeout; | 251 | __u16 disc_timeout; |
240 | unsigned long pend; | 252 | unsigned long pend; |
253 | __u8 ltk[16]; | ||
241 | 254 | ||
242 | __u8 remote_cap; | 255 | __u8 remote_cap; |
243 | __u8 remote_oob; | 256 | __u8 remote_oob; |
@@ -308,12 +321,14 @@ static inline long inquiry_entry_age(struct inquiry_entry *e) | |||
308 | return jiffies - e->timestamp; | 321 | return jiffies - e->timestamp; |
309 | } | 322 | } |
310 | 323 | ||
311 | struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); | 324 | struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, |
325 | bdaddr_t *bdaddr); | ||
312 | void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data); | 326 | void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data); |
313 | 327 | ||
314 | /* ----- HCI Connections ----- */ | 328 | /* ----- HCI Connections ----- */ |
315 | enum { | 329 | enum { |
316 | HCI_CONN_AUTH_PEND, | 330 | HCI_CONN_AUTH_PEND, |
331 | HCI_CONN_REAUTH_PEND, | ||
317 | HCI_CONN_ENCRYPT_PEND, | 332 | HCI_CONN_ENCRYPT_PEND, |
318 | HCI_CONN_RSWITCH_PEND, | 333 | HCI_CONN_RSWITCH_PEND, |
319 | HCI_CONN_MODE_CHANGE_PEND, | 334 | HCI_CONN_MODE_CHANGE_PEND, |
@@ -421,14 +436,15 @@ int hci_conn_del(struct hci_conn *conn); | |||
421 | void hci_conn_hash_flush(struct hci_dev *hdev); | 436 | void hci_conn_hash_flush(struct hci_dev *hdev); |
422 | void hci_conn_check_pending(struct hci_dev *hdev); | 437 | void hci_conn_check_pending(struct hci_dev *hdev); |
423 | 438 | ||
424 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); | 439 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, |
440 | __u8 sec_level, __u8 auth_type); | ||
425 | int hci_conn_check_link_mode(struct hci_conn *conn); | 441 | int hci_conn_check_link_mode(struct hci_conn *conn); |
426 | int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); | 442 | int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); |
427 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); | 443 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); |
428 | int hci_conn_change_link_key(struct hci_conn *conn); | 444 | int hci_conn_change_link_key(struct hci_conn *conn); |
429 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role); | 445 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role); |
430 | 446 | ||
431 | void hci_conn_enter_active_mode(struct hci_conn *conn); | 447 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); |
432 | void hci_conn_enter_sniff_mode(struct hci_conn *conn); | 448 | void hci_conn_enter_sniff_mode(struct hci_conn *conn); |
433 | 449 | ||
434 | void hci_conn_hold_device(struct hci_conn *conn); | 450 | void hci_conn_hold_device(struct hci_conn *conn); |
@@ -450,10 +466,12 @@ static inline void hci_conn_put(struct hci_conn *conn) | |||
450 | timeo = msecs_to_jiffies(conn->disc_timeout); | 466 | timeo = msecs_to_jiffies(conn->disc_timeout); |
451 | if (!conn->out) | 467 | if (!conn->out) |
452 | timeo *= 2; | 468 | timeo *= 2; |
453 | } else | 469 | } else { |
454 | timeo = msecs_to_jiffies(10); | 470 | timeo = msecs_to_jiffies(10); |
455 | } else | 471 | } |
472 | } else { | ||
456 | timeo = msecs_to_jiffies(10); | 473 | timeo = msecs_to_jiffies(10); |
474 | } | ||
457 | mod_timer(&conn->disc_timer, jiffies + timeo); | 475 | mod_timer(&conn->disc_timer, jiffies + timeo); |
458 | } | 476 | } |
459 | } | 477 | } |
@@ -512,6 +530,8 @@ int hci_inquiry(void __user *arg); | |||
512 | 530 | ||
513 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); | 531 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); |
514 | int hci_blacklist_clear(struct hci_dev *hdev); | 532 | int hci_blacklist_clear(struct hci_dev *hdev); |
533 | int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
534 | int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
515 | 535 | ||
516 | int hci_uuids_clear(struct hci_dev *hdev); | 536 | int hci_uuids_clear(struct hci_dev *hdev); |
517 | 537 | ||
@@ -528,6 +548,12 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, | |||
528 | u8 *randomizer); | 548 | u8 *randomizer); |
529 | int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); | 549 | int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); |
530 | 550 | ||
551 | #define ADV_CLEAR_TIMEOUT (3*60*HZ) /* Three minutes */ | ||
552 | int hci_adv_entries_clear(struct hci_dev *hdev); | ||
553 | struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
554 | int hci_add_adv_entry(struct hci_dev *hdev, | ||
555 | struct hci_ev_le_advertising_info *ev); | ||
556 | |||
531 | void hci_del_off_timer(struct hci_dev *hdev); | 557 | void hci_del_off_timer(struct hci_dev *hdev); |
532 | 558 | ||
533 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); | 559 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); |
@@ -562,16 +588,20 @@ struct hci_proto { | |||
562 | 588 | ||
563 | void *priv; | 589 | void *priv; |
564 | 590 | ||
565 | int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); | 591 | int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, |
592 | __u8 type); | ||
566 | int (*connect_cfm) (struct hci_conn *conn, __u8 status); | 593 | int (*connect_cfm) (struct hci_conn *conn, __u8 status); |
567 | int (*disconn_ind) (struct hci_conn *conn); | 594 | int (*disconn_ind) (struct hci_conn *conn); |
568 | int (*disconn_cfm) (struct hci_conn *conn, __u8 reason); | 595 | int (*disconn_cfm) (struct hci_conn *conn, __u8 reason); |
569 | int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); | 596 | int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, |
597 | __u16 flags); | ||
570 | int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); | 598 | int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); |
571 | int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); | 599 | int (*security_cfm) (struct hci_conn *conn, __u8 status, |
600 | __u8 encrypt); | ||
572 | }; | 601 | }; |
573 | 602 | ||
574 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | 603 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, |
604 | __u8 type) | ||
575 | { | 605 | { |
576 | register struct hci_proto *hp; | 606 | register struct hci_proto *hp; |
577 | int mask = 0; | 607 | int mask = 0; |
@@ -657,7 +687,8 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | |||
657 | conn->security_cfm_cb(conn, status); | 687 | conn->security_cfm_cb(conn, status); |
658 | } | 688 | } |
659 | 689 | ||
660 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) | 690 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, |
691 | __u8 encrypt) | ||
661 | { | 692 | { |
662 | register struct hci_proto *hp; | 693 | register struct hci_proto *hp; |
663 | 694 | ||
@@ -682,7 +713,8 @@ struct hci_cb { | |||
682 | 713 | ||
683 | char *name; | 714 | char *name; |
684 | 715 | ||
685 | void (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); | 716 | void (*security_cfm) (struct hci_conn *conn, __u8 status, |
717 | __u8 encrypt); | ||
686 | void (*key_change_cfm) (struct hci_conn *conn, __u8 status); | 718 | void (*key_change_cfm) (struct hci_conn *conn, __u8 status); |
687 | void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); | 719 | void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); |
688 | }; | 720 | }; |
@@ -708,13 +740,17 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) | |||
708 | read_unlock_bh(&hci_cb_list_lock); | 740 | read_unlock_bh(&hci_cb_list_lock); |
709 | } | 741 | } |
710 | 742 | ||
711 | static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) | 743 | static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, |
744 | __u8 encrypt) | ||
712 | { | 745 | { |
713 | struct list_head *p; | 746 | struct list_head *p; |
714 | 747 | ||
715 | if (conn->sec_level == BT_SECURITY_SDP) | 748 | if (conn->sec_level == BT_SECURITY_SDP) |
716 | conn->sec_level = BT_SECURITY_LOW; | 749 | conn->sec_level = BT_SECURITY_LOW; |
717 | 750 | ||
751 | if (conn->pending_sec_level > conn->sec_level) | ||
752 | conn->sec_level = conn->pending_sec_level; | ||
753 | |||
718 | hci_proto_encrypt_cfm(conn, status, encrypt); | 754 | hci_proto_encrypt_cfm(conn, status, encrypt); |
719 | 755 | ||
720 | read_lock_bh(&hci_cb_list_lock); | 756 | read_lock_bh(&hci_cb_list_lock); |
@@ -739,7 +775,8 @@ static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) | |||
739 | read_unlock_bh(&hci_cb_list_lock); | 775 | read_unlock_bh(&hci_cb_list_lock); |
740 | } | 776 | } |
741 | 777 | ||
742 | static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role) | 778 | static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, |
779 | __u8 role) | ||
743 | { | 780 | { |
744 | struct list_head *p; | 781 | struct list_head *p; |
745 | 782 | ||
@@ -831,4 +868,9 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result); | |||
831 | 868 | ||
832 | void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, | 869 | void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, |
833 | u16 latency, u16 to_multiplier); | 870 | u16 latency, u16 to_multiplier); |
871 | void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], | ||
872 | __u8 ltk[16]); | ||
873 | void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]); | ||
874 | void hci_le_ltk_neg_reply(struct hci_conn *conn); | ||
875 | |||
834 | #endif /* __HCI_CORE_H */ | 876 | #endif /* __HCI_CORE_H */ |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index d09c9b1118e3..9c18e555b6ed 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -287,6 +287,10 @@ struct l2cap_chan { | |||
287 | 287 | ||
288 | struct l2cap_conn *conn; | 288 | struct l2cap_conn *conn; |
289 | 289 | ||
290 | __u8 state; | ||
291 | |||
292 | atomic_t refcnt; | ||
293 | |||
290 | __le16 psm; | 294 | __le16 psm; |
291 | __u16 dcid; | 295 | __u16 dcid; |
292 | __u16 scid; | 296 | __u16 scid; |
@@ -295,6 +299,7 @@ struct l2cap_chan { | |||
295 | __u16 omtu; | 299 | __u16 omtu; |
296 | __u16 flush_to; | 300 | __u16 flush_to; |
297 | __u8 mode; | 301 | __u8 mode; |
302 | __u8 chan_type; | ||
298 | 303 | ||
299 | __le16 sport; | 304 | __le16 sport; |
300 | 305 | ||
@@ -302,6 +307,7 @@ struct l2cap_chan { | |||
302 | __u8 role_switch; | 307 | __u8 role_switch; |
303 | __u8 force_reliable; | 308 | __u8 force_reliable; |
304 | __u8 flushable; | 309 | __u8 flushable; |
310 | __u8 force_active; | ||
305 | 311 | ||
306 | __u8 ident; | 312 | __u8 ident; |
307 | 313 | ||
@@ -318,8 +324,8 @@ struct l2cap_chan { | |||
318 | __u16 monitor_timeout; | 324 | __u16 monitor_timeout; |
319 | __u16 mps; | 325 | __u16 mps; |
320 | 326 | ||
321 | __u8 conf_state; | 327 | unsigned long conf_state; |
322 | __u16 conn_state; | 328 | unsigned long conn_state; |
323 | 329 | ||
324 | __u8 next_tx_seq; | 330 | __u8 next_tx_seq; |
325 | __u8 expected_ack_seq; | 331 | __u8 expected_ack_seq; |
@@ -339,6 +345,7 @@ struct l2cap_chan { | |||
339 | __u8 remote_max_tx; | 345 | __u8 remote_max_tx; |
340 | __u16 remote_mps; | 346 | __u16 remote_mps; |
341 | 347 | ||
348 | struct timer_list chan_timer; | ||
342 | struct timer_list retrans_timer; | 349 | struct timer_list retrans_timer; |
343 | struct timer_list monitor_timer; | 350 | struct timer_list monitor_timer; |
344 | struct timer_list ack_timer; | 351 | struct timer_list ack_timer; |
@@ -351,6 +358,18 @@ struct l2cap_chan { | |||
351 | 358 | ||
352 | struct list_head list; | 359 | struct list_head list; |
353 | struct list_head global_l; | 360 | struct list_head global_l; |
361 | |||
362 | void *data; | ||
363 | struct l2cap_ops *ops; | ||
364 | }; | ||
365 | |||
366 | struct l2cap_ops { | ||
367 | char *name; | ||
368 | |||
369 | struct l2cap_chan *(*new_connection) (void *data); | ||
370 | int (*recv) (void *data, struct sk_buff *skb); | ||
371 | void (*close) (void *data); | ||
372 | void (*state_change) (void *data, int state); | ||
354 | }; | 373 | }; |
355 | 374 | ||
356 | struct l2cap_conn { | 375 | struct l2cap_conn { |
@@ -376,6 +395,15 @@ struct l2cap_conn { | |||
376 | 395 | ||
377 | __u8 disc_reason; | 396 | __u8 disc_reason; |
378 | 397 | ||
398 | __u8 preq[7]; /* SMP Pairing Request */ | ||
399 | __u8 prsp[7]; /* SMP Pairing Response */ | ||
400 | __u8 prnd[16]; /* SMP Pairing Random */ | ||
401 | __u8 pcnf[16]; /* SMP Pairing Confirm */ | ||
402 | __u8 tk[16]; /* SMP Temporary Key */ | ||
403 | __u8 smp_key_size; | ||
404 | |||
405 | struct timer_list security_timer; | ||
406 | |||
379 | struct list_head chan_l; | 407 | struct list_head chan_l; |
380 | rwlock_t chan_lock; | 408 | rwlock_t chan_lock; |
381 | }; | 409 | }; |
@@ -384,6 +412,10 @@ struct l2cap_conn { | |||
384 | #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 | 412 | #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 |
385 | #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 | 413 | #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 |
386 | 414 | ||
415 | #define L2CAP_CHAN_RAW 1 | ||
416 | #define L2CAP_CHAN_CONN_LESS 2 | ||
417 | #define L2CAP_CHAN_CONN_ORIENTED 3 | ||
418 | |||
387 | /* ----- L2CAP socket info ----- */ | 419 | /* ----- L2CAP socket info ----- */ |
388 | #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) | 420 | #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) |
389 | 421 | ||
@@ -392,36 +424,45 @@ struct l2cap_pinfo { | |||
392 | struct l2cap_chan *chan; | 424 | struct l2cap_chan *chan; |
393 | }; | 425 | }; |
394 | 426 | ||
395 | #define L2CAP_CONF_REQ_SENT 0x01 | 427 | enum { |
396 | #define L2CAP_CONF_INPUT_DONE 0x02 | 428 | CONF_REQ_SENT, |
397 | #define L2CAP_CONF_OUTPUT_DONE 0x04 | 429 | CONF_INPUT_DONE, |
398 | #define L2CAP_CONF_MTU_DONE 0x08 | 430 | CONF_OUTPUT_DONE, |
399 | #define L2CAP_CONF_MODE_DONE 0x10 | 431 | CONF_MTU_DONE, |
400 | #define L2CAP_CONF_CONNECT_PEND 0x20 | 432 | CONF_MODE_DONE, |
401 | #define L2CAP_CONF_NO_FCS_RECV 0x40 | 433 | CONF_CONNECT_PEND, |
402 | #define L2CAP_CONF_STATE2_DEVICE 0x80 | 434 | CONF_NO_FCS_RECV, |
435 | CONF_STATE2_DEVICE, | ||
436 | }; | ||
403 | 437 | ||
404 | #define L2CAP_CONF_MAX_CONF_REQ 2 | 438 | #define L2CAP_CONF_MAX_CONF_REQ 2 |
405 | #define L2CAP_CONF_MAX_CONF_RSP 2 | 439 | #define L2CAP_CONF_MAX_CONF_RSP 2 |
406 | 440 | ||
407 | #define L2CAP_CONN_SAR_SDU 0x0001 | 441 | enum { |
408 | #define L2CAP_CONN_SREJ_SENT 0x0002 | 442 | CONN_SAR_SDU, |
409 | #define L2CAP_CONN_WAIT_F 0x0004 | 443 | CONN_SREJ_SENT, |
410 | #define L2CAP_CONN_SREJ_ACT 0x0008 | 444 | CONN_WAIT_F, |
411 | #define L2CAP_CONN_SEND_PBIT 0x0010 | 445 | CONN_SREJ_ACT, |
412 | #define L2CAP_CONN_REMOTE_BUSY 0x0020 | 446 | CONN_SEND_PBIT, |
413 | #define L2CAP_CONN_LOCAL_BUSY 0x0040 | 447 | CONN_REMOTE_BUSY, |
414 | #define L2CAP_CONN_REJ_ACT 0x0080 | 448 | CONN_LOCAL_BUSY, |
415 | #define L2CAP_CONN_SEND_FBIT 0x0100 | 449 | CONN_REJ_ACT, |
416 | #define L2CAP_CONN_RNR_SENT 0x0200 | 450 | CONN_SEND_FBIT, |
417 | #define L2CAP_CONN_SAR_RETRY 0x0400 | 451 | CONN_RNR_SENT, |
418 | 452 | CONN_SAR_RETRY, | |
419 | #define __mod_retrans_timer() mod_timer(&chan->retrans_timer, \ | 453 | }; |
420 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); | 454 | |
421 | #define __mod_monitor_timer() mod_timer(&chan->monitor_timer, \ | 455 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) |
422 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); | 456 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) |
423 | #define __mod_ack_timer() mod_timer(&chan->ack_timer, \ | 457 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ |
424 | jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); | 458 | L2CAP_DEFAULT_RETRANS_TO); |
459 | #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) | ||
460 | #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ | ||
461 | L2CAP_DEFAULT_MONITOR_TO); | ||
462 | #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) | ||
463 | #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ | ||
464 | L2CAP_DEFAULT_ACK_TO); | ||
465 | #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) | ||
425 | 466 | ||
426 | static inline int l2cap_tx_window_full(struct l2cap_chan *ch) | 467 | static inline int l2cap_tx_window_full(struct l2cap_chan *ch) |
427 | { | 468 | { |
@@ -446,32 +487,16 @@ extern int disable_ertm; | |||
446 | int l2cap_init_sockets(void); | 487 | int l2cap_init_sockets(void); |
447 | void l2cap_cleanup_sockets(void); | 488 | void l2cap_cleanup_sockets(void); |
448 | 489 | ||
449 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); | ||
450 | void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); | 490 | void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); |
451 | int __l2cap_wait_ack(struct sock *sk); | 491 | int __l2cap_wait_ack(struct sock *sk); |
452 | 492 | ||
453 | struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); | ||
454 | struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); | ||
455 | struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen); | ||
456 | int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); | ||
457 | void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb); | ||
458 | void l2cap_streaming_send(struct l2cap_chan *chan); | ||
459 | int l2cap_ertm_send(struct l2cap_chan *chan); | ||
460 | |||
461 | int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm); | 493 | int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm); |
462 | int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); | 494 | int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); |
463 | 495 | ||
464 | void l2cap_sock_set_timer(struct sock *sk, long timeout); | ||
465 | void l2cap_sock_clear_timer(struct sock *sk); | ||
466 | void __l2cap_sock_close(struct sock *sk, int reason); | ||
467 | void l2cap_sock_kill(struct sock *sk); | ||
468 | void l2cap_sock_init(struct sock *sk, struct sock *parent); | ||
469 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | ||
470 | int proto, gfp_t prio); | ||
471 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); | ||
472 | struct l2cap_chan *l2cap_chan_create(struct sock *sk); | 496 | struct l2cap_chan *l2cap_chan_create(struct sock *sk); |
473 | void l2cap_chan_del(struct l2cap_chan *chan, int err); | 497 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); |
474 | void l2cap_chan_destroy(struct l2cap_chan *chan); | 498 | void l2cap_chan_destroy(struct l2cap_chan *chan); |
475 | int l2cap_chan_connect(struct l2cap_chan *chan); | 499 | int l2cap_chan_connect(struct l2cap_chan *chan); |
500 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len); | ||
476 | 501 | ||
477 | #endif /* __L2CAP_H */ | 502 | #endif /* __L2CAP_H */ |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 4899286ed4e4..45bea25d737f 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -199,6 +199,16 @@ struct mgmt_cp_remove_remote_oob_data { | |||
199 | 199 | ||
200 | #define MGMT_OP_STOP_DISCOVERY 0x001C | 200 | #define MGMT_OP_STOP_DISCOVERY 0x001C |
201 | 201 | ||
202 | #define MGMT_OP_BLOCK_DEVICE 0x001D | ||
203 | struct mgmt_cp_block_device { | ||
204 | bdaddr_t bdaddr; | ||
205 | } __packed; | ||
206 | |||
207 | #define MGMT_OP_UNBLOCK_DEVICE 0x001E | ||
208 | struct mgmt_cp_unblock_device { | ||
209 | bdaddr_t bdaddr; | ||
210 | } __packed; | ||
211 | |||
202 | #define MGMT_EV_CMD_COMPLETE 0x0001 | 212 | #define MGMT_EV_CMD_COMPLETE 0x0001 |
203 | struct mgmt_ev_cmd_complete { | 213 | struct mgmt_ev_cmd_complete { |
204 | __le16 opcode; | 214 | __le16 opcode; |
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 6eac4a760c3b..d5eee2093b1e 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h | |||
@@ -234,7 +234,8 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, | |||
234 | /* ---- RFCOMM DLCs (channels) ---- */ | 234 | /* ---- RFCOMM DLCs (channels) ---- */ |
235 | struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio); | 235 | struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio); |
236 | void rfcomm_dlc_free(struct rfcomm_dlc *d); | 236 | void rfcomm_dlc_free(struct rfcomm_dlc *d); |
237 | int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel); | 237 | int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, |
238 | u8 channel); | ||
238 | int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason); | 239 | int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason); |
239 | int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb); | 240 | int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb); |
240 | int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig); | 241 | int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig); |
@@ -271,7 +272,8 @@ static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) | |||
271 | } | 272 | } |
272 | 273 | ||
273 | /* ---- RFCOMM sessions ---- */ | 274 | /* ---- RFCOMM sessions ---- */ |
274 | void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst); | 275 | void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, |
276 | bdaddr_t *dst); | ||
275 | 277 | ||
276 | static inline void rfcomm_session_hold(struct rfcomm_session *s) | 278 | static inline void rfcomm_session_hold(struct rfcomm_session *s) |
277 | { | 279 | { |
@@ -312,7 +314,8 @@ struct rfcomm_pinfo { | |||
312 | int rfcomm_init_sockets(void); | 314 | int rfcomm_init_sockets(void); |
313 | void rfcomm_cleanup_sockets(void); | 315 | void rfcomm_cleanup_sockets(void); |
314 | 316 | ||
315 | int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d); | 317 | int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, |
318 | struct rfcomm_dlc **d); | ||
316 | 319 | ||
317 | /* ---- RFCOMM TTY ---- */ | 320 | /* ---- RFCOMM TTY ---- */ |
318 | #define RFCOMM_MAX_DEV 256 | 321 | #define RFCOMM_MAX_DEV 256 |
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h index 8f2edbf979dc..4fb7d198a876 100644 --- a/include/net/bluetooth/smp.h +++ b/include/net/bluetooth/smp.h | |||
@@ -1,3 +1,25 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License version 2 as | ||
7 | published by the Free Software Foundation; | ||
8 | |||
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
10 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
11 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
12 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
13 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
14 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | |||
18 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
19 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
20 | SOFTWARE IS DISCLAIMED. | ||
21 | */ | ||
22 | |||
1 | #ifndef __SMP_H | 23 | #ifndef __SMP_H |
2 | #define __SMP_H | 24 | #define __SMP_H |
3 | 25 | ||
@@ -16,6 +38,23 @@ struct smp_cmd_pairing { | |||
16 | __u8 resp_key_dist; | 38 | __u8 resp_key_dist; |
17 | } __packed; | 39 | } __packed; |
18 | 40 | ||
41 | #define SMP_IO_DISPLAY_ONLY 0x00 | ||
42 | #define SMP_IO_DISPLAY_YESNO 0x01 | ||
43 | #define SMP_IO_KEYBOARD_ONLY 0x02 | ||
44 | #define SMP_IO_NO_INPUT_OUTPUT 0x03 | ||
45 | #define SMP_IO_KEYBOARD_DISPLAY 0x04 | ||
46 | |||
47 | #define SMP_OOB_NOT_PRESENT 0x00 | ||
48 | #define SMP_OOB_PRESENT 0x01 | ||
49 | |||
50 | #define SMP_DIST_ENC_KEY 0x01 | ||
51 | #define SMP_DIST_ID_KEY 0x02 | ||
52 | #define SMP_DIST_SIGN 0x04 | ||
53 | |||
54 | #define SMP_AUTH_NONE 0x00 | ||
55 | #define SMP_AUTH_BONDING 0x01 | ||
56 | #define SMP_AUTH_MITM 0x04 | ||
57 | |||
19 | #define SMP_CMD_PAIRING_CONFIRM 0x03 | 58 | #define SMP_CMD_PAIRING_CONFIRM 0x03 |
20 | struct smp_cmd_pairing_confirm { | 59 | struct smp_cmd_pairing_confirm { |
21 | __u8 confirm_val[16]; | 60 | __u8 confirm_val[16]; |
@@ -73,4 +112,11 @@ struct smp_cmd_security_req { | |||
73 | #define SMP_UNSPECIFIED 0x08 | 112 | #define SMP_UNSPECIFIED 0x08 |
74 | #define SMP_REPEATED_ATTEMPTS 0x09 | 113 | #define SMP_REPEATED_ATTEMPTS 0x09 |
75 | 114 | ||
115 | #define SMP_MIN_ENC_KEY_SIZE 7 | ||
116 | #define SMP_MAX_ENC_KEY_SIZE 16 | ||
117 | |||
118 | /* SMP Commands */ | ||
119 | int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level); | ||
120 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); | ||
121 | |||
76 | #endif /* __SMP_H */ | 122 | #endif /* __SMP_H */ |
diff --git a/include/net/genetlink.h b/include/net/genetlink.h index d420f28b6d60..82d8d09faa44 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h | |||
@@ -160,6 +160,38 @@ static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, | |||
160 | } | 160 | } |
161 | 161 | ||
162 | /** | 162 | /** |
163 | * genlmsg_nlhdr - Obtain netlink header from user specified header | ||
164 | * @user_hdr: user header as returned from genlmsg_put() | ||
165 | * @family: generic netlink family | ||
166 | * | ||
167 | * Returns pointer to netlink header. | ||
168 | */ | ||
169 | static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr, | ||
170 | struct genl_family *family) | ||
171 | { | ||
172 | return (struct nlmsghdr *)((char *)user_hdr - | ||
173 | family->hdrsize - | ||
174 | GENL_HDRLEN - | ||
175 | NLMSG_HDRLEN); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * genl_dump_check_consistent - check if sequence is consistent and advertise if not | ||
180 | * @cb: netlink callback structure that stores the sequence number | ||
181 | * @user_hdr: user header as returned from genlmsg_put() | ||
182 | * @family: generic netlink family | ||
183 | * | ||
184 | * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it | ||
185 | * simpler to use with generic netlink. | ||
186 | */ | ||
187 | static inline void genl_dump_check_consistent(struct netlink_callback *cb, | ||
188 | void *user_hdr, | ||
189 | struct genl_family *family) | ||
190 | { | ||
191 | nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr, family)); | ||
192 | } | ||
193 | |||
194 | /** | ||
163 | * genlmsg_put_reply - Add generic netlink header to a reply message | 195 | * genlmsg_put_reply - Add generic netlink header to a reply message |
164 | * @skb: socket buffer holding the message | 196 | * @skb: socket buffer holding the message |
165 | * @info: receiver info | 197 | * @info: receiver info |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3b31ec95dd8e..120f102814b6 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1708,6 +1708,14 @@ enum ieee80211_ampdu_mlme_action { | |||
1708 | * any error unless this callback returned a negative error code. | 1708 | * any error unless this callback returned a negative error code. |
1709 | * The callback can sleep. | 1709 | * The callback can sleep. |
1710 | * | 1710 | * |
1711 | * @cancel_hw_scan: Ask the low-level tp cancel the active hw scan. | ||
1712 | * The driver should ask the hardware to cancel the scan (if possible), | ||
1713 | * but the scan will be completed only after the driver will call | ||
1714 | * ieee80211_scan_completed(). | ||
1715 | * This callback is needed for wowlan, to prevent enqueueing a new | ||
1716 | * scan_work after the low-level driver was already suspended. | ||
1717 | * The callback can sleep. | ||
1718 | * | ||
1711 | * @sched_scan_start: Ask the hardware to start scanning repeatedly at | 1719 | * @sched_scan_start: Ask the hardware to start scanning repeatedly at |
1712 | * specific intervals. The driver must call the | 1720 | * specific intervals. The driver must call the |
1713 | * ieee80211_sched_scan_results() function whenever it finds results. | 1721 | * ieee80211_sched_scan_results() function whenever it finds results. |
@@ -1900,6 +1908,8 @@ struct ieee80211_ops { | |||
1900 | u32 iv32, u16 *phase1key); | 1908 | u32 iv32, u16 *phase1key); |
1901 | int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1909 | int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
1902 | struct cfg80211_scan_request *req); | 1910 | struct cfg80211_scan_request *req); |
1911 | void (*cancel_hw_scan)(struct ieee80211_hw *hw, | ||
1912 | struct ieee80211_vif *vif); | ||
1903 | int (*sched_scan_start)(struct ieee80211_hw *hw, | 1913 | int (*sched_scan_start)(struct ieee80211_hw *hw, |
1904 | struct ieee80211_vif *vif, | 1914 | struct ieee80211_vif *vif, |
1905 | struct cfg80211_sched_scan_request *req, | 1915 | struct cfg80211_sched_scan_request *req, |
@@ -2920,6 +2930,16 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | |||
2920 | gfp_t gfp); | 2930 | gfp_t gfp); |
2921 | 2931 | ||
2922 | /** | 2932 | /** |
2933 | * ieee80211_get_operstate - get the operstate of the vif | ||
2934 | * | ||
2935 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | ||
2936 | * | ||
2937 | * The driver might need to know the operstate of the net_device | ||
2938 | * (specifically, whether the link is IF_OPER_UP after resume) | ||
2939 | */ | ||
2940 | unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif); | ||
2941 | |||
2942 | /** | ||
2923 | * ieee80211_chswitch_done - Complete channel switch process | 2943 | * ieee80211_chswitch_done - Complete channel switch process |
2924 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | 2944 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. |
2925 | * @success: make the channel switch successful or not | 2945 | * @success: make the channel switch successful or not |
diff --git a/include/net/netlink.h b/include/net/netlink.h index 02740a94f108..98c185441bee 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
@@ -638,6 +638,30 @@ static inline int nlmsg_unicast(struct sock *sk, struct sk_buff *skb, u32 pid) | |||
638 | nlmsg_ok(pos, rem); \ | 638 | nlmsg_ok(pos, rem); \ |
639 | pos = nlmsg_next(pos, &(rem))) | 639 | pos = nlmsg_next(pos, &(rem))) |
640 | 640 | ||
641 | /** | ||
642 | * nl_dump_check_consistent - check if sequence is consistent and advertise if not | ||
643 | * @cb: netlink callback structure that stores the sequence number | ||
644 | * @nlh: netlink message header to write the flag to | ||
645 | * | ||
646 | * This function checks if the sequence (generation) number changed during dump | ||
647 | * and if it did, advertises it in the netlink message header. | ||
648 | * | ||
649 | * The correct way to use it is to set cb->seq to the generation counter when | ||
650 | * all locks for dumping have been acquired, and then call this function for | ||
651 | * each message that is generated. | ||
652 | * | ||
653 | * Note that due to initialisation concerns, 0 is an invalid sequence number | ||
654 | * and must not be used by code that uses this functionality. | ||
655 | */ | ||
656 | static inline void | ||
657 | nl_dump_check_consistent(struct netlink_callback *cb, | ||
658 | struct nlmsghdr *nlh) | ||
659 | { | ||
660 | if (cb->prev_seq && cb->seq != cb->prev_seq) | ||
661 | nlh->nlmsg_flags |= NLM_F_DUMP_INTR; | ||
662 | cb->prev_seq = cb->seq; | ||
663 | } | ||
664 | |||
641 | /************************************************************************** | 665 | /************************************************************************** |
642 | * Netlink Attributes | 666 | * Netlink Attributes |
643 | **************************************************************************/ | 667 | **************************************************************************/ |
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 6ae5ec508587..f495dea741e3 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig | |||
@@ -22,6 +22,7 @@ menuconfig BT | |||
22 | BNEP Module (Bluetooth Network Encapsulation Protocol) | 22 | BNEP Module (Bluetooth Network Encapsulation Protocol) |
23 | CMTP Module (CAPI Message Transport Protocol) | 23 | CMTP Module (CAPI Message Transport Protocol) |
24 | HIDP Module (Human Interface Device Protocol) | 24 | HIDP Module (Human Interface Device Protocol) |
25 | SMP Module (Security Manager Protocol) | ||
25 | 26 | ||
26 | Say Y here to compile Bluetooth support into the kernel or say M to | 27 | Say Y here to compile Bluetooth support into the kernel or say M to |
27 | compile it as module (bluetooth). | 28 | compile it as module (bluetooth). |
@@ -36,11 +37,18 @@ if BT != n | |||
36 | config BT_L2CAP | 37 | config BT_L2CAP |
37 | bool "L2CAP protocol support" | 38 | bool "L2CAP protocol support" |
38 | select CRC16 | 39 | select CRC16 |
40 | select CRYPTO | ||
41 | select CRYPTO_BLKCIPHER | ||
42 | select CRYPTO_AES | ||
43 | select CRYPTO_ECB | ||
39 | help | 44 | help |
40 | L2CAP (Logical Link Control and Adaptation Protocol) provides | 45 | L2CAP (Logical Link Control and Adaptation Protocol) provides |
41 | connection oriented and connection-less data transport. L2CAP | 46 | connection oriented and connection-less data transport. L2CAP |
42 | support is required for most Bluetooth applications. | 47 | support is required for most Bluetooth applications. |
43 | 48 | ||
49 | Also included is support for SMP (Security Manager Protocol) which | ||
50 | is the security layer on top of LE (Low Energy) links. | ||
51 | |||
44 | config BT_SCO | 52 | config BT_SCO |
45 | bool "SCO links support" | 53 | bool "SCO links support" |
46 | help | 54 | help |
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index f04fe9a9d634..9b67f3d08fa4 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile | |||
@@ -9,5 +9,5 @@ obj-$(CONFIG_BT_CMTP) += cmtp/ | |||
9 | obj-$(CONFIG_BT_HIDP) += hidp/ | 9 | obj-$(CONFIG_BT_HIDP) += hidp/ |
10 | 10 | ||
11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o | 11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o |
12 | bluetooth-$(CONFIG_BT_L2CAP) += l2cap_core.o l2cap_sock.o | 12 | bluetooth-$(CONFIG_BT_L2CAP) += l2cap_core.o l2cap_sock.o smp.o |
13 | bluetooth-$(CONFIG_BT_SCO) += sco.o | 13 | bluetooth-$(CONFIG_BT_SCO) += sco.o |
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 744233cba244..040f67b12978 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c | |||
@@ -326,7 +326,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) | |||
326 | { | 326 | { |
327 | struct capi_ctr *ctrl = &session->ctrl; | 327 | struct capi_ctr *ctrl = &session->ctrl; |
328 | struct cmtp_application *application; | 328 | struct cmtp_application *application; |
329 | __u16 cmd, appl; | 329 | __u16 appl; |
330 | __u32 contr; | 330 | __u32 contr; |
331 | 331 | ||
332 | BT_DBG("session %p skb %p len %d", session, skb, skb->len); | 332 | BT_DBG("session %p skb %p len %d", session, skb, skb->len); |
@@ -344,7 +344,6 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) | |||
344 | return; | 344 | return; |
345 | } | 345 | } |
346 | 346 | ||
347 | cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data)); | ||
348 | appl = CAPIMSG_APPID(skb->data); | 347 | appl = CAPIMSG_APPID(skb->data); |
349 | contr = CAPIMSG_CONTROL(skb->data); | 348 | contr = CAPIMSG_CONTROL(skb->data); |
350 | 349 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 3163330cd4f1..fa48c0b3d93c 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -53,11 +53,13 @@ static void hci_le_connect(struct hci_conn *conn) | |||
53 | conn->state = BT_CONNECT; | 53 | conn->state = BT_CONNECT; |
54 | conn->out = 1; | 54 | conn->out = 1; |
55 | conn->link_mode |= HCI_LM_MASTER; | 55 | conn->link_mode |= HCI_LM_MASTER; |
56 | conn->sec_level = BT_SECURITY_LOW; | ||
56 | 57 | ||
57 | memset(&cp, 0, sizeof(cp)); | 58 | memset(&cp, 0, sizeof(cp)); |
58 | cp.scan_interval = cpu_to_le16(0x0004); | 59 | cp.scan_interval = cpu_to_le16(0x0004); |
59 | cp.scan_window = cpu_to_le16(0x0004); | 60 | cp.scan_window = cpu_to_le16(0x0004); |
60 | bacpy(&cp.peer_addr, &conn->dst); | 61 | bacpy(&cp.peer_addr, &conn->dst); |
62 | cp.peer_addr_type = conn->dst_type; | ||
61 | cp.conn_interval_min = cpu_to_le16(0x0008); | 63 | cp.conn_interval_min = cpu_to_le16(0x0008); |
62 | cp.conn_interval_max = cpu_to_le16(0x0100); | 64 | cp.conn_interval_max = cpu_to_le16(0x0100); |
63 | cp.supervision_timeout = cpu_to_le16(0x0064); | 65 | cp.supervision_timeout = cpu_to_le16(0x0064); |
@@ -203,6 +205,55 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, | |||
203 | } | 205 | } |
204 | EXPORT_SYMBOL(hci_le_conn_update); | 206 | EXPORT_SYMBOL(hci_le_conn_update); |
205 | 207 | ||
208 | void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], | ||
209 | __u8 ltk[16]) | ||
210 | { | ||
211 | struct hci_dev *hdev = conn->hdev; | ||
212 | struct hci_cp_le_start_enc cp; | ||
213 | |||
214 | BT_DBG("%p", conn); | ||
215 | |||
216 | memset(&cp, 0, sizeof(cp)); | ||
217 | |||
218 | cp.handle = cpu_to_le16(conn->handle); | ||
219 | memcpy(cp.ltk, ltk, sizeof(cp.ltk)); | ||
220 | cp.ediv = ediv; | ||
221 | memcpy(cp.rand, rand, sizeof(rand)); | ||
222 | |||
223 | hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp); | ||
224 | } | ||
225 | EXPORT_SYMBOL(hci_le_start_enc); | ||
226 | |||
227 | void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]) | ||
228 | { | ||
229 | struct hci_dev *hdev = conn->hdev; | ||
230 | struct hci_cp_le_ltk_reply cp; | ||
231 | |||
232 | BT_DBG("%p", conn); | ||
233 | |||
234 | memset(&cp, 0, sizeof(cp)); | ||
235 | |||
236 | cp.handle = cpu_to_le16(conn->handle); | ||
237 | memcpy(cp.ltk, ltk, sizeof(ltk)); | ||
238 | |||
239 | hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); | ||
240 | } | ||
241 | EXPORT_SYMBOL(hci_le_ltk_reply); | ||
242 | |||
243 | void hci_le_ltk_neg_reply(struct hci_conn *conn) | ||
244 | { | ||
245 | struct hci_dev *hdev = conn->hdev; | ||
246 | struct hci_cp_le_ltk_neg_reply cp; | ||
247 | |||
248 | BT_DBG("%p", conn); | ||
249 | |||
250 | memset(&cp, 0, sizeof(cp)); | ||
251 | |||
252 | cp.handle = cpu_to_le16(conn->handle); | ||
253 | |||
254 | hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(cp), &cp); | ||
255 | } | ||
256 | |||
206 | /* Device _must_ be locked */ | 257 | /* Device _must_ be locked */ |
207 | void hci_sco_setup(struct hci_conn *conn, __u8 status) | 258 | void hci_sco_setup(struct hci_conn *conn, __u8 status) |
208 | { | 259 | { |
@@ -447,14 +498,23 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
447 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); | 498 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); |
448 | 499 | ||
449 | if (type == LE_LINK) { | 500 | if (type == LE_LINK) { |
501 | struct adv_entry *entry; | ||
502 | |||
450 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); | 503 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); |
451 | if (le) | 504 | if (le) |
452 | return ERR_PTR(-EBUSY); | 505 | return ERR_PTR(-EBUSY); |
506 | |||
507 | entry = hci_find_adv_entry(hdev, dst); | ||
508 | if (!entry) | ||
509 | return ERR_PTR(-EHOSTUNREACH); | ||
510 | |||
453 | le = hci_conn_add(hdev, LE_LINK, dst); | 511 | le = hci_conn_add(hdev, LE_LINK, dst); |
454 | if (!le) | 512 | if (!le) |
455 | return ERR_PTR(-ENOMEM); | 513 | return ERR_PTR(-ENOMEM); |
456 | if (le->state == BT_OPEN) | 514 | |
457 | hci_le_connect(le); | 515 | le->dst_type = entry->bdaddr_type; |
516 | |||
517 | hci_le_connect(le); | ||
458 | 518 | ||
459 | hci_conn_hold(le); | 519 | hci_conn_hold(le); |
460 | 520 | ||
@@ -497,7 +557,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
497 | if (acl->state == BT_CONNECTED && | 557 | if (acl->state == BT_CONNECTED && |
498 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { | 558 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { |
499 | acl->power_save = 1; | 559 | acl->power_save = 1; |
500 | hci_conn_enter_active_mode(acl); | 560 | hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON); |
501 | 561 | ||
502 | if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { | 562 | if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { |
503 | /* defer SCO setup until mode change completed */ | 563 | /* defer SCO setup until mode change completed */ |
@@ -548,6 +608,8 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
548 | cp.handle = cpu_to_le16(conn->handle); | 608 | cp.handle = cpu_to_le16(conn->handle); |
549 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, | 609 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, |
550 | sizeof(cp), &cp); | 610 | sizeof(cp), &cp); |
611 | if (conn->key_type != 0xff) | ||
612 | set_bit(HCI_CONN_REAUTH_PEND, &conn->pend); | ||
551 | } | 613 | } |
552 | 614 | ||
553 | return 0; | 615 | return 0; |
@@ -608,11 +670,11 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
608 | goto encrypt; | 670 | goto encrypt; |
609 | 671 | ||
610 | auth: | 672 | auth: |
611 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 673 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
612 | return 0; | 674 | return 0; |
613 | 675 | ||
614 | hci_conn_auth(conn, sec_level, auth_type); | 676 | if (!hci_conn_auth(conn, sec_level, auth_type)) |
615 | return 0; | 677 | return 0; |
616 | 678 | ||
617 | encrypt: | 679 | encrypt: |
618 | if (conn->link_mode & HCI_LM_ENCRYPT) | 680 | if (conn->link_mode & HCI_LM_ENCRYPT) |
@@ -631,9 +693,7 @@ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) | |||
631 | if (sec_level != BT_SECURITY_HIGH) | 693 | if (sec_level != BT_SECURITY_HIGH) |
632 | return 1; /* Accept if non-secure is required */ | 694 | return 1; /* Accept if non-secure is required */ |
633 | 695 | ||
634 | if (conn->key_type == HCI_LK_AUTH_COMBINATION || | 696 | if (conn->sec_level == BT_SECURITY_HIGH) |
635 | (conn->key_type == HCI_LK_COMBINATION && | ||
636 | conn->pin_length == 16)) | ||
637 | return 1; | 697 | return 1; |
638 | 698 | ||
639 | return 0; /* Reject not secure link */ | 699 | return 0; /* Reject not secure link */ |
@@ -676,7 +736,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) | |||
676 | EXPORT_SYMBOL(hci_conn_switch_role); | 736 | EXPORT_SYMBOL(hci_conn_switch_role); |
677 | 737 | ||
678 | /* Enter active mode */ | 738 | /* Enter active mode */ |
679 | void hci_conn_enter_active_mode(struct hci_conn *conn) | 739 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) |
680 | { | 740 | { |
681 | struct hci_dev *hdev = conn->hdev; | 741 | struct hci_dev *hdev = conn->hdev; |
682 | 742 | ||
@@ -685,7 +745,10 @@ void hci_conn_enter_active_mode(struct hci_conn *conn) | |||
685 | if (test_bit(HCI_RAW, &hdev->flags)) | 745 | if (test_bit(HCI_RAW, &hdev->flags)) |
686 | return; | 746 | return; |
687 | 747 | ||
688 | if (conn->mode != HCI_CM_SNIFF || !conn->power_save) | 748 | if (conn->mode != HCI_CM_SNIFF) |
749 | goto timer; | ||
750 | |||
751 | if (!conn->power_save && !force_active) | ||
689 | goto timer; | 752 | goto timer; |
690 | 753 | ||
691 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | 754 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e937adab3683..b18db5628275 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
43 | #include <linux/rfkill.h> | 43 | #include <linux/rfkill.h> |
44 | #include <linux/timer.h> | 44 | #include <linux/timer.h> |
45 | #include <linux/crypto.h> | ||
45 | #include <net/sock.h> | 46 | #include <net/sock.h> |
46 | 47 | ||
47 | #include <asm/system.h> | 48 | #include <asm/system.h> |
@@ -59,6 +60,8 @@ static void hci_tx_task(unsigned long arg); | |||
59 | 60 | ||
60 | static DEFINE_RWLOCK(hci_task_lock); | 61 | static DEFINE_RWLOCK(hci_task_lock); |
61 | 62 | ||
63 | static int enable_smp; | ||
64 | |||
62 | /* HCI device list */ | 65 | /* HCI device list */ |
63 | LIST_HEAD(hci_dev_list); | 66 | LIST_HEAD(hci_dev_list); |
64 | DEFINE_RWLOCK(hci_dev_list_lock); | 67 | DEFINE_RWLOCK(hci_dev_list_lock); |
@@ -1202,6 +1205,177 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, | |||
1202 | return 0; | 1205 | return 0; |
1203 | } | 1206 | } |
1204 | 1207 | ||
1208 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, | ||
1209 | bdaddr_t *bdaddr) | ||
1210 | { | ||
1211 | struct list_head *p; | ||
1212 | |||
1213 | list_for_each(p, &hdev->blacklist) { | ||
1214 | struct bdaddr_list *b; | ||
1215 | |||
1216 | b = list_entry(p, struct bdaddr_list, list); | ||
1217 | |||
1218 | if (bacmp(bdaddr, &b->bdaddr) == 0) | ||
1219 | return b; | ||
1220 | } | ||
1221 | |||
1222 | return NULL; | ||
1223 | } | ||
1224 | |||
1225 | int hci_blacklist_clear(struct hci_dev *hdev) | ||
1226 | { | ||
1227 | struct list_head *p, *n; | ||
1228 | |||
1229 | list_for_each_safe(p, n, &hdev->blacklist) { | ||
1230 | struct bdaddr_list *b; | ||
1231 | |||
1232 | b = list_entry(p, struct bdaddr_list, list); | ||
1233 | |||
1234 | list_del(p); | ||
1235 | kfree(b); | ||
1236 | } | ||
1237 | |||
1238 | return 0; | ||
1239 | } | ||
1240 | |||
1241 | int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | ||
1242 | { | ||
1243 | struct bdaddr_list *entry; | ||
1244 | int err; | ||
1245 | |||
1246 | if (bacmp(bdaddr, BDADDR_ANY) == 0) | ||
1247 | return -EBADF; | ||
1248 | |||
1249 | hci_dev_lock(hdev); | ||
1250 | |||
1251 | if (hci_blacklist_lookup(hdev, bdaddr)) { | ||
1252 | err = -EEXIST; | ||
1253 | goto err; | ||
1254 | } | ||
1255 | |||
1256 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); | ||
1257 | if (!entry) { | ||
1258 | return -ENOMEM; | ||
1259 | goto err; | ||
1260 | } | ||
1261 | |||
1262 | bacpy(&entry->bdaddr, bdaddr); | ||
1263 | |||
1264 | list_add(&entry->list, &hdev->blacklist); | ||
1265 | |||
1266 | err = 0; | ||
1267 | |||
1268 | err: | ||
1269 | hci_dev_unlock(hdev); | ||
1270 | return err; | ||
1271 | } | ||
1272 | |||
1273 | int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | ||
1274 | { | ||
1275 | struct bdaddr_list *entry; | ||
1276 | int err = 0; | ||
1277 | |||
1278 | hci_dev_lock(hdev); | ||
1279 | |||
1280 | if (bacmp(bdaddr, BDADDR_ANY) == 0) { | ||
1281 | hci_blacklist_clear(hdev); | ||
1282 | goto done; | ||
1283 | } | ||
1284 | |||
1285 | entry = hci_blacklist_lookup(hdev, bdaddr); | ||
1286 | if (!entry) { | ||
1287 | err = -ENOENT; | ||
1288 | goto done; | ||
1289 | } | ||
1290 | |||
1291 | list_del(&entry->list); | ||
1292 | kfree(entry); | ||
1293 | |||
1294 | done: | ||
1295 | hci_dev_unlock(hdev); | ||
1296 | return err; | ||
1297 | } | ||
1298 | |||
1299 | static void hci_clear_adv_cache(unsigned long arg) | ||
1300 | { | ||
1301 | struct hci_dev *hdev = (void *) arg; | ||
1302 | |||
1303 | hci_dev_lock(hdev); | ||
1304 | |||
1305 | hci_adv_entries_clear(hdev); | ||
1306 | |||
1307 | hci_dev_unlock(hdev); | ||
1308 | } | ||
1309 | |||
1310 | int hci_adv_entries_clear(struct hci_dev *hdev) | ||
1311 | { | ||
1312 | struct adv_entry *entry, *tmp; | ||
1313 | |||
1314 | list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) { | ||
1315 | list_del(&entry->list); | ||
1316 | kfree(entry); | ||
1317 | } | ||
1318 | |||
1319 | BT_DBG("%s adv cache cleared", hdev->name); | ||
1320 | |||
1321 | return 0; | ||
1322 | } | ||
1323 | |||
1324 | struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr) | ||
1325 | { | ||
1326 | struct adv_entry *entry; | ||
1327 | |||
1328 | list_for_each_entry(entry, &hdev->adv_entries, list) | ||
1329 | if (bacmp(bdaddr, &entry->bdaddr) == 0) | ||
1330 | return entry; | ||
1331 | |||
1332 | return NULL; | ||
1333 | } | ||
1334 | |||
1335 | static inline int is_connectable_adv(u8 evt_type) | ||
1336 | { | ||
1337 | if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND) | ||
1338 | return 1; | ||
1339 | |||
1340 | return 0; | ||
1341 | } | ||
1342 | |||
1343 | int hci_add_adv_entry(struct hci_dev *hdev, | ||
1344 | struct hci_ev_le_advertising_info *ev) | ||
1345 | { | ||
1346 | struct adv_entry *entry; | ||
1347 | |||
1348 | if (!is_connectable_adv(ev->evt_type)) | ||
1349 | return -EINVAL; | ||
1350 | |||
1351 | /* Only new entries should be added to adv_entries. So, if | ||
1352 | * bdaddr was found, don't add it. */ | ||
1353 | if (hci_find_adv_entry(hdev, &ev->bdaddr)) | ||
1354 | return 0; | ||
1355 | |||
1356 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | ||
1357 | if (!entry) | ||
1358 | return -ENOMEM; | ||
1359 | |||
1360 | bacpy(&entry->bdaddr, &ev->bdaddr); | ||
1361 | entry->bdaddr_type = ev->bdaddr_type; | ||
1362 | |||
1363 | list_add(&entry->list, &hdev->adv_entries); | ||
1364 | |||
1365 | BT_DBG("%s adv entry added: address %s type %u", hdev->name, | ||
1366 | batostr(&entry->bdaddr), entry->bdaddr_type); | ||
1367 | |||
1368 | return 0; | ||
1369 | } | ||
1370 | |||
1371 | static struct crypto_blkcipher *alloc_cypher(void) | ||
1372 | { | ||
1373 | if (enable_smp) | ||
1374 | return crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); | ||
1375 | |||
1376 | return ERR_PTR(-ENOTSUPP); | ||
1377 | } | ||
1378 | |||
1205 | /* Register HCI device */ | 1379 | /* Register HCI device */ |
1206 | int hci_register_dev(struct hci_dev *hdev) | 1380 | int hci_register_dev(struct hci_dev *hdev) |
1207 | { | 1381 | { |
@@ -1268,6 +1442,10 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1268 | 1442 | ||
1269 | INIT_LIST_HEAD(&hdev->remote_oob_data); | 1443 | INIT_LIST_HEAD(&hdev->remote_oob_data); |
1270 | 1444 | ||
1445 | INIT_LIST_HEAD(&hdev->adv_entries); | ||
1446 | setup_timer(&hdev->adv_timer, hci_clear_adv_cache, | ||
1447 | (unsigned long) hdev); | ||
1448 | |||
1271 | INIT_WORK(&hdev->power_on, hci_power_on); | 1449 | INIT_WORK(&hdev->power_on, hci_power_on); |
1272 | INIT_WORK(&hdev->power_off, hci_power_off); | 1450 | INIT_WORK(&hdev->power_off, hci_power_off); |
1273 | setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); | 1451 | setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); |
@@ -1282,6 +1460,11 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1282 | if (!hdev->workqueue) | 1460 | if (!hdev->workqueue) |
1283 | goto nomem; | 1461 | goto nomem; |
1284 | 1462 | ||
1463 | hdev->tfm = alloc_cypher(); | ||
1464 | if (IS_ERR(hdev->tfm)) | ||
1465 | BT_INFO("Failed to load transform for ecb(aes): %ld", | ||
1466 | PTR_ERR(hdev->tfm)); | ||
1467 | |||
1285 | hci_register_sysfs(hdev); | 1468 | hci_register_sysfs(hdev); |
1286 | 1469 | ||
1287 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, | 1470 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, |
@@ -1330,6 +1513,9 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1330 | !test_bit(HCI_SETUP, &hdev->flags)) | 1513 | !test_bit(HCI_SETUP, &hdev->flags)) |
1331 | mgmt_index_removed(hdev->id); | 1514 | mgmt_index_removed(hdev->id); |
1332 | 1515 | ||
1516 | if (!IS_ERR(hdev->tfm)) | ||
1517 | crypto_free_blkcipher(hdev->tfm); | ||
1518 | |||
1333 | hci_notify(hdev, HCI_DEV_UNREG); | 1519 | hci_notify(hdev, HCI_DEV_UNREG); |
1334 | 1520 | ||
1335 | if (hdev->rfkill) { | 1521 | if (hdev->rfkill) { |
@@ -1340,6 +1526,7 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1340 | hci_unregister_sysfs(hdev); | 1526 | hci_unregister_sysfs(hdev); |
1341 | 1527 | ||
1342 | hci_del_off_timer(hdev); | 1528 | hci_del_off_timer(hdev); |
1529 | del_timer(&hdev->adv_timer); | ||
1343 | 1530 | ||
1344 | destroy_workqueue(hdev->workqueue); | 1531 | destroy_workqueue(hdev->workqueue); |
1345 | 1532 | ||
@@ -1348,6 +1535,7 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1348 | hci_uuids_clear(hdev); | 1535 | hci_uuids_clear(hdev); |
1349 | hci_link_keys_clear(hdev); | 1536 | hci_link_keys_clear(hdev); |
1350 | hci_remote_oob_data_clear(hdev); | 1537 | hci_remote_oob_data_clear(hdev); |
1538 | hci_adv_entries_clear(hdev); | ||
1351 | hci_dev_unlock_bh(hdev); | 1539 | hci_dev_unlock_bh(hdev); |
1352 | 1540 | ||
1353 | __hci_dev_put(hdev); | 1541 | __hci_dev_put(hdev); |
@@ -1891,7 +2079,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev) | |||
1891 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { | 2079 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { |
1892 | BT_DBG("skb %p len %d", skb, skb->len); | 2080 | BT_DBG("skb %p len %d", skb, skb->len); |
1893 | 2081 | ||
1894 | hci_conn_enter_active_mode(conn); | 2082 | hci_conn_enter_active_mode(conn, bt_cb(skb)->force_active); |
1895 | 2083 | ||
1896 | hci_send_frame(skb); | 2084 | hci_send_frame(skb); |
1897 | hdev->acl_last_tx = jiffies; | 2085 | hdev->acl_last_tx = jiffies; |
@@ -2030,7 +2218,7 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2030 | if (conn) { | 2218 | if (conn) { |
2031 | register struct hci_proto *hp; | 2219 | register struct hci_proto *hp; |
2032 | 2220 | ||
2033 | hci_conn_enter_active_mode(conn); | 2221 | hci_conn_enter_active_mode(conn, bt_cb(skb)->force_active); |
2034 | 2222 | ||
2035 | /* Send to upper protocol */ | 2223 | /* Send to upper protocol */ |
2036 | hp = hci_proto[HCI_PROTO_L2CAP]; | 2224 | hp = hci_proto[HCI_PROTO_L2CAP]; |
@@ -2164,3 +2352,6 @@ static void hci_cmd_task(unsigned long arg) | |||
2164 | } | 2352 | } |
2165 | } | 2353 | } |
2166 | } | 2354 | } |
2355 | |||
2356 | module_param(enable_smp, bool, 0644); | ||
2357 | MODULE_PARM_DESC(enable_smp, "Enable SMP support (LE only)"); | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 77930aa522e3..ac2c5e89617c 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -841,6 +841,57 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | |||
841 | rp->randomizer, rp->status); | 841 | rp->randomizer, rp->status); |
842 | } | 842 | } |
843 | 843 | ||
844 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | ||
845 | struct sk_buff *skb) | ||
846 | { | ||
847 | struct hci_cp_le_set_scan_enable *cp; | ||
848 | __u8 status = *((__u8 *) skb->data); | ||
849 | |||
850 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
851 | |||
852 | if (status) | ||
853 | return; | ||
854 | |||
855 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); | ||
856 | if (!cp) | ||
857 | return; | ||
858 | |||
859 | hci_dev_lock(hdev); | ||
860 | |||
861 | if (cp->enable == 0x01) { | ||
862 | del_timer(&hdev->adv_timer); | ||
863 | hci_adv_entries_clear(hdev); | ||
864 | } else if (cp->enable == 0x00) { | ||
865 | mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT); | ||
866 | } | ||
867 | |||
868 | hci_dev_unlock(hdev); | ||
869 | } | ||
870 | |||
871 | static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
872 | { | ||
873 | struct hci_rp_le_ltk_reply *rp = (void *) skb->data; | ||
874 | |||
875 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
876 | |||
877 | if (rp->status) | ||
878 | return; | ||
879 | |||
880 | hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status); | ||
881 | } | ||
882 | |||
883 | static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
884 | { | ||
885 | struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data; | ||
886 | |||
887 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
888 | |||
889 | if (rp->status) | ||
890 | return; | ||
891 | |||
892 | hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); | ||
893 | } | ||
894 | |||
844 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 895 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
845 | { | 896 | { |
846 | BT_DBG("%s status 0x%x", hdev->name, status); | 897 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -1209,16 +1260,23 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) | |||
1209 | } else { | 1260 | } else { |
1210 | if (!conn) { | 1261 | if (!conn) { |
1211 | conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr); | 1262 | conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr); |
1212 | if (conn) | 1263 | if (conn) { |
1264 | conn->dst_type = cp->peer_addr_type; | ||
1213 | conn->out = 1; | 1265 | conn->out = 1; |
1214 | else | 1266 | } else { |
1215 | BT_ERR("No memory for new connection"); | 1267 | BT_ERR("No memory for new connection"); |
1268 | } | ||
1216 | } | 1269 | } |
1217 | } | 1270 | } |
1218 | 1271 | ||
1219 | hci_dev_unlock(hdev); | 1272 | hci_dev_unlock(hdev); |
1220 | } | 1273 | } |
1221 | 1274 | ||
1275 | static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) | ||
1276 | { | ||
1277 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
1278 | } | ||
1279 | |||
1222 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1280 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1223 | { | 1281 | { |
1224 | __u8 status = *((__u8 *) skb->data); | 1282 | __u8 status = *((__u8 *) skb->data); |
@@ -1462,51 +1520,58 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1462 | hci_dev_lock(hdev); | 1520 | hci_dev_lock(hdev); |
1463 | 1521 | ||
1464 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 1522 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
1465 | if (conn) { | 1523 | if (!conn) |
1466 | if (!ev->status) { | 1524 | goto unlock; |
1525 | |||
1526 | if (!ev->status) { | ||
1527 | if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) && | ||
1528 | test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) { | ||
1529 | BT_INFO("re-auth of legacy device is not possible."); | ||
1530 | } else { | ||
1467 | conn->link_mode |= HCI_LM_AUTH; | 1531 | conn->link_mode |= HCI_LM_AUTH; |
1468 | conn->sec_level = conn->pending_sec_level; | 1532 | conn->sec_level = conn->pending_sec_level; |
1469 | } else { | ||
1470 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | ||
1471 | } | 1533 | } |
1534 | } else { | ||
1535 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | ||
1536 | } | ||
1472 | 1537 | ||
1473 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1538 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
1539 | clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend); | ||
1474 | 1540 | ||
1475 | if (conn->state == BT_CONFIG) { | 1541 | if (conn->state == BT_CONFIG) { |
1476 | if (!ev->status && hdev->ssp_mode > 0 && | 1542 | if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) { |
1477 | conn->ssp_mode > 0) { | 1543 | struct hci_cp_set_conn_encrypt cp; |
1478 | struct hci_cp_set_conn_encrypt cp; | 1544 | cp.handle = ev->handle; |
1479 | cp.handle = ev->handle; | 1545 | cp.encrypt = 0x01; |
1480 | cp.encrypt = 0x01; | 1546 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), |
1481 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, | 1547 | &cp); |
1482 | sizeof(cp), &cp); | ||
1483 | } else { | ||
1484 | conn->state = BT_CONNECTED; | ||
1485 | hci_proto_connect_cfm(conn, ev->status); | ||
1486 | hci_conn_put(conn); | ||
1487 | } | ||
1488 | } else { | 1548 | } else { |
1489 | hci_auth_cfm(conn, ev->status); | 1549 | conn->state = BT_CONNECTED; |
1490 | 1550 | hci_proto_connect_cfm(conn, ev->status); | |
1491 | hci_conn_hold(conn); | ||
1492 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | ||
1493 | hci_conn_put(conn); | 1551 | hci_conn_put(conn); |
1494 | } | 1552 | } |
1553 | } else { | ||
1554 | hci_auth_cfm(conn, ev->status); | ||
1495 | 1555 | ||
1496 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { | 1556 | hci_conn_hold(conn); |
1497 | if (!ev->status) { | 1557 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
1498 | struct hci_cp_set_conn_encrypt cp; | 1558 | hci_conn_put(conn); |
1499 | cp.handle = ev->handle; | 1559 | } |
1500 | cp.encrypt = 0x01; | 1560 | |
1501 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, | 1561 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { |
1502 | sizeof(cp), &cp); | 1562 | if (!ev->status) { |
1503 | } else { | 1563 | struct hci_cp_set_conn_encrypt cp; |
1504 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | 1564 | cp.handle = ev->handle; |
1505 | hci_encrypt_cfm(conn, ev->status, 0x00); | 1565 | cp.encrypt = 0x01; |
1506 | } | 1566 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), |
1567 | &cp); | ||
1568 | } else { | ||
1569 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | ||
1570 | hci_encrypt_cfm(conn, ev->status, 0x00); | ||
1507 | } | 1571 | } |
1508 | } | 1572 | } |
1509 | 1573 | ||
1574 | unlock: | ||
1510 | hci_dev_unlock(hdev); | 1575 | hci_dev_unlock(hdev); |
1511 | } | 1576 | } |
1512 | 1577 | ||
@@ -1557,6 +1622,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * | |||
1557 | /* Encryption implies authentication */ | 1622 | /* Encryption implies authentication */ |
1558 | conn->link_mode |= HCI_LM_AUTH; | 1623 | conn->link_mode |= HCI_LM_AUTH; |
1559 | conn->link_mode |= HCI_LM_ENCRYPT; | 1624 | conn->link_mode |= HCI_LM_ENCRYPT; |
1625 | conn->sec_level = conn->pending_sec_level; | ||
1560 | } else | 1626 | } else |
1561 | conn->link_mode &= ~HCI_LM_ENCRYPT; | 1627 | conn->link_mode &= ~HCI_LM_ENCRYPT; |
1562 | } | 1628 | } |
@@ -1816,6 +1882,18 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1816 | hci_cc_user_confirm_neg_reply(hdev, skb); | 1882 | hci_cc_user_confirm_neg_reply(hdev, skb); |
1817 | break; | 1883 | break; |
1818 | 1884 | ||
1885 | case HCI_OP_LE_SET_SCAN_ENABLE: | ||
1886 | hci_cc_le_set_scan_enable(hdev, skb); | ||
1887 | break; | ||
1888 | |||
1889 | case HCI_OP_LE_LTK_REPLY: | ||
1890 | hci_cc_le_ltk_reply(hdev, skb); | ||
1891 | break; | ||
1892 | |||
1893 | case HCI_OP_LE_LTK_NEG_REPLY: | ||
1894 | hci_cc_le_ltk_neg_reply(hdev, skb); | ||
1895 | break; | ||
1896 | |||
1819 | default: | 1897 | default: |
1820 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 1898 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1821 | break; | 1899 | break; |
@@ -1894,6 +1972,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1894 | hci_cs_le_create_conn(hdev, ev->status); | 1972 | hci_cs_le_create_conn(hdev, ev->status); |
1895 | break; | 1973 | break; |
1896 | 1974 | ||
1975 | case HCI_OP_LE_START_ENC: | ||
1976 | hci_cs_le_start_enc(hdev, ev->status); | ||
1977 | break; | ||
1978 | |||
1897 | default: | 1979 | default: |
1898 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 1980 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1899 | break; | 1981 | break; |
@@ -2658,6 +2740,8 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
2658 | hci_dev_unlock(hdev); | 2740 | hci_dev_unlock(hdev); |
2659 | return; | 2741 | return; |
2660 | } | 2742 | } |
2743 | |||
2744 | conn->dst_type = ev->bdaddr_type; | ||
2661 | } | 2745 | } |
2662 | 2746 | ||
2663 | if (ev->status) { | 2747 | if (ev->status) { |
@@ -2670,6 +2754,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
2670 | 2754 | ||
2671 | mgmt_connected(hdev->id, &ev->bdaddr); | 2755 | mgmt_connected(hdev->id, &ev->bdaddr); |
2672 | 2756 | ||
2757 | conn->sec_level = BT_SECURITY_LOW; | ||
2673 | conn->handle = __le16_to_cpu(ev->handle); | 2758 | conn->handle = __le16_to_cpu(ev->handle); |
2674 | conn->state = BT_CONNECTED; | 2759 | conn->state = BT_CONNECTED; |
2675 | 2760 | ||
@@ -2682,6 +2767,49 @@ unlock: | |||
2682 | hci_dev_unlock(hdev); | 2767 | hci_dev_unlock(hdev); |
2683 | } | 2768 | } |
2684 | 2769 | ||
2770 | static inline void hci_le_adv_report_evt(struct hci_dev *hdev, | ||
2771 | struct sk_buff *skb) | ||
2772 | { | ||
2773 | struct hci_ev_le_advertising_info *ev; | ||
2774 | u8 num_reports; | ||
2775 | |||
2776 | num_reports = skb->data[0]; | ||
2777 | ev = (void *) &skb->data[1]; | ||
2778 | |||
2779 | hci_dev_lock(hdev); | ||
2780 | |||
2781 | hci_add_adv_entry(hdev, ev); | ||
2782 | |||
2783 | while (--num_reports) { | ||
2784 | ev = (void *) (ev->data + ev->length + 1); | ||
2785 | hci_add_adv_entry(hdev, ev); | ||
2786 | } | ||
2787 | |||
2788 | hci_dev_unlock(hdev); | ||
2789 | } | ||
2790 | |||
2791 | static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, | ||
2792 | struct sk_buff *skb) | ||
2793 | { | ||
2794 | struct hci_ev_le_ltk_req *ev = (void *) skb->data; | ||
2795 | struct hci_cp_le_ltk_reply cp; | ||
2796 | struct hci_conn *conn; | ||
2797 | |||
2798 | BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle)); | ||
2799 | |||
2800 | hci_dev_lock(hdev); | ||
2801 | |||
2802 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
2803 | |||
2804 | memset(&cp, 0, sizeof(cp)); | ||
2805 | cp.handle = cpu_to_le16(conn->handle); | ||
2806 | memcpy(cp.ltk, conn->ltk, sizeof(conn->ltk)); | ||
2807 | |||
2808 | hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); | ||
2809 | |||
2810 | hci_dev_unlock(hdev); | ||
2811 | } | ||
2812 | |||
2685 | static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2813 | static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) |
2686 | { | 2814 | { |
2687 | struct hci_ev_le_meta *le_ev = (void *) skb->data; | 2815 | struct hci_ev_le_meta *le_ev = (void *) skb->data; |
@@ -2693,6 +2821,14 @@ static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2693 | hci_le_conn_complete_evt(hdev, skb); | 2821 | hci_le_conn_complete_evt(hdev, skb); |
2694 | break; | 2822 | break; |
2695 | 2823 | ||
2824 | case HCI_EV_LE_ADVERTISING_REPORT: | ||
2825 | hci_le_adv_report_evt(hdev, skb); | ||
2826 | break; | ||
2827 | |||
2828 | case HCI_EV_LE_LTK_REQ: | ||
2829 | hci_le_ltk_request_evt(hdev, skb); | ||
2830 | break; | ||
2831 | |||
2696 | default: | 2832 | default: |
2697 | break; | 2833 | break; |
2698 | } | 2834 | } |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 295e4a88fff8..ff02cf5e77cc 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -180,82 +180,24 @@ static int hci_sock_release(struct socket *sock) | |||
180 | return 0; | 180 | return 0; |
181 | } | 181 | } |
182 | 182 | ||
183 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) | 183 | static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg) |
184 | { | ||
185 | struct list_head *p; | ||
186 | |||
187 | list_for_each(p, &hdev->blacklist) { | ||
188 | struct bdaddr_list *b; | ||
189 | |||
190 | b = list_entry(p, struct bdaddr_list, list); | ||
191 | |||
192 | if (bacmp(bdaddr, &b->bdaddr) == 0) | ||
193 | return b; | ||
194 | } | ||
195 | |||
196 | return NULL; | ||
197 | } | ||
198 | |||
199 | static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg) | ||
200 | { | 184 | { |
201 | bdaddr_t bdaddr; | 185 | bdaddr_t bdaddr; |
202 | struct bdaddr_list *entry; | ||
203 | 186 | ||
204 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) | 187 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) |
205 | return -EFAULT; | 188 | return -EFAULT; |
206 | 189 | ||
207 | if (bacmp(&bdaddr, BDADDR_ANY) == 0) | 190 | return hci_blacklist_add(hdev, &bdaddr); |
208 | return -EBADF; | ||
209 | |||
210 | if (hci_blacklist_lookup(hdev, &bdaddr)) | ||
211 | return -EEXIST; | ||
212 | |||
213 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); | ||
214 | if (!entry) | ||
215 | return -ENOMEM; | ||
216 | |||
217 | bacpy(&entry->bdaddr, &bdaddr); | ||
218 | |||
219 | list_add(&entry->list, &hdev->blacklist); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | int hci_blacklist_clear(struct hci_dev *hdev) | ||
225 | { | ||
226 | struct list_head *p, *n; | ||
227 | |||
228 | list_for_each_safe(p, n, &hdev->blacklist) { | ||
229 | struct bdaddr_list *b; | ||
230 | |||
231 | b = list_entry(p, struct bdaddr_list, list); | ||
232 | |||
233 | list_del(p); | ||
234 | kfree(b); | ||
235 | } | ||
236 | |||
237 | return 0; | ||
238 | } | 191 | } |
239 | 192 | ||
240 | static int hci_blacklist_del(struct hci_dev *hdev, void __user *arg) | 193 | static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) |
241 | { | 194 | { |
242 | bdaddr_t bdaddr; | 195 | bdaddr_t bdaddr; |
243 | struct bdaddr_list *entry; | ||
244 | 196 | ||
245 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) | 197 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) |
246 | return -EFAULT; | 198 | return -EFAULT; |
247 | 199 | ||
248 | if (bacmp(&bdaddr, BDADDR_ANY) == 0) | 200 | return hci_blacklist_del(hdev, &bdaddr); |
249 | return hci_blacklist_clear(hdev); | ||
250 | |||
251 | entry = hci_blacklist_lookup(hdev, &bdaddr); | ||
252 | if (!entry) | ||
253 | return -ENOENT; | ||
254 | |||
255 | list_del(&entry->list); | ||
256 | kfree(entry); | ||
257 | |||
258 | return 0; | ||
259 | } | 201 | } |
260 | 202 | ||
261 | /* Ioctls that require bound socket */ | 203 | /* Ioctls that require bound socket */ |
@@ -290,12 +232,12 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign | |||
290 | case HCIBLOCKADDR: | 232 | case HCIBLOCKADDR: |
291 | if (!capable(CAP_NET_ADMIN)) | 233 | if (!capable(CAP_NET_ADMIN)) |
292 | return -EACCES; | 234 | return -EACCES; |
293 | return hci_blacklist_add(hdev, (void __user *) arg); | 235 | return hci_sock_blacklist_add(hdev, (void __user *) arg); |
294 | 236 | ||
295 | case HCIUNBLOCKADDR: | 237 | case HCIUNBLOCKADDR: |
296 | if (!capable(CAP_NET_ADMIN)) | 238 | if (!capable(CAP_NET_ADMIN)) |
297 | return -EACCES; | 239 | return -EACCES; |
298 | return hci_blacklist_del(hdev, (void __user *) arg); | 240 | return hci_sock_blacklist_del(hdev, (void __user *) arg); |
299 | 241 | ||
300 | default: | 242 | default: |
301 | if (hdev->ioctl) | 243 | if (hdev->ioctl) |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index e64a1c2df238..9ec9c8c5eb5e 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <net/bluetooth/bluetooth.h> | 54 | #include <net/bluetooth/bluetooth.h> |
55 | #include <net/bluetooth/hci_core.h> | 55 | #include <net/bluetooth/hci_core.h> |
56 | #include <net/bluetooth/l2cap.h> | 56 | #include <net/bluetooth/l2cap.h> |
57 | #include <net/bluetooth/smp.h> | ||
57 | 58 | ||
58 | int disable_ertm; | 59 | int disable_ertm; |
59 | 60 | ||
@@ -62,18 +63,34 @@ static u8 l2cap_fixed_chan[8] = { 0x02, }; | |||
62 | 63 | ||
63 | static struct workqueue_struct *_busy_wq; | 64 | static struct workqueue_struct *_busy_wq; |
64 | 65 | ||
65 | LIST_HEAD(chan_list); | 66 | static LIST_HEAD(chan_list); |
66 | DEFINE_RWLOCK(chan_list_lock); | 67 | static DEFINE_RWLOCK(chan_list_lock); |
67 | 68 | ||
68 | static void l2cap_busy_work(struct work_struct *work); | 69 | static void l2cap_busy_work(struct work_struct *work); |
69 | 70 | ||
70 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 71 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
71 | u8 code, u8 ident, u16 dlen, void *data); | 72 | u8 code, u8 ident, u16 dlen, void *data); |
73 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, | ||
74 | void *data); | ||
72 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); | 75 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); |
76 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, | ||
77 | struct l2cap_chan *chan, int err); | ||
73 | 78 | ||
74 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); | 79 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); |
75 | 80 | ||
76 | /* ---- L2CAP channels ---- */ | 81 | /* ---- L2CAP channels ---- */ |
82 | |||
83 | static inline void chan_hold(struct l2cap_chan *c) | ||
84 | { | ||
85 | atomic_inc(&c->refcnt); | ||
86 | } | ||
87 | |||
88 | static inline void chan_put(struct l2cap_chan *c) | ||
89 | { | ||
90 | if (atomic_dec_and_test(&c->refcnt)) | ||
91 | kfree(c); | ||
92 | } | ||
93 | |||
77 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) | 94 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) |
78 | { | 95 | { |
79 | struct l2cap_chan *c; | 96 | struct l2cap_chan *c; |
@@ -204,6 +221,62 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
204 | return 0; | 221 | return 0; |
205 | } | 222 | } |
206 | 223 | ||
224 | static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) | ||
225 | { | ||
226 | BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->state, timeout); | ||
227 | |||
228 | if (!mod_timer(timer, jiffies + timeout)) | ||
229 | chan_hold(chan); | ||
230 | } | ||
231 | |||
232 | static void l2cap_clear_timer(struct l2cap_chan *chan, struct timer_list *timer) | ||
233 | { | ||
234 | BT_DBG("chan %p state %d", chan, chan->state); | ||
235 | |||
236 | if (timer_pending(timer) && del_timer(timer)) | ||
237 | chan_put(chan); | ||
238 | } | ||
239 | |||
240 | static void l2cap_state_change(struct l2cap_chan *chan, int state) | ||
241 | { | ||
242 | chan->state = state; | ||
243 | chan->ops->state_change(chan->data, state); | ||
244 | } | ||
245 | |||
246 | static void l2cap_chan_timeout(unsigned long arg) | ||
247 | { | ||
248 | struct l2cap_chan *chan = (struct l2cap_chan *) arg; | ||
249 | struct sock *sk = chan->sk; | ||
250 | int reason; | ||
251 | |||
252 | BT_DBG("chan %p state %d", chan, chan->state); | ||
253 | |||
254 | bh_lock_sock(sk); | ||
255 | |||
256 | if (sock_owned_by_user(sk)) { | ||
257 | /* sk is owned by user. Try again later */ | ||
258 | __set_chan_timer(chan, HZ / 5); | ||
259 | bh_unlock_sock(sk); | ||
260 | chan_put(chan); | ||
261 | return; | ||
262 | } | ||
263 | |||
264 | if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG) | ||
265 | reason = ECONNREFUSED; | ||
266 | else if (chan->state == BT_CONNECT && | ||
267 | chan->sec_level != BT_SECURITY_SDP) | ||
268 | reason = ECONNREFUSED; | ||
269 | else | ||
270 | reason = ETIMEDOUT; | ||
271 | |||
272 | l2cap_chan_close(chan, reason); | ||
273 | |||
274 | bh_unlock_sock(sk); | ||
275 | |||
276 | chan->ops->close(chan->data); | ||
277 | chan_put(chan); | ||
278 | } | ||
279 | |||
207 | struct l2cap_chan *l2cap_chan_create(struct sock *sk) | 280 | struct l2cap_chan *l2cap_chan_create(struct sock *sk) |
208 | { | 281 | { |
209 | struct l2cap_chan *chan; | 282 | struct l2cap_chan *chan; |
@@ -218,6 +291,12 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk) | |||
218 | list_add(&chan->global_l, &chan_list); | 291 | list_add(&chan->global_l, &chan_list); |
219 | write_unlock_bh(&chan_list_lock); | 292 | write_unlock_bh(&chan_list_lock); |
220 | 293 | ||
294 | setup_timer(&chan->chan_timer, l2cap_chan_timeout, (unsigned long) chan); | ||
295 | |||
296 | chan->state = BT_OPEN; | ||
297 | |||
298 | atomic_set(&chan->refcnt, 1); | ||
299 | |||
221 | return chan; | 300 | return chan; |
222 | } | 301 | } |
223 | 302 | ||
@@ -227,13 +306,11 @@ void l2cap_chan_destroy(struct l2cap_chan *chan) | |||
227 | list_del(&chan->global_l); | 306 | list_del(&chan->global_l); |
228 | write_unlock_bh(&chan_list_lock); | 307 | write_unlock_bh(&chan_list_lock); |
229 | 308 | ||
230 | kfree(chan); | 309 | chan_put(chan); |
231 | } | 310 | } |
232 | 311 | ||
233 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 312 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
234 | { | 313 | { |
235 | struct sock *sk = chan->sk; | ||
236 | |||
237 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, | 314 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, |
238 | chan->psm, chan->dcid); | 315 | chan->psm, chan->dcid); |
239 | 316 | ||
@@ -241,7 +318,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
241 | 318 | ||
242 | chan->conn = conn; | 319 | chan->conn = conn; |
243 | 320 | ||
244 | if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) { | 321 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) { |
245 | if (conn->hcon->type == LE_LINK) { | 322 | if (conn->hcon->type == LE_LINK) { |
246 | /* LE connection */ | 323 | /* LE connection */ |
247 | chan->omtu = L2CAP_LE_DEFAULT_MTU; | 324 | chan->omtu = L2CAP_LE_DEFAULT_MTU; |
@@ -252,7 +329,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
252 | chan->scid = l2cap_alloc_cid(conn); | 329 | chan->scid = l2cap_alloc_cid(conn); |
253 | chan->omtu = L2CAP_DEFAULT_MTU; | 330 | chan->omtu = L2CAP_DEFAULT_MTU; |
254 | } | 331 | } |
255 | } else if (sk->sk_type == SOCK_DGRAM) { | 332 | } else if (chan->chan_type == L2CAP_CHAN_CONN_LESS) { |
256 | /* Connectionless socket */ | 333 | /* Connectionless socket */ |
257 | chan->scid = L2CAP_CID_CONN_LESS; | 334 | chan->scid = L2CAP_CID_CONN_LESS; |
258 | chan->dcid = L2CAP_CID_CONN_LESS; | 335 | chan->dcid = L2CAP_CID_CONN_LESS; |
@@ -264,20 +341,20 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
264 | chan->omtu = L2CAP_DEFAULT_MTU; | 341 | chan->omtu = L2CAP_DEFAULT_MTU; |
265 | } | 342 | } |
266 | 343 | ||
267 | sock_hold(sk); | 344 | chan_hold(chan); |
268 | 345 | ||
269 | list_add(&chan->list, &conn->chan_l); | 346 | list_add(&chan->list, &conn->chan_l); |
270 | } | 347 | } |
271 | 348 | ||
272 | /* Delete channel. | 349 | /* Delete channel. |
273 | * Must be called on the locked socket. */ | 350 | * Must be called on the locked socket. */ |
274 | void l2cap_chan_del(struct l2cap_chan *chan, int err) | 351 | static void l2cap_chan_del(struct l2cap_chan *chan, int err) |
275 | { | 352 | { |
276 | struct sock *sk = chan->sk; | 353 | struct sock *sk = chan->sk; |
277 | struct l2cap_conn *conn = chan->conn; | 354 | struct l2cap_conn *conn = chan->conn; |
278 | struct sock *parent = bt_sk(sk)->parent; | 355 | struct sock *parent = bt_sk(sk)->parent; |
279 | 356 | ||
280 | l2cap_sock_clear_timer(sk); | 357 | __clear_chan_timer(chan); |
281 | 358 | ||
282 | BT_DBG("chan %p, conn %p, err %d", chan, conn, err); | 359 | BT_DBG("chan %p, conn %p, err %d", chan, conn, err); |
283 | 360 | ||
@@ -286,13 +363,13 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
286 | write_lock_bh(&conn->chan_lock); | 363 | write_lock_bh(&conn->chan_lock); |
287 | list_del(&chan->list); | 364 | list_del(&chan->list); |
288 | write_unlock_bh(&conn->chan_lock); | 365 | write_unlock_bh(&conn->chan_lock); |
289 | __sock_put(sk); | 366 | chan_put(chan); |
290 | 367 | ||
291 | chan->conn = NULL; | 368 | chan->conn = NULL; |
292 | hci_conn_put(conn->hcon); | 369 | hci_conn_put(conn->hcon); |
293 | } | 370 | } |
294 | 371 | ||
295 | sk->sk_state = BT_CLOSED; | 372 | l2cap_state_change(chan, BT_CLOSED); |
296 | sock_set_flag(sk, SOCK_ZAPPED); | 373 | sock_set_flag(sk, SOCK_ZAPPED); |
297 | 374 | ||
298 | if (err) | 375 | if (err) |
@@ -304,8 +381,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
304 | } else | 381 | } else |
305 | sk->sk_state_change(sk); | 382 | sk->sk_state_change(sk); |
306 | 383 | ||
307 | if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE && | 384 | if (!(test_bit(CONF_OUTPUT_DONE, &chan->conf_state) && |
308 | chan->conf_state & L2CAP_CONF_INPUT_DONE)) | 385 | test_bit(CONF_INPUT_DONE, &chan->conf_state))) |
309 | return; | 386 | return; |
310 | 387 | ||
311 | skb_queue_purge(&chan->tx_q); | 388 | skb_queue_purge(&chan->tx_q); |
@@ -313,9 +390,9 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
313 | if (chan->mode == L2CAP_MODE_ERTM) { | 390 | if (chan->mode == L2CAP_MODE_ERTM) { |
314 | struct srej_list *l, *tmp; | 391 | struct srej_list *l, *tmp; |
315 | 392 | ||
316 | del_timer(&chan->retrans_timer); | 393 | __clear_retrans_timer(chan); |
317 | del_timer(&chan->monitor_timer); | 394 | __clear_monitor_timer(chan); |
318 | del_timer(&chan->ack_timer); | 395 | __clear_ack_timer(chan); |
319 | 396 | ||
320 | skb_queue_purge(&chan->srej_q); | 397 | skb_queue_purge(&chan->srej_q); |
321 | skb_queue_purge(&chan->busy_q); | 398 | skb_queue_purge(&chan->busy_q); |
@@ -327,11 +404,86 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
327 | } | 404 | } |
328 | } | 405 | } |
329 | 406 | ||
330 | static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) | 407 | static void l2cap_chan_cleanup_listen(struct sock *parent) |
331 | { | 408 | { |
409 | struct sock *sk; | ||
410 | |||
411 | BT_DBG("parent %p", parent); | ||
412 | |||
413 | /* Close not yet accepted channels */ | ||
414 | while ((sk = bt_accept_dequeue(parent, NULL))) { | ||
415 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
416 | __clear_chan_timer(chan); | ||
417 | lock_sock(sk); | ||
418 | l2cap_chan_close(chan, ECONNRESET); | ||
419 | release_sock(sk); | ||
420 | chan->ops->close(chan->data); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | void l2cap_chan_close(struct l2cap_chan *chan, int reason) | ||
425 | { | ||
426 | struct l2cap_conn *conn = chan->conn; | ||
332 | struct sock *sk = chan->sk; | 427 | struct sock *sk = chan->sk; |
333 | 428 | ||
334 | if (sk->sk_type == SOCK_RAW) { | 429 | BT_DBG("chan %p state %d socket %p", chan, chan->state, sk->sk_socket); |
430 | |||
431 | switch (chan->state) { | ||
432 | case BT_LISTEN: | ||
433 | l2cap_chan_cleanup_listen(sk); | ||
434 | |||
435 | l2cap_state_change(chan, BT_CLOSED); | ||
436 | sock_set_flag(sk, SOCK_ZAPPED); | ||
437 | break; | ||
438 | |||
439 | case BT_CONNECTED: | ||
440 | case BT_CONFIG: | ||
441 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && | ||
442 | conn->hcon->type == ACL_LINK) { | ||
443 | __clear_chan_timer(chan); | ||
444 | __set_chan_timer(chan, sk->sk_sndtimeo); | ||
445 | l2cap_send_disconn_req(conn, chan, reason); | ||
446 | } else | ||
447 | l2cap_chan_del(chan, reason); | ||
448 | break; | ||
449 | |||
450 | case BT_CONNECT2: | ||
451 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && | ||
452 | conn->hcon->type == ACL_LINK) { | ||
453 | struct l2cap_conn_rsp rsp; | ||
454 | __u16 result; | ||
455 | |||
456 | if (bt_sk(sk)->defer_setup) | ||
457 | result = L2CAP_CR_SEC_BLOCK; | ||
458 | else | ||
459 | result = L2CAP_CR_BAD_PSM; | ||
460 | l2cap_state_change(chan, BT_DISCONN); | ||
461 | |||
462 | rsp.scid = cpu_to_le16(chan->dcid); | ||
463 | rsp.dcid = cpu_to_le16(chan->scid); | ||
464 | rsp.result = cpu_to_le16(result); | ||
465 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
466 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | ||
467 | sizeof(rsp), &rsp); | ||
468 | } | ||
469 | |||
470 | l2cap_chan_del(chan, reason); | ||
471 | break; | ||
472 | |||
473 | case BT_CONNECT: | ||
474 | case BT_DISCONN: | ||
475 | l2cap_chan_del(chan, reason); | ||
476 | break; | ||
477 | |||
478 | default: | ||
479 | sock_set_flag(sk, SOCK_ZAPPED); | ||
480 | break; | ||
481 | } | ||
482 | } | ||
483 | |||
484 | static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) | ||
485 | { | ||
486 | if (chan->chan_type == L2CAP_CHAN_RAW) { | ||
335 | switch (chan->sec_level) { | 487 | switch (chan->sec_level) { |
336 | case BT_SECURITY_HIGH: | 488 | case BT_SECURITY_HIGH: |
337 | return HCI_AT_DEDICATED_BONDING_MITM; | 489 | return HCI_AT_DEDICATED_BONDING_MITM; |
@@ -371,7 +523,7 @@ static inline int l2cap_check_security(struct l2cap_chan *chan) | |||
371 | return hci_conn_security(conn->hcon, chan->sec_level, auth_type); | 523 | return hci_conn_security(conn->hcon, chan->sec_level, auth_type); |
372 | } | 524 | } |
373 | 525 | ||
374 | u8 l2cap_get_ident(struct l2cap_conn *conn) | 526 | static u8 l2cap_get_ident(struct l2cap_conn *conn) |
375 | { | 527 | { |
376 | u8 id; | 528 | u8 id; |
377 | 529 | ||
@@ -393,7 +545,7 @@ u8 l2cap_get_ident(struct l2cap_conn *conn) | |||
393 | return id; | 545 | return id; |
394 | } | 546 | } |
395 | 547 | ||
396 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) | 548 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) |
397 | { | 549 | { |
398 | struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); | 550 | struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); |
399 | u8 flags; | 551 | u8 flags; |
@@ -408,6 +560,8 @@ void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *d | |||
408 | else | 560 | else |
409 | flags = ACL_START; | 561 | flags = ACL_START; |
410 | 562 | ||
563 | bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON; | ||
564 | |||
411 | hci_send_acl(conn->hcon, skb, flags); | 565 | hci_send_acl(conn->hcon, skb, flags); |
412 | } | 566 | } |
413 | 567 | ||
@@ -415,13 +569,11 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
415 | { | 569 | { |
416 | struct sk_buff *skb; | 570 | struct sk_buff *skb; |
417 | struct l2cap_hdr *lh; | 571 | struct l2cap_hdr *lh; |
418 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
419 | struct l2cap_conn *conn = chan->conn; | 572 | struct l2cap_conn *conn = chan->conn; |
420 | struct sock *sk = (struct sock *)pi; | ||
421 | int count, hlen = L2CAP_HDR_SIZE + 2; | 573 | int count, hlen = L2CAP_HDR_SIZE + 2; |
422 | u8 flags; | 574 | u8 flags; |
423 | 575 | ||
424 | if (sk->sk_state != BT_CONNECTED) | 576 | if (chan->state != BT_CONNECTED) |
425 | return; | 577 | return; |
426 | 578 | ||
427 | if (chan->fcs == L2CAP_FCS_CRC16) | 579 | if (chan->fcs == L2CAP_FCS_CRC16) |
@@ -432,15 +584,11 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
432 | count = min_t(unsigned int, conn->mtu, hlen); | 584 | count = min_t(unsigned int, conn->mtu, hlen); |
433 | control |= L2CAP_CTRL_FRAME_TYPE; | 585 | control |= L2CAP_CTRL_FRAME_TYPE; |
434 | 586 | ||
435 | if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { | 587 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
436 | control |= L2CAP_CTRL_FINAL; | 588 | control |= L2CAP_CTRL_FINAL; |
437 | chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; | ||
438 | } | ||
439 | 589 | ||
440 | if (chan->conn_state & L2CAP_CONN_SEND_PBIT) { | 590 | if (test_and_clear_bit(CONN_SEND_PBIT, &chan->conn_state)) |
441 | control |= L2CAP_CTRL_POLL; | 591 | control |= L2CAP_CTRL_POLL; |
442 | chan->conn_state &= ~L2CAP_CONN_SEND_PBIT; | ||
443 | } | ||
444 | 592 | ||
445 | skb = bt_skb_alloc(count, GFP_ATOMIC); | 593 | skb = bt_skb_alloc(count, GFP_ATOMIC); |
446 | if (!skb) | 594 | if (!skb) |
@@ -461,14 +609,16 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
461 | else | 609 | else |
462 | flags = ACL_START; | 610 | flags = ACL_START; |
463 | 611 | ||
612 | bt_cb(skb)->force_active = chan->force_active; | ||
613 | |||
464 | hci_send_acl(chan->conn->hcon, skb, flags); | 614 | hci_send_acl(chan->conn->hcon, skb, flags); |
465 | } | 615 | } |
466 | 616 | ||
467 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) | 617 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) |
468 | { | 618 | { |
469 | if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 619 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
470 | control |= L2CAP_SUPER_RCV_NOT_READY; | 620 | control |= L2CAP_SUPER_RCV_NOT_READY; |
471 | chan->conn_state |= L2CAP_CONN_RNR_SENT; | 621 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
472 | } else | 622 | } else |
473 | control |= L2CAP_SUPER_RCV_READY; | 623 | control |= L2CAP_SUPER_RCV_READY; |
474 | 624 | ||
@@ -479,7 +629,7 @@ static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) | |||
479 | 629 | ||
480 | static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) | 630 | static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) |
481 | { | 631 | { |
482 | return !(chan->conf_state & L2CAP_CONF_CONNECT_PEND); | 632 | return !test_bit(CONF_CONNECT_PEND, &chan->conf_state); |
483 | } | 633 | } |
484 | 634 | ||
485 | static void l2cap_do_start(struct l2cap_chan *chan) | 635 | static void l2cap_do_start(struct l2cap_chan *chan) |
@@ -497,7 +647,7 @@ static void l2cap_do_start(struct l2cap_chan *chan) | |||
497 | req.psm = chan->psm; | 647 | req.psm = chan->psm; |
498 | 648 | ||
499 | chan->ident = l2cap_get_ident(conn); | 649 | chan->ident = l2cap_get_ident(conn); |
500 | chan->conf_state |= L2CAP_CONF_CONNECT_PEND; | 650 | set_bit(CONF_CONNECT_PEND, &chan->conf_state); |
501 | 651 | ||
502 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, | 652 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, |
503 | sizeof(req), &req); | 653 | sizeof(req), &req); |
@@ -533,7 +683,7 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | |||
533 | } | 683 | } |
534 | } | 684 | } |
535 | 685 | ||
536 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) | 686 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) |
537 | { | 687 | { |
538 | struct sock *sk; | 688 | struct sock *sk; |
539 | struct l2cap_disconn_req req; | 689 | struct l2cap_disconn_req req; |
@@ -544,9 +694,9 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, in | |||
544 | sk = chan->sk; | 694 | sk = chan->sk; |
545 | 695 | ||
546 | if (chan->mode == L2CAP_MODE_ERTM) { | 696 | if (chan->mode == L2CAP_MODE_ERTM) { |
547 | del_timer(&chan->retrans_timer); | 697 | __clear_retrans_timer(chan); |
548 | del_timer(&chan->monitor_timer); | 698 | __clear_monitor_timer(chan); |
549 | del_timer(&chan->ack_timer); | 699 | __clear_ack_timer(chan); |
550 | } | 700 | } |
551 | 701 | ||
552 | req.dcid = cpu_to_le16(chan->dcid); | 702 | req.dcid = cpu_to_le16(chan->dcid); |
@@ -554,7 +704,7 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, in | |||
554 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | 704 | l2cap_send_cmd(conn, l2cap_get_ident(conn), |
555 | L2CAP_DISCONN_REQ, sizeof(req), &req); | 705 | L2CAP_DISCONN_REQ, sizeof(req), &req); |
556 | 706 | ||
557 | sk->sk_state = BT_DISCONN; | 707 | l2cap_state_change(chan, BT_DISCONN); |
558 | sk->sk_err = err; | 708 | sk->sk_err = err; |
559 | } | 709 | } |
560 | 710 | ||
@@ -572,13 +722,12 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
572 | 722 | ||
573 | bh_lock_sock(sk); | 723 | bh_lock_sock(sk); |
574 | 724 | ||
575 | if (sk->sk_type != SOCK_SEQPACKET && | 725 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
576 | sk->sk_type != SOCK_STREAM) { | ||
577 | bh_unlock_sock(sk); | 726 | bh_unlock_sock(sk); |
578 | continue; | 727 | continue; |
579 | } | 728 | } |
580 | 729 | ||
581 | if (sk->sk_state == BT_CONNECT) { | 730 | if (chan->state == BT_CONNECT) { |
582 | struct l2cap_conn_req req; | 731 | struct l2cap_conn_req req; |
583 | 732 | ||
584 | if (!l2cap_check_security(chan) || | 733 | if (!l2cap_check_security(chan) || |
@@ -587,14 +736,13 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
587 | continue; | 736 | continue; |
588 | } | 737 | } |
589 | 738 | ||
590 | if (!l2cap_mode_supported(chan->mode, | 739 | if (!l2cap_mode_supported(chan->mode, conn->feat_mask) |
591 | conn->feat_mask) | 740 | && test_bit(CONF_STATE2_DEVICE, |
592 | && chan->conf_state & | 741 | &chan->conf_state)) { |
593 | L2CAP_CONF_STATE2_DEVICE) { | 742 | /* l2cap_chan_close() calls list_del(chan) |
594 | /* __l2cap_sock_close() calls list_del(chan) | ||
595 | * so release the lock */ | 743 | * so release the lock */ |
596 | read_unlock_bh(&conn->chan_lock); | 744 | read_unlock_bh(&conn->chan_lock); |
597 | __l2cap_sock_close(sk, ECONNRESET); | 745 | l2cap_chan_close(chan, ECONNRESET); |
598 | read_lock_bh(&conn->chan_lock); | 746 | read_lock_bh(&conn->chan_lock); |
599 | bh_unlock_sock(sk); | 747 | bh_unlock_sock(sk); |
600 | continue; | 748 | continue; |
@@ -604,12 +752,12 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
604 | req.psm = chan->psm; | 752 | req.psm = chan->psm; |
605 | 753 | ||
606 | chan->ident = l2cap_get_ident(conn); | 754 | chan->ident = l2cap_get_ident(conn); |
607 | chan->conf_state |= L2CAP_CONF_CONNECT_PEND; | 755 | set_bit(CONF_CONNECT_PEND, &chan->conf_state); |
608 | 756 | ||
609 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, | 757 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, |
610 | sizeof(req), &req); | 758 | sizeof(req), &req); |
611 | 759 | ||
612 | } else if (sk->sk_state == BT_CONNECT2) { | 760 | } else if (chan->state == BT_CONNECT2) { |
613 | struct l2cap_conn_rsp rsp; | 761 | struct l2cap_conn_rsp rsp; |
614 | char buf[128]; | 762 | char buf[128]; |
615 | rsp.scid = cpu_to_le16(chan->dcid); | 763 | rsp.scid = cpu_to_le16(chan->dcid); |
@@ -623,7 +771,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
623 | parent->sk_data_ready(parent, 0); | 771 | parent->sk_data_ready(parent, 0); |
624 | 772 | ||
625 | } else { | 773 | } else { |
626 | sk->sk_state = BT_CONFIG; | 774 | l2cap_state_change(chan, BT_CONFIG); |
627 | rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); | 775 | rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); |
628 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | 776 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); |
629 | } | 777 | } |
@@ -635,13 +783,13 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
635 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 783 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
636 | sizeof(rsp), &rsp); | 784 | sizeof(rsp), &rsp); |
637 | 785 | ||
638 | if (chan->conf_state & L2CAP_CONF_REQ_SENT || | 786 | if (test_bit(CONF_REQ_SENT, &chan->conf_state) || |
639 | rsp.result != L2CAP_CR_SUCCESS) { | 787 | rsp.result != L2CAP_CR_SUCCESS) { |
640 | bh_unlock_sock(sk); | 788 | bh_unlock_sock(sk); |
641 | continue; | 789 | continue; |
642 | } | 790 | } |
643 | 791 | ||
644 | chan->conf_state |= L2CAP_CONF_REQ_SENT; | 792 | set_bit(CONF_REQ_SENT, &chan->conf_state); |
645 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 793 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
646 | l2cap_build_conf_req(chan, buf), buf); | 794 | l2cap_build_conf_req(chan, buf), buf); |
647 | chan->num_conf_req++; | 795 | chan->num_conf_req++; |
@@ -665,7 +813,7 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdadd | |||
665 | list_for_each_entry(c, &chan_list, global_l) { | 813 | list_for_each_entry(c, &chan_list, global_l) { |
666 | struct sock *sk = c->sk; | 814 | struct sock *sk = c->sk; |
667 | 815 | ||
668 | if (state && sk->sk_state != state) | 816 | if (state && c->state != state) |
669 | continue; | 817 | continue; |
670 | 818 | ||
671 | if (c->scid == cid) { | 819 | if (c->scid == cid) { |
@@ -709,24 +857,16 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
709 | goto clean; | 857 | goto clean; |
710 | } | 858 | } |
711 | 859 | ||
712 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); | 860 | chan = pchan->ops->new_connection(pchan->data); |
713 | if (!sk) | 861 | if (!chan) |
714 | goto clean; | ||
715 | |||
716 | chan = l2cap_chan_create(sk); | ||
717 | if (!chan) { | ||
718 | l2cap_sock_kill(sk); | ||
719 | goto clean; | 862 | goto clean; |
720 | } | ||
721 | 863 | ||
722 | l2cap_pi(sk)->chan = chan; | 864 | sk = chan->sk; |
723 | 865 | ||
724 | write_lock_bh(&conn->chan_lock); | 866 | write_lock_bh(&conn->chan_lock); |
725 | 867 | ||
726 | hci_conn_hold(conn->hcon); | 868 | hci_conn_hold(conn->hcon); |
727 | 869 | ||
728 | l2cap_sock_init(sk, parent); | ||
729 | |||
730 | bacpy(&bt_sk(sk)->src, conn->src); | 870 | bacpy(&bt_sk(sk)->src, conn->src); |
731 | bacpy(&bt_sk(sk)->dst, conn->dst); | 871 | bacpy(&bt_sk(sk)->dst, conn->dst); |
732 | 872 | ||
@@ -734,9 +874,9 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
734 | 874 | ||
735 | __l2cap_chan_add(conn, chan); | 875 | __l2cap_chan_add(conn, chan); |
736 | 876 | ||
737 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 877 | __set_chan_timer(chan, sk->sk_sndtimeo); |
738 | 878 | ||
739 | sk->sk_state = BT_CONNECTED; | 879 | l2cap_state_change(chan, BT_CONNECTED); |
740 | parent->sk_data_ready(parent, 0); | 880 | parent->sk_data_ready(parent, 0); |
741 | 881 | ||
742 | write_unlock_bh(&conn->chan_lock); | 882 | write_unlock_bh(&conn->chan_lock); |
@@ -745,6 +885,23 @@ clean: | |||
745 | bh_unlock_sock(parent); | 885 | bh_unlock_sock(parent); |
746 | } | 886 | } |
747 | 887 | ||
888 | static void l2cap_chan_ready(struct sock *sk) | ||
889 | { | ||
890 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
891 | struct sock *parent = bt_sk(sk)->parent; | ||
892 | |||
893 | BT_DBG("sk %p, parent %p", sk, parent); | ||
894 | |||
895 | chan->conf_state = 0; | ||
896 | __clear_chan_timer(chan); | ||
897 | |||
898 | l2cap_state_change(chan, BT_CONNECTED); | ||
899 | sk->sk_state_change(sk); | ||
900 | |||
901 | if (parent) | ||
902 | parent->sk_data_ready(parent, 0); | ||
903 | } | ||
904 | |||
748 | static void l2cap_conn_ready(struct l2cap_conn *conn) | 905 | static void l2cap_conn_ready(struct l2cap_conn *conn) |
749 | { | 906 | { |
750 | struct l2cap_chan *chan; | 907 | struct l2cap_chan *chan; |
@@ -762,17 +919,15 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
762 | bh_lock_sock(sk); | 919 | bh_lock_sock(sk); |
763 | 920 | ||
764 | if (conn->hcon->type == LE_LINK) { | 921 | if (conn->hcon->type == LE_LINK) { |
765 | l2cap_sock_clear_timer(sk); | 922 | if (smp_conn_security(conn, chan->sec_level)) |
766 | sk->sk_state = BT_CONNECTED; | 923 | l2cap_chan_ready(sk); |
767 | sk->sk_state_change(sk); | ||
768 | } | ||
769 | 924 | ||
770 | if (sk->sk_type != SOCK_SEQPACKET && | 925 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
771 | sk->sk_type != SOCK_STREAM) { | 926 | __clear_chan_timer(chan); |
772 | l2cap_sock_clear_timer(sk); | 927 | l2cap_state_change(chan, BT_CONNECTED); |
773 | sk->sk_state = BT_CONNECTED; | ||
774 | sk->sk_state_change(sk); | 928 | sk->sk_state_change(sk); |
775 | } else if (sk->sk_state == BT_CONNECT) | 929 | |
930 | } else if (chan->state == BT_CONNECT) | ||
776 | l2cap_do_start(chan); | 931 | l2cap_do_start(chan); |
777 | 932 | ||
778 | bh_unlock_sock(sk); | 933 | bh_unlock_sock(sk); |
@@ -810,6 +965,45 @@ static void l2cap_info_timeout(unsigned long arg) | |||
810 | l2cap_conn_start(conn); | 965 | l2cap_conn_start(conn); |
811 | } | 966 | } |
812 | 967 | ||
968 | static void l2cap_conn_del(struct hci_conn *hcon, int err) | ||
969 | { | ||
970 | struct l2cap_conn *conn = hcon->l2cap_data; | ||
971 | struct l2cap_chan *chan, *l; | ||
972 | struct sock *sk; | ||
973 | |||
974 | if (!conn) | ||
975 | return; | ||
976 | |||
977 | BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); | ||
978 | |||
979 | kfree_skb(conn->rx_skb); | ||
980 | |||
981 | /* Kill channels */ | ||
982 | list_for_each_entry_safe(chan, l, &conn->chan_l, list) { | ||
983 | sk = chan->sk; | ||
984 | bh_lock_sock(sk); | ||
985 | l2cap_chan_del(chan, err); | ||
986 | bh_unlock_sock(sk); | ||
987 | chan->ops->close(chan->data); | ||
988 | } | ||
989 | |||
990 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | ||
991 | del_timer_sync(&conn->info_timer); | ||
992 | |||
993 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) | ||
994 | del_timer(&conn->security_timer); | ||
995 | |||
996 | hcon->l2cap_data = NULL; | ||
997 | kfree(conn); | ||
998 | } | ||
999 | |||
1000 | static void security_timeout(unsigned long arg) | ||
1001 | { | ||
1002 | struct l2cap_conn *conn = (void *) arg; | ||
1003 | |||
1004 | l2cap_conn_del(conn->hcon, ETIMEDOUT); | ||
1005 | } | ||
1006 | |||
813 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | 1007 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) |
814 | { | 1008 | { |
815 | struct l2cap_conn *conn = hcon->l2cap_data; | 1009 | struct l2cap_conn *conn = hcon->l2cap_data; |
@@ -841,7 +1035,10 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
841 | 1035 | ||
842 | INIT_LIST_HEAD(&conn->chan_l); | 1036 | INIT_LIST_HEAD(&conn->chan_l); |
843 | 1037 | ||
844 | if (hcon->type != LE_LINK) | 1038 | if (hcon->type == LE_LINK) |
1039 | setup_timer(&conn->security_timer, security_timeout, | ||
1040 | (unsigned long) conn); | ||
1041 | else | ||
845 | setup_timer(&conn->info_timer, l2cap_info_timeout, | 1042 | setup_timer(&conn->info_timer, l2cap_info_timeout, |
846 | (unsigned long) conn); | 1043 | (unsigned long) conn); |
847 | 1044 | ||
@@ -850,35 +1047,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
850 | return conn; | 1047 | return conn; |
851 | } | 1048 | } |
852 | 1049 | ||
853 | static void l2cap_conn_del(struct hci_conn *hcon, int err) | ||
854 | { | ||
855 | struct l2cap_conn *conn = hcon->l2cap_data; | ||
856 | struct l2cap_chan *chan, *l; | ||
857 | struct sock *sk; | ||
858 | |||
859 | if (!conn) | ||
860 | return; | ||
861 | |||
862 | BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); | ||
863 | |||
864 | kfree_skb(conn->rx_skb); | ||
865 | |||
866 | /* Kill channels */ | ||
867 | list_for_each_entry_safe(chan, l, &conn->chan_l, list) { | ||
868 | sk = chan->sk; | ||
869 | bh_lock_sock(sk); | ||
870 | l2cap_chan_del(chan, err); | ||
871 | bh_unlock_sock(sk); | ||
872 | l2cap_sock_kill(sk); | ||
873 | } | ||
874 | |||
875 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | ||
876 | del_timer_sync(&conn->info_timer); | ||
877 | |||
878 | hcon->l2cap_data = NULL; | ||
879 | kfree(conn); | ||
880 | } | ||
881 | |||
882 | static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 1050 | static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
883 | { | 1051 | { |
884 | write_lock_bh(&conn->chan_lock); | 1052 | write_lock_bh(&conn->chan_lock); |
@@ -900,7 +1068,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr | |||
900 | list_for_each_entry(c, &chan_list, global_l) { | 1068 | list_for_each_entry(c, &chan_list, global_l) { |
901 | struct sock *sk = c->sk; | 1069 | struct sock *sk = c->sk; |
902 | 1070 | ||
903 | if (state && sk->sk_state != state) | 1071 | if (state && c->state != state) |
904 | continue; | 1072 | continue; |
905 | 1073 | ||
906 | if (c->psm == psm) { | 1074 | if (c->psm == psm) { |
@@ -967,15 +1135,14 @@ int l2cap_chan_connect(struct l2cap_chan *chan) | |||
967 | 1135 | ||
968 | l2cap_chan_add(conn, chan); | 1136 | l2cap_chan_add(conn, chan); |
969 | 1137 | ||
970 | sk->sk_state = BT_CONNECT; | 1138 | l2cap_state_change(chan, BT_CONNECT); |
971 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 1139 | __set_chan_timer(chan, sk->sk_sndtimeo); |
972 | 1140 | ||
973 | if (hcon->state == BT_CONNECTED) { | 1141 | if (hcon->state == BT_CONNECTED) { |
974 | if (sk->sk_type != SOCK_SEQPACKET && | 1142 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
975 | sk->sk_type != SOCK_STREAM) { | 1143 | __clear_chan_timer(chan); |
976 | l2cap_sock_clear_timer(sk); | ||
977 | if (l2cap_check_security(chan)) | 1144 | if (l2cap_check_security(chan)) |
978 | sk->sk_state = BT_CONNECTED; | 1145 | l2cap_state_change(chan, BT_CONNECTED); |
979 | } else | 1146 | } else |
980 | l2cap_do_start(chan); | 1147 | l2cap_do_start(chan); |
981 | } | 1148 | } |
@@ -1035,7 +1202,7 @@ static void l2cap_monitor_timeout(unsigned long arg) | |||
1035 | } | 1202 | } |
1036 | 1203 | ||
1037 | chan->retry_count++; | 1204 | chan->retry_count++; |
1038 | __mod_monitor_timer(); | 1205 | __set_monitor_timer(chan); |
1039 | 1206 | ||
1040 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); | 1207 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); |
1041 | bh_unlock_sock(sk); | 1208 | bh_unlock_sock(sk); |
@@ -1050,9 +1217,9 @@ static void l2cap_retrans_timeout(unsigned long arg) | |||
1050 | 1217 | ||
1051 | bh_lock_sock(sk); | 1218 | bh_lock_sock(sk); |
1052 | chan->retry_count = 1; | 1219 | chan->retry_count = 1; |
1053 | __mod_monitor_timer(); | 1220 | __set_monitor_timer(chan); |
1054 | 1221 | ||
1055 | chan->conn_state |= L2CAP_CONN_WAIT_F; | 1222 | set_bit(CONN_WAIT_F, &chan->conn_state); |
1056 | 1223 | ||
1057 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); | 1224 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); |
1058 | bh_unlock_sock(sk); | 1225 | bh_unlock_sock(sk); |
@@ -1074,7 +1241,7 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan) | |||
1074 | } | 1241 | } |
1075 | 1242 | ||
1076 | if (!chan->unacked_frames) | 1243 | if (!chan->unacked_frames) |
1077 | del_timer(&chan->retrans_timer); | 1244 | __clear_retrans_timer(chan); |
1078 | } | 1245 | } |
1079 | 1246 | ||
1080 | void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | 1247 | void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) |
@@ -1089,6 +1256,7 @@ void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1089 | else | 1256 | else |
1090 | flags = ACL_START; | 1257 | flags = ACL_START; |
1091 | 1258 | ||
1259 | bt_cb(skb)->force_active = chan->force_active; | ||
1092 | hci_send_acl(hcon, skb, flags); | 1260 | hci_send_acl(hcon, skb, flags); |
1093 | } | 1261 | } |
1094 | 1262 | ||
@@ -1142,10 +1310,8 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1142 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1310 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1143 | control &= L2CAP_CTRL_SAR; | 1311 | control &= L2CAP_CTRL_SAR; |
1144 | 1312 | ||
1145 | if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { | 1313 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
1146 | control |= L2CAP_CTRL_FINAL; | 1314 | control |= L2CAP_CTRL_FINAL; |
1147 | chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; | ||
1148 | } | ||
1149 | 1315 | ||
1150 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1316 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1151 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1317 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
@@ -1163,11 +1329,10 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1163 | int l2cap_ertm_send(struct l2cap_chan *chan) | 1329 | int l2cap_ertm_send(struct l2cap_chan *chan) |
1164 | { | 1330 | { |
1165 | struct sk_buff *skb, *tx_skb; | 1331 | struct sk_buff *skb, *tx_skb; |
1166 | struct sock *sk = chan->sk; | ||
1167 | u16 control, fcs; | 1332 | u16 control, fcs; |
1168 | int nsent = 0; | 1333 | int nsent = 0; |
1169 | 1334 | ||
1170 | if (sk->sk_state != BT_CONNECTED) | 1335 | if (chan->state != BT_CONNECTED) |
1171 | return -ENOTCONN; | 1336 | return -ENOTCONN; |
1172 | 1337 | ||
1173 | while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) { | 1338 | while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) { |
@@ -1185,10 +1350,9 @@ int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1185 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1350 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1186 | control &= L2CAP_CTRL_SAR; | 1351 | control &= L2CAP_CTRL_SAR; |
1187 | 1352 | ||
1188 | if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { | 1353 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
1189 | control |= L2CAP_CTRL_FINAL; | 1354 | control |= L2CAP_CTRL_FINAL; |
1190 | chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; | 1355 | |
1191 | } | ||
1192 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1356 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1193 | | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1357 | | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1194 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1358 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
@@ -1201,7 +1365,7 @@ int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1201 | 1365 | ||
1202 | l2cap_do_send(chan, tx_skb); | 1366 | l2cap_do_send(chan, tx_skb); |
1203 | 1367 | ||
1204 | __mod_retrans_timer(); | 1368 | __set_retrans_timer(chan); |
1205 | 1369 | ||
1206 | bt_cb(skb)->tx_seq = chan->next_tx_seq; | 1370 | bt_cb(skb)->tx_seq = chan->next_tx_seq; |
1207 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; | 1371 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; |
@@ -1240,9 +1404,9 @@ static void l2cap_send_ack(struct l2cap_chan *chan) | |||
1240 | 1404 | ||
1241 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1405 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
1242 | 1406 | ||
1243 | if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 1407 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
1244 | control |= L2CAP_SUPER_RCV_NOT_READY; | 1408 | control |= L2CAP_SUPER_RCV_NOT_READY; |
1245 | chan->conn_state |= L2CAP_CONN_RNR_SENT; | 1409 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
1246 | l2cap_send_sframe(chan, control); | 1410 | l2cap_send_sframe(chan, control); |
1247 | return; | 1411 | return; |
1248 | } | 1412 | } |
@@ -1450,28 +1614,83 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le | |||
1450 | return size; | 1614 | return size; |
1451 | } | 1615 | } |
1452 | 1616 | ||
1453 | static void l2cap_chan_ready(struct sock *sk) | 1617 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) |
1454 | { | 1618 | { |
1455 | struct sock *parent = bt_sk(sk)->parent; | 1619 | struct sk_buff *skb; |
1456 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 1620 | u16 control; |
1621 | int err; | ||
1457 | 1622 | ||
1458 | BT_DBG("sk %p, parent %p", sk, parent); | 1623 | /* Connectionless channel */ |
1624 | if (chan->chan_type == L2CAP_CHAN_CONN_LESS) { | ||
1625 | skb = l2cap_create_connless_pdu(chan, msg, len); | ||
1626 | if (IS_ERR(skb)) | ||
1627 | return PTR_ERR(skb); | ||
1459 | 1628 | ||
1460 | chan->conf_state = 0; | 1629 | l2cap_do_send(chan, skb); |
1461 | l2cap_sock_clear_timer(sk); | 1630 | return len; |
1631 | } | ||
1462 | 1632 | ||
1463 | if (!parent) { | 1633 | switch (chan->mode) { |
1464 | /* Outgoing channel. | 1634 | case L2CAP_MODE_BASIC: |
1465 | * Wake up socket sleeping on connect. | 1635 | /* Check outgoing MTU */ |
1466 | */ | 1636 | if (len > chan->omtu) |
1467 | sk->sk_state = BT_CONNECTED; | 1637 | return -EMSGSIZE; |
1468 | sk->sk_state_change(sk); | 1638 | |
1469 | } else { | 1639 | /* Create a basic PDU */ |
1470 | /* Incoming channel. | 1640 | skb = l2cap_create_basic_pdu(chan, msg, len); |
1471 | * Wake up socket sleeping on accept. | 1641 | if (IS_ERR(skb)) |
1472 | */ | 1642 | return PTR_ERR(skb); |
1473 | parent->sk_data_ready(parent, 0); | 1643 | |
1644 | l2cap_do_send(chan, skb); | ||
1645 | err = len; | ||
1646 | break; | ||
1647 | |||
1648 | case L2CAP_MODE_ERTM: | ||
1649 | case L2CAP_MODE_STREAMING: | ||
1650 | /* Entire SDU fits into one PDU */ | ||
1651 | if (len <= chan->remote_mps) { | ||
1652 | control = L2CAP_SDU_UNSEGMENTED; | ||
1653 | skb = l2cap_create_iframe_pdu(chan, msg, len, control, | ||
1654 | 0); | ||
1655 | if (IS_ERR(skb)) | ||
1656 | return PTR_ERR(skb); | ||
1657 | |||
1658 | __skb_queue_tail(&chan->tx_q, skb); | ||
1659 | |||
1660 | if (chan->tx_send_head == NULL) | ||
1661 | chan->tx_send_head = skb; | ||
1662 | |||
1663 | } else { | ||
1664 | /* Segment SDU into multiples PDUs */ | ||
1665 | err = l2cap_sar_segment_sdu(chan, msg, len); | ||
1666 | if (err < 0) | ||
1667 | return err; | ||
1668 | } | ||
1669 | |||
1670 | if (chan->mode == L2CAP_MODE_STREAMING) { | ||
1671 | l2cap_streaming_send(chan); | ||
1672 | err = len; | ||
1673 | break; | ||
1674 | } | ||
1675 | |||
1676 | if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && | ||
1677 | test_bit(CONN_WAIT_F, &chan->conn_state)) { | ||
1678 | err = len; | ||
1679 | break; | ||
1680 | } | ||
1681 | |||
1682 | err = l2cap_ertm_send(chan); | ||
1683 | if (err >= 0) | ||
1684 | err = len; | ||
1685 | |||
1686 | break; | ||
1687 | |||
1688 | default: | ||
1689 | BT_DBG("bad state %1.1x", chan->mode); | ||
1690 | err = -EBADFD; | ||
1474 | } | 1691 | } |
1692 | |||
1693 | return err; | ||
1475 | } | 1694 | } |
1476 | 1695 | ||
1477 | /* Copy frame to all raw sockets on that connection */ | 1696 | /* Copy frame to all raw sockets on that connection */ |
@@ -1485,7 +1704,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1485 | read_lock(&conn->chan_lock); | 1704 | read_lock(&conn->chan_lock); |
1486 | list_for_each_entry(chan, &conn->chan_l, list) { | 1705 | list_for_each_entry(chan, &conn->chan_l, list) { |
1487 | struct sock *sk = chan->sk; | 1706 | struct sock *sk = chan->sk; |
1488 | if (sk->sk_type != SOCK_RAW) | 1707 | if (chan->chan_type != L2CAP_CHAN_RAW) |
1489 | continue; | 1708 | continue; |
1490 | 1709 | ||
1491 | /* Don't send frame to the socket it came from */ | 1710 | /* Don't send frame to the socket it came from */ |
@@ -1495,7 +1714,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1495 | if (!nskb) | 1714 | if (!nskb) |
1496 | continue; | 1715 | continue; |
1497 | 1716 | ||
1498 | if (sock_queue_rcv_skb(sk, nskb)) | 1717 | if (chan->ops->recv(chan->data, nskb)) |
1499 | kfree_skb(nskb); | 1718 | kfree_skb(nskb); |
1500 | } | 1719 | } |
1501 | read_unlock(&conn->chan_lock); | 1720 | read_unlock(&conn->chan_lock); |
@@ -1690,7 +1909,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | |||
1690 | switch (chan->mode) { | 1909 | switch (chan->mode) { |
1691 | case L2CAP_MODE_STREAMING: | 1910 | case L2CAP_MODE_STREAMING: |
1692 | case L2CAP_MODE_ERTM: | 1911 | case L2CAP_MODE_ERTM: |
1693 | if (chan->conf_state & L2CAP_CONF_STATE2_DEVICE) | 1912 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) |
1694 | break; | 1913 | break; |
1695 | 1914 | ||
1696 | /* fall through */ | 1915 | /* fall through */ |
@@ -1737,7 +1956,7 @@ done: | |||
1737 | break; | 1956 | break; |
1738 | 1957 | ||
1739 | if (chan->fcs == L2CAP_FCS_NONE || | 1958 | if (chan->fcs == L2CAP_FCS_NONE || |
1740 | chan->conf_state & L2CAP_CONF_NO_FCS_RECV) { | 1959 | test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { |
1741 | chan->fcs = L2CAP_FCS_NONE; | 1960 | chan->fcs = L2CAP_FCS_NONE; |
1742 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); | 1961 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); |
1743 | } | 1962 | } |
@@ -1760,7 +1979,7 @@ done: | |||
1760 | break; | 1979 | break; |
1761 | 1980 | ||
1762 | if (chan->fcs == L2CAP_FCS_NONE || | 1981 | if (chan->fcs == L2CAP_FCS_NONE || |
1763 | chan->conf_state & L2CAP_CONF_NO_FCS_RECV) { | 1982 | test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { |
1764 | chan->fcs = L2CAP_FCS_NONE; | 1983 | chan->fcs = L2CAP_FCS_NONE; |
1765 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); | 1984 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); |
1766 | } | 1985 | } |
@@ -1812,7 +2031,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
1812 | 2031 | ||
1813 | case L2CAP_CONF_FCS: | 2032 | case L2CAP_CONF_FCS: |
1814 | if (val == L2CAP_FCS_NONE) | 2033 | if (val == L2CAP_FCS_NONE) |
1815 | chan->conf_state |= L2CAP_CONF_NO_FCS_RECV; | 2034 | set_bit(CONF_NO_FCS_RECV, &chan->conf_state); |
1816 | 2035 | ||
1817 | break; | 2036 | break; |
1818 | 2037 | ||
@@ -1832,7 +2051,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
1832 | switch (chan->mode) { | 2051 | switch (chan->mode) { |
1833 | case L2CAP_MODE_STREAMING: | 2052 | case L2CAP_MODE_STREAMING: |
1834 | case L2CAP_MODE_ERTM: | 2053 | case L2CAP_MODE_ERTM: |
1835 | if (!(chan->conf_state & L2CAP_CONF_STATE2_DEVICE)) { | 2054 | if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) { |
1836 | chan->mode = l2cap_select_mode(rfc.mode, | 2055 | chan->mode = l2cap_select_mode(rfc.mode, |
1837 | chan->conn->feat_mask); | 2056 | chan->conn->feat_mask); |
1838 | break; | 2057 | break; |
@@ -1865,14 +2084,14 @@ done: | |||
1865 | result = L2CAP_CONF_UNACCEPT; | 2084 | result = L2CAP_CONF_UNACCEPT; |
1866 | else { | 2085 | else { |
1867 | chan->omtu = mtu; | 2086 | chan->omtu = mtu; |
1868 | chan->conf_state |= L2CAP_CONF_MTU_DONE; | 2087 | set_bit(CONF_MTU_DONE, &chan->conf_state); |
1869 | } | 2088 | } |
1870 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); | 2089 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); |
1871 | 2090 | ||
1872 | switch (rfc.mode) { | 2091 | switch (rfc.mode) { |
1873 | case L2CAP_MODE_BASIC: | 2092 | case L2CAP_MODE_BASIC: |
1874 | chan->fcs = L2CAP_FCS_NONE; | 2093 | chan->fcs = L2CAP_FCS_NONE; |
1875 | chan->conf_state |= L2CAP_CONF_MODE_DONE; | 2094 | set_bit(CONF_MODE_DONE, &chan->conf_state); |
1876 | break; | 2095 | break; |
1877 | 2096 | ||
1878 | case L2CAP_MODE_ERTM: | 2097 | case L2CAP_MODE_ERTM: |
@@ -1889,7 +2108,7 @@ done: | |||
1889 | rfc.monitor_timeout = | 2108 | rfc.monitor_timeout = |
1890 | le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO); | 2109 | le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO); |
1891 | 2110 | ||
1892 | chan->conf_state |= L2CAP_CONF_MODE_DONE; | 2111 | set_bit(CONF_MODE_DONE, &chan->conf_state); |
1893 | 2112 | ||
1894 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2113 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
1895 | sizeof(rfc), (unsigned long) &rfc); | 2114 | sizeof(rfc), (unsigned long) &rfc); |
@@ -1902,7 +2121,7 @@ done: | |||
1902 | 2121 | ||
1903 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 2122 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); |
1904 | 2123 | ||
1905 | chan->conf_state |= L2CAP_CONF_MODE_DONE; | 2124 | set_bit(CONF_MODE_DONE, &chan->conf_state); |
1906 | 2125 | ||
1907 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2126 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
1908 | sizeof(rfc), (unsigned long) &rfc); | 2127 | sizeof(rfc), (unsigned long) &rfc); |
@@ -1917,7 +2136,7 @@ done: | |||
1917 | } | 2136 | } |
1918 | 2137 | ||
1919 | if (result == L2CAP_CONF_SUCCESS) | 2138 | if (result == L2CAP_CONF_SUCCESS) |
1920 | chan->conf_state |= L2CAP_CONF_OUTPUT_DONE; | 2139 | set_bit(CONF_OUTPUT_DONE, &chan->conf_state); |
1921 | } | 2140 | } |
1922 | rsp->scid = cpu_to_le16(chan->dcid); | 2141 | rsp->scid = cpu_to_le16(chan->dcid); |
1923 | rsp->result = cpu_to_le16(result); | 2142 | rsp->result = cpu_to_le16(result); |
@@ -1959,7 +2178,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
1959 | if (olen == sizeof(rfc)) | 2178 | if (olen == sizeof(rfc)) |
1960 | memcpy(&rfc, (void *)val, olen); | 2179 | memcpy(&rfc, (void *)val, olen); |
1961 | 2180 | ||
1962 | if ((chan->conf_state & L2CAP_CONF_STATE2_DEVICE) && | 2181 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) && |
1963 | rfc.mode != chan->mode) | 2182 | rfc.mode != chan->mode) |
1964 | return -ECONNREFUSED; | 2183 | return -ECONNREFUSED; |
1965 | 2184 | ||
@@ -2021,10 +2240,9 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) | |||
2021 | l2cap_send_cmd(conn, chan->ident, | 2240 | l2cap_send_cmd(conn, chan->ident, |
2022 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 2241 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); |
2023 | 2242 | ||
2024 | if (chan->conf_state & L2CAP_CONF_REQ_SENT) | 2243 | if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) |
2025 | return; | 2244 | return; |
2026 | 2245 | ||
2027 | chan->conf_state |= L2CAP_CONF_REQ_SENT; | ||
2028 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2246 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2029 | l2cap_build_conf_req(chan, buf), buf); | 2247 | l2cap_build_conf_req(chan, buf), buf); |
2030 | chan->num_conf_req++; | 2248 | chan->num_conf_req++; |
@@ -2124,17 +2342,11 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2124 | goto response; | 2342 | goto response; |
2125 | } | 2343 | } |
2126 | 2344 | ||
2127 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); | 2345 | chan = pchan->ops->new_connection(pchan->data); |
2128 | if (!sk) | 2346 | if (!chan) |
2129 | goto response; | ||
2130 | |||
2131 | chan = l2cap_chan_create(sk); | ||
2132 | if (!chan) { | ||
2133 | l2cap_sock_kill(sk); | ||
2134 | goto response; | 2347 | goto response; |
2135 | } | ||
2136 | 2348 | ||
2137 | l2cap_pi(sk)->chan = chan; | 2349 | sk = chan->sk; |
2138 | 2350 | ||
2139 | write_lock_bh(&conn->chan_lock); | 2351 | write_lock_bh(&conn->chan_lock); |
2140 | 2352 | ||
@@ -2142,13 +2354,12 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2142 | if (__l2cap_get_chan_by_dcid(conn, scid)) { | 2354 | if (__l2cap_get_chan_by_dcid(conn, scid)) { |
2143 | write_unlock_bh(&conn->chan_lock); | 2355 | write_unlock_bh(&conn->chan_lock); |
2144 | sock_set_flag(sk, SOCK_ZAPPED); | 2356 | sock_set_flag(sk, SOCK_ZAPPED); |
2145 | l2cap_sock_kill(sk); | 2357 | chan->ops->close(chan->data); |
2146 | goto response; | 2358 | goto response; |
2147 | } | 2359 | } |
2148 | 2360 | ||
2149 | hci_conn_hold(conn->hcon); | 2361 | hci_conn_hold(conn->hcon); |
2150 | 2362 | ||
2151 | l2cap_sock_init(sk, parent); | ||
2152 | bacpy(&bt_sk(sk)->src, conn->src); | 2363 | bacpy(&bt_sk(sk)->src, conn->src); |
2153 | bacpy(&bt_sk(sk)->dst, conn->dst); | 2364 | bacpy(&bt_sk(sk)->dst, conn->dst); |
2154 | chan->psm = psm; | 2365 | chan->psm = psm; |
@@ -2160,29 +2371,29 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2160 | 2371 | ||
2161 | dcid = chan->scid; | 2372 | dcid = chan->scid; |
2162 | 2373 | ||
2163 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 2374 | __set_chan_timer(chan, sk->sk_sndtimeo); |
2164 | 2375 | ||
2165 | chan->ident = cmd->ident; | 2376 | chan->ident = cmd->ident; |
2166 | 2377 | ||
2167 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { | 2378 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { |
2168 | if (l2cap_check_security(chan)) { | 2379 | if (l2cap_check_security(chan)) { |
2169 | if (bt_sk(sk)->defer_setup) { | 2380 | if (bt_sk(sk)->defer_setup) { |
2170 | sk->sk_state = BT_CONNECT2; | 2381 | l2cap_state_change(chan, BT_CONNECT2); |
2171 | result = L2CAP_CR_PEND; | 2382 | result = L2CAP_CR_PEND; |
2172 | status = L2CAP_CS_AUTHOR_PEND; | 2383 | status = L2CAP_CS_AUTHOR_PEND; |
2173 | parent->sk_data_ready(parent, 0); | 2384 | parent->sk_data_ready(parent, 0); |
2174 | } else { | 2385 | } else { |
2175 | sk->sk_state = BT_CONFIG; | 2386 | l2cap_state_change(chan, BT_CONFIG); |
2176 | result = L2CAP_CR_SUCCESS; | 2387 | result = L2CAP_CR_SUCCESS; |
2177 | status = L2CAP_CS_NO_INFO; | 2388 | status = L2CAP_CS_NO_INFO; |
2178 | } | 2389 | } |
2179 | } else { | 2390 | } else { |
2180 | sk->sk_state = BT_CONNECT2; | 2391 | l2cap_state_change(chan, BT_CONNECT2); |
2181 | result = L2CAP_CR_PEND; | 2392 | result = L2CAP_CR_PEND; |
2182 | status = L2CAP_CS_AUTHEN_PEND; | 2393 | status = L2CAP_CS_AUTHEN_PEND; |
2183 | } | 2394 | } |
2184 | } else { | 2395 | } else { |
2185 | sk->sk_state = BT_CONNECT2; | 2396 | l2cap_state_change(chan, BT_CONNECT2); |
2186 | result = L2CAP_CR_PEND; | 2397 | result = L2CAP_CR_PEND; |
2187 | status = L2CAP_CS_NO_INFO; | 2398 | status = L2CAP_CS_NO_INFO; |
2188 | } | 2399 | } |
@@ -2213,10 +2424,10 @@ sendresp: | |||
2213 | L2CAP_INFO_REQ, sizeof(info), &info); | 2424 | L2CAP_INFO_REQ, sizeof(info), &info); |
2214 | } | 2425 | } |
2215 | 2426 | ||
2216 | if (chan && !(chan->conf_state & L2CAP_CONF_REQ_SENT) && | 2427 | if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) && |
2217 | result == L2CAP_CR_SUCCESS) { | 2428 | result == L2CAP_CR_SUCCESS) { |
2218 | u8 buf[128]; | 2429 | u8 buf[128]; |
2219 | chan->conf_state |= L2CAP_CONF_REQ_SENT; | 2430 | set_bit(CONF_REQ_SENT, &chan->conf_state); |
2220 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2431 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2221 | l2cap_build_conf_req(chan, buf), buf); | 2432 | l2cap_build_conf_req(chan, buf), buf); |
2222 | chan->num_conf_req++; | 2433 | chan->num_conf_req++; |
@@ -2254,31 +2465,29 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2254 | 2465 | ||
2255 | switch (result) { | 2466 | switch (result) { |
2256 | case L2CAP_CR_SUCCESS: | 2467 | case L2CAP_CR_SUCCESS: |
2257 | sk->sk_state = BT_CONFIG; | 2468 | l2cap_state_change(chan, BT_CONFIG); |
2258 | chan->ident = 0; | 2469 | chan->ident = 0; |
2259 | chan->dcid = dcid; | 2470 | chan->dcid = dcid; |
2260 | chan->conf_state &= ~L2CAP_CONF_CONNECT_PEND; | 2471 | clear_bit(CONF_CONNECT_PEND, &chan->conf_state); |
2261 | 2472 | ||
2262 | if (chan->conf_state & L2CAP_CONF_REQ_SENT) | 2473 | if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) |
2263 | break; | 2474 | break; |
2264 | 2475 | ||
2265 | chan->conf_state |= L2CAP_CONF_REQ_SENT; | ||
2266 | |||
2267 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2476 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2268 | l2cap_build_conf_req(chan, req), req); | 2477 | l2cap_build_conf_req(chan, req), req); |
2269 | chan->num_conf_req++; | 2478 | chan->num_conf_req++; |
2270 | break; | 2479 | break; |
2271 | 2480 | ||
2272 | case L2CAP_CR_PEND: | 2481 | case L2CAP_CR_PEND: |
2273 | chan->conf_state |= L2CAP_CONF_CONNECT_PEND; | 2482 | set_bit(CONF_CONNECT_PEND, &chan->conf_state); |
2274 | break; | 2483 | break; |
2275 | 2484 | ||
2276 | default: | 2485 | default: |
2277 | /* don't delete l2cap channel if sk is owned by user */ | 2486 | /* don't delete l2cap channel if sk is owned by user */ |
2278 | if (sock_owned_by_user(sk)) { | 2487 | if (sock_owned_by_user(sk)) { |
2279 | sk->sk_state = BT_DISCONN; | 2488 | l2cap_state_change(chan, BT_DISCONN); |
2280 | l2cap_sock_clear_timer(sk); | 2489 | __clear_chan_timer(chan); |
2281 | l2cap_sock_set_timer(sk, HZ / 5); | 2490 | __set_chan_timer(chan, HZ / 5); |
2282 | break; | 2491 | break; |
2283 | } | 2492 | } |
2284 | 2493 | ||
@@ -2292,14 +2501,12 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2292 | 2501 | ||
2293 | static inline void set_default_fcs(struct l2cap_chan *chan) | 2502 | static inline void set_default_fcs(struct l2cap_chan *chan) |
2294 | { | 2503 | { |
2295 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
2296 | |||
2297 | /* FCS is enabled only in ERTM or streaming mode, if one or both | 2504 | /* FCS is enabled only in ERTM or streaming mode, if one or both |
2298 | * sides request it. | 2505 | * sides request it. |
2299 | */ | 2506 | */ |
2300 | if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING) | 2507 | if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING) |
2301 | chan->fcs = L2CAP_FCS_NONE; | 2508 | chan->fcs = L2CAP_FCS_NONE; |
2302 | else if (!(pi->chan->conf_state & L2CAP_CONF_NO_FCS_RECV)) | 2509 | else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) |
2303 | chan->fcs = L2CAP_FCS_CRC16; | 2510 | chan->fcs = L2CAP_FCS_CRC16; |
2304 | } | 2511 | } |
2305 | 2512 | ||
@@ -2323,7 +2530,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2323 | 2530 | ||
2324 | sk = chan->sk; | 2531 | sk = chan->sk; |
2325 | 2532 | ||
2326 | if (sk->sk_state != BT_CONFIG) { | 2533 | if (chan->state != BT_CONFIG) { |
2327 | struct l2cap_cmd_rej rej; | 2534 | struct l2cap_cmd_rej rej; |
2328 | 2535 | ||
2329 | rej.reason = cpu_to_le16(0x0002); | 2536 | rej.reason = cpu_to_le16(0x0002); |
@@ -2366,13 +2573,13 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2366 | /* Reset config buffer. */ | 2573 | /* Reset config buffer. */ |
2367 | chan->conf_len = 0; | 2574 | chan->conf_len = 0; |
2368 | 2575 | ||
2369 | if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE)) | 2576 | if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) |
2370 | goto unlock; | 2577 | goto unlock; |
2371 | 2578 | ||
2372 | if (chan->conf_state & L2CAP_CONF_INPUT_DONE) { | 2579 | if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) { |
2373 | set_default_fcs(chan); | 2580 | set_default_fcs(chan); |
2374 | 2581 | ||
2375 | sk->sk_state = BT_CONNECTED; | 2582 | l2cap_state_change(chan, BT_CONNECTED); |
2376 | 2583 | ||
2377 | chan->next_tx_seq = 0; | 2584 | chan->next_tx_seq = 0; |
2378 | chan->expected_tx_seq = 0; | 2585 | chan->expected_tx_seq = 0; |
@@ -2384,9 +2591,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2384 | goto unlock; | 2591 | goto unlock; |
2385 | } | 2592 | } |
2386 | 2593 | ||
2387 | if (!(chan->conf_state & L2CAP_CONF_REQ_SENT)) { | 2594 | if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { |
2388 | u8 buf[64]; | 2595 | u8 buf[64]; |
2389 | chan->conf_state |= L2CAP_CONF_REQ_SENT; | ||
2390 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2596 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2391 | l2cap_build_conf_req(chan, buf), buf); | 2597 | l2cap_build_conf_req(chan, buf), buf); |
2392 | chan->num_conf_req++; | 2598 | chan->num_conf_req++; |
@@ -2451,7 +2657,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2451 | 2657 | ||
2452 | default: | 2658 | default: |
2453 | sk->sk_err = ECONNRESET; | 2659 | sk->sk_err = ECONNRESET; |
2454 | l2cap_sock_set_timer(sk, HZ * 5); | 2660 | __set_chan_timer(chan, HZ * 5); |
2455 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | 2661 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
2456 | goto done; | 2662 | goto done; |
2457 | } | 2663 | } |
@@ -2459,12 +2665,12 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2459 | if (flags & 0x01) | 2665 | if (flags & 0x01) |
2460 | goto done; | 2666 | goto done; |
2461 | 2667 | ||
2462 | chan->conf_state |= L2CAP_CONF_INPUT_DONE; | 2668 | set_bit(CONF_INPUT_DONE, &chan->conf_state); |
2463 | 2669 | ||
2464 | if (chan->conf_state & L2CAP_CONF_OUTPUT_DONE) { | 2670 | if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) { |
2465 | set_default_fcs(chan); | 2671 | set_default_fcs(chan); |
2466 | 2672 | ||
2467 | sk->sk_state = BT_CONNECTED; | 2673 | l2cap_state_change(chan, BT_CONNECTED); |
2468 | chan->next_tx_seq = 0; | 2674 | chan->next_tx_seq = 0; |
2469 | chan->expected_tx_seq = 0; | 2675 | chan->expected_tx_seq = 0; |
2470 | skb_queue_head_init(&chan->tx_q); | 2676 | skb_queue_head_init(&chan->tx_q); |
@@ -2506,9 +2712,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2506 | 2712 | ||
2507 | /* don't delete l2cap channel if sk is owned by user */ | 2713 | /* don't delete l2cap channel if sk is owned by user */ |
2508 | if (sock_owned_by_user(sk)) { | 2714 | if (sock_owned_by_user(sk)) { |
2509 | sk->sk_state = BT_DISCONN; | 2715 | l2cap_state_change(chan, BT_DISCONN); |
2510 | l2cap_sock_clear_timer(sk); | 2716 | __clear_chan_timer(chan); |
2511 | l2cap_sock_set_timer(sk, HZ / 5); | 2717 | __set_chan_timer(chan, HZ / 5); |
2512 | bh_unlock_sock(sk); | 2718 | bh_unlock_sock(sk); |
2513 | return 0; | 2719 | return 0; |
2514 | } | 2720 | } |
@@ -2516,7 +2722,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2516 | l2cap_chan_del(chan, ECONNRESET); | 2722 | l2cap_chan_del(chan, ECONNRESET); |
2517 | bh_unlock_sock(sk); | 2723 | bh_unlock_sock(sk); |
2518 | 2724 | ||
2519 | l2cap_sock_kill(sk); | 2725 | chan->ops->close(chan->data); |
2520 | return 0; | 2726 | return 0; |
2521 | } | 2727 | } |
2522 | 2728 | ||
@@ -2540,9 +2746,9 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2540 | 2746 | ||
2541 | /* don't delete l2cap channel if sk is owned by user */ | 2747 | /* don't delete l2cap channel if sk is owned by user */ |
2542 | if (sock_owned_by_user(sk)) { | 2748 | if (sock_owned_by_user(sk)) { |
2543 | sk->sk_state = BT_DISCONN; | 2749 | l2cap_state_change(chan,BT_DISCONN); |
2544 | l2cap_sock_clear_timer(sk); | 2750 | __clear_chan_timer(chan); |
2545 | l2cap_sock_set_timer(sk, HZ / 5); | 2751 | __set_chan_timer(chan, HZ / 5); |
2546 | bh_unlock_sock(sk); | 2752 | bh_unlock_sock(sk); |
2547 | return 0; | 2753 | return 0; |
2548 | } | 2754 | } |
@@ -2550,7 +2756,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2550 | l2cap_chan_del(chan, 0); | 2756 | l2cap_chan_del(chan, 0); |
2551 | bh_unlock_sock(sk); | 2757 | bh_unlock_sock(sk); |
2552 | 2758 | ||
2553 | l2cap_sock_kill(sk); | 2759 | chan->ops->close(chan->data); |
2554 | return 0; | 2760 | return 0; |
2555 | } | 2761 | } |
2556 | 2762 | ||
@@ -2858,18 +3064,18 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) | |||
2858 | 3064 | ||
2859 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3065 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
2860 | 3066 | ||
2861 | if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 3067 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
2862 | control |= L2CAP_SUPER_RCV_NOT_READY; | 3068 | control |= L2CAP_SUPER_RCV_NOT_READY; |
2863 | l2cap_send_sframe(chan, control); | 3069 | l2cap_send_sframe(chan, control); |
2864 | chan->conn_state |= L2CAP_CONN_RNR_SENT; | 3070 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
2865 | } | 3071 | } |
2866 | 3072 | ||
2867 | if (chan->conn_state & L2CAP_CONN_REMOTE_BUSY) | 3073 | if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) |
2868 | l2cap_retransmit_frames(chan); | 3074 | l2cap_retransmit_frames(chan); |
2869 | 3075 | ||
2870 | l2cap_ertm_send(chan); | 3076 | l2cap_ertm_send(chan); |
2871 | 3077 | ||
2872 | if (!(chan->conn_state & L2CAP_CONN_LOCAL_BUSY) && | 3078 | if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && |
2873 | chan->frames_sent == 0) { | 3079 | chan->frames_sent == 0) { |
2874 | control |= L2CAP_SUPER_RCV_READY; | 3080 | control |= L2CAP_SUPER_RCV_READY; |
2875 | l2cap_send_sframe(chan, control); | 3081 | l2cap_send_sframe(chan, control); |
@@ -2925,17 +3131,13 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk | |||
2925 | 3131 | ||
2926 | switch (control & L2CAP_CTRL_SAR) { | 3132 | switch (control & L2CAP_CTRL_SAR) { |
2927 | case L2CAP_SDU_UNSEGMENTED: | 3133 | case L2CAP_SDU_UNSEGMENTED: |
2928 | if (chan->conn_state & L2CAP_CONN_SAR_SDU) | 3134 | if (test_bit(CONN_SAR_SDU, &chan->conn_state)) |
2929 | goto drop; | 3135 | goto drop; |
2930 | 3136 | ||
2931 | err = sock_queue_rcv_skb(chan->sk, skb); | 3137 | return chan->ops->recv(chan->data, skb); |
2932 | if (!err) | ||
2933 | return err; | ||
2934 | |||
2935 | break; | ||
2936 | 3138 | ||
2937 | case L2CAP_SDU_START: | 3139 | case L2CAP_SDU_START: |
2938 | if (chan->conn_state & L2CAP_CONN_SAR_SDU) | 3140 | if (test_bit(CONN_SAR_SDU, &chan->conn_state)) |
2939 | goto drop; | 3141 | goto drop; |
2940 | 3142 | ||
2941 | chan->sdu_len = get_unaligned_le16(skb->data); | 3143 | chan->sdu_len = get_unaligned_le16(skb->data); |
@@ -2954,12 +3156,12 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk | |||
2954 | 3156 | ||
2955 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | 3157 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
2956 | 3158 | ||
2957 | chan->conn_state |= L2CAP_CONN_SAR_SDU; | 3159 | set_bit(CONN_SAR_SDU, &chan->conn_state); |
2958 | chan->partial_sdu_len = skb->len; | 3160 | chan->partial_sdu_len = skb->len; |
2959 | break; | 3161 | break; |
2960 | 3162 | ||
2961 | case L2CAP_SDU_CONTINUE: | 3163 | case L2CAP_SDU_CONTINUE: |
2962 | if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) | 3164 | if (!test_bit(CONN_SAR_SDU, &chan->conn_state)) |
2963 | goto disconnect; | 3165 | goto disconnect; |
2964 | 3166 | ||
2965 | if (!chan->sdu) | 3167 | if (!chan->sdu) |
@@ -2974,13 +3176,13 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk | |||
2974 | break; | 3176 | break; |
2975 | 3177 | ||
2976 | case L2CAP_SDU_END: | 3178 | case L2CAP_SDU_END: |
2977 | if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) | 3179 | if (!test_bit(CONN_SAR_SDU, &chan->conn_state)) |
2978 | goto disconnect; | 3180 | goto disconnect; |
2979 | 3181 | ||
2980 | if (!chan->sdu) | 3182 | if (!chan->sdu) |
2981 | goto disconnect; | 3183 | goto disconnect; |
2982 | 3184 | ||
2983 | if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) { | 3185 | if (!test_bit(CONN_SAR_RETRY, &chan->conn_state)) { |
2984 | chan->partial_sdu_len += skb->len; | 3186 | chan->partial_sdu_len += skb->len; |
2985 | 3187 | ||
2986 | if (chan->partial_sdu_len > chan->imtu) | 3188 | if (chan->partial_sdu_len > chan->imtu) |
@@ -2994,19 +3196,19 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk | |||
2994 | 3196 | ||
2995 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); | 3197 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); |
2996 | if (!_skb) { | 3198 | if (!_skb) { |
2997 | chan->conn_state |= L2CAP_CONN_SAR_RETRY; | 3199 | set_bit(CONN_SAR_RETRY, &chan->conn_state); |
2998 | return -ENOMEM; | 3200 | return -ENOMEM; |
2999 | } | 3201 | } |
3000 | 3202 | ||
3001 | err = sock_queue_rcv_skb(chan->sk, _skb); | 3203 | err = chan->ops->recv(chan->data, _skb); |
3002 | if (err < 0) { | 3204 | if (err < 0) { |
3003 | kfree_skb(_skb); | 3205 | kfree_skb(_skb); |
3004 | chan->conn_state |= L2CAP_CONN_SAR_RETRY; | 3206 | set_bit(CONN_SAR_RETRY, &chan->conn_state); |
3005 | return err; | 3207 | return err; |
3006 | } | 3208 | } |
3007 | 3209 | ||
3008 | chan->conn_state &= ~L2CAP_CONN_SAR_RETRY; | 3210 | clear_bit(CONN_SAR_RETRY, &chan->conn_state); |
3009 | chan->conn_state &= ~L2CAP_CONN_SAR_SDU; | 3211 | clear_bit(CONN_SAR_SDU, &chan->conn_state); |
3010 | 3212 | ||
3011 | kfree_skb(chan->sdu); | 3213 | kfree_skb(chan->sdu); |
3012 | break; | 3214 | break; |
@@ -3042,7 +3244,7 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) | |||
3042 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; | 3244 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; |
3043 | } | 3245 | } |
3044 | 3246 | ||
3045 | if (!(chan->conn_state & L2CAP_CONN_RNR_SENT)) | 3247 | if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) |
3046 | goto done; | 3248 | goto done; |
3047 | 3249 | ||
3048 | control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3250 | control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
@@ -3050,14 +3252,14 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) | |||
3050 | l2cap_send_sframe(chan, control); | 3252 | l2cap_send_sframe(chan, control); |
3051 | chan->retry_count = 1; | 3253 | chan->retry_count = 1; |
3052 | 3254 | ||
3053 | del_timer(&chan->retrans_timer); | 3255 | __clear_retrans_timer(chan); |
3054 | __mod_monitor_timer(); | 3256 | __set_monitor_timer(chan); |
3055 | 3257 | ||
3056 | chan->conn_state |= L2CAP_CONN_WAIT_F; | 3258 | set_bit(CONN_WAIT_F, &chan->conn_state); |
3057 | 3259 | ||
3058 | done: | 3260 | done: |
3059 | chan->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; | 3261 | clear_bit(CONN_LOCAL_BUSY, &chan->conn_state); |
3060 | chan->conn_state &= ~L2CAP_CONN_RNR_SENT; | 3262 | clear_bit(CONN_RNR_SENT, &chan->conn_state); |
3061 | 3263 | ||
3062 | BT_DBG("chan %p, Exit local busy", chan); | 3264 | BT_DBG("chan %p, Exit local busy", chan); |
3063 | 3265 | ||
@@ -3115,7 +3317,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c | |||
3115 | { | 3317 | { |
3116 | int sctrl, err; | 3318 | int sctrl, err; |
3117 | 3319 | ||
3118 | if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { | 3320 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
3119 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | 3321 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; |
3120 | __skb_queue_tail(&chan->busy_q, skb); | 3322 | __skb_queue_tail(&chan->busy_q, skb); |
3121 | return l2cap_try_push_rx_skb(chan); | 3323 | return l2cap_try_push_rx_skb(chan); |
@@ -3132,7 +3334,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c | |||
3132 | /* Busy Condition */ | 3334 | /* Busy Condition */ |
3133 | BT_DBG("chan %p, Enter local busy", chan); | 3335 | BT_DBG("chan %p, Enter local busy", chan); |
3134 | 3336 | ||
3135 | chan->conn_state |= L2CAP_CONN_LOCAL_BUSY; | 3337 | set_bit(CONN_LOCAL_BUSY, &chan->conn_state); |
3136 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; | 3338 | bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; |
3137 | __skb_queue_tail(&chan->busy_q, skb); | 3339 | __skb_queue_tail(&chan->busy_q, skb); |
3138 | 3340 | ||
@@ -3140,9 +3342,9 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c | |||
3140 | sctrl |= L2CAP_SUPER_RCV_NOT_READY; | 3342 | sctrl |= L2CAP_SUPER_RCV_NOT_READY; |
3141 | l2cap_send_sframe(chan, sctrl); | 3343 | l2cap_send_sframe(chan, sctrl); |
3142 | 3344 | ||
3143 | chan->conn_state |= L2CAP_CONN_RNR_SENT; | 3345 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
3144 | 3346 | ||
3145 | del_timer(&chan->ack_timer); | 3347 | __clear_ack_timer(chan); |
3146 | 3348 | ||
3147 | queue_work(_busy_wq, &chan->busy_work); | 3349 | queue_work(_busy_wq, &chan->busy_work); |
3148 | 3350 | ||
@@ -3161,19 +3363,19 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf | |||
3161 | 3363 | ||
3162 | switch (control & L2CAP_CTRL_SAR) { | 3364 | switch (control & L2CAP_CTRL_SAR) { |
3163 | case L2CAP_SDU_UNSEGMENTED: | 3365 | case L2CAP_SDU_UNSEGMENTED: |
3164 | if (chan->conn_state & L2CAP_CONN_SAR_SDU) { | 3366 | if (test_bit(CONN_SAR_SDU, &chan->conn_state)) { |
3165 | kfree_skb(chan->sdu); | 3367 | kfree_skb(chan->sdu); |
3166 | break; | 3368 | break; |
3167 | } | 3369 | } |
3168 | 3370 | ||
3169 | err = sock_queue_rcv_skb(chan->sk, skb); | 3371 | err = chan->ops->recv(chan->data, skb); |
3170 | if (!err) | 3372 | if (!err) |
3171 | return 0; | 3373 | return 0; |
3172 | 3374 | ||
3173 | break; | 3375 | break; |
3174 | 3376 | ||
3175 | case L2CAP_SDU_START: | 3377 | case L2CAP_SDU_START: |
3176 | if (chan->conn_state & L2CAP_CONN_SAR_SDU) { | 3378 | if (test_bit(CONN_SAR_SDU, &chan->conn_state)) { |
3177 | kfree_skb(chan->sdu); | 3379 | kfree_skb(chan->sdu); |
3178 | break; | 3380 | break; |
3179 | } | 3381 | } |
@@ -3194,13 +3396,13 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf | |||
3194 | 3396 | ||
3195 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | 3397 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
3196 | 3398 | ||
3197 | chan->conn_state |= L2CAP_CONN_SAR_SDU; | 3399 | set_bit(CONN_SAR_SDU, &chan->conn_state); |
3198 | chan->partial_sdu_len = skb->len; | 3400 | chan->partial_sdu_len = skb->len; |
3199 | err = 0; | 3401 | err = 0; |
3200 | break; | 3402 | break; |
3201 | 3403 | ||
3202 | case L2CAP_SDU_CONTINUE: | 3404 | case L2CAP_SDU_CONTINUE: |
3203 | if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) | 3405 | if (!test_bit(CONN_SAR_SDU, &chan->conn_state)) |
3204 | break; | 3406 | break; |
3205 | 3407 | ||
3206 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | 3408 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
@@ -3214,12 +3416,12 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf | |||
3214 | break; | 3416 | break; |
3215 | 3417 | ||
3216 | case L2CAP_SDU_END: | 3418 | case L2CAP_SDU_END: |
3217 | if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) | 3419 | if (!test_bit(CONN_SAR_SDU, &chan->conn_state)) |
3218 | break; | 3420 | break; |
3219 | 3421 | ||
3220 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | 3422 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); |
3221 | 3423 | ||
3222 | chan->conn_state &= ~L2CAP_CONN_SAR_SDU; | 3424 | clear_bit(CONN_SAR_SDU, &chan->conn_state); |
3223 | chan->partial_sdu_len += skb->len; | 3425 | chan->partial_sdu_len += skb->len; |
3224 | 3426 | ||
3225 | if (chan->partial_sdu_len > chan->imtu) | 3427 | if (chan->partial_sdu_len > chan->imtu) |
@@ -3227,7 +3429,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf | |||
3227 | 3429 | ||
3228 | if (chan->partial_sdu_len == chan->sdu_len) { | 3430 | if (chan->partial_sdu_len == chan->sdu_len) { |
3229 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); | 3431 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); |
3230 | err = sock_queue_rcv_skb(chan->sk, _skb); | 3432 | err = chan->ops->recv(chan->data, _skb); |
3231 | if (err < 0) | 3433 | if (err < 0) |
3232 | kfree_skb(_skb); | 3434 | kfree_skb(_skb); |
3233 | } | 3435 | } |
@@ -3310,11 +3512,11 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3310 | tx_seq, rx_control); | 3512 | tx_seq, rx_control); |
3311 | 3513 | ||
3312 | if (L2CAP_CTRL_FINAL & rx_control && | 3514 | if (L2CAP_CTRL_FINAL & rx_control && |
3313 | chan->conn_state & L2CAP_CONN_WAIT_F) { | 3515 | test_bit(CONN_WAIT_F, &chan->conn_state)) { |
3314 | del_timer(&chan->monitor_timer); | 3516 | __clear_monitor_timer(chan); |
3315 | if (chan->unacked_frames > 0) | 3517 | if (chan->unacked_frames > 0) |
3316 | __mod_retrans_timer(); | 3518 | __set_retrans_timer(chan); |
3317 | chan->conn_state &= ~L2CAP_CONN_WAIT_F; | 3519 | clear_bit(CONN_WAIT_F, &chan->conn_state); |
3318 | } | 3520 | } |
3319 | 3521 | ||
3320 | chan->expected_ack_seq = req_seq; | 3522 | chan->expected_ack_seq = req_seq; |
@@ -3333,10 +3535,10 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3333 | goto drop; | 3535 | goto drop; |
3334 | } | 3536 | } |
3335 | 3537 | ||
3336 | if (chan->conn_state == L2CAP_CONN_LOCAL_BUSY) | 3538 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) |
3337 | goto drop; | 3539 | goto drop; |
3338 | 3540 | ||
3339 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { | 3541 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3340 | struct srej_list *first; | 3542 | struct srej_list *first; |
3341 | 3543 | ||
3342 | first = list_first_entry(&chan->srej_l, | 3544 | first = list_first_entry(&chan->srej_l, |
@@ -3350,7 +3552,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3350 | 3552 | ||
3351 | if (list_empty(&chan->srej_l)) { | 3553 | if (list_empty(&chan->srej_l)) { |
3352 | chan->buffer_seq = chan->buffer_seq_srej; | 3554 | chan->buffer_seq = chan->buffer_seq_srej; |
3353 | chan->conn_state &= ~L2CAP_CONN_SREJ_SENT; | 3555 | clear_bit(CONN_SREJ_SENT, &chan->conn_state); |
3354 | l2cap_send_ack(chan); | 3556 | l2cap_send_ack(chan); |
3355 | BT_DBG("chan %p, Exit SREJ_SENT", chan); | 3557 | BT_DBG("chan %p, Exit SREJ_SENT", chan); |
3356 | } | 3558 | } |
@@ -3379,7 +3581,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3379 | if (tx_seq_offset < expected_tx_seq_offset) | 3581 | if (tx_seq_offset < expected_tx_seq_offset) |
3380 | goto drop; | 3582 | goto drop; |
3381 | 3583 | ||
3382 | chan->conn_state |= L2CAP_CONN_SREJ_SENT; | 3584 | set_bit(CONN_SREJ_SENT, &chan->conn_state); |
3383 | 3585 | ||
3384 | BT_DBG("chan %p, Enter SREJ", chan); | 3586 | BT_DBG("chan %p, Enter SREJ", chan); |
3385 | 3587 | ||
@@ -3390,18 +3592,18 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3390 | __skb_queue_head_init(&chan->busy_q); | 3592 | __skb_queue_head_init(&chan->busy_q); |
3391 | l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); | 3593 | l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); |
3392 | 3594 | ||
3393 | chan->conn_state |= L2CAP_CONN_SEND_PBIT; | 3595 | set_bit(CONN_SEND_PBIT, &chan->conn_state); |
3394 | 3596 | ||
3395 | l2cap_send_srejframe(chan, tx_seq); | 3597 | l2cap_send_srejframe(chan, tx_seq); |
3396 | 3598 | ||
3397 | del_timer(&chan->ack_timer); | 3599 | __clear_ack_timer(chan); |
3398 | } | 3600 | } |
3399 | return 0; | 3601 | return 0; |
3400 | 3602 | ||
3401 | expected: | 3603 | expected: |
3402 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; | 3604 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; |
3403 | 3605 | ||
3404 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { | 3606 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3405 | bt_cb(skb)->tx_seq = tx_seq; | 3607 | bt_cb(skb)->tx_seq = tx_seq; |
3406 | bt_cb(skb)->sar = sar; | 3608 | bt_cb(skb)->sar = sar; |
3407 | __skb_queue_tail(&chan->srej_q, skb); | 3609 | __skb_queue_tail(&chan->srej_q, skb); |
@@ -3413,13 +3615,11 @@ expected: | |||
3413 | return 0; | 3615 | return 0; |
3414 | 3616 | ||
3415 | if (rx_control & L2CAP_CTRL_FINAL) { | 3617 | if (rx_control & L2CAP_CTRL_FINAL) { |
3416 | if (chan->conn_state & L2CAP_CONN_REJ_ACT) | 3618 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
3417 | chan->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3418 | else | ||
3419 | l2cap_retransmit_frames(chan); | 3619 | l2cap_retransmit_frames(chan); |
3420 | } | 3620 | } |
3421 | 3621 | ||
3422 | __mod_ack_timer(); | 3622 | __set_ack_timer(chan); |
3423 | 3623 | ||
3424 | chan->num_acked = (chan->num_acked + 1) % num_to_ack; | 3624 | chan->num_acked = (chan->num_acked + 1) % num_to_ack; |
3425 | if (chan->num_acked == num_to_ack - 1) | 3625 | if (chan->num_acked == num_to_ack - 1) |
@@ -3441,33 +3641,31 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co | |||
3441 | l2cap_drop_acked_frames(chan); | 3641 | l2cap_drop_acked_frames(chan); |
3442 | 3642 | ||
3443 | if (rx_control & L2CAP_CTRL_POLL) { | 3643 | if (rx_control & L2CAP_CTRL_POLL) { |
3444 | chan->conn_state |= L2CAP_CONN_SEND_FBIT; | 3644 | set_bit(CONN_SEND_FBIT, &chan->conn_state); |
3445 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { | 3645 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3446 | if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && | 3646 | if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && |
3447 | (chan->unacked_frames > 0)) | 3647 | (chan->unacked_frames > 0)) |
3448 | __mod_retrans_timer(); | 3648 | __set_retrans_timer(chan); |
3449 | 3649 | ||
3450 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3650 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3451 | l2cap_send_srejtail(chan); | 3651 | l2cap_send_srejtail(chan); |
3452 | } else { | 3652 | } else { |
3453 | l2cap_send_i_or_rr_or_rnr(chan); | 3653 | l2cap_send_i_or_rr_or_rnr(chan); |
3454 | } | 3654 | } |
3455 | 3655 | ||
3456 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3656 | } else if (rx_control & L2CAP_CTRL_FINAL) { |
3457 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3657 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3458 | 3658 | ||
3459 | if (chan->conn_state & L2CAP_CONN_REJ_ACT) | 3659 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
3460 | chan->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3461 | else | ||
3462 | l2cap_retransmit_frames(chan); | 3660 | l2cap_retransmit_frames(chan); |
3463 | 3661 | ||
3464 | } else { | 3662 | } else { |
3465 | if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && | 3663 | if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && |
3466 | (chan->unacked_frames > 0)) | 3664 | (chan->unacked_frames > 0)) |
3467 | __mod_retrans_timer(); | 3665 | __set_retrans_timer(chan); |
3468 | 3666 | ||
3469 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3667 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3470 | if (chan->conn_state & L2CAP_CONN_SREJ_SENT) | 3668 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) |
3471 | l2cap_send_ack(chan); | 3669 | l2cap_send_ack(chan); |
3472 | else | 3670 | else |
3473 | l2cap_ertm_send(chan); | 3671 | l2cap_ertm_send(chan); |
@@ -3480,21 +3678,19 @@ static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_c | |||
3480 | 3678 | ||
3481 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 3679 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); |
3482 | 3680 | ||
3483 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3681 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3484 | 3682 | ||
3485 | chan->expected_ack_seq = tx_seq; | 3683 | chan->expected_ack_seq = tx_seq; |
3486 | l2cap_drop_acked_frames(chan); | 3684 | l2cap_drop_acked_frames(chan); |
3487 | 3685 | ||
3488 | if (rx_control & L2CAP_CTRL_FINAL) { | 3686 | if (rx_control & L2CAP_CTRL_FINAL) { |
3489 | if (chan->conn_state & L2CAP_CONN_REJ_ACT) | 3687 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
3490 | chan->conn_state &= ~L2CAP_CONN_REJ_ACT; | ||
3491 | else | ||
3492 | l2cap_retransmit_frames(chan); | 3688 | l2cap_retransmit_frames(chan); |
3493 | } else { | 3689 | } else { |
3494 | l2cap_retransmit_frames(chan); | 3690 | l2cap_retransmit_frames(chan); |
3495 | 3691 | ||
3496 | if (chan->conn_state & L2CAP_CONN_WAIT_F) | 3692 | if (test_bit(CONN_WAIT_F, &chan->conn_state)) |
3497 | chan->conn_state |= L2CAP_CONN_REJ_ACT; | 3693 | set_bit(CONN_REJ_ACT, &chan->conn_state); |
3498 | } | 3694 | } |
3499 | } | 3695 | } |
3500 | static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control) | 3696 | static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control) |
@@ -3503,32 +3699,32 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_ | |||
3503 | 3699 | ||
3504 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 3700 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); |
3505 | 3701 | ||
3506 | chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | 3702 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3507 | 3703 | ||
3508 | if (rx_control & L2CAP_CTRL_POLL) { | 3704 | if (rx_control & L2CAP_CTRL_POLL) { |
3509 | chan->expected_ack_seq = tx_seq; | 3705 | chan->expected_ack_seq = tx_seq; |
3510 | l2cap_drop_acked_frames(chan); | 3706 | l2cap_drop_acked_frames(chan); |
3511 | 3707 | ||
3512 | chan->conn_state |= L2CAP_CONN_SEND_FBIT; | 3708 | set_bit(CONN_SEND_FBIT, &chan->conn_state); |
3513 | l2cap_retransmit_one_frame(chan, tx_seq); | 3709 | l2cap_retransmit_one_frame(chan, tx_seq); |
3514 | 3710 | ||
3515 | l2cap_ertm_send(chan); | 3711 | l2cap_ertm_send(chan); |
3516 | 3712 | ||
3517 | if (chan->conn_state & L2CAP_CONN_WAIT_F) { | 3713 | if (test_bit(CONN_WAIT_F, &chan->conn_state)) { |
3518 | chan->srej_save_reqseq = tx_seq; | 3714 | chan->srej_save_reqseq = tx_seq; |
3519 | chan->conn_state |= L2CAP_CONN_SREJ_ACT; | 3715 | set_bit(CONN_SREJ_ACT, &chan->conn_state); |
3520 | } | 3716 | } |
3521 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3717 | } else if (rx_control & L2CAP_CTRL_FINAL) { |
3522 | if ((chan->conn_state & L2CAP_CONN_SREJ_ACT) && | 3718 | if (test_bit(CONN_SREJ_ACT, &chan->conn_state) && |
3523 | chan->srej_save_reqseq == tx_seq) | 3719 | chan->srej_save_reqseq == tx_seq) |
3524 | chan->conn_state &= ~L2CAP_CONN_SREJ_ACT; | 3720 | clear_bit(CONN_SREJ_ACT, &chan->conn_state); |
3525 | else | 3721 | else |
3526 | l2cap_retransmit_one_frame(chan, tx_seq); | 3722 | l2cap_retransmit_one_frame(chan, tx_seq); |
3527 | } else { | 3723 | } else { |
3528 | l2cap_retransmit_one_frame(chan, tx_seq); | 3724 | l2cap_retransmit_one_frame(chan, tx_seq); |
3529 | if (chan->conn_state & L2CAP_CONN_WAIT_F) { | 3725 | if (test_bit(CONN_WAIT_F, &chan->conn_state)) { |
3530 | chan->srej_save_reqseq = tx_seq; | 3726 | chan->srej_save_reqseq = tx_seq; |
3531 | chan->conn_state |= L2CAP_CONN_SREJ_ACT; | 3727 | set_bit(CONN_SREJ_ACT, &chan->conn_state); |
3532 | } | 3728 | } |
3533 | } | 3729 | } |
3534 | } | 3730 | } |
@@ -3539,15 +3735,15 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_c | |||
3539 | 3735 | ||
3540 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 3736 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); |
3541 | 3737 | ||
3542 | chan->conn_state |= L2CAP_CONN_REMOTE_BUSY; | 3738 | set_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3543 | chan->expected_ack_seq = tx_seq; | 3739 | chan->expected_ack_seq = tx_seq; |
3544 | l2cap_drop_acked_frames(chan); | 3740 | l2cap_drop_acked_frames(chan); |
3545 | 3741 | ||
3546 | if (rx_control & L2CAP_CTRL_POLL) | 3742 | if (rx_control & L2CAP_CTRL_POLL) |
3547 | chan->conn_state |= L2CAP_CONN_SEND_FBIT; | 3743 | set_bit(CONN_SEND_FBIT, &chan->conn_state); |
3548 | 3744 | ||
3549 | if (!(chan->conn_state & L2CAP_CONN_SREJ_SENT)) { | 3745 | if (!test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3550 | del_timer(&chan->retrans_timer); | 3746 | __clear_retrans_timer(chan); |
3551 | if (rx_control & L2CAP_CTRL_POLL) | 3747 | if (rx_control & L2CAP_CTRL_POLL) |
3552 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); | 3748 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); |
3553 | return; | 3749 | return; |
@@ -3564,11 +3760,11 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont | |||
3564 | BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len); | 3760 | BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len); |
3565 | 3761 | ||
3566 | if (L2CAP_CTRL_FINAL & rx_control && | 3762 | if (L2CAP_CTRL_FINAL & rx_control && |
3567 | chan->conn_state & L2CAP_CONN_WAIT_F) { | 3763 | test_bit(CONN_WAIT_F, &chan->conn_state)) { |
3568 | del_timer(&chan->monitor_timer); | 3764 | __clear_monitor_timer(chan); |
3569 | if (chan->unacked_frames > 0) | 3765 | if (chan->unacked_frames > 0) |
3570 | __mod_retrans_timer(); | 3766 | __set_retrans_timer(chan); |
3571 | chan->conn_state &= ~L2CAP_CONN_WAIT_F; | 3767 | clear_bit(CONN_WAIT_F, &chan->conn_state); |
3572 | } | 3768 | } |
3573 | 3769 | ||
3574 | switch (rx_control & L2CAP_CTRL_SUPERVISE) { | 3770 | switch (rx_control & L2CAP_CTRL_SUPERVISE) { |
@@ -3667,7 +3863,6 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3667 | { | 3863 | { |
3668 | struct l2cap_chan *chan; | 3864 | struct l2cap_chan *chan; |
3669 | struct sock *sk = NULL; | 3865 | struct sock *sk = NULL; |
3670 | struct l2cap_pinfo *pi; | ||
3671 | u16 control; | 3866 | u16 control; |
3672 | u8 tx_seq; | 3867 | u8 tx_seq; |
3673 | int len; | 3868 | int len; |
@@ -3679,11 +3874,10 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3679 | } | 3874 | } |
3680 | 3875 | ||
3681 | sk = chan->sk; | 3876 | sk = chan->sk; |
3682 | pi = l2cap_pi(sk); | ||
3683 | 3877 | ||
3684 | BT_DBG("chan %p, len %d", chan, skb->len); | 3878 | BT_DBG("chan %p, len %d", chan, skb->len); |
3685 | 3879 | ||
3686 | if (sk->sk_state != BT_CONNECTED) | 3880 | if (chan->state != BT_CONNECTED) |
3687 | goto drop; | 3881 | goto drop; |
3688 | 3882 | ||
3689 | switch (chan->mode) { | 3883 | switch (chan->mode) { |
@@ -3696,7 +3890,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3696 | if (chan->imtu < skb->len) | 3890 | if (chan->imtu < skb->len) |
3697 | goto drop; | 3891 | goto drop; |
3698 | 3892 | ||
3699 | if (!sock_queue_rcv_skb(sk, skb)) | 3893 | if (!chan->ops->recv(chan->data, skb)) |
3700 | goto done; | 3894 | goto done; |
3701 | break; | 3895 | break; |
3702 | 3896 | ||
@@ -3768,13 +3962,13 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str | |||
3768 | 3962 | ||
3769 | BT_DBG("sk %p, len %d", sk, skb->len); | 3963 | BT_DBG("sk %p, len %d", sk, skb->len); |
3770 | 3964 | ||
3771 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) | 3965 | if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) |
3772 | goto drop; | 3966 | goto drop; |
3773 | 3967 | ||
3774 | if (l2cap_pi(sk)->chan->imtu < skb->len) | 3968 | if (chan->imtu < skb->len) |
3775 | goto drop; | 3969 | goto drop; |
3776 | 3970 | ||
3777 | if (!sock_queue_rcv_skb(sk, skb)) | 3971 | if (!chan->ops->recv(chan->data, skb)) |
3778 | goto done; | 3972 | goto done; |
3779 | 3973 | ||
3780 | drop: | 3974 | drop: |
@@ -3801,13 +3995,13 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct | |||
3801 | 3995 | ||
3802 | BT_DBG("sk %p, len %d", sk, skb->len); | 3996 | BT_DBG("sk %p, len %d", sk, skb->len); |
3803 | 3997 | ||
3804 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) | 3998 | if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) |
3805 | goto drop; | 3999 | goto drop; |
3806 | 4000 | ||
3807 | if (l2cap_pi(sk)->chan->imtu < skb->len) | 4001 | if (chan->imtu < skb->len) |
3808 | goto drop; | 4002 | goto drop; |
3809 | 4003 | ||
3810 | if (!sock_queue_rcv_skb(sk, skb)) | 4004 | if (!chan->ops->recv(chan->data, skb)) |
3811 | goto done; | 4005 | goto done; |
3812 | 4006 | ||
3813 | drop: | 4007 | drop: |
@@ -3852,6 +4046,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
3852 | l2cap_att_channel(conn, cid, skb); | 4046 | l2cap_att_channel(conn, cid, skb); |
3853 | break; | 4047 | break; |
3854 | 4048 | ||
4049 | case L2CAP_CID_SMP: | ||
4050 | if (smp_sig_channel(conn, skb)) | ||
4051 | l2cap_conn_del(conn->hcon, EACCES); | ||
4052 | break; | ||
4053 | |||
3855 | default: | 4054 | default: |
3856 | l2cap_data_channel(conn, cid, skb); | 4055 | l2cap_data_channel(conn, cid, skb); |
3857 | break; | 4056 | break; |
@@ -3875,7 +4074,7 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
3875 | list_for_each_entry(c, &chan_list, global_l) { | 4074 | list_for_each_entry(c, &chan_list, global_l) { |
3876 | struct sock *sk = c->sk; | 4075 | struct sock *sk = c->sk; |
3877 | 4076 | ||
3878 | if (sk->sk_state != BT_LISTEN) | 4077 | if (c->state != BT_LISTEN) |
3879 | continue; | 4078 | continue; |
3880 | 4079 | ||
3881 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { | 4080 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { |
@@ -3919,7 +4118,7 @@ static int l2cap_disconn_ind(struct hci_conn *hcon) | |||
3919 | 4118 | ||
3920 | BT_DBG("hcon %p", hcon); | 4119 | BT_DBG("hcon %p", hcon); |
3921 | 4120 | ||
3922 | if (hcon->type != ACL_LINK || !conn) | 4121 | if ((hcon->type != ACL_LINK && hcon->type != LE_LINK) || !conn) |
3923 | return 0x13; | 4122 | return 0x13; |
3924 | 4123 | ||
3925 | return conn->disc_reason; | 4124 | return conn->disc_reason; |
@@ -3939,20 +4138,18 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) | |||
3939 | 4138 | ||
3940 | static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) | 4139 | static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) |
3941 | { | 4140 | { |
3942 | struct sock *sk = chan->sk; | 4141 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) |
3943 | |||
3944 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) | ||
3945 | return; | 4142 | return; |
3946 | 4143 | ||
3947 | if (encrypt == 0x00) { | 4144 | if (encrypt == 0x00) { |
3948 | if (chan->sec_level == BT_SECURITY_MEDIUM) { | 4145 | if (chan->sec_level == BT_SECURITY_MEDIUM) { |
3949 | l2cap_sock_clear_timer(sk); | 4146 | __clear_chan_timer(chan); |
3950 | l2cap_sock_set_timer(sk, HZ * 5); | 4147 | __set_chan_timer(chan, HZ * 5); |
3951 | } else if (chan->sec_level == BT_SECURITY_HIGH) | 4148 | } else if (chan->sec_level == BT_SECURITY_HIGH) |
3952 | __l2cap_sock_close(sk, ECONNREFUSED); | 4149 | l2cap_chan_close(chan, ECONNREFUSED); |
3953 | } else { | 4150 | } else { |
3954 | if (chan->sec_level == BT_SECURITY_MEDIUM) | 4151 | if (chan->sec_level == BT_SECURITY_MEDIUM) |
3955 | l2cap_sock_clear_timer(sk); | 4152 | __clear_chan_timer(chan); |
3956 | } | 4153 | } |
3957 | } | 4154 | } |
3958 | 4155 | ||
@@ -3973,50 +4170,72 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
3973 | 4170 | ||
3974 | bh_lock_sock(sk); | 4171 | bh_lock_sock(sk); |
3975 | 4172 | ||
3976 | if (chan->conf_state & L2CAP_CONF_CONNECT_PEND) { | 4173 | BT_DBG("chan->scid %d", chan->scid); |
4174 | |||
4175 | if (chan->scid == L2CAP_CID_LE_DATA) { | ||
4176 | if (!status && encrypt) { | ||
4177 | chan->sec_level = hcon->sec_level; | ||
4178 | del_timer(&conn->security_timer); | ||
4179 | l2cap_chan_ready(sk); | ||
4180 | } | ||
4181 | |||
3977 | bh_unlock_sock(sk); | 4182 | bh_unlock_sock(sk); |
3978 | continue; | 4183 | continue; |
3979 | } | 4184 | } |
3980 | 4185 | ||
3981 | if (!status && (sk->sk_state == BT_CONNECTED || | 4186 | if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) { |
3982 | sk->sk_state == BT_CONFIG)) { | 4187 | bh_unlock_sock(sk); |
4188 | continue; | ||
4189 | } | ||
4190 | |||
4191 | if (!status && (chan->state == BT_CONNECTED || | ||
4192 | chan->state == BT_CONFIG)) { | ||
3983 | l2cap_check_encryption(chan, encrypt); | 4193 | l2cap_check_encryption(chan, encrypt); |
3984 | bh_unlock_sock(sk); | 4194 | bh_unlock_sock(sk); |
3985 | continue; | 4195 | continue; |
3986 | } | 4196 | } |
3987 | 4197 | ||
3988 | if (sk->sk_state == BT_CONNECT) { | 4198 | if (chan->state == BT_CONNECT) { |
3989 | if (!status) { | 4199 | if (!status) { |
3990 | struct l2cap_conn_req req; | 4200 | struct l2cap_conn_req req; |
3991 | req.scid = cpu_to_le16(chan->scid); | 4201 | req.scid = cpu_to_le16(chan->scid); |
3992 | req.psm = chan->psm; | 4202 | req.psm = chan->psm; |
3993 | 4203 | ||
3994 | chan->ident = l2cap_get_ident(conn); | 4204 | chan->ident = l2cap_get_ident(conn); |
3995 | chan->conf_state |= L2CAP_CONF_CONNECT_PEND; | 4205 | set_bit(CONF_CONNECT_PEND, &chan->conf_state); |
3996 | 4206 | ||
3997 | l2cap_send_cmd(conn, chan->ident, | 4207 | l2cap_send_cmd(conn, chan->ident, |
3998 | L2CAP_CONN_REQ, sizeof(req), &req); | 4208 | L2CAP_CONN_REQ, sizeof(req), &req); |
3999 | } else { | 4209 | } else { |
4000 | l2cap_sock_clear_timer(sk); | 4210 | __clear_chan_timer(chan); |
4001 | l2cap_sock_set_timer(sk, HZ / 10); | 4211 | __set_chan_timer(chan, HZ / 10); |
4002 | } | 4212 | } |
4003 | } else if (sk->sk_state == BT_CONNECT2) { | 4213 | } else if (chan->state == BT_CONNECT2) { |
4004 | struct l2cap_conn_rsp rsp; | 4214 | struct l2cap_conn_rsp rsp; |
4005 | __u16 result; | 4215 | __u16 res, stat; |
4006 | 4216 | ||
4007 | if (!status) { | 4217 | if (!status) { |
4008 | sk->sk_state = BT_CONFIG; | 4218 | if (bt_sk(sk)->defer_setup) { |
4009 | result = L2CAP_CR_SUCCESS; | 4219 | struct sock *parent = bt_sk(sk)->parent; |
4220 | res = L2CAP_CR_PEND; | ||
4221 | stat = L2CAP_CS_AUTHOR_PEND; | ||
4222 | parent->sk_data_ready(parent, 0); | ||
4223 | } else { | ||
4224 | l2cap_state_change(chan, BT_CONFIG); | ||
4225 | res = L2CAP_CR_SUCCESS; | ||
4226 | stat = L2CAP_CS_NO_INFO; | ||
4227 | } | ||
4010 | } else { | 4228 | } else { |
4011 | sk->sk_state = BT_DISCONN; | 4229 | l2cap_state_change(chan, BT_DISCONN); |
4012 | l2cap_sock_set_timer(sk, HZ / 10); | 4230 | __set_chan_timer(chan, HZ / 10); |
4013 | result = L2CAP_CR_SEC_BLOCK; | 4231 | res = L2CAP_CR_SEC_BLOCK; |
4232 | stat = L2CAP_CS_NO_INFO; | ||
4014 | } | 4233 | } |
4015 | 4234 | ||
4016 | rsp.scid = cpu_to_le16(chan->dcid); | 4235 | rsp.scid = cpu_to_le16(chan->dcid); |
4017 | rsp.dcid = cpu_to_le16(chan->scid); | 4236 | rsp.dcid = cpu_to_le16(chan->scid); |
4018 | rsp.result = cpu_to_le16(result); | 4237 | rsp.result = cpu_to_le16(res); |
4019 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | 4238 | rsp.status = cpu_to_le16(stat); |
4020 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 4239 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
4021 | sizeof(rsp), &rsp); | 4240 | sizeof(rsp), &rsp); |
4022 | } | 4241 | } |
@@ -4152,10 +4371,10 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p) | |||
4152 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", | 4371 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", |
4153 | batostr(&bt_sk(sk)->src), | 4372 | batostr(&bt_sk(sk)->src), |
4154 | batostr(&bt_sk(sk)->dst), | 4373 | batostr(&bt_sk(sk)->dst), |
4155 | sk->sk_state, __le16_to_cpu(c->psm), | 4374 | c->state, __le16_to_cpu(c->psm), |
4156 | c->scid, c->dcid, c->imtu, c->omtu, | 4375 | c->scid, c->dcid, c->imtu, c->omtu, |
4157 | c->sec_level, c->mode); | 4376 | c->sec_level, c->mode); |
4158 | } | 4377 | } |
4159 | 4378 | ||
4160 | read_unlock_bh(&chan_list_lock); | 4379 | read_unlock_bh(&chan_list_lock); |
4161 | 4380 | ||
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 8248303f44e8..39082d4e77ce 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -29,54 +29,11 @@ | |||
29 | #include <net/bluetooth/bluetooth.h> | 29 | #include <net/bluetooth/bluetooth.h> |
30 | #include <net/bluetooth/hci_core.h> | 30 | #include <net/bluetooth/hci_core.h> |
31 | #include <net/bluetooth/l2cap.h> | 31 | #include <net/bluetooth/l2cap.h> |
32 | #include <net/bluetooth/smp.h> | ||
32 | 33 | ||
33 | static const struct proto_ops l2cap_sock_ops; | 34 | static const struct proto_ops l2cap_sock_ops; |
34 | 35 | static void l2cap_sock_init(struct sock *sk, struct sock *parent); | |
35 | /* ---- L2CAP timers ---- */ | 36 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); |
36 | static void l2cap_sock_timeout(unsigned long arg) | ||
37 | { | ||
38 | struct sock *sk = (struct sock *) arg; | ||
39 | int reason; | ||
40 | |||
41 | BT_DBG("sock %p state %d", sk, sk->sk_state); | ||
42 | |||
43 | bh_lock_sock(sk); | ||
44 | |||
45 | if (sock_owned_by_user(sk)) { | ||
46 | /* sk is owned by user. Try again later */ | ||
47 | l2cap_sock_set_timer(sk, HZ / 5); | ||
48 | bh_unlock_sock(sk); | ||
49 | sock_put(sk); | ||
50 | return; | ||
51 | } | ||
52 | |||
53 | if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) | ||
54 | reason = ECONNREFUSED; | ||
55 | else if (sk->sk_state == BT_CONNECT && | ||
56 | l2cap_pi(sk)->chan->sec_level != BT_SECURITY_SDP) | ||
57 | reason = ECONNREFUSED; | ||
58 | else | ||
59 | reason = ETIMEDOUT; | ||
60 | |||
61 | __l2cap_sock_close(sk, reason); | ||
62 | |||
63 | bh_unlock_sock(sk); | ||
64 | |||
65 | l2cap_sock_kill(sk); | ||
66 | sock_put(sk); | ||
67 | } | ||
68 | |||
69 | void l2cap_sock_set_timer(struct sock *sk, long timeout) | ||
70 | { | ||
71 | BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); | ||
72 | sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); | ||
73 | } | ||
74 | |||
75 | void l2cap_sock_clear_timer(struct sock *sk) | ||
76 | { | ||
77 | BT_DBG("sock %p state %d", sk, sk->sk_state); | ||
78 | sk_stop_timer(sk, &sk->sk_timer); | ||
79 | } | ||
80 | 37 | ||
81 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | 38 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) |
82 | { | 39 | { |
@@ -133,6 +90,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
133 | chan->sec_level = BT_SECURITY_SDP; | 90 | chan->sec_level = BT_SECURITY_SDP; |
134 | 91 | ||
135 | bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); | 92 | bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); |
93 | |||
94 | chan->state = BT_BOUND; | ||
136 | sk->sk_state = BT_BOUND; | 95 | sk->sk_state = BT_BOUND; |
137 | 96 | ||
138 | done: | 97 | done: |
@@ -162,7 +121,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
162 | 121 | ||
163 | lock_sock(sk); | 122 | lock_sock(sk); |
164 | 123 | ||
165 | if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) | 124 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED |
166 | && !(la.l2_psm || la.l2_cid)) { | 125 | && !(la.l2_psm || la.l2_cid)) { |
167 | err = -EINVAL; | 126 | err = -EINVAL; |
168 | goto done; | 127 | goto done; |
@@ -204,8 +163,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
204 | } | 163 | } |
205 | 164 | ||
206 | /* PSM must be odd and lsb of upper byte must be 0 */ | 165 | /* PSM must be odd and lsb of upper byte must be 0 */ |
207 | if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && | 166 | if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && !la.l2_cid && |
208 | sk->sk_type != SOCK_RAW && !la.l2_cid) { | 167 | chan->chan_type != L2CAP_CHAN_RAW) { |
209 | err = -EINVAL; | 168 | err = -EINVAL; |
210 | goto done; | 169 | goto done; |
211 | } | 170 | } |
@@ -258,6 +217,8 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) | |||
258 | 217 | ||
259 | sk->sk_max_ack_backlog = backlog; | 218 | sk->sk_max_ack_backlog = backlog; |
260 | sk->sk_ack_backlog = 0; | 219 | sk->sk_ack_backlog = 0; |
220 | |||
221 | chan->state = BT_LISTEN; | ||
261 | sk->sk_state = BT_LISTEN; | 222 | sk->sk_state = BT_LISTEN; |
262 | 223 | ||
263 | done: | 224 | done: |
@@ -437,6 +398,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
437 | struct sock *sk = sock->sk; | 398 | struct sock *sk = sock->sk; |
438 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 399 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
439 | struct bt_security sec; | 400 | struct bt_security sec; |
401 | struct bt_power pwr; | ||
440 | int len, err = 0; | 402 | int len, err = 0; |
441 | 403 | ||
442 | BT_DBG("sk %p", sk); | 404 | BT_DBG("sk %p", sk); |
@@ -454,8 +416,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
454 | 416 | ||
455 | switch (optname) { | 417 | switch (optname) { |
456 | case BT_SECURITY: | 418 | case BT_SECURITY: |
457 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM | 419 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && |
458 | && sk->sk_type != SOCK_RAW) { | 420 | chan->chan_type != L2CAP_CHAN_RAW) { |
459 | err = -EINVAL; | 421 | err = -EINVAL; |
460 | break; | 422 | break; |
461 | } | 423 | } |
@@ -485,6 +447,21 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
485 | 447 | ||
486 | break; | 448 | break; |
487 | 449 | ||
450 | case BT_POWER: | ||
451 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM | ||
452 | && sk->sk_type != SOCK_RAW) { | ||
453 | err = -EINVAL; | ||
454 | break; | ||
455 | } | ||
456 | |||
457 | pwr.force_active = chan->force_active; | ||
458 | |||
459 | len = min_t(unsigned int, len, sizeof(pwr)); | ||
460 | if (copy_to_user(optval, (char *) &pwr, len)) | ||
461 | err = -EFAULT; | ||
462 | |||
463 | break; | ||
464 | |||
488 | default: | 465 | default: |
489 | err = -ENOPROTOOPT; | 466 | err = -ENOPROTOOPT; |
490 | break; | 467 | break; |
@@ -535,7 +512,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
535 | chan->mode = opts.mode; | 512 | chan->mode = opts.mode; |
536 | switch (chan->mode) { | 513 | switch (chan->mode) { |
537 | case L2CAP_MODE_BASIC: | 514 | case L2CAP_MODE_BASIC: |
538 | chan->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; | 515 | clear_bit(CONF_STATE2_DEVICE, &chan->conf_state); |
539 | break; | 516 | break; |
540 | case L2CAP_MODE_ERTM: | 517 | case L2CAP_MODE_ERTM: |
541 | case L2CAP_MODE_STREAMING: | 518 | case L2CAP_MODE_STREAMING: |
@@ -585,6 +562,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
585 | struct sock *sk = sock->sk; | 562 | struct sock *sk = sock->sk; |
586 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 563 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
587 | struct bt_security sec; | 564 | struct bt_security sec; |
565 | struct bt_power pwr; | ||
566 | struct l2cap_conn *conn; | ||
588 | int len, err = 0; | 567 | int len, err = 0; |
589 | u32 opt; | 568 | u32 opt; |
590 | 569 | ||
@@ -600,8 +579,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
600 | 579 | ||
601 | switch (optname) { | 580 | switch (optname) { |
602 | case BT_SECURITY: | 581 | case BT_SECURITY: |
603 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM | 582 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && |
604 | && sk->sk_type != SOCK_RAW) { | 583 | chan->chan_type != L2CAP_CHAN_RAW) { |
605 | err = -EINVAL; | 584 | err = -EINVAL; |
606 | break; | 585 | break; |
607 | } | 586 | } |
@@ -621,6 +600,20 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
621 | } | 600 | } |
622 | 601 | ||
623 | chan->sec_level = sec.level; | 602 | chan->sec_level = sec.level; |
603 | |||
604 | conn = chan->conn; | ||
605 | if (conn && chan->scid == L2CAP_CID_LE_DATA) { | ||
606 | if (!conn->hcon->out) { | ||
607 | err = -EINVAL; | ||
608 | break; | ||
609 | } | ||
610 | |||
611 | if (smp_conn_security(conn, sec.level)) | ||
612 | break; | ||
613 | |||
614 | err = 0; | ||
615 | sk->sk_state = BT_CONFIG; | ||
616 | } | ||
624 | break; | 617 | break; |
625 | 618 | ||
626 | case BT_DEFER_SETUP: | 619 | case BT_DEFER_SETUP: |
@@ -661,6 +654,23 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
661 | chan->flushable = opt; | 654 | chan->flushable = opt; |
662 | break; | 655 | break; |
663 | 656 | ||
657 | case BT_POWER: | ||
658 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && | ||
659 | chan->chan_type != L2CAP_CHAN_RAW) { | ||
660 | err = -EINVAL; | ||
661 | break; | ||
662 | } | ||
663 | |||
664 | pwr.force_active = BT_POWER_FORCE_ACTIVE_ON; | ||
665 | |||
666 | len = min_t(unsigned int, sizeof(pwr), optlen); | ||
667 | if (copy_from_user((char *) &pwr, optval, len)) { | ||
668 | err = -EFAULT; | ||
669 | break; | ||
670 | } | ||
671 | chan->force_active = pwr.force_active; | ||
672 | break; | ||
673 | |||
664 | default: | 674 | default: |
665 | err = -ENOPROTOOPT; | 675 | err = -ENOPROTOOPT; |
666 | break; | 676 | break; |
@@ -674,8 +684,6 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
674 | { | 684 | { |
675 | struct sock *sk = sock->sk; | 685 | struct sock *sk = sock->sk; |
676 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 686 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
677 | struct sk_buff *skb; | ||
678 | u16 control; | ||
679 | int err; | 687 | int err; |
680 | 688 | ||
681 | BT_DBG("sock %p, sk %p", sock, sk); | 689 | BT_DBG("sock %p, sk %p", sock, sk); |
@@ -690,87 +698,12 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
690 | lock_sock(sk); | 698 | lock_sock(sk); |
691 | 699 | ||
692 | if (sk->sk_state != BT_CONNECTED) { | 700 | if (sk->sk_state != BT_CONNECTED) { |
693 | err = -ENOTCONN; | 701 | release_sock(sk); |
694 | goto done; | 702 | return -ENOTCONN; |
695 | } | ||
696 | |||
697 | /* Connectionless channel */ | ||
698 | if (sk->sk_type == SOCK_DGRAM) { | ||
699 | skb = l2cap_create_connless_pdu(chan, msg, len); | ||
700 | if (IS_ERR(skb)) { | ||
701 | err = PTR_ERR(skb); | ||
702 | } else { | ||
703 | l2cap_do_send(chan, skb); | ||
704 | err = len; | ||
705 | } | ||
706 | goto done; | ||
707 | } | 703 | } |
708 | 704 | ||
709 | switch (chan->mode) { | 705 | err = l2cap_chan_send(chan, msg, len); |
710 | case L2CAP_MODE_BASIC: | ||
711 | /* Check outgoing MTU */ | ||
712 | if (len > chan->omtu) { | ||
713 | err = -EMSGSIZE; | ||
714 | goto done; | ||
715 | } | ||
716 | |||
717 | /* Create a basic PDU */ | ||
718 | skb = l2cap_create_basic_pdu(chan, msg, len); | ||
719 | if (IS_ERR(skb)) { | ||
720 | err = PTR_ERR(skb); | ||
721 | goto done; | ||
722 | } | ||
723 | |||
724 | l2cap_do_send(chan, skb); | ||
725 | err = len; | ||
726 | break; | ||
727 | |||
728 | case L2CAP_MODE_ERTM: | ||
729 | case L2CAP_MODE_STREAMING: | ||
730 | /* Entire SDU fits into one PDU */ | ||
731 | if (len <= chan->remote_mps) { | ||
732 | control = L2CAP_SDU_UNSEGMENTED; | ||
733 | skb = l2cap_create_iframe_pdu(chan, msg, len, control, | ||
734 | 0); | ||
735 | if (IS_ERR(skb)) { | ||
736 | err = PTR_ERR(skb); | ||
737 | goto done; | ||
738 | } | ||
739 | __skb_queue_tail(&chan->tx_q, skb); | ||
740 | |||
741 | if (chan->tx_send_head == NULL) | ||
742 | chan->tx_send_head = skb; | ||
743 | |||
744 | } else { | ||
745 | /* Segment SDU into multiples PDUs */ | ||
746 | err = l2cap_sar_segment_sdu(chan, msg, len); | ||
747 | if (err < 0) | ||
748 | goto done; | ||
749 | } | ||
750 | |||
751 | if (chan->mode == L2CAP_MODE_STREAMING) { | ||
752 | l2cap_streaming_send(chan); | ||
753 | err = len; | ||
754 | break; | ||
755 | } | ||
756 | |||
757 | if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && | ||
758 | (chan->conn_state & L2CAP_CONN_WAIT_F)) { | ||
759 | err = len; | ||
760 | break; | ||
761 | } | ||
762 | err = l2cap_ertm_send(chan); | ||
763 | |||
764 | if (err >= 0) | ||
765 | err = len; | ||
766 | break; | ||
767 | |||
768 | default: | ||
769 | BT_DBG("bad state %1.1x", chan->mode); | ||
770 | err = -EBADFD; | ||
771 | } | ||
772 | 706 | ||
773 | done: | ||
774 | release_sock(sk); | 707 | release_sock(sk); |
775 | return err; | 708 | return err; |
776 | } | 709 | } |
@@ -800,7 +733,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
800 | /* Kill socket (only if zapped and orphan) | 733 | /* Kill socket (only if zapped and orphan) |
801 | * Must be called on unlocked socket. | 734 | * Must be called on unlocked socket. |
802 | */ | 735 | */ |
803 | void l2cap_sock_kill(struct sock *sk) | 736 | static void l2cap_sock_kill(struct sock *sk) |
804 | { | 737 | { |
805 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) | 738 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) |
806 | return; | 739 | return; |
@@ -814,87 +747,6 @@ void l2cap_sock_kill(struct sock *sk) | |||
814 | sock_put(sk); | 747 | sock_put(sk); |
815 | } | 748 | } |
816 | 749 | ||
817 | /* Must be called on unlocked socket. */ | ||
818 | static void l2cap_sock_close(struct sock *sk) | ||
819 | { | ||
820 | l2cap_sock_clear_timer(sk); | ||
821 | lock_sock(sk); | ||
822 | __l2cap_sock_close(sk, ECONNRESET); | ||
823 | release_sock(sk); | ||
824 | l2cap_sock_kill(sk); | ||
825 | } | ||
826 | |||
827 | static void l2cap_sock_cleanup_listen(struct sock *parent) | ||
828 | { | ||
829 | struct sock *sk; | ||
830 | |||
831 | BT_DBG("parent %p", parent); | ||
832 | |||
833 | /* Close not yet accepted channels */ | ||
834 | while ((sk = bt_accept_dequeue(parent, NULL))) | ||
835 | l2cap_sock_close(sk); | ||
836 | |||
837 | parent->sk_state = BT_CLOSED; | ||
838 | sock_set_flag(parent, SOCK_ZAPPED); | ||
839 | } | ||
840 | |||
841 | void __l2cap_sock_close(struct sock *sk, int reason) | ||
842 | { | ||
843 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
844 | struct l2cap_conn *conn = chan->conn; | ||
845 | |||
846 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); | ||
847 | |||
848 | switch (sk->sk_state) { | ||
849 | case BT_LISTEN: | ||
850 | l2cap_sock_cleanup_listen(sk); | ||
851 | break; | ||
852 | |||
853 | case BT_CONNECTED: | ||
854 | case BT_CONFIG: | ||
855 | if ((sk->sk_type == SOCK_SEQPACKET || | ||
856 | sk->sk_type == SOCK_STREAM) && | ||
857 | conn->hcon->type == ACL_LINK) { | ||
858 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | ||
859 | l2cap_send_disconn_req(conn, chan, reason); | ||
860 | } else | ||
861 | l2cap_chan_del(chan, reason); | ||
862 | break; | ||
863 | |||
864 | case BT_CONNECT2: | ||
865 | if ((sk->sk_type == SOCK_SEQPACKET || | ||
866 | sk->sk_type == SOCK_STREAM) && | ||
867 | conn->hcon->type == ACL_LINK) { | ||
868 | struct l2cap_conn_rsp rsp; | ||
869 | __u16 result; | ||
870 | |||
871 | if (bt_sk(sk)->defer_setup) | ||
872 | result = L2CAP_CR_SEC_BLOCK; | ||
873 | else | ||
874 | result = L2CAP_CR_BAD_PSM; | ||
875 | |||
876 | rsp.scid = cpu_to_le16(chan->dcid); | ||
877 | rsp.dcid = cpu_to_le16(chan->scid); | ||
878 | rsp.result = cpu_to_le16(result); | ||
879 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
880 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | ||
881 | sizeof(rsp), &rsp); | ||
882 | } | ||
883 | |||
884 | l2cap_chan_del(chan, reason); | ||
885 | break; | ||
886 | |||
887 | case BT_CONNECT: | ||
888 | case BT_DISCONN: | ||
889 | l2cap_chan_del(chan, reason); | ||
890 | break; | ||
891 | |||
892 | default: | ||
893 | sock_set_flag(sk, SOCK_ZAPPED); | ||
894 | break; | ||
895 | } | ||
896 | } | ||
897 | |||
898 | static int l2cap_sock_shutdown(struct socket *sock, int how) | 750 | static int l2cap_sock_shutdown(struct socket *sock, int how) |
899 | { | 751 | { |
900 | struct sock *sk = sock->sk; | 752 | struct sock *sk = sock->sk; |
@@ -912,8 +764,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
912 | err = __l2cap_wait_ack(sk); | 764 | err = __l2cap_wait_ack(sk); |
913 | 765 | ||
914 | sk->sk_shutdown = SHUTDOWN_MASK; | 766 | sk->sk_shutdown = SHUTDOWN_MASK; |
915 | l2cap_sock_clear_timer(sk); | 767 | l2cap_chan_close(chan, 0); |
916 | __l2cap_sock_close(sk, 0); | ||
917 | 768 | ||
918 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) | 769 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) |
919 | err = bt_sock_wait_state(sk, BT_CLOSED, | 770 | err = bt_sock_wait_state(sk, BT_CLOSED, |
@@ -944,6 +795,49 @@ static int l2cap_sock_release(struct socket *sock) | |||
944 | return err; | 795 | return err; |
945 | } | 796 | } |
946 | 797 | ||
798 | static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data) | ||
799 | { | ||
800 | struct sock *sk, *parent = data; | ||
801 | |||
802 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, | ||
803 | GFP_ATOMIC); | ||
804 | if (!sk) | ||
805 | return NULL; | ||
806 | |||
807 | l2cap_sock_init(sk, parent); | ||
808 | |||
809 | return l2cap_pi(sk)->chan; | ||
810 | } | ||
811 | |||
812 | static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) | ||
813 | { | ||
814 | struct sock *sk = data; | ||
815 | |||
816 | return sock_queue_rcv_skb(sk, skb); | ||
817 | } | ||
818 | |||
819 | static void l2cap_sock_close_cb(void *data) | ||
820 | { | ||
821 | struct sock *sk = data; | ||
822 | |||
823 | l2cap_sock_kill(sk); | ||
824 | } | ||
825 | |||
826 | static void l2cap_sock_state_change_cb(void *data, int state) | ||
827 | { | ||
828 | struct sock *sk = data; | ||
829 | |||
830 | sk->sk_state = state; | ||
831 | } | ||
832 | |||
833 | static struct l2cap_ops l2cap_chan_ops = { | ||
834 | .name = "L2CAP Socket Interface", | ||
835 | .new_connection = l2cap_sock_new_connection_cb, | ||
836 | .recv = l2cap_sock_recv_cb, | ||
837 | .close = l2cap_sock_close_cb, | ||
838 | .state_change = l2cap_sock_state_change_cb, | ||
839 | }; | ||
840 | |||
947 | static void l2cap_sock_destruct(struct sock *sk) | 841 | static void l2cap_sock_destruct(struct sock *sk) |
948 | { | 842 | { |
949 | BT_DBG("sk %p", sk); | 843 | BT_DBG("sk %p", sk); |
@@ -952,7 +846,7 @@ static void l2cap_sock_destruct(struct sock *sk) | |||
952 | skb_queue_purge(&sk->sk_write_queue); | 846 | skb_queue_purge(&sk->sk_write_queue); |
953 | } | 847 | } |
954 | 848 | ||
955 | void l2cap_sock_init(struct sock *sk, struct sock *parent) | 849 | static void l2cap_sock_init(struct sock *sk, struct sock *parent) |
956 | { | 850 | { |
957 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 851 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
958 | struct l2cap_chan *chan = pi->chan; | 852 | struct l2cap_chan *chan = pi->chan; |
@@ -965,6 +859,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
965 | sk->sk_type = parent->sk_type; | 859 | sk->sk_type = parent->sk_type; |
966 | bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; | 860 | bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; |
967 | 861 | ||
862 | chan->chan_type = pchan->chan_type; | ||
968 | chan->imtu = pchan->imtu; | 863 | chan->imtu = pchan->imtu; |
969 | chan->omtu = pchan->omtu; | 864 | chan->omtu = pchan->omtu; |
970 | chan->conf_state = pchan->conf_state; | 865 | chan->conf_state = pchan->conf_state; |
@@ -976,12 +871,27 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
976 | chan->role_switch = pchan->role_switch; | 871 | chan->role_switch = pchan->role_switch; |
977 | chan->force_reliable = pchan->force_reliable; | 872 | chan->force_reliable = pchan->force_reliable; |
978 | chan->flushable = pchan->flushable; | 873 | chan->flushable = pchan->flushable; |
874 | chan->force_active = pchan->force_active; | ||
979 | } else { | 875 | } else { |
876 | |||
877 | switch (sk->sk_type) { | ||
878 | case SOCK_RAW: | ||
879 | chan->chan_type = L2CAP_CHAN_RAW; | ||
880 | break; | ||
881 | case SOCK_DGRAM: | ||
882 | chan->chan_type = L2CAP_CHAN_CONN_LESS; | ||
883 | break; | ||
884 | case SOCK_SEQPACKET: | ||
885 | case SOCK_STREAM: | ||
886 | chan->chan_type = L2CAP_CHAN_CONN_ORIENTED; | ||
887 | break; | ||
888 | } | ||
889 | |||
980 | chan->imtu = L2CAP_DEFAULT_MTU; | 890 | chan->imtu = L2CAP_DEFAULT_MTU; |
981 | chan->omtu = 0; | 891 | chan->omtu = 0; |
982 | if (!disable_ertm && sk->sk_type == SOCK_STREAM) { | 892 | if (!disable_ertm && sk->sk_type == SOCK_STREAM) { |
983 | chan->mode = L2CAP_MODE_ERTM; | 893 | chan->mode = L2CAP_MODE_ERTM; |
984 | chan->conf_state |= L2CAP_CONF_STATE2_DEVICE; | 894 | set_bit(CONF_STATE2_DEVICE, &chan->conf_state); |
985 | } else { | 895 | } else { |
986 | chan->mode = L2CAP_MODE_BASIC; | 896 | chan->mode = L2CAP_MODE_BASIC; |
987 | } | 897 | } |
@@ -992,10 +902,15 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
992 | chan->role_switch = 0; | 902 | chan->role_switch = 0; |
993 | chan->force_reliable = 0; | 903 | chan->force_reliable = 0; |
994 | chan->flushable = BT_FLUSHABLE_OFF; | 904 | chan->flushable = BT_FLUSHABLE_OFF; |
905 | chan->force_active = BT_POWER_FORCE_ACTIVE_ON; | ||
906 | |||
995 | } | 907 | } |
996 | 908 | ||
997 | /* Default config options */ | 909 | /* Default config options */ |
998 | chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; | 910 | chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; |
911 | |||
912 | chan->data = sk; | ||
913 | chan->ops = &l2cap_chan_ops; | ||
999 | } | 914 | } |
1000 | 915 | ||
1001 | static struct proto l2cap_proto = { | 916 | static struct proto l2cap_proto = { |
@@ -1004,9 +919,10 @@ static struct proto l2cap_proto = { | |||
1004 | .obj_size = sizeof(struct l2cap_pinfo) | 919 | .obj_size = sizeof(struct l2cap_pinfo) |
1005 | }; | 920 | }; |
1006 | 921 | ||
1007 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) | 922 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) |
1008 | { | 923 | { |
1009 | struct sock *sk; | 924 | struct sock *sk; |
925 | struct l2cap_chan *chan; | ||
1010 | 926 | ||
1011 | sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto); | 927 | sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto); |
1012 | if (!sk) | 928 | if (!sk) |
@@ -1023,7 +939,13 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, g | |||
1023 | sk->sk_protocol = proto; | 939 | sk->sk_protocol = proto; |
1024 | sk->sk_state = BT_OPEN; | 940 | sk->sk_state = BT_OPEN; |
1025 | 941 | ||
1026 | setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); | 942 | chan = l2cap_chan_create(sk); |
943 | if (!chan) { | ||
944 | l2cap_sock_kill(sk); | ||
945 | return NULL; | ||
946 | } | ||
947 | |||
948 | l2cap_pi(sk)->chan = chan; | ||
1027 | 949 | ||
1028 | return sk; | 950 | return sk; |
1029 | } | 951 | } |
@@ -1032,7 +954,6 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, | |||
1032 | int kern) | 954 | int kern) |
1033 | { | 955 | { |
1034 | struct sock *sk; | 956 | struct sock *sk; |
1035 | struct l2cap_chan *chan; | ||
1036 | 957 | ||
1037 | BT_DBG("sock %p", sock); | 958 | BT_DBG("sock %p", sock); |
1038 | 959 | ||
@@ -1051,14 +972,6 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, | |||
1051 | if (!sk) | 972 | if (!sk) |
1052 | return -ENOMEM; | 973 | return -ENOMEM; |
1053 | 974 | ||
1054 | chan = l2cap_chan_create(sk); | ||
1055 | if (!chan) { | ||
1056 | l2cap_sock_kill(sk); | ||
1057 | return -ENOMEM; | ||
1058 | } | ||
1059 | |||
1060 | l2cap_pi(sk)->chan = chan; | ||
1061 | |||
1062 | l2cap_sock_init(sk, NULL); | 975 | l2cap_sock_init(sk, NULL); |
1063 | return 0; | 976 | return 0; |
1064 | } | 977 | } |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index dae382ce7020..64c0418a6221 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -41,7 +41,7 @@ struct pending_cmd { | |||
41 | void *user_data; | 41 | void *user_data; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | LIST_HEAD(cmd_list); | 44 | static LIST_HEAD(cmd_list); |
45 | 45 | ||
46 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | 46 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) |
47 | { | 47 | { |
@@ -990,7 +990,7 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
990 | 990 | ||
991 | put_unaligned_le16(conn->handle, &dc.handle); | 991 | put_unaligned_le16(conn->handle, &dc.handle); |
992 | dc.reason = 0x13; /* Remote User Terminated Connection */ | 992 | dc.reason = 0x13; /* Remote User Terminated Connection */ |
993 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, 0, NULL); | 993 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc); |
994 | } | 994 | } |
995 | 995 | ||
996 | unlock: | 996 | unlock: |
@@ -1092,8 +1092,6 @@ static int get_connections(struct sock *sk, u16 index) | |||
1092 | 1092 | ||
1093 | put_unaligned_le16(count, &rp->conn_count); | 1093 | put_unaligned_le16(count, &rp->conn_count); |
1094 | 1094 | ||
1095 | read_lock(&hci_dev_list_lock); | ||
1096 | |||
1097 | i = 0; | 1095 | i = 0; |
1098 | list_for_each(p, &hdev->conn_hash.list) { | 1096 | list_for_each(p, &hdev->conn_hash.list) { |
1099 | struct hci_conn *c = list_entry(p, struct hci_conn, list); | 1097 | struct hci_conn *c = list_entry(p, struct hci_conn, list); |
@@ -1101,8 +1099,6 @@ static int get_connections(struct sock *sk, u16 index) | |||
1101 | bacpy(&rp->conn[i++], &c->dst); | 1099 | bacpy(&rp->conn[i++], &c->dst); |
1102 | } | 1100 | } |
1103 | 1101 | ||
1104 | read_unlock(&hci_dev_list_lock); | ||
1105 | |||
1106 | err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len); | 1102 | err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len); |
1107 | 1103 | ||
1108 | unlock: | 1104 | unlock: |
@@ -1112,11 +1108,32 @@ unlock: | |||
1112 | return err; | 1108 | return err; |
1113 | } | 1109 | } |
1114 | 1110 | ||
1111 | static int send_pin_code_neg_reply(struct sock *sk, u16 index, | ||
1112 | struct hci_dev *hdev, struct mgmt_cp_pin_code_neg_reply *cp) | ||
1113 | { | ||
1114 | struct pending_cmd *cmd; | ||
1115 | int err; | ||
1116 | |||
1117 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, cp, | ||
1118 | sizeof(*cp)); | ||
1119 | if (!cmd) | ||
1120 | return -ENOMEM; | ||
1121 | |||
1122 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr), | ||
1123 | &cp->bdaddr); | ||
1124 | if (err < 0) | ||
1125 | mgmt_pending_remove(cmd); | ||
1126 | |||
1127 | return err; | ||
1128 | } | ||
1129 | |||
1115 | static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | 1130 | static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, |
1116 | u16 len) | 1131 | u16 len) |
1117 | { | 1132 | { |
1118 | struct hci_dev *hdev; | 1133 | struct hci_dev *hdev; |
1134 | struct hci_conn *conn; | ||
1119 | struct mgmt_cp_pin_code_reply *cp; | 1135 | struct mgmt_cp_pin_code_reply *cp; |
1136 | struct mgmt_cp_pin_code_neg_reply ncp; | ||
1120 | struct hci_cp_pin_code_reply reply; | 1137 | struct hci_cp_pin_code_reply reply; |
1121 | struct pending_cmd *cmd; | 1138 | struct pending_cmd *cmd; |
1122 | int err; | 1139 | int err; |
@@ -1139,6 +1156,25 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1139 | goto failed; | 1156 | goto failed; |
1140 | } | 1157 | } |
1141 | 1158 | ||
1159 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | ||
1160 | if (!conn) { | ||
1161 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENOTCONN); | ||
1162 | goto failed; | ||
1163 | } | ||
1164 | |||
1165 | if (conn->pending_sec_level == BT_SECURITY_HIGH && cp->pin_len != 16) { | ||
1166 | bacpy(&ncp.bdaddr, &cp->bdaddr); | ||
1167 | |||
1168 | BT_ERR("PIN code is not 16 bytes long"); | ||
1169 | |||
1170 | err = send_pin_code_neg_reply(sk, index, hdev, &ncp); | ||
1171 | if (err >= 0) | ||
1172 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | ||
1173 | EINVAL); | ||
1174 | |||
1175 | goto failed; | ||
1176 | } | ||
1177 | |||
1142 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len); | 1178 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len); |
1143 | if (!cmd) { | 1179 | if (!cmd) { |
1144 | err = -ENOMEM; | 1180 | err = -ENOMEM; |
@@ -1147,7 +1183,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1147 | 1183 | ||
1148 | bacpy(&reply.bdaddr, &cp->bdaddr); | 1184 | bacpy(&reply.bdaddr, &cp->bdaddr); |
1149 | reply.pin_len = cp->pin_len; | 1185 | reply.pin_len = cp->pin_len; |
1150 | memcpy(reply.pin_code, cp->pin_code, 16); | 1186 | memcpy(reply.pin_code, cp->pin_code, sizeof(reply.pin_code)); |
1151 | 1187 | ||
1152 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply); | 1188 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply); |
1153 | if (err < 0) | 1189 | if (err < 0) |
@@ -1165,7 +1201,6 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1165 | { | 1201 | { |
1166 | struct hci_dev *hdev; | 1202 | struct hci_dev *hdev; |
1167 | struct mgmt_cp_pin_code_neg_reply *cp; | 1203 | struct mgmt_cp_pin_code_neg_reply *cp; |
1168 | struct pending_cmd *cmd; | ||
1169 | int err; | 1204 | int err; |
1170 | 1205 | ||
1171 | BT_DBG(""); | 1206 | BT_DBG(""); |
@@ -1189,17 +1224,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1189 | goto failed; | 1224 | goto failed; |
1190 | } | 1225 | } |
1191 | 1226 | ||
1192 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, | 1227 | err = send_pin_code_neg_reply(sk, index, hdev, cp); |
1193 | data, len); | ||
1194 | if (!cmd) { | ||
1195 | err = -ENOMEM; | ||
1196 | goto failed; | ||
1197 | } | ||
1198 | |||
1199 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr), | ||
1200 | &cp->bdaddr); | ||
1201 | if (err < 0) | ||
1202 | mgmt_pending_remove(cmd); | ||
1203 | 1228 | ||
1204 | failed: | 1229 | failed: |
1205 | hci_dev_unlock(hdev); | 1230 | hci_dev_unlock(hdev); |
@@ -1641,6 +1666,70 @@ failed: | |||
1641 | return err; | 1666 | return err; |
1642 | } | 1667 | } |
1643 | 1668 | ||
1669 | static int block_device(struct sock *sk, u16 index, unsigned char *data, | ||
1670 | u16 len) | ||
1671 | { | ||
1672 | struct hci_dev *hdev; | ||
1673 | struct mgmt_cp_block_device *cp; | ||
1674 | int err; | ||
1675 | |||
1676 | BT_DBG("hci%u", index); | ||
1677 | |||
1678 | cp = (void *) data; | ||
1679 | |||
1680 | if (len != sizeof(*cp)) | ||
1681 | return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, | ||
1682 | EINVAL); | ||
1683 | |||
1684 | hdev = hci_dev_get(index); | ||
1685 | if (!hdev) | ||
1686 | return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, | ||
1687 | ENODEV); | ||
1688 | |||
1689 | err = hci_blacklist_add(hdev, &cp->bdaddr); | ||
1690 | |||
1691 | if (err < 0) | ||
1692 | err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, -err); | ||
1693 | else | ||
1694 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, | ||
1695 | NULL, 0); | ||
1696 | hci_dev_put(hdev); | ||
1697 | |||
1698 | return err; | ||
1699 | } | ||
1700 | |||
1701 | static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | ||
1702 | u16 len) | ||
1703 | { | ||
1704 | struct hci_dev *hdev; | ||
1705 | struct mgmt_cp_unblock_device *cp; | ||
1706 | int err; | ||
1707 | |||
1708 | BT_DBG("hci%u", index); | ||
1709 | |||
1710 | cp = (void *) data; | ||
1711 | |||
1712 | if (len != sizeof(*cp)) | ||
1713 | return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, | ||
1714 | EINVAL); | ||
1715 | |||
1716 | hdev = hci_dev_get(index); | ||
1717 | if (!hdev) | ||
1718 | return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, | ||
1719 | ENODEV); | ||
1720 | |||
1721 | err = hci_blacklist_del(hdev, &cp->bdaddr); | ||
1722 | |||
1723 | if (err < 0) | ||
1724 | err = cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, -err); | ||
1725 | else | ||
1726 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, | ||
1727 | NULL, 0); | ||
1728 | hci_dev_put(hdev); | ||
1729 | |||
1730 | return err; | ||
1731 | } | ||
1732 | |||
1644 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | 1733 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) |
1645 | { | 1734 | { |
1646 | unsigned char *buf; | 1735 | unsigned char *buf; |
@@ -1755,6 +1844,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1755 | case MGMT_OP_STOP_DISCOVERY: | 1844 | case MGMT_OP_STOP_DISCOVERY: |
1756 | err = stop_discovery(sk, index); | 1845 | err = stop_discovery(sk, index); |
1757 | break; | 1846 | break; |
1847 | case MGMT_OP_BLOCK_DEVICE: | ||
1848 | err = block_device(sk, index, buf + sizeof(*hdr), len); | ||
1849 | break; | ||
1850 | case MGMT_OP_UNBLOCK_DEVICE: | ||
1851 | err = unblock_device(sk, index, buf + sizeof(*hdr), len); | ||
1852 | break; | ||
1758 | default: | 1853 | default: |
1759 | BT_DBG("Unknown op %u", opcode); | 1854 | BT_DBG("Unknown op %u", opcode); |
1760 | err = cmd_status(sk, index, opcode, 0x01); | 1855 | err = cmd_status(sk, index, opcode, 0x01); |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 1b10727ce523..8f01e6b11a70 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -679,7 +679,8 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c | |||
679 | { | 679 | { |
680 | struct sock *sk = sock->sk; | 680 | struct sock *sk = sock->sk; |
681 | struct bt_security sec; | 681 | struct bt_security sec; |
682 | int len, err = 0; | 682 | int err = 0; |
683 | size_t len; | ||
683 | u32 opt; | 684 | u32 opt; |
684 | 685 | ||
685 | BT_DBG("sk %p", sk); | 686 | BT_DBG("sk %p", sk); |
@@ -741,7 +742,6 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c | |||
741 | static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) | 742 | static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) |
742 | { | 743 | { |
743 | struct sock *sk = sock->sk; | 744 | struct sock *sk = sock->sk; |
744 | struct sock *l2cap_sk; | ||
745 | struct rfcomm_conninfo cinfo; | 745 | struct rfcomm_conninfo cinfo; |
746 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; | 746 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; |
747 | int len, err = 0; | 747 | int len, err = 0; |
@@ -786,8 +786,6 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
786 | break; | 786 | break; |
787 | } | 787 | } |
788 | 788 | ||
789 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; | ||
790 | |||
791 | memset(&cinfo, 0, sizeof(cinfo)); | 789 | memset(&cinfo, 0, sizeof(cinfo)); |
792 | cinfo.hci_handle = conn->hcon->handle; | 790 | cinfo.hci_handle = conn->hcon->handle; |
793 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); | 791 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c new file mode 100644 index 000000000000..a36f8707d964 --- /dev/null +++ b/net/bluetooth/smp.c | |||
@@ -0,0 +1,534 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License version 2 as | ||
7 | published by the Free Software Foundation; | ||
8 | |||
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
10 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
11 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
12 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
13 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
14 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | |||
18 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
19 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
20 | SOFTWARE IS DISCLAIMED. | ||
21 | */ | ||
22 | |||
23 | #include <net/bluetooth/bluetooth.h> | ||
24 | #include <net/bluetooth/hci_core.h> | ||
25 | #include <net/bluetooth/l2cap.h> | ||
26 | #include <net/bluetooth/smp.h> | ||
27 | #include <linux/crypto.h> | ||
28 | #include <linux/scatterlist.h> | ||
29 | #include <crypto/b128ops.h> | ||
30 | |||
31 | #define SMP_TIMEOUT 30000 /* 30 seconds */ | ||
32 | |||
33 | static inline void swap128(u8 src[16], u8 dst[16]) | ||
34 | { | ||
35 | int i; | ||
36 | for (i = 0; i < 16; i++) | ||
37 | dst[15 - i] = src[i]; | ||
38 | } | ||
39 | |||
40 | static inline void swap56(u8 src[7], u8 dst[7]) | ||
41 | { | ||
42 | int i; | ||
43 | for (i = 0; i < 7; i++) | ||
44 | dst[6 - i] = src[i]; | ||
45 | } | ||
46 | |||
47 | static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) | ||
48 | { | ||
49 | struct blkcipher_desc desc; | ||
50 | struct scatterlist sg; | ||
51 | int err, iv_len; | ||
52 | unsigned char iv[128]; | ||
53 | |||
54 | if (tfm == NULL) { | ||
55 | BT_ERR("tfm %p", tfm); | ||
56 | return -EINVAL; | ||
57 | } | ||
58 | |||
59 | desc.tfm = tfm; | ||
60 | desc.flags = 0; | ||
61 | |||
62 | err = crypto_blkcipher_setkey(tfm, k, 16); | ||
63 | if (err) { | ||
64 | BT_ERR("cipher setkey failed: %d", err); | ||
65 | return err; | ||
66 | } | ||
67 | |||
68 | sg_init_one(&sg, r, 16); | ||
69 | |||
70 | iv_len = crypto_blkcipher_ivsize(tfm); | ||
71 | if (iv_len) { | ||
72 | memset(&iv, 0xff, iv_len); | ||
73 | crypto_blkcipher_set_iv(tfm, iv, iv_len); | ||
74 | } | ||
75 | |||
76 | err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16); | ||
77 | if (err) | ||
78 | BT_ERR("Encrypt data error %d", err); | ||
79 | |||
80 | return err; | ||
81 | } | ||
82 | |||
83 | static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], | ||
84 | u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, | ||
85 | u8 _rat, bdaddr_t *ra, u8 res[16]) | ||
86 | { | ||
87 | u8 p1[16], p2[16]; | ||
88 | int err; | ||
89 | |||
90 | memset(p1, 0, 16); | ||
91 | |||
92 | /* p1 = pres || preq || _rat || _iat */ | ||
93 | swap56(pres, p1); | ||
94 | swap56(preq, p1 + 7); | ||
95 | p1[14] = _rat; | ||
96 | p1[15] = _iat; | ||
97 | |||
98 | memset(p2, 0, 16); | ||
99 | |||
100 | /* p2 = padding || ia || ra */ | ||
101 | baswap((bdaddr_t *) (p2 + 4), ia); | ||
102 | baswap((bdaddr_t *) (p2 + 10), ra); | ||
103 | |||
104 | /* res = r XOR p1 */ | ||
105 | u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); | ||
106 | |||
107 | /* res = e(k, res) */ | ||
108 | err = smp_e(tfm, k, res); | ||
109 | if (err) { | ||
110 | BT_ERR("Encrypt data error"); | ||
111 | return err; | ||
112 | } | ||
113 | |||
114 | /* res = res XOR p2 */ | ||
115 | u128_xor((u128 *) res, (u128 *) res, (u128 *) p2); | ||
116 | |||
117 | /* res = e(k, res) */ | ||
118 | err = smp_e(tfm, k, res); | ||
119 | if (err) | ||
120 | BT_ERR("Encrypt data error"); | ||
121 | |||
122 | return err; | ||
123 | } | ||
124 | |||
125 | static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], | ||
126 | u8 r1[16], u8 r2[16], u8 _r[16]) | ||
127 | { | ||
128 | int err; | ||
129 | |||
130 | /* Just least significant octets from r1 and r2 are considered */ | ||
131 | memcpy(_r, r1 + 8, 8); | ||
132 | memcpy(_r + 8, r2 + 8, 8); | ||
133 | |||
134 | err = smp_e(tfm, k, _r); | ||
135 | if (err) | ||
136 | BT_ERR("Encrypt data error"); | ||
137 | |||
138 | return err; | ||
139 | } | ||
140 | |||
141 | static int smp_rand(u8 *buf) | ||
142 | { | ||
143 | get_random_bytes(buf, 16); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, | ||
149 | u16 dlen, void *data) | ||
150 | { | ||
151 | struct sk_buff *skb; | ||
152 | struct l2cap_hdr *lh; | ||
153 | int len; | ||
154 | |||
155 | len = L2CAP_HDR_SIZE + sizeof(code) + dlen; | ||
156 | |||
157 | if (len > conn->mtu) | ||
158 | return NULL; | ||
159 | |||
160 | skb = bt_skb_alloc(len, GFP_ATOMIC); | ||
161 | if (!skb) | ||
162 | return NULL; | ||
163 | |||
164 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | ||
165 | lh->len = cpu_to_le16(sizeof(code) + dlen); | ||
166 | lh->cid = cpu_to_le16(L2CAP_CID_SMP); | ||
167 | |||
168 | memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code)); | ||
169 | |||
170 | memcpy(skb_put(skb, dlen), data, dlen); | ||
171 | |||
172 | return skb; | ||
173 | } | ||
174 | |||
175 | static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | ||
176 | { | ||
177 | struct sk_buff *skb = smp_build_cmd(conn, code, len, data); | ||
178 | |||
179 | BT_DBG("code 0x%2.2x", code); | ||
180 | |||
181 | if (!skb) | ||
182 | return; | ||
183 | |||
184 | hci_send_acl(conn->hcon, skb, 0); | ||
185 | } | ||
186 | |||
187 | static __u8 seclevel_to_authreq(__u8 level) | ||
188 | { | ||
189 | switch (level) { | ||
190 | case BT_SECURITY_HIGH: | ||
191 | /* Right now we don't support bonding */ | ||
192 | return SMP_AUTH_MITM; | ||
193 | |||
194 | default: | ||
195 | return SMP_AUTH_NONE; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | static void build_pairing_cmd(struct l2cap_conn *conn, | ||
200 | struct smp_cmd_pairing *cmd, __u8 authreq) | ||
201 | { | ||
202 | cmd->io_capability = conn->hcon->io_capability; | ||
203 | cmd->oob_flag = SMP_OOB_NOT_PRESENT; | ||
204 | cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE; | ||
205 | cmd->init_key_dist = 0x00; | ||
206 | cmd->resp_key_dist = 0x00; | ||
207 | cmd->auth_req = authreq; | ||
208 | } | ||
209 | |||
210 | static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) | ||
211 | { | ||
212 | if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) || | ||
213 | (max_key_size < SMP_MIN_ENC_KEY_SIZE)) | ||
214 | return SMP_ENC_KEY_SIZE; | ||
215 | |||
216 | conn->smp_key_size = max_key_size; | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | ||
222 | { | ||
223 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; | ||
224 | u8 key_size; | ||
225 | |||
226 | BT_DBG("conn %p", conn); | ||
227 | |||
228 | conn->preq[0] = SMP_CMD_PAIRING_REQ; | ||
229 | memcpy(&conn->preq[1], req, sizeof(*req)); | ||
230 | skb_pull(skb, sizeof(*req)); | ||
231 | |||
232 | if (req->oob_flag) | ||
233 | return SMP_OOB_NOT_AVAIL; | ||
234 | |||
235 | /* We didn't start the pairing, so no requirements */ | ||
236 | build_pairing_cmd(conn, &rsp, SMP_AUTH_NONE); | ||
237 | |||
238 | key_size = min(req->max_key_size, rsp.max_key_size); | ||
239 | if (check_enc_key_size(conn, key_size)) | ||
240 | return SMP_ENC_KEY_SIZE; | ||
241 | |||
242 | /* Just works */ | ||
243 | memset(conn->tk, 0, sizeof(conn->tk)); | ||
244 | |||
245 | conn->prsp[0] = SMP_CMD_PAIRING_RSP; | ||
246 | memcpy(&conn->prsp[1], &rsp, sizeof(rsp)); | ||
247 | |||
248 | smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); | ||
249 | |||
250 | mod_timer(&conn->security_timer, jiffies + | ||
251 | msecs_to_jiffies(SMP_TIMEOUT)); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | ||
257 | { | ||
258 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; | ||
259 | struct smp_cmd_pairing_confirm cp; | ||
260 | struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm; | ||
261 | int ret; | ||
262 | u8 res[16], key_size; | ||
263 | |||
264 | BT_DBG("conn %p", conn); | ||
265 | |||
266 | skb_pull(skb, sizeof(*rsp)); | ||
267 | |||
268 | req = (void *) &conn->preq[1]; | ||
269 | |||
270 | key_size = min(req->max_key_size, rsp->max_key_size); | ||
271 | if (check_enc_key_size(conn, key_size)) | ||
272 | return SMP_ENC_KEY_SIZE; | ||
273 | |||
274 | if (rsp->oob_flag) | ||
275 | return SMP_OOB_NOT_AVAIL; | ||
276 | |||
277 | /* Just works */ | ||
278 | memset(conn->tk, 0, sizeof(conn->tk)); | ||
279 | |||
280 | conn->prsp[0] = SMP_CMD_PAIRING_RSP; | ||
281 | memcpy(&conn->prsp[1], rsp, sizeof(*rsp)); | ||
282 | |||
283 | ret = smp_rand(conn->prnd); | ||
284 | if (ret) | ||
285 | return SMP_UNSPECIFIED; | ||
286 | |||
287 | ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, 0, | ||
288 | conn->src, conn->hcon->dst_type, conn->dst, res); | ||
289 | if (ret) | ||
290 | return SMP_UNSPECIFIED; | ||
291 | |||
292 | swap128(res, cp.confirm_val); | ||
293 | |||
294 | smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | ||
300 | { | ||
301 | struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm; | ||
302 | |||
303 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); | ||
304 | |||
305 | memcpy(conn->pcnf, skb->data, sizeof(conn->pcnf)); | ||
306 | skb_pull(skb, sizeof(conn->pcnf)); | ||
307 | |||
308 | if (conn->hcon->out) { | ||
309 | u8 random[16]; | ||
310 | |||
311 | swap128(conn->prnd, random); | ||
312 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random), | ||
313 | random); | ||
314 | } else { | ||
315 | struct smp_cmd_pairing_confirm cp; | ||
316 | int ret; | ||
317 | u8 res[16]; | ||
318 | |||
319 | ret = smp_rand(conn->prnd); | ||
320 | if (ret) | ||
321 | return SMP_UNSPECIFIED; | ||
322 | |||
323 | ret = smp_c1(tfm, conn->tk, conn->prnd, conn->preq, conn->prsp, | ||
324 | conn->hcon->dst_type, conn->dst, | ||
325 | 0, conn->src, res); | ||
326 | if (ret) | ||
327 | return SMP_CONFIRM_FAILED; | ||
328 | |||
329 | swap128(res, cp.confirm_val); | ||
330 | |||
331 | smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); | ||
332 | } | ||
333 | |||
334 | mod_timer(&conn->security_timer, jiffies + | ||
335 | msecs_to_jiffies(SMP_TIMEOUT)); | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | ||
341 | { | ||
342 | struct hci_conn *hcon = conn->hcon; | ||
343 | struct crypto_blkcipher *tfm = hcon->hdev->tfm; | ||
344 | int ret; | ||
345 | u8 key[16], res[16], random[16], confirm[16]; | ||
346 | |||
347 | swap128(skb->data, random); | ||
348 | skb_pull(skb, sizeof(random)); | ||
349 | |||
350 | memset(hcon->ltk, 0, sizeof(hcon->ltk)); | ||
351 | |||
352 | if (conn->hcon->out) | ||
353 | ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, 0, | ||
354 | conn->src, conn->hcon->dst_type, conn->dst, | ||
355 | res); | ||
356 | else | ||
357 | ret = smp_c1(tfm, conn->tk, random, conn->preq, conn->prsp, | ||
358 | conn->hcon->dst_type, conn->dst, 0, conn->src, | ||
359 | res); | ||
360 | if (ret) | ||
361 | return SMP_UNSPECIFIED; | ||
362 | |||
363 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); | ||
364 | |||
365 | swap128(res, confirm); | ||
366 | |||
367 | if (memcmp(conn->pcnf, confirm, sizeof(conn->pcnf)) != 0) { | ||
368 | BT_ERR("Pairing failed (confirmation values mismatch)"); | ||
369 | return SMP_CONFIRM_FAILED; | ||
370 | } | ||
371 | |||
372 | if (conn->hcon->out) { | ||
373 | __le16 ediv; | ||
374 | u8 rand[8]; | ||
375 | |||
376 | smp_s1(tfm, conn->tk, random, conn->prnd, key); | ||
377 | swap128(key, hcon->ltk); | ||
378 | |||
379 | memset(hcon->ltk + conn->smp_key_size, 0, | ||
380 | SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size); | ||
381 | |||
382 | memset(rand, 0, sizeof(rand)); | ||
383 | ediv = 0; | ||
384 | hci_le_start_enc(hcon, ediv, rand, hcon->ltk); | ||
385 | } else { | ||
386 | u8 r[16]; | ||
387 | |||
388 | swap128(conn->prnd, r); | ||
389 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r); | ||
390 | |||
391 | smp_s1(tfm, conn->tk, conn->prnd, random, key); | ||
392 | swap128(key, hcon->ltk); | ||
393 | |||
394 | memset(hcon->ltk + conn->smp_key_size, 0, | ||
395 | SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size); | ||
396 | } | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | ||
402 | { | ||
403 | struct smp_cmd_security_req *rp = (void *) skb->data; | ||
404 | struct smp_cmd_pairing cp; | ||
405 | struct hci_conn *hcon = conn->hcon; | ||
406 | |||
407 | BT_DBG("conn %p", conn); | ||
408 | |||
409 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) | ||
410 | return 0; | ||
411 | |||
412 | skb_pull(skb, sizeof(*rp)); | ||
413 | |||
414 | memset(&cp, 0, sizeof(cp)); | ||
415 | build_pairing_cmd(conn, &cp, rp->auth_req); | ||
416 | |||
417 | conn->preq[0] = SMP_CMD_PAIRING_REQ; | ||
418 | memcpy(&conn->preq[1], &cp, sizeof(cp)); | ||
419 | |||
420 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); | ||
421 | |||
422 | mod_timer(&conn->security_timer, jiffies + | ||
423 | msecs_to_jiffies(SMP_TIMEOUT)); | ||
424 | |||
425 | set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend); | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | ||
431 | { | ||
432 | struct hci_conn *hcon = conn->hcon; | ||
433 | __u8 authreq; | ||
434 | |||
435 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); | ||
436 | |||
437 | if (IS_ERR(hcon->hdev->tfm)) | ||
438 | return 1; | ||
439 | |||
440 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) | ||
441 | return 0; | ||
442 | |||
443 | if (sec_level == BT_SECURITY_LOW) | ||
444 | return 1; | ||
445 | |||
446 | if (hcon->sec_level >= sec_level) | ||
447 | return 1; | ||
448 | |||
449 | authreq = seclevel_to_authreq(sec_level); | ||
450 | |||
451 | if (hcon->link_mode & HCI_LM_MASTER) { | ||
452 | struct smp_cmd_pairing cp; | ||
453 | |||
454 | build_pairing_cmd(conn, &cp, authreq); | ||
455 | conn->preq[0] = SMP_CMD_PAIRING_REQ; | ||
456 | memcpy(&conn->preq[1], &cp, sizeof(cp)); | ||
457 | |||
458 | mod_timer(&conn->security_timer, jiffies + | ||
459 | msecs_to_jiffies(SMP_TIMEOUT)); | ||
460 | |||
461 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); | ||
462 | } else { | ||
463 | struct smp_cmd_security_req cp; | ||
464 | cp.auth_req = authreq; | ||
465 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); | ||
466 | } | ||
467 | |||
468 | hcon->pending_sec_level = sec_level; | ||
469 | set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend); | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | ||
475 | { | ||
476 | __u8 code = skb->data[0]; | ||
477 | __u8 reason; | ||
478 | int err = 0; | ||
479 | |||
480 | if (IS_ERR(conn->hcon->hdev->tfm)) { | ||
481 | err = PTR_ERR(conn->hcon->hdev->tfm); | ||
482 | reason = SMP_PAIRING_NOTSUPP; | ||
483 | goto done; | ||
484 | } | ||
485 | |||
486 | skb_pull(skb, sizeof(code)); | ||
487 | |||
488 | switch (code) { | ||
489 | case SMP_CMD_PAIRING_REQ: | ||
490 | reason = smp_cmd_pairing_req(conn, skb); | ||
491 | break; | ||
492 | |||
493 | case SMP_CMD_PAIRING_FAIL: | ||
494 | reason = 0; | ||
495 | err = -EPERM; | ||
496 | break; | ||
497 | |||
498 | case SMP_CMD_PAIRING_RSP: | ||
499 | reason = smp_cmd_pairing_rsp(conn, skb); | ||
500 | break; | ||
501 | |||
502 | case SMP_CMD_SECURITY_REQ: | ||
503 | reason = smp_cmd_security_req(conn, skb); | ||
504 | break; | ||
505 | |||
506 | case SMP_CMD_PAIRING_CONFIRM: | ||
507 | reason = smp_cmd_pairing_confirm(conn, skb); | ||
508 | break; | ||
509 | |||
510 | case SMP_CMD_PAIRING_RANDOM: | ||
511 | reason = smp_cmd_pairing_random(conn, skb); | ||
512 | break; | ||
513 | |||
514 | case SMP_CMD_ENCRYPT_INFO: | ||
515 | case SMP_CMD_MASTER_IDENT: | ||
516 | case SMP_CMD_IDENT_INFO: | ||
517 | case SMP_CMD_IDENT_ADDR_INFO: | ||
518 | case SMP_CMD_SIGN_INFO: | ||
519 | default: | ||
520 | BT_DBG("Unknown command code 0x%2.2x", code); | ||
521 | |||
522 | reason = SMP_CMD_NOTSUPP; | ||
523 | err = -EOPNOTSUPP; | ||
524 | goto done; | ||
525 | } | ||
526 | |||
527 | done: | ||
528 | if (reason) | ||
529 | smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), | ||
530 | &reason); | ||
531 | |||
532 | kfree_skb(skb); | ||
533 | return err; | ||
534 | } | ||
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index eebf7a67daf7..0e7e4268ddf6 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -218,6 +218,16 @@ static inline int drv_hw_scan(struct ieee80211_local *local, | |||
218 | return ret; | 218 | return ret; |
219 | } | 219 | } |
220 | 220 | ||
221 | static inline void drv_cancel_hw_scan(struct ieee80211_local *local, | ||
222 | struct ieee80211_sub_if_data *sdata) | ||
223 | { | ||
224 | might_sleep(); | ||
225 | |||
226 | trace_drv_cancel_hw_scan(local, sdata); | ||
227 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); | ||
228 | trace_drv_return_void(local); | ||
229 | } | ||
230 | |||
221 | static inline int | 231 | static inline int |
222 | drv_sched_scan_start(struct ieee80211_local *local, | 232 | drv_sched_scan_start(struct ieee80211_local *local, |
223 | struct ieee80211_sub_if_data *sdata, | 233 | struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index ed9edcbd9aa5..3cb6795e926d 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -460,6 +460,12 @@ DEFINE_EVENT(local_sdata_evt, drv_hw_scan, | |||
460 | TP_ARGS(local, sdata) | 460 | TP_ARGS(local, sdata) |
461 | ); | 461 | ); |
462 | 462 | ||
463 | DEFINE_EVENT(local_sdata_evt, drv_cancel_hw_scan, | ||
464 | TP_PROTO(struct ieee80211_local *local, | ||
465 | struct ieee80211_sub_if_data *sdata), | ||
466 | TP_ARGS(local, sdata) | ||
467 | ); | ||
468 | |||
463 | DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start, | 469 | DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start, |
464 | TP_PROTO(struct ieee80211_local *local, | 470 | TP_PROTO(struct ieee80211_local *local, |
465 | struct ieee80211_sub_if_data *sdata), | 471 | struct ieee80211_sub_if_data *sdata), |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d595265d6c22..faca5033f061 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2206,6 +2206,7 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
2206 | add_timer(&ifmgd->chswitch_timer); | 2206 | add_timer(&ifmgd->chswitch_timer); |
2207 | ieee80211_sta_reset_beacon_monitor(sdata); | 2207 | ieee80211_sta_reset_beacon_monitor(sdata); |
2208 | ieee80211_restart_sta_timer(sdata); | 2208 | ieee80211_restart_sta_timer(sdata); |
2209 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.monitor_work); | ||
2209 | } | 2210 | } |
2210 | #endif | 2211 | #endif |
2211 | 2212 | ||
@@ -2652,3 +2653,10 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | |||
2652 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); | 2653 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); |
2653 | } | 2654 | } |
2654 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); | 2655 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); |
2656 | |||
2657 | unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif) | ||
2658 | { | ||
2659 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
2660 | return sdata->dev->operstate; | ||
2661 | } | ||
2662 | EXPORT_SYMBOL(ieee80211_get_operstate); | ||
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 730778a2c90c..67839eb90cc1 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -6,6 +6,28 @@ | |||
6 | #include "driver-ops.h" | 6 | #include "driver-ops.h" |
7 | #include "led.h" | 7 | #include "led.h" |
8 | 8 | ||
9 | /* return value indicates whether the driver should be further notified */ | ||
10 | static bool ieee80211_quiesce(struct ieee80211_sub_if_data *sdata) | ||
11 | { | ||
12 | switch (sdata->vif.type) { | ||
13 | case NL80211_IFTYPE_STATION: | ||
14 | ieee80211_sta_quiesce(sdata); | ||
15 | return true; | ||
16 | case NL80211_IFTYPE_ADHOC: | ||
17 | ieee80211_ibss_quiesce(sdata); | ||
18 | return true; | ||
19 | case NL80211_IFTYPE_MESH_POINT: | ||
20 | ieee80211_mesh_quiesce(sdata); | ||
21 | return true; | ||
22 | case NL80211_IFTYPE_AP_VLAN: | ||
23 | case NL80211_IFTYPE_MONITOR: | ||
24 | /* don't tell driver about this */ | ||
25 | return false; | ||
26 | default: | ||
27 | return true; | ||
28 | } | ||
29 | } | ||
30 | |||
9 | int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | 31 | int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) |
10 | { | 32 | { |
11 | struct ieee80211_local *local = hw_to_local(hw); | 33 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -54,6 +76,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
54 | local->quiescing = false; | 76 | local->quiescing = false; |
55 | return err; | 77 | return err; |
56 | } | 78 | } |
79 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
80 | cancel_work_sync(&sdata->work); | ||
81 | ieee80211_quiesce(sdata); | ||
82 | } | ||
57 | goto suspend; | 83 | goto suspend; |
58 | } | 84 | } |
59 | 85 | ||
@@ -82,23 +108,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
82 | list_for_each_entry(sdata, &local->interfaces, list) { | 108 | list_for_each_entry(sdata, &local->interfaces, list) { |
83 | cancel_work_sync(&sdata->work); | 109 | cancel_work_sync(&sdata->work); |
84 | 110 | ||
85 | switch(sdata->vif.type) { | 111 | if (!ieee80211_quiesce(sdata)) |
86 | case NL80211_IFTYPE_STATION: | ||
87 | ieee80211_sta_quiesce(sdata); | ||
88 | break; | ||
89 | case NL80211_IFTYPE_ADHOC: | ||
90 | ieee80211_ibss_quiesce(sdata); | ||
91 | break; | ||
92 | case NL80211_IFTYPE_MESH_POINT: | ||
93 | ieee80211_mesh_quiesce(sdata); | ||
94 | break; | ||
95 | case NL80211_IFTYPE_AP_VLAN: | ||
96 | case NL80211_IFTYPE_MONITOR: | ||
97 | /* don't tell driver about this */ | ||
98 | continue; | 112 | continue; |
99 | default: | ||
100 | break; | ||
101 | } | ||
102 | 113 | ||
103 | if (!ieee80211_sdata_running(sdata)) | 114 | if (!ieee80211_sdata_running(sdata)) |
104 | continue; | 115 | continue; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 58ffa7d069c7..1758b463c583 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -821,10 +821,8 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | |||
821 | */ | 821 | */ |
822 | void ieee80211_scan_cancel(struct ieee80211_local *local) | 822 | void ieee80211_scan_cancel(struct ieee80211_local *local) |
823 | { | 823 | { |
824 | bool abortscan; | ||
825 | |||
826 | /* | 824 | /* |
827 | * We are only canceling software scan, or deferred scan that was not | 825 | * We are canceling software scan, or deferred scan that was not |
828 | * yet really started (see __ieee80211_start_scan ). | 826 | * yet really started (see __ieee80211_start_scan ). |
829 | * | 827 | * |
830 | * Regarding hardware scan: | 828 | * Regarding hardware scan: |
@@ -836,23 +834,30 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
836 | * - we can not cancel scan_work since driver can schedule it | 834 | * - we can not cancel scan_work since driver can schedule it |
837 | * by ieee80211_scan_completed(..., true) to finish scan | 835 | * by ieee80211_scan_completed(..., true) to finish scan |
838 | * | 836 | * |
839 | * Hence low lever driver is responsible for canceling HW scan. | 837 | * Hence we only call the cancel_hw_scan() callback, but the low-level |
838 | * driver is still responsible for calling ieee80211_scan_completed() | ||
839 | * after the scan was completed/aborted. | ||
840 | */ | 840 | */ |
841 | 841 | ||
842 | mutex_lock(&local->mtx); | 842 | mutex_lock(&local->mtx); |
843 | abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); | 843 | if (!local->scan_req) |
844 | if (abortscan) { | 844 | goto out; |
845 | /* | 845 | |
846 | * The scan is canceled, but stop work from being pending. | 846 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { |
847 | * | 847 | if (local->ops->cancel_hw_scan) |
848 | * If the work is currently running, it must be blocked on | 848 | drv_cancel_hw_scan(local, local->scan_sdata); |
849 | * the mutex, but we'll set scan_sdata = NULL and it'll | 849 | goto out; |
850 | * simply exit once it acquires the mutex. | ||
851 | */ | ||
852 | cancel_delayed_work(&local->scan_work); | ||
853 | /* and clean up */ | ||
854 | __ieee80211_scan_completed(&local->hw, true, false); | ||
855 | } | 850 | } |
851 | |||
852 | /* | ||
853 | * If the work is currently running, it must be blocked on | ||
854 | * the mutex, but we'll set scan_sdata = NULL and it'll | ||
855 | * simply exit once it acquires the mutex. | ||
856 | */ | ||
857 | cancel_delayed_work(&local->scan_work); | ||
858 | /* and clean up */ | ||
859 | __ieee80211_scan_completed(&local->hw, true, false); | ||
860 | out: | ||
856 | mutex_unlock(&local->mtx); | 861 | mutex_unlock(&local->mtx); |
857 | } | 862 | } |
858 | 863 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index d3fe2d237485..05e3fb889d77 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1276,7 +1276,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1276 | if (ieee80211_sdata_running(sdata)) | 1276 | if (ieee80211_sdata_running(sdata)) |
1277 | ieee80211_enable_keys(sdata); | 1277 | ieee80211_enable_keys(sdata); |
1278 | 1278 | ||
1279 | #ifdef CONFIG_PM | ||
1279 | wake_up: | 1280 | wake_up: |
1281 | #endif | ||
1280 | ieee80211_wake_queues_by_reason(hw, | 1282 | ieee80211_wake_queues_by_reason(hw, |
1281 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 1283 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
1282 | 1284 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index ca5276c51804..0a4db0211da0 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1696,6 +1696,8 @@ static int netlink_dump(struct sock *sk) | |||
1696 | if (!nlh) | 1696 | if (!nlh) |
1697 | goto errout_skb; | 1697 | goto errout_skb; |
1698 | 1698 | ||
1699 | nl_dump_check_consistent(cb, nlh); | ||
1700 | |||
1699 | memcpy(nlmsg_data(nlh), &len, sizeof(len)); | 1701 | memcpy(nlmsg_data(nlh), &len, sizeof(len)); |
1700 | 1702 | ||
1701 | if (sk_filter(sk, skb)) | 1703 | if (sk_filter(sk, skb)) |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 493b939970cd..3633ab6af184 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -170,7 +170,9 @@ void __cfg80211_send_deauth(struct net_device *dev, | |||
170 | break; | 170 | break; |
171 | } | 171 | } |
172 | if (wdev->authtry_bsses[i] && | 172 | if (wdev->authtry_bsses[i] && |
173 | memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { | 173 | memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, |
174 | ETH_ALEN) == 0 && | ||
175 | memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) == 0) { | ||
174 | cfg80211_unhold_bss(wdev->authtry_bsses[i]); | 176 | cfg80211_unhold_bss(wdev->authtry_bsses[i]); |
175 | cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); | 177 | cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); |
176 | wdev->authtry_bsses[i] = NULL; | 178 | wdev->authtry_bsses[i] = NULL; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 10823e2b60ce..aed6d2ad4c90 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3620,7 +3620,8 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb, | |||
3620 | return __cfg80211_stop_sched_scan(rdev, false); | 3620 | return __cfg80211_stop_sched_scan(rdev, false); |
3621 | } | 3621 | } |
3622 | 3622 | ||
3623 | static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, | 3623 | static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, |
3624 | u32 seq, int flags, | ||
3624 | struct cfg80211_registered_device *rdev, | 3625 | struct cfg80211_registered_device *rdev, |
3625 | struct wireless_dev *wdev, | 3626 | struct wireless_dev *wdev, |
3626 | struct cfg80211_internal_bss *intbss) | 3627 | struct cfg80211_internal_bss *intbss) |
@@ -3632,11 +3633,13 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
3632 | 3633 | ||
3633 | ASSERT_WDEV_LOCK(wdev); | 3634 | ASSERT_WDEV_LOCK(wdev); |
3634 | 3635 | ||
3635 | hdr = nl80211hdr_put(msg, pid, seq, flags, | 3636 | hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).pid, seq, flags, |
3636 | NL80211_CMD_NEW_SCAN_RESULTS); | 3637 | NL80211_CMD_NEW_SCAN_RESULTS); |
3637 | if (!hdr) | 3638 | if (!hdr) |
3638 | return -1; | 3639 | return -1; |
3639 | 3640 | ||
3641 | genl_dump_check_consistent(cb, hdr, &nl80211_fam); | ||
3642 | |||
3640 | NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation); | 3643 | NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation); |
3641 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex); | 3644 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex); |
3642 | 3645 | ||
@@ -3725,11 +3728,12 @@ static int nl80211_dump_scan(struct sk_buff *skb, | |||
3725 | spin_lock_bh(&rdev->bss_lock); | 3728 | spin_lock_bh(&rdev->bss_lock); |
3726 | cfg80211_bss_expire(rdev); | 3729 | cfg80211_bss_expire(rdev); |
3727 | 3730 | ||
3731 | cb->seq = rdev->bss_generation; | ||
3732 | |||
3728 | list_for_each_entry(scan, &rdev->bss_list, list) { | 3733 | list_for_each_entry(scan, &rdev->bss_list, list) { |
3729 | if (++idx <= start) | 3734 | if (++idx <= start) |
3730 | continue; | 3735 | continue; |
3731 | if (nl80211_send_bss(skb, | 3736 | if (nl80211_send_bss(skb, cb, |
3732 | NETLINK_CB(cb->skb).pid, | ||
3733 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 3737 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
3734 | rdev, wdev, scan) < 0) { | 3738 | rdev, wdev, scan) < 0) { |
3735 | idx--; | 3739 | idx--; |