From ddf2320553827e7d54a9394f6aea982e3e577e10 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 16 May 2011 16:42:01 -0300 Subject: [PATCH] --- yaml --- r: 255817 b: refs/heads/master c: dc50a06dac61d7ca7ddb3d9bb8921ca5d68f51b6 h: refs/heads/master i: 255815: 4b9c8357eef30cf5464c2e7700fee89ae3fd0507 v: v3 --- [refs] | 2 +- trunk/drivers/bcma/bcma_private.h | 4 +- trunk/drivers/bcma/core.c | 3 +- trunk/drivers/bcma/driver_chipcommon_pmu.c | 6 +- trunk/drivers/bcma/driver_pci.c | 1 - trunk/drivers/bcma/host_pci.c | 1 - trunk/drivers/bcma/main.c | 2 + trunk/drivers/net/wireless/ath/ath5k/ahb.c | 1 - trunk/drivers/net/wireless/ath/ath5k/ath5k.h | 7 +- trunk/drivers/net/wireless/ath/ath5k/base.c | 15 +- .../net/wireless/ath/ath5k/mac80211-ops.c | 6 +- trunk/drivers/net/wireless/ath/ath5k/reset.c | 6 +- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 4 +- .../net/wireless/ath/ath9k/ar9003_paprd.c | 21 +- trunk/drivers/net/wireless/ath/ath9k/ath9k.h | 4 +- trunk/drivers/net/wireless/ath/ath9k/hw.h | 5 +- trunk/drivers/net/wireless/ath/ath9k/main.c | 16 +- trunk/drivers/net/wireless/ath/ath9k/rc.c | 6 +- trunk/drivers/net/wireless/b43/Kconfig | 13 - trunk/drivers/net/wireless/b43/Makefile | 1 - trunk/drivers/net/wireless/b43/b43.h | 6 - trunk/drivers/net/wireless/b43/bus.c | 9 +- trunk/drivers/net/wireless/b43/main.c | 37 +- trunk/drivers/net/wireless/b43/phy_common.c | 6 - trunk/drivers/net/wireless/b43/phy_common.h | 3 - trunk/drivers/net/wireless/b43/phy_ht.c | 156 ----- trunk/drivers/net/wireless/b43/phy_ht.h | 26 - .../drivers/net/wireless/iwlegacy/iwl-3945.c | 4 + .../net/wireless/iwlegacy/iwl-4965-lib.c | 79 ++- .../net/wireless/iwlegacy/iwl-4965-rx.c | 78 ++- .../drivers/net/wireless/iwlegacy/iwl-4965.c | 13 +- .../net/wireless/iwlegacy/iwl-commands.h | 7 + .../drivers/net/wireless/iwlegacy/iwl-core.c | 121 ++-- .../drivers/net/wireless/iwlegacy/iwl-core.h | 17 +- .../net/wireless/iwlegacy/iwl-debugfs.c | 192 +++++- trunk/drivers/net/wireless/iwlegacy/iwl-dev.h | 73 ++- .../net/wireless/iwlegacy/iwl-devtrace.c | 3 + .../net/wireless/iwlegacy/iwl-devtrace.h | 60 ++ .../net/wireless/iwlegacy/iwl-helpers.h | 9 - trunk/drivers/net/wireless/iwlegacy/iwl-rx.c | 21 + .../drivers/net/wireless/iwlegacy/iwl-scan.c | 92 ++- .../net/wireless/iwlegacy/iwl3945-base.c | 301 ++++++++- .../net/wireless/iwlegacy/iwl4965-base.c | 463 ++++++++++++-- trunk/drivers/net/wireless/iwlwifi/Makefile | 1 - trunk/drivers/net/wireless/iwlwifi/iwl-1000.c | 4 + trunk/drivers/net/wireless/iwlwifi/iwl-2000.c | 20 +- .../net/wireless/iwlwifi/iwl-5000-hw.h | 2 +- trunk/drivers/net/wireless/iwlwifi/iwl-5000.c | 23 +- trunk/drivers/net/wireless/iwlwifi/iwl-6000.c | 22 +- .../net/wireless/iwlwifi/iwl-agn-eeprom.c | 14 +- .../net/wireless/iwlwifi/iwl-agn-hcmd.c | 12 +- .../drivers/net/wireless/iwlwifi/iwl-agn-hw.h | 7 + .../net/wireless/iwlwifi/iwl-agn-ict.c | 4 +- .../net/wireless/iwlwifi/iwl-agn-lib.c | 75 +-- .../drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 38 +- .../drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 30 +- .../net/wireless/iwlwifi/iwl-agn-ucode.c | 45 +- trunk/drivers/net/wireless/iwlwifi/iwl-agn.c | 541 ++++++++++++----- trunk/drivers/net/wireless/iwlwifi/iwl-agn.h | 26 +- .../net/wireless/iwlwifi/iwl-commands.h | 35 +- trunk/drivers/net/wireless/iwlwifi/iwl-core.c | 85 ++- trunk/drivers/net/wireless/iwlwifi/iwl-core.h | 47 +- .../drivers/net/wireless/iwlwifi/iwl-debug.h | 18 +- .../net/wireless/iwlwifi/iwl-debugfs.c | 7 +- trunk/drivers/net/wireless/iwlwifi/iwl-dev.h | 60 +- .../drivers/net/wireless/iwlwifi/iwl-eeprom.c | 25 - .../drivers/net/wireless/iwlwifi/iwl-eeprom.h | 25 +- trunk/drivers/net/wireless/iwlwifi/iwl-hcmd.c | 11 +- .../net/wireless/iwlwifi/iwl-helpers.h | 9 - trunk/drivers/net/wireless/iwlwifi/iwl-io.h | 6 +- trunk/drivers/net/wireless/iwlwifi/iwl-led.c | 14 +- trunk/drivers/net/wireless/iwlwifi/iwl-pci.c | 571 ------------------ trunk/drivers/net/wireless/iwlwifi/iwl-pci.h | 69 --- .../drivers/net/wireless/iwlwifi/iwl-power.c | 33 +- .../drivers/net/wireless/iwlwifi/iwl-power.h | 2 +- trunk/drivers/net/wireless/iwlwifi/iwl-rx.c | 4 +- .../net/wireless/iwlwifi/iwl-sv-open.c | 139 +---- .../net/wireless/iwlwifi/iwl-testmode.h | 9 +- trunk/drivers/net/wireless/iwlwifi/iwl-tx.c | 33 +- trunk/drivers/net/wireless/libertas/if_sdio.c | 34 -- trunk/drivers/net/wireless/libertas/if_spi.c | 6 +- trunk/drivers/net/wireless/mwifiex/main.c | 16 +- trunk/drivers/net/wireless/mwifiex/main.h | 1 + trunk/drivers/net/wireless/mwifiex/sdio.c | 81 +-- trunk/drivers/net/wireless/rtlwifi/base.c | 2 +- trunk/drivers/net/wireless/rtlwifi/core.c | 12 +- trunk/drivers/net/wireless/rtlwifi/core.h | 2 - trunk/drivers/net/wireless/rtlwifi/efuse.c | 8 +- trunk/drivers/net/wireless/rtlwifi/pci.c | 198 +++--- trunk/drivers/net/wireless/rtlwifi/ps.c | 65 +- trunk/drivers/net/wireless/rtlwifi/ps.h | 3 +- trunk/drivers/net/wireless/rtlwifi/rc.c | 2 +- .../net/wireless/rtlwifi/rtl8192c/dm_common.c | 4 +- .../net/wireless/rtlwifi/rtl8192ce/hw.c | 10 +- .../net/wireless/rtlwifi/rtl8192ce/led.c | 2 +- .../net/wireless/rtlwifi/rtl8192ce/rf.c | 2 +- .../net/wireless/rtlwifi/rtl8192ce/trx.c | 8 +- .../net/wireless/rtlwifi/rtl8192cu/hw.c | 8 +- .../net/wireless/rtlwifi/rtl8192cu/led.c | 2 +- .../net/wireless/rtlwifi/rtl8192cu/rf.c | 2 +- .../net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- .../net/wireless/rtlwifi/rtl8192se/dm.c | 2 +- .../net/wireless/rtlwifi/rtl8192se/hw.c | 11 +- .../net/wireless/rtlwifi/rtl8192se/led.c | 2 +- .../net/wireless/rtlwifi/rtl8192se/phy.c | 4 +- .../net/wireless/rtlwifi/rtl8192se/reg.h | 6 +- .../net/wireless/rtlwifi/rtl8192se/rf.c | 2 +- .../net/wireless/rtlwifi/rtl8192se/trx.c | 6 +- trunk/drivers/net/wireless/rtlwifi/wifi.h | 4 +- trunk/drivers/net/wireless/zd1211rw/zd_chip.h | 2 - trunk/drivers/ssb/driver_chipcommon_pmu.c | 4 +- trunk/include/linux/bcma/bcma.h | 1 - trunk/include/linux/bcma/bcma_driver_pci.h | 2 - trunk/include/net/mac80211.h | 20 - trunk/net/bluetooth/l2cap_core.c | 18 +- trunk/net/bluetooth/l2cap_sock.c | 18 +- trunk/net/mac80211/driver-ops.h | 10 - trunk/net/mac80211/driver-trace.h | 6 - trunk/net/mac80211/ibss.c | 6 +- trunk/net/mac80211/mlme.c | 14 +- trunk/net/mac80211/pm.c | 43 +- trunk/net/mac80211/scan.c | 37 +- trunk/net/mac80211/util.c | 2 - trunk/net/wireless/mlme.c | 4 +- trunk/net/wireless/nl80211.c | 9 +- 125 files changed, 2570 insertions(+), 2099 deletions(-) delete mode 100644 trunk/drivers/net/wireless/b43/phy_ht.c delete mode 100644 trunk/drivers/net/wireless/b43/phy_ht.h delete mode 100644 trunk/drivers/net/wireless/iwlwifi/iwl-pci.c delete mode 100644 trunk/drivers/net/wireless/iwlwifi/iwl-pci.h diff --git a/[refs] b/[refs] index 21dcd4a4c335..23d4111cb90c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e10542c447abf7c840931ff12f7d0dee976ca2ea +refs/heads/master: dc50a06dac61d7ca7ddb3d9bb8921ca5d68f51b6 diff --git a/trunk/drivers/bcma/bcma_private.h b/trunk/drivers/bcma/bcma_private.h index 4228736de0e8..12a75ab3dd23 100644 --- a/trunk/drivers/bcma/bcma_private.h +++ b/trunk/drivers/bcma/bcma_private.h @@ -13,8 +13,8 @@ struct bcma_bus; /* main.c */ -int bcma_bus_register(struct bcma_bus *bus); -void bcma_bus_unregister(struct bcma_bus *bus); +extern int bcma_bus_register(struct bcma_bus *bus); +extern void bcma_bus_unregister(struct bcma_bus *bus); /* scan.c */ int bcma_bus_scan(struct bcma_bus *bus); diff --git a/trunk/drivers/bcma/core.c b/trunk/drivers/bcma/core.c index 1ec7d4528dd0..ced379f7b371 100644 --- a/trunk/drivers/bcma/core.c +++ b/trunk/drivers/bcma/core.c @@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_device *core) } EXPORT_SYMBOL_GPL(bcma_core_is_enabled); -void bcma_core_disable(struct bcma_device *core, u32 flags) +static void bcma_core_disable(struct bcma_device *core, u32 flags) { if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) return; @@ -31,7 +31,6 @@ void bcma_core_disable(struct bcma_device *core, u32 flags) bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET); udelay(1); } -EXPORT_SYMBOL_GPL(bcma_core_disable); int bcma_core_enable(struct bcma_device *core, u32 flags) { diff --git a/trunk/drivers/bcma/driver_chipcommon_pmu.c b/trunk/drivers/bcma/driver_chipcommon_pmu.c index dd5846bef029..f44177a644c7 100644 --- a/trunk/drivers/bcma/driver_chipcommon_pmu.c +++ b/trunk/drivers/bcma/driver_chipcommon_pmu.c @@ -53,7 +53,6 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) max_msk = 0xFFFF; break; case 43224: - case 43225: break; default: pr_err("PMU resource config unknown for device 0x%04X\n", @@ -75,7 +74,6 @@ void bcma_pmu_swreg_init(struct bcma_drv_cc *cc) case 0x4313: case 0x4331: case 43224: - case 43225: break; default: pr_err("PMU switch/regulators init unknown for device " @@ -98,13 +96,11 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc) if (bus->chipinfo.rev == 0) { pr_err("Workarounds for 43224 rev 0 not fully " "implemented\n"); - bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0); + bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); } else { bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); } break; - case 43225: - break; default: pr_err("Workarounds unknown for device 0x%04X\n", bus->chipinfo.id); diff --git a/trunk/drivers/bcma/driver_pci.c b/trunk/drivers/bcma/driver_pci.c index b0c19ede0d2e..789d68b4858b 100644 --- a/trunk/drivers/bcma/driver_pci.c +++ b/trunk/drivers/bcma/driver_pci.c @@ -184,4 +184,3 @@ int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, out: return err; } -EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl); diff --git a/trunk/drivers/bcma/host_pci.c b/trunk/drivers/bcma/host_pci.c index c4b313afb9cc..279bf50f6d8e 100644 --- a/trunk/drivers/bcma/host_pci.c +++ b/trunk/drivers/bcma/host_pci.c @@ -226,7 +226,6 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, { 0, }, }; diff --git a/trunk/drivers/bcma/main.c b/trunk/drivers/bcma/main.c index ba15105cc23a..11e96dc6011a 100644 --- a/trunk/drivers/bcma/main.c +++ b/trunk/drivers/bcma/main.c @@ -160,11 +160,13 @@ int bcma_bus_register(struct bcma_bus *bus) return 0; } +EXPORT_SYMBOL_GPL(bcma_bus_register); void bcma_bus_unregister(struct bcma_bus *bus) { bcma_unregister_cores(bus); } +EXPORT_SYMBOL_GPL(bcma_bus_unregister); int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) { diff --git a/trunk/drivers/net/wireless/ath/ath5k/ahb.c b/trunk/drivers/net/wireless/ath/ath5k/ahb.c index c38e9e848995..ea9982781559 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/ahb.c +++ b/trunk/drivers/net/wireless/ath/ath5k/ahb.c @@ -219,7 +219,6 @@ static int ath_ahb_remove(struct platform_device *pdev) ath5k_deinit_softc(sc); platform_set_drvdata(pdev, NULL); - ieee80211_free_hw(hw); return 0; } diff --git a/trunk/drivers/net/wireless/ath/ath5k/ath5k.h b/trunk/drivers/net/wireless/ath/ath5k/ath5k.h index c4c02d5145c2..bb50700436fe 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/trunk/drivers/net/wireless/ath/ath5k/ath5k.h @@ -767,7 +767,6 @@ struct ath5k_athchan_2ghz { */ #define AR5K_KEYCACHE_SIZE 8 -extern int ath5k_modparam_nohwcrypt; /***********************\ HW RELATED DEFINITIONS @@ -1181,8 +1180,8 @@ void ath5k_sysfs_unregister(struct ath5k_softc *sc); struct ath5k_buf; struct ath5k_txq; -void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable); -bool ath5k_any_vif_assoc(struct ath5k_softc *sc); +void set_beacon_filter(struct ieee80211_hw *hw, bool enable); +bool ath_any_vif_assoc(struct ath5k_softc *sc); void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath5k_txq *txq); int ath5k_init_hw(struct ath5k_softc *sc); @@ -1254,7 +1253,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, int len, struct ieee80211_rate *rate, bool shortpre); unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); -int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); +extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); /* RX filter control*/ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index a6623ddfdefe..b6c5d3715b96 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -87,6 +87,8 @@ MODULE_LICENSE("Dual BSD/GPL"); static int ath5k_init(struct ieee80211_hw *hw); static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, bool skip_pcu); +int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { @@ -2159,7 +2161,7 @@ ath5k_schedule_tx(struct ath5k_softc *sc) tasklet_schedule(&sc->txtq); } -static irqreturn_t +irqreturn_t ath5k_intr(int irq, void *dev_id) { struct ath5k_softc *sc = dev_id; @@ -2613,7 +2615,7 @@ ath5k_init_hw(struct ath5k_softc *sc) return ret; } -static void ath5k_stop_tasklets(struct ath5k_softc *sc) +static void stop_tasklets(struct ath5k_softc *sc) { sc->rx_pending = false; sc->tx_pending = false; @@ -2667,7 +2669,7 @@ ath5k_stop_hw(struct ath5k_softc *sc) mmiowb(); mutex_unlock(&sc->lock); - ath5k_stop_tasklets(sc); + stop_tasklets(sc); cancel_delayed_work_sync(&sc->tx_complete_work); @@ -2695,7 +2697,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, ath5k_hw_set_imr(ah, 0); synchronize_irq(sc->irq); - ath5k_stop_tasklets(sc); + stop_tasklets(sc); /* Save ani mode and disable ANI during * reset. If we don't we might get false @@ -2960,12 +2962,11 @@ ath5k_deinit_softc(struct ath5k_softc *sc) * state and potentially want to use them. */ ath5k_hw_deinit(sc->ah); - kfree(sc->ah); free_irq(sc->irq, sc); } bool -ath5k_any_vif_assoc(struct ath5k_softc *sc) +ath_any_vif_assoc(struct ath5k_softc *sc) { struct ath5k_vif_iter_data iter_data; iter_data.hw_macaddr = NULL; @@ -2979,7 +2980,7 @@ ath5k_any_vif_assoc(struct ath5k_softc *sc) } void -ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable) +set_beacon_filter(struct ieee80211_hw *hw, bool enable) { struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; diff --git a/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 493908299bb4..807bd6440169 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -46,6 +46,8 @@ #include "base.h" #include "reg.h" +extern int ath5k_modparam_nohwcrypt; + /********************\ * Mac80211 functions * \********************/ @@ -294,10 +296,10 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (bss_conf->assoc) sc->assoc = bss_conf->assoc; else - sc->assoc = ath5k_any_vif_assoc(sc); + sc->assoc = ath_any_vif_assoc(sc); if (sc->opmode == NL80211_IFTYPE_STATION) - ath5k_set_beacon_filter(hw, sc->assoc); + set_beacon_filter(hw, sc->assoc); ath5k_hw_set_ledstate(sc->ah, sc->assoc ? AR5K_LED_ASSOC : AR5K_LED_INIT); if (bss_conf->assoc) { diff --git a/trunk/drivers/net/wireless/ath/ath5k/reset.c b/trunk/drivers/net/wireless/ath/ath5k/reset.c index 1676a3e3dc3d..126a4eab35f3 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/reset.c +++ b/trunk/drivers/net/wireless/ath/ath5k/reset.c @@ -375,19 +375,19 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags) { u32 mask = flags ? flags : ~0U; - volatile __iomem u32 *reg; + volatile u32 *reg; u32 regval; u32 val = 0; /* ah->ah_mac_srev is not available at this point yet */ if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) { - reg = (u32 __iomem *) AR5K_AR2315_RESET; + reg = (u32 *) AR5K_AR2315_RESET; if (mask & AR5K_RESET_CTL_PCU) val |= AR5K_AR2315_RESET_WMAC; if (mask & AR5K_RESET_CTL_BASEBAND) val |= AR5K_AR2315_RESET_BB_WARM; } else { - reg = (u32 __iomem *) AR5K_AR5312_RESET; + reg = (u32 *) AR5K_AR5312_RESET; if (to_platform_device(ah->ah_sc->dev)->id == 0) { if (mask & AR5K_RESET_CTL_PCU) val |= AR5K_AR5312_RESET_WMAC0; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 2e370c668d4e..ff8150e46f0e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -1461,7 +1461,7 @@ static const struct ar9300_eeprom ar9300_h112 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -2616,7 +2616,7 @@ static const struct ar9300_eeprom ar9300_h116 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index fc9c08f513cf..2e7f0f2567eb 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -785,26 +785,7 @@ EXPORT_SYMBOL(ar9003_paprd_init_table); bool ar9003_paprd_is_done(struct ath_hw *ah) { - int paprd_done, agc2_pwr; - paprd_done = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, + return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); - - if (paprd_done == 0x1) { - agc2_pwr = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, - AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR); - - ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, - "AGC2_PWR = 0x%x training done = 0x%x\n", - agc2_pwr, paprd_done); - /* - * agc2_pwr range should not be less than 'IDEAL_AGC2_PWR_CHANGE' - * when the training is completely done, otherwise retraining is - * done to make sure the value is in ideal range - */ - if (agc2_pwr <= PAPRD_IDEAL_AGC2_PWR_RANGE) - paprd_done = 0; - } - - return !!paprd_done; } EXPORT_SYMBOL(ar9003_paprd_is_done); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 56a0ac4ddc62..3bf1d83ab41f 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -54,6 +54,8 @@ struct ath_node; (_l) &= ((_sz) - 1); \ } while (0) +#define A_MAX(a, b) ((a) > (b) ? (a) : (b)) + #define TSF_TO_TU(_h,_l) \ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) @@ -577,7 +579,7 @@ struct ath9k_vif_iter_data { int naps; /* number of AP vifs */ int nmeshes; /* number of mesh vifs */ int nstations; /* number of station vifs */ - int nwds; /* number of WDS vifs */ + int nwds; /* number of nwd vifs */ int nadhocs; /* number of adhoc vifs */ int nothers; /* number of vifs not specified above. */ }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index 66d2225b95f3..6a6fb5439831 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -157,9 +157,8 @@ #define ATH9K_HW_RX_HP_QDEPTH 16 #define ATH9K_HW_RX_LP_QDEPTH 128 -#define PAPRD_GAIN_TABLE_ENTRIES 32 -#define PAPRD_TABLE_SZ 24 -#define PAPRD_IDEAL_AGC2_PWR_RANGE 0xe0 +#define PAPRD_GAIN_TABLE_ENTRIES 32 +#define PAPRD_TABLE_SZ 24 enum ath_hw_txq_subtype { ATH_TXQ_AC_BE = 0, diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 5ae303b11e68..7f945333e2d8 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/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 txctl.paprd = BIT(chain); if (ath_tx_start(hw, skb, &txctl) != 0) { - ath_dbg(common, ATH_DBG_CALIBRATE, "PAPRD TX failed\n"); + ath_dbg(common, ATH_DBG_XMIT, "PAPRD TX failed\n"); dev_kfree_skb_any(skb); return false; } @@ -369,7 +369,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); if (!time_left) - ath_dbg(common, ATH_DBG_CALIBRATE, + ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, "Timeout waiting for paprd training on TX chain %d\n", chain); @@ -431,18 +431,11 @@ void ath_paprd_calibrate(struct work_struct *work) if (!ath_paprd_send_frame(sc, skb, chain)) goto fail_paprd; - if (!ar9003_paprd_is_done(ah)) { - ath_dbg(common, ATH_DBG_CALIBRATE, - "PAPRD not yet done on chain %d\n", chain); + if (!ar9003_paprd_is_done(ah)) break; - } - if (ar9003_paprd_create_curve(ah, caldata, chain)) { - ath_dbg(common, ATH_DBG_CALIBRATE, - "PAPRD create curve failed on chain %d\n", - chain); + if (ar9003_paprd_create_curve(ah, caldata, chain) != 0) break; - } chain_ok = 1; } @@ -1266,6 +1259,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) /* disable HAL and put h/w to sleep */ ath9k_hw_disable(ah); + ath9k_hw_configpcipowersave(ah, 1, 1); spin_unlock_bh(&sc->sc_pcu_lock); diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index e7fe4d9aee79..ba7f36ab0a74 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -533,7 +533,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, [valid_rate_count] = j; ath_rc_priv->valid_phy_ratecnt[phy] += 1; ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); - hi = max(hi, j); + hi = A_MAX(hi, j); } } } @@ -569,7 +569,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, [ath_rc_priv->valid_phy_ratecnt[phy]] = j; ath_rc_priv->valid_phy_ratecnt[phy] += 1; ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1); - hi = max(hi, j); + hi = A_MAX(hi, j); } } @@ -1228,7 +1228,7 @@ static void ath_rc_init(struct ath_softc *sc, ht_mcs, ath_rc_priv->ht_cap); } - hi = max(hi, hthi); + hi = A_MAX(hi, hthi); } ath_rc_priv->rate_table_size = hi + 1; diff --git a/trunk/drivers/net/wireless/b43/Kconfig b/trunk/drivers/net/wireless/b43/Kconfig index d5add69aac8f..fe26bf448fdb 100644 --- a/trunk/drivers/net/wireless/b43/Kconfig +++ b/trunk/drivers/net/wireless/b43/Kconfig @@ -31,11 +31,6 @@ config B43_BCMA depends on B43 && BCMA && BROKEN default y -config B43_SSB - bool - depends on B43 && SSB - default y - # Auto-select SSB PCI-HOST support, if possible config B43_PCI_AUTOSELECT bool @@ -117,14 +112,6 @@ config B43_PHY_LP and embedded devices. It supports 802.11a/g (802.11a support is optional, and currently disabled). -config B43_PHY_HT - bool "Support for HT-PHY devices (BROKEN)" - depends on B43 && BROKEN - ---help--- - Support for the HT-PHY. - - Say N, this is BROKEN and crashes driver. - # This config option automatically enables b43 LEDS support, # if it's possible. config B43_LEDS diff --git a/trunk/drivers/net/wireless/b43/Makefile b/trunk/drivers/net/wireless/b43/Makefile index 58d614a889b9..95f7c001fda1 100644 --- a/trunk/drivers/net/wireless/b43/Makefile +++ b/trunk/drivers/net/wireless/b43/Makefile @@ -10,7 +10,6 @@ b43-y += phy_a.o b43-$(CONFIG_B43_PHY_N) += phy_n.o b43-$(CONFIG_B43_PHY_LP) += phy_lp.o b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o -b43-$(CONFIG_B43_PHY_HT) += phy_ht.o b43-y += sysfs.o b43-y += xmit.o b43-y += lo.o diff --git a/trunk/drivers/net/wireless/b43/b43.h b/trunk/drivers/net/wireless/b43/b43.h index 666515e348b5..1cb2ddee9dcf 100644 --- a/trunk/drivers/net/wireless/b43/b43.h +++ b/trunk/drivers/net/wireless/b43/b43.h @@ -92,8 +92,6 @@ #define B43_MMIO_PIO11_BASE4 0x300 #define B43_MMIO_PIO11_BASE5 0x340 -#define B43_MMIO_RADIO24_CONTROL 0x3D8 /* core rev >= 24 only */ -#define B43_MMIO_RADIO24_DATA 0x3DA /* core rev >= 24 only */ #define B43_MMIO_PHY_VER 0x3E0 #define B43_MMIO_PHY_RADIO 0x3E2 #define B43_MMIO_PHY0 0x3E6 @@ -365,10 +363,6 @@ enum { #define B43_PHYTYPE_G 0x02 #define B43_PHYTYPE_N 0x04 #define B43_PHYTYPE_LP 0x05 -#define B43_PHYTYPE_SSLPN 0x06 -#define B43_PHYTYPE_HT 0x07 -#define B43_PHYTYPE_LCN 0x08 -#define B43_PHYTYPE_LCNXN 0x09 /* PHYRegisters */ #define B43_PHY_ILT_A_CTRL 0x0072 diff --git a/trunk/drivers/net/wireless/b43/bus.c b/trunk/drivers/net/wireless/b43/bus.c index 4200713eb597..6c63aecd6ab4 100644 --- a/trunk/drivers/net/wireless/b43/bus.c +++ b/trunk/drivers/net/wireless/b43/bus.c @@ -25,7 +25,7 @@ /* SSB */ -#ifdef CONFIG_B43_SSB + static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev) { return ssb_bus_may_powerdown(dev->sdev->bus); @@ -83,11 +83,7 @@ void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer, struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) { - struct b43_bus_dev *dev; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; + struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); dev->bus_type = B43_BUS_SSB; dev->sdev = sdev; @@ -124,4 +120,3 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) return dev; } -#endif /* CONFIG_B43_SSB */ diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 834df5a3fb6a..1d8d98324d15 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -123,7 +123,6 @@ static const struct bcma_device_id b43_bcma_tbl[] = { MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); #endif -#ifdef CONFIG_B43_SSB static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), @@ -137,8 +136,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), SSB_DEVTABLE_END }; + MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); -#endif /* Channel and ratetables are shared for all devices. * They can't be const, because ieee80211 puts some precalculated @@ -4097,12 +4096,6 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (phy_rev > 2) unsupported = 1; break; -#endif -#ifdef CONFIG_B43_PHY_HT - case B43_PHYTYPE_HT: - if (phy_rev > 1) - unsupported = 1; - break; #endif default: unsupported = 1; @@ -4160,10 +4153,6 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (radio_ver != 0x2062 && radio_ver != 0x2063) unsupported = 1; break; - case B43_PHYTYPE_HT: - if (radio_ver != 0x2059) - unsupported = 1; - break; default: B43_WARN_ON(1); } @@ -5027,7 +5016,6 @@ static struct bcma_driver b43_bcma_driver = { }; #endif -#ifdef CONFIG_B43_SSB static int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) { @@ -5037,8 +5025,6 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) int first = 0; dev = b43_bus_dev_ssb_init(sdev); - if (!dev) - return -ENOMEM; wl = ssb_get_devtypedata(sdev); if (!wl) { @@ -5105,14 +5091,6 @@ static void b43_ssb_remove(struct ssb_device *sdev) } } -static struct ssb_driver b43_ssb_driver = { - .name = KBUILD_MODNAME, - .id_table = b43_ssb_tbl, - .probe = b43_ssb_probe, - .remove = b43_ssb_remove, -}; -#endif /* CONFIG_B43_SSB */ - /* Perform a hardware reset. This can be called from any context. */ void b43_controller_restart(struct b43_wldev *dev, const char *reason) { @@ -5123,6 +5101,13 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason) ieee80211_queue_work(dev->wl->hw, &dev->restart_work); } +static struct ssb_driver b43_ssb_driver = { + .name = KBUILD_MODNAME, + .id_table = b43_ssb_tbl, + .probe = b43_ssb_probe, + .remove = b43_ssb_remove, +}; + static void b43_print_driverinfo(void) { const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", @@ -5166,18 +5151,14 @@ static int __init b43_init(void) if (err) goto err_sdio_exit; #endif -#ifdef CONFIG_B43_SSB err = ssb_driver_register(&b43_ssb_driver); if (err) goto err_bcma_driver_exit; -#endif b43_print_driverinfo(); return err; -#ifdef CONFIG_B43_SSB err_bcma_driver_exit: -#endif #ifdef CONFIG_B43_BCMA bcma_driver_unregister(&b43_bcma_driver); err_sdio_exit: @@ -5192,9 +5173,7 @@ static int __init b43_init(void) static void __exit b43_exit(void) { -#ifdef CONFIG_B43_SSB ssb_driver_unregister(&b43_ssb_driver); -#endif #ifdef CONFIG_B43_BCMA bcma_driver_unregister(&b43_bcma_driver); #endif diff --git a/trunk/drivers/net/wireless/b43/phy_common.c b/trunk/drivers/net/wireless/b43/phy_common.c index 9705950f059a..425af28ea4e5 100644 --- a/trunk/drivers/net/wireless/b43/phy_common.c +++ b/trunk/drivers/net/wireless/b43/phy_common.c @@ -31,7 +31,6 @@ #include "phy_a.h" #include "phy_n.h" #include "phy_lp.h" -#include "phy_ht.h" #include "b43.h" #include "main.h" @@ -58,11 +57,6 @@ int b43_phy_allocate(struct b43_wldev *dev) case B43_PHYTYPE_LP: #ifdef CONFIG_B43_PHY_LP phy->ops = &b43_phyops_lp; -#endif - break; - case B43_PHYTYPE_HT: -#ifdef CONFIG_B43_PHY_HT - phy->ops = &b43_phyops_ht; #endif break; } diff --git a/trunk/drivers/net/wireless/b43/phy_common.h b/trunk/drivers/net/wireless/b43/phy_common.h index 47dcb800a3c3..2401bee8b081 100644 --- a/trunk/drivers/net/wireless/b43/phy_common.h +++ b/trunk/drivers/net/wireless/b43/phy_common.h @@ -194,7 +194,6 @@ struct b43_phy_a; struct b43_phy_g; struct b43_phy_n; struct b43_phy_lp; -struct b43_phy_ht; struct b43_phy { /* Hardware operation callbacks. */ @@ -217,8 +216,6 @@ struct b43_phy { struct b43_phy_n *n; /* LP-PHY specific information */ struct b43_phy_lp *lp; - /* HT-PHY specific information */ - struct b43_phy_ht *ht; }; /* Band support flags. */ diff --git a/trunk/drivers/net/wireless/b43/phy_ht.c b/trunk/drivers/net/wireless/b43/phy_ht.c deleted file mode 100644 index 5777cdbc047b..000000000000 --- a/trunk/drivers/net/wireless/b43/phy_ht.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - - Broadcom B43 wireless driver - IEEE 802.11n HT-PHY support - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include - -#include "b43.h" -#include "phy_ht.h" -#include "main.h" - -/************************************************** - * Basic PHY ops. - **************************************************/ - -static int b43_phy_ht_op_allocate(struct b43_wldev *dev) -{ - struct b43_phy_ht *phy_ht; - - phy_ht = kzalloc(sizeof(*phy_ht), GFP_KERNEL); - if (!phy_ht) - return -ENOMEM; - dev->phy.ht = phy_ht; - - return 0; -} - -static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; - struct b43_phy_ht *phy_ht = phy->ht; - - memset(phy_ht, 0, sizeof(*phy_ht)); -} - -static void b43_phy_ht_op_free(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; - struct b43_phy_ht *phy_ht = phy->ht; - - kfree(phy_ht); - phy->ht = NULL; -} - -static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on) -{ - if (on) { - b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000); - } else { - b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff); - b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd); - } -} - -static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev) -{ - if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - return 1; - return 36; -} - -/************************************************** - * R/W ops. - **************************************************/ - -static u16 b43_phy_ht_op_read(struct b43_wldev *dev, u16 reg) -{ - b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); - return b43_read16(dev, B43_MMIO_PHY_DATA); -} - -static void b43_phy_ht_op_write(struct b43_wldev *dev, u16 reg, u16 value) -{ - b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); - b43_write16(dev, B43_MMIO_PHY_DATA, value); -} - -static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, - u16 set) -{ - b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); - b43_write16(dev, B43_MMIO_PHY_DATA, - (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); -} - -static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg) -{ - /* HT-PHY needs 0x200 for read access */ - reg |= 0x200; - - b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); - return b43_read16(dev, B43_MMIO_RADIO24_DATA); -} - -static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg, - u16 value) -{ - b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); - b43_write16(dev, B43_MMIO_RADIO24_DATA, value); -} - -/************************************************** - * PHY ops struct. - **************************************************/ - -const struct b43_phy_operations b43_phyops_ht = { - .allocate = b43_phy_ht_op_allocate, - .free = b43_phy_ht_op_free, - .prepare_structs = b43_phy_ht_op_prepare_structs, - /* - .init = b43_phy_ht_op_init, - */ - .phy_read = b43_phy_ht_op_read, - .phy_write = b43_phy_ht_op_write, - .phy_maskset = b43_phy_ht_op_maskset, - .radio_read = b43_phy_ht_op_radio_read, - .radio_write = b43_phy_ht_op_radio_write, - /* - .software_rfkill = b43_phy_ht_op_software_rfkill, - */ - .switch_analog = b43_phy_ht_op_switch_analog, - /* - .switch_channel = b43_phy_ht_op_switch_channel, - */ - .get_default_chan = b43_phy_ht_op_get_default_chan, - /* - .recalc_txpower = b43_phy_ht_op_recalc_txpower, - .adjust_txpower = b43_phy_ht_op_adjust_txpower, - */ -}; diff --git a/trunk/drivers/net/wireless/b43/phy_ht.h b/trunk/drivers/net/wireless/b43/phy_ht.h deleted file mode 100644 index 84ac47cbfaad..000000000000 --- a/trunk/drivers/net/wireless/b43/phy_ht.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef B43_PHY_HT_H_ -#define B43_PHY_HT_H_ - -#include "phy_common.h" - - -#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */ -#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ -#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ - -#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110) -#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111) -#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114) -#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115) -#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118) -#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119) - - -struct b43_phy_ht { -}; - - -struct b43_phy_operations; -extern const struct b43_phy_operations b43_phyops_ht; - -#endif /* B43_PHY_HT_H_ */ diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-3945.c b/trunk/drivers/net/wireless/iwlegacy/iwl-3945.c index dab67a12d73b..d096dc28204d 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-3945.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-3945.c @@ -408,6 +408,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv, #ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); #endif + iwl_legacy_recover_from_statistics(priv, pkt); memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); } @@ -2639,6 +2640,7 @@ static struct iwl_lib_ops iwl3945_lib = { .txq_free_tfd = iwl3945_hw_txq_free_tfd, .txq_init = iwl3945_hw_tx_queue_init, .load_ucode = iwl3945_load_bsm, + .dump_nic_event_log = iwl3945_dump_nic_event_log, .dump_nic_error_log = iwl3945_dump_nic_error_log, .apm_ops = { .init = iwl3945_apm_init, @@ -2696,7 +2698,9 @@ static struct iwl_base_params iwl3945_base_params = { .set_l0s = false, .use_bsm = true, .led_compensation = 64, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 512, }; static struct iwl_cfg iwl3945_bg_cfg = { diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index 2be6d9e3b019..a7a4739880dc 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-lib.c @@ -694,6 +694,47 @@ void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, sizeof(struct iwl_rx_phy_res)); } +static int iwl4965_get_single_channel_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + struct iwl_scan_channel *scan_ch) +{ + const struct ieee80211_supported_band *sband; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added = 0; + u16 channel = 0; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) { + IWL_ERR(priv, "invalid band\n"); + return added; + } + + active_dwell = iwl_legacy_get_active_dwell_time(priv, band, 0); + passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + channel = iwl_legacy_get_single_channel_number(priv, band); + if (channel) { + scan_ch->channel = cpu_to_le16(channel); + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + added++; + } else + IWL_ERR(priv, "no valid channel found\n"); + return added; +} + static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, struct ieee80211_vif *vif, enum ieee80211_band band, @@ -817,13 +858,16 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_time = IWL_ACTIVE_QUIET_TIME; if (iwl_legacy_is_any_associated(priv)) { - u16 interval; + u16 interval = 0; u32 extra; u32 suspend_time = 100; u32 scan_suspend_time = 100; IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - interval = vif->bss_conf.beacon_int; + if (priv->is_internal_short_scan) + interval = 0; + else + interval = vif->bss_conf.beacon_int; scan->suspend_time = 0; scan->max_out_time = cpu_to_le32(200 * 1024); @@ -838,7 +882,9 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan_suspend_time, interval); } - if (priv->scan_request->n_ssids) { + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); + } else if (priv->scan_request->n_ssids) { int i, p = 0; IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); for (i = 0; i < priv->scan_request->n_ssids; i++) { @@ -935,21 +981,38 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; scan->rx_chain = cpu_to_le16(rx_chain); - - cmd_len = iwl_legacy_fill_probe_req(priv, + if (!priv->is_internal_short_scan) { + cmd_len = iwl_legacy_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, vif->addr, priv->scan_request->ie, priv->scan_request->ie_len, IWL_MAX_SCAN_SIZE - sizeof(*scan)); + } else { + /* use bcast addr, will not be transmitted but must be valid */ + cmd_len = iwl_legacy_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + iwlegacy_bcast_addr, NULL, 0, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); + + } scan->tx_cmd.len = cpu_to_le16(cmd_len); scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | RXON_FILTER_BCON_AWARE_MSK); - scan->channel_count = iwl4965_get_channels_for_scan(priv, vif, band, - is_active, n_probes, - (void *)&scan->data[cmd_len]); + if (priv->is_internal_short_scan) { + scan->channel_count = + iwl4965_get_single_channel_for_scan(priv, vif, band, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } else { + scan->channel_count = + iwl4965_get_channels_for_scan(priv, vif, band, + is_active, n_probes, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); return -EIO; diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-rx.c b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-rx.c index 2b144bbfc3c5..b9fa2f6411a7 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-4965-rx.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-4965-rx.c @@ -151,6 +151,81 @@ static void iwl4965_accumulative_statistics(struct iwl_priv *priv, #define REG_RECALIB_PERIOD (60) +/** + * iwl4965_good_plcp_health - checks for plcp error. + * + * When the plcp error is exceeding the thresholds, reset the radio + * to improve the throughput. + */ +bool iwl4965_good_plcp_health(struct iwl_priv *priv, + struct iwl_rx_packet *pkt) +{ + bool rc = true; + int combined_plcp_delta; + unsigned int plcp_msec; + unsigned long plcp_received_jiffies; + + if (priv->cfg->base_params->plcp_delta_threshold == + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { + IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); + return rc; + } + + /* + * check for plcp_err and trigger radio reset if it exceeds + * the plcp error threshold plcp_delta. + */ + plcp_received_jiffies = jiffies; + plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - + (long) priv->plcp_jiffies); + priv->plcp_jiffies = plcp_received_jiffies; + /* + * check to make sure plcp_msec is not 0 to prevent division + * by zero. + */ + if (plcp_msec) { + struct statistics_rx_phy *ofdm; + struct statistics_rx_ht_phy *ofdm_ht; + + ofdm = &pkt->u.stats.rx.ofdm; + ofdm_ht = &pkt->u.stats.rx.ofdm_ht; + combined_plcp_delta = + (le32_to_cpu(ofdm->plcp_err) - + le32_to_cpu(priv->_4965.statistics. + rx.ofdm.plcp_err)) + + (le32_to_cpu(ofdm_ht->plcp_err) - + le32_to_cpu(priv->_4965.statistics. + rx.ofdm_ht.plcp_err)); + + if ((combined_plcp_delta > 0) && + ((combined_plcp_delta * 100) / plcp_msec) > + priv->cfg->base_params->plcp_delta_threshold) { + /* + * if plcp_err exceed the threshold, + * the following data is printed in csv format: + * Text: plcp_err exceeded %d, + * Received ofdm.plcp_err, + * Current ofdm.plcp_err, + * Received ofdm_ht.plcp_err, + * Current ofdm_ht.plcp_err, + * combined_plcp_delta, + * plcp_msec + */ + IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " + "%u, %u, %u, %u, %d, %u mSecs\n", + priv->cfg->base_params->plcp_delta_threshold, + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + combined_plcp_delta, plcp_msec); + + rc = false; + } + } + return rc; +} + void iwl4965_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -173,7 +248,8 @@ void iwl4965_rx_statistics(struct iwl_priv *priv, iwl4965_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); #endif - /* TODO: reading some of statistics is unneeded */ + iwl_legacy_recover_from_statistics(priv, pkt); + memcpy(&priv->_4965.statistics, &pkt->u.stats, sizeof(priv->_4965.statistics)); diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-4965.c b/trunk/drivers/net/wireless/iwlegacy/iwl-4965.c index bd4b000733f7..3a022bcf615c 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -1216,10 +1216,10 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c * receive commit_rxon request * abort any previous channel switch if still in process */ - if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && - (priv->switch_channel != ctx->staging.channel)) { + if (priv->switch_rxon.switch_in_progress && + (priv->switch_rxon.channel != ctx->staging.channel)) { IWL_DEBUG_11H(priv, "abort channel switch on %d\n", - le16_to_cpu(priv->switch_channel)); + le16_to_cpu(priv->switch_rxon.channel)); iwl_legacy_chswitch_done(priv, false); } @@ -1402,6 +1402,9 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, return rc; } + priv->switch_rxon.channel = cmd.channel; + priv->switch_rxon.switch_in_progress = true; + return iwl_legacy_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); } @@ -2069,6 +2072,7 @@ static struct iwl_lib_ops iwl4965_lib = { .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, .init_alive_start = iwl4965_init_alive_start, .load_ucode = iwl4965_load_bsm, + .dump_nic_event_log = iwl4965_dump_nic_event_log, .dump_nic_error_log = iwl4965_dump_nic_error_log, .dump_fh = iwl4965_dump_fh, .set_channel_switch = iwl4965_hw_channel_switch, @@ -2099,6 +2103,7 @@ static struct iwl_lib_ops iwl4965_lib = { .tx_stats_read = iwl4965_ucode_tx_stats_read, .general_stats_read = iwl4965_ucode_general_stats_read, }, + .check_plcp_health = iwl4965_good_plcp_health, }; static const struct iwl_legacy_ops iwl4965_legacy_ops = { @@ -2148,8 +2153,10 @@ static struct iwl_base_params iwl4965_base_params = { .use_bsm = true, .led_compensation = 61, .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, .wd_timeout = IWL_DEF_WD_TIMEOUT, .temperature_kelvin = true, + .max_event_log_size = 512, .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-commands.h b/trunk/drivers/net/wireless/iwlegacy/iwl-commands.h index ee21210bea9c..17a1d504348e 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-commands.h +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-commands.h @@ -2297,7 +2297,14 @@ struct iwl_spectrum_notification { #define IWL_POWER_VEC_SIZE 5 #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) +#define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0)) +#define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1)) +#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) +#define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) +#define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5)) +#define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6)) +#define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7)) struct iwl3945_powertable_cmd { __le16 flags; diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-core.c b/trunk/drivers/net/wireless/iwlegacy/iwl-core.c index 35cd2537e7fd..42df8321dae8 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-core.c @@ -859,8 +859,12 @@ void iwl_legacy_chswitch_done(struct iwl_priv *priv, bool is_success) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) + if (priv->switch_rxon.switch_in_progress) { ieee80211_chswitch_done(ctx->vif, is_success); + mutex_lock(&priv->mutex); + priv->switch_rxon.switch_in_progress = false; + mutex_unlock(&priv->mutex); + } } EXPORT_SYMBOL(iwl_legacy_chswitch_done); @@ -872,19 +876,19 @@ void iwl_legacy_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_legacy_rxon_cmd *rxon = (void *)&ctx->active; - if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) - return; - - if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { - rxon->channel = csa->channel; - ctx->staging.channel = csa->channel; - IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", + if (priv->switch_rxon.switch_in_progress) { + if (!le32_to_cpu(csa->status) && + (csa->channel == priv->switch_rxon.channel)) { + rxon->channel = csa->channel; + ctx->staging.channel = csa->channel; + IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", le16_to_cpu(csa->channel)); - iwl_legacy_chswitch_done(priv, true); - } else { - IWL_ERR(priv, "CSA notif (fail) : channel %d\n", - le16_to_cpu(csa->channel)); - iwl_legacy_chswitch_done(priv, false); + iwl_legacy_chswitch_done(priv, true); + } else { + IWL_ERR(priv, "CSA notif (fail) : channel %d\n", + le16_to_cpu(csa->channel)); + iwl_legacy_chswitch_done(priv, false); + } } } EXPORT_SYMBOL(iwl_legacy_rx_csa); @@ -931,6 +935,7 @@ void iwl_legacy_irq_handle_error(struct iwl_priv *priv) priv->cfg->ops->lib->dump_nic_error_log(priv); if (priv->cfg->ops->lib->dump_fh) priv->cfg->ops->lib->dump_fh(priv, NULL, false); + priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG if (iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) iwl_legacy_print_rx_config_cmd(priv, @@ -1706,14 +1711,41 @@ iwl_legacy_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) EXPORT_SYMBOL(iwl_legacy_update_stats); #endif -int iwl_legacy_force_reset(struct iwl_priv *priv, bool external) +static void _iwl_legacy_force_rf_reset(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!iwl_legacy_is_any_associated(priv)) { + IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); + return; + } + /* + * There is no easy and better way to force reset the radio, + * the only known method is switching channel which will force to + * reset and tune the radio. + * Use internal short scan (single channel) operation to should + * achieve this objective. + * Driver should reset the radio when number of consecutive missed + * beacon, or any other uCode error condition detected. + */ + IWL_DEBUG_INFO(priv, "perform radio reset.\n"); + iwl_legacy_internal_short_hw_scan(priv); +} + + +int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external) { struct iwl_force_reset *force_reset; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EINVAL; - force_reset = &priv->force_reset; + if (mode >= IWL_MAX_FORCE_RESET) { + IWL_DEBUG_INFO(priv, "invalid reset request.\n"); + return -EINVAL; + } + force_reset = &priv->force_reset[mode]; force_reset->reset_request_count++; if (!external) { if (force_reset->last_force_reset_jiffies && @@ -1726,34 +1758,37 @@ int iwl_legacy_force_reset(struct iwl_priv *priv, bool external) } force_reset->reset_success_count++; force_reset->last_force_reset_jiffies = jiffies; - - /* - * if the request is from external(ex: debugfs), - * then always perform the request in regardless the module - * parameter setting - * if the request is from internal (uCode error or driver - * detect failure), then fw_restart module parameter - * need to be check before performing firmware reload - */ - - if (!external && !priv->cfg->mod_params->restart_fw) { - IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " - "module parameter setting\n"); - return 0; + IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode); + switch (mode) { + case IWL_RF_RESET: + _iwl_legacy_force_rf_reset(priv); + break; + case IWL_FW_RESET: + /* + * if the request is from external(ex: debugfs), + * then always perform the request in regardless the module + * parameter setting + * if the request is from internal (uCode error or driver + * detect failure), then fw_restart module parameter + * need to be check before performing firmware reload + */ + if (!external && !priv->cfg->mod_params->restart_fw) { + IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " + "module parameter setting\n"); + break; + } + IWL_ERR(priv, "On demand firmware reload\n"); + /* Set the FW error flag -- cleared on iwl_down */ + set_bit(STATUS_FW_ERROR, &priv->status); + wake_up_interruptible(&priv->wait_command_queue); + /* + * Keep the restart process from trying to send host + * commands by clearing the INIT status bit + */ + clear_bit(STATUS_READY, &priv->status); + queue_work(priv->workqueue, &priv->restart); + break; } - - IWL_ERR(priv, "On demand firmware reload\n"); - - /* Set the FW error flag -- cleared on iwl_down */ - set_bit(STATUS_FW_ERROR, &priv->status); - wake_up_interruptible(&priv->wait_command_queue); - /* - * Keep the restart process from trying to send host - * commands by clearing the INIT status bit - */ - clear_bit(STATUS_READY, &priv->status); - queue_work(priv->workqueue, &priv->restart); - return 0; } @@ -1848,7 +1883,7 @@ static int iwl_legacy_check_stuck_queue(struct iwl_priv *priv, int cnt) if (time_after(jiffies, timeout)) { IWL_ERR(priv, "Queue %d stuck for %u ms.\n", q->id, priv->cfg->base_params->wd_timeout); - ret = iwl_legacy_force_reset(priv, false); + ret = iwl_legacy_force_reset(priv, IWL_FW_RESET, false); return (ret == -EAGAIN) ? 0 : 1; } diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-core.h b/trunk/drivers/net/wireless/iwlegacy/iwl-core.h index a2de7e991706..bc66c604106c 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-core.h @@ -143,7 +143,8 @@ struct iwl_lib_ops { int (*is_valid_rtc_data_addr)(u32 addr); /* 1st ucode load */ int (*load_ucode)(struct iwl_priv *priv); - + int (*dump_nic_event_log)(struct iwl_priv *priv, + bool full_log, char **buf, bool display); void (*dump_nic_error_log)(struct iwl_priv *priv); int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); int (*set_channel_switch)(struct iwl_priv *priv, @@ -160,6 +161,9 @@ struct iwl_lib_ops { /* temperature */ struct iwl_temp_ops temp_ops; + /* check for plcp health */ + bool (*check_plcp_health)(struct iwl_priv *priv, + struct iwl_rx_packet *pkt); struct iwl_debugfs_ops debugfs_ops; @@ -203,8 +207,11 @@ struct iwl_mod_params { * to the deviation to achieve the desired led frequency. * The detail algorithm is described in iwl-led.c * @chain_noise_num_beacons: number of beacons used to compute chain noise + * @plcp_delta_threshold: plcp error rate threshold used to trigger + * radio tuning when there is a high receiving plcp error rate * @wd_timeout: TX queues watchdog timeout * @temperature_kelvin: temperature report by uCode in kelvin + * @max_event_log_size: size of event log buffer size for ucode event logging * @ucode_tracing: support ucode continuous tracing * @sensitivity_calib_by_driver: driver has the capability to perform * sensitivity calibration operation @@ -222,8 +229,10 @@ struct iwl_base_params { u16 led_compensation; int chain_noise_num_beacons; + u8 plcp_delta_threshold; unsigned int wd_timeout; bool temperature_kelvin; + u32 max_event_log_size; const bool ucode_tracing; const bool sensitivity_calib_by_driver; const bool chain_noise_calib_by_driver; @@ -432,7 +441,7 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv); -int iwl_legacy_force_reset(struct iwl_priv *priv, bool external); +int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external); u16 iwl_legacy_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, const u8 *ta, const u8 *ie, int ie_len, int left); @@ -512,6 +521,8 @@ extern const struct dev_pm_ops iwl_legacy_pm_ops; * Error Handling Debugging ******************************************************/ void iwl4965_dump_nic_error_log(struct iwl_priv *priv); +int iwl4965_dump_nic_event_log(struct iwl_priv *priv, + bool full_log, char **buf, bool display); #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG void iwl_legacy_print_rx_config_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); @@ -549,7 +560,7 @@ void iwl_legacy_free_geos(struct iwl_priv *priv); #define STATUS_SCAN_HW 15 #define STATUS_POWER_PMI 16 #define STATUS_FW_ERROR 17 -#define STATUS_CHANNEL_SWITCH_PENDING 18 + static inline int iwl_legacy_is_ready(struct iwl_priv *priv) { diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlegacy/iwl-debugfs.c index 996996a71657..2d32438b4cb8 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-debugfs.c @@ -391,6 +391,48 @@ static ssize_t iwl_legacy_dbgfs_nvm_read(struct file *file, return ret; } +static ssize_t iwl_legacy_dbgfs_log_event_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char *buf; + int pos = 0; + ssize_t ret = -ENOMEM; + + ret = pos = priv->cfg->ops->lib->dump_nic_event_log( + priv, true, &buf, true); + if (buf) { + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + } + return ret; +} + +static ssize_t iwl_legacy_dbgfs_log_event_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + u32 event_log_flag; + char buf[8]; + int buf_size; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &event_log_flag) != 1) + return -EFAULT; + if (event_log_flag == 1) + priv->cfg->ops->lib->dump_nic_event_log(priv, true, + NULL, false); + + return count; +} + + + static ssize_t iwl_legacy_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -664,6 +706,7 @@ static ssize_t iwl_legacy_dbgfs_disable_ht40_read(struct file *file, } DEBUGFS_READ_WRITE_FILE_OPS(sram); +DEBUGFS_READ_WRITE_FILE_OPS(log_event); DEBUGFS_READ_FILE_OPS(nvm); DEBUGFS_READ_FILE_OPS(stations); DEBUGFS_READ_FILE_OPS(channels); @@ -1055,6 +1098,56 @@ static ssize_t iwl_legacy_dbgfs_clear_ucode_statistics_write(struct file *file, return count; } +static ssize_t iwl_legacy_dbgfs_ucode_tracing_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int pos = 0; + char buf[128]; + const size_t bufsz = sizeof(buf); + + pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", + priv->event_log.ucode_trace ? "On" : "Off"); + pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n", + priv->event_log.non_wraps_count); + pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n", + priv->event_log.wraps_once_count); + pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", + priv->event_log.wraps_more_count); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_ucode_tracing_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int trace; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &trace) != 1) + return -EFAULT; + + if (trace) { + priv->event_log.ucode_trace = true; + /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ + mod_timer(&priv->ucode_trace, + jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); + } else { + priv->event_log.ucode_trace = false; + del_timer_sync(&priv->ucode_trace); + } + + return count; +} + static ssize_t iwl_legacy_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1143,31 +1236,72 @@ static ssize_t iwl_legacy_dbgfs_missed_beacon_write(struct file *file, return count; } -static ssize_t iwl_legacy_dbgfs_force_reset_read(struct file *file, +static ssize_t iwl_legacy_dbgfs_plcp_delta_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; int pos = 0; - char buf[300]; + char buf[12]; const size_t bufsz = sizeof(buf); - struct iwl_force_reset *force_reset; - force_reset = &priv->force_reset; + pos += scnprintf(buf + pos, bufsz - pos, "%u\n", + priv->cfg->base_params->plcp_delta_threshold); - pos += scnprintf(buf + pos, bufsz - pos, - "\tnumber of reset request: %d\n", - force_reset->reset_request_count); - pos += scnprintf(buf + pos, bufsz - pos, - "\tnumber of reset request success: %d\n", - force_reset->reset_success_count); - pos += scnprintf(buf + pos, bufsz - pos, - "\tnumber of reset request reject: %d\n", - force_reset->reset_reject_count); - pos += scnprintf(buf + pos, bufsz - pos, - "\treset duration: %lu\n", - force_reset->reset_duration); + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_plcp_delta_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int plcp; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &plcp) != 1) + return -EINVAL; + if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || + (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) + priv->cfg->base_params->plcp_delta_threshold = + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; + else + priv->cfg->base_params->plcp_delta_threshold = plcp; + return count; +} + +static ssize_t iwl_legacy_dbgfs_force_reset_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int i, pos = 0; + char buf[300]; + const size_t bufsz = sizeof(buf); + struct iwl_force_reset *force_reset; + + for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { + force_reset = &priv->force_reset[i]; + pos += scnprintf(buf + pos, bufsz - pos, + "Force reset method %d\n", i); + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request: %d\n", + force_reset->reset_request_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request success: %d\n", + force_reset->reset_success_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request reject: %d\n", + force_reset->reset_reject_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\treset duration: %lu\n", + force_reset->reset_duration); + } return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -1175,11 +1309,25 @@ static ssize_t iwl_legacy_dbgfs_force_reset_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - int ret; struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int reset, ret; - ret = iwl_legacy_force_reset(priv, true); - + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &reset) != 1) + return -EINVAL; + switch (reset) { + case IWL_RF_RESET: + case IWL_FW_RESET: + ret = iwl_legacy_force_reset(priv, reset, true); + break; + default: + return -EINVAL; + } return ret ? ret : count; } @@ -1219,8 +1367,10 @@ DEBUGFS_READ_FILE_OPS(chain_noise); DEBUGFS_READ_FILE_OPS(power_save_status); DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); +DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); DEBUGFS_READ_FILE_OPS(fh_reg); DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); +DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); DEBUGFS_READ_WRITE_FILE_OPS(force_reset); DEBUGFS_READ_FILE_OPS(rxon_flags); DEBUGFS_READ_FILE_OPS(rxon_filter_flags); @@ -1253,6 +1403,7 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); @@ -1269,6 +1420,7 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); @@ -1278,6 +1430,8 @@ int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); if (priv->cfg->base_params->chain_noise_calib_by_driver) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); + if (priv->cfg->base_params->ucode_tracing) + DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-dev.h b/trunk/drivers/net/wireless/iwlegacy/iwl-dev.h index 62e8cc07f046..be0106c6a2da 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -854,6 +854,43 @@ struct traffic_stats { #endif }; +/* + * iwl_switch_rxon: "channel switch" structure + * + * @ switch_in_progress: channel switch in progress + * @ channel: new channel + */ +struct iwl_switch_rxon { + bool switch_in_progress; + __le16 channel; +}; + +/* + * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds + * to perform continuous uCode event logging operation if enabled + */ +#define UCODE_TRACE_PERIOD (100) + +/* + * iwl_event_log: current uCode event log position + * + * @ucode_trace: enable/disable ucode continuous trace timer + * @num_wraps: how many times the event buffer wraps + * @next_entry: the entry just before the next one that uCode would fill + * @non_wraps_count: counter for no wrap detected when dump ucode events + * @wraps_once_count: counter for wrap once detected when dump ucode events + * @wraps_more_count: counter for wrap more than once detected + * when dump ucode events + */ +struct iwl_event_log { + bool ucode_trace; + u32 num_wraps; + u32 next_entry; + int non_wraps_count; + int wraps_once_count; + int wraps_more_count; +}; + /* * host interrupt timeout value * used with setting interrupt coalescing timer @@ -869,6 +906,18 @@ struct traffic_stats { #define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) #define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) +/* + * This is the threshold value of plcp error rate per 100mSecs. It is + * used to set and check for the validity of plcp_delta. + */ +#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (1) +#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) +#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) +#define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200) +#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) +#define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) + +#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) /* TX queue watchdog timeouts in mSecs */ @@ -876,6 +925,12 @@ struct traffic_stats { #define IWL_LONG_WD_TIMEOUT (10000) #define IWL_MAX_WD_TIMEOUT (120000) +enum iwl_reset { + IWL_RF_RESET = 0, + IWL_FW_RESET, + IWL_MAX_FORCE_RESET, +}; + struct iwl_force_reset { int reset_request_count; int reset_success_count; @@ -988,8 +1043,11 @@ struct iwl_priv { /* track IBSS manager (last beacon) status */ u32 ibss_manager; + /* storing the jiffies when the plcp error rate is received */ + unsigned long plcp_jiffies; + /* force reset */ - struct iwl_force_reset force_reset; + struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; /* we allocate array of iwl_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ @@ -1010,6 +1068,7 @@ struct iwl_priv { enum ieee80211_band scan_band; struct cfg80211_scan_request *scan_request; struct ieee80211_vif *scan_vif; + bool is_internal_short_scan; u8 scan_tx_ant[IEEE80211_NUM_BANDS]; u8 mgmt_tx_ant; @@ -1056,7 +1115,7 @@ struct iwl_priv { struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; - __le16 switch_channel; + struct iwl_switch_rxon switch_rxon; /* 1st responses from initialize and runtime uCode images. * _4965's initialize alive response contains some calibration data. */ @@ -1164,6 +1223,12 @@ struct iwl_priv { #endif #if defined(CONFIG_IWL4965) || defined(CONFIG_IWL4965_MODULE) struct { + /* + * reporting the number of tids has AGG on. 0 means + * no AGGREGATION + */ + u8 agg_tids_count; + struct iwl_rx_phy_res last_phy_res; bool last_phy_res_valid; @@ -1202,6 +1267,7 @@ struct iwl_priv { struct iwl_rxon_context *beacon_ctx; struct sk_buff *beacon_skb; + struct work_struct start_internal_scan; struct work_struct tx_flush; struct tasklet_struct irq_tasklet; @@ -1238,9 +1304,12 @@ struct iwl_priv { u32 disable_tx_power_cal; struct work_struct run_time_calib_work; struct timer_list statistics_periodic; + struct timer_list ucode_trace; struct timer_list watchdog; bool hw_ready; + struct iwl_event_log event_log; + struct led_classdev led; unsigned long blink_on, blink_off; bool led_registered; diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.c b/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.c index acec99197ce0..080b852b33bd 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.c @@ -38,5 +38,8 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ioread32); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite32); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_rx); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_tx); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_event); EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_error); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_cont_event); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_wrap_event); #endif diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.h b/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.h index a443725ba6be..9612aa0f6ec4 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.h +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-devtrace.h @@ -96,6 +96,47 @@ TRACE_EVENT(iwlwifi_legacy_dev_iowrite32, #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_legacy_ucode +TRACE_EVENT(iwlwifi_legacy_dev_ucode_cont_event, + TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), + TP_ARGS(priv, time, data, ev), + TP_STRUCT__entry( + PRIV_ENTRY + + __field(u32, time) + __field(u32, data) + __field(u32, ev) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->time = time; + __entry->data = data; + __entry->ev = ev; + ), + TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", + __entry->priv, __entry->time, __entry->data, __entry->ev) +); + +TRACE_EVENT(iwlwifi_legacy_dev_ucode_wrap_event, + TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry), + TP_ARGS(priv, wraps, n_entry, p_entry), + TP_STRUCT__entry( + PRIV_ENTRY + + __field(u32, wraps) + __field(u32, n_entry) + __field(u32, p_entry) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->wraps = wraps; + __entry->n_entry = n_entry; + __entry->p_entry = p_entry; + ), + TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X", + __entry->priv, __entry->wraps, __entry->n_entry, + __entry->p_entry) +); + #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi @@ -201,6 +242,25 @@ TRACE_EVENT(iwlwifi_legacy_dev_ucode_error, __entry->blink2, __entry->ilink1, __entry->ilink2) ); +TRACE_EVENT(iwlwifi_legacy_dev_ucode_event, + TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), + TP_ARGS(priv, time, data, ev), + TP_STRUCT__entry( + PRIV_ENTRY + + __field(u32, time) + __field(u32, data) + __field(u32, ev) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->time = time; + __entry->data = data; + __entry->ev = ev; + ), + TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", + __entry->priv, __entry->time, __entry->data, __entry->ev) +); #endif /* __IWLWIFI_DEVICE_TRACE */ #undef TRACE_INCLUDE_PATH diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-helpers.h b/trunk/drivers/net/wireless/iwlegacy/iwl-helpers.h index 5cf23eaecbbb..a6effdae63f9 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-helpers.h +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-helpers.h @@ -132,16 +132,7 @@ static inline void iwl_legacy_stop_queue(struct iwl_priv *priv, ieee80211_stop_queue(priv->hw, ac); } -#ifdef ieee80211_stop_queue -#undef ieee80211_stop_queue -#endif - #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue - -#ifdef ieee80211_wake_queue -#undef ieee80211_wake_queue -#endif - #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv) diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-rx.c b/trunk/drivers/net/wireless/iwlegacy/iwl-rx.c index 9b5d0abe8be9..654cf233a384 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-rx.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-rx.c @@ -227,6 +227,27 @@ void iwl_legacy_rx_spectrum_measure_notif(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_legacy_rx_spectrum_measure_notif); +void iwl_legacy_recover_from_statistics(struct iwl_priv *priv, + struct iwl_rx_packet *pkt) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + if (iwl_legacy_is_any_associated(priv)) { + if (priv->cfg->ops->lib->check_plcp_health) { + if (!priv->cfg->ops->lib->check_plcp_health( + priv, pkt)) { + /* + * high plcp error detected + * reset Radio + */ + iwl_legacy_force_reset(priv, + IWL_RF_RESET, false); + } + } + } +} +EXPORT_SYMBOL(iwl_legacy_recover_from_statistics); + /* * returns non-zero if packet should be dropped */ diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-scan.c b/trunk/drivers/net/wireless/iwlegacy/iwl-scan.c index a6b5222fc59e..353234a02c6d 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-scan.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-scan.c @@ -101,6 +101,7 @@ static void iwl_legacy_complete_scan(struct iwl_priv *priv, bool aborted) ieee80211_scan_completed(priv->hw, aborted); } + priv->is_internal_short_scan = false; priv->scan_vif = NULL; priv->scan_request = NULL; } @@ -328,8 +329,10 @@ void iwl_legacy_init_scan_params(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_legacy_init_scan_params); -static int iwl_legacy_scan_initiate(struct iwl_priv *priv, - struct ieee80211_vif *vif) +static int __must_check iwl_legacy_scan_initiate(struct iwl_priv *priv, + struct ieee80211_vif *vif, + bool internal, + enum ieee80211_band band) { int ret; @@ -356,14 +359,18 @@ static int iwl_legacy_scan_initiate(struct iwl_priv *priv, return -EBUSY; } - IWL_DEBUG_SCAN(priv, "Starting scan...\n"); + IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", + internal ? "internal short " : ""); set_bit(STATUS_SCANNING, &priv->status); + priv->is_internal_short_scan = internal; priv->scan_start = jiffies; + priv->scan_band = band; ret = priv->cfg->ops->utils->request_scan(priv, vif); if (ret) { clear_bit(STATUS_SCANNING, &priv->status); + priv->is_internal_short_scan = false; return ret; } @@ -387,7 +394,8 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCANNING, &priv->status)) { + if (test_bit(STATUS_SCANNING, &priv->status) && + !priv->is_internal_short_scan) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); ret = -EAGAIN; goto out_unlock; @@ -396,9 +404,17 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, /* mac80211 will only ask for one band at a time */ priv->scan_request = req; priv->scan_vif = vif; - priv->scan_band = req->channels[0]->band; - ret = iwl_legacy_scan_initiate(priv, vif); + /* + * If an internal scan is in progress, just set + * up the scan_request as per above. + */ + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); + ret = 0; + } else + ret = iwl_legacy_scan_initiate(priv, vif, false, + req->channels[0]->band); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -409,6 +425,40 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_legacy_mac_hw_scan); +/* + * internal short scan, this function should only been called while associated. + * It will reset and tune the radio to prevent possible RF related problem + */ +void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv) +{ + queue_work(priv->workqueue, &priv->start_internal_scan); +} + +static void iwl_legacy_bg_start_internal_scan(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, start_internal_scan); + + IWL_DEBUG_SCAN(priv, "Start internal scan\n"); + + mutex_lock(&priv->mutex); + + if (priv->is_internal_short_scan == true) { + IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); + goto unlock; + } + + if (test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); + goto unlock; + } + + if (iwl_legacy_scan_initiate(priv, NULL, true, priv->band)) + IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); + unlock: + mutex_unlock(&priv->mutex); +} + static void iwl_legacy_bg_scan_check(struct work_struct *data) { struct iwl_priv *priv = @@ -492,7 +542,8 @@ static void iwl_legacy_bg_scan_completed(struct work_struct *work) container_of(work, struct iwl_priv, scan_completed); bool aborted; - IWL_DEBUG_SCAN(priv, "Completed scan.\n"); + IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", + priv->is_internal_short_scan ? "internal short " : ""); cancel_delayed_work(&priv->scan_check); @@ -507,6 +558,27 @@ static void iwl_legacy_bg_scan_completed(struct work_struct *work) goto out_settings; } + if (priv->is_internal_short_scan && !aborted) { + int err; + + /* Check if mac80211 requested scan during our internal scan */ + if (priv->scan_request == NULL) + goto out_complete; + + /* If so request a new scan */ + err = iwl_legacy_scan_initiate(priv, priv->scan_vif, false, + priv->scan_request->channels[0]->band); + if (err) { + IWL_DEBUG_SCAN(priv, + "failed to initiate pending scan: %d\n", err); + aborted = true; + goto out_complete; + } + + goto out; + } + +out_complete: iwl_legacy_complete_scan(priv, aborted); out_settings: @@ -518,7 +590,8 @@ static void iwl_legacy_bg_scan_completed(struct work_struct *work) * We do not commit power settings while scan is pending, * do it now if the settings changed. */ - iwl_legacy_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false); + iwl_legacy_power_set_mode(priv, &priv->power_data.sleep_cmd_next, + false); iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); priv->cfg->ops->utils->post_scan(priv); @@ -531,12 +604,15 @@ void iwl_legacy_setup_scan_deferred_work(struct iwl_priv *priv) { INIT_WORK(&priv->scan_completed, iwl_legacy_bg_scan_completed); INIT_WORK(&priv->abort_scan, iwl_legacy_bg_abort_scan); + INIT_WORK(&priv->start_internal_scan, + iwl_legacy_bg_start_internal_scan); INIT_DELAYED_WORK(&priv->scan_check, iwl_legacy_bg_scan_check); } EXPORT_SYMBOL(iwl_legacy_setup_scan_deferred_work); void iwl_legacy_cancel_scan_deferred_work(struct iwl_priv *priv) { + cancel_work_sync(&priv->start_internal_scan); cancel_work_sync(&priv->abort_scan); cancel_work_sync(&priv->scan_completed); diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c b/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c index 795826a014ed..0ee6be6a9c5d 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -1409,6 +1409,212 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv) } } +#define EVENT_START_OFFSET (6 * sizeof(u32)) + +/** + * iwl3945_print_event_log - Dump error event log to syslog + * + */ +static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, + u32 num_events, u32 mode, + int pos, char **buf, size_t bufsz) +{ + u32 i; + u32 base; /* SRAM byte address of event log header */ + u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ + u32 ptr; /* SRAM byte address of log data */ + u32 ev, time, data; /* event log data */ + unsigned long reg_flags; + + if (num_events == 0) + return pos; + + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + + if (mode == 0) + event_size = 2 * sizeof(u32); + else + event_size = 3 * sizeof(u32); + + ptr = base + EVENT_START_OFFSET + (start_idx * event_size); + + /* Make sure device is powered up for SRAM reads */ + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + + /* Set starting address; reads will auto-increment */ + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + rmb(); + + /* "time" is actually "data" for mode 0 (no timestamp). + * place event id # at far right for easier visual parsing. */ + for (i = 0; i < num_events; i++) { + ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (mode == 0) { + /* data, ev */ + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "0x%08x:%04u\n", + time, ev); + } else { + IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); + trace_iwlwifi_legacy_dev_ucode_event(priv, 0, + time, ev); + } + } else { + data = _iwl_legacy_read_direct32(priv, + HBUS_TARG_MEM_RDAT); + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "%010u:0x%08x:%04u\n", + time, data, ev); + } else { + IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", + time, data, ev); + trace_iwlwifi_legacy_dev_ucode_event(priv, time, + data, ev); + } + } + } + + /* Allow device to power down */ + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return pos; +} + +/** + * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog + */ +static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, + u32 num_wraps, u32 next_entry, + u32 size, u32 mode, + int pos, char **buf, size_t bufsz) +{ + /* + * display the newest DEFAULT_LOG_ENTRIES entries + * i.e the entries just before the next ont that uCode would fill. + */ + if (num_wraps) { + if (next_entry < size) { + pos = iwl3945_print_event_log(priv, + capacity - (size - next_entry), + size - next_entry, mode, + pos, buf, bufsz); + pos = iwl3945_print_event_log(priv, 0, + next_entry, mode, + pos, buf, bufsz); + } else + pos = iwl3945_print_event_log(priv, next_entry - size, + size, mode, + pos, buf, bufsz); + } else { + if (next_entry < size) + pos = iwl3945_print_event_log(priv, 0, + next_entry, mode, + pos, buf, bufsz); + else + pos = iwl3945_print_event_log(priv, next_entry - size, + size, mode, + pos, buf, bufsz); + } + return pos; +} + +#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) + +int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, + char **buf, bool display) +{ + u32 base; /* SRAM byte address of event log header */ + u32 capacity; /* event log capacity in # entries */ + u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ + u32 num_wraps; /* # times uCode wrapped to top of log */ + u32 next_entry; /* index of next entry to be written by uCode */ + u32 size; /* # entries that we'll print */ + int pos = 0; + size_t bufsz = 0; + + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + if (!iwl3945_hw_valid_rtc_data_addr(base)) { + IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); + return -EINVAL; + } + + /* event log header */ + capacity = iwl_legacy_read_targ_mem(priv, base); + mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); + num_wraps = iwl_legacy_read_targ_mem(priv, base + (2 * sizeof(u32))); + next_entry = iwl_legacy_read_targ_mem(priv, base + (3 * sizeof(u32))); + + if (capacity > priv->cfg->base_params->max_event_log_size) { + IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", + capacity, priv->cfg->base_params->max_event_log_size); + capacity = priv->cfg->base_params->max_event_log_size; + } + + if (next_entry > priv->cfg->base_params->max_event_log_size) { + IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", + next_entry, priv->cfg->base_params->max_event_log_size); + next_entry = priv->cfg->base_params->max_event_log_size; + } + + size = num_wraps ? capacity : next_entry; + + /* bail out if nothing in log */ + if (size == 0) { + IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); + return pos; + } + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (!(iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) + size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; +#else + size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; +#endif + + IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", + size); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (display) { + if (full_log) + bufsz = capacity * 48; + else + bufsz = size * 48; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + } + if ((iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { + /* if uCode has wrapped back to top of log, + * start at the oldest entry, + * i.e the next one that uCode would fill. + */ + if (num_wraps) + pos = iwl3945_print_event_log(priv, next_entry, + capacity - next_entry, mode, + pos, buf, bufsz); + + /* (then/else) start at top of log */ + pos = iwl3945_print_event_log(priv, 0, next_entry, mode, + pos, buf, bufsz); + } else + pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#else + pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#endif + return pos; +} + static void iwl3945_irq_tasklet(struct iwl_priv *priv) { u32 inta, handled = 0; @@ -1556,6 +1762,49 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) #endif } +static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + struct iwl3945_scan_channel *scan_ch) +{ + const struct ieee80211_supported_band *sband; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added = 0; + u8 channel = 0; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) { + IWL_ERR(priv, "invalid band\n"); + return added; + } + + active_dwell = iwl_legacy_get_active_dwell_time(priv, band, 0); + passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + + channel = iwl_legacy_get_single_channel_number(priv, band); + + if (channel) { + scan_ch->channel = channel; + scan_ch->type = 0; /* passive */ + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* Set txpower levels to defaults */ + scan_ch->tpc.dsp_atten = 110; + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); + added++; + } else + IWL_ERR(priv, "no valid channel found\n"); + return added; +} + static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, enum ieee80211_band band, u8 is_active, u8 n_probes, @@ -2567,7 +2816,6 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) enum ieee80211_band band; bool is_active = false; int ret; - u16 len; lockdep_assert_held(&priv->mutex); @@ -2586,14 +2834,17 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_time = IWL_ACTIVE_QUIET_TIME; if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) { - u16 interval; + u16 interval = 0; u32 extra; u32 suspend_time = 100; u32 scan_suspend_time = 100; IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - interval = vif->bss_conf.beacon_int; + if (priv->is_internal_short_scan) + interval = 0; + else + interval = vif->bss_conf.beacon_int; scan->suspend_time = 0; scan->max_out_time = cpu_to_le32(200 * 1024); @@ -2615,7 +2866,9 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan_suspend_time, interval); } - if (priv->scan_request->n_ssids) { + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); + } else if (priv->scan_request->n_ssids) { int i, p = 0; IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); for (i = 0; i < priv->scan_request->n_ssids; i++) { @@ -2666,17 +2919,36 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : IWL_GOOD_CRC_TH_DISABLED; - len = iwl_legacy_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, - vif->addr, priv->scan_request->ie, - priv->scan_request->ie_len, - IWL_MAX_SCAN_SIZE - sizeof(*scan)); - scan->tx_cmd.len = cpu_to_le16(len); - + if (!priv->is_internal_short_scan) { + scan->tx_cmd.len = cpu_to_le16( + iwl_legacy_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + vif->addr, + priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan))); + } else { + /* use bcast addr, will not be transmitted but must be valid */ + scan->tx_cmd.len = cpu_to_le16( + iwl_legacy_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + iwlegacy_bcast_addr, NULL, 0, + IWL_MAX_SCAN_SIZE - sizeof(*scan))); + } /* select Rx antennas */ scan->flags |= iwl3945_get_antenna_flags(priv); - scan->channel_count = iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, - (void *)&scan->data[len], vif); + if (priv->is_internal_short_scan) { + scan->channel_count = + iwl3945_get_single_channel_for_scan(priv, vif, band, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } else { + scan->channel_count = + iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, + (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); + } + if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); return -EIO; @@ -3552,7 +3824,10 @@ static int iwl3945_init_drv(struct iwl_priv *priv) priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; /* initialize force reset */ - priv->force_reset.reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD; + priv->force_reset[IWL_RF_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_RF_RESET; + priv->force_reset[IWL_FW_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_FW_RELOAD; if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c b/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c index 46242d2aa5ad..af2ae22fcfd3 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -488,6 +488,134 @@ static void iwl4965_bg_statistics_periodic(unsigned long data) iwl_legacy_send_statistics_request(priv, CMD_ASYNC, false); } + +static void iwl4965_print_cont_event_trace(struct iwl_priv *priv, u32 base, + u32 start_idx, u32 num_events, + u32 mode) +{ + u32 i; + u32 ptr; /* SRAM byte address of log data */ + u32 ev, time, data; /* event log data */ + unsigned long reg_flags; + + if (mode == 0) + ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32)); + else + ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); + + /* Make sure device is powered up for SRAM reads */ + spin_lock_irqsave(&priv->reg_lock, reg_flags); + if (iwl_grab_nic_access(priv)) { + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return; + } + + /* Set starting address; reads will auto-increment */ + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + rmb(); + + /* + * "time" is actually "data" for mode 0 (no timestamp). + * place event id # at far right for easier visual parsing. + */ + for (i = 0; i < num_events; i++) { + ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (mode == 0) { + trace_iwlwifi_legacy_dev_ucode_cont_event(priv, + 0, time, ev); + } else { + data = _iwl_legacy_read_direct32(priv, + HBUS_TARG_MEM_RDAT); + trace_iwlwifi_legacy_dev_ucode_cont_event(priv, + time, data, ev); + } + } + /* Allow device to power down */ + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} + +static void iwl4965_continuous_event_trace(struct iwl_priv *priv) +{ + u32 capacity; /* event log capacity in # entries */ + u32 base; /* SRAM byte address of event log header */ + u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ + u32 num_wraps; /* # times uCode wrapped to top of log */ + u32 next_entry; /* index of next entry to be written by uCode */ + + if (priv->ucode_type == UCODE_INIT) + base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); + else + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { + capacity = iwl_legacy_read_targ_mem(priv, base); + num_wraps = iwl_legacy_read_targ_mem(priv, + base + (2 * sizeof(u32))); + mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); + next_entry = iwl_legacy_read_targ_mem(priv, + base + (3 * sizeof(u32))); + } else + return; + + if (num_wraps == priv->event_log.num_wraps) { + iwl4965_print_cont_event_trace(priv, + base, priv->event_log.next_entry, + next_entry - priv->event_log.next_entry, + mode); + priv->event_log.non_wraps_count++; + } else { + if ((num_wraps - priv->event_log.num_wraps) > 1) + priv->event_log.wraps_more_count++; + else + priv->event_log.wraps_once_count++; + trace_iwlwifi_legacy_dev_ucode_wrap_event(priv, + num_wraps - priv->event_log.num_wraps, + next_entry, priv->event_log.next_entry); + if (next_entry < priv->event_log.next_entry) { + iwl4965_print_cont_event_trace(priv, base, + priv->event_log.next_entry, + capacity - priv->event_log.next_entry, + mode); + + iwl4965_print_cont_event_trace(priv, base, 0, + next_entry, mode); + } else { + iwl4965_print_cont_event_trace(priv, base, + next_entry, capacity - next_entry, + mode); + + iwl4965_print_cont_event_trace(priv, base, 0, + next_entry, mode); + } + } + priv->event_log.num_wraps = num_wraps; + priv->event_log.next_entry = next_entry; +} + +/** + * iwl4965_bg_ucode_trace - Timer callback to log ucode event + * + * The timer is continually set to execute every + * UCODE_TRACE_PERIOD milliseconds after the last timer expired + * this function is to perform continuous uCode event logging operation + * if enabled + */ +static void iwl4965_bg_ucode_trace(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (priv->event_log.ucode_trace) { + iwl4965_continuous_event_trace(priv); + /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */ + mod_timer(&priv->ucode_trace, + jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); + } +} + static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -1583,6 +1711,209 @@ void iwl4965_dump_nic_error_log(struct iwl_priv *priv) pc, blink1, blink2, ilink1, ilink2, hcmd); } +#define EVENT_START_OFFSET (4 * sizeof(u32)) + +/** + * iwl4965_print_event_log - Dump error event log to syslog + * + */ +static int iwl4965_print_event_log(struct iwl_priv *priv, u32 start_idx, + u32 num_events, u32 mode, + int pos, char **buf, size_t bufsz) +{ + u32 i; + u32 base; /* SRAM byte address of event log header */ + u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ + u32 ptr; /* SRAM byte address of log data */ + u32 ev, time, data; /* event log data */ + unsigned long reg_flags; + + if (num_events == 0) + return pos; + + if (priv->ucode_type == UCODE_INIT) { + base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); + } else { + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + } + + if (mode == 0) + event_size = 2 * sizeof(u32); + else + event_size = 3 * sizeof(u32); + + ptr = base + EVENT_START_OFFSET + (start_idx * event_size); + + /* Make sure device is powered up for SRAM reads */ + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + + /* Set starting address; reads will auto-increment */ + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + rmb(); + + /* "time" is actually "data" for mode 0 (no timestamp). + * place event id # at far right for easier visual parsing. */ + for (i = 0; i < num_events; i++) { + ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (mode == 0) { + /* data, ev */ + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "EVT_LOG:0x%08x:%04u\n", + time, ev); + } else { + trace_iwlwifi_legacy_dev_ucode_event(priv, 0, + time, ev); + IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", + time, ev); + } + } else { + data = _iwl_legacy_read_direct32(priv, + HBUS_TARG_MEM_RDAT); + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "EVT_LOGT:%010u:0x%08x:%04u\n", + time, data, ev); + } else { + IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", + time, data, ev); + trace_iwlwifi_legacy_dev_ucode_event(priv, time, + data, ev); + } + } + } + + /* Allow device to power down */ + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return pos; +} + +/** + * iwl4965_print_last_event_logs - Dump the newest # of event log to syslog + */ +static int iwl4965_print_last_event_logs(struct iwl_priv *priv, u32 capacity, + u32 num_wraps, u32 next_entry, + u32 size, u32 mode, + int pos, char **buf, size_t bufsz) +{ + /* + * display the newest DEFAULT_LOG_ENTRIES entries + * i.e the entries just before the next ont that uCode would fill. + */ + if (num_wraps) { + if (next_entry < size) { + pos = iwl4965_print_event_log(priv, + capacity - (size - next_entry), + size - next_entry, mode, + pos, buf, bufsz); + pos = iwl4965_print_event_log(priv, 0, + next_entry, mode, + pos, buf, bufsz); + } else + pos = iwl4965_print_event_log(priv, next_entry - size, + size, mode, pos, buf, bufsz); + } else { + if (next_entry < size) { + pos = iwl4965_print_event_log(priv, 0, next_entry, + mode, pos, buf, bufsz); + } else { + pos = iwl4965_print_event_log(priv, next_entry - size, + size, mode, pos, buf, bufsz); + } + } + return pos; +} + +#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) + +int iwl4965_dump_nic_event_log(struct iwl_priv *priv, bool full_log, + char **buf, bool display) +{ + u32 base; /* SRAM byte address of event log header */ + u32 capacity; /* event log capacity in # entries */ + u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ + u32 num_wraps; /* # times uCode wrapped to top of log */ + u32 next_entry; /* index of next entry to be written by uCode */ + u32 size; /* # entries that we'll print */ + int pos = 0; + size_t bufsz = 0; + + if (priv->ucode_type == UCODE_INIT) { + base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); + } else { + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + } + + if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { + IWL_ERR(priv, + "Invalid event log pointer 0x%08X for %s uCode\n", + base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); + return -EINVAL; + } + + /* event log header */ + capacity = iwl_legacy_read_targ_mem(priv, base); + mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); + num_wraps = iwl_legacy_read_targ_mem(priv, base + (2 * sizeof(u32))); + next_entry = iwl_legacy_read_targ_mem(priv, base + (3 * sizeof(u32))); + + size = num_wraps ? capacity : next_entry; + + /* bail out if nothing in log */ + if (size == 0) { + IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); + return pos; + } + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (!(iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) + size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; +#else + size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; +#endif + IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", + size); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (display) { + if (full_log) + bufsz = capacity * 48; + else + bufsz = size * 48; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + } + if ((iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { + /* + * if uCode has wrapped back to top of log, + * start at the oldest entry, + * i.e the next one that uCode would fill. + */ + if (num_wraps) + pos = iwl4965_print_event_log(priv, next_entry, + capacity - next_entry, mode, + pos, buf, bufsz); + /* (then/else) start at top of log */ + pos = iwl4965_print_event_log(priv, 0, + next_entry, mode, pos, buf, bufsz); + } else + pos = iwl4965_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#else + pos = iwl4965_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#endif + return pos; +} + static void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) { struct iwl_ct_kill_config cmd; @@ -2442,10 +2773,20 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_TX_START: IWL_DEBUG_HT(priv, "start Tx\n"); ret = iwl4965_tx_agg_start(priv, vif, sta, tid, ssn); + if (ret == 0) { + priv->_4965.agg_tids_count++; + IWL_DEBUG_HT(priv, "priv->_4965.agg_tids_count = %u\n", + priv->_4965.agg_tids_count); + } break; case IEEE80211_AMPDU_TX_STOP: IWL_DEBUG_HT(priv, "stop Tx\n"); ret = iwl4965_tx_agg_stop(priv, vif, sta, tid); + if ((ret == 0) && (priv->_4965.agg_tids_count > 0)) { + priv->_4965.agg_tids_count--; + IWL_DEBUG_HT(priv, "priv->_4965.agg_tids_count = %u\n", + priv->_4965.agg_tids_count); + } if (test_bit(STATUS_EXIT_PENDING, &priv->status)) ret = 0; break; @@ -2510,6 +2851,7 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u16 ch; + unsigned long flags = 0; IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -2519,73 +2861,73 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, goto out; if (test_bit(STATUS_EXIT_PENDING, &priv->status) || - test_bit(STATUS_SCANNING, &priv->status) || - test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) + test_bit(STATUS_SCANNING, &priv->status)) goto out; if (!iwl_legacy_is_associated_ctx(ctx)) goto out; - if (!priv->cfg->ops->lib->set_channel_switch) - goto out; - - ch = channel->hw_value; - if (le16_to_cpu(ctx->active.channel) == ch) - goto out; - - ch_info = iwl_legacy_get_channel_info(priv, channel->band, ch); - if (!iwl_legacy_is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "invalid channel\n"); + /* channel switch in progress */ + if (priv->switch_rxon.switch_in_progress == true) goto out; - } - spin_lock_irq(&priv->lock); + if (priv->cfg->ops->lib->set_channel_switch) { - priv->current_ht_config.smps = conf->smps_mode; - - /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) { - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; + ch = channel->hw_value; + if (le16_to_cpu(ctx->active.channel) != ch) { + ch_info = iwl_legacy_get_channel_info(priv, + channel->band, + ch); + if (!iwl_legacy_is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "invalid channel\n"); + goto out; + } + spin_lock_irqsave(&priv->lock, flags); + + priv->current_ht_config.smps = conf->smps_mode; + + /* Configure HT40 channels */ + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else + ctx->ht.is_40mhz = false; + + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; + + iwl_legacy_set_rxon_channel(priv, channel, ctx); + iwl_legacy_set_rxon_ht(priv, ht_conf); + iwl_legacy_set_flags_for_band(priv, ctx, channel->band, + ctx->vif); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_legacy_set_rate(priv); + /* + * at this point, staging_rxon has the + * configuration for channel switch + */ + if (priv->cfg->ops->lib->set_channel_switch(priv, + ch_switch)) + priv->switch_rxon.switch_in_progress = false; } - } else - ctx->ht.is_40mhz = false; - - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; - - iwl_legacy_set_rxon_channel(priv, channel, ctx); - iwl_legacy_set_rxon_ht(priv, ht_conf); - iwl_legacy_set_flags_for_band(priv, ctx, channel->band, ctx->vif); - - spin_unlock_irq(&priv->lock); - - iwl_legacy_set_rate(priv); - /* - * at this point, staging_rxon has the - * configuration for channel switch - */ - set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); - priv->switch_channel = cpu_to_le16(ch); - if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) { - clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); - priv->switch_channel = 0; - ieee80211_chswitch_done(ctx->vif, false); } - out: mutex_unlock(&priv->mutex); + if (!priv->switch_rxon.switch_in_progress) + ieee80211_chswitch_done(ctx->vif, false); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -2692,6 +3034,10 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv) priv->statistics_periodic.data = (unsigned long)priv; priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; + init_timer(&priv->ucode_trace); + priv->ucode_trace.data = (unsigned long)priv; + priv->ucode_trace.function = iwl4965_bg_ucode_trace; + init_timer(&priv->watchdog); priv->watchdog.data = (unsigned long)priv; priv->watchdog.function = iwl_legacy_bg_watchdog; @@ -2710,6 +3056,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) iwl_legacy_cancel_scan_deferred_work(priv); del_timer_sync(&priv->statistics_periodic); + del_timer_sync(&priv->ucode_trace); } static void iwl4965_init_hw_rates(struct iwl_priv *priv, @@ -2785,9 +3132,13 @@ static int iwl4965_init_drv(struct iwl_priv *priv) priv->iw_mode = NL80211_IFTYPE_STATION; priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; + priv->_4965.agg_tids_count = 0; /* initialize force reset */ - priv->force_reset.reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD; + priv->force_reset[IWL_RF_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_RF_RESET; + priv->force_reset[IWL_FW_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_FW_RELOAD; /* Choose which receivers/antennas to use */ if (priv->cfg->ops->hcmd->set_rxon_chain) diff --git a/trunk/drivers/net/wireless/iwlwifi/Makefile b/trunk/drivers/net/wireless/iwlwifi/Makefile index 9a56ce546715..822660483f9f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Makefile +++ b/trunk/drivers/net/wireless/iwlwifi/Makefile @@ -13,7 +13,6 @@ iwlagn-objs += iwl-5000.o iwlagn-objs += iwl-6000.o iwlagn-objs += iwl-1000.o iwlagn-objs += iwl-2000.o -iwlagn-objs += iwl-pci.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c index 2daca80f086f..7aa240e6ba1c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -192,6 +194,8 @@ static struct iwl_lib_ops iwl1000_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl1000_ops = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c index 1c1330035ca9..5484ab712da8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -74,7 +76,21 @@ static void iwl2000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 2000 series */ static void iwl2000_nic_config(struct iwl_priv *priv) { - iwl_rf_config(priv); + u16 radio_cfg; + + radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) | + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); if (priv->cfg->iq_invert) iwl_set_bit(priv, CSR_GP_DRIVER_REG, @@ -188,6 +204,8 @@ static struct iwl_lib_ops iwl2000_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl2000_ops = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index f9630a3c79fe..05ad47628b63 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -75,7 +75,7 @@ static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) { u16 temperature, voltage; __le16 *temp_calib = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); temperature = le16_to_cpu(temp_calib[0]); voltage = le16_to_cpu(temp_calib[1]); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index 937a8f12afa7..4353a658de25 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -64,11 +66,24 @@ static void iwl5000_nic_config(struct iwl_priv *priv) { unsigned long flags; - - iwl_rf_config(priv); + u16 radio_cfg; spin_lock_irqsave(&priv->lock, flags); + radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_RF_CONFIG_TYPE_MAX) + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) | + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + /* W/A : NIC is stuck in a reset state after Early PCIe power off * (PCIe power is lost before PERST# is asserted), * causing ME FW to lose ownership and not being able to obtain it back. @@ -346,6 +361,8 @@ static struct iwl_lib_ops iwl5000_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static struct iwl_lib_ops iwl5150_lib = { @@ -374,6 +391,8 @@ static struct iwl_lib_ops iwl5150_lib = { .temp_ops = { .temperature = iwl5150_temperature, }, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl5000_ops = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c index 3fcc0925d542..6e5ce4478490 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -95,7 +97,21 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { - iwl_rf_config(priv); + u16 radio_cfg; + + radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) | + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); /* no locking required for register write */ if (priv->cfg->pa_type == IWL_PA_INTERNAL) { @@ -285,6 +301,8 @@ static struct iwl_lib_ops iwl6000_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static struct iwl_lib_ops iwl6030_lib = { @@ -315,6 +333,8 @@ static struct iwl_lib_ops iwl6030_lib = { .temp_ops = { .temperature = iwlagn_temperature, }, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static struct iwl_nic_ops iwl6050_nic_ops = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 7745816eaff4..2ef9448b1c20 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -108,16 +108,18 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) int iwl_eeprom_check_sku(struct iwl_priv *priv) { + u16 eeprom_sku; u16 radio_cfg; + eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); + if (!priv->cfg->sku) { /* not using sku overwrite */ - priv->cfg->sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); - if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE && - !priv->cfg->ht_params) { - IWL_ERR(priv, "Invalid 11n configuration\n"); - return -EINVAL; - } + priv->cfg->sku = + ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >> + EEPROM_SKU_CAP_BAND_POS); + if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE) + priv->cfg->sku |= IWL_SKU_N; } if (!priv->cfg->sku) { IWL_ERR(priv, "Invalid device sku\n"); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index ba7ed9157c92..23eee0ca5b35 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -111,8 +111,10 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, memset(&cmd, 0, sizeof(cmd)); - iwl_set_calib_hdr(&cmd.hdr, - priv->_agn.phy_calib_chain_noise_gain_cmd); + cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_gain_cmd; + cmd.hdr.first_group = 0; + cmd.hdr.groups_num = 1; + cmd.hdr.data_valid = 1; cmd.delta_gain_1 = data->delta_gain_code[1]; cmd.delta_gain_2 = data->delta_gain_code[2]; iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, @@ -142,8 +144,10 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) data->beacon_count = 0; memset(&cmd, 0, sizeof(cmd)); - iwl_set_calib_hdr(&cmd.hdr, - priv->_agn.phy_calib_chain_noise_reset_cmd); + cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_reset_cmd; + cmd.hdr.first_group = 0; + cmd.hdr.groups_num = 1; + cmd.hdr.data_valid = 1; ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, sizeof(cmd), &cmd); if (ret) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index 0e5b842529c4..7bd19f4e66de 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -81,6 +81,13 @@ /* RSSI to dBm */ #define IWLAGN_RSSI_OFFSET 44 +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 + +/* PCI register values */ +#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 +#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 + #define IWLAGN_DEFAULT_TX_RETRY 15 /* Limit range of txpower output target to be between these values */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index f1b40ec1c873..0d5fda44c3a3 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -44,7 +44,7 @@ void iwl_free_isr_ict(struct iwl_priv *priv) { if (priv->_agn.ict_tbl_vir) { - dma_free_coherent(priv->bus.dev, + dma_free_coherent(&priv->pci_dev->dev, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, priv->_agn.ict_tbl_vir, priv->_agn.ict_tbl_dma); @@ -61,7 +61,7 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv) /* allocate shrared data table */ priv->_agn.ict_tbl_vir = - dma_alloc_coherent(priv->bus.dev, + dma_alloc_coherent(&priv->pci_dev->dev, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, &priv->_agn.ict_tbl_dma, GFP_KERNEL); if (!priv->_agn.ict_tbl_vir) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index efdab6506ae7..677f73c4c1e3 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -438,7 +438,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) { - IWL_DEBUG_COEX(priv, "receive reply tx with bt_kill\n"); + IWL_WARN(priv, "receive reply tx with bt_kill\n"); } iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); @@ -622,9 +622,6 @@ struct iwl_mod_params iwlagn_mod_params = { .amsdu_size_8K = 1, .restart_fw = 1, .plcp_check = true, - .bt_coex_active = true, - .no_sleep_autoadjust = true, - .power_level = IWL_POWER_INDEX_1, /* the rest are 0 by default */ }; @@ -640,9 +637,9 @@ void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) /* In the reset function, these buffers may have been allocated * to an SKB, so we need to unmap and free potential storage */ if (rxq->pool[i].page != NULL) { - dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, + pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, - DMA_FROM_DEVICE); + PCI_DMA_FROMDEVICE); __iwl_free_pages(priv, rxq->pool[i].page); rxq->pool[i].page = NULL; } @@ -914,9 +911,9 @@ void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority) BUG_ON(rxb->page); rxb->page = page; /* Get physical address of the RB */ - rxb->page_dma = dma_map_page(priv->bus.dev, page, 0, + rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, PAGE_SIZE << priv->hw_params.rx_page_order, - DMA_FROM_DEVICE); + PCI_DMA_FROMDEVICE); /* dma address must be no more than 36 bits */ BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); /* and also 256 byte aligned! */ @@ -959,18 +956,17 @@ void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) int i; for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { if (rxq->pool[i].page != NULL) { - dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma, + pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, - DMA_FROM_DEVICE); + PCI_DMA_FROMDEVICE); __iwl_free_pages(priv, rxq->pool[i].page); rxq->pool[i].page = NULL; } } - dma_free_coherent(priv->bus.dev, 4 * RX_QUEUE_SIZE, - rxq->bd, rxq->bd_dma); - dma_free_coherent(priv->bus.dev, - sizeof(struct iwl_rb_status), + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->bd_dma); + dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), rxq->rb_stts, rxq->rb_stts_dma); rxq->bd = NULL; rxq->rb_stts = NULL; @@ -1532,18 +1528,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) might_sleep(); memset(&flush_cmd, 0, sizeof(flush_cmd)); - if (flush_control & BIT(IWL_RXON_CTX_BSS)) - flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | - IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | - IWL_SCD_MGMT_MSK; - if ((flush_control & BIT(IWL_RXON_CTX_PAN)) && - (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) - flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | - IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | - IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | - IWL_PAN_SCD_MULTICAST_MSK; - - if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) + flush_cmd.fifo_control = IWL_TX_FIFO_VO_MSK | IWL_TX_FIFO_VI_MSK | + IWL_TX_FIFO_BE_MSK | IWL_TX_FIFO_BK_MSK; + if (priv->cfg->sku & IWL_SKU_N) flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", @@ -1557,7 +1544,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) { mutex_lock(&priv->mutex); ieee80211_stop_queues(priv->hw); - if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { + if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) { IWL_ERR(priv, "flush request fail\n"); goto done; } @@ -1712,8 +1699,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) * (might be in monitor mode), or the interface is in * IBSS mode (no proper uCode support for coex then). */ - if (!iwlagn_mod_params.bt_coex_active || - priv->iw_mode == NL80211_IFTYPE_ADHOC) { + if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { basic.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; } else { basic.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << @@ -1724,7 +1710,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) if (priv->bt_ch_announce) basic.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; - IWL_DEBUG_COEX(priv, "BT coex flag: 0X%x\n", basic.flags); + IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", basic.flags); } priv->bt_enable_flag = basic.flags; if (priv->bt_full_concurrent) @@ -1734,7 +1720,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) memcpy(basic.bt3_lookup_table, iwlagn_def_3w_lookup, sizeof(iwlagn_def_3w_lookup)); - IWL_DEBUG_COEX(priv, "BT coex %s in %s mode\n", + IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", basic.flags ? "active" : "disabled", priv->bt_full_concurrent ? "full concurrency" : "3-wire"); @@ -1772,7 +1758,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) * coex profile notifications. Ignore that since only bad consequence * can be not matching debug print with actual state. */ - IWL_DEBUG_COEX(priv, "BT traffic load changes: %d\n", + IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", priv->bt_traffic_load); switch (priv->bt_traffic_load) { @@ -1824,7 +1810,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) static void iwlagn_print_uartmsg(struct iwl_priv *priv, struct iwl_bt_uart_msg *uart_msg) { - IWL_DEBUG_COEX(priv, "Message Type = 0x%X, SSN = 0x%X, " + IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, " "Update Req = 0x%X", (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >> BT_UART_MSG_FRAME1MSGTYPE_POS, @@ -1833,7 +1819,7 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >> BT_UART_MSG_FRAME1UPDATEREQ_POS); - IWL_DEBUG_COEX(priv, "Open connections = 0x%X, Traffic load = 0x%X, " + IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, " "Chl_SeqN = 0x%X, In band = 0x%X", (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >> BT_UART_MSG_FRAME2OPENCONNECTIONS_POS, @@ -1844,7 +1830,7 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >> BT_UART_MSG_FRAME2INBAND_POS); - IWL_DEBUG_COEX(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " + IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X", (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> BT_UART_MSG_FRAME3SCOESCO_POS, @@ -1859,11 +1845,11 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >> BT_UART_MSG_FRAME3OBEX_POS); - IWL_DEBUG_COEX(priv, "Idle duration = 0x%X", + IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X", (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >> BT_UART_MSG_FRAME4IDLEDURATION_POS); - IWL_DEBUG_COEX(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " + IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " "eSCO Retransmissions = 0x%X", (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >> BT_UART_MSG_FRAME5TXACTIVITY_POS, @@ -1872,13 +1858,13 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >> BT_UART_MSG_FRAME5ESCORETRANSMIT_POS); - IWL_DEBUG_COEX(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", + IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >> BT_UART_MSG_FRAME6SNIFFINTERVAL_POS, (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> BT_UART_MSG_FRAME6DISCOVERABLE_POS); - IWL_DEBUG_COEX(priv, "Sniff Activity = 0x%X, Page = " + IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Page = " "0x%X, Inquiry = 0x%X, Connectable = 0x%X", (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, @@ -1928,10 +1914,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, return; } - IWL_DEBUG_COEX(priv, "BT Coex notification:\n"); - IWL_DEBUG_COEX(priv, " status: %d\n", coex->bt_status); - IWL_DEBUG_COEX(priv, " traffic load: %d\n", coex->bt_traffic_load); - IWL_DEBUG_COEX(priv, " CI compliance: %d\n", + IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); + IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); + IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); + IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", coex->bt_ci_compliance); iwlagn_print_uartmsg(priv, uart_msg); @@ -2329,8 +2315,7 @@ int iwlagn_start_device(struct iwl_priv *priv) { int ret; - if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) && - iwl_prepare_card_hw(priv)) { + if (iwl_prepare_card_hw(priv)) { IWL_WARN(priv, "Exit HW not ready\n"); return -EIO; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index f501d742984c..348f74f1c8e8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -198,7 +198,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) /* Reschedule the ct_kill timer to occur in * CT_KILL_EXIT_DURATION seconds to ensure we get a * thermal update */ - IWL_DEBUG_TEMP(priv, "schedule ct_kill exit timer\n"); + IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n"); mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies + CT_KILL_EXIT_DURATION * HZ); } @@ -208,15 +208,15 @@ static void iwl_perform_ct_kill_task(struct iwl_priv *priv, bool stop) { if (stop) { - IWL_DEBUG_TEMP(priv, "Stop all queues\n"); + IWL_DEBUG_POWER(priv, "Stop all queues\n"); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); - IWL_DEBUG_TEMP(priv, + IWL_DEBUG_POWER(priv, "Schedule 5 seconds CT_KILL Timer\n"); mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies + CT_KILL_EXIT_DURATION * HZ); } else { - IWL_DEBUG_TEMP(priv, "Wake all queues\n"); + IWL_DEBUG_POWER(priv, "Wake all queues\n"); if (priv->mac80211_registered) ieee80211_wake_queues(priv->hw); } @@ -232,7 +232,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) /* temperature timer expired, ready to go into CT_KILL state */ if (tt->state != IWL_TI_CT_KILL) { - IWL_DEBUG_TEMP(priv, "entering CT_KILL state when " + IWL_DEBUG_POWER(priv, "entering CT_KILL state when " "temperature timer expired\n"); tt->state = IWL_TI_CT_KILL; set_bit(STATUS_CT_KILL, &priv->status); @@ -242,7 +242,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) { - IWL_DEBUG_TEMP(priv, "Prepare to enter IWL_TI_CT_KILL\n"); + IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); /* make request to retrieve statistics information */ iwl_send_statistics_request(priv, CMD_SYNC, false); /* Reschedule the ct_kill wait timer */ @@ -273,7 +273,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) (temp > tt->tt_previous_temp) && ((temp - tt->tt_previous_temp) > IWL_TT_INCREASE_MARGIN)) { - IWL_DEBUG_TEMP(priv, + IWL_DEBUG_POWER(priv, "Temperature increase %d degree Celsius\n", (temp - tt->tt_previous_temp)); } @@ -338,9 +338,9 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) } else if (old_state == IWL_TI_CT_KILL && tt->state != IWL_TI_CT_KILL) iwl_perform_ct_kill_task(priv, false); - IWL_DEBUG_TEMP(priv, "Temperature state changed %u\n", + IWL_DEBUG_POWER(priv, "Temperature state changed %u\n", tt->state); - IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", + IWL_DEBUG_POWER(priv, "Power Index change to %u\n", tt->tt_power_mode); } mutex_unlock(&priv->mutex); @@ -397,7 +397,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) (temp > tt->tt_previous_temp) && ((temp - tt->tt_previous_temp) > IWL_TT_INCREASE_MARGIN)) { - IWL_DEBUG_TEMP(priv, + IWL_DEBUG_POWER(priv, "Temperature increase %d " "degree Celsius\n", (temp - tt->tt_previous_temp)); @@ -467,13 +467,13 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) set_bit(STATUS_CT_KILL, &priv->status); tt->state = old_state; } else { - IWL_DEBUG_TEMP(priv, + IWL_DEBUG_POWER(priv, "Thermal Throttling to new state: %u\n", tt->state); if (old_state != IWL_TI_CT_KILL && tt->state == IWL_TI_CT_KILL) { if (force) { - IWL_DEBUG_TEMP(priv, + IWL_DEBUG_POWER(priv, "Enter IWL_TI_CT_KILL\n"); set_bit(STATUS_CT_KILL, &priv->status); 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) } } else if (old_state == IWL_TI_CT_KILL && tt->state != IWL_TI_CT_KILL) { - IWL_DEBUG_TEMP(priv, "Exit IWL_TI_CT_KILL\n"); + IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n"); iwl_perform_ct_kill_task(priv, false); } } @@ -568,7 +568,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); + IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); queue_work(priv->workqueue, &priv->ct_enter); } @@ -577,7 +577,7 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); + IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); queue_work(priv->workqueue, &priv->ct_exit); } @@ -603,7 +603,7 @@ void iwl_tt_handler(struct iwl_priv *priv) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); + IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); queue_work(priv->workqueue, &priv->tt_work); } @@ -618,7 +618,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); struct iwl_tt_trans *transaction; - IWL_DEBUG_TEMP(priv, "Initialize Thermal Throttling\n"); + IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n"); memset(tt, 0, sizeof(struct iwl_tt_mgmt)); @@ -638,7 +638,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); if (priv->cfg->base_params->adv_thermal_throttle) { - IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); + IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * IWL_TI_STATE_MAX, GFP_KERNEL); tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) * @@ -671,7 +671,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) priv->thermal_throttle.advanced_tt = true; } } else { - IWL_DEBUG_TEMP(priv, "Legacy Thermal Throttling\n"); + IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); priv->thermal_throttle.advanced_tt = false; } } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index d0ac090399e9..8bd48f61a9f5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -716,10 +716,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ - txcmd_phys = dma_map_single(priv->bus.dev, + txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr, firstlen, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(priv->bus.dev, txcmd_phys))) + PCI_DMA_BIDIRECTIONAL); + if (unlikely(pci_dma_mapping_error(priv->pci_dev, txcmd_phys))) goto drop_unlock_sta; dma_unmap_addr_set(out_meta, mapping, txcmd_phys); dma_unmap_len_set(out_meta, len, firstlen); @@ -735,13 +735,13 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) * if any (802.11 null frames have no payload). */ secondlen = skb->len - hdr_len; if (secondlen > 0) { - phys_addr = dma_map_single(priv->bus.dev, skb->data + hdr_len, - secondlen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) { - dma_unmap_single(priv->bus.dev, + phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, + secondlen, PCI_DMA_TODEVICE); + if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { + pci_unmap_single(priv->pci_dev, dma_unmap_addr(out_meta, mapping), dma_unmap_len(out_meta, len), - DMA_BIDIRECTIONAL); + PCI_DMA_BIDIRECTIONAL); goto drop_unlock_sta; } } @@ -764,8 +764,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) offsetof(struct iwl_tx_cmd, scratch); /* take back ownership of DMA buffer to enable update */ - dma_sync_single_for_cpu(priv->bus.dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys, + firstlen, PCI_DMA_BIDIRECTIONAL); tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); @@ -780,8 +780,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwlagn_txq_update_byte_cnt_tbl(priv, txq, le16_to_cpu(tx_cmd->len)); - dma_sync_single_for_device(priv->bus.dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); + pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, + firstlen, PCI_DMA_BIDIRECTIONAL); trace_iwlwifi_dev_tx(priv, &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], @@ -834,8 +834,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv, struct iwl_dma_ptr *ptr, size_t size) { - ptr->addr = dma_alloc_coherent(priv->bus.dev, size, - &ptr->dma, GFP_KERNEL); + ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma, + GFP_KERNEL); if (!ptr->addr) return -ENOMEM; ptr->size = size; @@ -848,7 +848,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv, if (unlikely(!ptr->addr)) return; - dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma); + dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma); memset(ptr, 0, sizeof(*ptr)); } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index de8277e32253..97de5d9de67b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -143,7 +143,7 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name); + IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name); ret = wait_event_interruptible_timeout(priv->wait_command_queue, priv->ucode_write_complete, 5 * HZ); if (ret == -ERESTARTSYS) { @@ -183,7 +183,10 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv) __le16 *xtal_calib = (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL); - iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); + cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; + cmd.hdr.first_group = 0; + cmd.hdr.groups_num = 1; + cmd.hdr.data_valid = 1; cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], @@ -194,14 +197,15 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_cmd cmd; __le16 *offset_calib = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); - - memset(&cmd, 0, sizeof(cmd)); - iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); + cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD; + cmd.hdr.first_group = 0; + cmd.hdr.groups_num = 1; + cmd.hdr.data_valid = 1; cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]); if (!(cmd.radio_sensor_offset)) cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; - + cmd.reserved = 0; IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", cmd.radio_sensor_offset); return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET], @@ -504,7 +508,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, u32 val; u32 i; - IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { /* read data comes through single port, auto-incr addr */ @@ -529,7 +533,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, u32 offs; int errors = 0; - IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, IWLAGN_RTC_INST_LOWER_BOUND); @@ -555,7 +559,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img) { if (!iwlcore_verify_inst_sparse(priv, &img->code)) { - IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); + IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n"); return 0; } @@ -579,7 +583,7 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, palive = &pkt->u.alive_frame; - IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " + IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " "0x%01X 0x%01X\n", palive->is_valid, palive->ver_type, palive->ver_subtype); @@ -598,12 +602,12 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, struct fw_img *image, - enum iwlagn_ucode_type ucode_type) + int subtype, int alternate_subtype) { struct iwl_notification_wait alive_wait; struct iwlagn_alive_data alive_data; int ret; - enum iwlagn_ucode_type old_type; + enum iwlagn_ucode_subtype old_type; ret = iwlagn_start_device(priv); if (ret) @@ -613,7 +617,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, iwlagn_alive_fn, &alive_data); old_type = priv->ucode_type; - priv->ucode_type = ucode_type; + priv->ucode_type = subtype; ret = iwlagn_load_given_ucode(priv, image); if (ret) { @@ -641,6 +645,15 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, return -EIO; } + if (alive_data.subtype != subtype && + alive_data.subtype != alternate_subtype) { + IWL_ERR(priv, + "Loaded ucode is not expected type (got %d, expected %d)!\n", + alive_data.subtype, subtype); + priv->ucode_type = old_type; + return -EIO; + } + ret = iwl_verify_ucode(priv, image); if (ret) { priv->ucode_type = old_type; @@ -672,7 +685,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) if (!priv->ucode_init.code.len) return 0; - if (priv->ucode_type != IWL_UCODE_NONE) + if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED) return 0; iwlagn_init_notification_wait(priv, &calib_wait, @@ -681,7 +694,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) /* Will also start the device */ ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, - IWL_UCODE_INIT); + UCODE_SUBTYPE_INIT, -1); if (ret) goto error; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index 77ceb8deff75..099c2795ec0b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include #include @@ -47,6 +49,8 @@ #include +#define DRV_NAME "iwlagn" + #include "iwl-eeprom.h" #include "iwl-dev.h" #include "iwl-core.h" @@ -55,7 +59,6 @@ #include "iwl-sta.h" #include "iwl-agn-calib.h" #include "iwl-agn.h" -#include "iwl-pci.h" /****************************************************************************** @@ -437,8 +440,10 @@ static void iwl_bg_tx_flush(struct work_struct *work) if (!iwl_is_ready_rf(priv)) return; - IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); - iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); + if (priv->cfg->ops->lib->txfifo_flush) { + IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); + iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); + } } /** @@ -492,9 +497,9 @@ static void iwl_rx_handle(struct iwl_priv *priv) rxq->queue[i] = NULL; - dma_unmap_page(priv->bus.dev, rxb->page_dma, + pci_unmap_page(priv->pci_dev, rxb->page_dma, PAGE_SIZE << priv->hw_params.rx_page_order, - DMA_FROM_DEVICE); + PCI_DMA_FROMDEVICE); pkt = rxb_addr(rxb); len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; @@ -576,9 +581,9 @@ static void iwl_rx_handle(struct iwl_priv *priv) * rx_free list for reuse later. */ spin_lock_irqsave(&rxq->lock, flags); if (rxb->page != NULL) { - rxb->page_dma = dma_map_page(priv->bus.dev, rxb->page, + rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, 0, PAGE_SIZE << priv->hw_params.rx_page_order, - DMA_FROM_DEVICE); + PCI_DMA_FROMDEVICE); list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; } else @@ -934,28 +939,22 @@ static struct attribute_group iwl_attribute_group = { * ******************************************************************************/ -static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc) +static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) { if (desc->v_addr) - dma_free_coherent(priv->bus.dev, desc->len, + dma_free_coherent(&pci_dev->dev, desc->len, desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; } -static void iwl_free_fw_img(struct iwl_priv *priv, struct fw_img *img) +static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img) { - iwl_free_fw_desc(priv, &img->code); - iwl_free_fw_desc(priv, &img->data); + iwl_free_fw_desc(pci_dev, &img->code); + iwl_free_fw_desc(pci_dev, &img->data); } -static void iwl_dealloc_ucode(struct iwl_priv *priv) -{ - iwl_free_fw_img(priv, &priv->ucode_rt); - iwl_free_fw_img(priv, &priv->ucode_init); -} - -static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc, +static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc, const void *data, size_t len) { if (!len) { @@ -963,16 +962,21 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc, return -EINVAL; } - desc->v_addr = dma_alloc_coherent(priv->bus.dev, len, + desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; - desc->len = len; memcpy(desc->v_addr, data, len); return 0; } +static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) +{ + iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt); + iwl_free_fw_img(priv->pci_dev, &priv->ucode_init); +} + struct iwlagn_ucode_capabilities { u32 max_probe_length; u32 standard_phy_calibration_size; @@ -1017,8 +1021,8 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) priv->firmware_name); return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, - priv->bus.dev, - GFP_KERNEL, priv, iwl_ucode_callback); + &priv->pci_dev->dev, GFP_KERNEL, priv, + iwl_ucode_callback); } struct iwlagn_firmware_pieces { @@ -1439,19 +1443,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* Runtime instructions and 2 copies of data: * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.code, + if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code, pieces.inst, pieces.inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.data, + if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data, pieces.data, pieces.data_size)) goto err_pci_alloc; /* Initialization instructions and data */ if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(priv, &priv->ucode_init.code, + if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code, pieces.init, pieces.init_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(priv, &priv->ucode_init.data, + if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data, pieces.init_data, pieces.init_data_size)) goto err_pci_alloc; } @@ -1481,8 +1485,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) priv->new_scan_threshold_behaviour = !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); - if ((priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE) && - (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) { + if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; } else @@ -1520,7 +1523,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (err) IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - err = sysfs_create_group(&(priv->bus.dev->kobj), + err = sysfs_create_group(&priv->pci_dev->dev.kobj, &iwl_attribute_group); if (err) { IWL_ERR(priv, "failed to create sysfs device attributes\n"); @@ -1541,10 +1544,10 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) err_pci_alloc: IWL_ERR(priv, "failed to allocate pci memory\n"); - iwl_dealloc_ucode(priv); + iwl_dealloc_ucode_pci(priv); out_unbind: complete(&priv->_agn.firmware_loading_complete); - device_release_driver(priv->bus.dev); + device_release_driver(&priv->pci_dev->dev); release_firmware(ucode_raw); } @@ -1623,7 +1626,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) struct iwl_error_event_table table; base = priv->device_pointers.error_event_table; - if (priv->ucode_type == IWL_UCODE_INIT) { + if (priv->ucode_type == UCODE_SUBTYPE_INIT) { if (!base) base = priv->_agn.init_errlog_ptr; } else { @@ -1635,7 +1638,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) IWL_ERR(priv, "Not valid error log pointer 0x%08X for %s uCode\n", base, - (priv->ucode_type == IWL_UCODE_INIT) + (priv->ucode_type == UCODE_SUBTYPE_INIT) ? "Init" : "RT"); return; } @@ -1699,7 +1702,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, return pos; base = priv->device_pointers.log_event_table; - if (priv->ucode_type == IWL_UCODE_INIT) { + if (priv->ucode_type == UCODE_SUBTYPE_INIT) { if (!base) base = priv->_agn.init_evtlog_ptr; } else { @@ -1812,7 +1815,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, size_t bufsz = 0; base = priv->device_pointers.log_event_table; - if (priv->ucode_type == IWL_UCODE_INIT) { + if (priv->ucode_type == UCODE_SUBTYPE_INIT) { logsize = priv->_agn.init_evtlog_size; if (!base) base = priv->_agn.init_evtlog_ptr; @@ -1826,7 +1829,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, IWL_ERR(priv, "Invalid event log pointer 0x%08X for %s uCode\n", base, - (priv->ucode_type == IWL_UCODE_INIT) + (priv->ucode_type == UCODE_SUBTYPE_INIT) ? "Init" : "RT"); return -EINVAL; } @@ -2207,7 +2210,8 @@ static int __iwl_up(struct iwl_priv *priv) ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_rt, - IWL_UCODE_REGULAR); + UCODE_SUBTYPE_REGULAR, + UCODE_SUBTYPE_REGULAR_NEW); if (ret) { IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); goto error; @@ -2512,7 +2516,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; - if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (priv->cfg->sku & IWL_SKU_N) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS; @@ -2545,10 +2549,11 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; - if (iwlagn_mod_params.power_save) - hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; - else - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + /* + * For now, disable PS by default because it affects + * RX performance significantly. + */ + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; /* we create the 802.11 header and a zero-length SSID element */ @@ -2752,7 +2757,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", sta->addr, tid); - if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) + if (!(priv->cfg->sku & IWL_SKU_N)) return -EACCES; mutex_lock(&priv->mutex); @@ -3047,6 +3052,10 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter\n"); + /* do not support "flush" */ + if (!priv->cfg->ops->lib->txfifo_flush) + goto done; + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); goto done; @@ -3062,7 +3071,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) */ if (drop) { IWL_DEBUG_MAC80211(priv, "send flush command\n"); - if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { + if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) { IWL_ERR(priv, "flush request fail\n"); goto done; } @@ -3343,11 +3352,14 @@ struct ieee80211_ops iwlagn_hw_ops = { .offchannel_tx = iwl_mac_offchannel_tx, .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, CFG80211_TESTMODE_CMD(iwl_testmode_cmd) - CFG80211_TESTMODE_DUMP(iwl_testmode_dump) }; static u32 iwl_hw_detect(struct iwl_priv *priv) { + u8 rev_id; + + pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); + IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); return iwl_read32(priv, CSR_HW_REV); } @@ -3363,7 +3375,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; if (iwlagn_mod_params.disable_11n) - priv->cfg->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; + priv->cfg->sku &= ~IWL_SKU_N; /* Device-specific setup */ return priv->cfg->ops->lib->set_hw_params(priv); @@ -3413,9 +3425,29 @@ static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) return hw; } -static void iwl_init_context(struct iwl_priv *priv) +static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int i; + int err = 0, i; + struct iwl_priv *priv; + struct ieee80211_hw *hw; + struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + unsigned long flags; + u16 pci_cmd, num_mac; + u32 hw_rev; + + /************************ + * 1. Allocating HW data + ************************/ + + hw = iwl_alloc_all(cfg); + if (!hw) { + err = -ENOMEM; + goto out; + } + priv = hw->priv; + /* At this point both hw and priv are allocated. */ + + priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED; /* * The default context is always valid, @@ -3447,10 +3479,8 @@ static void iwl_init_context(struct iwl_priv *priv) priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; - priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = - REPLY_WIPAN_RXON_TIMING; - priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = - REPLY_WIPAN_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = REPLY_WIPAN_RXON_ASSOC; priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM; priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN; priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; @@ -3470,41 +3500,12 @@ static void iwl_init_context(struct iwl_priv *priv) priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); -} - -int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, - struct iwl_cfg *cfg) -{ - int err = 0; - struct iwl_priv *priv; - struct ieee80211_hw *hw; - u16 num_mac; - u32 hw_rev; - /************************ - * 1. Allocating HW data - ************************/ - hw = iwl_alloc_all(cfg); - if (!hw) { - err = -ENOMEM; - goto out; - } - - priv = hw->priv; - - priv->bus.priv = priv; - priv->bus.bus_specific = bus_specific; - priv->bus.ops = bus_ops; - priv->bus.irq = priv->bus.ops->get_irq(&priv->bus); - priv->bus.ops->set_drv_data(&priv->bus, priv); - priv->bus.dev = priv->bus.ops->get_dev(&priv->bus); - - /* At this point both hw and priv are allocated. */ - - SET_IEEE80211_DEV(hw, priv->bus.dev); + SET_IEEE80211_DEV(hw, &pdev->dev); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); priv->cfg = cfg; + priv->pci_dev = pdev; priv->inta_mask = CSR_INI_SET_MASK; /* is antenna coupling more than 35dB ? */ @@ -3520,6 +3521,52 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, if (iwl_alloc_traffic_mem(priv)) IWL_ERR(priv, "Not enough memory to generate traffic log\n"); + /************************** + * 2. Initializing PCI bus + **************************/ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + + if (pci_enable_device(pdev)) { + err = -ENODEV; + goto out_ieee80211_free_hw; + } + + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); + if (err) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + /* both attempts failed: */ + if (err) { + IWL_WARN(priv, "No suitable DMA available.\n"); + goto out_pci_disable_device; + } + } + + err = pci_request_regions(pdev, DRV_NAME); + if (err) + goto out_pci_disable_device; + + pci_set_drvdata(pdev, priv); + + + /*********************** + * 3. Read REV register + ***********************/ + priv->hw_base = pci_iomap(pdev, 0, 0); + if (!priv->hw_base) { + err = -ENODEV; + goto out_pci_release_regions; + } + + IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); /* these spin locks will be used in apm_ops.init and EEPROM access * we should init now @@ -3534,17 +3581,17 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, */ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - /*********************** - * 3. Read REV register - ***********************/ hw_rev = iwl_hw_detect(priv); IWL_INFO(priv, "Detected %s, REV=0x%X\n", priv->cfg->name, hw_rev); + /* We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + if (iwl_prepare_card_hw(priv)) { - err = -EIO; IWL_WARN(priv, "Failed, HW not ready\n"); - goto out_free_traffic_mem; + goto out_iounmap; } /***************** @@ -3554,7 +3601,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, err = iwl_eeprom_init(priv, hw_rev); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_free_traffic_mem; + goto out_iounmap; } err = iwl_eeprom_check_version(priv); if (err) @@ -3577,14 +3624,10 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, priv->hw->wiphy->n_addresses++; } - /* initialize all valid contexts */ - iwl_init_context(priv); - /************************ * 5. Setup HW constants ************************/ if (iwl_set_hw_params(priv)) { - err = -ENOENT; IWL_ERR(priv, "failed to set hw parameters\n"); goto out_free_eeprom; } @@ -3601,13 +3644,19 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, /******************** * 7. Setup services ********************/ + spin_lock_irqsave(&priv->lock, flags); + iwl_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + pci_enable_msi(priv->pci_dev); + iwl_alloc_isr_ict(priv); - err = request_irq(priv->bus.irq, iwl_isr_ict, IRQF_SHARED, - DRV_NAME, priv); + err = request_irq(priv->pci_dev->irq, iwl_isr_ict, + IRQF_SHARED, DRV_NAME, priv); if (err) { - IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus.irq); - goto out_uninit_drv; + IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); + goto out_disable_msi; } iwl_setup_deferred_work(priv); @@ -3615,9 +3664,16 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, iwl_testmode_init(priv); /********************************************* - * 8. Enable interrupts + * 8. Enable interrupts and read RFKILL state *********************************************/ + /* enable rfkill interrupt: hw bug w/a */ + pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); + if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { + pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); + } + iwl_enable_rfkill_int(priv); /* If platform's RF_KILL switch is NOT set to KILL */ @@ -3643,30 +3699,41 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, out_destroy_workqueue: destroy_workqueue(priv->workqueue); priv->workqueue = NULL; - free_irq(priv->bus.irq, priv); + free_irq(priv->pci_dev->irq, priv); + out_disable_msi: iwl_free_isr_ict(priv); - out_uninit_drv: + pci_disable_msi(priv->pci_dev); iwl_uninit_drv(priv); out_free_eeprom: iwl_eeprom_free(priv); - out_free_traffic_mem: + out_iounmap: + pci_iounmap(pdev, priv->hw_base); + out_pci_release_regions: + pci_set_drvdata(pdev, NULL); + pci_release_regions(pdev); + out_pci_disable_device: + pci_disable_device(pdev); + out_ieee80211_free_hw: iwl_free_traffic_mem(priv); ieee80211_free_hw(priv->hw); out: return err; } -void __devexit iwl_remove(struct iwl_priv * priv) +static void __devexit iwl_pci_remove(struct pci_dev *pdev) { + struct iwl_priv *priv = pci_get_drvdata(pdev); unsigned long flags; + if (!priv) + return; + wait_for_completion(&priv->_agn.firmware_loading_complete); IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); iwl_dbgfs_unregister(priv); - sysfs_remove_group(&priv->bus.dev->kobj, - &iwl_attribute_group); + sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); /* ieee80211_unregister_hw call wil cause iwl_mac_stop to * to be called and iwl_down since we are removing the device @@ -3696,7 +3763,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) iwl_synchronize_irq(priv); - iwl_dealloc_ucode(priv); + iwl_dealloc_ucode_pci(priv); if (priv->rxq.bd) iwlagn_rx_queue_free(priv, &priv->rxq); @@ -3715,8 +3782,12 @@ void __devexit iwl_remove(struct iwl_priv * priv) priv->workqueue = NULL; iwl_free_traffic_mem(priv); - free_irq(priv->bus.irq, priv); - priv->bus.ops->set_drv_data(&priv->bus, NULL); + free_irq(priv->pci_dev->irq, priv); + pci_disable_msi(priv->pci_dev); + pci_iounmap(pdev, priv->hw_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); iwl_uninit_drv(priv); @@ -3733,6 +3804,206 @@ void __devexit iwl_remove(struct iwl_priv * priv) * driver and module entry point * *****************************************************************************/ + +/* Hardware specific file defines the PCI IDs table for that hardware module */ +static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { + {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ + +/* 5300 Series WiFi */ + {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ + +/* 5350 Series WiFi/WiMax */ + {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ + +/* 5150 Series Wifi/WiMax */ + {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ + + {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ + +/* 6x00 Series */ + {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, + {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, + {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, + +/* 6x05 Series */ + {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, + +/* 6x30 Series */ + {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)}, + +/* 6x50 WiFi/WiMax Series */ + {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, + +/* 6150 WiFi/WiMax Series */ + {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, + +/* 1000 Series WiFi */ + {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, + {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, + +/* 100 Series WiFi */ + {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)}, + +/* 130 Series WiFi */ + {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, + +/* 2x00 Series */ + {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, + +/* 2x30 Series */ + {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, + +/* 6x35 Series */ + {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, + +/* 105 Series */ + {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, + {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, + +/* 135 Series */ + {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, + {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, + + {0} +}; +MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); + +static struct pci_driver iwl_driver = { + .name = DRV_NAME, + .id_table = iwl_hw_card_ids, + .probe = iwl_pci_probe, + .remove = __devexit_p(iwl_pci_remove), + .driver.pm = IWL_PM_OPS, +}; + static int __init iwl_init(void) { @@ -3746,10 +4017,12 @@ static int __init iwl_init(void) return ret; } - ret = iwl_pci_register_driver(); - - if (ret) + ret = pci_register_driver(&iwl_driver); + if (ret) { + pr_err("Unable to initialize PCI module\n"); goto error_register; + } + return ret; error_register: @@ -3759,7 +4032,7 @@ static int __init iwl_init(void) static void __exit iwl_exit(void) { - iwl_pci_unregister_driver(); + pci_unregister_driver(&iwl_driver); iwlagn_rate_control_unregister(); } @@ -3801,47 +4074,3 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); - -/* - * set bt_coex_active to true, uCode will do kill/defer - * every time the priority line is asserted (BT is sending signals on the - * priority line in the PCIx). - * set bt_coex_active to false, uCode will ignore the BT activity and - * perform the normal operation - * - * User might experience transmit issue on some platform due to WiFi/BT - * co-exist problem. The possible behaviors are: - * Able to scan and finding all the available AP - * Not able to associate with any AP - * On those platforms, WiFi communication can be restored by set - * "bt_coex_active" module parameter to "false" - * - * default: bt_coex_active = true (BT_COEX_ENABLE) - */ -module_param_named(bt_coex_active, iwlagn_mod_params.bt_coex_active, - bool, S_IRUGO); -MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); - -module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO); -MODULE_PARM_DESC(led_mode, "0=system default, " - "1=On(RF On)/Off(RF Off), 2=blinking (default: 0)"); - -module_param_named(power_save, iwlagn_mod_params.power_save, - bool, S_IRUGO); -MODULE_PARM_DESC(power_save, - "enable WiFi power management (default: disable)"); - -module_param_named(power_level, iwlagn_mod_params.power_level, - int, S_IRUGO); -MODULE_PARM_DESC(power_level, - "default power save level (range from 1 - 5, default: 1)"); - -/* - * For now, keep using power level 1 instead of automatically - * adjusting ... - */ -module_param_named(no_sleep_autoadjust, iwlagn_mod_params.no_sleep_autoadjust, - bool, S_IRUGO); -MODULE_PARM_DESC(no_sleep_autoadjust, - "don't automatically adjust sleep level " - "according to maximum network latency (default: true)"); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h index 6d5584ae5ebf..d1716844002e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -125,18 +125,10 @@ irqreturn_t iwl_isr_ict(int irq, void *data); static inline void iwl_synchronize_irq(struct iwl_priv *priv) { /* wait to make sure we flush pending tasklet*/ - synchronize_irq(priv->bus.irq); + synchronize_irq(priv->pci_dev->irq); tasklet_kill(&priv->irq_tasklet); } -static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) -{ - hdr->op_code = cmd; - hdr->first_group = 0; - hdr->groups_num = 1; - hdr->data_valid = 1; -} - int iwl_prepare_card_hw(struct iwl_priv *priv); int iwlagn_start_device(struct iwl_priv *priv); @@ -169,7 +161,7 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv); int iwlagn_run_init_ucode(struct iwl_priv *priv); int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, struct fw_img *image, - enum iwlagn_ucode_type ucode_type); + int subtype, int alternate_subtype); /* lib */ void iwl_check_abort_status(struct iwl_priv *priv, @@ -351,9 +343,6 @@ extern int iwl_alive_start(struct iwl_priv *priv); /* svtool */ #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); -extern int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, - struct netlink_callback *cb, - void *data, int len); extern void iwl_testmode_init(struct iwl_priv *priv); extern void iwl_testmode_cleanup(struct iwl_priv *priv); #else @@ -363,13 +352,6 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) return -ENOSYS; } static inline -int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, - struct netlink_callback *cb, - void *data, int len) -{ - return -ENOSYS; -} -static inline void iwl_testmode_init(struct iwl_priv *priv) { } @@ -379,8 +361,4 @@ void iwl_testmode_cleanup(struct iwl_priv *priv) } #endif -int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops, - struct iwl_cfg *cfg); -void __devexit iwl_remove(struct iwl_priv * priv); - #endif /* __iwl_agn_h__ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h index 8a2edf8dce32..6ee5f1aa555c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -384,6 +384,18 @@ struct iwl_tx_ant_config_cmd { #define UCODE_VALID_OK cpu_to_le32(0x1) +enum iwlagn_ucode_subtype { + UCODE_SUBTYPE_REGULAR = 0, + UCODE_SUBTYPE_REGULAR_NEW = 1, + UCODE_SUBTYPE_INIT = 9, + + /* + * Not a valid subtype, the ucode has just a u8, so + * we can use something > 0xff for this value. + */ + UCODE_SUBTYPE_NONE_LOADED = 0x100, +}; + /** * REPLY_ALIVE = 0x1 (response only, not a command) * @@ -972,26 +984,15 @@ struct iwl_rem_sta_cmd { u8 reserved2[2]; } __packed; - -/* WiFi queues mask */ -#define IWL_SCD_BK_MSK cpu_to_le32(BIT(0)) -#define IWL_SCD_BE_MSK cpu_to_le32(BIT(1)) -#define IWL_SCD_VI_MSK cpu_to_le32(BIT(2)) -#define IWL_SCD_VO_MSK cpu_to_le32(BIT(3)) -#define IWL_SCD_MGMT_MSK cpu_to_le32(BIT(3)) - -/* PAN queues mask */ -#define IWL_PAN_SCD_BK_MSK cpu_to_le32(BIT(4)) -#define IWL_PAN_SCD_BE_MSK cpu_to_le32(BIT(5)) -#define IWL_PAN_SCD_VI_MSK cpu_to_le32(BIT(6)) -#define IWL_PAN_SCD_VO_MSK cpu_to_le32(BIT(7)) -#define IWL_PAN_SCD_MGMT_MSK cpu_to_le32(BIT(7)) -#define IWL_PAN_SCD_MULTICAST_MSK cpu_to_le32(BIT(8)) - +#define IWL_TX_FIFO_BK_MSK cpu_to_le32(BIT(0)) +#define IWL_TX_FIFO_BE_MSK cpu_to_le32(BIT(1)) +#define IWL_TX_FIFO_VI_MSK cpu_to_le32(BIT(2)) +#define IWL_TX_FIFO_VO_MSK cpu_to_le32(BIT(3)) #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) #define IWL_DROP_SINGLE 0 -#define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN)) +#define IWL_DROP_SELECTED 1 +#define IWL_DROP_ALL 2 /* * REPLY_TXFIFO_FLUSH = 0x1e(command and response) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c index cde725326c32..5416b12cd931 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c @@ -43,6 +43,27 @@ #include "iwl-helpers.h" #include "iwl-agn.h" + +/* + * set bt_coex_active to true, uCode will do kill/defer + * every time the priority line is asserted (BT is sending signals on the + * priority line in the PCIx). + * set bt_coex_active to false, uCode will ignore the BT activity and + * perform the normal operation + * + * User might experience transmit issue on some platform due to WiFi/BT + * co-exist problem. The possible behaviors are: + * Able to scan and finding all the available AP + * Not able to associate with any AP + * On those platforms, WiFi communication can be restored by set + * "bt_coex_active" module parameter to "false" + * + * default: bt_coex_active = true (BT_COEX_ENABLE) + */ +bool bt_coex_active = true; +module_param(bt_coex_active, bool, S_IRUGO); +MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); + u32 iwl_debug_level; const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -143,7 +164,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; - if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (priv->cfg->sku & IWL_SKU_N) iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, IEEE80211_BAND_5GHZ); @@ -153,7 +174,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) sband->bitrates = rates; sband->n_bitrates = IWL_RATE_COUNT_LEGACY; - if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (priv->cfg->sku & IWL_SKU_N) iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, IEEE80211_BAND_2GHZ); @@ -208,12 +229,12 @@ int iwlcore_init_geos(struct iwl_priv *priv) priv->tx_power_next = max_tx_power; if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && - priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) { - char buf[32]; - priv->bus.ops->get_hw_id(&priv->bus, buf, sizeof(buf)); + priv->cfg->sku & IWL_SKU_A) { IWL_INFO(priv, "Incorrectly detected BG card as ABG. " - "Please send your %s to maintainer.\n", buf); - priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; + "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n", + priv->pci_dev->device, + priv->pci_dev->subsystem_device); + priv->cfg->sku &= ~IWL_SKU_A; } IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", @@ -997,6 +1018,8 @@ void iwl_apm_stop(struct iwl_priv *priv) int iwl_apm_init(struct iwl_priv *priv) { int ret = 0; + u16 lctl; + IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); /* @@ -1025,7 +1048,27 @@ int iwl_apm_init(struct iwl_priv *priv) iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); - priv->bus.ops->apm_config(&priv->bus); + /* + * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition. + * Check if BIOS (or OS) enabled L1-ASPM on this device. + * If so (likely), disable L0S, so device moves directly L0->L1; + * costs negligible amount of power savings. + * If not (unlikely), enable L0S, so there is at least some + * power savings, even without L1. + */ + lctl = iwl_pcie_link_ctl(priv); + if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == + PCI_CFG_LINK_CTRL_VAL_L1_EN) { + /* L1-ASPM enabled; disable(!) L0S */ + iwl_set_bit(priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); + } else { + /* L1-ASPM disabled; enable(!) L0S */ + iwl_clear_bit(priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); + } /* Configure analog phase-lock-loop before activating to D0A */ if (priv->cfg->base_params->pll_cfg_val) @@ -1136,7 +1179,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) .kill_cts_mask = 0, }; - if (!iwlagn_mod_params.bt_coex_active) + if (!bt_coex_active) bt_cmd.flags = BT_COEX_DISABLE; else bt_cmd.flags = BT_COEX_ENABLE; @@ -1926,8 +1969,11 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, #ifdef CONFIG_PM -int iwl_suspend(struct iwl_priv *priv) +int iwl_pci_suspend(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); + struct iwl_priv *priv = pci_get_drvdata(pdev); + /* * This function is called when system goes into suspend state * mac80211 will call iwl_mac_stop() from the mac80211 suspend function @@ -1940,10 +1986,18 @@ int iwl_suspend(struct iwl_priv *priv) return 0; } -int iwl_resume(struct iwl_priv *priv) +int iwl_pci_resume(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); + struct iwl_priv *priv = pci_get_drvdata(pdev); bool hw_rfkill = false; + /* + * We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ + pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + iwl_enable_interrupts(priv); if (!(iwl_read32(priv, CSR_GP_CNTRL) & @@ -1960,4 +2014,13 @@ int iwl_resume(struct iwl_priv *priv) return 0; } +const struct dev_pm_ops iwl_pm_ops = { + .suspend = iwl_pci_suspend, + .resume = iwl_pci_resume, + .freeze = iwl_pci_suspend, + .thaw = iwl_pci_resume, + .poweroff = iwl_pci_suspend, + .restore = iwl_pci_resume, +}; + #endif /* CONFIG_PM */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index adf9f9b2efb5..05ea88aa76e3 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -76,8 +76,17 @@ struct iwl_cmd; #define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" #define DRV_AUTHOR "" +#define IWL_PCI_DEVICE(dev, subdev, cfg) \ + .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ + .driver_data = (kernel_ulong_t)&(cfg) + #define TIME_UNIT 1024 +#define IWL_SKU_G 0x1 +#define IWL_SKU_A 0x2 +#define IWL_SKU_N 0x8 + #define IWL_CMD(x) case x: return #x struct iwl_hcmd_ops { @@ -137,6 +146,10 @@ struct iwl_lib_ops { /* temperature */ struct iwl_temp_ops temp_ops; + + int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); + void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); + }; /* NIC specific ops */ @@ -160,11 +173,6 @@ struct iwl_mod_params { int restart_fw; /* def: 1 = restart firmware */ bool plcp_check; /* def: true = enable plcp health check */ bool ack_check; /* def: false = disable ack health check */ - bool bt_coex_active; /* def: true = enable bt coex */ - int led_mode; /* def: 0 = system default */ - bool no_sleep_autoadjust; /* def: true = disable autoadjust */ - bool power_save; /* def: false = disable power save */ - int power_level; /* def: 1 = power level */ }; /* @@ -281,7 +289,7 @@ struct iwl_cfg { const unsigned int ucode_api_min; u8 valid_tx_ant; u8 valid_rx_ant; - u16 sku; + unsigned int sku; u16 eeprom_ver; u16 eeprom_calib_ver; const struct iwl_ops *ops; @@ -472,14 +480,36 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); + +/***************************************************** + * PCI * + *****************************************************/ + +static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) +{ + int pos; + u16 pci_lnk_ctl; + pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP); + pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); + return pci_lnk_ctl; +} + void iwl_bg_watchdog(unsigned long data); u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval); __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, u32 addon, u32 beacon_interval); #ifdef CONFIG_PM -int iwl_suspend(struct iwl_priv *priv); -int iwl_resume(struct iwl_priv *priv); +int iwl_pci_suspend(struct device *device); +int iwl_pci_resume(struct device *device); +extern const struct dev_pm_ops iwl_pm_ops; + +#define IWL_PM_OPS (&iwl_pm_ops) + +#else /* !CONFIG_PM */ + +#define IWL_PM_OPS NULL + #endif /* !CONFIG_PM */ /***************************************************** @@ -594,6 +624,7 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) priv->cfg->bt_params->advanced_bt_coexist; } +extern bool bt_coex_active; extern bool bt_siso_mode; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debug.h b/trunk/drivers/net/wireless/iwlwifi/iwl-debug.h index eb95d1a37487..2824ccbcc1fc 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -32,10 +32,10 @@ struct iwl_priv; extern u32 iwl_debug_level; -#define IWL_ERR(p, f, a...) dev_err(p->bus.ops->get_dev(&p->bus), f, ## a) -#define IWL_WARN(p, f, a...) dev_warn(p->bus.ops->get_dev(&p->bus), f, ## a) -#define IWL_INFO(p, f, a...) dev_info(p->bus.ops->get_dev(&p->bus), f, ## a) -#define IWL_CRIT(p, f, a...) dev_crit(p->bus.ops->get_dev(&p->bus), f, ## a) +#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a) +#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a) +#define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a) +#define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a) #define iwl_print_hex_error(priv, p, len) \ do { \ @@ -125,13 +125,13 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) /* 0x00000F00 - 0x00000100 */ #define IWL_DL_POWER (1 << 8) #define IWL_DL_TEMP (1 << 9) -/* reserved (1 << 10) */ +#define IWL_DL_NOTIF (1 << 10) #define IWL_DL_SCAN (1 << 11) /* 0x0000F000 - 0x00001000 */ #define IWL_DL_ASSOC (1 << 12) #define IWL_DL_DROP (1 << 13) -/* reserved (1 << 14) */ -#define IWL_DL_COEX (1 << 15) +#define IWL_DL_TXPOWER (1 << 14) +#define IWL_DL_AP (1 << 15) /* 0x000F0000 - 0x00010000 */ #define IWL_DL_FW (1 << 16) #define IWL_DL_RF_KILL (1 << 17) @@ -171,10 +171,12 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) #define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a) #define IWL_DEBUG_DROP_LIMIT(p, f, a...) \ IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) -#define IWL_DEBUG_COEX(p, f, a...) IWL_DEBUG(p, IWL_DL_COEX, f, ## a) +#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a) +#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a) #define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) #define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a) +#define IWL_DEBUG_NOTIF(p, f, a...) IWL_DEBUG(p, IWL_DL_NOTIF, f, ## a) #define IWL_DEBUG_ASSOC(p, f, a...) \ IWL_DEBUG(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) #define IWL_DEBUG_ASSOC_LIMIT(p, f, a...) \ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 6f9ebae8ca06..0e6a04b739ad 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -227,7 +227,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, /* default is to dump the entire data segment */ if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { priv->dbgfs_sram_offset = 0x800000; - if (priv->ucode_type == IWL_UCODE_INIT) + if (priv->ucode_type == UCODE_SUBTYPE_INIT) priv->dbgfs_sram_len = priv->ucode_init.data.len; else priv->dbgfs_sram_len = priv->ucode_rt.data.len; @@ -2493,7 +2493,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, if (iwl_is_rfkill(priv)) return -EFAULT; - iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); + priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL); return count; } @@ -2693,7 +2693,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); - DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); + if (priv->cfg->ops->lib->dev_txfifo_flush) + DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h index 8ec04f20c96a..c8de236c141b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -48,8 +48,6 @@ #include "iwl-agn-rs.h" #include "iwl-agn-tt.h" -#define DRV_NAME "iwlagn" - struct iwl_tx_queue; /* CT-KILL constants */ @@ -1170,63 +1168,14 @@ enum iwl_scan_type { IWL_SCAN_OFFCH_TX, }; -enum iwlagn_ucode_type { - IWL_UCODE_NONE, - IWL_UCODE_REGULAR, - IWL_UCODE_INIT, - IWL_UCODE_WOWLAN, -}; - #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL struct iwl_testmode_trace { - u32 buff_size; - u32 total_size; - u32 num_chunks; u8 *cpu_addr; u8 *trace_addr; dma_addr_t dma_addr; bool trace_enabled; }; #endif - -struct iwl_bus; - -/** - * struct iwl_bus_ops - bus specific operations - - * @get_pm_support: must returns true if the bus can go to sleep - * @apm_config: will be called during the config of the APM configuration - * @set_drv_data: set the priv pointer to the bus layer - * @get_dev: returns the device struct - * @get_irq: returns the irq number - * @get_hw_id: prints the hw_id in the provided buffer - * @write8: write a byte to register at offset ofs - * @write32: write a dword to register at offset ofs - * @wread32: read a dword at register at offset ofs - */ -struct iwl_bus_ops { - bool (*get_pm_support)(struct iwl_bus *bus); - void (*apm_config)(struct iwl_bus *bus); - void (*set_drv_data)(struct iwl_bus *bus, void *priv); - struct device *(*get_dev)(const struct iwl_bus *bus); - unsigned int (*get_irq)(const struct iwl_bus *bus); - void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len); - void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); - void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); - u32 (*read32)(struct iwl_bus *bus, u32 ofs); -}; - -struct iwl_bus { - /* pointer to bus specific struct */ - void *bus_specific; - - /* Common data to all buses */ - struct iwl_priv *priv; /* driver's context */ - struct device *dev; - struct iwl_bus_ops *ops; - unsigned int irq; -}; - struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1294,14 +1243,17 @@ struct iwl_priv { spinlock_t reg_lock; /* protect hw register access */ struct mutex mutex; - struct iwl_bus bus; /* bus specific data */ + /* basic pci-network driver stuff */ + struct pci_dev *pci_dev; + + /* pci hardware address support */ + void __iomem *hw_base; /* microcode/device supports multiple contexts */ u8 valid_contexts; /* command queue number */ u8 cmd_queue; - u8 last_sync_cmd_id; /* max number of station keys */ u8 sta_key_max_num; @@ -1318,7 +1270,7 @@ struct iwl_priv { struct fw_img ucode_rt; struct fw_img ucode_init; - enum iwlagn_ucode_type ucode_type; + enum iwlagn_ucode_subtype ucode_type; u8 ucode_write_complete; /* the image write is complete */ char firmware_name[25]; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 768d0ee276f7..47a56bc1cd12 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -834,28 +834,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, return NULL; } - -void iwl_rf_config(struct iwl_priv *priv) -{ - u16 radio_cfg; - - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); - - /* write radio config values to register */ - if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) | - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", - EEPROM_RF_CFG_TYPE_MSK(radio_cfg), - EEPROM_RF_CFG_STEP_MSK(radio_cfg), - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - } else - WARN_ON(1); - - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); -} diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 804f910c651e..c960c6fa009b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -110,10 +110,12 @@ enum { }; /* SKU Capabilities */ -#define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) -#define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) +/* 5000 and up */ +#define EEPROM_SKU_CAP_BAND_POS (4) +#define EEPROM_SKU_CAP_BAND_SELECTION \ + (3 << EEPROM_SKU_CAP_BAND_POS) #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) -#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) +#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) /* *regulatory* channel data format in eeprom, one for each channel. @@ -162,12 +164,16 @@ struct iwl_eeprom_enhanced_txpwr { s8 mimo3_max; } __packed; -/* calibration */ +/* 5000 Specific */ +#define EEPROM_5000_TX_POWER_VERSION (4) +#define EEPROM_5000_EEPROM_VERSION (0x11A) + +/* 5000 and up calibration */ #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) -/* temperature */ -#define EEPROM_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) +/* 5000 temperature */ +#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) /* agn links */ #define EEPROM_LINK_HOST (2*0x64) @@ -199,10 +205,6 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ -/* 5000 Specific */ -#define EEPROM_5000_TX_POWER_VERSION (4) -#define EEPROM_5000_EEPROM_VERSION (0x11A) - /* 5050 Specific */ #define EEPROM_5050_TX_POWER_VERSION (4) #define EEPROM_5050_EEPROM_VERSION (0x21E) @@ -268,13 +270,13 @@ extern const u8 iwl_eeprom_band_1[14]; /* General */ #define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ -#define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ #define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ #define EEPROM_VERSION (2*0x44) /* 2 bytes */ #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ +#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ @@ -309,6 +311,5 @@ void iwl_free_channel_map(struct iwl_priv *priv); const struct iwl_channel_info *iwl_get_channel_info( const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); -void iwl_rf_config(struct iwl_priv *priv); #endif /* __iwl_eeprom_h__ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/trunk/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 7cdb1ec73b54..76f996623140 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -181,16 +181,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); - if (test_and_set_bit(STATUS_HCMD_ACTIVE, &priv->status)) { - IWL_ERR(priv, "STATUS_HCMD_ACTIVE already set while sending %s" - ". Previous SYNC cmdn is %s\n", - get_cmd_string(cmd->id), - get_cmd_string(priv->last_sync_cmd_id)); - WARN_ON(1); - } else { - priv->last_sync_cmd_id = cmd->id; - } - + set_bit(STATUS_HCMD_ACTIVE, &priv->status); IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->id)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h b/trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h index 9d91552d13c1..41207a3645b8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -120,16 +120,7 @@ static inline void iwl_wake_any_queue(struct iwl_priv *priv, } } -#ifdef ieee80211_stop_queue -#undef ieee80211_stop_queue -#endif - #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue - -#ifdef ieee80211_wake_queue -#undef ieee80211_wake_queue -#endif - #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue static inline void iwl_disable_interrupts(struct iwl_priv *priv) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-io.h b/trunk/drivers/net/wireless/iwlwifi/iwl-io.h index c56eae74c3cd..869edc580ec6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-io.h @@ -38,18 +38,18 @@ static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val) { trace_iwlwifi_dev_iowrite8(priv, ofs, val); - priv->bus.ops->write8(&priv->bus, ofs, val); + iowrite8(val, priv->hw_base + ofs); } static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) { trace_iwlwifi_dev_iowrite32(priv, ofs, val); - priv->bus.ops->write32(&priv->bus, ofs, val); + iowrite32(val, priv->hw_base + ofs); } static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs) { - u32 val = priv->bus.ops->read32(&priv->bus, ofs); + u32 val = ioread32(priv->hw_base + ofs); trace_iwlwifi_dev_ioread32(priv, ofs, val); return val; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-led.c b/trunk/drivers/net/wireless/iwlwifi/iwl-led.c index ff08da099754..7c23beb49d7c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-led.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -38,9 +40,14 @@ #include "iwl-dev.h" #include "iwl-core.h" -#include "iwl-agn.h" #include "iwl-io.h" +/* default: IWL_LED_BLINK(0) using blinking index table */ +static int led_mode; +module_param(led_mode, int, S_IRUGO); +MODULE_PARM_DESC(led_mode, "0=system default, " + "1=On(RF On)/Off(RF Off), 2=blinking"); + /* Throughput OFF time(ms) ON time (ms) * >300 25 25 * >200 to 300 40 40 @@ -174,7 +181,7 @@ static int iwl_led_blink_set(struct led_classdev *led_cdev, void iwl_leds_init(struct iwl_priv *priv) { - int mode = iwlagn_mod_params.led_mode; + int mode = led_mode; int ret; if (mode == IWL_LED_DEFAULT) @@ -202,8 +209,7 @@ void iwl_leds_init(struct iwl_priv *priv) break; } - ret = led_classdev_register(priv->bus.dev, - &priv->led); + ret = led_classdev_register(&priv->pci_dev->dev, &priv->led); if (ret) { kfree(priv->led.name); return; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-pci.c b/trunk/drivers/net/wireless/iwlwifi/iwl-pci.c deleted file mode 100644 index 7328fbff7f7b..000000000000 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-pci.c +++ /dev/null @@ -1,571 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -#include -#include - -#include "iwl-pci.h" -#include "iwl-agn.h" -#include "iwl-core.h" -#include "iwl-io.h" - -/* PCI registers */ -#define PCI_CFG_RETRY_TIMEOUT 0x041 -#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 -#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 - -struct iwl_pci_bus { - /* basic pci-network driver stuff */ - struct pci_dev *pci_dev; - - /* pci hardware address support */ - void __iomem *hw_base; -}; - -#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ - ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) - -#define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ - ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) - -static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus) -{ - int pos; - u16 pci_lnk_ctl; - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - pos = pci_find_capability(pci_dev, PCI_CAP_ID_EXP); - pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); - return pci_lnk_ctl; -} - -static bool iwl_pci_is_pm_supported(struct iwl_bus *bus) -{ - u16 lctl = iwl_pciexp_link_ctrl(bus); - - return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); -} - -static void iwl_pci_apm_config(struct iwl_bus *bus) -{ - /* - * HW bug W/A for instability in PCIe bus L0S->L1 transition. - * Check if BIOS (or OS) enabled L1-ASPM on this device. - * If so (likely), disable L0S, so device moves directly L0->L1; - * costs negligible amount of power savings. - * If not (unlikely), enable L0S, so there is at least some - * power savings, even without L1. - */ - u16 lctl = iwl_pciexp_link_ctrl(bus); - - if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == - PCI_CFG_LINK_CTRL_VAL_L1_EN) { - /* L1-ASPM enabled; disable(!) L0S */ - iwl_set_bit(bus->priv, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - IWL_DEBUG_POWER(bus->priv, "L1 Enabled; Disabling L0S\n"); - } else { - /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(bus->priv, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - IWL_DEBUG_POWER(bus->priv, "L1 Disabled; Enabling L0S\n"); - } -} - -static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_priv) -{ - pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_priv); -} - -static struct device *iwl_pci_get_dev(const struct iwl_bus *bus) -{ - return &(IWL_BUS_GET_PCI_DEV(bus)->dev); -} - -static unsigned int iwl_pci_get_irq(const struct iwl_bus *bus) -{ - return IWL_BUS_GET_PCI_DEV(bus)->irq; -} - -static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], - int buf_len) -{ - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - snprintf(buf, buf_len, "PCI ID: 0x%04X:0x%04X", pci_dev->device, - pci_dev->subsystem_device); -} - -static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) -{ - iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); -} - -static void iwl_pci_write32(struct iwl_bus *bus, u32 ofs, u32 val) -{ - iowrite32(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); -} - -static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) -{ - u32 val = ioread32(IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); - return val; -} - -static struct iwl_bus_ops pci_ops = { - .get_pm_support = iwl_pci_is_pm_supported, - .apm_config = iwl_pci_apm_config, - .set_drv_data = iwl_pci_set_drv_data, - .get_dev = iwl_pci_get_dev, - .get_irq = iwl_pci_get_irq, - .get_hw_id = iwl_pci_get_hw_id, - .write8 = iwl_pci_write8, - .write32 = iwl_pci_write32, - .read32 = iwl_pci_read32, -}; - -#define IWL_PCI_DEVICE(dev, subdev, cfg) \ - .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ - .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ - .driver_data = (kernel_ulong_t)&(cfg) - -/* Hardware specific file defines the PCI IDs table for that hardware module */ -static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { - {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ - -/* 5300 Series WiFi */ - {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ - -/* 5350 Series WiFi/WiMax */ - {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ - -/* 5150 Series Wifi/WiMax */ - {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ - - {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ - {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ - -/* 6x00 Series */ - {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, - {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, - {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, - {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, - -/* 6x05 Series */ - {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, - -/* 6x30 Series */ - {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)}, - {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)}, - -/* 6x50 WiFi/WiMax Series */ - {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, - {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, - {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, - -/* 6150 WiFi/WiMax Series */ - {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, - -/* 1000 Series WiFi */ - {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, - {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, - -/* 100 Series WiFi */ - {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, - {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, - {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)}, - -/* 130 Series WiFi */ - {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, - {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, - -/* 2x00 Series */ - {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, - -/* 2x30 Series */ - {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, - {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, - {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, - -/* 6x35 Series */ - {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, - {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, - {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, - -/* 105 Series */ - {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, - {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, - {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, - -/* 135 Series */ - {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, - {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, - {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, - - {0} -}; -MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); - -static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); - struct iwl_pci_bus *bus; - u8 rev_id; - u16 pci_cmd; - int err; - - bus = kzalloc(sizeof(*bus), GFP_KERNEL); - if (!bus) { - pr_err("Couldn't allocate iwl_pci_bus"); - err = -ENOMEM; - goto out_no_pci; - } - - bus->pci_dev = pdev; - - /* W/A - seems to solve weird behavior. We need to remove this if we - * don't want to stay in L1 all the time. This wastes a lot of power */ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM); - - if (pci_enable_device(pdev)) { - err = -ENODEV; - goto out_no_pci; - } - - pci_set_master(pdev); - - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); - if (err) { - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, - DMA_BIT_MASK(32)); - /* both attempts failed: */ - if (err) { - pr_err("No suitable DMA available.\n"); - goto out_pci_disable_device; - } - } - - err = pci_request_regions(pdev, DRV_NAME); - if (err) { - pr_err("pci_request_regions failed"); - goto out_pci_disable_device; - } - - bus->hw_base = pci_iomap(pdev, 0, 0); - if (!bus->hw_base) { - pr_err("pci_iomap failed"); - err = -ENODEV; - goto out_pci_release_regions; - } - - pr_info("pci_resource_len = 0x%08llx\n", - (unsigned long long) pci_resource_len(pdev, 0)); - pr_info("pci_resource_base = %p\n", bus->hw_base); - - pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); - pr_info("HW Revision ID = 0x%X\n", rev_id); - - /* We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state */ - pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - - err = pci_enable_msi(pdev); - if (err) { - pr_err("pci_enable_msi failed"); - goto out_iounmap; - } - - /* TODO: Move this away, not needed if not MSI */ - /* enable rfkill interrupt: hw bug w/a */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); - if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { - pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); - } - - err = iwl_probe((void *) bus, &pci_ops, cfg); - if (err) - goto out_disable_msi; - return 0; - -out_disable_msi: - pci_disable_msi(pdev); -out_iounmap: - pci_iounmap(pdev, bus->hw_base); -out_pci_release_regions: - pci_set_drvdata(pdev, NULL); - pci_release_regions(pdev); -out_pci_disable_device: - pci_disable_device(pdev); -out_no_pci: - kfree(bus); - return err; -} - -static void iwl_pci_down(void *bus) -{ - struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus; - - pci_disable_msi(pci_bus->pci_dev); - pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base); - pci_release_regions(pci_bus->pci_dev); - pci_disable_device(pci_bus->pci_dev); - pci_set_drvdata(pci_bus->pci_dev, NULL); - - kfree(pci_bus); -} - -static void __devexit iwl_pci_remove(struct pci_dev *pdev) -{ - struct iwl_priv *priv = pci_get_drvdata(pdev); - - /* This can happen if probe failed */ - if (unlikely(!priv)) - return; - - iwl_remove(priv); - - iwl_pci_down(IWL_BUS_GET_PCI_BUS(&priv->bus)); -} - -#ifdef CONFIG_PM - -static int iwl_pci_suspend(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct iwl_priv *priv = pci_get_drvdata(pdev); - - return iwl_suspend(priv); -} - -static int iwl_pci_resume(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct iwl_priv *priv = pci_get_drvdata(pdev); - - /* - * We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state. - */ - pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - - return iwl_resume(priv); -} - -static const struct dev_pm_ops iwl_dev_pm_ops = { - .suspend = iwl_pci_suspend, - .resume = iwl_pci_resume, - .freeze = iwl_pci_suspend, - .thaw = iwl_pci_resume, - .poweroff = iwl_pci_suspend, - .restore = iwl_pci_resume, -}; - -#define IWL_PM_OPS (&iwl_dev_pm_ops) - -#else - -#define IWL_PM_OPS NULL - -#endif - -static struct pci_driver iwl_pci_driver = { - .name = DRV_NAME, - .id_table = iwl_hw_card_ids, - .probe = iwl_pci_probe, - .remove = __devexit_p(iwl_pci_remove), - .driver.pm = IWL_PM_OPS, -}; - -int __must_check iwl_pci_register_driver(void) -{ - int ret; - ret = pci_register_driver(&iwl_pci_driver); - if (ret) - pr_err("Unable to initialize PCI module\n"); - - return ret; -} - -void iwl_pci_unregister_driver(void) -{ - pci_unregister_driver(&iwl_pci_driver); -} diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-pci.h b/trunk/drivers/net/wireless/iwlwifi/iwl-pci.h deleted file mode 100644 index 9396c7c8d6a4..000000000000 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-pci.h +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -#ifndef __iwl_pci_h__ -#define __iwl_pci_h__ - -int __must_check iwl_pci_register_driver(void); -void iwl_pci_unregister_driver(void); - -#endif diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-power.c b/trunk/drivers/net/wireless/iwlwifi/iwl-power.c index 565e57e48be8..595c930b28ae 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-power.c @@ -36,7 +36,6 @@ #include "iwl-eeprom.h" #include "iwl-dev.h" -#include "iwl-agn.h" #include "iwl-core.h" #include "iwl-io.h" #include "iwl-commands.h" @@ -51,6 +50,16 @@ * also use pre-defined power levels. */ +/* + * For now, keep using power level 1 instead of automatically + * adjusting ... + */ +bool no_sleep_autoadjust = true; +module_param(no_sleep_autoadjust, bool, S_IRUGO); +MODULE_PARM_DESC(no_sleep_autoadjust, + "don't automatically adjust sleep level " + "according to maximum network latency"); + /* * This defines the old power levels. They are still used by default * (level 1) and for thermal throttle (levels 3 through 5) @@ -245,7 +254,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, } } - if (priv->power_data.bus_pm) + if (priv->power_data.pci_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; else cmd->flags &= ~IWL_POWER_PCI_PM_MSK; @@ -260,7 +269,7 @@ static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv, { memset(cmd, 0, sizeof(*cmd)); - if (priv->power_data.bus_pm) + if (priv->power_data.pci_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); @@ -296,7 +305,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | IWL_POWER_FAST_PD; /* no use seeing frames for others */ - if (priv->power_data.bus_pm) + if (priv->power_data.pci_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; if (priv->cfg->base_params->shadow_reg_enable) @@ -358,15 +367,9 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, iwl_static_sleep_cmd(priv, cmd, priv->power_data.debug_sleep_level_override, dtimper); - else if (iwlagn_mod_params.no_sleep_autoadjust) { - if (iwlagn_mod_params.power_level > IWL_POWER_INDEX_1 && - iwlagn_mod_params.power_level <= IWL_POWER_INDEX_5) - iwl_static_sleep_cmd(priv, cmd, - iwlagn_mod_params.power_level, dtimper); - else - iwl_static_sleep_cmd(priv, cmd, - IWL_POWER_INDEX_1, dtimper); - } else + else if (no_sleep_autoadjust) + iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper); + else iwl_power_fill_sleep_cmd(priv, cmd, priv->hw->conf.dynamic_ps_timeout, priv->hw->conf.max_sleep_period); @@ -431,7 +434,9 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) { - priv->power_data.bus_pm = priv->bus.ops->get_pm_support(&priv->bus); + u16 lctl = iwl_pcie_link_ctl(priv); + + priv->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); priv->power_data.debug_sleep_level_override = -1; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-power.h b/trunk/drivers/net/wireless/iwlwifi/iwl-power.h index 5f7b720cf1a4..59635d784e27 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-power.h @@ -43,7 +43,7 @@ struct iwl_power_mgr { struct iwl_powertable_cmd sleep_cmd; struct iwl_powertable_cmd sleep_cmd_next; int debug_sleep_level_override; - bool bus_pm; + bool pci_pm; }; int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c index 3efa7066e987..b774517aa9fa 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/trunk/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 int iwl_rx_queue_alloc(struct iwl_priv *priv) { struct iwl_rx_queue *rxq = &priv->rxq; - struct device *dev = priv->bus.dev; + struct device *dev = &priv->pci_dev->dev; int i; spin_lock_init(&rxq->lock); @@ -213,7 +213,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) return 0; err_rb: - dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd, + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, rxq->bd_dma); err_bd: return -ENOMEM; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/trunk/drivers/net/wireless/iwlwifi/iwl-sv-open.c index c00aa5a1b8b8..69b7e6bf2d6f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -69,6 +69,7 @@ #include #include + #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-debug.h" @@ -100,11 +101,9 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, }, - [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, }, - [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, }, - }; /* @@ -180,21 +179,19 @@ void iwl_testmode_init(struct iwl_priv *priv) static void iwl_trace_cleanup(struct iwl_priv *priv) { - struct device *dev = priv->bus.dev; + struct device *dev = &priv->pci_dev->dev; if (priv->testmode_trace.trace_enabled) { if (priv->testmode_trace.cpu_addr && priv->testmode_trace.dma_addr) dma_free_coherent(dev, - priv->testmode_trace.total_size, + TRACE_TOTAL_SIZE, priv->testmode_trace.cpu_addr, priv->testmode_trace.dma_addr); priv->testmode_trace.trace_enabled = false; priv->testmode_trace.cpu_addr = NULL; priv->testmode_trace.trace_addr = NULL; priv->testmode_trace.dma_addr = 0; - priv->testmode_trace.buff_size = 0; - priv->testmode_trace.total_size = 0; } } @@ -397,7 +394,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, - IWL_UCODE_INIT); + UCODE_SUBTYPE_INIT, -1); if (status) IWL_DEBUG_INFO(priv, "Error loading init ucode: %d\n", status); @@ -411,7 +408,8 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_rt, - IWL_UCODE_REGULAR); + UCODE_SUBTYPE_REGULAR, + UCODE_SUBTYPE_REGULAR_NEW); if (status) { IWL_DEBUG_INFO(priv, "Error loading runtime ucode: %d\n", status); @@ -484,29 +482,16 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) struct iwl_priv *priv = hw->priv; struct sk_buff *skb; int status = 0; - struct device *dev = priv->bus.dev; + struct device *dev = &priv->pci_dev->dev; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: if (priv->testmode_trace.trace_enabled) return -EBUSY; - if (!tb[IWL_TM_ATTR_TRACE_SIZE]) - priv->testmode_trace.buff_size = TRACE_BUFF_SIZE_DEF; - else - priv->testmode_trace.buff_size = - nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]); - if (!priv->testmode_trace.buff_size) - return -EINVAL; - if (priv->testmode_trace.buff_size < TRACE_BUFF_SIZE_MIN || - priv->testmode_trace.buff_size > TRACE_BUFF_SIZE_MAX) - return -EINVAL; - - priv->testmode_trace.total_size = - priv->testmode_trace.buff_size + TRACE_BUFF_PADD; priv->testmode_trace.cpu_addr = dma_alloc_coherent(dev, - priv->testmode_trace.total_size, + TRACE_TOTAL_SIZE, &priv->testmode_trace.dma_addr, GFP_KERNEL); if (!priv->testmode_trace.cpu_addr) @@ -515,7 +500,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN( priv->testmode_trace.cpu_addr, 0x100); memset(priv->testmode_trace.trace_addr, 0x03B, - priv->testmode_trace.buff_size); + TRACE_BUFF_SIZE); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, sizeof(priv->testmode_trace.dma_addr) + 20); if (!skb) { @@ -533,14 +518,34 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) "Error sending msg : %d\n", status); } - priv->testmode_trace.num_chunks = - DIV_ROUND_UP(priv->testmode_trace.buff_size, - TRACE_CHUNK_SIZE); break; case IWL_TM_CMD_APP2DEV_END_TRACE: iwl_trace_cleanup(priv); break; + + case IWL_TM_CMD_APP2DEV_READ_TRACE: + if (priv->testmode_trace.trace_enabled && + priv->testmode_trace.trace_addr) { + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, + 20 + TRACE_BUFF_SIZE); + if (skb == NULL) { + IWL_DEBUG_INFO(priv, + "Error allocating memory\n"); + return -ENOMEM; + } + NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA, + TRACE_BUFF_SIZE, + priv->testmode_trace.trace_addr); + status = cfg80211_testmode_reply(skb); + if (status < 0) { + IWL_DEBUG_INFO(priv, + "Error sending msg : %d\n", status); + } + } else + return -EFAULT; + break; + default: IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n"); return -ENOSYS; @@ -555,37 +560,6 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) return -EMSGSIZE; } -static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, - struct sk_buff *skb, - struct netlink_callback *cb) -{ - struct iwl_priv *priv = hw->priv; - int idx, length; - - if (priv->testmode_trace.trace_enabled && - priv->testmode_trace.trace_addr) { - idx = cb->args[4]; - if (idx >= priv->testmode_trace.num_chunks) - return -ENOENT; - length = TRACE_CHUNK_SIZE; - if (((idx + 1) == priv->testmode_trace.num_chunks) && - (priv->testmode_trace.buff_size % TRACE_CHUNK_SIZE)) - length = priv->testmode_trace.buff_size % - TRACE_CHUNK_SIZE; - - NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length, - priv->testmode_trace.trace_addr + - (TRACE_CHUNK_SIZE * idx)); - idx++; - cb->args[4] = idx; - return 0; - } else - return -EFAULT; - - nla_put_failure: - return -ENOBUFS; -} - /* The testmode gnl message handler that takes the gnl message from the * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then * invoke the corresponding handlers. @@ -664,50 +638,3 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) mutex_unlock(&priv->mutex); return result; } - -int iwl_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, - struct netlink_callback *cb, - void *data, int len) -{ - struct nlattr *tb[IWL_TM_ATTR_MAX]; - struct iwl_priv *priv = hw->priv; - int result; - u32 cmd; - - if (cb->args[3]) { - /* offset by 1 since commands start at 0 */ - cmd = cb->args[3] - 1; - } else { - result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, - iwl_testmode_gnl_msg_policy); - if (result) { - IWL_DEBUG_INFO(priv, - "Error parsing the gnl message : %d\n", result); - return result; - } - - /* IWL_TM_ATTR_COMMAND is absolutely mandatory */ - if (!tb[IWL_TM_ATTR_COMMAND]) { - IWL_DEBUG_INFO(priv, - "Error finding testmode command type\n"); - return -ENOMSG; - } - cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); - cb->args[3] = cmd + 1; - } - - /* in case multiple accesses to the device happens */ - mutex_lock(&priv->mutex); - switch (cmd) { - case IWL_TM_CMD_APP2DEV_READ_TRACE: - IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); - result = iwl_testmode_trace_dump(hw, tb, skb, cb); - break; - default: - result = -EINVAL; - break; - } - - mutex_unlock(&priv->mutex); - return result; -} diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-testmode.h b/trunk/drivers/net/wireless/iwlwifi/iwl-testmode.h index 160911a3716a..a88085e9b361 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -166,8 +166,7 @@ enum iwl_tm_attr_t { * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address */ IWL_TM_ATTR_TRACE_ADDR, - IWL_TM_ATTR_TRACE_SIZE, - IWL_TM_ATTR_TRACE_DUMP, + IWL_TM_ATTR_TRACE_DATA, /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ, * The mandatory fields are: @@ -179,10 +178,8 @@ enum iwl_tm_attr_t { }; /* uCode trace buffer */ -#define TRACE_BUFF_SIZE_MAX 0x200000 -#define TRACE_BUFF_SIZE_MIN 0x20000 -#define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN +#define TRACE_BUFF_SIZE 0x20000 #define TRACE_BUFF_PADD 0x2000 -#define TRACE_CHUNK_SIZE (PAGE_SIZE - 1024) +#define TRACE_TOTAL_SIZE (TRACE_BUFF_SIZE + TRACE_BUFF_PADD) #endif diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c index fd8aee9972c1..1084fe0e8a86 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -128,6 +128,7 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, struct iwl_tfd *tfd) { + struct pci_dev *dev = priv->pci_dev; int i; int num_tbs; @@ -142,15 +143,15 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, /* Unmap tx_cmd */ if (num_tbs) - dma_unmap_single(priv->bus.dev, + pci_unmap_single(dev, dma_unmap_addr(meta, mapping), dma_unmap_len(meta, len), - DMA_BIDIRECTIONAL); + PCI_DMA_BIDIRECTIONAL); /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) - dma_unmap_single(priv->bus.dev, iwl_tfd_tb_get_addr(tfd, i), - iwl_tfd_tb_get_len(tfd, i), DMA_TO_DEVICE); + pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), + iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); } /** @@ -265,7 +266,7 @@ void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) { struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct device *dev = priv->bus.dev; + struct device *dev = &priv->pci_dev->dev; int i; iwl_tx_queue_unmap(priv, txq_id); @@ -309,10 +310,10 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) i = get_cmd_index(q, q->read_ptr); if (txq->meta[i].flags & CMD_MAPPED) { - dma_unmap_single(priv->bus.dev, + pci_unmap_single(priv->pci_dev, dma_unmap_addr(&txq->meta[i], mapping), dma_unmap_len(&txq->meta[i], len), - DMA_BIDIRECTIONAL); + PCI_DMA_BIDIRECTIONAL); txq->meta[i].flags = 0; } @@ -331,7 +332,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) void iwl_cmd_queue_free(struct iwl_priv *priv) { struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; - struct device *dev = priv->bus.dev; + struct device *dev = &priv->pci_dev->dev; int i; iwl_cmd_queue_unmap(priv); @@ -433,7 +434,7 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, static int iwl_tx_queue_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq, u32 id) { - struct device *dev = priv->bus.dev; + struct device *dev = &priv->pci_dev->dev; size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; /* Driver private data, only for Tx (not command) queues, @@ -455,7 +456,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); if (!txq->tfds) { - IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz); + IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); goto error; } txq->q.id = id; @@ -676,9 +677,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, priv->cmd_queue); - phys_addr = dma_map_single(priv->bus.dev, &out_cmd->hdr, copy_size, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) { + phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, + copy_size, PCI_DMA_BIDIRECTIONAL); + if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { idx = -ENOMEM; goto out; } @@ -698,9 +699,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) continue; if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) continue; - phys_addr = dma_map_single(priv->bus.dev, (void *)cmd->data[i], - cmd->len[i], DMA_TO_DEVICE); - if (dma_mapping_error(priv->bus.dev, phys_addr)) { + phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i], + cmd->len[i], PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) { iwlagn_unmap_tfd(priv, out_meta, &txq->tfds[q->write_ptr]); idx = -ENOMEM; diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.c b/trunk/drivers/net/wireless/libertas/if_sdio.c index 387786e1b394..224e9853c480 100644 --- a/trunk/drivers/net/wireless/libertas/if_sdio.c +++ b/trunk/drivers/net/wireless/libertas/if_sdio.c @@ -892,37 +892,6 @@ static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv) } -static struct mmc_host *reset_host; - -static void if_sdio_reset_card_worker(struct work_struct *work) -{ - /* - * The actual reset operation must be run outside of lbs_thread. This - * is because mmc_remove_host() will cause the device to be instantly - * destroyed, and the libertas driver then needs to end lbs_thread, - * leading to a deadlock. - * - * We run it in a workqueue totally independent from the if_sdio_card - * instance for that reason. - */ - - pr_info("Resetting card..."); - mmc_remove_host(reset_host); - mmc_add_host(reset_host); -} -static DECLARE_WORK(card_reset_work, if_sdio_reset_card_worker); - -static void if_sdio_reset_card(struct lbs_private *priv) -{ - struct if_sdio_card *card = priv->card; - - if (work_pending(&card_reset_work)) - return; - - reset_host = card->func->card->host; - schedule_work(&card_reset_work); -} - /*******************************************************************/ /* SDIO callbacks */ /*******************************************************************/ @@ -1096,7 +1065,6 @@ static int if_sdio_probe(struct sdio_func *func, priv->enter_deep_sleep = if_sdio_enter_deep_sleep; priv->exit_deep_sleep = if_sdio_exit_deep_sleep; priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup; - priv->reset_card = if_sdio_reset_card; sdio_claim_host(func); @@ -1333,8 +1301,6 @@ static void __exit if_sdio_exit_module(void) /* Set the flag as user is removing this module. */ user_rmmod = 1; - cancel_work_sync(&card_reset_work); - sdio_unregister_driver(&if_sdio_driver); lbs_deb_leave(LBS_DEB_SDIO); diff --git a/trunk/drivers/net/wireless/libertas/if_spi.c b/trunk/drivers/net/wireless/libertas/if_spi.c index d041bb2b5777..463352c890d7 100644 --- a/trunk/drivers/net/wireless/libertas/if_spi.c +++ b/trunk/drivers/net/wireless/libertas/if_spi.c @@ -1032,6 +1032,7 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) static int if_spi_init_card(struct if_spi_card *card) { struct lbs_private *priv = card->priv; + struct spi_device *spi = card->spi; int err, i; u32 scratch; const struct firmware *helper = NULL; @@ -1079,9 +1080,8 @@ static int if_spi_init_card(struct if_spi_card *card) "attached to SPI bus_num %d, chip_select %d. " "spi->max_speed_hz=%d\n", card->card_id, card->card_rev, - card->spi->master->bus_num, - card->spi->chip_select, - card->spi->max_speed_hz); + spi->master->bus_num, spi->chip_select, + spi->max_speed_hz); err = if_spi_prog_helper_firmware(card, helper); if (err) goto out; diff --git a/trunk/drivers/net/wireless/mwifiex/main.c b/trunk/drivers/net/wireless/mwifiex/main.c index 054a5c348a24..4f43443036f4 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.c +++ b/trunk/drivers/net/wireless/mwifiex/main.c @@ -26,6 +26,9 @@ const char driver_version[] = "mwifiex " VERSION " (%s) "; +struct mwifiex_adapter *g_adapter; +EXPORT_SYMBOL_GPL(g_adapter); + static struct mwifiex_bss_attr mwifiex_bss_sta[] = { {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0}, }; @@ -57,8 +60,7 @@ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { * proper cleanup before exiting. */ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, - struct mwifiex_drv_mode *drv_mode_ptr, - void **padapter) + struct mwifiex_drv_mode *drv_mode_ptr) { struct mwifiex_adapter *adapter; int i; @@ -67,7 +69,7 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, if (!adapter) return -ENOMEM; - *padapter = adapter; + g_adapter = adapter; adapter->card = card; /* Save interface specific operations in adapter */ @@ -322,7 +324,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) * and initializing the private structures. */ static int -mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter) +mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops) { int i; struct mwifiex_drv_mode *drv_mode_ptr; @@ -341,7 +343,7 @@ mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter) return -1; } - if (mwifiex_register(card, if_ops, drv_mode_ptr, padapter)) + if (mwifiex_register(card, if_ops, drv_mode_ptr)) return -1; return 0; @@ -853,11 +855,13 @@ mwifiex_add_card(void *card, struct semaphore *sem, if (down_interruptible(sem)) goto exit_sem_err; - if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) { + if (mwifiex_init_sw(card, if_ops)) { pr_err("%s: software init failed\n", __func__); goto err_init_sw; } + adapter = g_adapter; + adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; adapter->surprise_removed = false; init_waitqueue_head(&adapter->init_wait_q); diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h index db201cc1473b..57b183af72d7 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.h +++ b/trunk/drivers/net/wireless/mwifiex/main.h @@ -39,6 +39,7 @@ #include "fw.h" extern const char driver_version[]; +extern struct mwifiex_adapter *g_adapter; enum { MWIFIEX_ASYNC_CMD, diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.c b/trunk/drivers/net/wireless/mwifiex/sdio.c index 711fa689a95c..4327b6d099c8 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.c +++ b/trunk/drivers/net/wireless/mwifiex/sdio.c @@ -31,27 +31,10 @@ #define SDIO_VERSION "1.0" -/* The mwifiex_sdio_remove() callback function is called when - * user removes this module from kernel space or ejects - * the card from the slot. The driver handles these 2 cases - * differently. - * If the user is removing the module, the few commands (FUNC_SHUTDOWN, - * HS_CANCEL etc.) are sent to the firmware. - * If the card is removed, there is no need to send these command. - * - * The variable 'user_rmmod' is used to distinguish these two - * scenarios. This flag is initialized as FALSE in case the card - * is removed, and will be set to TRUE for module removal when - * module_exit function is called. - */ -static u8 user_rmmod; - static struct mwifiex_if_ops sdio_ops; static struct semaphore add_remove_card_sem; -static int mwifiex_sdio_resume(struct device *dev); - /* * SDIO probe. * @@ -110,36 +93,17 @@ static void mwifiex_sdio_remove(struct sdio_func *func) { struct sdio_mmc_card *card; - struct mwifiex_adapter *adapter; - int i; pr_debug("info: SDIO func num=%d\n", func->num); - card = sdio_get_drvdata(func); - if (!card) - return; - - adapter = card->adapter; - if (!adapter || !adapter->priv_num) - return; - - if (user_rmmod) { - if (adapter->is_suspended) - mwifiex_sdio_resume(adapter->dev); - - for (i = 0; i < adapter->priv_num; i++) - if ((GET_BSS_ROLE(adapter->priv[i]) == - MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) - mwifiex_deauthenticate(adapter->priv[i], NULL); - - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + if (func) { + card = sdio_get_drvdata(func); + if (card) { + mwifiex_remove_card(card->adapter, + &add_remove_card_sem); + kfree(card); + } } - - mwifiex_remove_card(card->adapter, &add_remove_card_sem); - kfree(card); } /* @@ -1732,9 +1696,6 @@ mwifiex_sdio_init_module(void) { sema_init(&add_remove_card_sem, 1); - /* Clear the flag in case user removes the card. */ - user_rmmod = 0; - return sdio_register_driver(&mwifiex_sdio); } @@ -1750,12 +1711,32 @@ mwifiex_sdio_init_module(void) static void mwifiex_sdio_cleanup_module(void) { - if (!down_interruptible(&add_remove_card_sem)) - up(&add_remove_card_sem); + struct mwifiex_adapter *adapter = g_adapter; + int i; + + if (down_interruptible(&add_remove_card_sem)) + goto exit_sem_err; + + if (!adapter || !adapter->priv_num) + goto exit; + + if (adapter->is_suspended) + mwifiex_sdio_resume(adapter->dev); + + for (i = 0; i < adapter->priv_num; i++) + if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && + adapter->priv[i]->media_connected) + mwifiex_deauthenticate(adapter->priv[i], NULL); + + if (!adapter->surprise_removed) + mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY), + MWIFIEX_FUNC_SHUTDOWN); - /* Set the flag as user is removing this module. */ - user_rmmod = 1; +exit: + up(&add_remove_card_sem); +exit_sem_err: sdio_unregister_driver(&mwifiex_sdio); } diff --git a/trunk/drivers/net/wireless/rtlwifi/base.c b/trunk/drivers/net/wireless/rtlwifi/base.c index bc13533a5418..fb5e43bd7c3c 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.c +++ b/trunk/drivers/net/wireless/rtlwifi/base.c @@ -523,7 +523,7 @@ static void _rtl_query_shortgi(struct ieee80211_hw *hw, mac->opmode == NL80211_IFTYPE_ADHOC) bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; - if (bw_40 && sgi_40) + if ((bw_40 == true) && sgi_40) tcb_desc->use_shortgi = true; else if ((bw_40 == false) && sgi_20) tcb_desc->use_shortgi = true; diff --git a/trunk/drivers/net/wireless/rtlwifi/core.c b/trunk/drivers/net/wireless/rtlwifi/core.c index 03ce69660b26..d2ec2535aa3c 100644 --- a/trunk/drivers/net/wireless/rtlwifi/core.c +++ b/trunk/drivers/net/wireless/rtlwifi/core.c @@ -335,8 +335,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) * before going offchannel, or dis-association or delete BA will * happen by AP */ - if (rtlpriv->mac80211.offchan_delay) { - rtlpriv->mac80211.offchan_delay = false; + if (rtlpriv->mac80211.offchan_deley) { + rtlpriv->mac80211.offchan_deley = false; mdelay(50); } rtlphy->current_channel = wide_chan; @@ -443,11 +443,11 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, sta_entry->wireless_mode = WIRELESS_MODE_G; if (sta->supp_rates[0] <= 0xf) sta_entry->wireless_mode = WIRELESS_MODE_B; - if (sta->ht_cap.ht_supported) + if (sta->ht_cap.ht_supported == true) sta_entry->wireless_mode = WIRELESS_MODE_N_24G; } else if (rtlhal->current_bandtype == BAND_ON_5G) { sta_entry->wireless_mode = WIRELESS_MODE_A; - if (sta->ht_cap.ht_supported) + if (sta->ht_cap.ht_supported == true) sta_entry->wireless_mode = WIRELESS_MODE_N_24G; } @@ -650,7 +650,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, ("BSS_CHANGED_HT\n")); rcu_read_lock(); - sta = get_sta(hw, vif, bss_conf->bssid); + sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); if (sta) { if (sta->ht_cap.ampdu_density > mac->current_ampdu_density) @@ -685,7 +685,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_network_type(hw, vif->type); rcu_read_lock(); - sta = get_sta(hw, vif, bss_conf->bssid); + sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); if (!sta) { rcu_read_unlock(); goto out; diff --git a/trunk/drivers/net/wireless/rtlwifi/core.h b/trunk/drivers/net/wireless/rtlwifi/core.h index f02824a3b747..4b247db2861d 100644 --- a/trunk/drivers/net/wireless/rtlwifi/core.h +++ b/trunk/drivers/net/wireless/rtlwifi/core.h @@ -30,8 +30,6 @@ #ifndef __RTL_CORE_H__ #define __RTL_CORE_H__ -#include - #define RTL_SUPPORTED_FILTERS \ (FIF_PROMISC_IN_BSS | \ FIF_ALLMULTI | FIF_CONTROL | \ diff --git a/trunk/drivers/net/wireless/rtlwifi/efuse.c b/trunk/drivers/net/wireless/rtlwifi/efuse.c index 3fc21f60bb04..0b562322f138 100644 --- a/trunk/drivers/net/wireless/rtlwifi/efuse.c +++ b/trunk/drivers/net/wireless/rtlwifi/efuse.c @@ -382,7 +382,7 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) } } - if (wordchanged) + if (wordchanged == true) hdr_num++; } @@ -453,7 +453,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) base = offset * 8; for (i = 0; i < 8; i++) { - if (first_pg) { + if (first_pg == true) { word_en &= ~(BIT(i / 2)); @@ -505,7 +505,7 @@ void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - if (rtlefuse->autoload_failflag) + if (rtlefuse->autoload_failflag == true) memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); else @@ -690,7 +690,7 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } } - if (dataempty) { + if (dataempty == true) { *readstate = PG_STATE_DATA; } else { *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index ad39af462f87..fc44005b0d53 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -581,7 +581,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) fc = rtl_get_fc(skb); if (ieee80211_is_nullfunc(fc)) { if (ieee80211_has_pm(fc)) { - rtlpriv->mac80211.offchan_delay = true; + rtlpriv->mac80211.offchan_deley = true; rtlpriv->psc.state_inap = 1; } else { rtlpriv->psc.state_inap = 0; @@ -626,56 +626,6 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) } } -static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ieee80211_rx_status rx_status) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct ieee80211_hdr *hdr = rtl_get_hdr(skb); - __le16 fc = rtl_get_fc(skb); - bool unicast = false; - struct sk_buff *uskb = NULL; - u8 *pdata; - - - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); - - if (is_broadcast_ether_addr(hdr->addr1)) { - ;/*TODO*/ - } else if (is_multicast_ether_addr(hdr->addr1)) { - ;/*TODO*/ - } else { - unicast = true; - rtlpriv->stats.rxbytesunicast += skb->len; - } - - rtl_is_special_data(hw, skb, false); - - if (ieee80211_is_data(fc)) { - rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); - - if (unicast) - rtlpriv->link_info.num_rx_inperiod++; - } - - /* for sw lps */ - rtl_swlps_beacon(hw, (void *)skb->data, skb->len); - rtl_recognize_peer(hw, (void *)skb->data, skb->len); - if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && - (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) && - (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc))) - return; - - if (unlikely(!rtl_action_proc(hw, skb, false))) - return; - - uskb = dev_alloc_skb(skb->len + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, skb->len); - memcpy(pdata, skb->data, skb->len); - - ieee80211_rx_irqsafe(hw, uskb); -} - static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -687,6 +637,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) u8 own; u8 tmp_one; u32 bufferaddress; + bool unicast = false; struct rtl_stats stats = { .signal = 0, @@ -703,63 +654,130 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) /*rx pkt */ struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ index]; - struct sk_buff *new_skb = NULL; own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false, HW_DESC_OWN); - /*wait data to be filled by hardware */ - if (own) + if (own) { + /*wait data to be filled by hardware */ break; + } else { + struct ieee80211_hdr *hdr; + __le16 fc; + struct sk_buff *new_skb = NULL; - rtlpriv->cfg->ops->query_rx_desc(hw, &stats, - &rx_status, - (u8 *) pdesc, skb); - - if (stats.crc || stats.hwerror) - goto done; + rtlpriv->cfg->ops->query_rx_desc(hw, &stats, + &rx_status, + (u8 *) pdesc, skb); - new_skb = dev_alloc_skb(rtlpci->rxbuffersize); - if (unlikely(!new_skb)) { - RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), - DBG_DMESG, - ("can't alloc skb for rx\n")); - goto done; - } + skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, + false, + HW_DESC_RXPKT_LEN)); + skb_reserve(skb, + stats.rx_drvinfo_size + stats.rx_bufshift); - pci_unmap_single(rtlpci->pdev, - *((dma_addr_t *) skb->cb), - rtlpci->rxbuffersize, - PCI_DMA_FROMDEVICE); + /* + *NOTICE This can not be use for mac80211, + *this is done in mac80211 code, + *if you done here sec DHCP will fail + *skb_trim(skb, skb->len - 4); + */ - skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false, - HW_DESC_RXPKT_LEN)); - skb_reserve(skb, stats.rx_drvinfo_size + stats.rx_bufshift); + hdr = rtl_get_hdr(skb); + fc = rtl_get_fc(skb); - /* - * NOTICE This can not be use for mac80211, - * this is done in mac80211 code, - * if you done here sec DHCP will fail - * skb_trim(skb, skb->len - 4); - */ + /* try for new buffer - if allocation fails, drop + * frame and reuse old buffer + */ + new_skb = dev_alloc_skb(rtlpci->rxbuffersize); + if (unlikely(!new_skb)) { + RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), + DBG_DMESG, + ("can't alloc skb for rx\n")); + goto done; + } + pci_unmap_single(rtlpci->pdev, + *((dma_addr_t *) skb->cb), + rtlpci->rxbuffersize, + PCI_DMA_FROMDEVICE); - _rtl_receive_one(hw, skb, rx_status); + if (!stats.crc && !stats.hwerror) { + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, + sizeof(rx_status)); + + if (is_broadcast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else if (is_multicast_ether_addr(hdr->addr1)) { + ;/*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += + skb->len; + } + + rtl_is_special_data(hw, skb, false); + + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_RX); + + if (unicast) + rtlpriv->link_info. + num_rx_inperiod++; + } + + /* for sw lps */ + rtl_swlps_beacon(hw, (void *)skb->data, + skb->len); + rtl_recognize_peer(hw, (void *)skb->data, + skb->len); + if ((rtlpriv->mac80211.opmode == + NL80211_IFTYPE_AP) && + (rtlpriv->rtlhal.current_bandtype == + BAND_ON_2_4G) && + (ieee80211_is_beacon(fc) || + ieee80211_is_probe_resp(fc))) { + dev_kfree_skb_any(skb); + } else { + if (unlikely(!rtl_action_proc(hw, skb, + false))) { + dev_kfree_skb_any(skb); + } else { + struct sk_buff *uskb = NULL; + u8 *pdata; + uskb = dev_alloc_skb(skb->len + + 128); + memcpy(IEEE80211_SKB_RXCB(uskb), + &rx_status, + sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, + skb->len); + memcpy(pdata, skb->data, + skb->len); + dev_kfree_skb_any(skb); + + ieee80211_rx_irqsafe(hw, uskb); + } + } + } else { + dev_kfree_skb_any(skb); + } - if (((rtlpriv->link_info.num_rx_inperiod + - rtlpriv->link_info.num_tx_inperiod) > 8) || - (rtlpriv->link_info.num_rx_inperiod > 2)) { - tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); - } + if (((rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod) > 8) || + (rtlpriv->link_info.num_rx_inperiod > 2)) { + tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); + } - dev_kfree_skb_any(skb); - skb = new_skb; + skb = new_skb; - rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; - *((dma_addr_t *) skb->cb) = + rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; + *((dma_addr_t *) skb->cb) = pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); + } done: bufferaddress = (*((dma_addr_t *)skb->cb)); tmp_one = 1; diff --git a/trunk/drivers/net/wireless/rtlwifi/ps.c b/trunk/drivers/net/wireless/rtlwifi/ps.c index a693feffbe72..d14c13d02177 100644 --- a/trunk/drivers/net/wireless/rtlwifi/ps.c +++ b/trunk/drivers/net/wireless/rtlwifi/ps.c @@ -79,18 +79,59 @@ EXPORT_SYMBOL(rtl_ps_disable_nic); bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, enum rf_pwrstate state_toset, - u32 changesource) + u32 changesource, bool protect_or_not) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool actionallowed = false; + u16 rfwait_cnt = 0; + /*protect_or_not = true; */ + + if (protect_or_not) + goto no_protect; + + /* + *Only one thread can change + *the RF state at one time, and others + *should wait to be executed. + */ + while (true) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (ppsc->rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("RF Change in progress!" + "Wait to set..state_toset(%d).\n", + state_toset)); + + /* Set RF after the previous action is done. */ + while (ppsc->rfchange_inprogress) { + rfwait_cnt++; + mdelay(1); + + /* + *Wait too long, return false to avoid + *to be stuck here. + */ + if (rfwait_cnt > 100) + return false; + } + } else { + ppsc->rfchange_inprogress = true; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + break; + } + } + +no_protect: switch (state_toset) { case ERFON: ppsc->rfoff_reason &= (~changesource); if ((changesource == RF_CHANGE_BY_HW) && - (ppsc->hwradiooff)) { + (ppsc->hwradiooff == true)) { ppsc->hwradiooff = false; } @@ -126,6 +167,12 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, if (actionallowed) rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); + if (!protect_or_not) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + } + return actionallowed; } EXPORT_SYMBOL(rtl_ps_set_rf_state); @@ -148,7 +195,8 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) } } - rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, RF_CHANGE_BY_IPS); + rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, + RF_CHANGE_BY_IPS, false); if (ppsc->inactive_pwrstate == ERFOFF && rtlhal->interface == INTF_PCI) { @@ -539,7 +587,7 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) } spin_lock(&rtlpriv->locks.lps_lock); - rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); + rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false); spin_unlock(&rtlpriv->locks.lps_lock); } @@ -573,8 +621,15 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) if (rtlpriv->link_info.busytraffic) return; + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (rtlpriv->psc.rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + return; + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); + spin_lock(&rtlpriv->locks.lps_lock); - rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); + rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false); spin_unlock(&rtlpriv->locks.lps_lock); if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && diff --git a/trunk/drivers/net/wireless/rtlwifi/ps.h b/trunk/drivers/net/wireless/rtlwifi/ps.h index 84628e6041c7..e3bf89840370 100644 --- a/trunk/drivers/net/wireless/rtlwifi/ps.h +++ b/trunk/drivers/net/wireless/rtlwifi/ps.h @@ -33,7 +33,8 @@ #define MAX_SW_LPS_SLEEP_INTV 5 bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, - enum rf_pwrstate state_toset, u32 changesource); + enum rf_pwrstate state_toset, u32 changesource, + bool protect_or_not); bool rtl_ps_enable_nic(struct ieee80211_hw *hw); bool rtl_ps_disable_nic(struct ieee80211_hw *hw); void rtl_ips_nic_off(struct ieee80211_hw *hw); diff --git a/trunk/drivers/net/wireless/rtlwifi/rc.c b/trunk/drivers/net/wireless/rtlwifi/rc.c index 539df66dce0a..30da68a77786 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rc.c +++ b/trunk/drivers/net/wireless/rtlwifi/rc.c @@ -200,7 +200,7 @@ static void rtl_tx_status(void *ppriv, if (sta) { /* Check if aggregation has to be enabled for this tid */ sta_entry = (struct rtl_sta_info *) sta->drv_priv; - if ((sta->ht_cap.ht_supported) && + if ((sta->ht_cap.ht_supported == true) && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { if (ieee80211_is_data_qos(fc)) { u8 tid = rtl_get_tid(skb); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index a00774e7090d..97183829b9be 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -474,7 +474,7 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) { struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - if (mac->act_scanning) + if (mac->act_scanning == true) return; if (mac->link_state >= MAC80211_LINKED) @@ -670,7 +670,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; int i; bool is2t = IS_92C_SERIAL(rtlhal->version); - s8 txpwr_level[2] = {0, 0}; + u8 txpwr_level[2] = {0, 0}; u8 ofdm_min_index = 6, rf; rtlpriv->dm.txpower_trackinginit = true; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index bc6ae9dcf940..944f55e9d316 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -488,7 +488,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_CORRECT_TSF:{ u8 btype_ibss = ((u8 *) (val))[0]; - if (btype_ibss) + if (btype_ibss == true) _rtl92ce_stop_tx_beacon(hw); _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) _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); - if (btype_ibss) + if (btype_ibss == true) _rtl92ce_resume_tx_beacon(hw); break; @@ -1121,7 +1121,7 @@ void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) if (rtlpriv->psc.rfpwr_state != ERFON) return; - if (check_bssid) { + if (check_bssid == true) { reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (®_rcr)); @@ -1585,7 +1585,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->autoload_failflag = false; } - if (rtlefuse->autoload_failflag) + if (rtlefuse->autoload_failflag == true) return; for (i = 0; i < 6; i += 2) { @@ -1994,7 +1994,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; - if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { + if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, ("GPIOChangeRF - HW Radio ON, RF ON\n")); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 28a1a707d09c..9dd1ed7b6422 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -84,7 +84,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; case LED_PIN_LED0: ledcfg &= 0xf0; - if (pcipriv->ledctl.led_opendrain) + if (pcipriv->ledctl.led_opendrain == true) rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(1) | BIT(5) | BIT(6))); else diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index d3b01e6023ba..90d0f2cf3b27 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -76,7 +76,7 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, if (rtlefuse->eeprom_regulatory != 0) turbo_scanoff = true; - if (mac->act_scanning) { + if (mac->act_scanning == true) { tx_agc[RF90_PATH_A] = 0x3f3f3f3f; tx_agc[RF90_PATH_B] = 0x3f3f3f3f; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 230bbe900d8d..2492cc234c03 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -225,7 +225,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct phy_sts_cck_8192s_t *cck_buf; - s8 rx_pwr_all = 0, rx_pwr[4]; + s8 rx_pwr_all, rx_pwr[4]; u8 evm, pwdb_all, rf_rx_num = 0; u8 i, max_spatial_stream; u32 rssi, total_rssi = 0; @@ -678,7 +678,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, GET_RX_DESC_PAGGR(pdesc)); rx_status->mactime = GET_RX_DESC_TSFL(pdesc); - if (phystatus) { + if (phystatus == true) { p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + stats->rx_bufshift); @@ -927,7 +927,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) { - if (istx) { + if (istx == true) { switch (desc_name) { case HW_DESC_OWN: wmb(); @@ -968,7 +968,7 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) { u32 ret = 0; - if (istx) { + if (istx == true) { switch (desc_name) { case HW_DESC_OWN: ret = GET_TX_DESC_OWN(p_desc); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 2b34764fbf73..52e2af58c1ed 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -520,7 +520,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); rtlefuse->autoload_failflag = false; } - if (rtlefuse->autoload_failflag) + if (rtlefuse->autoload_failflag == true) return; for (i = 0; i < 6; i += 2) { usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; @@ -1594,7 +1594,7 @@ static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw, default: break; } - if (filterout_non_associated_bssid) { + if (filterout_non_associated_bssid == true) { if (IS_NORMAL_CHIP(rtlhal->version)) { switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: @@ -2155,7 +2155,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_CORRECT_TSF:{ u8 btype_ibss = ((u8 *) (val))[0]; - if (btype_ibss) + if (btype_ibss == true) _rtl92cu_stop_tx_beacon(hw); _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); 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) rtl_write_dword(rtlpriv, REG_TSFTR + 4, (u32)((mac->tsf >> 32) & 0xffffffff)); _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); - if (btype_ibss) + if (btype_ibss == true) _rtl92cu_resume_tx_beacon(hw); break; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/led.c index 2ff9d8314e7b..332c74348a69 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/led.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/led.c @@ -82,7 +82,7 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; case LED_PIN_LED0: ledcfg &= 0xf0; - if (usbpriv->ledctl.led_opendrain) + if (usbpriv->ledctl.led_opendrain == true) rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(1) | BIT(5) | BIT(6))); else diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 1e851aae58db..c7576ec4744e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -82,7 +82,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, (rtlefuse->external_pa)) turbo_scanoff = true; } - if (mac->act_scanning) { + if (mac->act_scanning == true) { tx_agc[RF90_PATH_A] = 0x3f3f3f3f; tx_agc[RF90_PATH_B] = 0x3f3f3f3f; if (turbo_scanoff) { diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 906e7aa55bc3..3a92ba3c4a1e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -342,7 +342,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, (u8)GET_RX_DESC_RX_MCS(pdesc), (bool)GET_RX_DESC_PAGGR(pdesc)); rx_status->mactime = GET_RX_DESC_TSFL(pdesc); - if (phystatus) { + if (phystatus == true) { p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, p_drvinfo); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 4203a8531ca0..609c7ec7e66a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -452,7 +452,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) if (rtlpriv->psc.rfpwr_state != ERFON) return; - if (digtable.backoff_enable_flag) + if (digtable.backoff_enable_flag == true) rtl92s_backoff_enable_flag(hw); else digtable.backoff_val = DM_DIG_BACKOFF; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 13da7b3c0202..35dd12d0dcf3 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -516,7 +516,7 @@ static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw) mdelay(10); /* check GPIO3 */ - u1tmp = rtl_read_byte(rtlpriv, GPIO_IN_SE); + u1tmp = rtl_read_byte(rtlpriv, GPIO_IN); retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF; return retval; @@ -994,8 +994,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT; rtlpriv->psc.rfpwr_state = ERFON; - /* FIXME: check spinlocks if this block is uncommented */ - rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason); + rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason, true); } else { /* gpio radio on/off is out of adapter start */ if (rtlpriv->psc.hwradiooff == false) { @@ -1106,7 +1105,7 @@ void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) if (rtlpriv->psc.rfpwr_state != ERFON) return; - if (check_bssid) { + if (check_bssid == true) { reg_rcr |= (RCR_CBSSID); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); } else if (check_bssid == false) { @@ -1652,7 +1651,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->autoload_failflag = false; } - if (rtlefuse->autoload_failflag) + if (rtlefuse->autoload_failflag == true) return; _rtl8192se_get_IC_Inferiority(hw); @@ -2302,7 +2301,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) rfpwr_toset = _rtl92se_rf_onoff_detect(hw); - if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { + if ((ppsc->hwradiooff == true) && (rfpwr_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, ("RFKILL-HW Radio ON, RF ON\n")); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/led.c index e3fe7c90ebf4..6d4f66616680 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -90,7 +90,7 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; case LED_PIN_LED0: ledcfg &= 0xf0; - if (pcipriv->ledctl.led_opendrain) + if (pcipriv->ledctl.led_opendrain == true) rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1))); else rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3))); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 81a5aa4370cf..7ee2daccd7d5 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -1416,7 +1416,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) break; case FW_CMD_HIGH_PWR_ENABLE: if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || - rtlpriv->dm.dynamic_txpower_enable) + (rtlpriv->dm.dynamic_txpower_enable == true)) break; /* CCA threshold */ @@ -1608,7 +1608,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) fw_cmdmap &= ~FW_DIG_ENABLE_CTL; if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || - rtlpriv->dm.dynamic_txpower_enable) + (rtlpriv->dm.dynamic_txpower_enable == true)) fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; if ((digtable.dig_ext_port_stage == diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/reg.h index ea32ef2d4098..0116eaddbfac 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/reg.h @@ -248,8 +248,12 @@ #define PSTIME 0x02E0 #define TIMER0 0x02E4 #define TIMER1 0x02E8 -#define GPIO_IN_SE 0x02EC +#define GPIO_CTRL 0x02EC +#define GPIO_IN 0x02EC +#define GPIO_OUT 0x02ED #define GPIO_IO_SEL 0x02EE +#define GPIO_MOD 0x02EF +#define GPIO_INTCTRL 0x02F0 #define MAC_PINMUX_CFG 0x02F1 #define LEDCFG 0x02F2 #define PHY_REG 0x02F3 diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index c6e3a4ca42f9..1d3a48330399 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -410,7 +410,7 @@ void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel) (rtlefuse->eeprom_regulatory != 0))) dont_inc_cck_or_turboscanoff = true; - if (mac->act_scanning) { + if (mac->act_scanning == true) { txagc = 0x3f; if (dont_inc_cck_or_turboscanoff) txagc = pwrlevel; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index cffe30851f79..d509cf6a1e4d 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -661,7 +661,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc); - if (phystatus) { + if (phystatus == true) { p_drvinfo = (struct rx_fwinfo *)(skb->data + stats->rx_bufshift); _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc, @@ -900,7 +900,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) { - if (istx) { + if (istx == true) { switch (desc_name) { case HW_DESC_OWN: wmb(); @@ -941,7 +941,7 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) { u32 ret = 0; - if (istx) { + if (istx == true) { switch (desc_name) { case HW_DESC_OWN: ret = GET_TX_DESC_OWN(desc); diff --git a/trunk/drivers/net/wireless/rtlwifi/wifi.h b/trunk/drivers/net/wireless/rtlwifi/wifi.h index c54cda5ce22a..9d003e0864f5 100644 --- a/trunk/drivers/net/wireless/rtlwifi/wifi.h +++ b/trunk/drivers/net/wireless/rtlwifi/wifi.h @@ -938,7 +938,7 @@ struct rtl_mac { int n_channels; int n_bitrates; - bool offchan_delay; + bool offchan_deley; /*filters */ u32 rx_conf; @@ -1983,7 +1983,7 @@ static inline u16 rtl_get_tid(struct sk_buff *skb) static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - const u8 *bssid) + u8 *bssid) { return ieee80211_find_sta(vif, bssid); } diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_chip.h b/trunk/drivers/net/wireless/zd1211rw/zd_chip.h index 117c4123943c..4be7c3b5b265 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_chip.h @@ -21,8 +21,6 @@ #ifndef _ZD_CHIP_H #define _ZD_CHIP_H -#include - #include "zd_rf.h" #include "zd_usb.h" diff --git a/trunk/drivers/ssb/driver_chipcommon_pmu.c b/trunk/drivers/ssb/driver_chipcommon_pmu.c index a7aef47bf739..305ade7825f7 100644 --- a/trunk/drivers/ssb/driver_chipcommon_pmu.c +++ b/trunk/drivers/ssb/driver_chipcommon_pmu.c @@ -417,9 +417,9 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc) u32 min_msk = 0, max_msk = 0; unsigned int i; const struct pmu_res_updown_tab_entry *updown_tab = NULL; - unsigned int updown_tab_size = 0; + unsigned int updown_tab_size; const struct pmu_res_depend_tab_entry *depend_tab = NULL; - unsigned int depend_tab_size = 0; + unsigned int depend_tab_size; switch (bus->chip_id) { case 0x4312: diff --git a/trunk/include/linux/bcma/bcma.h b/trunk/include/linux/bcma/bcma.h index 3895aeb494a3..6ff080eac0b2 100644 --- a/trunk/include/linux/bcma/bcma.h +++ b/trunk/include/linux/bcma/bcma.h @@ -244,7 +244,6 @@ void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value) } extern bool bcma_core_is_enabled(struct bcma_device *core); -extern void bcma_core_disable(struct bcma_device *core, u32 flags); extern int bcma_core_enable(struct bcma_device *core, u32 flags); #endif /* LINUX_BCMA_H_ */ diff --git a/trunk/include/linux/bcma/bcma_driver_pci.h b/trunk/include/linux/bcma/bcma_driver_pci.h index 3871b668caf9..b7e191cf00ec 100644 --- a/trunk/include/linux/bcma/bcma_driver_pci.h +++ b/trunk/include/linux/bcma/bcma_driver_pci.h @@ -85,7 +85,5 @@ struct bcma_drv_pci { #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) extern void bcma_core_pci_init(struct bcma_drv_pci *pc); -extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, - struct bcma_device *core, bool enable); #endif /* LINUX_BCMA_DRIVER_PCI_H_ */ diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index 120f102814b6..3b31ec95dd8e 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -1708,14 +1708,6 @@ enum ieee80211_ampdu_mlme_action { * any error unless this callback returned a negative error code. * The callback can sleep. * - * @cancel_hw_scan: Ask the low-level tp cancel the active hw scan. - * The driver should ask the hardware to cancel the scan (if possible), - * but the scan will be completed only after the driver will call - * ieee80211_scan_completed(). - * This callback is needed for wowlan, to prevent enqueueing a new - * scan_work after the low-level driver was already suspended. - * The callback can sleep. - * * @sched_scan_start: Ask the hardware to start scanning repeatedly at * specific intervals. The driver must call the * ieee80211_sched_scan_results() function whenever it finds results. @@ -1908,8 +1900,6 @@ struct ieee80211_ops { u32 iv32, u16 *phase1key); int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); - void (*cancel_hw_scan)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); int (*sched_scan_start)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *req, @@ -2929,16 +2919,6 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, enum nl80211_cqm_rssi_threshold_event rssi_event, gfp_t gfp); -/** - * ieee80211_get_operstate - get the operstate of the vif - * - * @vif: &struct ieee80211_vif pointer from the add_interface callback. - * - * The driver might need to know the operstate of the net_device - * (specifically, whether the link is IF_OPER_UP after resume) - */ -unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif); - /** * ieee80211_chswitch_done - Complete channel switch process * @vif: &struct ieee80211_vif pointer from the add_interface callback. diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index dff9d76fe790..49f890bce312 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -846,13 +846,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) if (!sk) goto clean; - chan = l2cap_chan_create(sk); - if (!chan) { - l2cap_sock_kill(sk); - goto clean; - } - - l2cap_pi(sk)->chan = chan; + chan = l2cap_pi(sk)->chan; write_lock_bh(&conn->chan_lock); @@ -2339,14 +2333,6 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd if (!sk) goto response; - chan = l2cap_chan_create(sk); - if (!chan) { - l2cap_sock_kill(sk); - goto response; - } - - l2cap_pi(sk)->chan = chan; - write_lock_bh(&conn->chan_lock); /* Check if we already have channel with that dcid */ @@ -2359,6 +2345,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd hci_conn_hold(conn->hcon); + chan = l2cap_pi(sk)->chan; + l2cap_sock_init(sk, parent); bacpy(&bt_sk(sk)->src, conn->src); bacpy(&bt_sk(sk)->dst, conn->dst); diff --git a/trunk/net/bluetooth/l2cap_sock.c b/trunk/net/bluetooth/l2cap_sock.c index ab81894c6677..2f4fd5751a46 100644 --- a/trunk/net/bluetooth/l2cap_sock.c +++ b/trunk/net/bluetooth/l2cap_sock.c @@ -853,6 +853,7 @@ static struct proto l2cap_proto = { struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) { struct sock *sk; + struct l2cap_chan *chan; sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto); if (!sk) @@ -869,6 +870,14 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, g sk->sk_protocol = proto; sk->sk_state = BT_OPEN; + chan = l2cap_chan_create(sk); + if (!chan) { + l2cap_sock_kill(sk); + return NULL; + } + + l2cap_pi(sk)->chan = chan; + return sk; } @@ -876,7 +885,6 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, int kern) { struct sock *sk; - struct l2cap_chan *chan; BT_DBG("sock %p", sock); @@ -895,14 +903,6 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, if (!sk) return -ENOMEM; - chan = l2cap_chan_create(sk); - if (!chan) { - l2cap_sock_kill(sk); - return -ENOMEM; - } - - l2cap_pi(sk)->chan = chan; - l2cap_sock_init(sk, NULL); return 0; } diff --git a/trunk/net/mac80211/driver-ops.h b/trunk/net/mac80211/driver-ops.h index 0e7e4268ddf6..eebf7a67daf7 100644 --- a/trunk/net/mac80211/driver-ops.h +++ b/trunk/net/mac80211/driver-ops.h @@ -218,16 +218,6 @@ static inline int drv_hw_scan(struct ieee80211_local *local, return ret; } -static inline void drv_cancel_hw_scan(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata) -{ - might_sleep(); - - trace_drv_cancel_hw_scan(local, sdata); - local->ops->cancel_hw_scan(&local->hw, &sdata->vif); - trace_drv_return_void(local); -} - static inline int drv_sched_scan_start(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, diff --git a/trunk/net/mac80211/driver-trace.h b/trunk/net/mac80211/driver-trace.h index 3cb6795e926d..ed9edcbd9aa5 100644 --- a/trunk/net/mac80211/driver-trace.h +++ b/trunk/net/mac80211/driver-trace.h @@ -460,12 +460,6 @@ DEFINE_EVENT(local_sdata_evt, drv_hw_scan, TP_ARGS(local, sdata) ); -DEFINE_EVENT(local_sdata_evt, drv_cancel_hw_scan, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata), - TP_ARGS(local, sdata) -); - DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata), diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index 56c24cabf26d..421eaa6b0c2b 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -965,10 +965,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->u.ibss.mtx); - sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; - memset(sdata->u.ibss.bssid, 0, ETH_ALEN); - sdata->u.ibss.ssid_len = 0; - active_ibss = ieee80211_sta_active_ibss(sdata); if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { @@ -1003,6 +999,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) kfree_skb(skb); skb_queue_purge(&sdata->skb_queue); + memset(sdata->u.ibss.bssid, 0, ETH_ALEN); + sdata->u.ibss.ssid_len = 0; del_timer_sync(&sdata->u.ibss.timer); diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index faca5033f061..456cccf26b51 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -232,6 +232,9 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); } + ieee80211_stop_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CSA); + /* channel_type change automatically detected */ ieee80211_hw_config(local, 0); @@ -245,6 +248,9 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, rcu_read_unlock(); } + ieee80211_wake_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CSA); + ht_opmode = le16_to_cpu(hti->operation_mode); /* if bss configuration changed store the new one */ @@ -2206,7 +2212,6 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) add_timer(&ifmgd->chswitch_timer); ieee80211_sta_reset_beacon_monitor(sdata); ieee80211_restart_sta_timer(sdata); - ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.monitor_work); } #endif @@ -2653,10 +2658,3 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); } EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); - -unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif) -{ - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); - return sdata->dev->operstate; -} -EXPORT_SYMBOL(ieee80211_get_operstate); diff --git a/trunk/net/mac80211/pm.c b/trunk/net/mac80211/pm.c index 67839eb90cc1..730778a2c90c 100644 --- a/trunk/net/mac80211/pm.c +++ b/trunk/net/mac80211/pm.c @@ -6,28 +6,6 @@ #include "driver-ops.h" #include "led.h" -/* return value indicates whether the driver should be further notified */ -static bool ieee80211_quiesce(struct ieee80211_sub_if_data *sdata) -{ - switch (sdata->vif.type) { - case NL80211_IFTYPE_STATION: - ieee80211_sta_quiesce(sdata); - return true; - case NL80211_IFTYPE_ADHOC: - ieee80211_ibss_quiesce(sdata); - return true; - case NL80211_IFTYPE_MESH_POINT: - ieee80211_mesh_quiesce(sdata); - return true; - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_MONITOR: - /* don't tell driver about this */ - return false; - default: - return true; - } -} - int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { struct ieee80211_local *local = hw_to_local(hw); @@ -76,10 +54,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) local->quiescing = false; return err; } - list_for_each_entry(sdata, &local->interfaces, list) { - cancel_work_sync(&sdata->work); - ieee80211_quiesce(sdata); - } goto suspend; } @@ -108,8 +82,23 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) list_for_each_entry(sdata, &local->interfaces, list) { cancel_work_sync(&sdata->work); - if (!ieee80211_quiesce(sdata)) + switch(sdata->vif.type) { + case NL80211_IFTYPE_STATION: + ieee80211_sta_quiesce(sdata); + break; + case NL80211_IFTYPE_ADHOC: + ieee80211_ibss_quiesce(sdata); + break; + case NL80211_IFTYPE_MESH_POINT: + ieee80211_mesh_quiesce(sdata); + break; + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_MONITOR: + /* don't tell driver about this */ continue; + default: + break; + } if (!ieee80211_sdata_running(sdata)) continue; diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index 1758b463c583..58ffa7d069c7 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -821,8 +821,10 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, */ void ieee80211_scan_cancel(struct ieee80211_local *local) { + bool abortscan; + /* - * We are canceling software scan, or deferred scan that was not + * We are only canceling software scan, or deferred scan that was not * yet really started (see __ieee80211_start_scan ). * * Regarding hardware scan: @@ -834,30 +836,23 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) * - we can not cancel scan_work since driver can schedule it * by ieee80211_scan_completed(..., true) to finish scan * - * Hence we only call the cancel_hw_scan() callback, but the low-level - * driver is still responsible for calling ieee80211_scan_completed() - * after the scan was completed/aborted. + * Hence low lever driver is responsible for canceling HW scan. */ mutex_lock(&local->mtx); - if (!local->scan_req) - goto out; - - if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { - if (local->ops->cancel_hw_scan) - drv_cancel_hw_scan(local, local->scan_sdata); - goto out; + abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); + if (abortscan) { + /* + * The scan is canceled, but stop work from being pending. + * + * If the work is currently running, it must be blocked on + * the mutex, but we'll set scan_sdata = NULL and it'll + * simply exit once it acquires the mutex. + */ + cancel_delayed_work(&local->scan_work); + /* and clean up */ + __ieee80211_scan_completed(&local->hw, true, false); } - - /* - * If the work is currently running, it must be blocked on - * the mutex, but we'll set scan_sdata = NULL and it'll - * simply exit once it acquires the mutex. - */ - cancel_delayed_work(&local->scan_work); - /* and clean up */ - __ieee80211_scan_completed(&local->hw, true, false); -out: mutex_unlock(&local->mtx); } diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 05e3fb889d77..d3fe2d237485 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -1276,9 +1276,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) if (ieee80211_sdata_running(sdata)) ieee80211_enable_keys(sdata); -#ifdef CONFIG_PM wake_up: -#endif ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); diff --git a/trunk/net/wireless/mlme.c b/trunk/net/wireless/mlme.c index 3633ab6af184..493b939970cd 100644 --- a/trunk/net/wireless/mlme.c +++ b/trunk/net/wireless/mlme.c @@ -170,9 +170,7 @@ void __cfg80211_send_deauth(struct net_device *dev, break; } if (wdev->authtry_bsses[i] && - memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, - ETH_ALEN) == 0 && - memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) == 0) { + memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { cfg80211_unhold_bss(wdev->authtry_bsses[i]); cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); wdev->authtry_bsses[i] = NULL; diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 10823e2b60ce..70cbc8ca371e 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -3406,11 +3406,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) i = 0; if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { - if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { + request->ssids[i].ssid_len = nla_len(attr); + if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) { err = -EINVAL; goto out_free; } - request->ssids[i].ssid_len = nla_len(attr); memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); i++; } @@ -3572,11 +3572,12 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { - if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { + request->ssids[i].ssid_len = nla_len(attr); + if (request->ssids[i].ssid_len > + IEEE80211_MAX_SSID_LEN) { err = -EINVAL; goto out_free; } - request->ssids[i].ssid_len = nla_len(attr); memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); i++;