提交 a5d5a914 编写于 作者: J John W. Linville
...@@ -309,11 +309,7 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, ...@@ -309,11 +309,7 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
u8 i; u8 i;
u32 val; u32 val;
if (ah->is_pciexpress != true) if (ah->is_pciexpress != true || ah->aspm_enabled != true)
return;
/* Do not touch SerDes registers */
if (ah->config.pcie_powersave_enable == 2)
return; return;
/* Nothing to do on restore for 11N */ /* Nothing to do on restore for 11N */
......
...@@ -519,11 +519,7 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, ...@@ -519,11 +519,7 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
int restore, int restore,
int power_off) int power_off)
{ {
if (ah->is_pciexpress != true) if (ah->is_pciexpress != true || ah->aspm_enabled != true)
return;
/* Do not touch SerDes registers */
if (ah->config.pcie_powersave_enable == 2)
return; return;
/* Nothing to do on restore for 11N */ /* Nothing to do on restore for 11N */
......
...@@ -318,6 +318,14 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) ...@@ -318,6 +318,14 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
} }
static void ath9k_hw_aspm_init(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
if (common->bus_ops->aspm_init)
common->bus_ops->aspm_init(common);
}
/* This should work for all families including legacy */ /* This should work for all families including legacy */
static bool ath9k_hw_chip_test(struct ath_hw *ah) static bool ath9k_hw_chip_test(struct ath_hw *ah)
{ {
...@@ -378,7 +386,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ...@@ -378,7 +386,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
ah->config.additional_swba_backoff = 0; ah->config.additional_swba_backoff = 0;
ah->config.ack_6mb = 0x0; ah->config.ack_6mb = 0x0;
ah->config.cwm_ignore_extcca = 0; ah->config.cwm_ignore_extcca = 0;
ah->config.pcie_powersave_enable = 0;
ah->config.pcie_clock_req = 0; ah->config.pcie_clock_req = 0;
ah->config.pcie_waen = 0; ah->config.pcie_waen = 0;
ah->config.analog_shiftreg = 1; ah->config.analog_shiftreg = 1;
...@@ -598,7 +605,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) ...@@ -598,7 +605,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
if (ah->is_pciexpress) if (ah->is_pciexpress)
ath9k_hw_configpcipowersave(ah, 0, 0); ath9k_hw_aspm_init(ah);
else else
ath9k_hw_disablepcie(ah); ath9k_hw_disablepcie(ah);
......
...@@ -219,7 +219,6 @@ struct ath9k_ops_config { ...@@ -219,7 +219,6 @@ struct ath9k_ops_config {
int additional_swba_backoff; int additional_swba_backoff;
int ack_6mb; int ack_6mb;
u32 cwm_ignore_extcca; u32 cwm_ignore_extcca;
u8 pcie_powersave_enable;
bool pcieSerDesWrite; bool pcieSerDesWrite;
u8 pcie_clock_req; u8 pcie_clock_req;
u32 pcie_waen; u32 pcie_waen;
...@@ -673,6 +672,7 @@ struct ath_hw { ...@@ -673,6 +672,7 @@ struct ath_hw {
bool sw_mgmt_crypto; bool sw_mgmt_crypto;
bool is_pciexpress; bool is_pciexpress;
bool aspm_enabled;
bool is_monitoring; bool is_monitoring;
bool need_an_top2_fixup; bool need_an_top2_fixup;
u16 tx_trig_level; u16 tx_trig_level;
...@@ -874,6 +874,7 @@ struct ath_bus_ops { ...@@ -874,6 +874,7 @@ struct ath_bus_ops {
bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
void (*bt_coex_prep)(struct ath_common *common); void (*bt_coex_prep)(struct ath_common *common);
void (*extn_synch_en)(struct ath_common *common); void (*extn_synch_en)(struct ath_common *common);
void (*aspm_init)(struct ath_common *common);
}; };
static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
......
...@@ -670,8 +670,10 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) ...@@ -670,8 +670,10 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
static void ath9k_init_txpower_limits(struct ath_softc *sc) static void ath9k_init_txpower_limits(struct ath_softc *sc)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath9k_channel *curchan = ah->curchan; struct ath9k_channel *curchan = ah->curchan;
ah->txchainmask = common->tx_chainmask;
if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/nl80211.h> #include <linux/nl80211.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci-aspm.h>
#include <linux/ath9k_platform.h> #include <linux/ath9k_platform.h>
#include "ath9k.h" #include "ath9k.h"
...@@ -115,12 +116,38 @@ static void ath_pci_extn_synch_enable(struct ath_common *common) ...@@ -115,12 +116,38 @@ static void ath_pci_extn_synch_enable(struct ath_common *common)
pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
} }
static void ath_pci_aspm_init(struct ath_common *common)
{
struct ath_softc *sc = (struct ath_softc *) common->priv;
struct ath_hw *ah = sc->sc_ah;
struct pci_dev *pdev = to_pci_dev(sc->dev);
struct pci_dev *parent;
int pos;
u8 aspm;
if (!pci_is_pcie(pdev))
return;
parent = pdev->bus->self;
if (WARN_ON(!parent))
return;
pos = pci_pcie_cap(parent);
pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
ah->aspm_enabled = true;
/* Initialize PCIe PM and SERDES registers. */
ath9k_hw_configpcipowersave(ah, 0, 0);
}
}
static const struct ath_bus_ops ath_pci_bus_ops = { static const struct ath_bus_ops ath_pci_bus_ops = {
.ath_bus_type = ATH_PCI, .ath_bus_type = ATH_PCI,
.read_cachesize = ath_pci_read_cachesize, .read_cachesize = ath_pci_read_cachesize,
.eeprom_read = ath_pci_eeprom_read, .eeprom_read = ath_pci_eeprom_read,
.bt_coex_prep = ath_pci_bt_coex_prep, .bt_coex_prep = ath_pci_bt_coex_prep,
.extn_synch_en = ath_pci_extn_synch_enable, .extn_synch_en = ath_pci_extn_synch_enable,
.aspm_init = ath_pci_aspm_init,
}; };
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
......
...@@ -1746,7 +1746,11 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -1746,7 +1746,11 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
} }
memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
/*
* We do not commit tx power settings while channel changing,
* do it now if tx power changed.
*/
iwl_legacy_set_tx_power(priv, priv->tx_power_next, false);
return 0; return 0;
} }
......
...@@ -1235,7 +1235,12 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c ...@@ -1235,7 +1235,12 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
iwl_legacy_print_rx_config_cmd(priv, ctx); iwl_legacy_print_rx_config_cmd(priv, ctx);
goto set_tx_power; /*
* We do not commit tx power settings while channel changing,
* do it now if tx power changed.
*/
iwl_legacy_set_tx_power(priv, priv->tx_power_next, false);
return 0;
} }
/* If we are currently associated and the new config requires /* If we are currently associated and the new config requires
...@@ -1315,7 +1320,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c ...@@ -1315,7 +1320,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
iwl4965_init_sensitivity(priv); iwl4965_init_sensitivity(priv);
set_tx_power:
/* If we issue a new RXON command which required a tune then we must /* If we issue a new RXON command which required a tune then we must
* send a new TXPOWER command or we won't be able to Tx any frames */ * send a new TXPOWER command or we won't be able to Tx any frames */
ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true);
......
...@@ -365,6 +365,7 @@ static struct iwl_base_params iwl5000_base_params = { ...@@ -365,6 +365,7 @@ static struct iwl_base_params iwl5000_base_params = {
.chain_noise_scale = 1000, .chain_noise_scale = 1000,
.wd_timeout = IWL_LONG_WD_TIMEOUT, .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.no_idle_support = true,
}; };
static struct iwl_ht_params iwl5000_ht_params = { static struct iwl_ht_params iwl5000_ht_params = {
.ht_greenfield_support = true, .ht_greenfield_support = true,
......
...@@ -135,6 +135,7 @@ struct iwl_mod_params { ...@@ -135,6 +135,7 @@ struct iwl_mod_params {
* @temperature_kelvin: temperature report by uCode in kelvin * @temperature_kelvin: temperature report by uCode in kelvin
* @max_event_log_size: size of event log buffer size for ucode event logging * @max_event_log_size: size of event log buffer size for ucode event logging
* @shadow_reg_enable: HW shadhow register bit * @shadow_reg_enable: HW shadhow register bit
* @no_idle_support: do not support idle mode
*/ */
struct iwl_base_params { struct iwl_base_params {
int eeprom_size; int eeprom_size;
...@@ -156,6 +157,7 @@ struct iwl_base_params { ...@@ -156,6 +157,7 @@ struct iwl_base_params {
bool temperature_kelvin; bool temperature_kelvin;
u32 max_event_log_size; u32 max_event_log_size;
const bool shadow_reg_enable; const bool shadow_reg_enable;
const bool no_idle_support;
}; };
/* /*
* @advanced_bt_coexist: support advanced bt coexist * @advanced_bt_coexist: support advanced bt coexist
......
...@@ -134,6 +134,7 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) ...@@ -134,6 +134,7 @@ static void iwl_pci_apm_config(struct iwl_bus *bus)
static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_data) static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_data)
{ {
bus->drv_data = drv_data; bus->drv_data = drv_data;
pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_data);
} }
static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[],
...@@ -454,8 +455,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -454,8 +455,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
} }
pci_set_drvdata(pdev, bus);
bus->dev = &pdev->dev; bus->dev = &pdev->dev;
bus->irq = pdev->irq; bus->irq = pdev->irq;
bus->ops = &pci_ops; bus->ops = &pci_ops;
...@@ -494,11 +493,12 @@ static void iwl_pci_down(struct iwl_bus *bus) ...@@ -494,11 +493,12 @@ static void iwl_pci_down(struct iwl_bus *bus)
static void __devexit iwl_pci_remove(struct pci_dev *pdev) static void __devexit iwl_pci_remove(struct pci_dev *pdev)
{ {
struct iwl_bus *bus = pci_get_drvdata(pdev); struct iwl_priv *priv = pci_get_drvdata(pdev);
void *bus_specific = priv->bus->bus_specific;
iwl_remove(bus->drv_data); iwl_remove(priv);
iwl_pci_down(bus); iwl_pci_down(bus_specific);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -506,20 +506,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) ...@@ -506,20 +506,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
static int iwl_pci_suspend(struct device *device) static int iwl_pci_suspend(struct device *device)
{ {
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
struct iwl_bus *bus = pci_get_drvdata(pdev); struct iwl_priv *priv = pci_get_drvdata(pdev);
/* Before you put code here, think about WoWLAN. You cannot check here /* Before you put code here, think about WoWLAN. You cannot check here
* whether WoWLAN is enabled or not, and your code will run even if * whether WoWLAN is enabled or not, and your code will run even if
* WoWLAN is enabled - don't kill the NIC, someone may need it in Sx. * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx.
*/ */
return iwl_suspend(bus->drv_data); return iwl_suspend(priv);
} }
static int iwl_pci_resume(struct device *device) static int iwl_pci_resume(struct device *device)
{ {
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
struct iwl_bus *bus = pci_get_drvdata(pdev); struct iwl_priv *priv = pci_get_drvdata(pdev);
/* Before you put code here, think about WoWLAN. You cannot check here /* Before you put code here, think about WoWLAN. You cannot check here
* whether WoWLAN is enabled or not, and your code will run even if * whether WoWLAN is enabled or not, and your code will run even if
...@@ -532,7 +532,7 @@ static int iwl_pci_resume(struct device *device) ...@@ -532,7 +532,7 @@ static int iwl_pci_resume(struct device *device)
*/ */
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
return iwl_resume(bus->drv_data); return iwl_resume(priv);
} }
static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);
......
...@@ -349,7 +349,8 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, ...@@ -349,7 +349,8 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
if (priv->wowlan) if (priv->wowlan)
iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) else if (!priv->cfg->base_params->no_idle_support &&
priv->hw->conf.flags & IEEE80211_CONF_IDLE)
iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
else if (iwl_tt_is_low_power_state(priv)) { else if (iwl_tt_is_low_power_state(priv)) {
/* in thermal throttling low power state */ /* in thermal throttling low power state */
......
...@@ -703,8 +703,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) ...@@ -703,8 +703,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
/* /*
* Add space for the TXWI in front of the skb. * Add space for the TXWI in front of the skb.
*/ */
skb_push(entry->skb, TXWI_DESC_SIZE); memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE);
memset(entry->skb, 0, TXWI_DESC_SIZE);
/* /*
* Register descriptor details in skb frame descriptor. * Register descriptor details in skb frame descriptor.
......
...@@ -355,7 +355,8 @@ static inline enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf * ...@@ -355,7 +355,8 @@ static inline enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *
return CIPHER_NONE; return CIPHER_NONE;
} }
static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, static inline void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
struct txentry_desc *txdesc) struct txentry_desc *txdesc)
{ {
} }
......
...@@ -113,7 +113,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -113,7 +113,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* due to possible race conditions in mac80211. * due to possible race conditions in mac80211.
*/ */
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
goto exit_fail; goto exit_free_skb;
/* /*
* Use the ATIM queue if appropriate and present. * Use the ATIM queue if appropriate and present.
...@@ -127,7 +127,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -127,7 +127,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
ERROR(rt2x00dev, ERROR(rt2x00dev,
"Attempt to send packet over invalid queue %d.\n" "Attempt to send packet over invalid queue %d.\n"
"Please file bug report to %s.\n", qid, DRV_PROJECT); "Please file bug report to %s.\n", qid, DRV_PROJECT);
goto exit_fail; goto exit_free_skb;
} }
/* /*
...@@ -159,6 +159,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -159,6 +159,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
exit_fail: exit_fail:
rt2x00queue_pause_queue(queue); rt2x00queue_pause_queue(queue);
exit_free_skb:
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
EXPORT_SYMBOL_GPL(rt2x00mac_tx); EXPORT_SYMBOL_GPL(rt2x00mac_tx);
......
...@@ -1696,15 +1696,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, ...@@ -1696,15 +1696,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn);
/*find bridge info */ if (bridge_pdev) {
pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; /*find bridge info if available */
for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor;
if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) {
pcipriv->ndis_adapter.pcibridge_vendor = tmp; if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, pcipriv->ndis_adapter.pcibridge_vendor = tmp;
("Pci Bridge Vendor is found index: %d\n", RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
tmp)); ("Pci Bridge Vendor is found index:"
break; " %d\n", tmp));
break;
}
} }
} }
......
...@@ -3464,7 +3464,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) ...@@ -3464,7 +3464,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
tmp) { tmp) {
enum ieee80211_band band = nla_type(attr); enum ieee80211_band band = nla_type(attr);
if (band < 0 || band > IEEE80211_NUM_BANDS) { if (band < 0 || band >= IEEE80211_NUM_BANDS) {
err = -EINVAL; err = -EINVAL;
goto out_free; goto out_free;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册