Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/rtlwifi/pci.c include/linux/netlink.h
This commit is contained in:
Коммит
36099365c7
|
@ -13,8 +13,8 @@
|
|||
struct bcma_bus;
|
||||
|
||||
/* main.c */
|
||||
extern int bcma_bus_register(struct bcma_bus *bus);
|
||||
extern void bcma_bus_unregister(struct bcma_bus *bus);
|
||||
int bcma_bus_register(struct bcma_bus *bus);
|
||||
void bcma_bus_unregister(struct bcma_bus *bus);
|
||||
|
||||
/* scan.c */
|
||||
int bcma_bus_scan(struct bcma_bus *bus);
|
||||
|
|
|
@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_device *core)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
|
||||
|
||||
static void bcma_core_disable(struct bcma_device *core, u32 flags)
|
||||
void bcma_core_disable(struct bcma_device *core, u32 flags)
|
||||
{
|
||||
if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
|
||||
return;
|
||||
|
@ -31,6 +31,7 @@ static 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)
|
||||
{
|
||||
|
|
|
@ -53,6 +53,7 @@ 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",
|
||||
|
@ -74,6 +75,7 @@ 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 "
|
||||
|
@ -96,11 +98,13 @@ 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, 0xF0);
|
||||
bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
|
||||
} 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);
|
||||
|
|
|
@ -184,3 +184,4 @@ 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);
|
||||
|
|
|
@ -227,6 +227,7 @@ 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, },
|
||||
};
|
||||
|
|
|
@ -160,13 +160,11 @@ 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)
|
||||
{
|
||||
|
|
|
@ -2336,7 +2336,7 @@ static struct ssb_driver b44_ssb_driver = {
|
|||
.resume = b44_resume,
|
||||
};
|
||||
|
||||
static inline int b44_pci_init(void)
|
||||
static inline int __init b44_pci_init(void)
|
||||
{
|
||||
int err = 0;
|
||||
#ifdef CONFIG_B44_PCI
|
||||
|
@ -2345,7 +2345,7 @@ static inline int b44_pci_init(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
static inline void b44_pci_exit(void)
|
||||
static inline void __exit b44_pci_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_B44_PCI
|
||||
ssb_pcihost_unregister(&b44_pci_driver);
|
||||
|
|
|
@ -219,6 +219,7 @@ static int ath_ahb_remove(struct platform_device *pdev)
|
|||
|
||||
ath5k_deinit_softc(sc);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
ieee80211_free_hw(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -767,6 +767,7 @@ struct ath5k_athchan_2ghz {
|
|||
*/
|
||||
|
||||
#define AR5K_KEYCACHE_SIZE 8
|
||||
extern int ath5k_modparam_nohwcrypt;
|
||||
|
||||
/***********************\
|
||||
HW RELATED DEFINITIONS
|
||||
|
@ -1180,8 +1181,8 @@ void ath5k_sysfs_unregister(struct ath5k_softc *sc);
|
|||
struct ath5k_buf;
|
||||
struct ath5k_txq;
|
||||
|
||||
void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
|
||||
bool ath_any_vif_assoc(struct ath5k_softc *sc);
|
||||
void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
|
||||
bool ath5k_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);
|
||||
|
@ -1253,7 +1254,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);
|
||||
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
|
||||
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);
|
||||
|
|
|
@ -88,8 +88,6 @@ 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[] = {
|
||||
|
@ -2162,7 +2160,7 @@ ath5k_schedule_tx(struct ath5k_softc *sc)
|
|||
tasklet_schedule(&sc->txtq);
|
||||
}
|
||||
|
||||
irqreturn_t
|
||||
static irqreturn_t
|
||||
ath5k_intr(int irq, void *dev_id)
|
||||
{
|
||||
struct ath5k_softc *sc = dev_id;
|
||||
|
@ -2616,7 +2614,7 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void stop_tasklets(struct ath5k_softc *sc)
|
||||
static void ath5k_stop_tasklets(struct ath5k_softc *sc)
|
||||
{
|
||||
sc->rx_pending = false;
|
||||
sc->tx_pending = false;
|
||||
|
@ -2670,7 +2668,7 @@ ath5k_stop_hw(struct ath5k_softc *sc)
|
|||
mmiowb();
|
||||
mutex_unlock(&sc->lock);
|
||||
|
||||
stop_tasklets(sc);
|
||||
ath5k_stop_tasklets(sc);
|
||||
|
||||
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
|
||||
|
@ -2698,7 +2696,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
|
|||
|
||||
ath5k_hw_set_imr(ah, 0);
|
||||
synchronize_irq(sc->irq);
|
||||
stop_tasklets(sc);
|
||||
ath5k_stop_tasklets(sc);
|
||||
|
||||
/* Save ani mode and disable ANI during
|
||||
* reset. If we don't we might get false
|
||||
|
@ -2963,11 +2961,12 @@ 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
|
||||
ath_any_vif_assoc(struct ath5k_softc *sc)
|
||||
ath5k_any_vif_assoc(struct ath5k_softc *sc)
|
||||
{
|
||||
struct ath5k_vif_iter_data iter_data;
|
||||
iter_data.hw_macaddr = NULL;
|
||||
|
@ -2981,7 +2980,7 @@ ath_any_vif_assoc(struct ath5k_softc *sc)
|
|||
}
|
||||
|
||||
void
|
||||
set_beacon_filter(struct ieee80211_hw *hw, bool enable)
|
||||
ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable)
|
||||
{
|
||||
struct ath5k_softc *sc = hw->priv;
|
||||
struct ath5k_hw *ah = sc->ah;
|
||||
|
|
|
@ -46,8 +46,6 @@
|
|||
#include "base.h"
|
||||
#include "reg.h"
|
||||
|
||||
extern int ath5k_modparam_nohwcrypt;
|
||||
|
||||
/********************\
|
||||
* Mac80211 functions *
|
||||
\********************/
|
||||
|
@ -296,10 +294,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 = ath_any_vif_assoc(sc);
|
||||
sc->assoc = ath5k_any_vif_assoc(sc);
|
||||
|
||||
if (sc->opmode == NL80211_IFTYPE_STATION)
|
||||
set_beacon_filter(hw, sc->assoc);
|
||||
ath5k_set_beacon_filter(hw, sc->assoc);
|
||||
ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
|
||||
AR5K_LED_ASSOC : AR5K_LED_INIT);
|
||||
if (bss_conf->assoc) {
|
||||
|
|
|
@ -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 u32 *reg;
|
||||
volatile __iomem 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 *) AR5K_AR2315_RESET;
|
||||
reg = (u32 __iomem *) 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 *) AR5K_AR5312_RESET;
|
||||
reg = (u32 __iomem *) AR5K_AR5312_RESET;
|
||||
if (to_platform_device(ah->ah_sc->dev)->id == 0) {
|
||||
if (mask & AR5K_RESET_CTL_PCU)
|
||||
val |= AR5K_AR5312_RESET_WMAC0;
|
||||
|
|
|
@ -26,6 +26,10 @@ static const struct platform_device_id ath9k_platform_id_table[] = {
|
|||
.name = "ath9k",
|
||||
.driver_data = AR5416_AR9100_DEVID,
|
||||
},
|
||||
{
|
||||
.name = "ar933x_wmac",
|
||||
.driver_data = AR9300_DEVID_AR9330,
|
||||
},
|
||||
{
|
||||
.name = "ar934x_wmac",
|
||||
.driver_data = AR9300_DEVID_AR9340,
|
||||
|
|
|
@ -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(0, 0), CTL(0, 0) } },
|
||||
{ { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 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(0, 0), CTL(0, 0) } },
|
||||
{ { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 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) } },
|
||||
|
||||
|
@ -3324,6 +3324,8 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
|
|||
read = ar9300_read_eeprom;
|
||||
if (AR_SREV_9485(ah))
|
||||
cptr = AR9300_BASE_ADDR_4K;
|
||||
else if (AR_SREV_9330(ah))
|
||||
cptr = AR9300_BASE_ADDR_512;
|
||||
else
|
||||
cptr = AR9300_BASE_ADDR;
|
||||
ath_dbg(common, ATH_DBG_EEPROM,
|
||||
|
@ -3442,7 +3444,7 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
|
|||
{
|
||||
int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
|
||||
else {
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
|
||||
|
@ -3523,7 +3525,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
|||
}
|
||||
}
|
||||
|
||||
if (AR_SREV_9485(ah)) {
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
|
||||
value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
|
||||
/*
|
||||
* main_lnaconf, alt_lnaconf, main_tb, alt_tb
|
||||
|
@ -3710,7 +3712,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
|||
ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
|
||||
|
||||
if (internal_regulator) {
|
||||
if (AR_SREV_9485(ah)) {
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
|
||||
int reg_pmu_set;
|
||||
|
||||
reg_pmu_set = REG_READ(ah, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM;
|
||||
|
@ -3718,9 +3720,24 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
|||
if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
|
||||
return;
|
||||
|
||||
reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) |
|
||||
(2 << 14) | (6 << 17) | (1 << 20) |
|
||||
(3 << 24) | (1 << 28);
|
||||
if (AR_SREV_9330(ah)) {
|
||||
if (ah->is_clk_25mhz) {
|
||||
reg_pmu_set = (3 << 1) | (8 << 4) |
|
||||
(3 << 8) | (1 << 14) |
|
||||
(6 << 17) | (1 << 20) |
|
||||
(3 << 24);
|
||||
} else {
|
||||
reg_pmu_set = (4 << 1) | (7 << 4) |
|
||||
(3 << 8) | (1 << 14) |
|
||||
(6 << 17) | (1 << 20) |
|
||||
(3 << 24);
|
||||
}
|
||||
} else {
|
||||
reg_pmu_set = (5 << 1) | (7 << 4) |
|
||||
(1 << 8) | (2 << 14) |
|
||||
(6 << 17) | (1 << 20) |
|
||||
(3 << 24) | (1 << 28);
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set);
|
||||
if (!is_pmu_set(ah, AR_PHY_PMU1, reg_pmu_set))
|
||||
|
@ -3751,7 +3768,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
|||
AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
|
||||
}
|
||||
} else {
|
||||
if (AR_SREV_9485(ah)) {
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
|
||||
REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
|
||||
while (REG_READ_FIELD(ah, AR_PHY_PMU2,
|
||||
AR_PHY_PMU2_PGM))
|
||||
|
@ -3795,9 +3812,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
|
|||
ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
|
||||
ar9003_hw_drive_strength_apply(ah);
|
||||
ar9003_hw_atten_apply(ah, chan);
|
||||
if (!AR_SREV_9340(ah))
|
||||
if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah))
|
||||
ar9003_hw_internal_regulator_apply(ah);
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
|
||||
ar9003_hw_apply_tuning_caps(ah);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "ar9003_2p2_initvals.h"
|
||||
#include "ar9485_initvals.h"
|
||||
#include "ar9340_initvals.h"
|
||||
#include "ar9330_1p1_initvals.h"
|
||||
#include "ar9330_1p2_initvals.h"
|
||||
|
||||
/* General hardware code for the AR9003 hadware family */
|
||||
|
||||
|
@ -29,7 +31,113 @@
|
|||
*/
|
||||
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9340(ah)) {
|
||||
if (AR_SREV_9330_11(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
ar9331_1p1_mac_core,
|
||||
ARRAY_SIZE(ar9331_1p1_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9331_1p1_mac_postamble,
|
||||
ARRAY_SIZE(ar9331_1p1_mac_postamble), 5);
|
||||
|
||||
/* bb */
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9331_1p1_baseband_core,
|
||||
ARRAY_SIZE(ar9331_1p1_baseband_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9331_1p1_baseband_postamble,
|
||||
ARRAY_SIZE(ar9331_1p1_baseband_postamble), 5);
|
||||
|
||||
/* radio */
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9331_1p1_radio_core,
|
||||
ARRAY_SIZE(ar9331_1p1_radio_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0);
|
||||
|
||||
/* soc */
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9331_1p1_soc_preamble,
|
||||
ARRAY_SIZE(ar9331_1p1_soc_preamble), 2);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9331_1p1_soc_postamble,
|
||||
ARRAY_SIZE(ar9331_1p1_soc_postamble), 2);
|
||||
|
||||
/* rx/tx gain */
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_rx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_common_rx_gain_1p1), 2);
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_lowest_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
|
||||
/* additional clock settings */
|
||||
if (ah->is_clk_25mhz)
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9331_1p1_xtal_25M,
|
||||
ARRAY_SIZE(ar9331_1p1_xtal_25M), 2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9331_1p1_xtal_40M,
|
||||
ARRAY_SIZE(ar9331_1p1_xtal_40M), 2);
|
||||
} else if (AR_SREV_9330_12(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
ar9331_1p2_mac_core,
|
||||
ARRAY_SIZE(ar9331_1p2_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9331_1p2_mac_postamble,
|
||||
ARRAY_SIZE(ar9331_1p2_mac_postamble), 5);
|
||||
|
||||
/* bb */
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9331_1p2_baseband_core,
|
||||
ARRAY_SIZE(ar9331_1p2_baseband_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9331_1p2_baseband_postamble,
|
||||
ARRAY_SIZE(ar9331_1p2_baseband_postamble), 5);
|
||||
|
||||
/* radio */
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9331_1p2_radio_core,
|
||||
ARRAY_SIZE(ar9331_1p2_radio_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0);
|
||||
|
||||
/* soc */
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9331_1p2_soc_preamble,
|
||||
ARRAY_SIZE(ar9331_1p2_soc_preamble), 2);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9331_1p2_soc_postamble,
|
||||
ARRAY_SIZE(ar9331_1p2_soc_postamble), 2);
|
||||
|
||||
/* rx/tx gain */
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_rx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_common_rx_gain_1p2), 2);
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_lowest_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
|
||||
/* additional clock settings */
|
||||
if (ah->is_clk_25mhz)
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9331_1p2_xtal_25M,
|
||||
ARRAY_SIZE(ar9331_1p2_xtal_25M), 2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9331_1p2_xtal_40M,
|
||||
ARRAY_SIZE(ar9331_1p2_xtal_40M), 2);
|
||||
} else if (AR_SREV_9340(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
|
@ -220,7 +328,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
|||
switch (ar9003_hw_get_tx_gain_idx(ah)) {
|
||||
case 0:
|
||||
default:
|
||||
if (AR_SREV_9340(ah))
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_lowest_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_lowest_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
|
@ -237,7 +355,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
|||
5);
|
||||
break;
|
||||
case 1:
|
||||
if (AR_SREV_9340(ah))
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
|
@ -254,7 +382,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
|||
5);
|
||||
break;
|
||||
case 2:
|
||||
if (AR_SREV_9340(ah))
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_low_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_low_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
|
@ -271,7 +409,17 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
|||
5);
|
||||
break;
|
||||
case 3:
|
||||
if (AR_SREV_9340(ah))
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_power_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_power_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
|
@ -295,7 +443,17 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
|
|||
switch (ar9003_hw_get_rx_gain_idx(ah)) {
|
||||
case 0:
|
||||
default:
|
||||
if (AR_SREV_9340(ah))
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_rx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_common_rx_gain_1p2),
|
||||
2);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_rx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_common_rx_gain_1p1),
|
||||
2);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
|
||||
|
@ -312,7 +470,17 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
|
|||
2);
|
||||
break;
|
||||
case 1:
|
||||
if (AR_SREV_9340(ah))
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_wo_xlna_rx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2),
|
||||
2);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_wo_xlna_rx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1),
|
||||
2);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_wo_xlna_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
|
||||
|
|
|
@ -83,7 +83,23 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah)
|
|||
if (delta > scale)
|
||||
return -1;
|
||||
|
||||
power += 2 * get_streams(common->tx_chainmask);
|
||||
switch (get_streams(common->tx_chainmask)) {
|
||||
case 1:
|
||||
delta = 6;
|
||||
break;
|
||||
case 2:
|
||||
delta = 4;
|
||||
break;
|
||||
case 3:
|
||||
delta = 2;
|
||||
break;
|
||||
default:
|
||||
delta = 0;
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Invalid tx-chainmask: %u\n", common->tx_chainmask);
|
||||
}
|
||||
|
||||
power += delta;
|
||||
return power;
|
||||
}
|
||||
|
||||
|
@ -785,7 +801,26 @@ EXPORT_SYMBOL(ar9003_paprd_init_table);
|
|||
|
||||
bool ar9003_paprd_is_done(struct ath_hw *ah)
|
||||
{
|
||||
return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1,
|
||||
int paprd_done, agc2_pwr;
|
||||
paprd_done = 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);
|
||||
|
|
|
@ -75,7 +75,19 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
|
|||
freq = centers.synth_center;
|
||||
|
||||
if (freq < 4800) { /* 2 GHz, fractional mode */
|
||||
if (AR_SREV_9485(ah)) {
|
||||
if (AR_SREV_9330(ah)) {
|
||||
u32 chan_frac;
|
||||
u32 div;
|
||||
|
||||
if (ah->is_clk_25mhz)
|
||||
div = 75;
|
||||
else
|
||||
div = 120;
|
||||
|
||||
channelSel = (freq * 4) / div;
|
||||
chan_frac = (((freq * 4) % div) * 0x20000) / div;
|
||||
channelSel = (channelSel << 17) | chan_frac;
|
||||
} else if (AR_SREV_9485(ah)) {
|
||||
u32 chan_frac;
|
||||
|
||||
/*
|
||||
|
@ -104,7 +116,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
|
|||
u32 chan_frac;
|
||||
|
||||
channelSel = (freq * 2) / 75;
|
||||
chan_frac = ((freq % 75) * 0x20000) / 75;
|
||||
chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
|
||||
channelSel = (channelSel << 17) | chan_frac;
|
||||
} else {
|
||||
channelSel = CHANSEL_5G(freq);
|
||||
|
@ -168,7 +180,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
|
|||
* is out-of-band and can be ignored.
|
||||
*/
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) {
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) {
|
||||
spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
|
||||
IS_CHAN_2GHZ(chan));
|
||||
if (spur_fbin_ptr[0] == 0) /* No spur */
|
||||
|
@ -193,7 +205,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
|
|||
|
||||
for (i = 0; i < max_spur_cnts; i++) {
|
||||
negative = 0;
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah))
|
||||
cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
|
||||
IS_CHAN_2GHZ(chan)) - synth_freq;
|
||||
else
|
||||
|
@ -659,6 +671,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
|||
REG_WRITE_ARRAY(&ah->iniModesAdditional,
|
||||
modesIndex, regWrites);
|
||||
|
||||
if (AR_SREV_9300(ah))
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
|
||||
|
||||
if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
|
||||
|
||||
|
@ -1074,7 +1089,10 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
|
|||
{
|
||||
ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
|
||||
ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
|
||||
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
|
||||
if (AR_SREV_9330(ah))
|
||||
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ;
|
||||
else
|
||||
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
|
||||
ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
|
||||
ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
|
||||
ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ;
|
||||
|
@ -1196,8 +1214,17 @@ static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah,
|
|||
AR_PHY_9485_ANT_DIV_ALT_LNACONF_S;
|
||||
antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >>
|
||||
AR_PHY_9485_ANT_FAST_DIV_BIAS_S;
|
||||
antconf->lna1_lna2_delta = -9;
|
||||
antconf->div_group = 2;
|
||||
|
||||
if (AR_SREV_9330_11(ah)) {
|
||||
antconf->lna1_lna2_delta = -9;
|
||||
antconf->div_group = 1;
|
||||
} else if (AR_SREV_9485(ah)) {
|
||||
antconf->lna1_lna2_delta = -9;
|
||||
antconf->div_group = 2;
|
||||
} else {
|
||||
antconf->lna1_lna2_delta = -3;
|
||||
antconf->div_group = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
|
||||
|
|
|
@ -332,6 +332,8 @@
|
|||
#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95
|
||||
#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100
|
||||
|
||||
#define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118
|
||||
|
||||
/*
|
||||
* AGC Field Definitions
|
||||
*/
|
||||
|
@ -623,11 +625,11 @@
|
|||
#define AR_PHY_65NM_CH2_RXTX1 0x16900
|
||||
#define AR_PHY_65NM_CH2_RXTX2 0x16904
|
||||
|
||||
#define AR_CH0_TOP2 (AR_SREV_9485(ah) ? 0x00016284 : 0x0001628c)
|
||||
#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : 0x16284)
|
||||
#define AR_CH0_TOP2_XPABIASLVL 0xf000
|
||||
#define AR_CH0_TOP2_XPABIASLVL_S 12
|
||||
|
||||
#define AR_CH0_XTAL (AR_SREV_9485(ah) ? 0x16290 : 0x16294)
|
||||
#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : 0x16290)
|
||||
#define AR_CH0_XTAL_CAPINDAC 0x7f000000
|
||||
#define AR_CH0_XTAL_CAPINDAC_S 24
|
||||
#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -55,8 +55,6 @@ 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))
|
||||
|
||||
|
@ -580,7 +578,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 nwd vifs */
|
||||
int nwds; /* number of WDS vifs */
|
||||
int nadhocs; /* number of adhoc vifs */
|
||||
int nothers; /* number of vifs not specified above. */
|
||||
};
|
||||
|
|
|
@ -251,6 +251,15 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
|
|||
case AR5416_AR9100_DEVID:
|
||||
ah->hw_version.macVersion = AR_SREV_VERSION_9100;
|
||||
break;
|
||||
case AR9300_DEVID_AR9330:
|
||||
ah->hw_version.macVersion = AR_SREV_VERSION_9330;
|
||||
if (ah->get_mac_revision) {
|
||||
ah->hw_version.macRev = ah->get_mac_revision();
|
||||
} else {
|
||||
val = REG_READ(ah, AR_SREV);
|
||||
ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
|
||||
}
|
||||
return;
|
||||
case AR9300_DEVID_AR9340:
|
||||
ah->hw_version.macVersion = AR_SREV_VERSION_9340;
|
||||
val = REG_READ(ah, AR_SREV);
|
||||
|
@ -551,6 +560,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
|||
case AR_SREV_VERSION_9287:
|
||||
case AR_SREV_VERSION_9271:
|
||||
case AR_SREV_VERSION_9300:
|
||||
case AR_SREV_VERSION_9330:
|
||||
case AR_SREV_VERSION_9485:
|
||||
case AR_SREV_VERSION_9340:
|
||||
break;
|
||||
|
@ -561,7 +571,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah))
|
||||
if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) ||
|
||||
AR_SREV_9330(ah))
|
||||
ah->is_pciexpress = false;
|
||||
|
||||
ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
|
||||
|
@ -604,7 +615,10 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
|||
else
|
||||
ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
|
||||
|
||||
ah->bb_watchdog_timeout_ms = 25;
|
||||
if (AR_SREV_9330(ah))
|
||||
ah->bb_watchdog_timeout_ms = 85;
|
||||
else
|
||||
ah->bb_watchdog_timeout_ms = 25;
|
||||
|
||||
common->state = ATH_HW_INITIALIZED;
|
||||
|
||||
|
@ -630,6 +644,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
|||
case AR2427_DEVID_PCIE:
|
||||
case AR9300_DEVID_PCIE:
|
||||
case AR9300_DEVID_AR9485_PCIE:
|
||||
case AR9300_DEVID_AR9330:
|
||||
case AR9300_DEVID_AR9340:
|
||||
break;
|
||||
default:
|
||||
|
@ -722,6 +737,39 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
|
|||
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
|
||||
AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
|
||||
udelay(1000);
|
||||
} else if (AR_SREV_9330(ah)) {
|
||||
u32 ddr_dpll2, pll_control2, kd;
|
||||
|
||||
if (ah->is_clk_25mhz) {
|
||||
ddr_dpll2 = 0x18e82f01;
|
||||
pll_control2 = 0xe04a3d;
|
||||
kd = 0x1d;
|
||||
} else {
|
||||
ddr_dpll2 = 0x19e82f01;
|
||||
pll_control2 = 0x886666;
|
||||
kd = 0x3d;
|
||||
}
|
||||
|
||||
/* program DDR PLL ki and kd value */
|
||||
REG_WRITE(ah, AR_CH0_DDR_DPLL2, ddr_dpll2);
|
||||
|
||||
/* program DDR PLL phase_shift */
|
||||
REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3,
|
||||
AR_CH0_DPLL3_PHASE_SHIFT, 0x1);
|
||||
|
||||
REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
|
||||
udelay(1000);
|
||||
|
||||
/* program refdiv, nint, frac to RTC register */
|
||||
REG_WRITE(ah, AR_RTC_PLL_CONTROL2, pll_control2);
|
||||
|
||||
/* program BB PLL kd and ki value */
|
||||
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_DPLL2_KD, kd);
|
||||
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_DPLL2_KI, 0x06);
|
||||
|
||||
/* program BB PLL phase_shift */
|
||||
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
|
||||
AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1);
|
||||
} else if (AR_SREV_9340(ah)) {
|
||||
u32 regval, pll2_divint, pll2_divfrac, refdiv;
|
||||
|
||||
|
@ -763,7 +811,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
|
|||
|
||||
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah))
|
||||
udelay(1000);
|
||||
|
||||
/* Switch the core clock for ar9271 to 117Mhz */
|
||||
|
@ -1114,6 +1162,41 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
|
|||
rst_flags |= AR_RTC_RC_MAC_COLD;
|
||||
}
|
||||
|
||||
if (AR_SREV_9330(ah)) {
|
||||
int npend = 0;
|
||||
int i;
|
||||
|
||||
/* AR9330 WAR:
|
||||
* call external reset function to reset WMAC if:
|
||||
* - doing a cold reset
|
||||
* - we have pending frames in the TX queues
|
||||
*/
|
||||
|
||||
for (i = 0; i < AR_NUM_QCU; i++) {
|
||||
npend = ath9k_hw_numtxpending(ah, i);
|
||||
if (npend)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ah->external_reset &&
|
||||
(npend || type == ATH9K_RESET_COLD)) {
|
||||
int reset_err = 0;
|
||||
|
||||
ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET,
|
||||
"reset MAC via external reset\n");
|
||||
|
||||
reset_err = ah->external_reset();
|
||||
if (reset_err) {
|
||||
ath_err(ath9k_hw_common(ah),
|
||||
"External reset failed, err=%d\n",
|
||||
reset_err);
|
||||
return false;
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_RTC_RESET, 1);
|
||||
}
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_RTC_RC, rst_flags);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
@ -1545,7 +1628,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
|||
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
|
||||
}
|
||||
#ifdef __BIG_ENDIAN
|
||||
else if (AR_SREV_9340(ah))
|
||||
else if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
|
||||
REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
|
||||
else
|
||||
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
|
||||
|
@ -1983,7 +2066,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
|||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
|
||||
if (!AR_SREV_9485(ah))
|
||||
if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_LDPC;
|
||||
|
||||
pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
|
||||
|
@ -2025,7 +2108,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
|||
}
|
||||
|
||||
|
||||
if (AR_SREV_9485(ah)) {
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
|
||||
ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
|
||||
/*
|
||||
* enable the diversity-combining algorithm only when
|
||||
|
@ -2574,6 +2657,7 @@ static struct {
|
|||
{ AR_SREV_VERSION_9287, "9287" },
|
||||
{ AR_SREV_VERSION_9271, "9271" },
|
||||
{ AR_SREV_VERSION_9300, "9300" },
|
||||
{ AR_SREV_VERSION_9330, "9330" },
|
||||
{ AR_SREV_VERSION_9485, "9485" },
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#define AR9300_DEVID_PCIE 0x0030
|
||||
#define AR9300_DEVID_AR9340 0x0031
|
||||
#define AR9300_DEVID_AR9485_PCIE 0x0032
|
||||
#define AR9300_DEVID_AR9330 0x0035
|
||||
|
||||
#define AR5416_AR9100_DEVID 0x000b
|
||||
|
||||
|
@ -157,8 +158,9 @@
|
|||
#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_GAIN_TABLE_ENTRIES 32
|
||||
#define PAPRD_TABLE_SZ 24
|
||||
#define PAPRD_IDEAL_AGC2_PWR_RANGE 0xe0
|
||||
|
||||
enum ath_hw_txq_subtype {
|
||||
ATH_TXQ_AC_BE = 0,
|
||||
|
@ -860,6 +862,8 @@ struct ath_hw {
|
|||
u32 ent_mode;
|
||||
|
||||
bool is_clk_25mhz;
|
||||
int (*get_mac_revision)(void);
|
||||
int (*external_reset)(void);
|
||||
};
|
||||
|
||||
struct ath_bus_ops {
|
||||
|
|
|
@ -246,7 +246,7 @@ static void setup_ht_cap(struct ath_softc *sc,
|
|||
ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
|
||||
|
||||
if (AR_SREV_9485(ah))
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah))
|
||||
max_streams = 1;
|
||||
else if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
max_streams = 3;
|
||||
|
@ -575,6 +575,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
|||
sc->sc_ah->gpio_val = pdata->gpio_val;
|
||||
sc->sc_ah->led_pin = pdata->led_pin;
|
||||
ah->is_clk_25mhz = pdata->is_clk_25mhz;
|
||||
ah->get_mac_revision = pdata->get_mac_revision;
|
||||
ah->external_reset = pdata->external_reset;
|
||||
}
|
||||
|
||||
common = ath9k_hw_common(ah);
|
||||
|
|
|
@ -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_XMIT, "PAPRD TX failed\n");
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE, "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(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE,
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Timeout waiting for paprd training on TX chain %d\n",
|
||||
chain);
|
||||
|
||||
|
@ -431,11 +431,18 @@ 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))
|
||||
if (!ar9003_paprd_is_done(ah)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"PAPRD not yet done on chain %d\n", chain);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ar9003_paprd_create_curve(ah, caldata, chain) != 0)
|
||||
if (ar9003_paprd_create_curve(ah, caldata, chain)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"PAPRD create curve failed on chain %d\n",
|
||||
chain);
|
||||
break;
|
||||
}
|
||||
|
||||
chain_ok = 1;
|
||||
}
|
||||
|
@ -1259,7 +1266,6 @@ 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);
|
||||
|
||||
|
|
|
@ -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 = A_MAX(hi, j);
|
||||
hi = 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 = A_MAX(hi, j);
|
||||
hi = max(hi, j);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1228,7 +1228,7 @@ static void ath_rc_init(struct ath_softc *sc,
|
|||
ht_mcs,
|
||||
ath_rc_priv->ht_cap);
|
||||
}
|
||||
hi = A_MAX(hi, hthi);
|
||||
hi = max(hi, hthi);
|
||||
}
|
||||
|
||||
ath_rc_priv->rate_table_size = hi + 1;
|
||||
|
|
|
@ -40,6 +40,7 @@ static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio,
|
|||
result = true;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) &&
|
||||
(curr_alt_set == ATH_ANT_DIV_COMB_LNA1) &&
|
||||
(alt_rssi_avg >= (main_rssi_avg - 5))) ||
|
||||
|
@ -1076,39 +1077,39 @@ static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb,
|
|||
antcomb->rssi_lna1 = main_rssi_avg;
|
||||
|
||||
switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) {
|
||||
case (0x10): /* LNA2 A-B */
|
||||
case 0x10: /* LNA2 A-B */
|
||||
antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
|
||||
antcomb->first_quick_scan_conf =
|
||||
ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
|
||||
antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1;
|
||||
break;
|
||||
case (0x20): /* LNA1 A-B */
|
||||
case 0x20: /* LNA1 A-B */
|
||||
antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
|
||||
antcomb->first_quick_scan_conf =
|
||||
ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
|
||||
antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2;
|
||||
break;
|
||||
case (0x21): /* LNA1 LNA2 */
|
||||
case 0x21: /* LNA1 LNA2 */
|
||||
antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2;
|
||||
antcomb->first_quick_scan_conf =
|
||||
ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
|
||||
antcomb->second_quick_scan_conf =
|
||||
ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
|
||||
break;
|
||||
case (0x12): /* LNA2 LNA1 */
|
||||
case 0x12: /* LNA2 LNA1 */
|
||||
antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1;
|
||||
antcomb->first_quick_scan_conf =
|
||||
ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
|
||||
antcomb->second_quick_scan_conf =
|
||||
ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
|
||||
break;
|
||||
case (0x13): /* LNA2 A+B */
|
||||
case 0x13: /* LNA2 A+B */
|
||||
antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
|
||||
antcomb->first_quick_scan_conf =
|
||||
ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
|
||||
antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1;
|
||||
break;
|
||||
case (0x23): /* LNA1 A+B */
|
||||
case 0x23: /* LNA1 A+B */
|
||||
antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
|
||||
antcomb->first_quick_scan_conf =
|
||||
ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
|
||||
|
@ -1325,65 +1326,148 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|||
/* Adjust the fast_div_bias based on main and alt lna conf */
|
||||
switch ((ant_conf->main_lna_conf << 4) |
|
||||
ant_conf->alt_lna_conf) {
|
||||
case (0x01): /* A-B LNA2 */
|
||||
case 0x01: /* A-B LNA2 */
|
||||
ant_conf->fast_div_bias = 0x3b;
|
||||
break;
|
||||
case (0x02): /* A-B LNA1 */
|
||||
case 0x02: /* A-B LNA1 */
|
||||
ant_conf->fast_div_bias = 0x3d;
|
||||
break;
|
||||
case (0x03): /* A-B A+B */
|
||||
case 0x03: /* A-B A+B */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
break;
|
||||
case (0x10): /* LNA2 A-B */
|
||||
case 0x10: /* LNA2 A-B */
|
||||
ant_conf->fast_div_bias = 0x7;
|
||||
break;
|
||||
case (0x12): /* LNA2 LNA1 */
|
||||
case 0x12: /* LNA2 LNA1 */
|
||||
ant_conf->fast_div_bias = 0x2;
|
||||
break;
|
||||
case (0x13): /* LNA2 A+B */
|
||||
case 0x13: /* LNA2 A+B */
|
||||
ant_conf->fast_div_bias = 0x7;
|
||||
break;
|
||||
case (0x20): /* LNA1 A-B */
|
||||
case 0x20: /* LNA1 A-B */
|
||||
ant_conf->fast_div_bias = 0x6;
|
||||
break;
|
||||
case (0x21): /* LNA1 LNA2 */
|
||||
case 0x21: /* LNA1 LNA2 */
|
||||
ant_conf->fast_div_bias = 0x0;
|
||||
break;
|
||||
case (0x23): /* LNA1 A+B */
|
||||
case 0x23: /* LNA1 A+B */
|
||||
ant_conf->fast_div_bias = 0x6;
|
||||
break;
|
||||
case (0x30): /* A+B A-B */
|
||||
case 0x30: /* A+B A-B */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
break;
|
||||
case (0x31): /* A+B LNA2 */
|
||||
case 0x31: /* A+B LNA2 */
|
||||
ant_conf->fast_div_bias = 0x3b;
|
||||
break;
|
||||
case (0x32): /* A+B LNA1 */
|
||||
case 0x32: /* A+B LNA1 */
|
||||
ant_conf->fast_div_bias = 0x3d;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (ant_conf->div_group == 1) {
|
||||
/* Adjust the fast_div_bias based on main and alt_lna_conf */
|
||||
switch ((ant_conf->main_lna_conf << 4) |
|
||||
ant_conf->alt_lna_conf) {
|
||||
case 0x01: /* A-B LNA2 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x02: /* A-B LNA1 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x03: /* A-B A+B */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x10: /* LNA2 A-B */
|
||||
if (!(antcomb->scan) &&
|
||||
(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
||||
ant_conf->fast_div_bias = 0x3f;
|
||||
else
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x12: /* LNA2 LNA1 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x13: /* LNA2 A+B */
|
||||
if (!(antcomb->scan) &&
|
||||
(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
||||
ant_conf->fast_div_bias = 0x3f;
|
||||
else
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x20: /* LNA1 A-B */
|
||||
if (!(antcomb->scan) &&
|
||||
(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
||||
ant_conf->fast_div_bias = 0x3f;
|
||||
else
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x21: /* LNA1 LNA2 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x23: /* LNA1 A+B */
|
||||
if (!(antcomb->scan) &&
|
||||
(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
||||
ant_conf->fast_div_bias = 0x3f;
|
||||
else
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x30: /* A+B A-B */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x31: /* A+B LNA2 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case 0x32: /* A+B LNA1 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (ant_conf->div_group == 2) {
|
||||
/* Adjust the fast_div_bias based on main and alt_lna_conf */
|
||||
switch ((ant_conf->main_lna_conf << 4) |
|
||||
ant_conf->alt_lna_conf) {
|
||||
case (0x01): /* A-B LNA2 */
|
||||
case 0x01: /* A-B LNA2 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x02): /* A-B LNA1 */
|
||||
case 0x02: /* A-B LNA1 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x03): /* A-B A+B */
|
||||
case 0x03: /* A-B A+B */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x10): /* LNA2 A-B */
|
||||
case 0x10: /* LNA2 A-B */
|
||||
if (!(antcomb->scan) &&
|
||||
(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
|
@ -1392,12 +1476,12 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x12): /* LNA2 LNA1 */
|
||||
case 0x12: /* LNA2 LNA1 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x13): /* LNA2 A+B */
|
||||
case 0x13: /* LNA2 A+B */
|
||||
if (!(antcomb->scan) &&
|
||||
(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
|
@ -1406,7 +1490,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x20): /* LNA1 A-B */
|
||||
case 0x20: /* LNA1 A-B */
|
||||
if (!(antcomb->scan) &&
|
||||
(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
|
@ -1415,12 +1499,12 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x21): /* LNA1 LNA2 */
|
||||
case 0x21: /* LNA1 LNA2 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x23): /* LNA1 A+B */
|
||||
case 0x23: /* LNA1 A+B */
|
||||
if (!(antcomb->scan) &&
|
||||
(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
|
@ -1429,17 +1513,17 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x30): /* A+B A-B */
|
||||
case 0x30: /* A+B A-B */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x31): /* A+B LNA2 */
|
||||
case 0x31: /* A+B LNA2 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
break;
|
||||
case (0x32): /* A+B LNA1 */
|
||||
case 0x32: /* A+B LNA1 */
|
||||
ant_conf->fast_div_bias = 0x1;
|
||||
ant_conf->main_gaintb = 0;
|
||||
ant_conf->alt_gaintb = 0;
|
||||
|
@ -1447,9 +1531,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Antenna diversity and combining */
|
||||
|
|
|
@ -788,6 +788,10 @@
|
|||
#define AR_SREV_REVISION_9271_11 1
|
||||
#define AR_SREV_VERSION_9300 0x1c0
|
||||
#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
|
||||
#define AR_SREV_VERSION_9330 0x200
|
||||
#define AR_SREV_REVISION_9330_10 0
|
||||
#define AR_SREV_REVISION_9330_11 1
|
||||
#define AR_SREV_REVISION_9330_12 2
|
||||
#define AR_SREV_VERSION_9485 0x240
|
||||
#define AR_SREV_REVISION_9485_10 0
|
||||
#define AR_SREV_REVISION_9485_11 1
|
||||
|
@ -862,6 +866,18 @@
|
|||
#define AR_SREV_9300_20_OR_LATER(_ah) \
|
||||
((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300)
|
||||
|
||||
#define AR_SREV_9330(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330))
|
||||
#define AR_SREV_9330_10(_ah) \
|
||||
(AR_SREV_9330((_ah)) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_10))
|
||||
#define AR_SREV_9330_11(_ah) \
|
||||
(AR_SREV_9330((_ah)) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_11))
|
||||
#define AR_SREV_9330_12(_ah) \
|
||||
(AR_SREV_9330((_ah)) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_12))
|
||||
|
||||
#define AR_SREV_9485(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
|
||||
#define AR_SREV_9485_10(_ah) \
|
||||
|
|
|
@ -31,6 +31,11 @@ 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
|
||||
|
@ -112,6 +117,14 @@ 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
|
||||
|
|
|
@ -10,6 +10,8 @@ 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-$(CONFIG_B43_PHY_HT) += radio_2059.o
|
||||
b43-y += sysfs.o
|
||||
b43-y += xmit.o
|
||||
b43-y += lo.o
|
||||
|
|
|
@ -92,6 +92,8 @@
|
|||
#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
|
||||
|
@ -363,6 +365,10 @@ 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
|
||||
|
|
|
@ -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,7 +83,11 @@ 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 = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
struct b43_bus_dev *dev;
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
dev->bus_type = B43_BUS_SSB;
|
||||
dev->sdev = sdev;
|
||||
|
@ -120,3 +124,4 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
|
|||
|
||||
return dev;
|
||||
}
|
||||
#endif /* CONFIG_B43_SSB */
|
||||
|
|
|
@ -123,6 +123,7 @@ 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),
|
||||
|
@ -136,8 +137,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
|
||||
|
@ -4096,6 +4097,12 @@ 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;
|
||||
|
@ -4153,6 +4160,10 @@ 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);
|
||||
}
|
||||
|
@ -5016,6 +5027,7 @@ 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)
|
||||
{
|
||||
|
@ -5025,6 +5037,8 @@ 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) {
|
||||
|
@ -5091,6 +5105,14 @@ 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)
|
||||
{
|
||||
|
@ -5101,13 +5123,6 @@ 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 = "",
|
||||
|
@ -5151,14 +5166,18 @@ 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:
|
||||
|
@ -5173,7 +5192,9 @@ err_dfs_exit:
|
|||
|
||||
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
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "phy_a.h"
|
||||
#include "phy_n.h"
|
||||
#include "phy_lp.h"
|
||||
#include "phy_ht.h"
|
||||
#include "b43.h"
|
||||
#include "main.h"
|
||||
|
||||
|
@ -57,6 +58,11 @@ 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;
|
||||
}
|
||||
|
|
|
@ -194,6 +194,7 @@ 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. */
|
||||
|
@ -216,6 +217,8 @@ 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. */
|
||||
|
|
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
|
||||
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 <linux/slab.h>
|
||||
|
||||
#include "b43.h"
|
||||
#include "phy_ht.h"
|
||||
#include "radio_2059.h"
|
||||
#include "main.h"
|
||||
|
||||
static void b43_radio_2059_channel_setup(struct b43_wldev *dev,
|
||||
const struct b43_phy_ht_channeltab_e_radio2059 *e)
|
||||
{
|
||||
u8 i;
|
||||
u16 routing;
|
||||
|
||||
b43_radio_write(dev, 0x16, e->radio_syn16);
|
||||
b43_radio_write(dev, 0x17, e->radio_syn17);
|
||||
b43_radio_write(dev, 0x22, e->radio_syn22);
|
||||
b43_radio_write(dev, 0x25, e->radio_syn25);
|
||||
b43_radio_write(dev, 0x27, e->radio_syn27);
|
||||
b43_radio_write(dev, 0x28, e->radio_syn28);
|
||||
b43_radio_write(dev, 0x29, e->radio_syn29);
|
||||
b43_radio_write(dev, 0x2c, e->radio_syn2c);
|
||||
b43_radio_write(dev, 0x2d, e->radio_syn2d);
|
||||
b43_radio_write(dev, 0x37, e->radio_syn37);
|
||||
b43_radio_write(dev, 0x41, e->radio_syn41);
|
||||
b43_radio_write(dev, 0x43, e->radio_syn43);
|
||||
b43_radio_write(dev, 0x47, e->radio_syn47);
|
||||
b43_radio_write(dev, 0x4a, e->radio_syn4a);
|
||||
b43_radio_write(dev, 0x58, e->radio_syn58);
|
||||
b43_radio_write(dev, 0x5a, e->radio_syn5a);
|
||||
b43_radio_write(dev, 0x6a, e->radio_syn6a);
|
||||
b43_radio_write(dev, 0x6d, e->radio_syn6d);
|
||||
b43_radio_write(dev, 0x6e, e->radio_syn6e);
|
||||
b43_radio_write(dev, 0x92, e->radio_syn92);
|
||||
b43_radio_write(dev, 0x98, e->radio_syn98);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
routing = i ? 0x800 : 0x400;
|
||||
b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a);
|
||||
b43_radio_write(dev, routing | 0x58, e->radio_rxtx58);
|
||||
b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a);
|
||||
b43_radio_write(dev, routing | 0x6a, e->radio_rxtx6a);
|
||||
b43_radio_write(dev, routing | 0x6d, e->radio_rxtx6d);
|
||||
b43_radio_write(dev, routing | 0x6e, e->radio_rxtx6e);
|
||||
b43_radio_write(dev, routing | 0x92, e->radio_rxtx92);
|
||||
b43_radio_write(dev, routing | 0x98, e->radio_rxtx98);
|
||||
}
|
||||
|
||||
udelay(50);
|
||||
|
||||
/* Calibration */
|
||||
b43_radio_mask(dev, 0x2b, ~0x1);
|
||||
b43_radio_mask(dev, 0x2e, ~0x4);
|
||||
b43_radio_set(dev, 0x2e, 0x4);
|
||||
b43_radio_set(dev, 0x2b, 0x1);
|
||||
|
||||
udelay(300);
|
||||
}
|
||||
|
||||
static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
|
||||
const struct b43_phy_ht_channeltab_e_phy *e,
|
||||
struct ieee80211_channel *new_channel)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static int b43_phy_ht_set_channel(struct b43_wldev *dev,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
const struct b43_phy_ht_channeltab_e_radio2059 *chent_r2059 = NULL;
|
||||
|
||||
if (phy->radio_ver == 0x2059) {
|
||||
chent_r2059 = b43_phy_ht_get_channeltab_e_r2059(dev,
|
||||
channel->center_freq);
|
||||
if (!chent_r2059)
|
||||
return -ESRCH;
|
||||
} else {
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
/* TODO: In case of N-PHY some bandwidth switching goes here */
|
||||
|
||||
if (phy->radio_ver == 0x2059) {
|
||||
b43_radio_2059_channel_setup(dev, chent_r2059);
|
||||
b43_phy_ht_channel_setup(dev, &(chent_r2059->phy_regs),
|
||||
channel);
|
||||
} else {
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
|
||||
static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
|
||||
bool blocked)
|
||||
{
|
||||
if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
|
||||
b43err(dev->wl, "MAC not suspended\n");
|
||||
|
||||
if (blocked) {
|
||||
b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
|
||||
} else {
|
||||
b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x1);
|
||||
b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
|
||||
b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x2);
|
||||
}
|
||||
}
|
||||
|
||||
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 int b43_phy_ht_op_switch_channel(struct b43_wldev *dev,
|
||||
unsigned int new_channel)
|
||||
{
|
||||
struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
|
||||
enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
if ((new_channel < 1) || (new_channel > 14))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return b43_phy_ht_set_channel(dev, channel, channel_type);
|
||||
}
|
||||
|
||||
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,
|
||||
*/
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
#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_RF_CTL1 B43_PHY_EXTG(0x010)
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
/* Values for PHY registers used on channel switching */
|
||||
struct b43_phy_ht_channeltab_e_phy {
|
||||
/* TODO */
|
||||
};
|
||||
|
||||
|
||||
struct b43_phy_ht {
|
||||
};
|
||||
|
||||
|
||||
struct b43_phy_operations;
|
||||
extern const struct b43_phy_operations b43_phyops_ht;
|
||||
|
||||
#endif /* B43_PHY_HT_H_ */
|
|
@ -4025,11 +4025,24 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
|
|||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
|
||||
static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
|
||||
{
|
||||
u16 val = on ? 0 : 0x7FFF;
|
||||
u16 override = on ? 0x0 : 0x7FFF;
|
||||
u16 core = on ? 0xD : 0x00FD;
|
||||
|
||||
if (dev->phy.rev >= 3)
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, val);
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_OVER, val);
|
||||
if (dev->phy.rev >= 3) {
|
||||
if (on) {
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_C2, core);
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override);
|
||||
} else {
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override);
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_C2, core);
|
||||
}
|
||||
} else {
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override);
|
||||
}
|
||||
}
|
||||
|
||||
static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
|
||||
|
|
|
@ -251,4 +251,9 @@ struct b43_nphy_channeltab_entry_rev2 {
|
|||
void b2055_upload_inittab(struct b43_wldev *dev,
|
||||
bool ghz5, bool ignore_uploadflag);
|
||||
|
||||
/* Get the NPHY Channel Switch Table entry for a channel.
|
||||
* Returns NULL on failure to find an entry. */
|
||||
const struct b43_nphy_channeltab_entry_rev2 *
|
||||
b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
|
||||
|
||||
#endif /* B43_RADIO_2055_H_ */
|
||||
|
|
|
@ -1117,4 +1117,9 @@ struct b43_nphy_channeltab_entry_rev3 {
|
|||
void b2056_upload_inittabs(struct b43_wldev *dev,
|
||||
bool ghz5, bool ignore_uploadflag);
|
||||
|
||||
/* Get the NPHY Channel Switch Table entry for a channel.
|
||||
* Returns NULL on failure to find an entry. */
|
||||
const struct b43_nphy_channeltab_entry_rev3 *
|
||||
b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq);
|
||||
|
||||
#endif /* B43_RADIO_2056_H_ */
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11n 2059 radio device data tables
|
||||
|
||||
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 "b43.h"
|
||||
#include "radio_2059.h"
|
||||
|
||||
const struct b43_phy_ht_channeltab_e_radio2059
|
||||
*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq)
|
||||
{
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef B43_RADIO_2059_H_
|
||||
#define B43_RADIO_2059_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "phy_ht.h"
|
||||
|
||||
/* Values for various registers uploaded on channel switching */
|
||||
struct b43_phy_ht_channeltab_e_radio2059 {
|
||||
/* The channel frequency in MHz */
|
||||
u16 freq;
|
||||
/* Values for radio registers */
|
||||
u8 radio_syn16;
|
||||
u8 radio_syn17;
|
||||
u8 radio_syn22;
|
||||
u8 radio_syn25;
|
||||
u8 radio_syn27;
|
||||
u8 radio_syn28;
|
||||
u8 radio_syn29;
|
||||
u8 radio_syn2c;
|
||||
u8 radio_syn2d;
|
||||
u8 radio_syn37;
|
||||
u8 radio_syn41;
|
||||
u8 radio_syn43;
|
||||
u8 radio_syn47;
|
||||
u8 radio_syn4a;
|
||||
u8 radio_syn58;
|
||||
u8 radio_syn5a;
|
||||
u8 radio_syn6a;
|
||||
u8 radio_syn6d;
|
||||
u8 radio_syn6e;
|
||||
u8 radio_syn92;
|
||||
u8 radio_syn98;
|
||||
u8 radio_rxtx4a;
|
||||
u8 radio_rxtx58;
|
||||
u8 radio_rxtx5a;
|
||||
u8 radio_rxtx6a;
|
||||
u8 radio_rxtx6d;
|
||||
u8 radio_rxtx6e;
|
||||
u8 radio_rxtx92;
|
||||
u8 radio_rxtx98;
|
||||
/* Values for PHY registers */
|
||||
struct b43_phy_ht_channeltab_e_phy phy_regs;
|
||||
};
|
||||
|
||||
const struct b43_phy_ht_channeltab_e_radio2059
|
||||
*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq);
|
||||
|
||||
#endif /* B43_RADIO_2059_H_ */
|
|
@ -93,8 +93,8 @@ void b43_sdio_free_irq(struct b43_wldev *dev)
|
|||
sdio->irq_handler = NULL;
|
||||
}
|
||||
|
||||
static int b43_sdio_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
static int __devinit b43_sdio_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
struct b43_sdio *sdio;
|
||||
struct sdio_func_tuple *tuple;
|
||||
|
@ -171,7 +171,7 @@ out:
|
|||
return error;
|
||||
}
|
||||
|
||||
static void b43_sdio_remove(struct sdio_func *func)
|
||||
static void __devexit b43_sdio_remove(struct sdio_func *func)
|
||||
{
|
||||
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
||||
|
||||
|
|
|
@ -60,16 +60,8 @@ struct nphy_gain_ctl_workaround_entry {
|
|||
struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
|
||||
struct b43_wldev *dev, bool ghz5, bool ext_lna);
|
||||
|
||||
/* Get the NPHY Channel Switch Table entry for a channel.
|
||||
* Returns NULL on failure to find an entry. */
|
||||
const struct b43_nphy_channeltab_entry_rev2 *
|
||||
b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
|
||||
const struct b43_nphy_channeltab_entry_rev3 *
|
||||
b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq);
|
||||
|
||||
|
||||
/* The N-PHY tables. */
|
||||
|
||||
#define B43_NTAB_TYPEMASK 0xF0000000
|
||||
#define B43_NTAB_8BIT 0x10000000
|
||||
#define B43_NTAB_16BIT 0x20000000
|
||||
|
|
|
@ -408,7 +408,6 @@ 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));
|
||||
}
|
||||
|
@ -2640,7 +2639,6 @@ 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,
|
||||
|
@ -2698,9 +2696,7 @@ 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 = {
|
||||
|
|
|
@ -694,47 +694,6 @@ 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,
|
||||
|
@ -858,16 +817,13 @@ 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 = 0;
|
||||
u16 interval;
|
||||
u32 extra;
|
||||
u32 suspend_time = 100;
|
||||
u32 scan_suspend_time = 100;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
|
||||
if (priv->is_internal_short_scan)
|
||||
interval = 0;
|
||||
else
|
||||
interval = vif->bss_conf.beacon_int;
|
||||
interval = vif->bss_conf.beacon_int;
|
||||
|
||||
scan->suspend_time = 0;
|
||||
scan->max_out_time = cpu_to_le32(200 * 1024);
|
||||
|
@ -882,9 +838,7 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
|||
scan_suspend_time, interval);
|
||||
}
|
||||
|
||||
if (priv->is_internal_short_scan) {
|
||||
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
|
||||
} else if (priv->scan_request->n_ssids) {
|
||||
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++) {
|
||||
|
@ -981,38 +935,21 @@ 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);
|
||||
if (!priv->is_internal_short_scan) {
|
||||
cmd_len = iwl_legacy_fill_probe_req(priv,
|
||||
|
||||
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);
|
||||
|
||||
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)]);
|
||||
}
|
||||
scan->channel_count = iwl4965_get_channels_for_scan(priv, vif, band,
|
||||
is_active, n_probes,
|
||||
(void *)&scan->data[cmd_len]);
|
||||
if (scan->channel_count == 0) {
|
||||
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
|
||||
return -EIO;
|
||||
|
|
|
@ -151,81 +151,6 @@ 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)
|
||||
{
|
||||
|
@ -248,8 +173,7 @@ void iwl4965_rx_statistics(struct iwl_priv *priv,
|
|||
iwl4965_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
|
||||
#endif
|
||||
|
||||
iwl_legacy_recover_from_statistics(priv, pkt);
|
||||
|
||||
/* TODO: reading some of statistics is unneeded */
|
||||
memcpy(&priv->_4965.statistics, &pkt->u.stats,
|
||||
sizeof(priv->_4965.statistics));
|
||||
|
||||
|
|
|
@ -2069,7 +2069,6 @@ 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,
|
||||
|
@ -2100,7 +2099,6 @@ 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 = {
|
||||
|
@ -2150,10 +2148,8 @@ 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,
|
||||
|
|
|
@ -2297,14 +2297,7 @@ 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;
|
||||
|
|
|
@ -931,7 +931,6 @@ 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,
|
||||
|
@ -1707,41 +1706,14 @@ iwl_legacy_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
|
|||
EXPORT_SYMBOL(iwl_legacy_update_stats);
|
||||
#endif
|
||||
|
||||
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)
|
||||
int iwl_legacy_force_reset(struct iwl_priv *priv, bool external)
|
||||
{
|
||||
struct iwl_force_reset *force_reset;
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return -EINVAL;
|
||||
|
||||
if (mode >= IWL_MAX_FORCE_RESET) {
|
||||
IWL_DEBUG_INFO(priv, "invalid reset request.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
force_reset = &priv->force_reset[mode];
|
||||
force_reset = &priv->force_reset;
|
||||
force_reset->reset_request_count++;
|
||||
if (!external) {
|
||||
if (force_reset->last_force_reset_jiffies &&
|
||||
|
@ -1754,37 +1726,34 @@ int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external)
|
|||
}
|
||||
force_reset->reset_success_count++;
|
||||
force_reset->last_force_reset_jiffies = jiffies;
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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_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;
|
||||
}
|
||||
|
||||
|
@ -1879,7 +1848,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, IWL_FW_RESET, false);
|
||||
ret = iwl_legacy_force_reset(priv, false);
|
||||
return (ret == -EAGAIN) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,8 +143,7 @@ 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,
|
||||
|
@ -161,9 +160,6 @@ 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;
|
||||
|
||||
|
@ -207,11 +203,8 @@ 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
|
||||
|
@ -229,10 +222,8 @@ 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;
|
||||
|
@ -441,7 +432,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, int mode, bool external);
|
||||
int iwl_legacy_force_reset(struct iwl_priv *priv, 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);
|
||||
|
@ -521,8 +512,6 @@ 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);
|
||||
|
|
|
@ -391,48 +391,6 @@ 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)
|
||||
|
@ -706,7 +664,6 @@ 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);
|
||||
|
@ -1098,56 +1055,6 @@ 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) {
|
||||
|
@ -1236,72 +1143,31 @@ static ssize_t iwl_legacy_dbgfs_missed_beacon_write(struct file *file,
|
|||
return count;
|
||||
}
|
||||
|
||||
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[12];
|
||||
const size_t bufsz = sizeof(buf);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
|
||||
priv->cfg->base_params->plcp_delta_threshold);
|
||||
|
||||
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;
|
||||
int 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);
|
||||
}
|
||||
force_reset = &priv->force_reset;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1309,25 +1175,11 @@ 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;
|
||||
|
||||
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;
|
||||
}
|
||||
ret = iwl_legacy_force_reset(priv, true);
|
||||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
|
||||
|
@ -1367,10 +1219,8 @@ 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);
|
||||
|
@ -1403,7 +1253,6 @@ 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);
|
||||
|
@ -1420,7 +1269,6 @@ 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);
|
||||
|
@ -1430,8 +1278,6 @@ 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);
|
||||
|
|
|
@ -855,32 +855,6 @@ struct traffic_stats {
|
|||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -896,18 +870,6 @@ struct iwl_event_log {
|
|||
#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 */
|
||||
|
@ -915,12 +877,6 @@ struct iwl_event_log {
|
|||
#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;
|
||||
|
@ -1033,11 +989,8 @@ 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[IWL_MAX_FORCE_RESET];
|
||||
struct iwl_force_reset force_reset;
|
||||
|
||||
/* we allocate array of iwl_channel_info for NIC's valid channels.
|
||||
* Access via channel # using indirect index array */
|
||||
|
@ -1058,7 +1011,6 @@ 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;
|
||||
|
||||
|
@ -1213,12 +1165,6 @@ 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;
|
||||
|
||||
|
@ -1257,7 +1203,6 @@ 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;
|
||||
|
@ -1294,12 +1239,9 @@ 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;
|
||||
|
|
|
@ -38,8 +38,5 @@ 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
|
||||
|
|
|
@ -96,47 +96,6 @@ 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
|
||||
|
||||
|
@ -242,25 +201,6 @@ 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
|
||||
|
|
|
@ -132,7 +132,16 @@ 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)
|
||||
|
|
|
@ -227,27 +227,6 @@ 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
|
||||
*/
|
||||
|
|
|
@ -101,7 +101,6 @@ 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;
|
||||
}
|
||||
|
@ -329,10 +328,8 @@ void iwl_legacy_init_scan_params(struct iwl_priv *priv)
|
|||
}
|
||||
EXPORT_SYMBOL(iwl_legacy_init_scan_params);
|
||||
|
||||
static int __must_check iwl_legacy_scan_initiate(struct iwl_priv *priv,
|
||||
struct ieee80211_vif *vif,
|
||||
bool internal,
|
||||
enum ieee80211_band band)
|
||||
static int iwl_legacy_scan_initiate(struct iwl_priv *priv,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -359,18 +356,14 @@ static int __must_check iwl_legacy_scan_initiate(struct iwl_priv *priv,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
|
||||
internal ? "internal short " : "");
|
||||
IWL_DEBUG_SCAN(priv, "Starting scan...\n");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -394,8 +387,7 @@ int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw,
|
|||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (test_bit(STATUS_SCANNING, &priv->status) &&
|
||||
!priv->is_internal_short_scan) {
|
||||
if (test_bit(STATUS_SCANNING, &priv->status)) {
|
||||
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
|
||||
ret = -EAGAIN;
|
||||
goto out_unlock;
|
||||
|
@ -404,17 +396,9 @@ 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;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
ret = iwl_legacy_scan_initiate(priv, vif);
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
|
||||
|
@ -425,40 +409,6 @@ out_unlock:
|
|||
}
|
||||
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 =
|
||||
|
@ -542,8 +492,7 @@ 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 %sscan.\n",
|
||||
priv->is_internal_short_scan ? "internal short " : "");
|
||||
IWL_DEBUG_SCAN(priv, "Completed scan.\n");
|
||||
|
||||
cancel_delayed_work(&priv->scan_check);
|
||||
|
||||
|
@ -558,27 +507,6 @@ 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:
|
||||
|
@ -590,8 +518,7 @@ out_settings:
|
|||
* 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);
|
||||
|
@ -604,15 +531,12 @@ 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);
|
||||
|
||||
|
|
|
@ -1409,212 +1409,6 @@ 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;
|
||||
|
@ -1762,49 +1556,6 @@ 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,
|
||||
|
@ -2816,6 +2567,7 @@ 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);
|
||||
|
||||
|
@ -2834,17 +2586,14 @@ 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 = 0;
|
||||
u16 interval;
|
||||
u32 extra;
|
||||
u32 suspend_time = 100;
|
||||
u32 scan_suspend_time = 100;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
|
||||
|
||||
if (priv->is_internal_short_scan)
|
||||
interval = 0;
|
||||
else
|
||||
interval = vif->bss_conf.beacon_int;
|
||||
interval = vif->bss_conf.beacon_int;
|
||||
|
||||
scan->suspend_time = 0;
|
||||
scan->max_out_time = cpu_to_le32(200 * 1024);
|
||||
|
@ -2866,9 +2615,7 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
|||
scan_suspend_time, interval);
|
||||
}
|
||||
|
||||
if (priv->is_internal_short_scan) {
|
||||
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
|
||||
} else if (priv->scan_request->n_ssids) {
|
||||
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++) {
|
||||
|
@ -2919,36 +2666,17 @@ 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;
|
||||
|
||||
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)));
|
||||
}
|
||||
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);
|
||||
|
||||
/* select Rx antennas */
|
||||
scan->flags |= iwl3945_get_antenna_flags(priv);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
scan->channel_count = iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
|
||||
(void *)&scan->data[len], vif);
|
||||
if (scan->channel_count == 0) {
|
||||
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
|
||||
return -EIO;
|
||||
|
@ -3824,10 +3552,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
|
|||
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
|
||||
|
||||
/* initialize force reset */
|
||||
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;
|
||||
priv->force_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",
|
||||
|
|
|
@ -488,134 +488,6 @@ 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)
|
||||
{
|
||||
|
@ -1711,209 +1583,6 @@ 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;
|
||||
|
@ -2773,20 +2442,10 @@ 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;
|
||||
|
@ -2851,7 +2510,6 @@ 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");
|
||||
|
||||
|
@ -2868,64 +2526,64 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw,
|
|||
if (!iwl_legacy_is_associated_ctx(ctx))
|
||||
goto out;
|
||||
|
||||
if (priv->cfg->ops->lib->set_channel_switch) {
|
||||
if (!priv->cfg->ops->lib->set_channel_switch)
|
||||
goto out;
|
||||
|
||||
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);
|
||||
ch = channel->hw_value;
|
||||
if (le16_to_cpu(ctx->active.channel) == ch)
|
||||
goto out;
|
||||
|
||||
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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
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_irq(&priv->lock);
|
||||
|
||||
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_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);
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
|
@ -3034,10 +2692,6 @@ 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;
|
||||
|
@ -3056,7 +2710,6 @@ 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,
|
||||
|
@ -3132,13 +2785,9 @@ 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[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;
|
||||
priv->force_reset.reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD;
|
||||
|
||||
/* Choose which receivers/antennas to use */
|
||||
if (priv->cfg->ops->hcmd->set_rxon_chain)
|
||||
|
|
|
@ -13,6 +13,7 @@ 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
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
@ -194,8 +192,6 @@ 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 = {
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
@ -76,21 +74,7 @@ static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
|
|||
/* NIC configuration for 2000 series */
|
||||
static void iwl2000_nic_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));
|
||||
|
||||
/* 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);
|
||||
iwl_rf_config(priv);
|
||||
|
||||
if (priv->cfg->iq_invert)
|
||||
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
|
||||
|
@ -204,8 +188,6 @@ 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 = {
|
||||
|
|
|
@ -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_5000_TEMPERATURE);
|
||||
(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE);
|
||||
|
||||
temperature = le16_to_cpu(temp_calib[0]);
|
||||
voltage = le16_to_cpu(temp_calib[1]);
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
@ -66,24 +64,11 @@
|
|||
static void iwl5000_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
u16 radio_cfg;
|
||||
|
||||
iwl_rf_config(priv);
|
||||
|
||||
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.
|
||||
|
@ -361,8 +346,6 @@ 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 = {
|
||||
|
@ -391,8 +374,6 @@ 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 = {
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
@ -97,21 +95,7 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv)
|
|||
/* NIC configuration for 6000 series */
|
||||
static void iwl6000_nic_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));
|
||||
|
||||
/* 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);
|
||||
iwl_rf_config(priv);
|
||||
|
||||
/* no locking required for register write */
|
||||
if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
|
||||
|
@ -301,8 +285,6 @@ 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 = {
|
||||
|
@ -333,8 +315,6 @@ 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 = {
|
||||
|
|
|
@ -108,18 +108,16 @@ err:
|
|||
|
||||
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 =
|
||||
((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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (!priv->cfg->sku) {
|
||||
IWL_ERR(priv, "Invalid device sku\n");
|
||||
|
|
|
@ -111,10 +111,8 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
|
|||
|
||||
memset(&cmd, 0, sizeof(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;
|
||||
iwl_set_calib_hdr(&cmd.hdr,
|
||||
priv->_agn.phy_calib_chain_noise_gain_cmd);
|
||||
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,
|
||||
|
@ -144,10 +142,8 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
|
|||
data->beacon_count = 0;
|
||||
|
||||
memset(&cmd, 0, sizeof(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;
|
||||
iwl_set_calib_hdr(&cmd.hdr,
|
||||
priv->_agn.phy_calib_chain_noise_reset_cmd);
|
||||
ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
|
||||
sizeof(cmd), &cmd);
|
||||
if (ret)
|
||||
|
|
|
@ -81,13 +81,6 @@
|
|||
/* 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 */
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
void iwl_free_isr_ict(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->_agn.ict_tbl_vir) {
|
||||
dma_free_coherent(&priv->pci_dev->dev,
|
||||
dma_free_coherent(priv->bus.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->pci_dev->dev,
|
||||
dma_alloc_coherent(priv->bus.dev,
|
||||
(sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
|
||||
&priv->_agn.ict_tbl_dma, GFP_KERNEL);
|
||||
if (!priv->_agn.ict_tbl_vir)
|
||||
|
|
|
@ -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_WARN(priv, "receive reply tx with bt_kill\n");
|
||||
IWL_DEBUG_COEX(priv, "receive reply tx with bt_kill\n");
|
||||
}
|
||||
iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
|
||||
|
||||
|
@ -622,6 +622,9 @@ 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 */
|
||||
};
|
||||
|
||||
|
@ -637,9 +640,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) {
|
||||
pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
|
||||
dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma,
|
||||
PAGE_SIZE << priv->hw_params.rx_page_order,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
DMA_FROM_DEVICE);
|
||||
__iwl_free_pages(priv, rxq->pool[i].page);
|
||||
rxq->pool[i].page = NULL;
|
||||
}
|
||||
|
@ -911,9 +914,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 = pci_map_page(priv->pci_dev, page, 0,
|
||||
rxb->page_dma = dma_map_page(priv->bus.dev, page, 0,
|
||||
PAGE_SIZE << priv->hw_params.rx_page_order,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
DMA_FROM_DEVICE);
|
||||
/* dma address must be no more than 36 bits */
|
||||
BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
|
||||
/* and also 256 byte aligned! */
|
||||
|
@ -956,17 +959,18 @@ 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) {
|
||||
pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
|
||||
dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma,
|
||||
PAGE_SIZE << priv->hw_params.rx_page_order,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
DMA_FROM_DEVICE);
|
||||
__iwl_free_pages(priv, rxq->pool[i].page);
|
||||
rxq->pool[i].page = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
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),
|
||||
rxq->rb_stts, rxq->rb_stts_dma);
|
||||
rxq->bd = NULL;
|
||||
rxq->rb_stts = NULL;
|
||||
|
@ -1528,9 +1532,18 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
|
|||
might_sleep();
|
||||
|
||||
memset(&flush_cmd, 0, sizeof(flush_cmd));
|
||||
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)
|
||||
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_AGG_TX_QUEUE_MSK;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
|
||||
|
@ -1544,7 +1557,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
|
|||
{
|
||||
mutex_lock(&priv->mutex);
|
||||
ieee80211_stop_queues(priv->hw);
|
||||
if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
|
||||
if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) {
|
||||
IWL_ERR(priv, "flush request fail\n");
|
||||
goto done;
|
||||
}
|
||||
|
@ -1699,7 +1712,8 @@ 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 (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) {
|
||||
if (!iwlagn_mod_params.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 <<
|
||||
|
@ -1710,7 +1724,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_INFO(priv, "BT coex flag: 0X%x\n", basic.flags);
|
||||
IWL_DEBUG_COEX(priv, "BT coex flag: 0X%x\n", basic.flags);
|
||||
}
|
||||
priv->bt_enable_flag = basic.flags;
|
||||
if (priv->bt_full_concurrent)
|
||||
|
@ -1720,7 +1734,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_INFO(priv, "BT coex %s in %s mode\n",
|
||||
IWL_DEBUG_COEX(priv, "BT coex %s in %s mode\n",
|
||||
basic.flags ? "active" : "disabled",
|
||||
priv->bt_full_concurrent ?
|
||||
"full concurrency" : "3-wire");
|
||||
|
@ -1758,7 +1772,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_INFO(priv, "BT traffic load changes: %d\n",
|
||||
IWL_DEBUG_COEX(priv, "BT traffic load changes: %d\n",
|
||||
priv->bt_traffic_load);
|
||||
|
||||
switch (priv->bt_traffic_load) {
|
||||
|
@ -1810,7 +1824,7 @@ out:
|
|||
static void iwlagn_print_uartmsg(struct iwl_priv *priv,
|
||||
struct iwl_bt_uart_msg *uart_msg)
|
||||
{
|
||||
IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, "
|
||||
IWL_DEBUG_COEX(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,
|
||||
|
@ -1819,7 +1833,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_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, "
|
||||
IWL_DEBUG_COEX(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,
|
||||
|
@ -1830,7 +1844,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_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, "
|
||||
IWL_DEBUG_COEX(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,
|
||||
|
@ -1845,11 +1859,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_NOTIF(priv, "Idle duration = 0x%X",
|
||||
IWL_DEBUG_COEX(priv, "Idle duration = 0x%X",
|
||||
(BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >>
|
||||
BT_UART_MSG_FRAME4IDLEDURATION_POS);
|
||||
|
||||
IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, "
|
||||
IWL_DEBUG_COEX(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,
|
||||
|
@ -1858,13 +1872,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_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X",
|
||||
IWL_DEBUG_COEX(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_NOTIF(priv, "Sniff Activity = 0x%X, Page = "
|
||||
IWL_DEBUG_COEX(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,
|
||||
|
@ -1914,10 +1928,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
|
|||
return;
|
||||
}
|
||||
|
||||
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",
|
||||
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",
|
||||
coex->bt_ci_compliance);
|
||||
iwlagn_print_uartmsg(priv, uart_msg);
|
||||
|
||||
|
@ -2315,7 +2329,8 @@ int iwlagn_start_device(struct iwl_priv *priv)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (iwl_prepare_card_hw(priv)) {
|
||||
if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
|
||||
iwl_prepare_card_hw(priv)) {
|
||||
IWL_WARN(priv, "Exit HW not ready\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
|
|
@ -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_POWER(priv, "schedule ct_kill exit timer\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Stop all queues\n");
|
||||
IWL_DEBUG_TEMP(priv, "Stop all queues\n");
|
||||
if (priv->mac80211_registered)
|
||||
ieee80211_stop_queues(priv->hw);
|
||||
IWL_DEBUG_POWER(priv,
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Wake all queues\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "entering CT_KILL state when "
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv,
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Temperature state changed %u\n",
|
||||
IWL_DEBUG_TEMP(priv, "Temperature state changed %u\n",
|
||||
tt->state);
|
||||
IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
|
||||
IWL_DEBUG_TEMP(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_POWER(priv,
|
||||
IWL_DEBUG_TEMP(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_POWER(priv,
|
||||
IWL_DEBUG_TEMP(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_POWER(priv,
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Exit IWL_TI_CT_KILL\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Queueing critical temperature enter.\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Queueing critical temperature exit.\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Queueing thermal throttling work.\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Initialize Thermal Throttling\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Advanced Thermal Throttling\n");
|
||||
IWL_DEBUG_TEMP(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_POWER(priv, "Legacy Thermal Throttling\n");
|
||||
IWL_DEBUG_TEMP(priv, "Legacy Thermal Throttling\n");
|
||||
priv->thermal_throttle.advanced_tt = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = pci_map_single(priv->pci_dev,
|
||||
txcmd_phys = dma_map_single(priv->bus.dev,
|
||||
&out_cmd->hdr, firstlen,
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
if (unlikely(pci_dma_mapping_error(priv->pci_dev, txcmd_phys)))
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (unlikely(dma_mapping_error(priv->bus.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 = 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,
|
||||
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,
|
||||
dma_unmap_addr(out_meta, mapping),
|
||||
dma_unmap_len(out_meta, len),
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
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 */
|
||||
pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
|
||||
firstlen, PCI_DMA_BIDIRECTIONAL);
|
||||
dma_sync_single_for_cpu(priv->bus.dev, txcmd_phys, firstlen,
|
||||
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));
|
||||
|
||||
pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
|
||||
firstlen, PCI_DMA_BIDIRECTIONAL);
|
||||
dma_sync_single_for_device(priv->bus.dev, txcmd_phys, firstlen,
|
||||
DMA_BIDIRECTIONAL);
|
||||
|
||||
trace_iwlwifi_dev_tx(priv,
|
||||
&((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
|
||||
|
@ -834,8 +834,8 @@ drop_unlock_priv:
|
|||
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->pci_dev->dev, size, &ptr->dma,
|
||||
GFP_KERNEL);
|
||||
ptr->addr = dma_alloc_coherent(priv->bus.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->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
|
||||
dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma);
|
||||
memset(ptr, 0, sizeof(*ptr));
|
||||
}
|
||||
|
||||
|
|
|
@ -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_INFO(priv, "%s uCode section being loaded...\n", name);
|
||||
IWL_DEBUG_FW(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,10 +183,7 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
|
|||
__le16 *xtal_calib =
|
||||
(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL);
|
||||
|
||||
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;
|
||||
iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD);
|
||||
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],
|
||||
|
@ -197,15 +194,14 @@ 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_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;
|
||||
(__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);
|
||||
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],
|
||||
|
@ -508,7 +504,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv,
|
|||
u32 val;
|
||||
u32 i;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
|
||||
IWL_DEBUG_FW(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 */
|
||||
|
@ -533,7 +529,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv,
|
|||
u32 offs;
|
||||
int errors = 0;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
|
||||
IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
|
||||
|
||||
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
|
@ -559,7 +555,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_INFO(priv, "uCode is good in inst SRAM\n");
|
||||
IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -583,7 +579,7 @@ static void iwlagn_alive_fn(struct iwl_priv *priv,
|
|||
|
||||
palive = &pkt->u.alive_frame;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
|
||||
IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision "
|
||||
"0x%01X 0x%01X\n",
|
||||
palive->is_valid, palive->ver_type,
|
||||
palive->ver_subtype);
|
||||
|
@ -602,12 +598,12 @@ static void iwlagn_alive_fn(struct iwl_priv *priv,
|
|||
|
||||
int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
struct fw_img *image,
|
||||
int subtype, int alternate_subtype)
|
||||
enum iwlagn_ucode_type ucode_type)
|
||||
{
|
||||
struct iwl_notification_wait alive_wait;
|
||||
struct iwlagn_alive_data alive_data;
|
||||
int ret;
|
||||
enum iwlagn_ucode_subtype old_type;
|
||||
enum iwlagn_ucode_type old_type;
|
||||
|
||||
ret = iwlagn_start_device(priv);
|
||||
if (ret)
|
||||
|
@ -617,7 +613,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
|
|||
iwlagn_alive_fn, &alive_data);
|
||||
|
||||
old_type = priv->ucode_type;
|
||||
priv->ucode_type = subtype;
|
||||
priv->ucode_type = ucode_type;
|
||||
|
||||
ret = iwlagn_load_given_ucode(priv, image);
|
||||
if (ret) {
|
||||
|
@ -645,15 +641,6 @@ 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;
|
||||
|
@ -685,7 +672,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv)
|
|||
if (!priv->ucode_init.code.len)
|
||||
return 0;
|
||||
|
||||
if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED)
|
||||
if (priv->ucode_type != IWL_UCODE_NONE)
|
||||
return 0;
|
||||
|
||||
iwlagn_init_notification_wait(priv, &calib_wait,
|
||||
|
@ -694,7 +681,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,
|
||||
UCODE_SUBTYPE_INIT, -1);
|
||||
IWL_UCODE_INIT);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci-aspm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -49,8 +47,6 @@
|
|||
|
||||
#include <asm/div64.h>
|
||||
|
||||
#define DRV_NAME "iwlagn"
|
||||
|
||||
#include "iwl-eeprom.h"
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
|
@ -59,6 +55,7 @@
|
|||
#include "iwl-sta.h"
|
||||
#include "iwl-agn-calib.h"
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-pci.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -440,10 +437,8 @@ static void iwl_bg_tx_flush(struct work_struct *work)
|
|||
if (!iwl_is_ready_rf(priv))
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
|
||||
iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -497,9 +492,9 @@ static void iwl_rx_handle(struct iwl_priv *priv)
|
|||
|
||||
rxq->queue[i] = NULL;
|
||||
|
||||
pci_unmap_page(priv->pci_dev, rxb->page_dma,
|
||||
dma_unmap_page(priv->bus.dev, rxb->page_dma,
|
||||
PAGE_SIZE << priv->hw_params.rx_page_order,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
DMA_FROM_DEVICE);
|
||||
pkt = rxb_addr(rxb);
|
||||
|
||||
len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
|
||||
|
@ -581,9 +576,9 @@ static void iwl_rx_handle(struct iwl_priv *priv)
|
|||
* rx_free list for reuse later. */
|
||||
spin_lock_irqsave(&rxq->lock, flags);
|
||||
if (rxb->page != NULL) {
|
||||
rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page,
|
||||
rxb->page_dma = dma_map_page(priv->bus.dev, rxb->page,
|
||||
0, PAGE_SIZE << priv->hw_params.rx_page_order,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
DMA_FROM_DEVICE);
|
||||
list_add_tail(&rxb->list, &rxq->rx_free);
|
||||
rxq->free_count++;
|
||||
} else
|
||||
|
@ -939,22 +934,28 @@ static struct attribute_group iwl_attribute_group = {
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc)
|
||||
static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc)
|
||||
{
|
||||
if (desc->v_addr)
|
||||
dma_free_coherent(&pci_dev->dev, desc->len,
|
||||
dma_free_coherent(priv->bus.dev, desc->len,
|
||||
desc->v_addr, desc->p_addr);
|
||||
desc->v_addr = NULL;
|
||||
desc->len = 0;
|
||||
}
|
||||
|
||||
static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img)
|
||||
static void iwl_free_fw_img(struct iwl_priv *priv, struct fw_img *img)
|
||||
{
|
||||
iwl_free_fw_desc(pci_dev, &img->code);
|
||||
iwl_free_fw_desc(pci_dev, &img->data);
|
||||
iwl_free_fw_desc(priv, &img->code);
|
||||
iwl_free_fw_desc(priv, &img->data);
|
||||
}
|
||||
|
||||
static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc,
|
||||
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,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
if (!len) {
|
||||
|
@ -962,21 +963,16 @@ static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len,
|
||||
desc->v_addr = dma_alloc_coherent(priv->bus.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;
|
||||
|
@ -1021,8 +1017,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->pci_dev->dev, GFP_KERNEL, priv,
|
||||
iwl_ucode_callback);
|
||||
priv->bus.dev,
|
||||
GFP_KERNEL, priv, iwl_ucode_callback);
|
||||
}
|
||||
|
||||
struct iwlagn_firmware_pieces {
|
||||
|
@ -1443,19 +1439,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->pci_dev, &priv->ucode_rt.code,
|
||||
if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.code,
|
||||
pieces.inst, pieces.inst_size))
|
||||
goto err_pci_alloc;
|
||||
if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data,
|
||||
if (iwl_alloc_fw_desc(priv, &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->pci_dev, &priv->ucode_init.code,
|
||||
if (iwl_alloc_fw_desc(priv, &priv->ucode_init.code,
|
||||
pieces.init, pieces.init_size))
|
||||
goto err_pci_alloc;
|
||||
if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data,
|
||||
if (iwl_alloc_fw_desc(priv, &priv->ucode_init.data,
|
||||
pieces.init_data, pieces.init_data_size))
|
||||
goto err_pci_alloc;
|
||||
}
|
||||
|
@ -1485,7 +1481,8 @@ 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 (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
|
||||
if ((priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE) &&
|
||||
(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
|
||||
|
@ -1523,7 +1520,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->pci_dev->dev.kobj,
|
||||
err = sysfs_create_group(&(priv->bus.dev->kobj),
|
||||
&iwl_attribute_group);
|
||||
if (err) {
|
||||
IWL_ERR(priv, "failed to create sysfs device attributes\n");
|
||||
|
@ -1544,10 +1541,10 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
|||
|
||||
err_pci_alloc:
|
||||
IWL_ERR(priv, "failed to allocate pci memory\n");
|
||||
iwl_dealloc_ucode_pci(priv);
|
||||
iwl_dealloc_ucode(priv);
|
||||
out_unbind:
|
||||
complete(&priv->_agn.firmware_loading_complete);
|
||||
device_release_driver(&priv->pci_dev->dev);
|
||||
device_release_driver(priv->bus.dev);
|
||||
release_firmware(ucode_raw);
|
||||
}
|
||||
|
||||
|
@ -1626,7 +1623,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 == UCODE_SUBTYPE_INIT) {
|
||||
if (priv->ucode_type == IWL_UCODE_INIT) {
|
||||
if (!base)
|
||||
base = priv->_agn.init_errlog_ptr;
|
||||
} else {
|
||||
|
@ -1638,7 +1635,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 == UCODE_SUBTYPE_INIT)
|
||||
(priv->ucode_type == IWL_UCODE_INIT)
|
||||
? "Init" : "RT");
|
||||
return;
|
||||
}
|
||||
|
@ -1702,7 +1699,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 == UCODE_SUBTYPE_INIT) {
|
||||
if (priv->ucode_type == IWL_UCODE_INIT) {
|
||||
if (!base)
|
||||
base = priv->_agn.init_evtlog_ptr;
|
||||
} else {
|
||||
|
@ -1815,7 +1812,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 == UCODE_SUBTYPE_INIT) {
|
||||
if (priv->ucode_type == IWL_UCODE_INIT) {
|
||||
logsize = priv->_agn.init_evtlog_size;
|
||||
if (!base)
|
||||
base = priv->_agn.init_evtlog_ptr;
|
||||
|
@ -1829,7 +1826,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 == UCODE_SUBTYPE_INIT)
|
||||
(priv->ucode_type == IWL_UCODE_INIT)
|
||||
? "Init" : "RT");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -2210,8 +2207,7 @@ static int __iwl_up(struct iwl_priv *priv)
|
|||
|
||||
ret = iwlagn_load_ucode_wait_alive(priv,
|
||||
&priv->ucode_rt,
|
||||
UCODE_SUBTYPE_REGULAR,
|
||||
UCODE_SUBTYPE_REGULAR_NEW);
|
||||
IWL_UCODE_REGULAR);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret);
|
||||
goto error;
|
||||
|
@ -2516,7 +2512,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 & IWL_SKU_N)
|
||||
if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||
hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
|
||||
IEEE80211_HW_SUPPORTS_STATIC_SMPS;
|
||||
|
||||
|
@ -2549,11 +2545,10 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
|
|||
WIPHY_FLAG_DISABLE_BEACON_HINTS |
|
||||
WIPHY_FLAG_IBSS_RSN;
|
||||
|
||||
/*
|
||||
* For now, disable PS by default because it affects
|
||||
* RX performance significantly.
|
||||
*/
|
||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
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;
|
||||
|
||||
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
|
||||
/* we create the 802.11 header and a zero-length SSID element */
|
||||
|
@ -2757,7 +2752,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
|
|||
IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
|
||||
sta->addr, tid);
|
||||
|
||||
if (!(priv->cfg->sku & IWL_SKU_N))
|
||||
if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE))
|
||||
return -EACCES;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
@ -3052,10 +3047,6 @@ 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;
|
||||
|
@ -3071,7 +3062,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
|
|||
*/
|
||||
if (drop) {
|
||||
IWL_DEBUG_MAC80211(priv, "send flush command\n");
|
||||
if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
|
||||
if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) {
|
||||
IWL_ERR(priv, "flush request fail\n");
|
||||
goto done;
|
||||
}
|
||||
|
@ -3352,14 +3343,11 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -3375,7 +3363,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 &= ~IWL_SKU_N;
|
||||
priv->cfg->sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
|
||||
|
||||
/* Device-specific setup */
|
||||
return priv->cfg->ops->lib->set_hw_params(priv);
|
||||
|
@ -3425,29 +3413,9 @@ out:
|
|||
return hw;
|
||||
}
|
||||
|
||||
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
static void iwl_init_context(struct iwl_priv *priv)
|
||||
{
|
||||
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;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* The default context is always valid,
|
||||
|
@ -3479,8 +3447,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
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;
|
||||
|
@ -3500,12 +3470,41 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;
|
||||
|
||||
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
|
||||
}
|
||||
|
||||
SET_IEEE80211_DEV(hw, &pdev->dev);
|
||||
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);
|
||||
|
||||
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 ? */
|
||||
|
@ -3521,52 +3520,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
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
|
||||
|
@ -3581,17 +3534,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
*/
|
||||
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_iounmap;
|
||||
goto out_free_traffic_mem;
|
||||
}
|
||||
|
||||
/*****************
|
||||
|
@ -3601,7 +3554,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
err = iwl_eeprom_init(priv, hw_rev);
|
||||
if (err) {
|
||||
IWL_ERR(priv, "Unable to init EEPROM\n");
|
||||
goto out_iounmap;
|
||||
goto out_free_traffic_mem;
|
||||
}
|
||||
err = iwl_eeprom_check_version(priv);
|
||||
if (err)
|
||||
|
@ -3624,10 +3577,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
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;
|
||||
}
|
||||
|
@ -3644,19 +3601,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
/********************
|
||||
* 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->pci_dev->irq, iwl_isr_ict,
|
||||
IRQF_SHARED, DRV_NAME, priv);
|
||||
err = request_irq(priv->bus.irq, iwl_isr_ict, IRQF_SHARED,
|
||||
DRV_NAME, priv);
|
||||
if (err) {
|
||||
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
|
||||
goto out_disable_msi;
|
||||
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus.irq);
|
||||
goto out_uninit_drv;
|
||||
}
|
||||
|
||||
iwl_setup_deferred_work(priv);
|
||||
|
@ -3664,16 +3615,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
iwl_testmode_init(priv);
|
||||
|
||||
/*********************************************
|
||||
* 8. Enable interrupts and read RFKILL state
|
||||
* 8. Enable interrupts
|
||||
*********************************************/
|
||||
|
||||
/* 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 */
|
||||
|
@ -3699,41 +3643,30 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
out_destroy_workqueue:
|
||||
destroy_workqueue(priv->workqueue);
|
||||
priv->workqueue = NULL;
|
||||
free_irq(priv->pci_dev->irq, priv);
|
||||
out_disable_msi:
|
||||
free_irq(priv->bus.irq, priv);
|
||||
iwl_free_isr_ict(priv);
|
||||
pci_disable_msi(priv->pci_dev);
|
||||
out_uninit_drv:
|
||||
iwl_uninit_drv(priv);
|
||||
out_free_eeprom:
|
||||
iwl_eeprom_free(priv);
|
||||
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:
|
||||
out_free_traffic_mem:
|
||||
iwl_free_traffic_mem(priv);
|
||||
ieee80211_free_hw(priv->hw);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
||||
void __devexit iwl_remove(struct iwl_priv * priv)
|
||||
{
|
||||
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(&pdev->dev.kobj, &iwl_attribute_group);
|
||||
sysfs_remove_group(&priv->bus.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
|
||||
|
@ -3763,7 +3696,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
|||
|
||||
iwl_synchronize_irq(priv);
|
||||
|
||||
iwl_dealloc_ucode_pci(priv);
|
||||
iwl_dealloc_ucode(priv);
|
||||
|
||||
if (priv->rxq.bd)
|
||||
iwlagn_rx_queue_free(priv, &priv->rxq);
|
||||
|
@ -3782,12 +3715,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
|||
priv->workqueue = NULL;
|
||||
iwl_free_traffic_mem(priv);
|
||||
|
||||
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);
|
||||
free_irq(priv->bus.irq, priv);
|
||||
priv->bus.ops->set_drv_data(&priv->bus, NULL);
|
||||
|
||||
iwl_uninit_drv(priv);
|
||||
|
||||
|
@ -3804,206 +3733,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
|||
* 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)
|
||||
{
|
||||
|
||||
|
@ -4017,12 +3746,10 @@ static int __init iwl_init(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = pci_register_driver(&iwl_driver);
|
||||
if (ret) {
|
||||
pr_err("Unable to initialize PCI module\n");
|
||||
goto error_register;
|
||||
}
|
||||
ret = iwl_pci_register_driver();
|
||||
|
||||
if (ret)
|
||||
goto error_register;
|
||||
return ret;
|
||||
|
||||
error_register:
|
||||
|
@ -4032,7 +3759,7 @@ error_register:
|
|||
|
||||
static void __exit iwl_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&iwl_driver);
|
||||
iwl_pci_unregister_driver();
|
||||
iwlagn_rate_control_unregister();
|
||||
}
|
||||
|
||||
|
@ -4074,3 +3801,47 @@ 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)");
|
||||
|
|
|
@ -125,10 +125,18 @@ 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->pci_dev->irq);
|
||||
synchronize_irq(priv->bus.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);
|
||||
|
@ -161,7 +169,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,
|
||||
int subtype, int alternate_subtype);
|
||||
enum iwlagn_ucode_type ucode_type);
|
||||
|
||||
/* lib */
|
||||
void iwl_check_abort_status(struct iwl_priv *priv,
|
||||
|
@ -343,6 +351,9 @@ 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
|
||||
|
@ -352,6 +363,13 @@ 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)
|
||||
{
|
||||
}
|
||||
|
@ -361,4 +379,8 @@ 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__ */
|
||||
|
|
|
@ -384,18 +384,6 @@ 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)
|
||||
*
|
||||
|
@ -984,15 +972,26 @@ struct iwl_rem_sta_cmd {
|
|||
u8 reserved2[2];
|
||||
} __packed;
|
||||
|
||||
#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))
|
||||
|
||||
/* 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_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00)
|
||||
|
||||
#define IWL_DROP_SINGLE 0
|
||||
#define IWL_DROP_SELECTED 1
|
||||
#define IWL_DROP_ALL 2
|
||||
#define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN))
|
||||
|
||||
/*
|
||||
* REPLY_TXFIFO_FLUSH = 0x1e(command and response)
|
||||
|
|
|
@ -43,27 +43,6 @@
|
|||
#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 };
|
||||
|
@ -164,7 +143,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 & IWL_SKU_N)
|
||||
if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||
iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
|
||||
IEEE80211_BAND_5GHZ);
|
||||
|
||||
|
@ -174,7 +153,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
|
|||
sband->bitrates = rates;
|
||||
sband->n_bitrates = IWL_RATE_COUNT_LEGACY;
|
||||
|
||||
if (priv->cfg->sku & IWL_SKU_N)
|
||||
if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||
iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
|
||||
IEEE80211_BAND_2GHZ);
|
||||
|
||||
|
@ -229,12 +208,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 & IWL_SKU_A) {
|
||||
priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
|
||||
char buf[32];
|
||||
priv->bus.ops->get_hw_id(&priv->bus, buf, sizeof(buf));
|
||||
IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
|
||||
"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;
|
||||
"Please send your %s to maintainer.\n", buf);
|
||||
priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
|
||||
}
|
||||
|
||||
IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
|
||||
|
@ -1018,8 +997,6 @@ void iwl_apm_stop(struct iwl_priv *priv)
|
|||
int iwl_apm_init(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
u16 lctl;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Init card's basic functions\n");
|
||||
|
||||
/*
|
||||
|
@ -1048,27 +1025,7 @@ 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);
|
||||
|
||||
/*
|
||||
* 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");
|
||||
}
|
||||
priv->bus.ops->apm_config(&priv->bus);
|
||||
|
||||
/* Configure analog phase-lock-loop before activating to D0A */
|
||||
if (priv->cfg->base_params->pll_cfg_val)
|
||||
|
@ -1179,7 +1136,7 @@ void iwl_send_bt_config(struct iwl_priv *priv)
|
|||
.kill_cts_mask = 0,
|
||||
};
|
||||
|
||||
if (!bt_coex_active)
|
||||
if (!iwlagn_mod_params.bt_coex_active)
|
||||
bt_cmd.flags = BT_COEX_DISABLE;
|
||||
else
|
||||
bt_cmd.flags = BT_COEX_ENABLE;
|
||||
|
@ -1969,11 +1926,8 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
int iwl_pci_suspend(struct device *device)
|
||||
int iwl_suspend(struct iwl_priv *priv)
|
||||
{
|
||||
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
|
||||
|
@ -1986,18 +1940,10 @@ int iwl_pci_suspend(struct device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int iwl_pci_resume(struct device *device)
|
||||
int iwl_resume(struct iwl_priv *priv)
|
||||
{
|
||||
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) &
|
||||
|
@ -2014,13 +1960,4 @@ int iwl_pci_resume(struct device *device)
|
|||
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 */
|
||||
|
|
|
@ -76,17 +76,8 @@ struct iwl_cmd;
|
|||
#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation"
|
||||
#define DRV_AUTHOR "<ilw@linux.intel.com>"
|
||||
|
||||
#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 {
|
||||
|
@ -146,10 +137,6 @@ 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 */
|
||||
|
@ -173,6 +160,11 @@ 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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -289,7 +281,7 @@ struct iwl_cfg {
|
|||
const unsigned int ucode_api_min;
|
||||
u8 valid_tx_ant;
|
||||
u8 valid_rx_ant;
|
||||
unsigned int sku;
|
||||
u16 sku;
|
||||
u16 eeprom_ver;
|
||||
u16 eeprom_calib_ver;
|
||||
const struct iwl_ops *ops;
|
||||
|
@ -480,36 +472,14 @@ 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_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
|
||||
|
||||
int iwl_suspend(struct iwl_priv *priv);
|
||||
int iwl_resume(struct iwl_priv *priv);
|
||||
#endif /* !CONFIG_PM */
|
||||
|
||||
/*****************************************************
|
||||
|
@ -624,7 +594,6 @@ 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;
|
||||
|
||||
|
||||
|
|
|
@ -32,10 +32,10 @@
|
|||
struct iwl_priv;
|
||||
extern u32 iwl_debug_level;
|
||||
|
||||
#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_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_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)
|
||||
#define IWL_DL_NOTIF (1 << 10)
|
||||
/* reserved (1 << 10) */
|
||||
#define IWL_DL_SCAN (1 << 11)
|
||||
/* 0x0000F000 - 0x00001000 */
|
||||
#define IWL_DL_ASSOC (1 << 12)
|
||||
#define IWL_DL_DROP (1 << 13)
|
||||
#define IWL_DL_TXPOWER (1 << 14)
|
||||
#define IWL_DL_AP (1 << 15)
|
||||
/* reserved (1 << 14) */
|
||||
#define IWL_DL_COEX (1 << 15)
|
||||
/* 0x000F0000 - 0x00010000 */
|
||||
#define IWL_DL_FW (1 << 16)
|
||||
#define IWL_DL_RF_KILL (1 << 17)
|
||||
|
@ -171,12 +171,10 @@ 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_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_COEX(p, f, a...) IWL_DEBUG(p, IWL_DL_COEX, 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...) \
|
||||
|
|
|
@ -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 == UCODE_SUBTYPE_INIT)
|
||||
if (priv->ucode_type == IWL_UCODE_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;
|
||||
|
||||
priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL);
|
||||
iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -2693,8 +2693,7 @@ 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);
|
||||
if (priv->cfg->ops->lib->dev_txfifo_flush)
|
||||
DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
|
||||
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);
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
#include "iwl-agn-rs.h"
|
||||
#include "iwl-agn-tt.h"
|
||||
|
||||
#define DRV_NAME "iwlagn"
|
||||
|
||||
struct iwl_tx_queue;
|
||||
|
||||
/* CT-KILL constants */
|
||||
|
@ -1169,14 +1171,63 @@ 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 */
|
||||
|
@ -1244,17 +1295,14 @@ struct iwl_priv {
|
|||
spinlock_t reg_lock; /* protect hw register access */
|
||||
struct mutex mutex;
|
||||
|
||||
/* basic pci-network driver stuff */
|
||||
struct pci_dev *pci_dev;
|
||||
|
||||
/* pci hardware address support */
|
||||
void __iomem *hw_base;
|
||||
struct iwl_bus bus; /* bus specific data */
|
||||
|
||||
/* 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;
|
||||
|
@ -1271,7 +1319,7 @@ struct iwl_priv {
|
|||
struct fw_img ucode_rt;
|
||||
struct fw_img ucode_init;
|
||||
|
||||
enum iwlagn_ucode_subtype ucode_type;
|
||||
enum iwlagn_ucode_type ucode_type;
|
||||
u8 ucode_write_complete; /* the image write is complete */
|
||||
char firmware_name[25];
|
||||
|
||||
|
|
|
@ -834,3 +834,28 @@ 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);
|
||||
}
|
||||
|
|
|
@ -110,12 +110,10 @@ enum {
|
|||
};
|
||||
|
||||
/* SKU Capabilities */
|
||||
/* 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_BAND_24GHZ (1 << 4)
|
||||
#define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5)
|
||||
#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.
|
||||
|
@ -164,16 +162,12 @@ struct iwl_eeprom_enhanced_txpwr {
|
|||
s8 mimo3_max;
|
||||
} __packed;
|
||||
|
||||
/* 5000 Specific */
|
||||
#define EEPROM_5000_TX_POWER_VERSION (4)
|
||||
#define EEPROM_5000_EEPROM_VERSION (0x11A)
|
||||
|
||||
/* 5000 and up calibration */
|
||||
/* calibration */
|
||||
#define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION)
|
||||
#define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL)
|
||||
|
||||
/* 5000 temperature */
|
||||
#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL)
|
||||
/* temperature */
|
||||
#define EEPROM_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL)
|
||||
|
||||
/* agn links */
|
||||
#define EEPROM_LINK_HOST (2*0x64)
|
||||
|
@ -205,6 +199,10 @@ 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)
|
||||
|
@ -270,13 +268,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 */
|
||||
|
||||
|
@ -311,5 +309,6 @@ 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__ */
|
||||
|
|
|
@ -181,7 +181,16 @@ 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));
|
||||
|
||||
set_bit(STATUS_HCMD_ACTIVE, &priv->status);
|
||||
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;
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
|
||||
get_cmd_string(cmd->id));
|
||||
|
||||
|
|
|
@ -120,7 +120,16 @@ 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)
|
||||
|
|
|
@ -38,18 +38,18 @@
|
|||
static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
|
||||
{
|
||||
trace_iwlwifi_dev_iowrite8(priv, ofs, val);
|
||||
iowrite8(val, priv->hw_base + ofs);
|
||||
priv->bus.ops->write8(&priv->bus, ofs, val);
|
||||
}
|
||||
|
||||
static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
|
||||
{
|
||||
trace_iwlwifi_dev_iowrite32(priv, ofs, val);
|
||||
iowrite32(val, priv->hw_base + ofs);
|
||||
priv->bus.ops->write32(&priv->bus, ofs, val);
|
||||
}
|
||||
|
||||
static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs)
|
||||
{
|
||||
u32 val = ioread32(priv->hw_base + ofs);
|
||||
u32 val = priv->bus.ops->read32(&priv->bus, ofs);
|
||||
trace_iwlwifi_dev_ioread32(priv, ofs, val);
|
||||
return val;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
@ -40,14 +38,9 @@
|
|||
|
||||
#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
|
||||
|
@ -181,7 +174,7 @@ static int iwl_led_blink_set(struct led_classdev *led_cdev,
|
|||
|
||||
void iwl_leds_init(struct iwl_priv *priv)
|
||||
{
|
||||
int mode = led_mode;
|
||||
int mode = iwlagn_mod_params.led_mode;
|
||||
int ret;
|
||||
|
||||
if (mode == IWL_LED_DEFAULT)
|
||||
|
@ -209,7 +202,8 @@ void iwl_leds_init(struct iwl_priv *priv)
|
|||
break;
|
||||
}
|
||||
|
||||
ret = led_classdev_register(&priv->pci_dev->dev, &priv->led);
|
||||
ret = led_classdev_register(priv->bus.dev,
|
||||
&priv->led);
|
||||
if (ret) {
|
||||
kfree(priv->led.name);
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,571 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* 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 <linux/pci.h>
|
||||
#include <linux/pci-aspm.h>
|
||||
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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 <ilw@linux.intel.com>
|
||||
* 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
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "iwl-eeprom.h"
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-commands.h"
|
||||
|
@ -50,16 +51,6 @@
|
|||
* 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)
|
||||
|
@ -254,7 +245,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
|
|||
}
|
||||
}
|
||||
|
||||
if (priv->power_data.pci_pm)
|
||||
if (priv->power_data.bus_pm)
|
||||
cmd->flags |= IWL_POWER_PCI_PM_MSK;
|
||||
else
|
||||
cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
|
||||
|
@ -269,7 +260,7 @@ static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv,
|
|||
{
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
||||
if (priv->power_data.pci_pm)
|
||||
if (priv->power_data.bus_pm)
|
||||
cmd->flags |= IWL_POWER_PCI_PM_MSK;
|
||||
|
||||
IWL_DEBUG_POWER(priv, "Sleep command for CAM\n");
|
||||
|
@ -305,7 +296,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.pci_pm)
|
||||
if (priv->power_data.bus_pm)
|
||||
cmd->flags |= IWL_POWER_PCI_PM_MSK;
|
||||
|
||||
if (priv->cfg->base_params->shadow_reg_enable)
|
||||
|
@ -367,9 +358,15 @@ 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 (no_sleep_autoadjust)
|
||||
iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper);
|
||||
else
|
||||
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
|
||||
iwl_power_fill_sleep_cmd(priv, cmd,
|
||||
priv->hw->conf.dynamic_ps_timeout,
|
||||
priv->hw->conf.max_sleep_period);
|
||||
|
@ -434,9 +431,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
|
|||
/* initialize to default */
|
||||
void iwl_power_initialize(struct iwl_priv *priv)
|
||||
{
|
||||
u16 lctl = iwl_pcie_link_ctl(priv);
|
||||
|
||||
priv->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
|
||||
priv->power_data.bus_pm = priv->bus.ops->get_pm_support(&priv->bus);
|
||||
|
||||
priv->power_data.debug_sleep_level_override = -1;
|
||||
|
||||
|
|
|
@ -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 pci_pm;
|
||||
bool bus_pm;
|
||||
};
|
||||
|
||||
int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
|
||||
|
|
|
@ -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->pci_dev->dev;
|
||||
struct device *dev = priv->bus.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(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
|
||||
dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd,
|
||||
rxq->bd_dma);
|
||||
err_bd:
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#include <net/mac80211.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-debug.h"
|
||||
|
@ -101,9 +100,11 @@ 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_DATA] = { .type = NLA_UNSPEC, },
|
||||
[IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
|
||||
[IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },
|
||||
|
||||
[IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -179,19 +180,21 @@ void iwl_testmode_init(struct iwl_priv *priv)
|
|||
|
||||
static void iwl_trace_cleanup(struct iwl_priv *priv)
|
||||
{
|
||||
struct device *dev = &priv->pci_dev->dev;
|
||||
struct device *dev = priv->bus.dev;
|
||||
|
||||
if (priv->testmode_trace.trace_enabled) {
|
||||
if (priv->testmode_trace.cpu_addr &&
|
||||
priv->testmode_trace.dma_addr)
|
||||
dma_free_coherent(dev,
|
||||
TRACE_TOTAL_SIZE,
|
||||
priv->testmode_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,7 +397,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,
|
||||
UCODE_SUBTYPE_INIT, -1);
|
||||
IWL_UCODE_INIT);
|
||||
if (status)
|
||||
IWL_DEBUG_INFO(priv,
|
||||
"Error loading init ucode: %d\n", status);
|
||||
|
@ -408,8 +411,7 @@ 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,
|
||||
UCODE_SUBTYPE_REGULAR,
|
||||
UCODE_SUBTYPE_REGULAR_NEW);
|
||||
IWL_UCODE_REGULAR);
|
||||
if (status) {
|
||||
IWL_DEBUG_INFO(priv,
|
||||
"Error loading runtime ucode: %d\n", status);
|
||||
|
@ -482,16 +484,29 @@ 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->pci_dev->dev;
|
||||
struct device *dev = priv->bus.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,
|
||||
TRACE_TOTAL_SIZE,
|
||||
priv->testmode_trace.total_size,
|
||||
&priv->testmode_trace.dma_addr,
|
||||
GFP_KERNEL);
|
||||
if (!priv->testmode_trace.cpu_addr)
|
||||
|
@ -500,7 +515,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,
|
||||
TRACE_BUFF_SIZE);
|
||||
priv->testmode_trace.buff_size);
|
||||
skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
|
||||
sizeof(priv->testmode_trace.dma_addr) + 20);
|
||||
if (!skb) {
|
||||
|
@ -518,34 +533,14 @@ 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;
|
||||
|
@ -560,6 +555,37 @@ nla_put_failure:
|
|||
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.
|
||||
|
@ -638,3 +664,50 @@ 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;
|
||||
}
|
||||
|
|
|
@ -166,7 +166,8 @@ enum iwl_tm_attr_t {
|
|||
* IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
|
||||
*/
|
||||
IWL_TM_ATTR_TRACE_ADDR,
|
||||
IWL_TM_ATTR_TRACE_DATA,
|
||||
IWL_TM_ATTR_TRACE_SIZE,
|
||||
IWL_TM_ATTR_TRACE_DUMP,
|
||||
|
||||
/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
|
||||
* The mandatory fields are:
|
||||
|
@ -178,8 +179,10 @@ enum iwl_tm_attr_t {
|
|||
};
|
||||
|
||||
/* uCode trace buffer */
|
||||
#define TRACE_BUFF_SIZE 0x20000
|
||||
#define TRACE_BUFF_SIZE_MAX 0x200000
|
||||
#define TRACE_BUFF_SIZE_MIN 0x20000
|
||||
#define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN
|
||||
#define TRACE_BUFF_PADD 0x2000
|
||||
#define TRACE_TOTAL_SIZE (TRACE_BUFF_SIZE + TRACE_BUFF_PADD)
|
||||
#define TRACE_CHUNK_SIZE (PAGE_SIZE - 1024)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -128,7 +128,6 @@ 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;
|
||||
|
||||
|
@ -143,15 +142,15 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
|
|||
|
||||
/* Unmap tx_cmd */
|
||||
if (num_tbs)
|
||||
pci_unmap_single(dev,
|
||||
dma_unmap_single(priv->bus.dev,
|
||||
dma_unmap_addr(meta, mapping),
|
||||
dma_unmap_len(meta, len),
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
DMA_BIDIRECTIONAL);
|
||||
|
||||
/* Unmap chunks, if any. */
|
||||
for (i = 1; i < num_tbs; i++)
|
||||
pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
|
||||
iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
|
||||
dma_unmap_single(priv->bus.dev, iwl_tfd_tb_get_addr(tfd, i),
|
||||
iwl_tfd_tb_get_len(tfd, i), DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -266,7 +265,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->pci_dev->dev;
|
||||
struct device *dev = priv->bus.dev;
|
||||
int i;
|
||||
|
||||
iwl_tx_queue_unmap(priv, txq_id);
|
||||
|
@ -310,10 +309,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) {
|
||||
pci_unmap_single(priv->pci_dev,
|
||||
dma_unmap_single(priv->bus.dev,
|
||||
dma_unmap_addr(&txq->meta[i], mapping),
|
||||
dma_unmap_len(&txq->meta[i], len),
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
DMA_BIDIRECTIONAL);
|
||||
txq->meta[i].flags = 0;
|
||||
}
|
||||
|
||||
|
@ -332,7 +331,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->pci_dev->dev;
|
||||
struct device *dev = priv->bus.dev;
|
||||
int i;
|
||||
|
||||
iwl_cmd_queue_unmap(priv);
|
||||
|
@ -434,7 +433,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->pci_dev->dev;
|
||||
struct device *dev = priv->bus.dev;
|
||||
size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
|
||||
|
||||
/* Driver private data, only for Tx (not command) queues,
|
||||
|
@ -456,7 +455,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, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
|
||||
IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
|
||||
goto error;
|
||||
}
|
||||
txq->q.id = id;
|
||||
|
@ -677,9 +676,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 = 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))) {
|
||||
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))) {
|
||||
idx = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
@ -699,9 +698,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 = 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)) {
|
||||
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)) {
|
||||
iwlagn_unmap_tfd(priv, out_meta,
|
||||
&txq->tfds[q->write_ptr]);
|
||||
idx = -ENOMEM;
|
||||
|
|
|
@ -892,6 +892,37 @@ 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 */
|
||||
/*******************************************************************/
|
||||
|
@ -1065,6 +1096,7 @@ 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);
|
||||
|
||||
|
@ -1301,6 +1333,8 @@ 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);
|
||||
|
|
|
@ -1034,7 +1034,6 @@ 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;
|
||||
|
@ -1082,8 +1081,9 @@ 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,
|
||||
spi->master->bus_num, spi->chip_select,
|
||||
spi->max_speed_hz);
|
||||
card->spi->master->bus_num,
|
||||
card->spi->chip_select,
|
||||
card->spi->max_speed_hz);
|
||||
err = if_spi_prog_helper_firmware(card, helper);
|
||||
if (err)
|
||||
goto out;
|
||||
|
|
|
@ -185,13 +185,12 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
|
|||
*
|
||||
* Handling includes changing the header fields into CPU format.
|
||||
*/
|
||||
int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf)
|
||||
int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp,
|
||||
struct mwifiex_ds_11n_tx_cfg *tx_cfg)
|
||||
{
|
||||
struct mwifiex_ds_11n_tx_cfg *tx_cfg;
|
||||
struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg;
|
||||
|
||||
if (data_buf) {
|
||||
tx_cfg = (struct mwifiex_ds_11n_tx_cfg *) data_buf;
|
||||
if (tx_cfg) {
|
||||
tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap);
|
||||
tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info);
|
||||
}
|
||||
|
@ -208,11 +207,10 @@ int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf)
|
|||
*/
|
||||
int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *cmd, int cmd_action,
|
||||
void *data_buf)
|
||||
u16 *buf_size)
|
||||
{
|
||||
struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf;
|
||||
u16 action = (u16) cmd_action;
|
||||
u16 buf_size = *((u16 *) data_buf);
|
||||
|
||||
cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF);
|
||||
cmd->size =
|
||||
|
@ -220,8 +218,8 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
|
|||
tx_buf->action = cpu_to_le16(action);
|
||||
switch (action) {
|
||||
case HostCmd_ACT_GEN_SET:
|
||||
dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", buf_size);
|
||||
tx_buf->buff_size = cpu_to_le16(buf_size);
|
||||
dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", *buf_size);
|
||||
tx_buf->buff_size = cpu_to_le16(*buf_size);
|
||||
break;
|
||||
case HostCmd_ACT_GEN_GET:
|
||||
default:
|
||||
|
@ -240,13 +238,12 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
|
|||
* - Ensuring correct endian-ness
|
||||
*/
|
||||
int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
|
||||
int cmd_action, void *data_buf)
|
||||
int cmd_action,
|
||||
struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl)
|
||||
{
|
||||
struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
|
||||
&cmd->params.amsdu_aggr_ctrl;
|
||||
u16 action = (u16) cmd_action;
|
||||
struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl =
|
||||
(struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf;
|
||||
|
||||
cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL);
|
||||
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl)
|
||||
|
@ -272,15 +269,13 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
|
|||
* Handling includes changing the header fields into CPU format.
|
||||
*/
|
||||
int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
|
||||
void *data_buf)
|
||||
struct mwifiex_ds_11n_amsdu_aggr_ctrl
|
||||
*amsdu_aggr_ctrl)
|
||||
{
|
||||
struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl;
|
||||
struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
|
||||
&resp->params.amsdu_aggr_ctrl;
|
||||
|
||||
if (data_buf) {
|
||||
amsdu_aggr_ctrl =
|
||||
(struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf;
|
||||
if (amsdu_aggr_ctrl) {
|
||||
amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable);
|
||||
amsdu_aggr_ctrl->curr_buf_size =
|
||||
le16_to_cpu(amsdu_ctrl->curr_buf_size);
|
||||
|
@ -296,12 +291,10 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
|
|||
* - Setting HT Tx capability and HT Tx information fields
|
||||
* - Ensuring correct endian-ness
|
||||
*/
|
||||
int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd,
|
||||
u16 cmd_action, void *data_buf)
|
||||
int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action,
|
||||
struct mwifiex_ds_11n_tx_cfg *txcfg)
|
||||
{
|
||||
struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
|
||||
struct mwifiex_ds_11n_tx_cfg *txcfg =
|
||||
(struct mwifiex_ds_11n_tx_cfg *) data_buf;
|
||||
|
||||
cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG);
|
||||
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN);
|
||||
|
|
|
@ -29,9 +29,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
|
|||
int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp);
|
||||
int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp,
|
||||
void *data_buf);
|
||||
int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd,
|
||||
u16 cmd_action, void *data_buf);
|
||||
struct mwifiex_ds_11n_tx_cfg *tx_cfg);
|
||||
int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action,
|
||||
struct mwifiex_ds_11n_tx_cfg *txcfg);
|
||||
|
||||
int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc,
|
||||
|
@ -62,12 +62,14 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
|
|||
int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
|
||||
struct mwifiex_ds_tx_ba_stream_tbl *buf);
|
||||
int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
|
||||
void *data_buf);
|
||||
struct mwifiex_ds_11n_amsdu_aggr_ctrl
|
||||
*amsdu_aggr_ctrl);
|
||||
int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *cmd,
|
||||
int cmd_action, void *data_buf);
|
||||
int cmd_action, u16 *buf_size);
|
||||
int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
|
||||
int cmd_action, void *data_buf);
|
||||
int cmd_action,
|
||||
struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl);
|
||||
|
||||
/*
|
||||
* This function checks whether AMPDU is allowed or not for a particular TID.
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче